From 00c48435a422716b94e09ca535342b5dbe9c5253 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Tue, 9 Jan 2024 15:43:01 -0600 Subject: [PATCH 01/11] PHP 8.1 Implementation --- .github/workflows/phpunit.yml | 3 +-- .vscode/launch.json | 38 --------------------------- composer.json | 11 +++++--- src/Row.php | 4 +-- tests/AnyDatasetTest.php | 2 +- tests/IteratorFilterTest.php | 2 +- tests/ModelTest.php | 19 +++++++------- tests/RowOutputTest.php | 2 +- tests/RowTest.php | 13 ++++----- tests/RowValidatorTest.php | 2 +- tests/Sample/ModelGetter.php | 2 +- tests/Sample/ModelPropertyPattern.php | 2 +- tests/Sample/ModelPublic.php | 2 +- tests/Sample/SampleModel.php | 2 +- 14 files changed, 33 insertions(+), 71 deletions(-) delete mode 100644 .vscode/launch.json diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index c73af56..b65df91 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -16,10 +16,9 @@ jobs: strategy: matrix: php-version: + - "8.3" - "8.2" - "8.1" - - "8.0" - - "7.4" steps: - uses: actions/checkout@v4 diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index eb13393..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Debug current Script in Console", - "type": "php", - "request": "launch", - "program": "${file}", - "cwd": "${fileDirname}", - "port": 0, - "runtimeArgs": [ - "-dxdebug.start_with_request=yes" - ], - "env": { - "XDEBUG_MODE": "debug,develop", - "XDEBUG_CONFIG": "client_port=${port}" - } - }, - { - "name": "PHPUnit Debug", - "type": "php", - "request": "launch", - "program": "${workspaceFolder}/vendor/bin/phpunit", - "cwd": "${workspaceFolder}", - "port": 0, - "runtimeArgs": [ - "-dxdebug.start_with_request=yes" - ], - "env": { - "XDEBUG_MODE": "debug,develop", - "XDEBUG_CONFIG": "client_port=${port}" - } - } - ] -} diff --git a/composer.json b/composer.json index 643fd52..c5513e4 100644 --- a/composer.json +++ b/composer.json @@ -6,12 +6,17 @@ "ByJG\\AnyDataset\\Core\\": "src/" } }, + "autoload-dev": { + "psr-4": { + "Tests\\": "tests/" + } + }, "prefer-stable": true, "minimum-stability": "dev", "require": { - "php": ">=7.4", - "byjg/xmlutil": "4.9.*", - "byjg/serializer": "4.9.*" + "php": ">=8.1", + "byjg/xmlutil": "^5.0", + "byjg/serializer": "^5.0" }, "suggest": { "ext-dom": "*" diff --git a/src/Row.php b/src/Row.php index f638c26..39a754d 100644 --- a/src/Row.php +++ b/src/Row.php @@ -2,7 +2,7 @@ namespace ByJG\AnyDataset\Core; -use ByJG\Serializer\SerializerObject; +use ByJG\Serializer\Serialize; class Row { @@ -33,7 +33,7 @@ public function __construct($instance = []) if (is_array($instance)) { $this->row = $instance; } else { - $this->row = SerializerObject::instance($instance)->serialize(); + $this->row = Serialize::from($instance)->toArray(); } $this->acceptChanges(); diff --git a/tests/AnyDatasetTest.php b/tests/AnyDatasetTest.php index 0bd96ec..679db2e 100644 --- a/tests/AnyDatasetTest.php +++ b/tests/AnyDatasetTest.php @@ -1,6 +1,6 @@ addField("id", 10); $sr->addField("name", "Testing"); - $object = new \Tests\AnyDataset\Sample\SampleModel($sr->toArray()); + $object = new SampleModel($sr->toArray()); $this->assertEquals(10, $object->Id); $this->assertEquals("Testing", $object->getName()); @@ -31,7 +30,7 @@ public function testBindIterator() $sr->addField("name", "Testing"); $anydata->appendRow($sr); - $object = new \Tests\AnyDataset\Sample\SampleModel($anydata->getIterator()->moveNext()->toArray()); + $object = new SampleModel($anydata->getIterator()->moveNext()->toArray()); $this->assertEquals(10, $object->Id); $this->assertEquals("Testing", $object->getName()); @@ -46,8 +45,8 @@ public function testBind_Iterator2() $anydata->addField('Id', 20); $anydata->addField('Name', 'Gilberto'); - $object1 = new \Tests\AnyDataset\Sample\SampleModel(); - $object1->bindFrom( $anydata->getIterator()->moveNext()->toArray() ); + $object1 = new SampleModel(); + $object1->copyFrom( $anydata->getIterator()->moveNext()->toArray() ); $this->assertEquals(10, $object1->Id); $this->assertEquals('Joao', $object1->getName()); } @@ -64,8 +63,8 @@ public function testIterator() $iterator = $model->getIterator(); - $object = new SerializerObject($iterator->toArray()); - $result = $object->serialize(); + $object = Serialize::from($iterator->toArray()); + $result = $object->toArray(); $this->assertEquals( [ diff --git a/tests/RowOutputTest.php b/tests/RowOutputTest.php index 688232f..a03e397 100644 --- a/tests/RowOutputTest.php +++ b/tests/RowOutputTest.php @@ -1,6 +1,6 @@ setIdModel(10); $model->setClientName("Testing"); diff --git a/tests/RowValidatorTest.php b/tests/RowValidatorTest.php index 4aa45cd..4925a18 100644 --- a/tests/RowValidatorTest.php +++ b/tests/RowValidatorTest.php @@ -1,6 +1,6 @@ Date: Mon, 8 Apr 2024 14:51:55 -0500 Subject: [PATCH 02/11] Added Relation::IN and Relation::NOT_IN --- src/IteratorFilter.php | 87 ++++++++++------------------ src/IteratorFilterFormatter.php | 10 ++-- src/IteratorFilterXPathFormatter.php | 10 ++-- 3 files changed, 39 insertions(+), 68 deletions(-) diff --git a/src/IteratorFilter.php b/src/IteratorFilter.php index 7092027..ae3276e 100644 --- a/src/IteratorFilter.php +++ b/src/IteratorFilter.php @@ -10,7 +10,7 @@ class IteratorFilter /** * @var array */ - private $filters; + private array $filters; /** * IteratorFilter Constructor @@ -23,7 +23,7 @@ public function __construct() /** * @return IteratorFilter */ - public static function getInstance() + public static function getInstance(): IteratorFilter { return new IteratorFilter(); } @@ -32,7 +32,7 @@ public static function getInstance() * @param array $array * @return Row[] */ - public function match($array) + public function match(array $array): array { $returnArray = []; @@ -49,12 +49,12 @@ public function match($array) * Get the filter * * @param IteratorFilterFormatter $formatter - * @param string $tableName + * @param string|null $tableName * @param array $params * @param string $returnFields * @return string */ - public function format(IteratorFilterFormatter $formatter, $tableName = null, &$params = [], $returnFields = "*") + public function format(IteratorFilterFormatter $formatter, string $tableName = null, array &$params = [], string $returnFields = "*"): string { return $formatter->format($this->filters, $tableName, $params, $returnFields); } @@ -64,7 +64,7 @@ public function format(IteratorFilterFormatter $formatter, $tableName = null, &$ * @param Row $singleRow * @return bool */ - private function evalString(Row $singleRow) + private function evalString(Row $singleRow): bool { $result = []; $finalResult = false; @@ -85,47 +85,18 @@ private function evalString(Row $singleRow) $field = [$singleRow->get($name)]; foreach ($field as $valueparam) { - switch ($relation) { - case Relation::EQUAL: - $result[$pos] = $result[$pos] && ($valueparam == $value); - break; - - case Relation::GREATER_THAN: - $result[$pos] = $result[$pos] && ($valueparam > $value); - break; - - case Relation::LESS_THAN: - $result[$pos] = $result[$pos] && ($valueparam < $value); - break; - - case Relation::GREATER_OR_EQUAL_THAN: - $result[$pos] = $result[$pos] && ($valueparam >= $value); - break; - - case Relation::LESS_OR_EQUAL_THAN: - $result[$pos] = $result[$pos] && ($valueparam <= $value); - break; - - case Relation::NOT_EQUAL: - $result[$pos] = $result[$pos] && ($valueparam != $value); - break; - - case Relation::STARTS_WITH: - $result[$pos] = $result[$pos] && (strpos(is_null($valueparam) ? "" : $valueparam, $value) === 0); - break; - - case Relation::IN: - $result[$pos] = $result[$pos] && in_array($valueparam, $value); - break; - - case Relation::NOT_IN: - $result[$pos] = $result[$pos] && !in_array($valueparam, $value); - break; - - default: // Relation::CONTAINS: - $result[$pos] = $result[$pos] && (strpos(is_null($valueparam) ? "" : $valueparam, $value) !== false); - break; - } + $result[$pos] = match ($relation) { + Relation::EQUAL => $result[$pos] && ($valueparam == $value), + Relation::GREATER_THAN => $result[$pos] && ($valueparam > $value), + Relation::LESS_THAN => $result[$pos] && ($valueparam < $value), + Relation::GREATER_OR_EQUAL_THAN => $result[$pos] && ($valueparam >= $value), + Relation::LESS_OR_EQUAL_THAN => $result[$pos] && ($valueparam <= $value), + Relation::NOT_EQUAL => $result[$pos] && ($valueparam != $value), + Relation::STARTS_WITH => $result[$pos] && (str_starts_with(is_null($valueparam) ? "" : $valueparam, $value)), + Relation::IN => $result[$pos] && in_array($valueparam, $value), + Relation::NOT_IN => $result[$pos] && !in_array($valueparam, $value), + default => $result[$pos] && (str_contains(is_null($valueparam) ? "" : $valueparam, $value)), + }; } } @@ -137,11 +108,11 @@ private function evalString(Row $singleRow) /** * @param string $name Field name * @param int $relation Relation enum - * @param string|array $value Field string value - * @return IteratorFilter + * @param array|string $value Field string value + * @return static * @desc Add a single string comparison to filter. */ - public function addRelation($name, $relation, $value) + public function addRelation(string $name, int $relation, array|string $value): static { $this->filters[] = [" and ", $name, $relation, $value]; return $this; @@ -150,11 +121,11 @@ public function addRelation($name, $relation, $value) /** * @param string $name Field name * @param int $relation Relation enum - * @param string $value Field string value - * @return IteratorFilter + * @param array|string $value Field string value + * @return static * @desc Add a single string comparison to filter. This comparison use the OR operator. */ - public function addRelationOr($name, $relation, $value) + public function addRelationOr(string $name, int $relation, array|string $value): static { $this->filters[] = [" or ", $name, $relation, $value]; return $this; @@ -162,9 +133,9 @@ public function addRelationOr($name, $relation, $value) /** * Add a "(" - * @return IteratorFilter + * @return static */ - public function startGroup() + public function startGroup(): static { $this->filters[] = ["(", "", "", ""]; return $this; @@ -172,9 +143,9 @@ public function startGroup() /** * Add a ")" - * @return IteratorFilter + * @return static */ - public function endGroup() + public function endGroup(): static { $this->filters[] = [")", "", "", ""]; return $this; @@ -183,7 +154,7 @@ public function endGroup() /** * @return array */ - public function getRawFilters() + public function getRawFilters(): array { return $this->filters; } diff --git a/src/IteratorFilterFormatter.php b/src/IteratorFilterFormatter.php index ccab474..35cde8a 100644 --- a/src/IteratorFilterFormatter.php +++ b/src/IteratorFilterFormatter.php @@ -10,22 +10,22 @@ abstract class IteratorFilterFormatter * * @param string $name * @param string $relation - * @param string|array $value + * @param array|string $value * @param array $param * @return string */ - abstract public function getRelation($name, $relation, $value, &$param); + abstract public function getRelation(string $name, string $relation, array|string $value, array &$param): string; /** * Get formatted field * * @param array $filters - * @param string $tableName + * @param string|null $tableName * @param array $params * @param string $returnFields * @return string */ - abstract public function format($filters, $tableName = null, &$params = [], $returnFields = "*"); + abstract public function format(array $filters, string $tableName = null, array &$params = [], string $returnFields = "*"): string; /** * Get Filter @@ -34,7 +34,7 @@ abstract public function format($filters, $tableName = null, &$params = [], $ret * @param array $param * @return string */ - public function getFilter($filters, &$param) + public function getFilter(array $filters, array &$param): string { $filter = ""; $param = array(); diff --git a/src/IteratorFilterXPathFormatter.php b/src/IteratorFilterXPathFormatter.php index c7c575b..157dac7 100644 --- a/src/IteratorFilterXPathFormatter.php +++ b/src/IteratorFilterXPathFormatter.php @@ -9,8 +9,8 @@ class IteratorFilterXPathFormatter extends IteratorFilterFormatter /** * @inheritDoc */ - public function format($filters, $tableName = null, &$params = [], $returnFields = "*") - { + public function format(array $filters, string $tableName = null, array &$params = [], string $returnFields = "*"): string + { $param = []; $xpathFilter = $this->getFilter($filters, $param); @@ -19,13 +19,13 @@ public function format($filters, $tableName = null, &$params = [], $returnFields } return "/anydataset/row[" . $xpathFilter . "]"; - } + } /** * @inheritDoc */ - public function getRelation($name, $relation, $value, &$param) - { + public function getRelation(string $name, string $relation, array|string $value, array &$param): string + { $str = is_numeric($value) ? "" : "'"; $field = "field[@name='" . $name . "'] "; if (is_string($value)) { From 0edf6dba60d8e67892ada23760a7ec5e22e2c668 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Tue, 14 May 2024 16:09:06 -0500 Subject: [PATCH 03/11] Fixed value type for iteratorFilter --- src/IteratorFilter.php | 4 ++-- src/IteratorFilterFormatter.php | 2 +- src/IteratorFilterXPathFormatter.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/IteratorFilter.php b/src/IteratorFilter.php index ae3276e..3d1c2e7 100644 --- a/src/IteratorFilter.php +++ b/src/IteratorFilter.php @@ -112,7 +112,7 @@ private function evalString(Row $singleRow): bool * @return static * @desc Add a single string comparison to filter. */ - public function addRelation(string $name, int $relation, array|string $value): static + public function addRelation(string $name, int $relation, mixed $value): static { $this->filters[] = [" and ", $name, $relation, $value]; return $this; @@ -125,7 +125,7 @@ public function addRelation(string $name, int $relation, array|string $value): s * @return static * @desc Add a single string comparison to filter. This comparison use the OR operator. */ - public function addRelationOr(string $name, int $relation, array|string $value): static + public function addRelationOr(string $name, int $relation, mixed $value): static { $this->filters[] = [" or ", $name, $relation, $value]; return $this; diff --git a/src/IteratorFilterFormatter.php b/src/IteratorFilterFormatter.php index 35cde8a..3db783d 100644 --- a/src/IteratorFilterFormatter.php +++ b/src/IteratorFilterFormatter.php @@ -14,7 +14,7 @@ abstract class IteratorFilterFormatter * @param array $param * @return string */ - abstract public function getRelation(string $name, string $relation, array|string $value, array &$param): string; + abstract public function getRelation(string $name, string $relation, mixed $value, array &$param): string; /** * Get formatted field diff --git a/src/IteratorFilterXPathFormatter.php b/src/IteratorFilterXPathFormatter.php index 157dac7..c2df862 100644 --- a/src/IteratorFilterXPathFormatter.php +++ b/src/IteratorFilterXPathFormatter.php @@ -24,7 +24,7 @@ public function format(array $filters, string $tableName = null, array &$params /** * @inheritDoc */ - public function getRelation(string $name, string $relation, array|string $value, array &$param): string + public function getRelation(string $name, string $relation, mixed $value, array &$param): string { $str = is_numeric($value) ? "" : "'"; $field = "field[@name='" . $name . "'] "; From d7d4243078095ccd2083ce9a09cf6a06680c76a5 Mon Sep 17 00:00:00 2001 From: Joao M Date: Mon, 10 Jun 2024 01:58:27 +0000 Subject: [PATCH 04/11] Fix to use with new XmlUtil. --- src/AnyDataset.php | 47 ++++++++++++++++------------------ src/Formatter/XmlFormatter.php | 40 ++++++++++++----------------- tests/AnyDatasetTest.php | 10 +++++--- tests/RowTest.php | 6 ++--- 4 files changed, 47 insertions(+), 56 deletions(-) diff --git a/src/AnyDataset.php b/src/AnyDataset.php index 822c743..99b7804 100644 --- a/src/AnyDataset.php +++ b/src/AnyDataset.php @@ -4,7 +4,8 @@ use ByJG\AnyDataset\Core\Exception\DatabaseException; use ByJG\AnyDataset\Core\Formatter\XmlFormatter; -use ByJG\Util\XmlUtil; +use ByJG\Util\File; +use ByJG\Util\XmlDocument; use InvalidArgumentException; /** @@ -56,11 +57,7 @@ class AnyDataset */ private $currentRow; - /** - * Path to anydataset file - * @var string|null - */ - private $filename; + private ?File $file; /** * @param null|string $filename @@ -72,10 +69,10 @@ public function __construct($filename = null) $this->collection = array(); $this->currentRow = -1; - $this->filename = null; + $this->file = null; $this->defineSavePath($filename, function () { - if (!is_null($this->filename)) { - $this->createFrom($this->filename); + if (!is_null($this->file)) { + $this->createFromFile(); } }); } @@ -85,23 +82,23 @@ public function __construct($filename = null) */ public function getFilename() { - return $this->filename; + return $this->file->getFilename(); } /** * - * @param string|null $file + * @param string|null $filename * @param mixed $closure * @return void */ - private function defineSavePath($file, $closure) + private function defineSavePath($filename, $closure) { - if (!is_null($file)) { - $ext = pathinfo($file, PATHINFO_EXTENSION); - if (empty($ext) && substr($file, 0, 6) !== "php://") { - $file .= '.anydata.xml'; + if (!is_null($filename)) { + $ext = pathinfo($filename, PATHINFO_EXTENSION); + if (empty($ext) && substr($filename, 0, 6) !== "php://") { + $filename .= '.anydata.xml'; } - $this->filename = $file; + $this->file = new File($filename, allowNotFound: true); } $closure(); @@ -115,20 +112,20 @@ private function defineSavePath($file, $closure) * @throws \ByJG\Serializer\Exception\InvalidArgumentException * @throws \ByJG\Util\Exception\XmlUtilException */ - private function createFrom($filepath) + private function createFromFile() { - if (file_exists($filepath)) { - $anyDataSet = XmlUtil::createXmlDocumentFromFile($filepath); + if (file_exists($this->getFilename())) { + $anyDataSet = new XmlDocument($this->file); $this->collection = array(); - $rows = $anyDataSet->getElementsByTagName("row"); + $rows = $anyDataSet->selectNodes("row"); foreach ($rows as $row) { $sr = new Row(); $fields = $row->getElementsByTagName("field"); foreach ($fields as $field) { $attr = $field->attributes->getNamedItem("name"); if (is_null($attr) || is_null($attr->nodeValue)) { - throw new InvalidArgumentException('Malformed anydataset file ' . basename($filepath)); + throw new InvalidArgumentException('Malformed anydataset file ' . basename($this->getFilename())); } $sr->addField($attr->nodeValue, $field->nodeValue); @@ -159,12 +156,12 @@ public function xml() */ public function save($filename = null) { - $this->defineSavePath($filename, function () { - if (is_null($this->filename)) { + $this->defineSavePath($filename, function () use ($filename){ + if (is_null($this->file)) { throw new DatabaseException("No such file path to save anydataset"); } - (new XmlFormatter($this->getIterator()))->saveToFile($this->filename); + (new XmlFormatter($this->getIterator()))->saveToFile($this->file->getFilename()); }); } diff --git a/src/Formatter/XmlFormatter.php b/src/Formatter/XmlFormatter.php index db60e70..57adeff 100644 --- a/src/Formatter/XmlFormatter.php +++ b/src/Formatter/XmlFormatter.php @@ -3,9 +3,7 @@ namespace ByJG\AnyDataset\Core\Formatter; use ByJG\AnyDataset\Core\GenericIterator; -use ByJG\Util\XmlUtil; -use DOMDocument; -use DOMNode; +use ByJG\Util\XmlDocument; class XmlFormatter extends BaseFormatter { @@ -13,17 +11,13 @@ class XmlFormatter extends BaseFormatter * Return a DOMNode representing AnyDataset * * @param array $collection - * @return DOMNode + * @return XmlDocument */ protected function anydatasetXml($collection) { - $anyDataSet = XmlUtil::createXmlDocumentFromStr(""); - $nodeRoot = $anyDataSet->getElementsByTagName("anydataset")->item(0); + $anyDataSet = new XmlDocument(""); foreach ($collection as $sr) { - $row = $this->rowXml($sr); - $nodeRow = $row->getElementsByTagName("row")->item(0); - $newRow = XmlUtil::createChild($nodeRoot, "row"); - XmlUtil::addNodeFromNode($newRow, $nodeRow); + $this->rowXml($sr, $anyDataSet); } return $anyDataSet; @@ -31,21 +25,19 @@ protected function anydatasetXml($collection) /** * @param array $row - * @return DOMDocument + * @return XmlDocument */ - protected function rowXml($row) + protected function rowXml($row, XmlDocument $parentDocument = null) { - $node = XmlUtil::createXmlDocumentFromStr(""); - $root = $node->getElementsByTagName("row")->item(0); + if (!empty($parentDocument)) { + $node = $parentDocument->appendChild('row'); + } else { + $node = new XmlDocument(""); + } foreach ($row as $key => $value) { - if (!is_array($value)) { - $field = XmlUtil::createChild($root, "field", $value); - XmlUtil::addAttribute($field, "name", $key); - } else { - foreach ($value as $valueItem) { - $field = XmlUtil::createChild($root, "field", $valueItem); - XmlUtil::addAttribute($field, "name", $key); - } + foreach ((array)$value as $valueItem) { + $field = $node->appendChild("field", $valueItem); + $field->addAttribute("name", $key); } } return $node; @@ -58,9 +50,9 @@ protected function rowXml($row) public function raw() { if ($this->object instanceof GenericIterator) { - return $this->anydatasetXml($this->object->toArray()); + return $this->anydatasetXml($this->object->toArray())->DOMDocument(); } - return $this->rowXml($this->object->toArray()); + return $this->rowXml($this->object->toArray())->DOMNode(); } /** diff --git a/tests/AnyDatasetTest.php b/tests/AnyDatasetTest.php index 679db2e..5feb119 100644 --- a/tests/AnyDatasetTest.php +++ b/tests/AnyDatasetTest.php @@ -7,7 +7,9 @@ use ByJG\AnyDataset\Core\Formatter\JsonFormatter; use ByJG\AnyDataset\Core\Formatter\XmlFormatter; use ByJG\AnyDataset\Core\IteratorFilter; +use ByJG\Util\XmlDocument; use PHPUnit\Framework\TestCase; +use PHPUnit\Util\Xml; class AnyDatasetTest extends TestCase { @@ -77,7 +79,7 @@ public function testXML() $this->object->appendRow(); $this->object->addField('field', 'value'); - $xmlDom = \ByJG\Util\XmlUtil::createXmlDocumentFromStr( + $xmlDom = new XmlDocument( '' . '' . '' @@ -85,7 +87,7 @@ public function testXML() . '' . '' ); - $xmlDomValidate = \ByJG\Util\XmlUtil::createXmlDocumentFromStr($this->object->xml()); + $xmlDomValidate = new XmlDocument($this->object->xml()); $this->assertEquals($xmlDom, $xmlDomValidate); } @@ -95,7 +97,7 @@ public function testXMFormatter() $this->object->appendRow(); $this->object->addField('field', 'value'); - $xmlDom = \ByJG\Util\XmlUtil::createXmlDocumentFromStr( + $xmlDom = new XmlDocument( '' . '' . '' @@ -105,7 +107,7 @@ public function testXMFormatter() ); $formatter = new XmlFormatter($this->object->getIterator()); - $this->assertEquals($xmlDom, $formatter->raw()); + $this->assertEquals($xmlDom->DOMNode(), $formatter->raw()); } public function testJsonFormatter() diff --git a/tests/RowTest.php b/tests/RowTest.php index d038876..97d31e5 100644 --- a/tests/RowTest.php +++ b/tests/RowTest.php @@ -5,8 +5,8 @@ use ByJG\AnyDataset\Core\Formatter\JsonFormatter; use ByJG\AnyDataset\Core\Formatter\XmlFormatter; use ByJG\AnyDataset\Core\Row; +use ByJG\Util\XmlDocument; use PHPUnit\Framework\TestCase; -use ByJG\Util\XmlUtil; use stdClass; use Tests\Sample\ModelGetter; use Tests\Sample\ModelPropertyPattern; @@ -180,7 +180,7 @@ public function testGetDomObject() { $this->fill(); - $dom = XmlUtil::CreateXmlDocumentFromStr( + $dom = new XmlDocument( "" . "10" . "20" @@ -191,7 +191,7 @@ public function testGetDomObject() $formatter = (new XmlFormatter($this->object))->raw(); - $this->assertEquals($dom, $formatter); + $this->assertEquals($dom->DOMNode(), $formatter); } public function testGetJson() From 269192130ee9072f502b57598ab8206e8ac418af Mon Sep 17 00:00:00 2001 From: Joao M Date: Mon, 10 Jun 2024 02:25:51 +0000 Subject: [PATCH 05/11] Fix to use with new XmlUtil. --- src/AnyDataset.php | 12 ++++++------ src/Formatter/XmlFormatter.php | 2 +- tests/AnyDatasetTest.php | 2 +- tests/RowTest.php | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/AnyDataset.php b/src/AnyDataset.php index 99b7804..7ad0c8e 100644 --- a/src/AnyDataset.php +++ b/src/AnyDataset.php @@ -4,8 +4,8 @@ use ByJG\AnyDataset\Core\Exception\DatabaseException; use ByJG\AnyDataset\Core\Formatter\XmlFormatter; -use ByJG\Util\File; -use ByJG\Util\XmlDocument; +use ByJG\XmlUtil\File; +use ByJG\XmlUtil\XmlDocument; use InvalidArgumentException; /** @@ -62,7 +62,7 @@ class AnyDataset /** * @param null|string $filename * @throws \ByJG\Serializer\Exception\InvalidArgumentException - * @throws \ByJG\Util\Exception\XmlUtilException + * @throws \ByJG\XmlUtil\Exception\XmlUtilException */ public function __construct($filename = null) { @@ -110,7 +110,7 @@ private function defineSavePath($filename, $closure) * @param string $filepath Path and Filename to be read * @return void * @throws \ByJG\Serializer\Exception\InvalidArgumentException - * @throws \ByJG\Util\Exception\XmlUtilException + * @throws \ByJG\XmlUtil\Exception\XmlUtilException */ private function createFromFile() { @@ -141,7 +141,7 @@ private function createFromFile() * Returns the AnyDataset XML representative structure. * * @return string XML String - * @throws \ByJG\Util\Exception\XmlUtilException + * @throws \ByJG\XmlUtil\Exception\XmlUtilException */ public function xml() { @@ -152,7 +152,7 @@ public function xml() * @param string|null $filename * @return void * @throws DatabaseException - * @throws \ByJG\Util\Exception\XmlUtilException + * @throws \ByJG\XmlUtil\Exception\XmlUtilException */ public function save($filename = null) { diff --git a/src/Formatter/XmlFormatter.php b/src/Formatter/XmlFormatter.php index 57adeff..1232a55 100644 --- a/src/Formatter/XmlFormatter.php +++ b/src/Formatter/XmlFormatter.php @@ -3,7 +3,7 @@ namespace ByJG\AnyDataset\Core\Formatter; use ByJG\AnyDataset\Core\GenericIterator; -use ByJG\Util\XmlDocument; +use ByJG\XmlUtil\XmlDocument; class XmlFormatter extends BaseFormatter { diff --git a/tests/AnyDatasetTest.php b/tests/AnyDatasetTest.php index 5feb119..ea43a2f 100644 --- a/tests/AnyDatasetTest.php +++ b/tests/AnyDatasetTest.php @@ -7,7 +7,7 @@ use ByJG\AnyDataset\Core\Formatter\JsonFormatter; use ByJG\AnyDataset\Core\Formatter\XmlFormatter; use ByJG\AnyDataset\Core\IteratorFilter; -use ByJG\Util\XmlDocument; +use ByJG\XmlUtil\XmlDocument; use PHPUnit\Framework\TestCase; use PHPUnit\Util\Xml; diff --git a/tests/RowTest.php b/tests/RowTest.php index 97d31e5..a3d3f00 100644 --- a/tests/RowTest.php +++ b/tests/RowTest.php @@ -5,7 +5,7 @@ use ByJG\AnyDataset\Core\Formatter\JsonFormatter; use ByJG\AnyDataset\Core\Formatter\XmlFormatter; use ByJG\AnyDataset\Core\Row; -use ByJG\Util\XmlDocument; +use ByJG\XmlUtil\XmlDocument; use PHPUnit\Framework\TestCase; use stdClass; use Tests\Sample\ModelGetter; From 5fec5af4fd8b2fe0d02aee56264387bae5b992b4 Mon Sep 17 00:00:00 2001 From: Joao M Date: Mon, 10 Jun 2024 02:38:29 +0000 Subject: [PATCH 06/11] Fix to use with new XmlUtil. --- src/AnyDataset.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/AnyDataset.php b/src/AnyDataset.php index 7ad0c8e..35a2e06 100644 --- a/src/AnyDataset.php +++ b/src/AnyDataset.php @@ -6,6 +6,8 @@ use ByJG\AnyDataset\Core\Formatter\XmlFormatter; use ByJG\XmlUtil\File; use ByJG\XmlUtil\XmlDocument; +use ByJG\XmlUtil\XmlNode; +use DOMElement; use InvalidArgumentException; /** @@ -121,14 +123,13 @@ private function createFromFile() $rows = $anyDataSet->selectNodes("row"); foreach ($rows as $row) { $sr = new Row(); - $fields = $row->getElementsByTagName("field"); + $fields = XmlNode::instance($row)->selectNodes("field"); + /** @var DOMElement $field */ foreach ($fields as $field) { - $attr = $field->attributes->getNamedItem("name"); - if (is_null($attr) || is_null($attr->nodeValue)) { + if (!$field->hasAttribute("name")) { throw new InvalidArgumentException('Malformed anydataset file ' . basename($this->getFilename())); } - - $sr->addField($attr->nodeValue, $field->nodeValue); + $sr->addField($field->getAttribute("name"), $field->nodeValue); } $sr->acceptChanges(); $this->collection[] = $sr; @@ -141,9 +142,8 @@ private function createFromFile() * Returns the AnyDataset XML representative structure. * * @return string XML String - * @throws \ByJG\XmlUtil\Exception\XmlUtilException */ - public function xml() + public function xml(): string { return (new XmlFormatter($this->getIterator()))->toText(); } From 2e7b8d6a0c90fe8deb4abb55a27facba0cf97f48 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Wed, 11 Sep 2024 18:06:16 -0500 Subject: [PATCH 07/11] Add types to methods --- .github/FUNDING.yml | 3 ++ composer.json | 2 +- src/AnyDataset.php | 67 +++++++++++++--------------- src/AnyIterator.php | 6 +-- src/Formatter/BaseFormatter.php | 12 ++--- src/Formatter/FormatterInterface.php | 6 +-- src/Formatter/JsonFormatter.php | 7 ++- src/Formatter/XmlFormatter.php | 13 +++--- src/GenericIterator.php | 11 ++--- src/IteratorInterface.php | 8 ++-- src/Row.php | 63 +++++++++++++------------- src/RowOutput.php | 16 +++---- 12 files changed, 108 insertions(+), 106 deletions(-) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..3a9251f --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms + +github: byjg diff --git a/composer.json b/composer.json index c5513e4..82eeba3 100644 --- a/composer.json +++ b/composer.json @@ -15,11 +15,11 @@ "minimum-stability": "dev", "require": { "php": ">=8.1", + "ext-dom": "*", "byjg/xmlutil": "^5.0", "byjg/serializer": "^5.0" }, "suggest": { - "ext-dom": "*" }, "require-dev": { "phpunit/phpunit": "^9.6", diff --git a/src/AnyDataset.php b/src/AnyDataset.php index 35a2e06..12d0f7f 100644 --- a/src/AnyDataset.php +++ b/src/AnyDataset.php @@ -4,9 +4,12 @@ use ByJG\AnyDataset\Core\Exception\DatabaseException; use ByJG\AnyDataset\Core\Formatter\XmlFormatter; +use ByJG\XmlUtil\Exception\FileException; +use ByJG\XmlUtil\Exception\XmlUtilException; use ByJG\XmlUtil\File; use ByJG\XmlUtil\XmlDocument; use ByJG\XmlUtil\XmlNode; +use Closure; use DOMElement; use InvalidArgumentException; @@ -51,22 +54,22 @@ class AnyDataset * * @var Row[] */ - private $collection; + private array $collection; /** * Current node anydataset works * @var int */ - private $currentRow; + private int $currentRow; private ?File $file; /** - * @param null|string $filename - * @throws \ByJG\Serializer\Exception\InvalidArgumentException - * @throws \ByJG\XmlUtil\Exception\XmlUtilException + * @param string|null $filename + * @throws FileException + * @throws XmlUtilException */ - public function __construct($filename = null) + public function __construct(?string $filename = null) { $this->collection = array(); $this->currentRow = -1; @@ -82,7 +85,7 @@ public function __construct($filename = null) /** * @return string|null */ - public function getFilename() + public function getFilename(): ?string { return $this->file->getFilename(); } @@ -92,12 +95,13 @@ public function getFilename() * @param string|null $filename * @param mixed $closure * @return void + * @throws FileException */ - private function defineSavePath($filename, $closure) + private function defineSavePath(?string $filename, Closure $closure): void { if (!is_null($filename)) { $ext = pathinfo($filename, PATHINFO_EXTENSION); - if (empty($ext) && substr($filename, 0, 6) !== "php://") { + if (empty($ext) && !str_starts_with($filename, "php://")) { $filename .= '.anydata.xml'; } $this->file = new File($filename, allowNotFound: true); @@ -109,12 +113,10 @@ private function defineSavePath($filename, $closure) /** * Private method used to read and populate anydataset class from specified file * - * @param string $filepath Path and Filename to be read * @return void - * @throws \ByJG\Serializer\Exception\InvalidArgumentException - * @throws \ByJG\XmlUtil\Exception\XmlUtilException + * @throws XmlUtilException */ - private function createFromFile() + private function createFromFile(): void { if (file_exists($this->getFilename())) { $anyDataSet = new XmlDocument($this->file); @@ -152,9 +154,9 @@ public function xml(): string * @param string|null $filename * @return void * @throws DatabaseException - * @throws \ByJG\XmlUtil\Exception\XmlUtilException + * @throws FileException */ - public function save($filename = null) + public function save(?string $filename = null): void { $this->defineSavePath($filename, function () use ($filename){ if (is_null($this->file)) { @@ -168,11 +170,10 @@ public function save($filename = null) /** * Append one row to AnyDataset. * - * @param Row|array|\stdClass|object|null $singleRow + * @param Row|array $singleRow * @return void - * @throws \ByJG\Serializer\Exception\InvalidArgumentException */ - public function appendRow($singleRow = []) + public function appendRow(Row|array $singleRow = []): void { if (!empty($singleRow)) { if ($singleRow instanceof Row) { @@ -196,9 +197,8 @@ public function appendRow($singleRow = []) * * @param GenericIterator $iterator * @return void - * @throws \ByJG\Serializer\Exception\InvalidArgumentException */ - public function import($iterator) + public function import(GenericIterator $iterator): void { foreach ($iterator as $singleRow) { $this->appendRow($singleRow); @@ -209,11 +209,9 @@ public function import($iterator) * Insert one row before specified position. * * @param int $rowNumber - * @param Row|array|\stdClass|object $row - * @return void - * @throws \ByJG\Serializer\Exception\InvalidArgumentException + * @param Row|array $row */ - public function insertRowBefore($rowNumber, $row) + public function insertRowBefore(int $rowNumber, Row|array $row): void { if ($rowNumber > count($this->collection)) { $this->appendRow($row); @@ -236,11 +234,11 @@ public function insertRowBefore($rowNumber, $row) /** * - * @param mixed $row + * @param int|Row|null $row * @return void * @throws \ByJG\Serializer\Exception\InvalidArgumentException */ - public function removeRow($row = null) + public function removeRow(int|Row $row = null): void { if (is_null($row)) { $row = $this->currentRow; @@ -270,9 +268,8 @@ public function removeRow($row = null) * @param string $name - Field name * @param string $value - Field value * @return void - * @throws \ByJG\Serializer\Exception\InvalidArgumentException */ - public function addField($name, $value) + public function addField(string $name, mixed $value): void { if ($this->currentRow < 0) { $this->appendRow(); @@ -282,10 +279,10 @@ public function addField($name, $value) /** * Get an Iterator filtered by an IteratorFilter - * @param IteratorFilter $itf - * @return GenericIterator + * @param IteratorFilter|null $itf + * @return GenericIterator|AnyIterator */ - public function getIterator(IteratorFilter $itf = null) + public function getIterator(IteratorFilter $itf = null): GenericIterator|AnyIterator { if (is_null($itf)) { return new AnyIterator($this->collection); @@ -298,10 +295,10 @@ public function getIterator(IteratorFilter $itf = null) * Undocumented function * * @param string $fieldName - * @param IteratorFilter $itf + * @param IteratorFilter|null $itf * @return array */ - public function getArray($fieldName, $itf = null) + public function getArray(string $fieldName, IteratorFilter $itf = null): array { $iterator = $this->getIterator($itf); $result = array(); @@ -316,7 +313,7 @@ public function getArray($fieldName, $itf = null) * @param string $field * @return void */ - public function sort($field) + public function sort(string $field): void { if (count($this->collection) == 0) { return; @@ -330,7 +327,7 @@ public function sort($field) * @param string $field * @return array */ - protected function quickSortExec($seq, $field) + protected function quickSortExec(array $seq, string $field): array { if (!count($seq)) { return $seq; diff --git a/src/AnyIterator.php b/src/AnyIterator.php index e2fb5e8..b6180cc 100644 --- a/src/AnyIterator.php +++ b/src/AnyIterator.php @@ -34,7 +34,7 @@ public function __construct($list) /** * @inheritDoc */ - public function count() + public function count(): int { return count($this->list); } @@ -42,7 +42,7 @@ public function count() /** * @inheritDoc */ - public function hasNext() + public function hasNext(): bool { return ($this->curRow < $this->count()); } @@ -50,7 +50,7 @@ public function hasNext() /** * @inheritDoc */ - public function moveNext() + public function moveNext(): Row|null { if (!$this->hasNext()) { return null; diff --git a/src/Formatter/BaseFormatter.php b/src/Formatter/BaseFormatter.php index 9adcb28..03613db 100644 --- a/src/Formatter/BaseFormatter.php +++ b/src/Formatter/BaseFormatter.php @@ -3,7 +3,7 @@ namespace ByJG\AnyDataset\Core\Formatter; use ByJG\AnyDataset\Core\GenericIterator; -use \ByJG\AnyDataset\Core\Row; +use ByJG\AnyDataset\Core\Row; use InvalidArgumentException; abstract class BaseFormatter implements FormatterInterface @@ -11,22 +11,22 @@ abstract class BaseFormatter implements FormatterInterface /** * @var GenericIterator|Row */ - protected $object; + protected Row|GenericIterator $object; /** * @inheritDoc */ - abstract public function raw(); + abstract public function raw(): mixed; /** * @inheritDoc */ - abstract public function toText(); + abstract public function toText(): string; /** * @inheritDoc */ - public function saveToFile($filename) + public function saveToFile(string $filename): void { if (empty($filename)) { throw new InvalidArgumentException("Filename cannot be empty"); @@ -37,7 +37,7 @@ public function saveToFile($filename) /** * @param GenericIterator|Row $object */ - public function __construct($object) + public function __construct(GenericIterator|Row $object) { if (!($object instanceof GenericIterator) && !($object instanceof Row)) { throw new InvalidArgumentException("Constructor must have a GenericIterator or Row instance in the argument"); diff --git a/src/Formatter/FormatterInterface.php b/src/Formatter/FormatterInterface.php index 8184692..6ff6994 100644 --- a/src/Formatter/FormatterInterface.php +++ b/src/Formatter/FormatterInterface.php @@ -9,14 +9,14 @@ interface FormatterInterface * * @return mixed */ - public function raw(); + public function raw(): mixed; /** * Return the object transformed to string. * * @return string */ - public function toText(); + public function toText(): string; /** * Save the contents to a file @@ -24,5 +24,5 @@ public function toText(); * @param string $filename * @return void */ - public function saveToFile($filename); + public function saveToFile(string $filename): void; } \ No newline at end of file diff --git a/src/Formatter/JsonFormatter.php b/src/Formatter/JsonFormatter.php index 1f4b8d0..b74fd9b 100644 --- a/src/Formatter/JsonFormatter.php +++ b/src/Formatter/JsonFormatter.php @@ -3,21 +3,24 @@ namespace ByJG\AnyDataset\Core\Formatter; use ByJG\AnyDataset\Core\GenericIterator; +use ByJG\Serializer\Exception\InvalidArgumentException; class JsonFormatter extends BaseFormatter { /** * @inheritDoc + * @throws InvalidArgumentException */ - public function raw() + public function raw(): mixed { return json_decode($this->toText()); } /** * @inheritDoc + * @throws InvalidArgumentException */ - public function toText() + public function toText(): string { if ($this->object instanceof GenericIterator) { return json_encode($this->object->toArray()); diff --git a/src/Formatter/XmlFormatter.php b/src/Formatter/XmlFormatter.php index 1232a55..d552a19 100644 --- a/src/Formatter/XmlFormatter.php +++ b/src/Formatter/XmlFormatter.php @@ -4,6 +4,7 @@ use ByJG\AnyDataset\Core\GenericIterator; use ByJG\XmlUtil\XmlDocument; +use ByJG\XmlUtil\XmlNode; class XmlFormatter extends BaseFormatter { @@ -11,9 +12,9 @@ class XmlFormatter extends BaseFormatter * Return a DOMNode representing AnyDataset * * @param array $collection - * @return XmlDocument + * @return XmlNode */ - protected function anydatasetXml($collection) + protected function anydatasetXml(array $collection): XmlNode { $anyDataSet = new XmlDocument(""); foreach ($collection as $sr) { @@ -25,9 +26,9 @@ protected function anydatasetXml($collection) /** * @param array $row - * @return XmlDocument + * @return XmlNode */ - protected function rowXml($row, XmlDocument $parentDocument = null) + protected function rowXml(array $row, XmlDocument $parentDocument = null): XmlNode { if (!empty($parentDocument)) { $node = $parentDocument->appendChild('row'); @@ -47,7 +48,7 @@ protected function rowXml($row, XmlDocument $parentDocument = null) /** * @inheritDoc */ - public function raw() + public function raw(): mixed { if ($this->object instanceof GenericIterator) { return $this->anydatasetXml($this->object->toArray())->DOMDocument(); @@ -58,7 +59,7 @@ public function raw() /** * @inheritDoc */ - public function toText() + public function toText(): string { return $this->raw()->saveXML(); } diff --git a/src/GenericIterator.php b/src/GenericIterator.php index 78bfa57..63d97f3 100644 --- a/src/GenericIterator.php +++ b/src/GenericIterator.php @@ -10,17 +10,17 @@ abstract class GenericIterator implements IteratorInterface, Iterator /** * @inheritDoc */ - abstract public function hasNext(); + abstract public function hasNext(): bool; /** * @inheritDoc */ - abstract public function moveNext(); + abstract public function moveNext(): Row|null; /** * @inheritDoc */ - abstract public function count(); + abstract public function count(): int; /** * @inheritDoc @@ -30,9 +30,10 @@ abstract public function key(); /** * @inheritDoc - * @throws \ByJG\Serializer\Exception\InvalidArgumentException + * @param array $fields + * @return array */ - public function toArray($fields = []) + public function toArray(array $fields = []): array { $retArray = []; diff --git a/src/IteratorInterface.php b/src/IteratorInterface.php index c686876..0e37137 100644 --- a/src/IteratorInterface.php +++ b/src/IteratorInterface.php @@ -10,21 +10,21 @@ interface IteratorInterface * * @return bool Return True if is possible get one or more records. */ - public function hasNext(); + public function hasNext(): bool; /** * Get the next record.Return a Row object * * @return Row|null */ - public function moveNext(); + public function moveNext(): Row|null; /** * Get the record count. Some implementations may have return -1. * * @return int */ - public function count(); + public function count(): int; /** * Get an array of the iterator @@ -32,5 +32,5 @@ public function count(); * @param array $fields * @return array */ - public function toArray($fields = []); + public function toArray(array $fields = []): array; } diff --git a/src/Row.php b/src/Row.php index 39a754d..0ff52ac 100644 --- a/src/Row.php +++ b/src/Row.php @@ -10,25 +10,24 @@ class Row /** * @var array */ - private $row = []; + private array $row = []; /** * @var array */ - private $originalRow = []; + private array $originalRow = []; /** * @var boolean */ - protected $fieldNameCaseSensitive = true; + protected bool $fieldNameCaseSensitive = true; /** * Row constructor - * - * @param Row|array|\stdClass|object $instance - * @throws \ByJG\Serializer\Exception\InvalidArgumentException + * + * @param object|array $instance */ - public function __construct($instance = []) + public function __construct(object|array $instance = []) { if (is_array($instance)) { $this->row = $instance; @@ -42,10 +41,10 @@ public function __construct($instance = []) /** * Add a string field to row * @param string $name - * @param string|array|null $value + * @param array|string|null $value * @return void */ - public function addField($name, $value) + public function addField(string $name, array|string|null $value): void { $name = $this->getHydratedFieldName($name); @@ -60,10 +59,10 @@ public function addField($name, $value) /** * @param string $name - Field name - * @return null|string + * @return mixed * @desc et the string value from a field name */ - public function get($name) + public function get(string $name): mixed { $name = $this->getHydratedFieldName($name); @@ -85,7 +84,7 @@ public function get($name) * @param string $fieldName * @return array */ - public function getAsArray($fieldName) + public function getAsArray(string $fieldName): array { $fieldName = $this->getHydratedFieldName($fieldName); @@ -106,7 +105,7 @@ public function getAsArray($fieldName) * Return all Field Names from current Row * @return array */ - public function getFieldNames() + public function getFieldNames(): array { return array_keys($this->row); } @@ -117,7 +116,7 @@ public function getFieldNames() * @param string $value * @return void */ - public function set($name, $value) + public function set(string $name, mixed $value): void { $name = $this->getHydratedFieldName($name); @@ -132,9 +131,8 @@ public function set($name, $value) * Remove specified field name from row. * * @param string $fieldName - * @return null */ - public function removeField($fieldName) + public function removeField(string $fieldName): void { $fieldName = $this->getHydratedFieldName($fieldName); @@ -150,7 +148,7 @@ public function removeField($fieldName) * @param mixed $value * @return void */ - public function removeValue($fieldName, $value) + public function removeValue(string $fieldName, mixed $value): void { $fieldName = $this->getHydratedFieldName($fieldName); @@ -173,12 +171,11 @@ public function removeValue($fieldName, $value) /** * Update a specific field and specific value with new value * - * @param String $fieldName - * @param String $oldvalue - * @param String $newvalue - * @return void + * @param string $fieldName + * @param mixed $oldvalue + * @param mixed $newvalue */ - public function replaceValue($fieldName, $oldvalue, $newvalue) + public function replaceValue(string $fieldName, mixed $oldvalue, mixed $newvalue): void { $fieldName = $this->getHydratedFieldName($fieldName); @@ -200,7 +197,7 @@ public function replaceValue($fieldName, $oldvalue, $newvalue) * @param array|null $fields * @return array */ - public function toArray($fields = []) + public function toArray(?array $fields = []): array { if (empty($fields)) { return $this->row; @@ -213,7 +210,7 @@ public function toArray($fields = []) /** * @return array */ - public function getAsRaw() + public function getAsRaw(): array { return $this->originalRow; } @@ -222,7 +219,7 @@ public function getAsRaw() * * @return bool */ - public function hasChanges() + public function hasChanges(): bool { return ($this->row != $this->originalRow); } @@ -230,7 +227,7 @@ public function hasChanges() /** * @return void */ - public function acceptChanges() + public function acceptChanges(): void { $this->originalRow = $this->row; } @@ -238,7 +235,7 @@ public function acceptChanges() /** * @return void */ - public function rejectChanges() + public function rejectChanges(): void { $this->row = $this->originalRow; } @@ -248,10 +245,10 @@ public function rejectChanges() * * @param Row $obj * @param string $propName - * @param string $value + * @param mixed $value * @return void */ - protected function setPropValue($obj, $propName, $value) + protected function setPropValue(Row $obj, string $propName, mixed $value): void { $obj->set($propName, $value); } @@ -260,7 +257,7 @@ protected function setPropValue($obj, $propName, $value) * @param string $name * @return bool */ - public function fieldExists($name) + public function fieldExists(string $name): bool { return isset($this->row[$this->getHydratedFieldName($name)]); } @@ -268,7 +265,7 @@ public function fieldExists($name) /** * @return void */ - public function enableFieldNameCaseInSensitive() + public function enableFieldNameCaseInSensitive(): void { $this->row = array_change_key_case($this->row, CASE_LOWER); $this->originalRow = array_change_key_case($this->originalRow, CASE_LOWER); @@ -278,7 +275,7 @@ public function enableFieldNameCaseInSensitive() /** * @return bool */ - public function isFieldNameCaseSensitive() + public function isFieldNameCaseSensitive(): bool { return $this->fieldNameCaseSensitive; } @@ -287,7 +284,7 @@ public function isFieldNameCaseSensitive() * @param string $name * @return string */ - protected function getHydratedFieldName($name) + protected function getHydratedFieldName(string $name): string { if (!$this->isFieldNameCaseSensitive()) { return strtolower($name); diff --git a/src/RowOutput.php b/src/RowOutput.php index d2a828f..6326a32 100644 --- a/src/RowOutput.php +++ b/src/RowOutput.php @@ -11,12 +11,12 @@ class RowOutput /** * @var array */ - protected $fieldList = []; + protected array $fieldList = []; /** * @return RowOutput */ - public static function getInstance() + public static function getInstance(): RowOutput { return new RowOutput(); } @@ -26,7 +26,7 @@ public static function getInstance() * @param string $field * @return mixed */ - public function print($row, $field) + public function print(Row $row, string $field): mixed { if (!isset($this->fieldList[$field])) { return $row->get($field); @@ -46,7 +46,7 @@ public function print($row, $field) * @param Row $row * @return Row */ - public function apply($row) + public function apply(Row $row): Row { $newRow = new Row(); @@ -66,7 +66,7 @@ public function apply($row) * @param string $pattern * @return string */ - protected function formatPattern($row, $field, $pattern) + protected function formatPattern(Row $row, string $field, string $pattern): string { $rowParsed = $row->toArray(); foreach ($rowParsed as $key => $value) { @@ -85,7 +85,7 @@ protected function formatPattern($row, $field, $pattern) * @param mixed $closure * @return string */ - protected function formatCustom($row, $field, $closure) + protected function formatCustom(Row $row, string $field, Closure $closure): string { return $closure($row, $field, $row->get($field)); } @@ -95,7 +95,7 @@ protected function formatCustom($row, $field, $closure) * @param string $pattern * @return RowOutput */ - public function addFormat($field, $pattern) + public function addFormat(string $field, string $pattern): static { $this->fieldList[$field] = [ self::FORMAT, $pattern ]; return $this; @@ -106,7 +106,7 @@ public function addFormat($field, $pattern) * @param Closure $closure * @return RowOutput */ - public function addCustomFormat($field, Closure $closure) + public function addCustomFormat(string $field, Closure $closure): static { $this->fieldList[$field] = [ self::CUSTOM, $closure ]; return $this; From 106a6a42757a46ffd7c894930f08fb97d1d459da Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Wed, 11 Sep 2024 18:41:59 -0500 Subject: [PATCH 08/11] Fix PSalm errors --- .run/PSalm.run.xml | 5 +++++ .run/Test Project.run.xml | 6 ++++++ src/AnyDataset.php | 17 +++++------------ src/RowOutput.php | 4 ++-- 4 files changed, 18 insertions(+), 14 deletions(-) create mode 100644 .run/PSalm.run.xml create mode 100644 .run/Test Project.run.xml diff --git a/.run/PSalm.run.xml b/.run/PSalm.run.xml new file mode 100644 index 0000000..bd119ce --- /dev/null +++ b/.run/PSalm.run.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/.run/Test Project.run.xml b/.run/Test Project.run.xml new file mode 100644 index 0000000..f595dd3 --- /dev/null +++ b/.run/Test Project.run.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/AnyDataset.php b/src/AnyDataset.php index 12d0f7f..2431afd 100644 --- a/src/AnyDataset.php +++ b/src/AnyDataset.php @@ -175,20 +175,13 @@ public function save(?string $filename = null): void */ public function appendRow(Row|array $singleRow = []): void { - if (!empty($singleRow)) { - if ($singleRow instanceof Row) { - $this->collection[] = $singleRow; - $singleRow->acceptChanges(); - } elseif (is_array($singleRow)) { - $this->collection[] = new Row($singleRow); - } else { - throw new InvalidArgumentException("You must pass an array or a Row object"); - } - } else { + if (empty($singleRow)) { $singleRow = new Row(); - $this->collection[] = $singleRow; - $singleRow->acceptChanges(); + } elseif (is_array($singleRow)) { + $singleRow = new Row($singleRow); } + + $this->collection[] = $singleRow; $this->currentRow = count($this->collection) - 1; } diff --git a/src/RowOutput.php b/src/RowOutput.php index 6326a32..bbe3cee 100644 --- a/src/RowOutput.php +++ b/src/RowOutput.php @@ -93,7 +93,7 @@ protected function formatCustom(Row $row, string $field, Closure $closure): stri /** * @param string $field * @param string $pattern - * @return RowOutput + * @return static */ public function addFormat(string $field, string $pattern): static { @@ -104,7 +104,7 @@ public function addFormat(string $field, string $pattern): static /** * @param string $field * @param Closure $closure - * @return RowOutput + * @return static */ public function addCustomFormat(string $field, Closure $closure): static { From d0bb1f02ed2deee75d24577b4675f8cf44a58ccb Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Fri, 13 Sep 2024 14:56:05 -0500 Subject: [PATCH 09/11] Convert Relation to Enum. --- src/Enum/Relation.php | 64 ++++++---------------------- src/IteratorFilter.php | 12 +++--- src/IteratorFilterFormatter.php | 6 ++- src/IteratorFilterXPathFormatter.php | 2 +- 4 files changed, 23 insertions(+), 61 deletions(-) diff --git a/src/Enum/Relation.php b/src/Enum/Relation.php index f86cbf2..d4d4c45 100644 --- a/src/Enum/Relation.php +++ b/src/Enum/Relation.php @@ -7,56 +7,16 @@ * * Use this in AddRelation method. */ -class Relation +enum Relation { - - /** - * "Equal" relational operator - */ - const EQUAL = 0; - - /** - * "Less than" relational operator - */ - const LESS_THAN = 1; - - /** - * "Greater than" relational operator - */ - const GREATER_THAN = 2; - - /** - * "Less or Equal Than" relational operator - */ - const LESS_OR_EQUAL_THAN = 3; - - /** - * "Greater or equal than" relational operator - */ - const GREATER_OR_EQUAL_THAN = 4; - - /** - * "Not equal" relational operator - */ - const NOT_EQUAL = 5; - - /** - * "Starts with" unary comparator - */ - const STARTS_WITH = 6; - - /** - * "Contains" unary comparator - */ - const CONTAINS = 7; - - /** - * "In" unary comparator - */ - const IN = 8; - - /** - * "Not In" unary comparator - */ - const NOT_IN = 9; -} + case EQUAL; + case LESS_THAN; + case GREATER_THAN; + case LESS_OR_EQUAL_THAN; + case GREATER_OR_EQUAL_THAN; + case NOT_EQUAL; + case STARTS_WITH; + case CONTAINS; + case IN; + case NOT_IN; +} \ No newline at end of file diff --git a/src/IteratorFilter.php b/src/IteratorFilter.php index 3d1c2e7..60b2a30 100644 --- a/src/IteratorFilter.php +++ b/src/IteratorFilter.php @@ -107,12 +107,12 @@ private function evalString(Row $singleRow): bool /** * @param string $name Field name - * @param int $relation Relation enum - * @param array|string $value Field string value + * @param Relation $relation Relation enum + * @param mixed $value Field string value * @return static * @desc Add a single string comparison to filter. */ - public function addRelation(string $name, int $relation, mixed $value): static + public function addRelation(string $name, Relation $relation, mixed $value): static { $this->filters[] = [" and ", $name, $relation, $value]; return $this; @@ -120,12 +120,12 @@ public function addRelation(string $name, int $relation, mixed $value): static /** * @param string $name Field name - * @param int $relation Relation enum - * @param array|string $value Field string value + * @param Relation $relation Relation enum + * @param mixed $value Field string value * @return static * @desc Add a single string comparison to filter. This comparison use the OR operator. */ - public function addRelationOr(string $name, int $relation, mixed $value): static + public function addRelationOr(string $name, Relation $relation, mixed $value): static { $this->filters[] = [" or ", $name, $relation, $value]; return $this; diff --git a/src/IteratorFilterFormatter.php b/src/IteratorFilterFormatter.php index 3db783d..064d4fa 100644 --- a/src/IteratorFilterFormatter.php +++ b/src/IteratorFilterFormatter.php @@ -2,6 +2,8 @@ namespace ByJG\AnyDataset\Core; +use ByJG\AnyDataset\Core\Enum\Relation; + abstract class IteratorFilterFormatter { @@ -9,12 +11,12 @@ abstract class IteratorFilterFormatter * Get Relation * * @param string $name - * @param string $relation + * @param Relation $relation * @param array|string $value * @param array $param * @return string */ - abstract public function getRelation(string $name, string $relation, mixed $value, array &$param): string; + abstract public function getRelation(string $name, Relation $relation, mixed $value, array &$param): string; /** * Get formatted field diff --git a/src/IteratorFilterXPathFormatter.php b/src/IteratorFilterXPathFormatter.php index c2df862..aaf77f0 100644 --- a/src/IteratorFilterXPathFormatter.php +++ b/src/IteratorFilterXPathFormatter.php @@ -24,7 +24,7 @@ public function format(array $filters, string $tableName = null, array &$params /** * @inheritDoc */ - public function getRelation(string $name, string $relation, mixed $value, array &$param): string + public function getRelation(string $name, Relation $relation, mixed $value, array &$param): string { $str = is_numeric($value) ? "" : "'"; $field = "field[@name='" . $name . "'] "; From 1ab492b495e3ef05469b41fe9d9b641b6e59e052 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sat, 14 Sep 2024 12:47:51 -0500 Subject: [PATCH 10/11] Renamed IteratorFilter::addRelation to IteratorFilter::and; Renamed IteratorFilter::addRelationOr to IteratorFilter::or; --- example.php | 2 +- src/IteratorFilter.php | 26 +++++++++++++++++++++++ tests/AnyDatasetTest.php | 3 +-- tests/IteratorFilterAnydatasetTest.php | 29 +++++++++++++------------- tests/IteratorFilterXPathTest.php | 23 ++++++++++---------- 5 files changed, 53 insertions(+), 30 deletions(-) diff --git a/example.php b/example.php index 03125c6..c9cb25c 100644 --- a/example.php +++ b/example.php @@ -10,7 +10,7 @@ $filter = new \ByJG\AnyDataset\Core\IteratorFilter(); -$filter->addRelation("field1", \ByJG\AnyDataset\Core\Enum\Relation::EQUAL, 10); +$filter->and("field1", \ByJG\AnyDataset\Core\Enum\Relation::EQUAL, 10); $iterator2 = $dataset->getIterator($filter); $iterator->toArray(); diff --git a/src/IteratorFilter.php b/src/IteratorFilter.php index 60b2a30..2cafb4d 100644 --- a/src/IteratorFilter.php +++ b/src/IteratorFilter.php @@ -111,8 +111,21 @@ private function evalString(Row $singleRow): bool * @param mixed $value Field string value * @return static * @desc Add a single string comparison to filter. + * @deprecated use and() instead */ public function addRelation(string $name, Relation $relation, mixed $value): static + { + return $this->and($name, $relation, $value); + } + + /** + * @param string $name Field name + * @param Relation $relation Relation enum + * @param mixed $value Field string value + * @return static + * @desc Add a single string comparison to filter. + */ + public function and(string $name, Relation $relation, mixed $value): static { $this->filters[] = [" and ", $name, $relation, $value]; return $this; @@ -124,8 +137,21 @@ public function addRelation(string $name, Relation $relation, mixed $value): sta * @param mixed $value Field string value * @return static * @desc Add a single string comparison to filter. This comparison use the OR operator. + * @deprecated use or() instead */ public function addRelationOr(string $name, Relation $relation, mixed $value): static + { + return $this->or($name, $relation, $value); + } + + /** + * @param string $name Field name + * @param Relation $relation Relation enum + * @param mixed $value Field string value + * @return static + * @desc Add a single string comparison to filter. This comparison use the OR operator. + */ + public function or(string $name, Relation $relation, mixed $value): static { $this->filters[] = [" or ", $name, $relation, $value]; return $this; diff --git a/tests/AnyDatasetTest.php b/tests/AnyDatasetTest.php index ea43a2f..996a618 100644 --- a/tests/AnyDatasetTest.php +++ b/tests/AnyDatasetTest.php @@ -9,7 +9,6 @@ use ByJG\AnyDataset\Core\IteratorFilter; use ByJG\XmlUtil\XmlDocument; use PHPUnit\Framework\TestCase; -use PHPUnit\Util\Xml; class AnyDatasetTest extends TestCase { @@ -306,7 +305,7 @@ public function testIteratorFilter() $this->object->appendRow(['name' => 'jg jr', 'age' => 4]); $filter = IteratorFilter::getInstance() - ->addRelation("age", Relation::LESS_THAN, 40); + ->and("age", Relation::LESS_THAN, 40); $this->assertEquals([ ['name' => 'jf', 'age' => 15], diff --git a/tests/IteratorFilterAnydatasetTest.php b/tests/IteratorFilterAnydatasetTest.php index 97e8447..57e72a2 100644 --- a/tests/IteratorFilterAnydatasetTest.php +++ b/tests/IteratorFilterAnydatasetTest.php @@ -2,10 +2,9 @@ namespace Tests\AnyDataset\Dataset; +use ByJG\AnyDataset\Core\Enum\Relation; use ByJG\AnyDataset\Core\IteratorFilter; -use ByJG\AnyDataset\Core\IteratorFilterXPathFormatter; use ByJG\AnyDataset\Core\Row; -use ByJG\AnyDataset\Core\Enum\Relation; use PHPUnit\Framework\TestCase; class IteratorFilterAnydatasetTest extends TestCase @@ -65,63 +64,63 @@ public function testMatch() $this->assertEquals($collection, $this->object->match($collection)); - $this->object->addRelation('field2', Relation::EQUAL, 'other2'); + $this->object->and('field2', Relation::EQUAL, 'other2'); $this->assertEquals([$row2], $this->object->match($collection)); - $this->object->addRelationOr('field', Relation::EQUAL, 'last1'); + $this->object->or('field', Relation::EQUAL, 'last1'); $this->assertEquals([$row2, $row3], $this->object->match($collection)); //------------------------ $this->object = new IteratorFilter(); - $this->object->addRelation('field', Relation::EQUAL, 'last1'); - $this->object->addRelation('field2', Relation::EQUAL, 'last2'); + $this->object->and('field', Relation::EQUAL, 'last1'); + $this->object->and('field2', Relation::EQUAL, 'last2'); $this->assertEquals([$row3], $this->object->match($collection)); // Test Greater Than $this->object = new IteratorFilter(); - $this->object->addRelation('val', Relation::GREATER_THAN, 50); + $this->object->and('val', Relation::GREATER_THAN, 50); $this->assertEquals([$row2], $this->object->match($collection)); // Test Less Than $this->object = new IteratorFilter(); - $this->object->addRelation('val', Relation::LESS_THAN, 50); + $this->object->and('val', Relation::LESS_THAN, 50); $this->assertEquals([$row3, $row4], $this->object->match($collection)); // Test Greater or Equal Than $this->object = new IteratorFilter(); - $this->object->addRelation('val', Relation::GREATER_OR_EQUAL_THAN, 50); + $this->object->and('val', Relation::GREATER_OR_EQUAL_THAN, 50); $this->assertEquals([$row1, $row2], $this->object->match($collection)); // Test Less or Equal Than $this->object = new IteratorFilter(); - $this->object->addRelation('val', Relation::LESS_OR_EQUAL_THAN, 50); + $this->object->and('val', Relation::LESS_OR_EQUAL_THAN, 50); $this->assertEquals([$row1, $row3, $row4], $this->object->match($collection)); // Test Not Equal $this->object = new IteratorFilter(); - $this->object->addRelation('val', Relation::NOT_EQUAL, 50); + $this->object->and('val', Relation::NOT_EQUAL, 50); $this->assertEquals([$row2, $row3, $row4], $this->object->match($collection)); // Test Starts With $this->object = new IteratorFilter(); - $this->object->addRelation('field', Relation::STARTS_WITH, 'la'); + $this->object->and('field', Relation::STARTS_WITH, 'la'); $this->assertEquals([$row3], $this->object->match($collection)); // Test Contains $this->object = new IteratorFilter(); - $this->object->addRelation('field', Relation::CONTAINS, '1'); + $this->object->and('field', Relation::CONTAINS, '1'); $this->assertEquals([$row1, $row2, $row3], $this->object->match($collection)); // Test In $this->object = new IteratorFilter(); - $this->object->addRelation('val', Relation::IN, [10, 30, 50]); + $this->object->and('val', Relation::IN, [10, 30, 50]); $this->assertEquals([$row1, $row3, $row4], $this->object->match($collection)); // Test Not In $this->object = new IteratorFilter(); - $this->object->addRelation('val', Relation::NOT_IN, [10, 30, 50]); + $this->object->and('val', Relation::NOT_IN, [10, 30, 50]); $this->assertEquals([$row2], $this->object->match($collection)); } diff --git a/tests/IteratorFilterXPathTest.php b/tests/IteratorFilterXPathTest.php index f7289f9..67d8014 100644 --- a/tests/IteratorFilterXPathTest.php +++ b/tests/IteratorFilterXPathTest.php @@ -2,10 +2,9 @@ namespace Tests; +use ByJG\AnyDataset\Core\Enum\Relation; use ByJG\AnyDataset\Core\IteratorFilter; use ByJG\AnyDataset\Core\IteratorFilterXPathFormatter; -use ByJG\AnyDataset\Core\Row; -use ByJG\AnyDataset\Core\Enum\Relation; use PHPUnit\Framework\TestCase; class IteratorFilterXPathTest extends TestCase @@ -32,19 +31,19 @@ public function testGetXPath() $this->object->format(new IteratorFilterXPathFormatter()) ); - $this->object->addRelation('field', Relation::EQUAL, 'test'); + $this->object->and('field', Relation::EQUAL, 'test'); $this->assertEquals( "/anydataset/row[field[@name='field'] = 'test' ]", $this->object->format(new IteratorFilterXPathFormatter()) ); - $this->object->addRelation('field2', Relation::GREATER_OR_EQUAL_THAN, 'test2'); + $this->object->and('field2', Relation::GREATER_OR_EQUAL_THAN, 'test2'); $this->assertEquals( "/anydataset/row[field[@name='field'] = 'test' and field[@name='field2'] >= 'test2' ]", $this->object->format(new IteratorFilterXPathFormatter()) ); - $this->object->addRelation('field3', Relation::CONTAINS, 'test3'); + $this->object->and('field3', Relation::CONTAINS, 'test3'); $this->assertEquals( "/anydataset/row[field[@name='field'] = 'test' and field[@name='field2'] >= 'test2' and contains(field[@name='field3'] , 'test3' ) ]", $this->object->format(new IteratorFilterXPathFormatter()) @@ -53,8 +52,8 @@ public function testGetXPath() public function testAddRelationOr() { - $this->object->addRelation('field', Relation::EQUAL, 'test'); - $this->object->addRelationOr('field2', Relation::EQUAL, 'test2'); + $this->object->and('field', Relation::EQUAL, 'test'); + $this->object->or('field2', Relation::EQUAL, 'test2'); $this->assertEquals( "/anydataset/row[field[@name='field'] = 'test' or field[@name='field2'] = 'test2' ]", $this->object->format(new IteratorFilterXPathFormatter()) @@ -64,10 +63,10 @@ public function testAddRelationOr() public function testGroup() { $this->object->startGroup(); - $this->object->addRelation('field', Relation::EQUAL, 'test'); - $this->object->addRelation('field2', Relation::EQUAL, 'test2'); + $this->object->and('field', Relation::EQUAL, 'test'); + $this->object->and('field2', Relation::EQUAL, 'test2'); $this->object->endGroup(); - $this->object->addRelationOr('field3', Relation::EQUAL, 'test3'); + $this->object->or('field3', Relation::EQUAL, 'test3'); $this->assertEquals( "/anydataset/row[ ( field[@name='field'] = 'test' and field[@name='field2'] = 'test2' ) or field[@name='field3'] = 'test3' ]", $this->object->format(new IteratorFilterXPathFormatter()) @@ -77,14 +76,14 @@ public function testGroup() public function testIn() { $this->expectException(\InvalidArgumentException::class); - $this->object->addRelation('field', Relation::IN, ['test', 'test2']); + $this->object->and('field', Relation::IN, ['test', 'test2']); $this->object->format(new IteratorFilterXPathFormatter()); } public function testNotIn() { $this->expectException(\InvalidArgumentException::class); - $this->object->addRelation('field', Relation::NOT_IN, ['test', 'test2']); + $this->object->and('field', Relation::NOT_IN, ['test', 'test2']); $this->object->format(new IteratorFilterXPathFormatter()); } } From 7f14c9e1bdd27d3773f41c5c6180307f6742ef87 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sun, 27 Oct 2024 10:12:53 -0500 Subject: [PATCH 11/11] Limit PHP Version --- composer.json | 2 +- src/AnyDataset.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 82eeba3..1edc6a4 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "prefer-stable": true, "minimum-stability": "dev", "require": { - "php": ">=8.1", + "php": ">=8.1 <8.4", "ext-dom": "*", "byjg/xmlutil": "^5.0", "byjg/serializer": "^5.0" diff --git a/src/AnyDataset.php b/src/AnyDataset.php index 2431afd..617b1dd 100644 --- a/src/AnyDataset.php +++ b/src/AnyDataset.php @@ -238,8 +238,9 @@ public function removeRow(int|Row $row = null): void } if ($row instanceof Row) { $iPos = 0; + $rowArr = $row->toArray(); foreach ($this->collection as $sr) { - if ($sr->toArray() == $row->toArray()) { + if ($sr->toArray() == $rowArr) { $this->removeRow($iPos); break; }