diff --git a/src/Csv.php b/src/Csv.php index 5037791..df148a5 100644 --- a/src/Csv.php +++ b/src/Csv.php @@ -2,6 +2,7 @@ namespace ParseCsv; +use ParseCsv\enums\SortEnum; use ParseCsv\enums\FileProcessingModeEnum; use ParseCsv\extensions\DatatypeTrait; @@ -90,7 +91,7 @@ class Csv { * * @var string|null */ - public $sort_type = null; + public $sort_type = SortEnum::SORT_TYPE_REGULAR; /** * Delimiter @@ -298,12 +299,34 @@ class Csv { * Class constructor * * @param string|null $input The CSV string or a direct filepath - * @param integer|null $offset Number of rows to ignore from the beginning of the data - * @param integer|null $limit Limits the number of returned rows to specified amount - * @param string|null $conditions Basic SQL-like conditions for row matching - * @param null|true $keep_file_data Keep raw file data in memory after successful parsing (useful for debugging) + * @param integer|null $offset Number of rows to ignore from the beginning + * of the data + * @param integer|null $limit Limits the number of returned rows to + * specified amount + * @param string|null $conditions Basic SQL-like conditions for row + * matching + * @param null|true $keep_file_data Keep raw file data in memory after + * successful parsing (useful for debugging) */ public function __construct($input = null, $offset = null, $limit = null, $conditions = null, $keep_file_data = null) { + $this->init($offset, $limit, $conditions, $keep_file_data); + + if (!empty($input)) { + $this->parse($input); + } + } + + /** + * @param integer|null $offset Number of rows to ignore from the beginning + * of the data + * @param integer|null $limit Limits the number of returned rows to + * specified amount + * @param string|null $conditions Basic SQL-like conditions for row + * matching + * @param null|true $keep_file_data Keep raw file data in memory after + * successful parsing (useful for debugging) + */ + public function init($offset = null, $limit = null, $conditions = null, $keep_file_data = null) { if (!is_null($offset)) { $this->offset = $offset; } @@ -319,10 +342,6 @@ class Csv { if (!is_null($keep_file_data)) { $this->keep_file_data = $keep_file_data; } - - if (!empty($input)) { - $this->parse($input); - } } // ============================================== @@ -345,32 +364,29 @@ class Csv { $input = $this->file; } - if (!empty($input)) { - if (!is_null($offset)) { - $this->offset = $offset; - } + if (empty($input)) { + // todo: but why true? + return true; + } - if (!is_null($limit)) { - $this->limit = $limit; - } + $this->init($offset, $limit, $conditions); - if (!is_null($conditions)) { - $this->conditions = $conditions; - } - if (strlen($input) <= PHP_MAXPATHLEN && is_readable($input)) { - $this->data = $this->parse_file($input); - } else { - $this->file_data = &$input; - $this->data = $this->parse_string(); - } + if (strlen($input) <= PHP_MAXPATHLEN && is_readable($input)) { + $this->file = $input; + $this->data = $this->parse_file(); + } else { + $this->file = null; + $this->file_data = &$input; + $this->data = $this->parse_string(); + } - if ($this->data === false) { - return false; - } + if ($this->data === false) { + return false; } return true; + } /** @@ -559,7 +575,7 @@ class Csv { * * @return array|bool */ - public function parse_file($file = null) { + protected function parse_file($file = null) { if (is_null($file)) { $file = $this->file; } @@ -582,7 +598,7 @@ class Csv { * * @return array|false - 2D array with CSV data, or false on failure */ - public function parse_string($data = null) { + protected function parse_string($data = null) { if (empty($data)) { if ($this->_check_data()) { $data = &$this->file_data; @@ -733,13 +749,7 @@ class Csv { $this->titles = $head; if (!empty($this->sort_by)) { - $sort_type = SORT_REGULAR; - if ($this->sort_type == 'numeric') { - $sort_type = SORT_NUMERIC; - } elseif ($this->sort_type == 'string') { - $sort_type = SORT_STRING; - } - + $sort_type = SortEnum::getSorting($this->sort_type); $this->sort_reverse ? krsort($rows, $sort_type) : ksort($rows, $sort_type); if ($this->offset !== null || $this->limit !== null) { diff --git a/src/enums/AbstractEnum.php b/src/enums/AbstractEnum.php new file mode 100644 index 0000000..aae78e1 --- /dev/null +++ b/src/enums/AbstractEnum.php @@ -0,0 +1,40 @@ +isValid($value)) { + throw new \UnexpectedValueException("Value '$value' is not part of the enum " . get_called_class()); + } + $this->value = $value; + } + + public static function getConstants(){ + $class = get_called_class(); + $reflection = new \ReflectionClass($class); + + return $reflection->getConstants(); + } + + /** + * Check if enum value is valid + * + * @param $value + * + * @return bool + */ + public static function isValid($value) + { + return in_array($value, static::getConstants(), true); + } +} diff --git a/src/enums/DatatypeEnum.php b/src/enums/DatatypeEnum.php index 8fea47d..7f490e9 100644 --- a/src/enums/DatatypeEnum.php +++ b/src/enums/DatatypeEnum.php @@ -9,7 +9,7 @@ namespace ParseCsv\enums; * * todo: needs a basic parent enum class for error handling. */ -class DatatypeEnum { +class DatatypeEnum extends AbstractEnum { const __DEFAULT = self::TYPE_STRING; diff --git a/src/enums/SortEnum.php b/src/enums/SortEnum.php new file mode 100644 index 0000000..54c3040 --- /dev/null +++ b/src/enums/SortEnum.php @@ -0,0 +1,28 @@ + SORT_REGULAR, + self::SORT_TYPE_STRING => SORT_STRING, + self::SORT_TYPE_NUMERIC => SORT_NUMERIC + ); + + public static function getSorting($type){ + if (array_key_exists($type, self::$sorting)){ + return self::$sorting[$type]; + } + + return self::$sorting[self::__DEFAULT]; + } + +} diff --git a/tests/methods/ParseTest.php b/tests/methods/ParseTest.php index 28f04f7..f6cfb05 100644 --- a/tests/methods/ParseTest.php +++ b/tests/methods/ParseTest.php @@ -85,7 +85,8 @@ class ParseTest extends TestCase { $this->csv->enclosure = '"'; $sInput = "86545235689,a\r\n34365587654,b\r\n13469874576,\"c\r\nd\""; $expected_data = [86545235689, 34365587654, 13469874576]; - $actual_data = $this->csv->parse_string($sInput); + + $actual_data = $this->invokeMethod($this->csv, 'parse_string', array($sInput)); $actual_column = array_map('reset', $actual_data); $this->assertEquals($expected_data, $actual_column); $this->assertEquals([ @@ -219,4 +220,22 @@ class ParseTest extends TestCase { $this->assertArrayHasKey('column1', $csv->data[0], 'Data parsed incorrectly with enclosure ' . $enclosure); $this->assertEquals('value1', $csv->data[0]['column1'], 'Data parsed incorrectly with enclosure ' . $enclosure); } + + /** + * Call protected/private method of a class. + * + * @param object &$object Instantiated object that we will run method on. + * @param string $methodName Method name to call + * @param array $parameters Array of parameters to pass into method. + * + * @return mixed Method return. + */ + private function invokeMethod(&$object, $methodName, array $parameters = array()) + { + $reflection = new \ReflectionClass(get_class($object)); + $method = $reflection->getMethod($methodName); + $method->setAccessible(true); + + return $method->invokeArgs($object, $parameters); + } } diff --git a/tests/properties/DefaultValuesPropertiesTest.php b/tests/properties/DefaultValuesPropertiesTest.php index 803afcc..364f7cd 100644 --- a/tests/properties/DefaultValuesPropertiesTest.php +++ b/tests/properties/DefaultValuesPropertiesTest.php @@ -57,7 +57,7 @@ class DefaultValuesPropertiesTest extends TestCase { } public function test_sort_type_default() { - $this->assertNull($this->csv->sort_type); + $this->assertEquals('regular', $this->csv->sort_type); } public function test_delimiter_default() { diff --git a/tests/properties/PublicPropertiesTest.php b/tests/properties/PublicPropertiesTest.php index fbf85d5..ed49354 100644 --- a/tests/properties/PublicPropertiesTest.php +++ b/tests/properties/PublicPropertiesTest.php @@ -3,6 +3,7 @@ namespace ParseCsv\tests\properties; use ParseCsv\Csv; +use ParseCsv\enums\SortEnum; use PHPUnit\Framework\TestCase; class PublicPropertiesTest extends TestCase { @@ -145,4 +146,26 @@ class PublicPropertiesTest extends TestCase { $this->assertCount($counter, $this->properties); } + + public function testDefaultSortTypeIsRegular(){ + $this->assertEquals(SortEnum::SORT_TYPE_REGULAR, $this->csv->sort_type); + } + + public function testSetSortType(){ + $this->csv->sort_type = 'numeric'; + $this->assertEquals(SortEnum::SORT_TYPE_NUMERIC, $this->csv->sort_type); + + $this->csv->sort_type = 'string'; + $this->assertEquals(SortEnum::SORT_TYPE_STRING, $this->csv->sort_type); + } + + public function testGetSorting(){ + $this->csv->sort_type = 'numeric'; + $sorting = SortEnum::getSorting($this->csv->sort_type); + $this->assertEquals(SORT_NUMERIC, $sorting); + + $this->csv->sort_type = 'string'; + $sorting = SortEnum::getSorting($this->csv->sort_type); + $this->assertEquals(SORT_STRING, $sorting); + } }