chg: [behavior:adminNotification] Added support of watched fields and improved metafield integration

pull/121/head
Sami Mokaddem 2022-10-27 10:12:06 +02:00
parent c8ff7bb4b2
commit ee5adaf971
No known key found for this signature in database
GPG Key ID: 164C473F627A06FA
1 changed files with 68 additions and 19 deletions

View File

@ -72,6 +72,7 @@ class NotifyAdminsBehavior extends Behavior
$watchedFields = !empty($this->getConfig()['fields']) ? $this->getConfig()['fields'] : $entity->getVisible(); $watchedFields = !empty($this->getConfig()['fields']) ? $this->getConfig()['fields'] : $entity->getVisible();
$originalFields = []; $originalFields = [];
$changedFields = $entity->extract($watchedFields); $changedFields = $entity->extract($watchedFields);
$titleTemplate = 'New {0} `{1}` created'; $titleTemplate = 'New {0} `{1}` created';
$title = __( $title = __(
$titleTemplate, $titleTemplate,
@ -79,24 +80,19 @@ class NotifyAdminsBehavior extends Behavior
$entity->get($this->table()->getDisplayField()) $entity->get($this->table()->getDisplayField())
); );
$message = __('New {0}', Inflector::singularize($entity->getSource())); $message = __('New {0}', Inflector::singularize($entity->getSource()));
if (!$entity->isNew()) { if (!$entity->isNew()) {
$originalFields = $this->_getOriginalChangedFields($entity, $watchedFields); $originalFields = $this->_getOriginalFields($entity, $watchedFields);
if ($entity->table()->hasBehavior('MetaFields') && !empty($entity->meta_fields)) { $changedFields = $this->_getChangedFields($entity, $originalFields);
$originalFields['meta_fields'] = array_merge(
$originalFields['meta_fields'], if (
$this->_getDeletedMetafields($entity) $entity->table()->hasBehavior('Timestamp') &&
); count($changedFields) == 1 && !empty($changedFields['modified'])
} ) {
$changedFields = $entity->extract(array_keys($originalFields)); return; // A not watched field has changed
if ($entity->table()->hasBehavior('MetaFields') && !empty($entity->meta_fields)) {
$originalFields['meta_fields'] = array_map(function($metaField) {
$originalValues = $metaField->getOriginalValues($metaField->getVisible());
$metaField->set($originalValues);
return $metaField;
}, $originalFields['meta_fields']);
$originalFields['meta_fields'] = $this->_massageMetaField($entity, $originalFields['meta_fields']);
$changedFields['meta_fields'] = $this->_massageMetaField($entity, $changedFields['meta_fields']);
} }
$changeAmount = $this->_computeChangeAmount($entity, $originalFields, $changedFields);
$titleTemplate = '{0} {1} modified'; $titleTemplate = '{0} {1} modified';
$title = __( $title = __(
$titleTemplate, $titleTemplate,
@ -106,10 +102,18 @@ class NotifyAdminsBehavior extends Behavior
$message = __n( $message = __n(
'{0} field was updated', '{0} field was updated',
'{0} fields were updated', '{0} fields were updated',
count($changedFields), $changeAmount,
count($changedFields) $changeAmount
); );
} }
if ($entity->table()->hasBehavior('MetaFields')) {
$originalFields['meta_fields'] = $this->_massageMetaField($entity, $originalFields['meta_fields'] ?? []);
$changedFields['meta_fields'] = $this->_massageMetaField($entity, $changedFields['meta_fields'] ?? []);
if (empty($originalFields['meta_fields']) && empty($changedFields['meta_fields'])) {
unset($originalFields['meta_fields']);
unset($changedFields['meta_fields']);
}
}
$data = [ $data = [
'original' => $this->_serializeFields($originalFields), 'original' => $this->_serializeFields($originalFields),
'changed' => $this->_serializeFields($changedFields), 'changed' => $this->_serializeFields($changedFields),
@ -198,7 +202,7 @@ class NotifyAdminsBehavior extends Behavior
->all()->toList(); ->all()->toList();
} }
protected function _getOriginalChangedFields($entity, array $fields): array protected function _getOriginalFields(AppModel $entity, array $fields): array
{ {
$originalChangedFields = $entity->extractOriginalChanged($fields); $originalChangedFields = $entity->extractOriginalChanged($fields);
$originalChangedFields = array_map(function ($fieldValue) { $originalChangedFields = array_map(function ($fieldValue) {
@ -218,9 +222,40 @@ class NotifyAdminsBehavior extends Behavior
} }
return $fieldValue; return $fieldValue;
}, $originalChangedFields); }, $originalChangedFields);
if ($entity->table()->hasBehavior('MetaFields')) {
// Include deleted meta-fields
$originalChangedFields['meta_fields'] = array_merge(
$originalChangedFields['meta_fields'] ?? [],
$this->_getDeletedMetafields($entity)
);
// Restore original values of meta-fields as the entity has been saved with the changes
if (!empty($entity->meta_fields)) {
$originalChangedFields['meta_fields'] = array_map(function ($metaField) {
$originalValues = $metaField->getOriginalValues($metaField->getVisible());
$originalMetafield = $metaField->table()->newEntity($metaField->toArray());
$originalMetafield->set($originalValues);
return $originalMetafield;
}, $originalChangedFields['meta_fields']);
}
}
return $originalChangedFields; return $originalChangedFields;
} }
protected function _getChangedFields(AppModel $entity, array $originalFields): array
{
$changedFields = array_filter(
$entity->extract(array_keys($originalFields)),
fn ($v) => !is_null($v)
);
if ($entity->table()->hasBehavior('MetaFields')) {
$changedMetafields = $entity->extractOriginalChanged($entity->getVisible())['meta_fields'] ?? [];
$changedFields['meta_fields'] = array_filter($changedMetafields, function($metaField) {
return !empty($metaField->getDirty());
});
}
return $changedFields;
}
protected function _massageMetaField(AppModel $entity, array $metaFields): array protected function _massageMetaField(AppModel $entity, array $metaFields): array
{ {
$massaged = []; $massaged = [];
@ -250,6 +285,20 @@ class NotifyAdminsBehavior extends Behavior
return $entity->_metafields_to_delete ?? []; return $entity->_metafields_to_delete ?? [];
} }
protected function _computeChangeAmount(AppModel $entity, array $originalFields, array $changedFields): int
{
$amount = count($changedFields);
if ($entity->table()->hasBehavior('MetaFields')) {
$amount -= 1; // `meta_fields` key was counted without checking at the content
}
if (!empty($originalFields['meta_fields']) && !empty($changedFields['meta_fields'])) {
$amount += count(array_intersect_key($originalFields['meta_fields'] ?? [], $changedFields['meta_fields'] ?? [])); // Add changed fields
$amount += count(array_diff_key($changedFields['meta_fields'] ?? [], $originalFields['meta_fields'] ?? [])); // Add new fields
$amount += count(array_diff_key($originalFields['meta_fields'] ?? [], $changedFields['meta_fields'] ?? [])); // Add deleted fields
}
return $amount;
}
protected function _serializeFields($fields): array protected function _serializeFields($fields): array
{ {
return array_map(function ($fieldValue) { return array_map(function ($fieldValue) {