/** * save * Save the form data, excludes widgets and settings api fields. * * @return bool Whether or not data was saved. * * @access public * @static * @since 1.0 */ public static function save() { global $wpdb, $wp_post_types, $wp_taxonomies; $check = piklist_validate::check(); // Get our field data after its been sanitized and validated if (!isset($_REQUEST[piklist::$prefix]['fields']) || isset($_REQUEST[piklist::$prefix]['filter']) || !$check['valid'] || $check['type'] != 'POST') { self::$form_submission = $check['fields_data']; return false; } $fields_data = $check['fields_data']; // Handle normal file uploads foreach ($fields_data as $scope => &$fields) { if (in_array($scope, array('post_meta', 'term_meta', 'user_meta', 'comment_meta'))) { $meta_type = substr($scope, 0, strpos($scope, '_')); foreach ($fields as &$field) { if (!$field['display'] && array_key_exists(piklist::$prefix . $scope, $_FILES) && array_key_exists($field['field'], $_FILES[piklist::$prefix . $scope]['name'])) { $paths = piklist::array_paths($_FILES[piklist::$prefix . $scope]['name'][$field['field']]); if (!empty($paths)) { if (strstr($paths[0], ':')) { foreach ($paths as $path) { $files_path = explode(':', $path); unset($files_path[count($files_path) - 1]); $files_path = array_merge(array(piklist::$prefix . $scope, 'name'), explode(':', $field['field'] . ':' . implode(':', $files_path))); $field_name = explode(':', $path); $field_name = $field_name[1]; $options = $field['options']; foreach ($field['fields'] as $_field) { if ($_field['field'] == $field_name) { $options = $_field['options']; break; } } $storage = array(); $storage_type = isset($field['options']['save']) && $field['options']['save'] == 'url'; $upload = self::save_upload($files_path, $storage, $storage_type); if ($upload) { piklist::array_path_set($field['request_value'], explode(':', $path), current($upload)); } } } else { $path = array_merge(array(piklist::$prefix . $scope, 'name'), array($field['field'])); $storage = is_array($field['request_value']) ? array_filter($field['request_value']) : $field['request_value']; $storage_type = isset($field['options']['save']) && $field['options']['save'] == 'url'; $upload = self::save_upload($path, $storage, $storage_type); if ($upload) { $field['request_value'] = $upload; } } } } } } } $object_ids = array(); // Save field data foreach ($fields_data as $scope => &$fields) { if (in_array($scope, array('post', 'user', 'comment'))) { $objects = array(); foreach ($fields as &$field) { $values = is_array($field['request_value']) ? $field['request_value'] : array($field['request_value']); foreach ($values as $index => $value) { if (is_array($field['object_id'])) { $id = isset($field['object_id'][$index]) ? $field['object_id'][$index] : 'insert-' . $index; } else { $id = isset($field['object_id']) ? $field['object_id'] : 'insert-' . $index; } if (isset($field['object_id'][$id]) && !isset($objects[$field['object_id'][$id]])) { $objects[$id] = array(); } if (isset($field['object_id'][$index]) || $field['object_id']) { $objects[$id][$scope == 'comment' ? $field['relate'] ? 'comment_ID' : 'comment_post_ID' : 'ID'] = $id; } if ($field['request_value'] && !$field['display']) { $field_name = strrpos($field['field'], ':') > 0 ? substr($field['field'], strrpos($field['field'], ':') + 1) : $field['field']; $objects[$id][$field_name] = $value; } } } foreach ($fields as &$field) { if ($field['relate']) { $_object_ids = is_array($field['object_id']) ? $field['object_id'] : array($field['object_id']); foreach ($_object_ids as $_object_id) { if (!isset($objects[$_object_id])) { if (!isset($field['relate']['remove'])) { $field['relate']['remove'] = array(); } array_push($field['relate']['remove'], $_object_id); } } } } foreach ($objects as $id => $object) { $result_id = self::save_object($scope, $object); if (strstr($id, 'insert-')) { foreach ($fields as &$field) { if ($field['object_id']) { $field['object_id'] = is_array($field['object_id']) ? $field['object_id'] : array($field['object_id']); array_push($field['object_id'], $result_id); } else { $field['object_id'] = $result_id; } } } if (!isset($object_ids[$scope])) { $object_ids[$scope] = $result_id; } } } elseif (in_array($scope, array('post_meta', 'term_meta', 'user_meta', 'comment_meta'))) { $meta_type = substr($scope, 0, strpos($scope, '_')); $meta = piklist_meta::get_meta_properties($meta_type); foreach ($fields as &$field) { $field['object_id'] = $field['object_id'] ? $field['object_id'] : $object_ids[$meta_type]; if ($field['object_id'] && !$field['display'] && !strstr($field['field'], ':')) { $save_as = is_string($field['save_as']) ? $field['save_as'] : $field['field']; $grouped = in_array($field['type'], self::$field_list_types['multiple_value']); $current_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT {$meta->id} FROM {$meta->table} WHERE {$meta->object_id} = %d AND meta_key = %s", $field['object_id'], $save_as)); if ($grouped) { $current_group_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT {$meta->id} FROM {$meta->table} WHERE {$meta->object_id} = %d AND meta_key = %s", $field['object_id'], '_' . piklist::$prefix . $save_as)); } if (is_array($field['request_value']) && $field['type'] != 'group') { foreach ($field['request_value'] as $values) { if (is_array($values)) { $meta_ids = array(); foreach ($values as $value) { if (!empty($current_meta_ids)) { $meta_id = array_shift($current_meta_ids); update_metadata_by_mid($meta_type, $meta_id, $value); } else { $meta_id = add_metadata($meta_type, $field['object_id'], $save_as, $value); } if ($meta_id) { array_push($meta_ids, $meta_id); } } if ($grouped) { if (!empty($current_group_meta_ids)) { $group_meta_id = array_shift($current_group_meta_ids); update_metadata_by_mid($meta_type, $group_meta_id, $meta_ids); } else { add_metadata($meta_type, $field['object_id'], '_' . piklist::$prefix . $save_as, $meta_ids); } } } else { if (is_array($values) && count($values) == 1) { $values = current($values); } if (!empty($current_meta_ids)) { $meta_id = array_shift($current_meta_ids); update_metadata_by_mid($meta_type, $meta_id, $values); } else { add_metadata($meta_type, $field['object_id'], $save_as, $values); } } } if (!empty($current_group_meta_ids)) { foreach ($current_group_meta_ids as $current_group_meta_id) { delete_metadata_by_mid($meta_type, $current_group_meta_id); } } } else { if (!empty($current_meta_ids)) { if (is_numeric($field['index_force'])) { if (isset($current_meta_ids[$field['index_force']])) { $meta_id = $current_meta_ids[$field['index_force']]; update_metadata_by_mid($meta_type, $meta_id, $field['request_value']); } else { add_metadata($meta_type, $field['object_id'], $save_as, $field['request_value']); } $current_meta_ids = array(); } else { $meta_id = array_shift($current_meta_ids); } if (isset($meta_id)) { update_metadata_by_mid($meta_type, $meta_id, $field['request_value']); } } else { add_metadata($meta_type, $field['object_id'], $save_as, $field['request_value']); } } if (!empty($current_meta_ids)) { foreach ($current_meta_ids as $current_meta_id) { delete_metadata_by_mid($meta_type, $current_meta_id); } } } } } elseif ($scope == 'taxonomy') { $taxonomies = array(); $append = array(); $ids = array(); foreach ($fields as &$field) { if (!$field['display']) { $taxonomy = is_string($field['save_as']) ? $field['save_as'] : $field['field']; $append[$taxonomy] = isset($field['options']['append']) && is_bool($field['options']['append']) ? $field['options']['append'] : false; if (!isset($taxonomies[$taxonomy])) { $taxonomies[$taxonomy] = array(); $field['object_id'] = $field['object_id'] ? $field['object_id'] : $object_ids[$wp_taxonomies[$taxonomy]->object_type[0]]; $ids[$taxonomy] = $field['object_id']; } if ($field['request_value']) { $request_value = is_array($field['request_value']) ? $field['request_value'] : array($field['request_value']); foreach ($request_value as $terms) { if (!empty($terms)) { $terms = !is_array($terms) ? array($terms) : $terms; foreach ($terms as $term) { if (!in_array($term, $taxonomies[$taxonomy])) { array_push($taxonomies[$taxonomy], is_numeric($term) ? (int) $term : $term); } } } } } } } foreach ($taxonomies as $taxonomy => $terms) { if (isset($wp_taxonomies[$taxonomy]->object_type[0])) { switch ($wp_taxonomies[$taxonomy]->object_type[0]) { case 'user': if (current_user_can('edit_user', $field['object_id']) && current_user_can($wp_taxonomies[$taxonomy]->cap->assign_terms)) { $id = $ids[$taxonomy]; } break; default: $id = $ids[$taxonomy]; break; } } if (isset($id)) { wp_set_object_terms($id, $terms, $taxonomy, $append[$taxonomy]); clean_object_term_cache($id, $taxonomy); } } } elseif ($scope == 'option') { foreach ($fields as &$field) { if ($field['field'] && !stristr($field['field'], ':')) { $value = $field['request_value']; if (is_array($value) && piklist::is_flat($value) && count($value) == 1) { $value = current($value); } if (!isset($field['options']['type'])) { $auto_load = isset($field['options']['auto_load']) ? $field['options']['auto_load'] : null; update_option($field['field'], $value, $auto_load); } elseif ($field['options']['type'] == 'blog' && $field['object_id']) { $deprecated = isset($field['options']['deprecated']) ? $field['options']['deprecated'] : null; update_blog_option($field['object_id'], $field['field'], $value, $deprecated); } elseif ($field['options']['type'] == 'user' && $field['object_id']) { $global = isset($field['options']['global']) ? $field['options']['global'] : false; update_user_option($field['object_id'], $field['field'], $value, $global); } elseif ($field['options']['type'] == 'site') { update_site_option($field['field'], $value); } } } } /** * piklist_save_field * Fires after fields have been saved * * @param $type Field type. * * @since 1.0 */ do_action('piklist_save_field', $scope, $fields); /** * piklist_save_field-{$scope} * Fires after fields have been saved and is scope specific * * @param $type Field type. * * @since 1.0 */ do_action("piklist_save_field-{$scope}", $fields); } self::$form_submission = $fields_data; self::relate(); return true; }
/** * check * Run all validation and sanitization checks against the rendered fields. * * @param array $stored_data The data to parse if the REQUEST object is not used by default. * @param string $fields_id The fields id. * * @return array Results of the check. * * @access public * @static * @since 1.0 */ public static function check($stored_data = null, $fields_id = null) { self::$valid = true; self::$checked = false; if (!$fields_id) { $fields_id = isset($_REQUEST[piklist::$prefix]['fields']) ? esc_attr($_REQUEST[piklist::$prefix]['fields']) : null; } if (!$fields_id || !($fields_data = get_transient(piklist::$prefix . $fields_id))) { return false; } $clones = array(); foreach ($fields_data as $type => &$fields) { foreach ($fields as &$field) { if (!is_null($stored_data)) { if ($field['prefix'] && isset($stored_data[piklist::$prefix . $field['scope']])) { $request_data = $stored_data[piklist::$prefix . $field['scope']]; } elseif (!$field['prefix'] && isset($stored_data[$field['scope']])) { $request_data = $stored_data[$field['scope']]; } else { $request_data = $stored_data; } } else { if ($field['scope'] && isset($_REQUEST[piklist::$prefix . $field['scope']])) { $request_data = $_REQUEST[piklist::$prefix . $field['scope']]; } elseif ($field['scope'] && $field['scope'] == piklist::$prefix && isset($_REQUEST[piklist::$prefix])) { $request_data = $_REQUEST[piklist::$prefix]; } else { $request_data = $_REQUEST; } } if ($request_data && $field['field'] && $field['type'] != 'html') { $field['errors'] = false; if (!in_array($field['field'], $clones)) { if (isset($request_data[$field['field']])) { $field['request_value'] = $request_data[$field['field']]; } elseif (strstr($field['field'], ':')) { $pluck = explode(':', $field['field']); $pluck_field = array_pop($pluck); if (is_numeric($pluck[count($pluck) - 1])) { array_pop($pluck); } $pluck = implode(':', $pluck); if (isset($request_data[$pluck][$pluck_field])) { $field['request_value'] = $request_data[$pluck][$pluck_field]; } else { $request_data = piklist::array_path_get($request_data, explode(':', $pluck)); if (isset($request_data[$pluck_field])) { $field['request_value'] = $request_data[$pluck_field]; } else { $field['request_value'] = $request_data ? piklist::pluck($request_data, $pluck_field) : null; } } } } if ($field['type'] == 'group' && $field['field'] && !strstr($field['field'], ':')) { $paths = piklist::array_paths($field['request_value']); foreach ($paths as $path) { $path = explode(':', $path); if (is_numeric($path[count($path) - 1])) { unset($path[count($path) - 1]); } $path = implode(':', $path); $field_name = $field['field'] . ':' . $path; if (!isset($fields[$path]) && !in_array($field_name, $clones)) { $original = preg_replace('/\\:\\d+\\:/', ':0:', $field_name); $original = explode(':', $original); if (is_numeric($original[count($original) - 1])) { unset($original[count($original) - 1]); } $original = implode(':', $original); if (isset($fields[$original])) { $clone = $fields[$original]; $path = array_reverse(explode(':', $path)); for ($i = 0; $i < count($path); $i++) { if (is_numeric($path[$i])) { $clone['index'] = (int) $path[$i]; break; } } $path = array_reverse($path); $clone['field'] = $field_name; $clone['id'] = piklist_form::get_field_id($clone); $clone['name'] = piklist_form::get_field_name($clone); $clone['request_value'] = piklist::array_path_get($field['request_value'], $path); $original_path = explode(':', $original); $group = array_shift($original_path); $fields[$original]['request_value'] = piklist::array_path_get($field['request_value'], $original_path); $position = array_search($original, array_keys($fields)) + 1; $fields = array_slice($fields, 0, $position, true) + array($field_name => $clone) + array_slice($fields, $position, count($fields) - 1, true); array_push($clones, $field_name); } } } } // Strip Slashes $field['request_value'] = stripslashes_deep($field['request_value']); // Required if ($field['required']) { $field = self::required_value($field); } // Sanitization foreach ($field['sanitize'] as $sanitize) { if (isset(self::$sanitization_rules[$sanitize['type']])) { $sanitization = array_merge(self::$sanitization_rules[$sanitize['type']], $sanitize); if (isset($sanitization['callback'])) { $field = self::sanitize_value_callback($field, $sanitization); if (strstr($field['field'], ':')) { $path = explode(':', $field['field']); $group = array_shift($path); piklist::array_path_set($fields[$group]['request_value'], $path, $field['request_value']); } } } else { $trigger_error = sprintf(__('Sanitization type "%s" is not valid.', 'piklist'), $sanitize['type']); trigger_error($trigger_error, E_USER_NOTICE); } } // Validation foreach ($field['validate'] as $validate) { if (isset(self::$validation_rules[$validate['type']])) { $validation = array_merge(self::$validation_rules[$validate['type']], $validate); if (isset($validation['rule'])) { $field = self::validate_value_rule($field, $validation); } if (isset($validation['callback'])) { $field = self::validate_value_callback($field, $validation, $fields_data); } } else { $trigger_error = sprintf(__('Validation type "%s" is not valid.', 'piklist'), $validate['type']); trigger_error($trigger_error, E_USER_NOTICE); } } } } } self::$checked = true; self::set_data($fields_id, $fields_data); return array('valid' => self::$valid, 'type' => $_SERVER['REQUEST_METHOD'], 'fields_data' => $fields_data); }
/** * pre_update_option * Handle saving the setting. * * @param array $new The new setting object. * @param array $old The old setting object. * * @return public * * @access public * @static * @since 1.0 */ public static function pre_update_option($new, $old = false) { $check = piklist_validate::check($new); if (false !== $check['valid'] && $check['type'] == 'POST') { $fields_data = $check['fields_data']; $setting = $_REQUEST['option_page']; $_old = $old; foreach ($fields_data[$setting] as $field => &$data) { if (!isset($data['display']) || isset($data['display']) && !$data['display']) { if (isset($new[$field])) { $new[$field] = $data['request_value']; } if (!isset($new[$field]) && isset($_old[$field])) { unset($_old[$field]); } if (isset($new[$field]) && is_array($new[$field]) && $data['multiple'] && is_array($data['choices']) && count($data['choices']) == 1) { $new[$field] = current($new[$field]); } if (isset($data['field']) && !$data['display'] && array_key_exists($setting, $_FILES) && array_key_exists($data['field'], $_FILES[$setting]['name'])) { $paths = piklist::array_paths($_FILES[$setting]['name'][$data['field']]); if (!empty($paths)) { if (strstr($paths[0], ':')) { foreach ($paths as $path) { $files_path = explode(':', $path); unset($files_path[count($files_path) - 1]); $files_path = array_merge(array($setting, 'name'), explode(':', $data['field'] . ':' . implode(':', $files_path))); $field_name = explode(':', $path); $field_name = $field_name[1]; $options = $data['options']; foreach ($data['fields'] as $_field) { if ($_field['field'] == $field_name) { $options = $_field['options']; break; } } $storage = array(); $storage_type = isset($options['save']) && $options['save'] == 'url'; $upload = piklist_form::save_upload($files_path, $storage, $storage_type); if ($upload) { piklist::array_path_set($new[$data['field']], explode(':', $path), current($upload)); } } } else { $path = array_merge(array($setting, 'name'), array($data['field'])); $storage = is_array($data['request_value']) ? array_filter($data['request_value']) : $data['request_value']; $storage_type = isset($data['options']['save']) && $data['options']['save'] == 'url'; $upload = piklist_form::save_upload($path, $storage, $storage_type); if ($upload) { $new[$data['field']] = $upload; } } } } } } $settings = wp_parse_args($new, $_old); /** * piklist_pre_update_option * Filter settings before they update. * * @param array $settings All settings fields that are getting saved. * @param $setting The setting. * @param array $new The new data in the form (what is currently being saved) * @param array $old The old data in the form (what is currently in the database) * * @since 1.0 */ $settings = apply_filters('piklist_pre_update_option', $settings, $setting, $new, $old); /** * piklist_pre_update_option_$setting * Filter a particular setting before it's update. * * @param $setting The setting to filter. * @param array $settings All settings fields that are getting saved. * @param array $new The new data in the form (what is currently being saved) * @param array $old The old data in the form (what is currently in the database) * * @since 1.0 */ $settings = apply_filters('piklist_pre_update_option_' . $setting, $settings, $new, $old); } else { $settings = $old; } return $settings; }