From 77ab47c268816d9de685533b7b296f73f8b91cb9 Mon Sep 17 00:00:00 2001 From: Fran Moreno Date: Fri, 27 Oct 2023 09:05:53 +0200 Subject: [PATCH 1/5] Add PHP 8.3 to CI --- .github/workflows/continuous-integration.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 863fb29647..a7d1ced3d0 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -21,6 +21,7 @@ jobs: - "8.0" - "8.1" - "8.2" + - "8.3" mongodb-version: - "6.0" - "5.0" From 43063d635a819fbf79972d60d242074467b6ed59 Mon Sep 17 00:00:00 2001 From: Fran Moreno Date: Sun, 29 Oct 2023 18:05:34 +0100 Subject: [PATCH 2/5] Doctrine CS 12 --- composer.json | 3 +- .../ODM/MongoDB/Mapping/Driver/XmlDriver.php | 28 +++++++++---------- psalm-baseline.xml | 16 +++++------ 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/composer.json b/composer.json index 11c2ef3d64..014c52d76a 100644 --- a/composer.json +++ b/composer.json @@ -39,13 +39,12 @@ }, "require-dev": { "ext-bcmath": "*", - "doctrine/coding-standard": "^11.0", + "doctrine/coding-standard": "^12.0", "jmikola/geojson": "^1.0", "phpbench/phpbench": "^1.0.0@dev", "phpstan/phpstan": "^1.10.11", "phpstan/phpstan-phpunit": "^1.0", "phpunit/phpunit": "^9.5.5 || ^10.0.15", - "squizlabs/php_codesniffer": "^3.5", "symfony/cache": "^4.4 || ^5.0 || ^6.0", "vimeo/psalm": "^5.9.0" }, diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ODM/MongoDB/Mapping/Driver/XmlDriver.php index 3ca151f412..600554b393 100644 --- a/lib/Doctrine/ODM/MongoDB/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ODM/MongoDB/Mapping/Driver/XmlDriver.php @@ -184,8 +184,8 @@ public function loadMetadataForClass($className, \Doctrine\Persistence\Mapping\C $metadata->setDefaultDiscriminatorValue((string) $xmlRoot->{'default-discriminator-value'}['value']); } - if (isset($xmlRoot->{'indexes'})) { - foreach ($xmlRoot->{'indexes'}->{'index'} as $index) { + if (isset($xmlRoot->indexes)) { + foreach ($xmlRoot->indexes->index as $index) { $this->addIndex($metadata, $index); } } @@ -474,15 +474,15 @@ private function addReferenceMapping(ClassMetadata $class, ?SimpleXMLElement $re $mapping['defaultDiscriminatorValue'] = (string) $reference->{'default-discriminator-value'}['value']; } - if (isset($reference->{'sort'})) { - foreach ($reference->{'sort'}->{'sort'} as $sort) { + if (isset($reference->sort)) { + foreach ($reference->sort->sort as $sort) { $attr = $sort->attributes(); $mapping['sort'][(string) $attr['field']] = (string) ($attr['order'] ?? 'asc'); } } - if (isset($reference->{'criteria'})) { - foreach ($reference->{'criteria'}->{'criteria'} as $criteria) { + if (isset($reference->criteria)) { + foreach ($reference->criteria->criteria as $criteria) { $attr = $criteria->attributes(); $mapping['criteria'][(string) $attr['field']] = (string) $attr['value']; } @@ -496,8 +496,8 @@ private function addReferenceMapping(ClassMetadata $class, ?SimpleXMLElement $re $mapping['alsoLoadFields'] = explode(',', (string) $attributes['also-load']); } - if (isset($reference->{'prime'})) { - foreach ($reference->{'prime'}->{'field'} as $field) { + if (isset($reference->prime)) { + foreach ($reference->prime->field as $field) { $attr = $field->attributes(); $mapping['prime'][] = (string) $attr['name']; } @@ -513,7 +513,7 @@ private function addIndex(ClassMetadata $class, SimpleXMLElement $xmlIndex): voi $keys = []; - foreach ($xmlIndex->{'key'} as $key) { + foreach ($xmlIndex->key as $key) { $keys[(string) $key['name']] = (string) ($key['order'] ?? 'asc'); } @@ -535,8 +535,8 @@ private function addIndex(ClassMetadata $class, SimpleXMLElement $xmlIndex): voi $options['unique'] = ((string) $attributes['unique'] === 'true'); } - if (isset($xmlIndex->{'option'})) { - foreach ($xmlIndex->{'option'} as $option) { + if (isset($xmlIndex->option)) { + foreach ($xmlIndex->option as $option) { $options[(string) $option['name']] = $this->convertXMLElementValue((string) $option['value']); } } @@ -635,7 +635,7 @@ private function setShardKey(ClassMetadata $class, SimpleXMLElement $xmlShardkey $keys = []; $options = []; - foreach ($xmlShardkey->{'key'} as $key) { + foreach ($xmlShardkey->key as $key) { $keys[(string) $key['name']] = (string) ($key['order'] ?? 'asc'); } @@ -647,8 +647,8 @@ private function setShardKey(ClassMetadata $class, SimpleXMLElement $xmlShardkey $options['numInitialChunks'] = (int) $attributes['numInitialChunks']; } - if (isset($xmlShardkey->{'option'})) { - foreach ($xmlShardkey->{'option'} as $option) { + if (isset($xmlShardkey->option)) { + foreach ($xmlShardkey->option as $option) { $options[(string) $option['name']] = $this->convertXMLElementValue((string) $option['value']); } } diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 941b851bc2..b2cc0a72c4 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -85,13 +85,13 @@ field]]> id]]> + indexes]]> {'also-load-methods'}]]> {'default-discriminator-value'}]]> {'discriminator-field'}]]> {'discriminator-map'}]]> {'embed-many'}]]> {'embed-one'}]]> - {'indexes'}]]> {'lifecycle-callbacks'}]]> {'read-preference'}]]> {'reference-many'}]]> @@ -102,13 +102,13 @@ field]]> id]]> + indexes]]> {'also-load-methods'}]]> {'default-discriminator-value'}]]> {'discriminator-field'}]]> {'discriminator-map'}]]> {'embed-many'}]]> {'embed-one'}]]> - {'indexes'}]]> {'lifecycle-callbacks'}]]> {'read-preference'}]]> {'reference-many'}]]> @@ -130,30 +130,30 @@ {'generator-option'})]]> and)]]> field)]]> - {'criteria'})]]> + criteria)]]> + prime)]]> + sort)]]> {'default-discriminator-value'})]]> {'discriminator-field'})]]> {'discriminator-map'})]]> - {'prime'})]]> - {'sort'})]]> - {'option'})]]> + option)]]> {'partial-filter-expression'})]]> {'tag-set'})]]> field)]]> id)]]> + indexes)]]> {'default-discriminator-value'})]]> {'discriminator-field'})]]> {'discriminator-map'})]]> {'embed-many'})]]> {'embed-one'})]]> - {'indexes'})]]> {'lifecycle-callbacks'})]]> {'read-preference'})]]> {'reference-many'})]]> {'reference-one'})]]> {'schema-validation'})]]> {'shard-key'})]]> - {'option'})]]> + option)]]> getName() === 'document']]> From da553436f295bb94163559362808deea5a1a263b Mon Sep 17 00:00:00 2001 From: Fran Moreno Date: Sun, 29 Oct 2023 18:49:16 +0100 Subject: [PATCH 3/5] Bump workflows --- .github/workflows/coding-standards.yml | 4 +--- .github/workflows/continuous-integration.yml | 6 +++--- .github/workflows/performance.yml | 6 +++--- .github/workflows/release-on-milestone-closed.yml | 2 +- .github/workflows/static-analysis.yml | 14 +++++++------- 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index b30e251b38..b52cd6feaf 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -10,6 +10,4 @@ on: jobs: coding-standards: name: "Coding Standards" - uses: "doctrine/.github/.github/workflows/coding-standards.yml@3.0.0" - with: - php-version: "8.2" + uses: "doctrine/.github/.github/workflows/coding-standards.yml@3.1.0" diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index a7d1ced3d0..cd47ee9069 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -46,7 +46,7 @@ jobs: steps: - name: "Checkout" - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" with: fetch-depth: 2 @@ -59,7 +59,7 @@ jobs: key: "extcache-v1" - name: Cache extensions - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.extcache.outputs.dir }} key: ${{ steps.extcache.outputs.key }} @@ -88,7 +88,7 @@ jobs: composer-options: "--prefer-dist" - name: "Upload composer.lock as build artifact" - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: composer.lock path: composer.lock diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index f89edd2940..60f5842ea8 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -9,7 +9,7 @@ on: jobs: performance-tests: name: "Performance Tests" - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" strategy: matrix: @@ -24,7 +24,7 @@ jobs: steps: - name: "Checkout" - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: Setup cache environment id: extcache @@ -35,7 +35,7 @@ jobs: key: "extcache-v1" - name: Cache extensions - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.extcache.outputs.dir }} key: ${{ steps.extcache.outputs.key }} diff --git a/.github/workflows/release-on-milestone-closed.yml b/.github/workflows/release-on-milestone-closed.yml index e7e127f4ab..cc6ac55fee 100644 --- a/.github/workflows/release-on-milestone-closed.yml +++ b/.github/workflows/release-on-milestone-closed.yml @@ -8,7 +8,7 @@ on: jobs: release: name: "Git tag, release & create merge-up PR" - uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@1.4.1" + uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@3.1.0" secrets: GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }} GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }} diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index a1bac2c2f7..5ce7f19d85 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -10,16 +10,16 @@ on: jobs: static-analysis-phpstan: name: "Static Analysis with PHPStan" - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" strategy: matrix: php-version: - - "8.1" + - "8.2" steps: - name: "Checkout code" - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: Setup cache environment id: extcache @@ -30,7 +30,7 @@ jobs: key: "extcache-v1" - name: Cache extensions - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.extcache.outputs.dir }} key: ${{ steps.extcache.outputs.key }} @@ -60,16 +60,16 @@ jobs: static-analysis-psalm: name: "Static Analysis with Psalm" - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" strategy: matrix: php-version: - - "8.1" + - "8.2" steps: - name: "Checkout code" - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: "Install PHP" uses: "shivammathur/setup-php@v2" From 5b5b7420c8a15a01f3a9890284c8adf6a148b5b5 Mon Sep 17 00:00:00 2001 From: Fran Moreno Date: Mon, 30 Oct 2023 18:36:41 +0100 Subject: [PATCH 4/5] Enable Dependabot --- .github/dependabot.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..5ace4600a1 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" From 3c77ba4f6ad06278ae37cddc13503e1ff8db6db5 Mon Sep 17 00:00:00 2001 From: Maciej Malarz Date: Wed, 1 Nov 2023 22:37:33 +0100 Subject: [PATCH 5/5] Preserve iterator position when counting --- .../ODM/MongoDB/Iterator/CachingIterator.php | 2 ++ .../Iterator/CachingIteratorTest.php | 20 ++++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/Doctrine/ODM/MongoDB/Iterator/CachingIterator.php b/lib/Doctrine/ODM/MongoDB/Iterator/CachingIterator.php index 9f8ddcf54a..d726712013 100644 --- a/lib/Doctrine/ODM/MongoDB/Iterator/CachingIterator.php +++ b/lib/Doctrine/ODM/MongoDB/Iterator/CachingIterator.php @@ -58,7 +58,9 @@ public function __construct(Traversable $iterator) /** @see https://php.net/countable.count */ public function count(): int { + $currentKey = key($this->items); $this->exhaustIterator(); + for (reset($this->items); key($this->items) !== $currentKey; next($this->items)); return count($this->items); } diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Iterator/CachingIteratorTest.php b/tests/Doctrine/ODM/MongoDB/Tests/Functional/Iterator/CachingIteratorTest.php index c077cadcb5..52b90c1dec 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Iterator/CachingIteratorTest.php +++ b/tests/Doctrine/ODM/MongoDB/Tests/Functional/Iterator/CachingIteratorTest.php @@ -114,7 +114,7 @@ public function testToArrayAfterPartialIteration(): void public function testCount(): void { $iterator = new CachingIterator($this->getTraversable([1, 2, 3])); - $this->assertCount(3, $iterator); + self::assertCount(3, $iterator); } public function testCountAfterPartialIteration(): void @@ -122,18 +122,24 @@ public function testCountAfterPartialIteration(): void $iterator = new CachingIterator($this->getTraversable([1, 2, 3])); $iterator->rewind(); - $this->assertTrue($iterator->valid()); - $this->assertSame(0, $iterator->key()); - $this->assertSame(1, $iterator->current()); + self::assertTrue($iterator->valid()); + self::assertSame(0, $iterator->key()); + self::assertSame(1, $iterator->current()); $iterator->next(); - $this->assertCount(3, $iterator); + self::assertSame(1, $iterator->key()); + self::assertSame(2, $iterator->current()); + + self::assertCount(3, $iterator); + self::assertTrue($iterator->valid()); + self::assertSame(1, $iterator->key()); + self::assertSame(2, $iterator->current()); } public function testCountWithEmptySet(): void { $iterator = new CachingIterator($this->getTraversable([])); - $this->assertCount(0, $iterator); + self::assertCount(0, $iterator); } /** @@ -172,7 +178,7 @@ public function rewind(): void }; $iterator = new CachingIterator($nestedIterator); - $this->assertCount(1, $iterator); + self::assertCount(1, $iterator); } /**