From 9ffad21dd45197315cfe0e1c43db57ea9b7868ab Mon Sep 17 00:00:00 2001 From: Iwona Just Date: Fri, 6 Sep 2024 09:53:35 +0100 Subject: [PATCH 1/7] limit user addresses (via attribute) to not grab the custom field values --- src/elements/User.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/elements/User.php b/src/elements/User.php index 2182f407912..51f25b5bae6 100644 --- a/src/elements/User.php +++ b/src/elements/User.php @@ -1087,7 +1087,7 @@ public function getAddresses(): ElementCollection return ElementCollection::make(); } - $this->_addresses = $this->createAddressQuery()->collect(); + $this->_addresses = $this->createAddressQuery()->where(['fieldId' => null])->collect(); } return $this->_addresses; From 31b5dfb0917bfdc566e5536dcc698e80494aac74 Mon Sep 17 00:00:00 2001 From: Iwona Just Date: Fri, 6 Sep 2024 11:44:25 +0100 Subject: [PATCH 2/7] delete addressees belonging to hard deleted fields --- src/services/Gc.php | 46 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/services/Gc.php b/src/services/Gc.php index dd3cca05f3c..ab64cdf5bcd 100644 --- a/src/services/Gc.php +++ b/src/services/Gc.php @@ -15,6 +15,7 @@ use craft\db\Connection; use craft\db\Query; use craft\db\Table; +use craft\elements\Address; use craft\elements\Asset; use craft\elements\Category; use craft\elements\Entry; @@ -145,6 +146,8 @@ public function run(bool $force = false): void Table::SITES, ]); + $this->_deleteAddressesOrphanedByFields(); + $this->hardDeleteVolumes(); $this->removeEmptyTempFolders(); $this->_gcCache(); @@ -712,6 +715,49 @@ private function _hardDeleteStructures(): void } } + /** + * Delete addresses that belong to the fields that were hard deleted. + * + * @return void + * @throws \yii\db\Exception + */ + private function _deleteAddressesOrphanedByFields() + { + $this->_stdout(' > deleting addresses orphaned by hard deleted fields ... '); + + // delete addresses whose fieldId points to a field that was hard deleted + $elementsTable = Table::ELEMENTS; + $addressesTable = Table::ADDRESSES; + $fieldsTable = Table::FIELDS; + + if ($this->db->getIsMysql()) { + $sql = <<db->createCommand($sql, ['type' => Address::class])->execute(); + + $this->_stdout("done\n", Console::FG_GREEN); + } + private function _gcCache(): void { $cache = Craft::$app->getCache(); From 5e90c47d7d4e256716b4a0b59d7687ffbaa03fe0 Mon Sep 17 00:00:00 2001 From: Iwona Just Date: Fri, 6 Sep 2024 12:51:48 +0100 Subject: [PATCH 3/7] Revert "delete addressees belonging to hard deleted fields" This reverts commit 31b5dfb0917bfdc566e5536dcc698e80494aac74. --- src/services/Gc.php | 46 --------------------------------------------- 1 file changed, 46 deletions(-) diff --git a/src/services/Gc.php b/src/services/Gc.php index ab64cdf5bcd..dd3cca05f3c 100644 --- a/src/services/Gc.php +++ b/src/services/Gc.php @@ -15,7 +15,6 @@ use craft\db\Connection; use craft\db\Query; use craft\db\Table; -use craft\elements\Address; use craft\elements\Asset; use craft\elements\Category; use craft\elements\Entry; @@ -146,8 +145,6 @@ public function run(bool $force = false): void Table::SITES, ]); - $this->_deleteAddressesOrphanedByFields(); - $this->hardDeleteVolumes(); $this->removeEmptyTempFolders(); $this->_gcCache(); @@ -715,49 +712,6 @@ private function _hardDeleteStructures(): void } } - /** - * Delete addresses that belong to the fields that were hard deleted. - * - * @return void - * @throws \yii\db\Exception - */ - private function _deleteAddressesOrphanedByFields() - { - $this->_stdout(' > deleting addresses orphaned by hard deleted fields ... '); - - // delete addresses whose fieldId points to a field that was hard deleted - $elementsTable = Table::ELEMENTS; - $addressesTable = Table::ADDRESSES; - $fieldsTable = Table::FIELDS; - - if ($this->db->getIsMysql()) { - $sql = <<db->createCommand($sql, ['type' => Address::class])->execute(); - - $this->_stdout("done\n", Console::FG_GREEN); - } - private function _gcCache(): void { $cache = Craft::$app->getCache(); From 1d4e8fc885f1554b813182da9c39781b472f6a15 Mon Sep 17 00:00:00 2001 From: Iwona Just Date: Fri, 6 Sep 2024 13:13:56 +0100 Subject: [PATCH 4/7] add foreign key to addresses fieldId column + gc adjustment --- src/config/app.php | 2 +- ...31_add_addresses_fieldid_fk_constraint.php | 57 +++++++++++++++++++ src/services/Gc.php | 2 + 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/migrations/m240906_115231_add_addresses_fieldid_fk_constraint.php diff --git a/src/config/app.php b/src/config/app.php index df9332556df..ea62b4a6f8d 100644 --- a/src/config/app.php +++ b/src/config/app.php @@ -4,7 +4,7 @@ 'id' => 'CraftCMS', 'name' => 'Craft CMS', 'version' => '5.4.1', - 'schemaVersion' => '5.3.0.2', + 'schemaVersion' => '5.3.0.3', 'minVersionRequired' => '4.5.0', 'basePath' => dirname(__DIR__), // Defines the @app alias 'runtimePath' => '@storage/runtime', // Defines the @runtime alias diff --git a/src/migrations/m240906_115231_add_addresses_fieldid_fk_constraint.php b/src/migrations/m240906_115231_add_addresses_fieldid_fk_constraint.php new file mode 100644 index 00000000000..d088adc9cb4 --- /dev/null +++ b/src/migrations/m240906_115231_add_addresses_fieldid_fk_constraint.php @@ -0,0 +1,57 @@ +db->getIsMysql()) { + $sql = <<db->createCommand($sql)->execute(); + + // and now add a foreign key + $this->addForeignKey(null, Table::ADDRESSES, ['fieldId'], Table::FIELDS, ['id'], 'CASCADE', null); + + return true; + } + + /** + * @inheritdoc + */ + public function safeDown(): bool + { + echo "m240906_115231_add_addresses_fieldid_fk_constraint cannot be reverted.\n"; + return false; + } +} diff --git a/src/services/Gc.php b/src/services/Gc.php index dd3cca05f3c..209aad761a1 100644 --- a/src/services/Gc.php +++ b/src/services/Gc.php @@ -15,6 +15,7 @@ use craft\db\Connection; use craft\db\Query; use craft\db\Table; +use craft\elements\Address; use craft\elements\Asset; use craft\elements\Category; use craft\elements\Entry; @@ -115,6 +116,7 @@ public function run(bool $force = false): void Table::TAGGROUPS, ]); + $this->deletePartialElements(Address::class, Table::ADDRESSES, 'id'); $this->deletePartialElements(Asset::class, Table::ASSETS, 'id'); $this->deletePartialElements(Category::class, Table::CATEGORIES, 'id'); $this->deletePartialElements(Entry::class, Table::ENTRIES, 'id'); From 1f2a0626a372945b8777a6c797a14b60740dda27 Mon Sep 17 00:00:00 2001 From: brandonkelly Date: Fri, 6 Sep 2024 09:15:44 -0700 Subject: [PATCH 5/7] andWhere() --- src/elements/User.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/elements/User.php b/src/elements/User.php index 51f25b5bae6..a0839883f9c 100644 --- a/src/elements/User.php +++ b/src/elements/User.php @@ -1087,7 +1087,9 @@ public function getAddresses(): ElementCollection return ElementCollection::make(); } - $this->_addresses = $this->createAddressQuery()->where(['fieldId' => null])->collect(); + $this->_addresses = $this->createAddressQuery() + ->andWhere(['fieldId' => null]) + ->collect(); } return $this->_addresses; From d6d0d975a978f190883448a15b75dfbf1db91bf6 Mon Sep 17 00:00:00 2001 From: brandonkelly Date: Fri, 6 Sep 2024 09:16:19 -0700 Subject: [PATCH 6/7] Fully rely on garbage collection --- src/config/app.php | 2 +- ...31_add_addresses_fieldid_fk_constraint.php | 57 ------------------- src/services/Gc.php | 50 +++++++++++----- 3 files changed, 37 insertions(+), 72 deletions(-) delete mode 100644 src/migrations/m240906_115231_add_addresses_fieldid_fk_constraint.php diff --git a/src/config/app.php b/src/config/app.php index ea62b4a6f8d..df9332556df 100644 --- a/src/config/app.php +++ b/src/config/app.php @@ -4,7 +4,7 @@ 'id' => 'CraftCMS', 'name' => 'Craft CMS', 'version' => '5.4.1', - 'schemaVersion' => '5.3.0.3', + 'schemaVersion' => '5.3.0.2', 'minVersionRequired' => '4.5.0', 'basePath' => dirname(__DIR__), // Defines the @app alias 'runtimePath' => '@storage/runtime', // Defines the @runtime alias diff --git a/src/migrations/m240906_115231_add_addresses_fieldid_fk_constraint.php b/src/migrations/m240906_115231_add_addresses_fieldid_fk_constraint.php deleted file mode 100644 index d088adc9cb4..00000000000 --- a/src/migrations/m240906_115231_add_addresses_fieldid_fk_constraint.php +++ /dev/null @@ -1,57 +0,0 @@ -db->getIsMysql()) { - $sql = <<db->createCommand($sql)->execute(); - - // and now add a foreign key - $this->addForeignKey(null, Table::ADDRESSES, ['fieldId'], Table::FIELDS, ['id'], 'CASCADE', null); - - return true; - } - - /** - * @inheritdoc - */ - public function safeDown(): bool - { - echo "m240906_115231_add_addresses_fieldid_fk_constraint cannot be reverted.\n"; - return false; - } -} diff --git a/src/services/Gc.php b/src/services/Gc.php index 209aad761a1..de4671f497f 100644 --- a/src/services/Gc.php +++ b/src/services/Gc.php @@ -112,6 +112,7 @@ public function run(bool $force = false): void $this->hardDelete([ Table::CATEGORYGROUPS, Table::ENTRYTYPES, + Table::FIELDS, Table::SECTIONS, Table::TAGGROUPS, ]); @@ -125,7 +126,8 @@ public function run(bool $force = false): void $this->deletePartialElements(User::class, Table::USERS, 'id'); $this->_deleteUnsupportedSiteEntries(); - $this->_deleteOrphanedNestedEntries(); + $this->deleteOrphanedNestedElements(Address::class, Table::ADDRESSES); + $this->deleteOrphanedNestedElements(Entry::class, Table::ENTRIES); // Fire a 'run' event // Note this should get fired *before* orphaned drafts & revisions are deleted @@ -143,7 +145,6 @@ public function run(bool $force = false): void $this->hardDelete([ Table::FIELDLAYOUTS, - Table::FIELDS, Table::SITES, ]); @@ -527,35 +528,56 @@ private function _deleteUnsupportedSiteEntries(): void } /** - * Deletes any orphaned nested entries. + * Deletes elements which have a `fieldId` value, but it’s set to an invalid field ID, + * or they're missing a row in the `elements_owners` table. + * + * @param string $elementType The element type + * @phpstan-param class-string $elementType + * @param string $table The extension table name + * @param string $fieldFk The column name that contains the foreign key to `fields.id` + * @since 5.4.2 */ - private function _deleteOrphanedNestedEntries(): void + public function deleteOrphanedNestedElements(string $elementType, string $table, string $fieldFk = 'fieldId'): void { - $this->_stdout(' > deleting orphaned nested entries ... '); + /** @var string|ElementInterface $elementType */ + $this->_stdout(sprintf(' > deleting orphaned nested %s ... ', $elementType::pluralLowerDisplayName())); - $now = Db::prepareDateForDb(new DateTime()); $elementsTable = Table::ELEMENTS; - $entriesTable = Table::ENTRIES; $elementsOwnersTable = Table::ELEMENTS_OWNERS; + $fieldsTable = Table::FIELDS; if ($this->db->getIsMysql()) { - $sql = <<db->createCommand($sql)->execute(); + $this->db->createCommand($sql1)->execute(); + $this->db->createCommand($sql2)->execute(); $this->_stdout("done\n", Console::FG_GREEN); } From ac3ca1be53b7595e9eaab101f1cbc0df62ba3867 Mon Sep 17 00:00:00 2001 From: brandonkelly Date: Fri, 6 Sep 2024 09:19:59 -0700 Subject: [PATCH 7/7] Release notes [ci skip] --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c03594d7669..db8303c9340 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,11 @@ - Fixed a PHP error that occurred when running PHP 8.2 or 8.3. - Fixed a bug where disabled entries became enabled when edited within Live Preview. ([#15670](https://github.com/craftcms/cms/issues/15670)) - Fixed a bug where new nested entries could get incremented slugs even if there were no elements with conflicting URIs. ([#15672](https://github.com/craftcms/cms/issues/15672)) +- Fixed a bug where users’ Addresses screens were displaying addresses that belonged to the user via a custom Addresses field. ([#15678](https://github.com/craftcms/cms/issues/15678)) - Fixed a bug where Addresses fields weren’t always returning data in GraphQL. +- Fixed a bug where partial addresses weren’t getting garbage collected. +- Fixed a bug where orphaned nested addresses weren’t getting garbage collected. ([#15678](https://github.com/craftcms/cms/issues/15678)) +- Fixed a bug where orphaned nested entries weren’t getting garbage collected after their field had been hard-deleted. ([#15678](https://github.com/craftcms/cms/issues/15678)) - Fixed an information disclosure vulnerability. ## 5.4.1 - 2024-09-04