public function save_field($params, $table_operation = true, $sanitized = false, $db = true)
{
/**
* @var $wpdb wpdb
*/
global $wpdb;
if (true !== $db) {
$table_operation = false;
}
$tableless_field_types = PodsForm::tableless_field_types();
$simple_tableless_objects = PodsForm::simple_tableless_objects();
$params = (object) $params;
if (false === $sanitized) {
$params = pods_sanitize($params);
}
if (isset($params->pod_id)) {
$params->pod_id = pods_absint($params->pod_id);
}
if (true !== $db) {
$params->pod_id = (int) $db;
}
$pod = null;
$save_pod = false;
$id_required = false;
if (isset($params->id_required)) {
unset($params->id_required);
$id_required = true;
}
if ((!isset($params->pod) || empty($params->pod)) && (!isset($params->pod_id) || empty($params->pod_id))) {
return pods_error(__('Pod ID or name is required', 'pods'), $this);
}
if (isset($params->pod) && is_array($params->pod)) {
$pod = $params->pod;
$save_pod = true;
} elseif ((!isset($params->pod_id) || empty($params->pod_id)) && (true === $db || 0 < $db)) {
$pod = $this->load_pod(array('name' => $params->pod, 'table_info' => true));
} elseif (!isset($params->pod) && (true === $db || 0 < $db)) {
$pod = $this->load_pod(array('id' => $params->pod_id, 'table_info' => true));
} elseif (true === $db || 0 < $db) {
$pod = $this->load_pod(array('id' => $params->pod_id, 'name' => $params->pod, 'table_info' => true));
}
if (empty($pod) && true === $db) {
return pods_error(__('Pod not found', 'pods'), $this);
}
$params->pod_id = $pod['id'];
$params->pod = $pod['name'];
$params->pod_data = $pod;
$params->name = pods_clean_name($params->name, true, 'meta' == $pod['storage'] ? false : true);
if (!isset($params->id)) {
$params->id = 0;
}
if (empty($params->name)) {
return pods_error('Pod field name is required', $this);
}
$field = $this->load_field($params);
unset($params->pod_data);
$old_id = $old_name = $old_type = $old_definition = $old_simple = $old_options = $old_sister_id = null;
if (!empty($field)) {
$old_id = pods_var('id', $field);
$old_name = pods_clean_name($field['name'], true, 'meta' == $pod['storage'] ? false : true);
$old_type = $field['type'];
$old_options = $field['options'];
$old_sister_id = (int) pods_var('sister_id', $old_options, 0);
$old_simple = 'pick' == $old_type && in_array(pods_var('pick_object', $field), $simple_tableless_objects);
if (isset($params->name) && !empty($params->name)) {
$field['name'] = $params->name;
}
if ($old_name != $field['name'] && false !== $this->field_exists($params)) {
return pods_error(sprintf(__('Field %s already exists, you cannot rename %s to that', 'pods'), $field['name'], $old_name), $this);
}
if (($id_required || !empty($params->id)) && (empty($old_id) || $old_id != $params->id)) {
return pods_error(sprintf(__('Field %s already exists', 'pods'), $field['name']), $this);
}
if (empty($params->id)) {
$params->id = $old_id;
}
if (!in_array($old_type, $tableless_field_types) || $old_simple) {
$definition = $this->get_field_definition($old_type, array_merge($field, $old_options));
if (0 < strlen($definition)) {
$old_definition = "`{$old_name}` " . $definition;
}
}
} else {
$field = array('id' => 0, 'pod_id' => $params->pod_id, 'name' => $params->name, 'label' => $params->name, 'description' => '', 'type' => 'text', 'pick_object' => '', 'pick_val' => '', 'sister_id' => '', 'weight' => null, 'options' => array());
}
// Setup options
$options = get_object_vars($params);
$options_ignore = array('method', 'table_info', 'attributes', 'group', 'grouped', 'developer_mode', 'dependency', 'depends-on', 'excludes-on');
foreach ($options_ignore as $ignore) {
if (isset($options[$ignore])) {
unset($options[$ignore]);
}
}
if (isset($options['method'])) {
unset($options['method']);
} elseif (isset($options['table_info'])) {
unset($options['table_info']);
}
$exclude = array('id', 'pod_id', 'pod', 'name', 'label', 'description', 'type', 'pick_object', 'pick_val', 'sister_id', 'weight', 'options');
foreach ($exclude as $k => $exclude_field) {
$aliases = array($exclude_field);
if (is_array($exclude_field)) {
$aliases = array_merge(array($k), $exclude_field);
$exclude_field = $k;
}
foreach ($aliases as $alias) {
if (isset($options[$alias])) {
$field[$exclude_field] = pods_trim($options[$alias]);
unset($options[$alias]);
}
}
}
if (strlen($field['label']) < 1) {
$field['label'] = $field['name'];
}
$field['options']['type'] = $field['type'];
if (in_array($field['options']['type'], $tableless_field_types)) {
// Clean up special drop-down in field editor and save out pick_val
$field['pick_object'] = pods_var('pick_object', $field, '', null, true);
if (0 === strpos($field['pick_object'], 'pod-')) {
$field['pick_val'] = pods_str_replace('pod-', '', $field['pick_object'], 1);
$field['pick_object'] = 'pod';
} elseif (0 === strpos($field['pick_object'], 'post_type-')) {
$field['pick_val'] = pods_str_replace('post_type-', '', $field['pick_object'], 1);
$field['pick_object'] = 'post_type';
} elseif (0 === strpos($field['pick_object'], 'taxonomy-')) {
$field['pick_val'] = pods_str_replace('taxonomy-', '', $field['pick_object'], 1);
$field['pick_object'] = 'taxonomy';
} elseif ('table' == $field['pick_object'] && 0 < strlen(pods_var_raw('pick_table', $field['options']))) {
$field['pick_val'] = $field['options']['pick_table'];
$field['pick_object'] = 'table';
} elseif (false === strpos($field['pick_object'], '-') && !in_array($field['pick_object'], array('pod', 'post_type', 'taxonomy'))) {
$field['pick_val'] = '';
} elseif ('custom-simple' == $field['pick_object']) {
$field['pick_val'] = '';
}
$field['options']['pick_object'] = $field['pick_object'];
$field['options']['pick_val'] = $field['pick_val'];
$field['options']['sister_id'] = pods_var('sister_id', $field);
unset($field['pick_object']);
unset($field['pick_val']);
if (isset($field['sister_id'])) {
unset($field['sister_id']);
}
}
$field['options'] = array_merge($field['options'], $options);
$object_fields = (array) pods_var_raw('object_fields', $pod, array(), null, true);
if (0 < $old_id && defined('PODS_FIELD_STRICT') && !PODS_FIELD_STRICT) {
$params->id = $field['id'] = $old_id;
}
// Add new field
if (!isset($params->id) || empty($params->id) || empty($field)) {
if ($table_operation && in_array($field['name'], array('created', 'modified')) && !in_array($field['type'], array('date', 'datetime')) && (!defined('PODS_FIELD_STRICT') || PODS_FIELD_STRICT)) {
return pods_error(sprintf(__('%s is reserved for internal Pods usage, please try a different name', 'pods'), $field['name']), $this);
}
if ($table_operation && 'author' == $field['name'] && 'pick' != $field['type'] && (!defined('PODS_FIELD_STRICT') || PODS_FIELD_STRICT)) {
return pods_error(sprintf(__('%s is reserved for internal Pods usage, please try a different name', 'pods'), $field['name']), $this);
}
if (in_array($field['name'], array('id', 'ID'))) {
return pods_error(sprintf(__('%s is reserved for internal Pods usage, please try a different name', 'pods'), $field['name']), $this);
}
foreach ($object_fields as $object_field => $object_field_opt) {
if ($object_field == $field['name'] || in_array($field['name'], $object_field_opt['alias'])) {
return pods_error(sprintf(__('%s is reserved for internal WordPress or Pods usage, please try a different name. Also consider what WordPress and Pods provide you built-in.', 'pods'), $field['name']), $this);
}
}
if (in_array($field['name'], array('rss'))) {
// Reserved post_name values that can't be used as field names
$field['name'] .= '2';
}
if ('slug' == $field['type'] && true === $db) {
if (in_array($pod['type'], array('post_type', 'taxonomy', 'user'))) {
return pods_error(__('This pod already has an internal WordPress permalink field', 'pods'), $this);
}
$slug_field = get_posts(array('post_type' => '_pods_field', 'orderby' => 'menu_order', 'order' => 'ASC', 'posts_per_page' => 1, 'post_parent' => $field['pod_id'], 'meta_query' => array(array('key' => 'type', 'value' => 'slug'))));
if (!empty($slug_field)) {
return pods_error(__('This pod already has a permalink field', 'pods'), $this);
}
}
// Sink the new field to the bottom of the list
if (null === $field['weight']) {
$field['weight'] = 0;
$bottom_most_field = get_posts(array('post_type' => '_pods_field', 'orderby' => 'menu_order', 'order' => 'DESC', 'posts_per_page' => 1, 'post_parent' => $field['pod_id']));
if (!empty($bottom_most_field)) {
$field['weight'] = pods_absint($bottom_most_field[0]->menu_order) + 1;
}
}
$field['weight'] = pods_absint($field['weight']);
$post_data = array('post_name' => $field['name'], 'post_title' => $field['label'], 'post_content' => $field['description'], 'post_type' => '_pods_field', 'post_parent' => $field['pod_id'], 'post_status' => 'publish', 'menu_order' => $field['weight']);
} else {
if (in_array($field['name'], array('id', 'ID'))) {
if (null !== $old_name) {
return pods_error(sprintf(__('%s is reserved for internal Pods usage, please try a different name', 'pods'), $field['name']), $this);
} else {
return pods_error(sprintf(__('%s is not editable', 'pods'), $field['name']), $this);
}
}
if (null !== $old_name && $field['name'] != $old_name && in_array($field['name'], array('created', 'modified')) && !in_array($field['type'], array('date', 'datetime')) && (!defined('PODS_FIELD_STRICT') || PODS_FIELD_STRICT)) {
return pods_error(sprintf(__('%s is reserved for internal Pods usage, please try a different name', 'pods'), $field['name']), $this);
}
if (null !== $old_name && $field['name'] != $old_name && 'author' == $field['name'] && 'pick' != $field['type'] && (!defined('PODS_FIELD_STRICT') || PODS_FIELD_STRICT)) {
return pods_error(sprintf(__('%s is reserved for internal Pods usage, please try a different name', 'pods'), $field['name']), $this);
}
foreach ($object_fields as $object_field => $object_field_opt) {
if ($object_field != $field['name'] && !in_array($field['name'], $object_field_opt['alias'])) {
continue;
}
if (null !== $old_name) {
return pods_error(sprintf(__('%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods'), $field['name']), $this);
} else {
return pods_error(sprintf(__('%s is not editable', 'pods'), $field['name']), $this);
}
}
$post_data = array('ID' => $field['id'], 'post_name' => $field['name'], 'post_title' => $field['label'], 'post_content' => $field['description']);
if (null !== $field['weight']) {
$field['weight'] = pods_absint($field['weight']);
$post_data['menu_order'] = $field['weight'];
}
}
if (true === $db) {
if (!has_filter('wp_unique_post_slug', array($this, 'save_slug_fix'))) {
add_filter('wp_unique_post_slug', array($this, 'save_slug_fix'), 100, 6);
}
$conflicted = false;
// Headway compatibility fix
if (has_filter('wp_insert_post_data', 'headway_clean_slug', 0)) {
remove_filter('wp_insert_post_data', 'headway_clean_slug', 0);
$conflicted = true;
}
$params->id = $this->save_wp_object('post', $post_data, $field['options'], true, true);
if ($conflicted) {
add_filter('wp_insert_post_data', 'headway_clean_slug', 0);
}
if (false === $params->id) {
return pods_error(__('Cannot save Field', 'pods'), $this);
}
} else {
$params->id = $field['name'];
}
$field['id'] = $params->id;
$simple = 'pick' == $field['type'] && in_array(pods_var('pick_object', $field['options']), $simple_tableless_objects);
$definition = false;
if (!in_array($field['type'], $tableless_field_types) || $simple) {
$field_definition = $this->get_field_definition($field['type'], array_merge($field, $field['options']));
if (0 < strlen($field_definition)) {
$definition = '`' . $field['name'] . '` ' . $field_definition;
}
}
$sister_id = (int) pods_var('sister_id', $field['options'], 0);
if ($table_operation && 'table' == $pod['storage'] && !pods_tableless()) {
if (!empty($old_id)) {
if (($field['type'] != $old_type || $old_simple != $simple) && empty($definition)) {
pods_query("ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$old_name}`", false);
} elseif (0 < strlen($definition)) {
if ($old_name != $field['name'] || $old_simple != $simple) {
$test = false;
if (0 < strlen($old_definition)) {
$test = pods_query("ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false);
}
// If the old field doesn't exist, continue to add a new field
if (false === $test) {
pods_query("ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __('Cannot create new field', 'pods'));
}
} elseif (null !== $old_definition && $definition != $old_definition) {
$test = pods_query("ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false);
// If the old field doesn't exist, continue to add a new field
if (false === $test) {
pods_query("ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __('Cannot create new field', 'pods'));
}
}
}
} elseif (0 < strlen($definition)) {
$test = false;
if (0 < strlen($old_definition)) {
$test = pods_query("ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `" . $field['name'] . "` {$definition}", false);
}
// If the old field doesn't exist, continue to add a new field
if (false === $test) {
pods_query("ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __('Cannot create new field', 'pods'));
}
}
}
if (!empty($old_id) && 'meta' == $pod['storage'] && $old_name != $field['name'] && $pod['meta_table'] != $pod['table']) {
$prepare = array($field['name'], $old_name);
// Users don't have a type
if (!empty($pod['field_type'])) {
$prepare[] = $pod['name'];
}
pods_query("\n UPDATE `{$pod['meta_table']}` AS `m`\n LEFT JOIN `{$pod['table']}` AS `t`\n ON `t`.`{$pod['field_id']}` = `m`.`{$pod['meta_field_id']}`\n SET\n `m`.`{$pod['meta_field_index']}` = %s\n WHERE\n `m`.`{$pod['meta_field_index']}` = %s\n " . (!empty($pod['field_type']) ? " AND `t`.`{$pod['field_type']}` = %s" : ""), $prepare);
}
if ($field['type'] != $old_type && in_array($old_type, $tableless_field_types)) {
delete_post_meta($old_sister_id, 'sister_id');
if (true === $db) {
pods_query("\n DELETE pm\n FROM {$wpdb->postmeta} AS pm\n LEFT JOIN {$wpdb->posts} AS p\n ON p.post_type = '_pods_field'\n AND p.ID = pm.post_id\n WHERE\n p.ID IS NOT NULL\n AND pm.meta_key = 'sister_id'\n AND pm.meta_value = %d\n ", array($params->id));
if (!pods_tableless()) {
pods_query("DELETE FROM @wp_podsrel WHERE `field_id` = {$params->id}", false);
pods_query("\n UPDATE `@wp_podsrel`\n SET `related_field_id` = 0\n WHERE `field_id` = %d\n ", array($old_sister_id));
}
}
} elseif (0 < $sister_id) {
update_post_meta($sister_id, 'sister_id', $params->id);
if (true === $db && !pods_tableless()) {
pods_query("\n UPDATE `@wp_podsrel`\n SET `related_field_id` = %d\n WHERE `field_id` = %d\n ", array($params->id, $sister_id));
}
} elseif (0 < $old_sister_id) {
delete_post_meta($old_sister_id, 'sister_id');
if (true === $db && !pods_tableless()) {
pods_query("\n UPDATE `@wp_podsrel`\n SET `related_field_id` = 0\n WHERE `field_id` = %d\n ", array($old_sister_id));
}
}
if (!empty($old_id) && $old_name != $field['name'] && true === $db) {
pods_query("\n UPDATE `@wp_postmeta`\n SET `meta_value` = %s\n WHERE\n `post_id` = %d\n AND `meta_key` = 'pod_index'\n AND `meta_value` = %s\n ", array($field['name'], $pod['id'], $old_name));
}
if (!$save_pod) {
$this->cache_flush_pods($pod);
} else {
pods_transient_clear('pods_field_' . $pod['name'] . '_' . $field['name']);
if (!empty($old_id) && $old_name != $field['name']) {
pods_transient_clear('pods_field_' . $pod['name'] . '_' . $old_name);
}
}
if (true === $db) {
return $params->id;
} else {
return $field;
}
}