/**
  * @inheritdoc
  *
  * todo document
  *
  * @param array $arguments
  */
 public function process_call($arguments)
 {
     $am = $this->get_am();
     $am->ajax_begin(array('nonce' => $am->get_action_js_name(Types_Ajax::CALLBACK_FIELD_CONTROL_ACTION)));
     // Read and validate input
     $field_action = sanitize_text_field(wpcf_getpost('field_action'));
     $fields = wpcf_getpost('fields');
     // array of values, will be sanitized when processed
     $current_domain = wpcf_getpost('domain', null, Types_Field_Utils::get_domains());
     if (null == $current_domain) {
         $am->ajax_finish(array('message' => __('Wrong field domain.', 'wpcf')), false);
     }
     if (!is_array($fields) || empty($fields)) {
         $am->ajax_finish(array('message' => __('No fields have been selected.', 'wpcf')), false);
     }
     // will be sanitized when/if used by the action-specific method
     $action_specific_data = wpcf_getpost('action_specific', array());
     // Process fields one by one
     $errors = array();
     $results = array();
     foreach ($fields as $field) {
         $result = $this->single_field_control_action($field_action, $field, $current_domain, $action_specific_data);
         if (is_array($result)) {
             // Array of errors
             $errors = array_merge($errors, $result);
         } else {
             if ($result instanceof WP_Error) {
                 // Single error
                 $errors[] = $result;
             } else {
                 if (false == $result) {
                     // This should not happen...!
                     $errors[] = new WP_Error(0, __('An unexpected error happened while processing the request.', 'wpcf'));
                 } else {
                     // Success
                     // Save the field definition model as a result if we got a whole definition
                     if ($result instanceof WPCF_Field_Definition) {
                         $result = $result->to_json();
                     }
                     $results[wpcf_getarr($field, 'slug')] = $result;
                 }
             }
         }
     }
     $data = array('results' => $results);
     $is_success = empty($errors);
     if (!$is_success) {
         $error_messages = array();
         /** @var WP_Error $error */
         foreach ($errors as $error) {
             $error_messages[] = $error->get_error_message();
         }
         $data['messages'] = $error_messages;
     }
     $am->ajax_finish($data, $is_success);
 }
Example #2
0
 /**
  * @return array Array of true and WP_Error, one for each field value.
  */
 public function validate_field_data()
 {
     $field_config = Types_Field_Utils::get_toolset_forms_field_config($this->field);
     $this->toggle_adding_field_names_to_error_messages(false);
     $values = $this->read_field_values();
     $results = array();
     foreach ($values as $key => $value) {
         $results[$key] = $this->validate_single_field_value($field_config, $value);
     }
     $this->toggle_adding_field_names_to_error_messages(true);
     return $results;
 }
 /**
  * Query field groups from a single domain.
  *
  * @param string $domain One of the valid field domains. Legacy "meta type" values will be also accepted.
  * @param array $query Query arguments for Types_Field_Group_Factory::query_groups().
  *
  * @return null|Types_Field_Group[] Array of field groups or null on error.
  * @since m2m
  */
 private function query_specific_domain($domain, $query)
 {
     // Make sure we have a valid domain string.
     $valid_domains = Types_Field_Utils::get_domains();
     if (!in_array($domain, $valid_domains)) {
         $domain = Types_Field_Utils::legacy_meta_type_to_domain($domain);
     }
     // Pass the group query to the proper factory class.
     try {
         $group_factory = Types_Field_Group_Factory::get_factory_by_domain($domain);
         $groups = $group_factory->query_groups($query);
     } catch (Exception $e) {
         // We don't care, it's a failure.
         return null;
     }
     return $groups;
 }
Example #4
0
 /**
  * @param string $action_name One of the allowed action names: 'manage_with_types'
  * @param array $field Field definition model passed from JS.
  * @param string $domain Field domain name.
  * @param mixed $action_specific_data
  * @return bool|mixed|null|WP_Error|WP_Error[]|WPCF_Field_Definition An error, array of errors, boolean indicating
  *     success or a result value to be passed back to JS.
  * @since 2.0
  */
 private function single_field_control_action($action_name, $field, $domain, $action_specific_data)
 {
     $field_slug = wpcf_getarr($field, 'slug');
     switch ($action_name) {
         case 'manage_with_types':
             return Types_Field_Utils::start_managing_field(wpcf_getarr($field, 'metaKey'), $domain);
         case 'stop_managing_with_types':
             return Types_Field_Utils::stop_managing_field($field_slug, $domain);
         case 'change_group_assignment':
             return Types_Field_Utils::change_assignment_to_groups($field_slug, $domain, $action_specific_data);
         case 'delete_field':
             return Types_Field_Utils::delete_field($field_slug, $domain);
         case 'change_field_type':
             return Types_Field_Utils::change_field_type($field_slug, $domain, $action_specific_data);
         case 'change_field_cardinality':
             return Types_Field_Utils::change_field_cardinality($field_slug, $domain, $action_specific_data);
         default:
             return new WP_Error(42, __('Invalid action name.', 'wpcf'));
     }
 }
 public function on_term_update($term_id, $tt_id)
 {
     // Get an array of fields that we need to update. We don't care about their groups here.
     $term = get_term_by('term_taxonomy_id', $tt_id);
     if (!$term instanceof WP_Term) {
         return;
     }
     $factory = Types_Field_Group_Term_Factory::get_instance();
     $groups = $factory->get_groups_by_taxonomy($term->taxonomy);
     if (empty($groups)) {
         return;
     }
     $field_definitions = Types_Field_Utils::get_field_definitions_from_groups($groups);
     $update_errors = $this->update_term_fields($term_id, $field_definitions);
     // Display errors if we have any.
     if (!empty($update_errors)) {
         foreach ($update_errors as $update_error) {
             wpcf_admin_message_store($update_error->get_error_message(), 'error');
         }
         wpcf_admin_message_store(sprintf('<strong>%s</strong>', __('There has been a problem while saving custom fields. Please fix it and try again.', 'wpcf')), 'error');
     }
 }
 /**
  * This method is to be used only for bringing existing fields under Types control.
  *
  * At this point it is assumed that there doesn't exist any field definition for given meta_key.
  * See Types_Field_Utils::start_managing_field() for details.
  *
  * Maybe the usage could be wider, but that is not yet clear from the legacy code. The behaviour is slightly
  * different for meta_keys with the wpcf- prefix from the ones without it. More details in the code.
  *
  * The field will be created as a text field.
  *
  * @param string $meta_key Field meta key.
  *
  * @return string|false New field slug on success, false otherwise.
  * @since 2.0
  */
 public final function create_field_definition_for_existing_fields($meta_key)
 {
     // If the meta_key has our wpcf- prefix, we will not use it in the slug.
     $field_slug = preg_replace('/^wpcf\\-/', '', $meta_key);
     $definition_array = array('slug' => $field_slug, 'meta_key' => $meta_key, 'meta_type' => Types_Field_Utils::domain_to_legacy_meta_type($this->get_domain()), 'type' => Types_Field_Type_Definition_Factory::TEXTFIELD, 'name' => $field_slug, 'description' => '', 'data' => array(), 'id' => $field_slug);
     // Now comes a funny part that I don't fully understand. When the field's meta_key does contain the Types
     // prefix ('wpcf-'), we assume that this was most probably a Types field whose definition got lost. If not,
     // it's a completely "foreign" field that we'll only manage from now on.
     //
     // In the first case, the legacy code says "let's take full control" and that means setting 'controlled' to 0,
     // while for other fields (apparently without "full control") we set 'controlled' to 1... well, ok...
     //
     // But it also says "WATCH THIS! MUST NOT BE DROPPED IN ANY CASE", so let's not drop it.
     //
     // Name of the legacy function is: wpcf_types_cf_under_control().
     //
     // I assume this setting is somehow related to toolset-forms.
     $adding_field_with_prefix = substr($meta_key, 0, strlen(WPCF_Field_Definition::FIELD_META_KEY_PREFIX)) == WPCF_Field_Definition::FIELD_META_KEY_PREFIX;
     $definition_array['data']['controlled'] = $adding_field_with_prefix ? 0 : 1;
     // Sanitize the definition array by type
     $textfield_type = Types_Field_Type_Definition_Factory::get_instance()->load_field_type_definition(Types_Field_Type_Definition_Factory::TEXTFIELD);
     if (null == $textfield_type) {
         return false;
     }
     $definition_array = $textfield_type->sanitize_field_definition_array($definition_array);
     // Save the data
     $this->set_field_definition($field_slug, $definition_array);
     // Indicate success
     return $field_slug;
 }
Example #7
0
 /**
  * Change cardinality of given field, if it is permitted by its type.
  *
  * @param string $field_slug Field definition slug.
  * @param string $domain Field domain.
  * @param string[] $arguments Needs to contain the 'target_cardinality' key with 'single'|'repetitive' value.
  * @return bool|WP_Error|WPCF_Field_Definition The updated definition on succes, error/false otherwise.
  * @since 2.0
  */
 public static function change_field_cardinality($field_slug, $domain, $arguments)
 {
     $factory = Types_Field_Utils::get_definition_factory_by_domain($domain);
     $definition = $factory->load_field_definition($field_slug);
     if (null == $definition) {
         return new WP_Error(42, sprintf(__('Field definition for field "%s" not found in options.', 'wpcf'), sanitize_text_field($field_slug)));
     } else {
         if (!$definition->is_managed_by_types()) {
             return new WP_Error(42, sprintf(__('Field "%s" will not be converted because it is not managed by Types.', 'wpcf'), sanitize_text_field($field_slug)));
         }
     }
     $target_cardinality = wpcf_getarr($arguments, 'target_cardinality', null, array('single', 'repetitive'));
     if (null == $target_cardinality) {
         return false;
     }
     $set_as_repetitive = 'repetitive' == $target_cardinality;
     $result = $definition->set_is_repetitive($set_as_repetitive);
     if ($result) {
         return $definition;
     } else {
         return false;
     }
 }
Example #8
0
 /**
  * Hook for types_filter_query_field_definitions.
  *
  * @param mixed $ignored
  * @param array $query Field definition query. See Types_Field_Definition_Factory::query() for supported arguments.
  *     Additionally, you can specify:
  *     - 'domain': A single field domain (see Types_Field_Utils) or 'all'. Legacy domain names are also accepted.
  *       For 'all', the method returns a multidimensional arrays with results for individual domains:
  *     - 'refresh': A boolean to refresh the definitions, useful when getting data after saving fields
  *       array( 'posts' => array( ... ), 'users' => array( ... ),  ... ).
  *
  * @note The 'refresh' parameter is temporal and might dissapear without prior notice when the groups and fields saving gets integrated in the fields definition factory
  *
  * @return null|array Field definition arrays, sanitized as per field type, or null if an error has occurred.
  * @since 2.1
  */
 public function query_field_definitions($ignored, $query)
 {
     $domain = wpcf_getarr($query, 'domain', 'all');
     if ('all' == $domain) {
         // Call itself for each available domain.
         $results_by_domain = array();
         $domains = Types_Field_Utils::get_domains();
         foreach ($domains as $field_domain) {
             $per_domain_query = $query;
             $per_domain_query['domain'] = $field_domain;
             $results_by_domain[$field_domain] = $this->query_field_definitions(null, $per_domain_query);
         }
         return $results_by_domain;
     } else {
         // Sanitize input
         if (!is_string($domain) || !is_array($query)) {
             return null;
         }
         // Get the factory by domain, and if it fails, try to convert from legacy meta_type value.
         try {
             $definition_factory = Types_Field_Utils::get_definition_factory_by_domain($domain);
         } catch (InvalidArgumentException $e) {
             $definition_factory = null;
         }
         if (null == $definition_factory) {
             try {
                 $definition_factory = Types_Field_Utils::get_definition_factory_by_domain(Types_Field_Utils::legacy_meta_type_to_domain($domain));
             } catch (InvalidArgumentException $e) {
                 return null;
             }
         }
         // Allways query only Types fields.
         $query['filter'] = 'types';
         if (isset($query['refresh']) && $query['refresh']) {
             $definition_factory->clear_definition_storage();
         }
         /** @var WPCF_Field_Definition[] $definitions */
         $definitions = $definition_factory->query_definitions($query);
         $definition_arrays = array();
         foreach ($definitions as $definition) {
             $definition_arrays[] = $definition->get_definition_array();
         }
         return $definition_arrays;
     }
 }
 /**
  * Build an array describing existing field groups within the domain.
  * 
  * @return array
  * @since 2.0
  */
 private function build_group_data()
 {
     $factory = Types_Field_Utils::get_group_factory_by_domain($this->get_current_domain());
     $groups = $factory->query_groups();
     $group_data = array();
     foreach ($groups as $group) {
         $group_data[$group->get_slug()] = array('slug' => $group->get_slug(), 'displayName' => $group->get_display_name());
     }
     return $group_data;
 }
Example #10
0
/**
 * Update an existing field group or create new one.
 *
 * @param array $group
 * @param string $post_type
 * @return int Group ID.
 */
function wpcf_admin_fields_save_group($group, $post_type = TYPES_CUSTOM_FIELD_GROUP_CPT_NAME, $which_fields = 'none')
{
    if (!isset($group['name']) || empty($group['name'])) {
        return false;
    }
    $post = array('post_status' => 'publish', 'post_type' => $post_type, 'post_title' => sanitize_text_field($group['name']), 'post_name' => sanitize_text_field($group['name']), 'post_content' => empty($group['description']) ? '' : $group['description']);
    if (empty($post['post_title'])) {
        wpcf_admin_message(__('Please set name', 'wpcf'), 'error');
        return false;
    }
    $update = false;
    $slug_pre_save = false;
    if (isset($group['id']) && !empty($group['id'])) {
        $update = true;
        $post_to_update = get_post($group['id']);
        if (empty($post_to_update) || $post_to_update->post_type != $post_type) {
            return false;
        }
        $post['ID'] = $post_to_update->ID;
        $slug_pre_save = $post_to_update->post_name;
        $post['post_status'] = $post_to_update->post_status;
    }
    if ($update) {
        $group_id = wp_update_post($post);
        if (!$group_id) {
            return false;
        }
        update_post_meta($group_id, TOOLSET_EDIT_LAST, time());
    } else {
        $group_id = wp_insert_post($post, true);
        if (is_wp_error($group_id)) {
            return false;
        }
    }
    if (isset($group['admin_styles'])) {
        wpcf_admin_fields_save_group_admin_styles($group_id, $group['admin_styles']);
    }
    if (!empty($group['filters_association'])) {
        update_post_meta($group_id, '_wp_types_group_filters_association', $group['filters_association']);
    } else {
        delete_post_meta($group_id, '_wp_types_group_filters_association');
    }
    // WPML register strings
    if (function_exists('icl_register_string')) {
        try {
            // Legacy function gives us only the underlying post type of the field group.
            $group_factory = Types_Field_Utils::get_group_factory_by_post_type($post_type);
            $field_group = $group_factory->load_field_group(sanitize_title($group['name']));
            // Skip registering if the group does not exist.
            if (null != $field_group) {
                $group_wpml = new Types_Wpml_Field_Group($field_group);
                $group_wpml->register($slug_pre_save);
            }
        } catch (InvalidArgumentException $e) {
            // Something is seriously wrong - there's no field group factory for given post type, bail.
        }
    }
    // admin message
    wpcf_admin_fields_save_message($update, $which_fields);
    return $group_id;
}
 /**
  * @param string $domain Valid field domain
  * @param array $group Field group import data as associative array.
  * @param string $conflict_resolution = 'overwrite'|'create_new' Defines how to handle a situation when a
  *     field group already exists in the database.
  *
  * @return array Import results:
  *     'is_success' bool
  *     'display_message' string
  *     'new_group_id' int
  *
  * @since 2.1
  */
 public function import_field_group($domain, $group, $conflict_resolution)
 {
     $group_slug = wpcf_getarr($group, Types_Field_Group::XML_SLUG);
     $group_factory = Types_Field_Utils::get_group_factory_by_domain($domain);
     $existing_groups = $group_factory->query_groups(array('name' => $group_slug));
     $group_already_exists = count($existing_groups) > 0;
     $new_post = array('post_status' => $group['post_status'], 'post_type' => $group_factory->get_post_type(), 'post_title' => $group['post_title'], 'post_content' => !empty($group['post_content']) ? $group['post_content'] : '');
     $update_existing = $group_already_exists && 'overwrite' == $conflict_resolution;
     if ($update_existing) {
         $existing_group = $existing_groups[0];
         $new_post['ID'] = $existing_group->get_id();
         $new_group_id = wp_update_post($new_post);
     } else {
         $new_group_id = wp_insert_post($new_post, true);
     }
     $is_success = !is_wp_error($new_group_id) && 0 < $new_group_id;
     // Update group's postmeta
     if ($is_success && !empty($group['meta'])) {
         foreach ($group['meta'] as $meta_key => $meta_value) {
             if (Types_Field_Group_Term::POSTMETA_ASSOCIATED_TAXONOMY == $meta_key) {
                 $meta_values = explode(',', $meta_value);
                 delete_post_meta($new_group_id, $meta_key);
                 foreach ($meta_values as $single_meta_value) {
                     update_post_meta($new_group_id, $meta_key, $single_meta_value);
                 }
             } else {
                 update_post_meta($new_group_id, $meta_key, $meta_value);
             }
         }
     }
     // Create display message
     if ($is_success) {
         if ($update_existing) {
             $display_message = sprintf(__('Term field group "%s" updated', 'wpcf'), $group['post_title']);
         } else {
             $display_message = sprintf(__('Term field group "%s" added', 'wpcf'), $group['post_title']);
         }
     } else {
         if ($update_existing) {
             $display_message = sprintf(__('Term field group "%s" update failed', 'wpcf'), $group['post_title']);
         } else {
             $display_message = sprintf(__('Term field group "%s" insert failed', 'wpcf'), $group['post_title']);
         }
     }
     return array('is_success' => $is_success, 'display_message' => $display_message, 'new_group_id' => $new_group_id);
 }