Skip to content

Commit

Permalink
Merge pull request #10577 from craftcms/feature/dev-110-improve-matri…
Browse files Browse the repository at this point in the history
…x-save-performance

Multi-Matrix block ownership
  • Loading branch information
brandonkelly authored Feb 16, 2022
2 parents 3f18329 + 037f80f commit dd86bc5
Show file tree
Hide file tree
Showing 15 changed files with 404 additions and 115 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
- It’s now possible to edit images’ focal points from their preview modals. ([#8489](https://github.com/craftcms/cms/discussions/8489))
- Added the `|money` Twig filter.
- Added the `assetUploaders` user query param.
- Added the `primaryOwner` and `primaryOwnerId` Matrix block query params.
- Added the `authors` user query param.
- Added the `hasAlt` asset query param.
- Added the `button`, `submitButton`, `fs`, and `fsField` macros to the `_includes/forms` control panel template.
Expand Down Expand Up @@ -91,6 +92,7 @@
- Added `craft\db\Table::ASSETINDEXINGSESSIONS`.
- Added `craft\db\Table::IMAGETRANSFORMINDEX`.
- Added `craft\db\Table::IMAGETRANSFORMS`.
- Added `craft\db\Table::MATRIXBLOCKS_OWNERS`.
- Added `craft\elements\Asset::$alt`.
- Added `craft\elements\Asset::getFs()`.
- Added `craft\elements\Asset::setFilename()`.
Expand Down Expand Up @@ -135,6 +137,7 @@
- Added `craft\elements\conditions\users\LastNameConditionRule`.
- Added `craft\elements\conditions\users\UserCondition`.
- Added `craft\elements\conditions\users\UsernameConditionRule`.
- Added `craft\elements\MatrixBlock::$primaryOwnerId`.
- Added `craft\elements\User::$active`.
- Added `craft\elements\User::canAssignUserGroups()`.
- Added `craft\elements\User::getIsCredentialed()`.
Expand Down Expand Up @@ -253,11 +256,13 @@
- Added `craft\services\Conditions`.
- Added `craft\services\Config::CATEGORY_CUSTOM`.
- Added `craft\services\Config::getCustom()`.
- Added `craft\services\Drafts::removeDraftData()`.
- Added `craft\services\ElementSources`, which replaces `craft\services\ElementIndexes`.
- Added `craft\services\Fields::createLayout()`.
- Added `craft\services\Fs`.
- Added `craft\services\Gql::prepareFieldDefinitions()`.
- Added `craft\services\ImageTransforms`.
- Added `craft\services\Matrix::duplicateOwnership()`.
- Added `craft\services\ProjectConfig::applyExternalChanges()`.
- Added `craft\services\ProjectConfig::ASSOC_KEY`.
- Added `craft\services\ProjectConfig::getDoesExternalConfigExist()`.
Expand Down Expand Up @@ -342,6 +347,7 @@
- Craft now requires PHP 8.0 or later.
- Craft now requires MySQL 5.7.8 / MariaDB 10.2.7 / PostgreSQL 10.0 or later.
- Craft now requires the [Intl](https://php.net/manual/en/book.intl.php) and [BCMath](https://www.php.net/manual/en/book.bc.php) PHP extensions.
- Improved draft creation/application performance. ([#10577](https://github.com/craftcms/cms/pull/10577))
- The “What’ New” HUD now displays an icon and label above each announcement, identifying where it came from (Craft CMS or a plugin). ([#9747](https://github.com/craftcms/cms/discussions/9747))
- The control panel now keeps track of the currently-edited site on a per-tab basis by adding a `site` query string param to all control panel URLs. ([#8920](https://github.com/craftcms/cms/discussions/8920))
- Users are no longer required to have a username or email.
Expand Down
2 changes: 2 additions & 0 deletions src/db/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ abstract class Table
public const GQLTOKENS = '{{%gqltokens}}';
public const INFO = '{{%info}}';
public const MATRIXBLOCKS = '{{%matrixblocks}}';
/** @since 4.0.0 */
public const MATRIXBLOCKS_OWNERS = '{{%matrixblocks_owners}}';
public const MATRIXBLOCKTYPES = '{{%matrixblocktypes}}';
public const MIGRATIONS = '{{%migrations}}';
/** @since 3.4.0 */
Expand Down
22 changes: 17 additions & 5 deletions src/elements/MatrixBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@ public static function gqlTypeNameByContext($context): string
*/
public ?int $fieldId = null;

/**
* @var int|null Primary owner ID
* @since 4.0.0
*/
public ?int $primaryOwnerId = null;

/**
* @var int|null Owner ID
*/
Expand Down Expand Up @@ -239,7 +245,7 @@ public function extraFields(): array
protected function defineRules(): array
{
$rules = parent::defineRules();
$rules[] = [['fieldId', 'ownerId', 'typeId', 'sortOrder'], 'number', 'integerOnly' => true];
$rules[] = [['fieldId', 'primaryOwnerId', 'typeId', 'sortOrder'], 'number', 'integerOnly' => true];
return $rules;
}

Expand Down Expand Up @@ -269,9 +275,9 @@ public function getSupportedSites(): array
public function getCacheTags(): array
{
return [
"field-owner:$this->fieldId-$this->ownerId",
"field-owner:$this->fieldId-$this->primaryOwnerId",
"field:$this->fieldId",
"owner:$this->ownerId",
"owner:$this->primaryOwnerId",
];
}

Expand Down Expand Up @@ -328,6 +334,7 @@ public function getOwner(): ElementInterface
public function setOwner(?ElementInterface $owner = null): void
{
$this->_owner = $owner;
$this->ownerId = $owner->id;
}

/**
Expand Down Expand Up @@ -433,10 +440,15 @@ public function afterSave(bool $isNew): void
}

$record->fieldId = (int)$this->fieldId;
$record->ownerId = (int)$this->ownerId;
$record->primaryOwnerId = (int)$this->primaryOwnerId;
$record->typeId = (int)$this->typeId;
$record->sortOrder = (int)$this->sortOrder ?: null;
$record->save(false);

Db::upsert(Table::MATRIXBLOCKS_OWNERS, [
'blockId' => $this->id,
'ownerId' => $this->ownerId,
'sortOrder' => $this->sortOrder ?? 0,
]);
}

parent::afterSave($isNew);
Expand Down
10 changes: 5 additions & 5 deletions src/elements/db/ElementQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -1318,16 +1318,16 @@ public function prepare($builder): Query
$this->query->withQueries = $this->withQueries;
$this->subQuery = new Query();

// Give other classes a chance to make changes up front
if (!$this->beforePrepare()) {
throw new QueryAbortedException();
}

$this->query
->from(['subquery' => $this->subQuery])
->innerJoin(['elements' => Table::ELEMENTS], '[[elements.id]] = [[subquery.elementsId]]')
->innerJoin(['elements_sites' => Table::ELEMENTS_SITES], '[[elements_sites.id]] = [[subquery.elementsSitesId]]');

// Give other classes a chance to make changes up front
if (!$this->beforePrepare()) {
throw new QueryAbortedException();
}

$this->subQuery
->addSelect([
'elementsId' => 'elements.id',
Expand Down
4 changes: 2 additions & 2 deletions src/elements/db/ElementRelationParamParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ private function _subparse($relCriteria)
->innerJoin([$targetMatrixBlocksAlias => Table::MATRIXBLOCKS], "[[$targetMatrixBlocksAlias.id]] = [[$sourcesAlias.sourceId]]")
->innerJoin([$targetMatrixElementsAlias => Table::ELEMENTS], "[[$targetMatrixElementsAlias.id]] = [[$targetMatrixBlocksAlias.id]]")
->where([
"$targetMatrixBlocksAlias.ownerId" => $relElementIds,
"$targetMatrixBlocksAlias.primaryOwnerId" => $relElementIds,
"$targetMatrixBlocksAlias.fieldId" => $fieldModel->id,
"$targetMatrixElementsAlias.enabled" => true,
"$targetMatrixElementsAlias.dateDeleted" => null,
Expand All @@ -394,7 +394,7 @@ private function _subparse($relCriteria)
$matrixBlockTargetsAlias = 'matrixblock_targets' . self::$_relateSourceMatrixBlocksCount;

$subQuery = (new Query())
->select(["$sourceMatrixBlocksAlias.ownerId"])
->select(["$sourceMatrixBlocksAlias.primaryOwnerId"])
->from([$sourceMatrixBlocksAlias => Table::MATRIXBLOCKS])
->innerJoin([$sourceMatrixElementsAlias => Table::ELEMENTS], "[[$sourceMatrixElementsAlias.id]] = [[$sourceMatrixBlocksAlias.id]]")
->innerJoin([$matrixBlockTargetsAlias => Table::RELATIONS], "[[$matrixBlockTargetsAlias.sourceId]] = [[$sourceMatrixBlocksAlias.id]]")
Expand Down
Loading

0 comments on commit dd86bc5

Please sign in to comment.