Fieldmanager_Field::presave_all PHP Method

presave_all() public method

Presaves all elements in what could be a set of them, dispatches to $this->presave()
public presave_all ( $values, $current_values ) : mixed[]
return mixed[] sanitized values
    public function presave_all($values, $current_values)
    {
        if ($this->limit == 1 && empty($this->multiple)) {
            $values = $this->presave_alter_values(array($values), array($current_values));
            if (!empty($values)) {
                $value = $this->presave($values[0], $current_values);
            } else {
                $value = $values;
            }
            if (!empty($this->index)) {
                $this->save_index(array($value), array($current_values));
            }
            return $value;
        }
        // If $this->limit != 1, and $values is not an array, that'd just be wrong, and possibly an attack, so...
        if ($this->limit != 1 && !is_array($values)) {
            // EXCEPT maybe this is a request to remove indices
            if (!empty($this->index) && null === $values && !empty($current_values) && is_array($current_values)) {
                $this->save_index(null, $current_values);
                return;
            }
            // OR doing cron, where we should just do nothing if there are no values to process.
            // OR we've now accumulated some cases where a null value instead of an empty array is an acceptable case to
            // just bail out instead of throwing an error. If it WAS an attack, bailing should prevent damage.
            if (null === $values || defined('DOING_CRON') && DOING_CRON && empty($values)) {
                return;
            }
            $this->_unauthorized_access(sprintf(__('$values should be an array because $limit is %d', 'fieldmanager'), $this->limit));
        }
        if (empty($values)) {
            $values = array();
        }
        // Remove the proto
        if (isset($values['proto'])) {
            unset($values['proto']);
        }
        // If $this->limit is not 0 or 1, and $values has more than $limit, that could also be an attack...
        if ($this->limit > 1 && count($values) > $this->limit) {
            $this->_unauthorized_access(sprintf(__('submitted %1$d values against a limit of %2$d', 'fieldmanager'), count($values), $this->limit));
        }
        // Check for non-numeric keys
        $keys = array_keys($values);
        foreach ($keys as $key) {
            if (!is_numeric($key)) {
                throw new FM_Exception(esc_html__('Use of a non-numeric key suggests that something is wrong with this group.', 'fieldmanager'));
            }
        }
        // Condense the array to account for middle items removed
        $values = array_values($values);
        $values = $this->presave_alter_values($values, $current_values);
        // If this update results in fewer children, trigger presave on empty children to make up the difference.
        if (!empty($current_values) && is_array($current_values)) {
            foreach (array_diff(array_keys($current_values), array_keys($values)) as $i) {
                $values[$i] = null;
            }
        }
        foreach ($values as $i => $value) {
            $values[$i] = $this->presave($value, empty($current_values[$i]) ? array() : $current_values[$i]);
        }
        if (!$this->save_empty) {
            // reindex the array after removing empty values
            $values = array_values(array_filter($values));
        }
        if (!empty($this->index)) {
            $this->save_index($values, $current_values);
        }
        return $values;
    }

Usage Example

 /**
  * Override presave_all to handle special cases associated with multiple options fields.
  * @input mixed[] $values
  * @return mixed[] sanitized values
  */
 public function presave_all($values, $current_values)
 {
     // Multiple select and radio fields with no values chosen are left out of
     // the post request altogether, requiring special case handling.
     if (1 !== $this->limit && '' === $values) {
         $values = null;
     }
     return parent::presave_all($values, $current_values);
 }