Skip to content

Commit

Permalink
Duplicate blocks for all sites when saving a new element
Browse files Browse the repository at this point in the history
Fixes #4449
  • Loading branch information
brandonkelly committed Jun 26, 2019
1 parent f95428c commit 5613536
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-v3.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,4 @@

### Fixed
- Fixed a bug where `craft\helpers\UrlHelper` methods could add duplicate query params on generated URLs.
- Fixed a bug where Matrix blocks weren’t getting duplicated for other sites when creating a new element. ([#4449](https://github.com/craftcms/cms/issues/4449))
1 change: 1 addition & 0 deletions CHANGELOG-v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
### Fixed
- Fixed a bug where Edit Entry pages would show unnecessary page unload warnings in Chrome 75.
- Fixed an error that could occur when editing entries on multi-site installs.
- Fixed a bug where Matrix blocks weren’t getting duplicated for other sites when creating a new element. ([#4449](https://github.com/craftcms/cms/issues/4449))

## 3.2.0-RC1 - 2019-06-25

Expand Down
11 changes: 8 additions & 3 deletions src/services/Elements.php
Original file line number Diff line number Diff line change
Expand Up @@ -479,9 +479,14 @@ public function saveElement(ElementInterface $element, bool $runValidation = tru
/** @var Element $element */
$isNewElement = !$element->id;

// If this is a new element, give it a UID right away
if ($isNewElement && !$element->uid) {
$element->uid = StringHelper::UUID();
if ($isNewElement) {
// Give it a UID right away
if (!$element->uid) {
$element->uid = StringHelper::UUID();
}

// Let Matrix fields, etc., know they should be duplicating their values across all sites.
$element->propagateAll = true;
}

// Fire a 'beforeSaveElement' event
Expand Down
42 changes: 42 additions & 0 deletions src/services/Matrix.php
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,48 @@ public function saveField(MatrixField $field, ElementInterface $owner)
// Delete any blocks that shouldn't be there anymore
$this->_deleteOtherBlocks($field, $owner, $blockIds);

// Should we duplicate the blocks to other sites?
if ($owner->propagateAll && $field->propagationMethod !== MatrixField::PROPAGATION_METHOD_ALL) {
// Find the owner's site IDs that *aren't* supported by this site's Matrix blocks
$ownerSiteIds = ArrayHelper::getColumn(ElementHelper::supportedSitesForElement($owner), 'siteId');
$fieldSiteIds = $this->getSupportedSiteIdsForField($field, $owner);
$otherSiteIds = array_diff($ownerSiteIds, $fieldSiteIds);

if (!empty($otherSiteIds)) {
// Get the original element and duplicated element for each of those sites
/** @var Element[] $otherTargets */
$otherTargets = $owner::find()
->drafts($owner->getIsDraft())
->revisions($owner->getIsRevision())
->id($owner->id)
->siteId($otherSiteIds)
->anyStatus()
->all();

// Duplicate Matrix blocks, ensuring we don't process the same blocks more than once
$handledSiteIds = [];

$cachedQuery = (clone $query)->anyStatus();
$cachedQuery->setCachedResult($blocks);
$owner->setFieldValue($field->handle, $cachedQuery);

foreach ($otherTargets as $otherTarget) {
// Make sure we haven't already duplicated blocks for this site, via propagation from another site
if (isset($handledSiteIds[$otherTarget->siteId])) {
continue;
}

$this->duplicateBlocks($field, $owner, $otherTarget);

// Make sure we don't duplicate blocks for any of the sites that were just propagated to
$sourceSupportedSiteIds = $this->getSupportedSiteIdsForField($field, $otherTarget);
$handledSiteIds = array_merge($handledSiteIds, array_flip($sourceSupportedSiteIds));
}

$owner->setFieldValue($field->handle, $query);
}
}

$transaction->commit();
} catch (\Throwable $e) {
$transaction->rollBack();
Expand Down

0 comments on commit 5613536

Please # to comment.