diff --git a/administrator/components/com_fields/models/field.php b/administrator/components/com_fields/models/field.php index 02802f897d0ef..6cf51090da0f1 100644 --- a/administrator/components/com_fields/models/field.php +++ b/administrator/components/com_fields/models/field.php @@ -589,8 +589,9 @@ public function setFieldValue($fieldId, $itemId, $value) } elseif (count($value) == 1 && count((array) $oldValue) == 1) { - // Only a single row value update can be done - $needsUpdate = true; + // Only a single row value update can be done when not empty + $needsUpdate = is_array($value[0]) ? count($value[0]) : strlen($value[0]); + $needsDelete = !$needsUpdate; } else { diff --git a/components/com_users/controllers/profile.php b/components/com_users/controllers/profile.php index 594ee0b404ac6..3175402a60221 100644 --- a/components/com_users/controllers/profile.php +++ b/components/com_users/controllers/profile.php @@ -113,6 +113,14 @@ public function save() return false; } + // Send an object which can be modified through the plugin event + $objData = (object) $requestData; + $app->triggerEvent( + 'onContentNormaliseRequestData', + array('com_users.user', $objData, $form) + ); + $requestData = (array) $objData; + // Validate the posted data. $data = $model->validate($form, $requestData); diff --git a/libraries/src/MVC/Controller/FormController.php b/libraries/src/MVC/Controller/FormController.php index 5052dedd5c560..27d532a5d00b8 100644 --- a/libraries/src/MVC/Controller/FormController.php +++ b/libraries/src/MVC/Controller/FormController.php @@ -694,6 +694,14 @@ public function save($key = null, $urlVar = null) return false; } + // Send an object which can be modified through the plugin event + $objData = (object) $data; + $app->triggerEvent( + 'onContentNormaliseRequestData', + array($this->option . '.' . $this->context, $objData, $form) + ); + $data = (array) $objData; + // Test whether the data is valid. $validData = $model->validate($form, $data); diff --git a/plugins/system/fields/fields.php b/plugins/system/fields/fields.php index ba1e1396b3009..746f689f5eedb 100644 --- a/plugins/system/fields/fields.php +++ b/plugins/system/fields/fields.php @@ -9,6 +9,7 @@ defined('_JEXEC') or die; +use Joomla\CMS\Form\Form; use Joomla\Registry\Registry; use Joomla\CMS\Factory; use Joomla\CMS\Language\Multilanguage; @@ -30,6 +31,38 @@ class PlgSystemFields extends JPlugin */ protected $autoloadLanguage = true; + /** + * Normalizes the request data. + * + * @param string $context The context + * @param object $data The object + * @param Form $form The form + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onContentNormaliseRequestData($context, $data, Form $form) + { + if (!FieldsHelper::extract($context, $data)) + { + return true; + } + + // Loop over all fields + foreach ($form->getGroup('com_fields') as $field) + { + // Make sure the data object has an entry + if (isset($data->com_fields[$field->fieldname])) + { + continue; + } + + // Set a default value for the field + $data->com_fields[$field->fieldname] = false; + } + } + /** * The save event. * @@ -45,7 +78,7 @@ class PlgSystemFields extends JPlugin public function onContentAfterSave($context, $item, $isNew, $data = array()) { // Check if data is an array and the item has an id - if (!is_array($data) || empty($item->id)) + if (!is_array($data) || empty($item->id) || empty($data['com_fields'])) { return true; } @@ -78,17 +111,28 @@ public function onContentAfterSave($context, $item, $isNew, $data = array()) return true; } - // Get the fields data - $fieldsData = !empty($data['com_fields']) ? $data['com_fields'] : array(); - // Loading the model $model = JModelLegacy::getInstance('Field', 'FieldsModel', array('ignore_request' => true)); // Loop over the fields foreach ($fields as $field) { - // Determine the value if it is available from the data - $value = key_exists($field->name, $fieldsData) ? $fieldsData[$field->name] : null; + // Determine the value if it is (un)available from the data + if (key_exists($field->name, $data['com_fields'])) + { + $value = $data['com_fields'][$field->name] === false ? null : $data['com_fields'][$field->name]; + } + // Field not available on form, use stored value + else + { + $value = $field->rawvalue; + } + + // If no value set (empty) remove value from database + if (is_array($value) ? !count($value) : !strlen($value)) + { + $value = null; + } // JSON encode value for complex fields if (is_array($value) && (count($value, COUNT_NORMAL) !== count($value, COUNT_RECURSIVE) || !count(array_filter(array_keys($value), 'is_numeric'))))