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;
}