Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00%
0 / 1
42.86%
3 / 7
CRAP
90.80%
79 / 87
CSV
0.00%
0 / 1
42.86%
3 / 7
19.28
90.80%
79 / 87
 __construct(array $options = array())
100.00%
1 / 1
1
100.00%
4 / 4
 setDefaultOptions(OptionsResolverInterface $resolver)
100.00%
1 / 1
1
100.00%
30 / 30
 read()
0.00%
0 / 1
9.17
87.10%
27 / 31
 readColumns($handle)
0.00%
0 / 1
3.21
71.43%
5 / 7
 checkColumns($columns)
0.00%
0 / 1
3.03
85.71%
6 / 7
 readLine($handle)
100.00%
1 / 1
1
100.00%
7 / 7
 write()
0.00%
0 / 1
2
0.00%
0 / 1
<?php
/**
* This file is part of the Statistical Classifier package.
*
* (c) Cam Spiers <camspiers@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Camspiers\StatisticalClassifier\DataSource;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
/**
* @author Cam Spiers <camspiers@gmail.com>
* @package Statistical Classifier
*/
class CSV extends DataArray
{
/**
* Stores the configuration options
* @var array
*/
protected $options;
/**
* Creates the object from an array of options
* @param array $options
*/
public function __construct(array $options = array())
{
$resolver = new OptionsResolver();
$this->setDefaultOptions($resolver);
$this->options = $resolver->resolve($options);
}
/**
* Sets the configuration for the options resolver
* @param OptionsResolverInterface $resolver
*/
protected function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setRequired(
array(
'file',
'document_columns',
'category_column'
)
);
$resolver->setOptional(
array(
'limit',
'delimiter',
'enclosure',
'escape',
'category_modifier'
)
);
$resolver->setDefaults(
array(
'limit' => false,
'length' => 0,
'delimiter' => ',',
'enclosure' => '"',
'escape' => '\\',
'category_modifier' => false
)
);
$resolver->setAllowedTypes(
array(
'file' => 'string',
'document_columns' => 'array',
'category_column' => 'string',
'length' => 'int',
'delimiter' => 'string',
'enclosure' => 'string',
'escape' => 'string'
)
);
}
/**
* @{inheritdoc}
*/
public function read()
{
$entries = array();
if (file_exists($this->options['file'])) {
$handle = fopen($this->options['file'], 'r');
$columns = $this->readColumns($handle);
$this->checkColumns($columns);
$columnTotal = count($columns);
$entryCount = 0;
$hasModifier = is_callable($this->options['category_modifier']);
while (true) {
if ($this->options['limit'] && $this->options['limit'] < $entryCount) {
break;
}
if (($csvData = $this->readLine($handle)) === false) {
break;
}
if ($columnTotal !== count($csvData)) {
continue;
}
$document = array();
foreach ($this->options['document_columns'] as $column) {
$document[] = $csvData[$columns[$column]];
}
$category = $csvData[$columns[$this->options['category_column']]];
if ($hasModifier) {
$category = $this->options['category_modifier']($category);
}
$entries[] = array(
'document' => implode(' ', $document),
'category' => $category
);
$entryCount++;
}
fclose($handle);
}
return $entries;
}
/**
* @param $handle
* @return array
* @throws \RuntimeException
*/
protected function readColumns($handle)
{
if ($handle === false) {
throw new \RuntimeException("Could not read file '{$this->options['file']}'");
}
$columns = $this->readLine($handle);
if ($columns === false) {
throw new \RuntimeException("Failed to determine csv columns");
}
/**
* Result:
* array(
* 'ColumnName1' => 0,
* 'ColumnName2' => 1
* )
*/
$columns = array_flip($columns);
return $columns;
}
/**
* @param $columns
* @return array
* @throws \RuntimeException
*/
protected function checkColumns($columns)
{
$neededColumns = $this->options['document_columns'];
$neededColumns[] = $this->options['category_column'];
foreach ($neededColumns as $column) {
if (!array_key_exists($column, $columns)) {
throw new \RuntimeException("Column '$column' doesn't exist in the csv");
}
}
}
/**
* @param $handle
* @return array
*/
protected function readLine($handle)
{
return fgetcsv(
$handle,
$this->options['length'],
$this->options['delimiter'],
$this->options['enclosure'],
$this->options['escape']
);
}
/**
* @{inheritdoc}
*/
public function write()
{
}
}