From 0d633e8f509d89a1b7cca915d0e24451eb514296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Dufraisse?= Date: Mon, 27 Jun 2022 18:39:18 +0200 Subject: [PATCH] fix(BazarFields): change canEdit signature and create formatValuesBeforeSaveIfEditable methods BREAKING_CHANGE custom fields must change canEdit signature --- tools/attach/handlers/UpdateHandler__.php | 2 +- tools/bazar/fields/BazarField.php | 12 +++++++++--- tools/bazar/fields/CheckboxField.php | 7 ++++++- tools/bazar/fields/MapField.php | 8 ++++++-- tools/bazar/fields/PasswordField.php | 7 ++++++- tools/bazar/fields/TitleField.php | 2 +- tools/bazar/handlers/UpdateHandler__.php | 2 +- tools/bazar/services/EntryManager.php | 13 +++++++------ 8 files changed, 37 insertions(+), 16 deletions(-) diff --git a/tools/attach/handlers/UpdateHandler__.php b/tools/attach/handlers/UpdateHandler__.php index d69ad8107..e3db257c4 100644 --- a/tools/attach/handlers/UpdateHandler__.php +++ b/tools/attach/handlers/UpdateHandler__.php @@ -88,7 +88,7 @@ private function extractImages(array $page): bool $updated = false; foreach ($form['prepared'] as $field) { if ($field instanceof TextareaField && !empty($entry[$field->getPropertyName()])) { - $newValue = $field->formatValuesBeforeSave($entry); + $newValue = $field->formatValuesBeforeSaveIfEditable($entry); if (isset($newValue[$field->getPropertyName()])) { $oldValue = json_encode($entry[$field->getPropertyName()]); $newValue = json_encode($newValue[$field->getPropertyName()]); diff --git a/tools/bazar/fields/BazarField.php b/tools/bazar/fields/BazarField.php index 0ad80c01f..b1ee64190 100644 --- a/tools/bazar/fields/BazarField.php +++ b/tools/bazar/fields/BazarField.php @@ -85,13 +85,20 @@ public function renderStaticIfPermitted($entry, ?string $userNameForRendering = public function renderInputIfPermitted($entry) { // Safety checks, must be run before every renderInput - if (!$this->canEdit($entry)) { + if (!$this->canEdit($entry, !$entry)) { return ''; } return $this->renderInput($entry); } + public function formatValuesBeforeSaveIfEditable($entry, bool $isCreation = false) + { + // this method is defined to check $this->canEdit with $isCreation + // without changing signature of formatValuesBeforeSave() + return $this->formatValuesBeforeSave($entry); + } + // Format input values before save public function formatValuesBeforeSave($entry) { @@ -145,10 +152,9 @@ public function canRead($entry, ?string $userNameForRendering = null) } /* Return true if we are if editing is allowed for the field */ - public function canEdit($entry) + public function canEdit($entry, bool $isCreation = false) { $writeAcl = empty($this->writeAccess) ? '' : $this->writeAccess; - $isCreation = !$entry; return empty($writeAcl) || $this->getService(AclService::class)->check($writeAcl, null, true, $isCreation ? '' : $entry['id_fiche'], $isCreation ? 'creation' : 'edit'); } diff --git a/tools/bazar/fields/CheckboxField.php b/tools/bazar/fields/CheckboxField.php index ad3547c2b..eeb477afb 100644 --- a/tools/bazar/fields/CheckboxField.php +++ b/tools/bazar/fields/CheckboxField.php @@ -80,7 +80,12 @@ public function getValues($entry) public function formatValuesBeforeSave($entry) { - if ($this->canEdit($entry)) { + return $this->formatValuesBeforeSaveIfEditable($entry, false); + } + + public function formatValuesBeforeSaveIfEditable($entry, bool $isCreation = false) + { + if ($this->canEdit($entry, $isCreation)) { // get value $checkboxField = $entry[$this->propertyName] ?? null ; // detect if from Form to check if clean field diff --git a/tools/bazar/fields/MapField.php b/tools/bazar/fields/MapField.php index 1fc2c7d8b..31e7c4b19 100644 --- a/tools/bazar/fields/MapField.php +++ b/tools/bazar/fields/MapField.php @@ -271,10 +271,14 @@ function geocodedmarkerRefresh( point ) 'longitude' => is_array($value) && !empty($value[$this->getLongitudeField()]) ? $value[$this->getLongitudeField()] : null ]); } - public function formatValuesBeforeSave($entry) { - if (!$this->canEdit($entry)) { + return $this->formatValuesBeforeSaveIfEditable($entry, false); + } + + public function formatValuesBeforeSaveIfEditable($entry, bool $isCreation = false) + { + if (!$this->canEdit($entry, $isCreation)) { // retrieve value from value because redefined with right value $values = $this->getValue($entry); if (empty($values)) { diff --git a/tools/bazar/fields/PasswordField.php b/tools/bazar/fields/PasswordField.php index 0c7e47687..1a008e343 100644 --- a/tools/bazar/fields/PasswordField.php +++ b/tools/bazar/fields/PasswordField.php @@ -21,9 +21,14 @@ public function __construct(array $values, ContainerInterface $services) } public function formatValuesBeforeSave($entry) + { + return $this->formatValuesBeforeSaveIfEditable($entry, false); + } + + public function formatValuesBeforeSaveIfEditable($entry, bool $isCreation = false) { $value = $this->getValue($entry); - if ($this->canEdit($entry)) { + if ($this->canEdit($entry, $isCreation)) { if (!empty($value)) { // If a new password has been set, encode it return [$this->propertyName => md5($value), diff --git a/tools/bazar/fields/TitleField.php b/tools/bazar/fields/TitleField.php index 3bb09ee1a..408716e5b 100644 --- a/tools/bazar/fields/TitleField.php +++ b/tools/bazar/fields/TitleField.php @@ -49,7 +49,7 @@ public function formatValuesBeforeSave($entry) $fieldValue = $field->getValue($entry); if ($field instanceof CheckboxField) { // get first value instead of keys - $formattedValue = $field->formatValuesBeforeSave($entry)[$field->getPropertyName()]; + $formattedValue = $field->formatValuesBeforeSaveIfEditable($entry)[$field->getPropertyName()]; $fieldValues = $field->getValues([$field->getPropertyName() => $formattedValue]); $replacement = $field->getOptions()[$fieldValues[0] ?? null] ?? ''; } elseif ($field instanceof TagsField) { diff --git a/tools/bazar/handlers/UpdateHandler__.php b/tools/bazar/handlers/UpdateHandler__.php index f69c3b50f..3070ff953 100644 --- a/tools/bazar/handlers/UpdateHandler__.php +++ b/tools/bazar/handlers/UpdateHandler__.php @@ -97,7 +97,7 @@ private function extractOldCarto(array $entry): bool if ($field instanceof MapField) { // update location $entry = array_merge($entry, $this->getMapFieldValue($field, $entry)); - $tab = $field->formatValuesBeforeSave($entry); + $tab = $field->formatValuesBeforeSaveIfEditable($entry); if (is_array($tab)) { if (isset($tab['fields-to-remove']) and is_array($tab['fields-to-remove'])) { foreach ($tab['fields-to-remove'] as $fieldName) { diff --git a/tools/bazar/services/EntryManager.php b/tools/bazar/services/EntryManager.php index 5d1088a99..6f7b732f5 100644 --- a/tools/bazar/services/EntryManager.php +++ b/tools/bazar/services/EntryManager.php @@ -499,7 +499,7 @@ public function create($formId, $data, $semantic = false, $sourceUrl = null) $this->validate($data); - $data = $this->formatDataBeforeSave($data); + $data = $this->formatDataBeforeSave($data, true); // on change provisoirement d'utilisateur if (isset($GLOBALS['utilisateur_wikini'])) { @@ -610,7 +610,7 @@ public function update($tag, $data, $semantic = false, $replace = false) $this->validate($data); - $data = $this->formatDataBeforeSave($data); + $data = $this->formatDataBeforeSave($data, false); // get the sendmail and remove it before saving $sendmail = $this->removeSendmail($data); @@ -648,7 +648,7 @@ protected function assignRestrictedFields(array $data, array $previousData, arra // be carefull : BazarField's objects, that do not save data (as ACL, Label, Hidden), do not have propertyName // see BazarField->formatValuesBeforeSave() for details // so do not save the previous data even if existing - if (!empty($propName) && !$field->canEdit($data)) { + if (!empty($propName) && !$field->canEdit($data, false)) { $restrictedFields[] = $propName; } } @@ -761,10 +761,11 @@ public function decode($body) * prepare la requete d'insertion ou de MAJ de la fiche en supprimant * de la valeur POST les valeurs inadequates et en formattant les champs. * @param $data + * @param bool $isCreation * @return array * @throws Exception */ - public function formatDataBeforeSave($data) + public function formatDataBeforeSave($data, bool $isCreation = false) { // not possible to init the formManager in the constructor because of circular reference problem $form = $this->wiki->services->get(FormManager::class)->getOne($data['id_typeannonce']); @@ -772,7 +773,7 @@ public function formatDataBeforeSave($data) // If there is a title field, compute the entry's title foreach ($form['prepared'] as $field) { if ($field instanceof TitleField) { - $data = array_merge($data, $field->formatValuesBeforeSave($data)); + $data = array_merge($data, $field->formatValuesBeforeSaveIfEditable($data, $isCreation)); } } @@ -803,7 +804,7 @@ public function formatDataBeforeSave($data) foreach ($form['prepared'] as $bazarField) { if ($bazarField instanceof BazarField) { - $tab = $bazarField->formatValuesBeforeSave($data); + $tab = $bazarField->formatValuesBeforeSaveIfEditable($data, $isCreation); } if (is_array($tab)) {