Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Delta updates #5146

Merged
merged 36 commits into from
Oct 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
001e0cf
recursive |merge filter
brandonkelly Oct 21, 2019
4bbc7de
|parseAttr filter
brandonkelly Oct 21, 2019
2582d13
Cleaner
brandonkelly Oct 21, 2019
67b0f61
_includes/forms/field improvements
brandonkelly Oct 21, 2019
2a09815
Merge branch '3.4' into feature/delta-updates
brandonkelly Oct 22, 2019
56a81d3
Cleanup
brandonkelly Oct 22, 2019
48bddf3
Cleanup
brandonkelly Oct 22, 2019
672ae62
Cleanup
brandonkelly Oct 22, 2019
4d8fc2d
Initial work on delta updates
brandonkelly Oct 22, 2019
be847e5
Merge branch '3.4' into feature/delta-updates
brandonkelly Oct 24, 2019
1dd21cb
View::registerDeltaName(), etc.
brandonkelly Oct 24, 2019
a8fc8f1
Only enable delta input registration if it was already enabled
brandonkelly Oct 26, 2019
7e2ac5c
Add delta support to Matrix blocks & sub-fields
brandonkelly Oct 26, 2019
dc5ab1d
Cleanup
brandonkelly Oct 26, 2019
eca86e0
Delta update support for element editor HUDs
brandonkelly Oct 26, 2019
75cc07c
No point in turning this off
brandonkelly Oct 27, 2019
d234177
Merge branch '3.4' into feature/delta-updates
brandonkelly Oct 27, 2019
e2c15cc
Craft.createForm()
brandonkelly Oct 27, 2019
190cb8e
User form cleanup
brandonkelly Oct 27, 2019
ab79ffb
Merge branch '3.4' into feature/delta-updates
brandonkelly Oct 27, 2019
e1d71c0
mainAttributes, mainFormAttributes
brandonkelly Oct 27, 2019
9aeee49
Make it easy for any CP form to support delta updates
brandonkelly Oct 27, 2019
b71ac85
Delta updates for Edit Category pages
brandonkelly Oct 27, 2019
feed3ae
Cleanup
brandonkelly Oct 27, 2019
58b64fa
Delta updates for Edit User pages
brandonkelly Oct 27, 2019
11b94c9
Fixed bug where changed Matrix blocks could be omitted from post data
brandonkelly Oct 28, 2019
c7dd660
Only save new and changed blocks
brandonkelly Oct 28, 2019
cbd1d26
Element::getDirtyFields()
brandonkelly Oct 28, 2019
fb4f1eb
Only update search indexes for dirty fields
brandonkelly Oct 28, 2019
891c6c6
Whoops
brandonkelly Oct 28, 2019
0cdf1f1
There is one.
brandonkelly Oct 28, 2019
46c17be
Important
brandonkelly Oct 28, 2019
df52c62
Update the sort order for otherwise unchanged blocks
brandonkelly Oct 28, 2019
1a60496
Merge branch '3.4' into feature/delta-updates
brandonkelly Oct 28, 2019
1bc652a
Cleanup
brandonkelly Oct 28, 2019
8c007a8
Update the changelog
brandonkelly Oct 28, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CHANGELOG-v3.4.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Running Release Notes for Craft 3.4

### Added
- Added support for delta element updates. ([#4064](https://github.com/craftcms/cms/issues/4064))
- Elements now track which field values have changed since the element was first loaded. ([#4149](https://github.com/craftcms/cms/issues/4149))
- Added the `verifyEmailPath` config setting.
- Added the `maxBackups` config setting. ([#2078](https://github.com/craftcms/cms/issues/2078))
- Added the `{% requireGuest %}` tag, which redirects a user to the path specified by the `postLoginRedirect` config setting if they’re already logged in. ([#5015](https://github.com/craftcms/cms/pull/5015))
Expand All @@ -11,21 +13,31 @@
- Added `craft\base\AssetPreview`.
- Added `craft\base\AssetPreviewInterface`.
- Added `craft\base\AssetPreviewTrait`.
- Added `craft\base\ElementInterface::clearDirtyFields()`.
- Added `craft\base\ElementInterface::getDirtyFields()`.
- Added `craft\base\ElementInterface::isFieldDirty()`.
- Added `craft\db\Connection::DRIVER_MYSQL`.
- Added `craft\db\Connection::DRIVER_PGSQL`.
- Added `craft\elements\MatrixBlock::$dirty`.
- Added `craft\events\AssetPreviewEvent`.
- Added `craft\events\DefineGqlTypeFieldsEvent`.
- Added `craft\events\DefineGqlValidationRulesEvent`.
- Added `craft\events\RegisterGqlPermissionsEvent`.
- Added `craft\gql\TypeManager`.
- Added `craft\helpers\Db::parseDsn()`.
- Added `craft\helpers\Db::url2config()`.
- Added `craft\queue\jobs\UpdateSearchIndex::$fieldHandles`.
- Added `craft\services\Assets::getAssetPreview()`.
- Added `craft\services\Gql::getValidationRules()`.
- Added `craft\services\Search::indexFields()`.
- Added `craft\web\Controller::requireGuest()`.
- Added `craft\web\twig\nodes\RequireGuestNode`.
- Added `craft\web\twig\tokenparsers\RequireGuestTokenParser`.
- Added `craft\web\User::guestRequired()`.
- Added `craft\web\View::getDeltaNames()`.
- Added `craft\web\View::getIsDeltaRegistrationActive()`.
- Added `craft\web\View::registerDeltaName()`.
- Added `craft\web\View::setIsDeltaRegistrationActive()`.
- Added `craft\web\twig\variables\Paginate::getDynamicRangeUrls()`, making it easy to create Google-style pagination links. ([#5005](https://github.com/craftcms/cms/issues/5005))
- Added the `cp.users.edit.prefs` template hook to the Edit User page. ([#5114](https://github.com/craftcms/cms/issues/5114))

Expand All @@ -43,6 +55,10 @@
- The installer now requires `config/db.php` to be setting the `dsn` database config setting with a `DB_DSN` environment variable, if a connection can’t already be established.
- `craft\services\Elements::saveElement()` now has an `$updateSearchIndex` argument (defaults to `true`). ([#4840](https://github.com/craftcms/cms/issues/4840))
- `craft\services\Elements::resaveElements()` now has an `$updateSearchIndex` argument (defaults to `false`). ([#4840](https://github.com/craftcms/cms/issues/4840))
- `craft\services\Search::indexElementAttributes()` now has a `$withFields` argument.
- The `_includes/forms/field.html` template now supports `fieldAttributes`, `labelAttributes`, and `inputAttributes` variables.
- The `_includes/field.html` template now supports a `registerDeltas` variable.
- The `_layouts/cp.html` template now supports `mainAttributes` and `mainFormAttributes` variables.
- Asset previews are now extensible, allowing plugins to add new preview types. ([#5136](https://github.com/craftcms/cms/pull/5136))
- Updated Yii to 2.0.29.

Expand All @@ -52,3 +68,4 @@
- Deprecated `craft\config\DbConfig::DRIVER_PGSQL`.
- Deprecated `craft\config\DbConfig::updateDsn()`.
- Deprecated `craft\elements\Asset::getSupportsPreview()`. Use `craft\services\Assets::getAssetPreview()` instead.
- Deprecated `craft\services\Search::indexElementFields()`.
52 changes: 50 additions & 2 deletions src/base/Element.php
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,11 @@ private static function _indexOrderBy(array $viewState)
*/
protected $revisionNotes;

/**
* @var bool
*/
private $_initialized = false;

/**
* @var
*/
Expand All @@ -878,6 +883,12 @@ private static function _indexOrderBy(array $viewState)
*/
private $_normalizedFieldValues;

/**
* @var array Record of dirty fields.
* @see isFieldDirty()
*/
private $_dirtyFields;

/**
* @var
*/
Expand Down Expand Up @@ -1026,6 +1037,8 @@ public function init()
if ($this->siteId === null && Craft::$app->getIsInstalled()) {
$this->siteId = Craft::$app->getSites()->getPrimarySite()->id;
}

$this->_initialized = true;
}

/**
Expand Down Expand Up @@ -1945,6 +1958,38 @@ public function setFieldValue(string $fieldHandle, $value)

// Don't assume that $value has been normalized
unset($this->_normalizedFieldValues[$fieldHandle]);

// If the element is fully initialized, mark the value as dirty
if ($this->_initialized) {
$this->_dirtyFields[$fieldHandle] = true;
}
}

/**
* @inheritdoc
*/
public function isFieldDirty(string $fieldHandle): bool
{
return isset($this->_dirtyFields[$fieldHandle]);
}

/**
* @inheritdoc
*/
public function getDirtyFields(): array
{
if ($this->_dirtyFields) {
return array_keys($this->_dirtyFields);
}
return [];
}

/**
* @inheritdoc
*/
public function clearDirtyFields()
{
$this->_dirtyFields = null;
}

/**
Expand Down Expand Up @@ -2149,18 +2194,21 @@ public function getEditorHtml(): string
$originalNamespace = $view->getNamespace();
$namespace = $view->namespaceInputName('fields', $originalNamespace);
$view->setNamespace($namespace);
$view->setIsDeltaRegistrationActive(true);

foreach ($fieldLayout->getFields() as $field) {
$fieldHtml = $view->renderTemplate('_includes/field', [
'element' => $this,
'field' => $field,
'required' => $field->required
'required' => $field->required,
'registerDeltas' => true,
]);

$html .= $view->namespaceInputs($fieldHtml, 'fields');
}

Craft::$app->getView()->setNamespace($originalNamespace);
$view->setNamespace($originalNamespace);
$view->setIsDeltaRegistrationActive(false);

$html .= Html::hiddenInput('fieldLayoutId', $fieldLayout->id);
}
Expand Down
24 changes: 24 additions & 0 deletions src/base/ElementInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,30 @@ public function getFieldValue(string $fieldHandle);
*/
public function setFieldValue(string $fieldHandle, $value);

/**
* Returns whether a custom field value has changed since the element was first loaded.
*
* @param string $fieldHandle
* @return bool
* @since 3.4.0
*/
public function isFieldDirty(string $fieldHandle): bool;

/**
* Returns a list of custom field handles that have changed since the element was first loaded.
*
* @return string[]
* @since 3.4.0
*/
public function getDirtyFields(): array;

/**
* Resets the record of dirty fields.
*
* @since 3.4.0
*/
public function clearDirtyFields();

/**
* Sets the element’s custom field values, when the values have come from post data.
*
Expand Down
7 changes: 4 additions & 3 deletions src/controllers/ElementsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -396,8 +396,9 @@ private function _getEditorHtmlResponse(ElementInterface $element, bool $include

$response['siteId'] = $element->siteId;

$view = $this->getView();
$namespace = 'editor_' . StringHelper::randomString(10);
$this->getView()->setNamespace($namespace);
$view->setNamespace($namespace);

$response['html'] = '<input type="hidden" name="namespace" value="' . $namespace . '">';

Expand All @@ -410,12 +411,12 @@ private function _getEditorHtmlResponse(ElementInterface $element, bool $include
}

$response['html'] .= '<div class="meta">' .
$this->getView()->namespaceInputs((string)$element->getEditorHtml()) .
$view->namespaceInputs((string)$element->getEditorHtml()) .
'</div>';

$view = $this->getView();
$response['headHtml'] = $view->getHeadHtml();
$response['footHtml'] = $view->getBodyHtml();
$response['deltaNames'] = $view->getDeltaNames();

return $this->asJson($response);
}
Expand Down
7 changes: 7 additions & 0 deletions src/elements/MatrixBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,13 @@ public static function gqlTypeNameByContext($context): string
*/
public $sortOrder;

/**
* @var bool Whether the block has changed.
* @internal
* @since 3.4.0
*/
public $dirty = false;

/**
* @var bool Collapsed
*/
Expand Down
11 changes: 5 additions & 6 deletions src/elements/db/ElementQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -1749,6 +1749,11 @@ public function createElement(array $row): ElementInterface
$row['trashed'] = $row['dateDeleted'] !== null;
}

// Set the custom field values
if (isset($fieldValues)) {
$row['fieldValues'] = $fieldValues;
}

$behaviors = [];

if ($this->drafts) {
Expand All @@ -1773,12 +1778,6 @@ public function createElement(array $row): ElementInterface
$element = new $class($row);
$element->attachBehaviors($behaviors);

// Set the custom field values
/** @noinspection UnSafeIsSetOverArrayInspection - FP */
if (isset($fieldValues)) {
$element->setFieldValues($fieldValues);
}

// Fire an 'afterPopulateElement' event
if ($this->hasEventHandlers(self::EVENT_AFTER_POPULATE_ELEMENT)) {
$this->trigger(self::EVENT_AFTER_POPULATE_ELEMENT, new PopulateElementEvent([
Expand Down
7 changes: 5 additions & 2 deletions src/fields/BaseRelationField.php
Original file line number Diff line number Diff line change
Expand Up @@ -641,9 +641,12 @@ public function afterSave(bool $isNew)
*/
public function afterElementSave(ElementInterface $element, bool $isNew)
{
// Skip if the element is just propagating, and we're not localizing relations
// Skip if nothing changed, or the element is just propagating and we're not localizing relations
/** @var Element $element */
if (!$element->propagating || $this->localizeRelations) {
if (
$element->isFieldDirty($this->handle) &&
(!$element->propagating || $this->localizeRelations)
) {
/** @var ElementQuery $value */
$value = $element->getFieldValue($this->handle);

Expand Down
Loading