Пример #1
0
 /**
  * Get the purpose of the page that is being displayed, depending on provided data and user capabilities.
  *
  * @return string 'add'|'edit'|'view'. Note that 'edit' is also returned when the new group is about to be created,
  * but it doesn't exist yet (has no ID).
  */
 public function get_page_purpose()
 {
     $role_type = 'term-field';
     $group_id = wpcf_getget('group_id');
     $is_group_specified = 0 != $group_id;
     if ($is_group_specified) {
         if (WPCF_Roles::user_can_edit($role_type, array('id' => $group_id))) {
             $purpose = 'edit';
         } else {
             $purpose = 'view';
         }
     } else {
         if ($this->is_there_something_to_save()) {
             if (WPCF_Roles::user_can_create($role_type)) {
                 // We're creating a group now, the page will be used for editing it.
                 $purpose = 'edit';
             } else {
                 $purpose = 'view';
             }
         } else {
             if (WPCF_Roles::user_can_create($role_type)) {
                 $purpose = 'add';
             } else {
                 $purpose = 'view';
                 // Invalid state
             }
         }
     }
     return $purpose;
 }
Пример #2
0
 /**
  * Call this only if you are actually showing the page.
  */
 public function initialize()
 {
     $page_hook = wpcf_admin_add_submenu_page(array('menu_title' => $this->get_title(), 'function' => array($this, 'page_handler'), 'capability_filter' => 'wpcf_tfc_view'), wpcf_getget('page'));
     // I hate having to do this. Refactor!
     require_once WPCF_INC_ABSPATH . '/fields.php';
     wpcf_fields_contol_common_resources();
     add_action("load-{$page_hook}", array($this, 'add_screen_options'));
 }
Пример #3
0
 /**
  * Add all Types submenus and jumpstart a specific page controller if needed.
  *
  * Toolset shared menu usage is described here:
  * @link https://git.onthegosystems.com/toolset/toolset-common/wikis/toolset-shared-menu
  *
  * @param array $pages Array of menu item definitions.
  * @return array Updated item definition array.
  * @since 2.0
  */
 public function on_admin_menu($pages)
 {
     // Add legacy pages
     $pages = wpcf_admin_toolset_register_menu_pages($pages);
     $page_name = sanitize_text_field(wpcf_getget('page'));
     if (!empty($page_name)) {
         $pages = $this->maybe_add_ondemand_submenu($pages, $page_name);
     }
     return $pages;
 }
Пример #4
0
 /**
  * Call this only if you are actually showing the page.
  */
 public function initialize()
 {
     $hook = wpcf_admin_add_submenu_page(array('menu_title' => $this->get_menu_title(), 'function' => array($this, 'page_handler'), 'capability' => WPCF_TERM_FIELD_EDIT), wpcf_getget('page'));
     $load_page_action = 'load-' . $hook;
     // Prepare form, which includes saving data and optionally redirecting to the edit page with group ID
     // as GET parameter. That's why it must be executed earlier than as a menu page callback.
     add_action($load_page_action, array($this, 'prepare_form_maybe_redirect'));
     // This one handles enqueuing script and styles. Originally it is meant for post fields and it also probably
     // does some things that are not needed now.
     add_action($load_page_action, 'wpcf_admin_enqueue_group_edit_page_assets');
     wpcf_admin_plugin_help($hook, self::PAGE_NAME);
 }
Пример #5
0
 function prepare_items()
 {
     $per_page = $this->get_items_per_page(WPCF_Page_Control_Termmeta::SCREEN_OPTION_PER_PAGE_NAME, 10);
     $columns = $this->get_columns();
     $hidden = array();
     $sortable = $this->get_sortable_columns();
     $this->_column_headers = array($columns, $hidden, $sortable);
     $this->process_bulk_action();
     $search_string = mb_strtolower(trim(wpcf_getpost('s')));
     $query_args = array('filter' => 'all', 'orderby' => sanitize_text_field(wpcf_getget('orderby', 'name')), 'order' => sanitize_text_field(wpcf_getget('order', 'asc')), 'search' => $search_string);
     $definitions = WPCF_Field_Term_Definition_Factory::get_instance()->query_definitions($query_args);
     $current_page = $this->get_pagenum();
     $total_items = count($definitions);
     $definitions = array_slice($definitions, ($current_page - 1) * $per_page, $per_page);
     $this->items = $definitions;
     $this->set_pagination_args(array('total_items' => $total_items, 'per_page' => $per_page, 'total_pages' => ceil($total_items / $per_page)));
 }
 /**
  * Add help tabs to current screen.
  *
  * Used as a hook for 'contextual_help_hook' in the shared Toolset menu.
  *
  * @since 2.0
  */
 public function add_help_tab()
 {
     $screen = get_current_screen();
     if (is_null($screen)) {
         return;
     }
     $current_page = sanitize_text_field(wpcf_getget('page', null));
     if (null == $current_page) {
         return;
     }
     $help_content = $this->get_help_content($current_page);
     if (null == $help_content) {
         return;
     }
     $args = array('title' => wpcf_getarr($help_content, 'title'), 'id' => 'wpcf', 'content' => wpcf_getarr($help_content, 'content'), 'callback' => false);
     $screen->add_help_tab($args);
     $this->add_need_help_tab();
 }
Пример #7
0
 function prepare_items()
 {
     $per_page = $this->get_items_per_page(WPCF_Page_Listing_Termmeta::SCREEN_OPTION_PER_PAGE_NAME, WPCF_Page_Listing_Termmeta::SCREEN_OPTION_PER_PAGE_DEFAULT_VALUE);
     $columns = $this->get_columns();
     $hidden = array();
     $sortable = $this->get_sortable_columns();
     $this->_column_headers = array($columns, $hidden, $sortable);
     $this->process_bulk_action();
     $search_string = isset($_POST['s']) ? mb_strtolower(trim($_POST['s'])) : null;
     $query_args = array('orderby' => sanitize_text_field(wpcf_getget('orderby', 'post_title')), 'order' => sanitize_text_field(wpcf_getget('order', 'asc')));
     $groups = WPCF_Field_Group_Term_Factory::get_instance()->query_groups($query_args, $search_string);
     /**
      * REQUIRED for pagination. Let's figure out what page the user is currently
      * looking at. We'll need this later, so you should always include it in
      * your own package classes.
      */
     $current_page = $this->get_pagenum();
     /**
      * REQUIRED for pagination. Let's check how many items are in our data array.
      * In real-world use, this would be the total number of items in your database,
      * without filtering. We'll need this later, so you should always include it
      * in your own package classes.
      */
     $total_items = count($groups);
     /**
      * The WP_List_Table class does not handle pagination for us, so we need
      * to ensure that the data is trimmed to only the current page. We can use
      * array_slice() to
      */
     $groups = array_slice($groups, ($current_page - 1) * $per_page, $per_page);
     /**
      * REQUIRED. Now we can add our *sorted* data to the items property, where
      * it can be used by the rest of the class.
      */
     $this->items = $groups;
     /**
      * REQUIRED. We also have to register our pagination options & calculations.
      */
     $this->set_pagination_args(array('total_items' => $total_items, 'per_page' => $per_page, 'total_pages' => ceil($total_items / $per_page)));
 }
 /**
  * Add/edit form
  */
 public function form()
 {
     $this->save();
     // Flush rewrite rules if we're asked to do so.
     //
     // This must be done after all post types and taxonomies are registered, and they can be registered properly
     // only on 'init'. So after making changes, we need to reload the page and THEN flush.
     if ('1' == wpcf_getget('flush', '0')) {
         flush_rewrite_rules();
     }
     global $wpcf;
     $id = false;
     $update = false;
     if (isset($_GET[$this->get_id])) {
         $id = sanitize_text_field($_GET[$this->get_id]);
     } elseif (isset($_POST[$this->get_id])) {
         $id = sanitize_text_field($_POST[$this->get_id]);
     }
     /**
      * get current post type
      */
     require_once WPCF_INC_ABSPATH . '/classes/class.types.admin.post-type.php';
     $wpcf_post_type = new Types_Admin_Post_Type();
     $custom_post_type = $wpcf_post_type->get_post_type($id);
     if (empty($custom_post_type)) {
         wpcf_admin_message(__('Please save new Post Type first.', 'wpcf'), 'error');
         die;
     }
     $this->ct = $custom_post_type;
     $current_user_can_edit = WPCF_Roles::user_can_edit('custom-post-type', $this->ct);
     /**
      * sanitize _builtin
      */
     if (!isset($this->ct['_builtin'])) {
         $this->ct['_builtin'] = false;
     }
     /**
      * fix taxonomies assigment for builitin post types
      */
     if ($this->ct['_builtin']) {
         $taxonomies = get_taxonomies('', 'objects');
         foreach ($taxonomies as $slug => $tax) {
             foreach ($tax->object_type as $post_slug) {
                 if ($this->ct['slug'] == $post_slug) {
                     $this->ct['taxonomies'][$slug] = 1;
                 }
             }
         }
     }
     $form = $this->prepare_screen();
     if ($current_user_can_edit && $this->ct['update']) {
         $form['id'] = array('#type' => 'hidden', '#value' => $id, '#name' => 'ct[wpcf-post-type]', '_builtin' => true);
         /**
          * update Taxonomy too
          */
         $custom_taxonomies = get_option(WPCF_OPTION_NAME_CUSTOM_TAXONOMIES, array());
         foreach ($custom_taxonomies as $slug => $data) {
             if (!array_key_exists('supports', $data)) {
                 continue;
             }
             if (!array_key_exists($id, $data['supports'])) {
                 continue;
             }
             if (array_key_exists('taxonomies', $this->ct) && array_key_exists($slug, $this->ct['taxonomies'])) {
                 continue;
             }
             unset($custom_taxonomies[$slug]['supports'][$id]);
         }
         update_option(WPCF_OPTION_NAME_CUSTOM_TAXONOMIES, $custom_taxonomies);
     }
     /*
      * menu icon
      */
     switch ($this->ct['slug']) {
         case 'page':
             $menu_icon = 'admin-page';
             break;
         case 'attachment':
             $menu_icon = 'admin-media';
             break;
         default:
             $menu_icon = isset($this->ct['icon']) && !empty($this->ct['icon']) ? $this->ct['icon'] : 'admin-post';
             break;
     }
     /**
      * post icon field
      */
     $form['icon'] = array('#type' => 'hidden', '#name' => 'ct[icon]', '#value' => $menu_icon, '#id' => 'wpcf-types-icon');
     $form['form-open'] = array('#type' => 'markup', '#markup' => sprintf('<div id="post-body-content" class="%s">', $current_user_can_edit ? '' : 'wpcf-types-read-only'), '_builtin' => true);
     $form['table-1-open'] = array('#type' => 'markup', '#markup' => '<table id="wpcf-types-form-name-table" class="wpcf-types-form-table widefat js-wpcf-slugize-container"><thead><tr><th colspan="2">' . __('Post Type name and description', 'wpcf') . '</th></tr></thead><tbody>', '_builtin' => true);
     $table_row = '<tr><td><LABEL></td><td><ERROR><BEFORE><ELEMENT><AFTER></td></tr>';
     $form['name'] = array('#type' => 'textfield', '#name' => 'ct[labels][name]', '#title' => __('Post Type name plural', 'wpcf') . ' (<strong>' . __('required', 'wpcf') . '</strong>)', '#description' => '<strong>' . __('Enter in plural!', 'wpcf') . '.', '#value' => isset($this->ct['labels']['name']) ? $this->ct['labels']['name'] : '', '#validate' => array('required' => array('value' => 'true')), '#pattern' => $table_row, '#inline' => true, '#id' => 'name-plural', '#attributes' => array('data-wpcf_warning_same_as_slug' => $wpcf->post_types->message('warning_singular_plural_match'), 'data-wpcf_warning_same_as_slug_ignore' => $wpcf->post_types->message('warning_singular_plural_match_ignore'), 'placeholder' => __('Enter Post Type name plural', 'wpcf'), 'class' => 'large-text'), '_builtin' => true);
     $form['name-singular'] = array('#type' => 'textfield', '#name' => 'ct[labels][singular_name]', '#title' => __('Post Type name singular', 'wpcf') . ' (<strong>' . __('required', 'wpcf') . '</strong>)', '#description' => '<strong>' . __('Enter in singular!', 'wpcf') . '</strong><br />' . '.', '#value' => isset($this->ct['labels']['singular_name']) ? $this->ct['labels']['singular_name'] : '', '#validate' => array('required' => array('value' => 'true')), '#pattern' => $table_row, '#inline' => true, '#id' => 'name-singular', '#attributes' => array('placeholder' => __('Enter Post Type name singular', 'wpcf'), 'class' => 'js-wpcf-slugize-source large-text'), '_builtin' => true);
     /**
      * IF isset $_POST['slug'] it means form is not submitted
      */
     $attributes = array();
     if (!empty($_POST['ct']['slug'])) {
         $reserved = wpcf_is_reserved_name(sanitize_text_field($_POST['ct']['slug']), 'post_type');
         if (is_wp_error($reserved)) {
             $attributes = array('class' => 'wpcf-form-error', 'onclick' => 'jQuery(this).removeClass(\'wpcf-form-error\');');
         }
     }
     $form['slug'] = array('#type' => 'textfield', '#name' => 'ct[slug]', '#title' => __('Slug', 'wpcf') . ' (<strong>' . __('required', 'wpcf') . '</strong>)', '#value' => isset($this->ct['slug']) ? $this->ct['slug'] : '', '#pattern' => $table_row, '#inline' => true, '#validate' => array('required' => array('value' => 'true'), 'nospecialchars' => array('value' => 'true'), 'maxlength' => array('value' => '20')), '#attributes' => $attributes + array('maxlength' => '20', 'placeholder' => __('Enter Post Type slug', 'wpcf'), 'class' => 'js-wpcf-slugize large-text'), '#id' => 'slug', '_builtin' => true);
     // disable for inbuilt
     if ($this->ct['_builtin']) {
         $form['slug']['#disable'] = 1;
         $form['slug']['#pattern'] = '<tr><td><LABEL></td><td><ERROR><BEFORE><ELEMENT><DESCRIPTION><AFTER></td></tr>';
         $form['slug']['#description'] = __('This option is not available for built-in post types.', 'wpcf');
     }
     $form['description'] = array('#type' => 'textarea', '#name' => 'ct[description]', '#title' => __('Description', 'wpcf'), '#value' => isset($this->ct['description']) ? $this->ct['description'] : '', '#attributes' => array('rows' => 4, 'cols' => 60, 'placeholder' => __('Enter Post Type description', 'wpcf'), 'class' => 'hidden js-wpcf-description'), '#pattern' => $table_row, '#inline' => true, '#after' => sprintf('<a class="js-wpcf-toggle-description hidden" href="#">%s</a>', __('Add description', 'wpcf')));
     /**
      * icons only for version 3.8 up
      */
     global $wp_version;
     if (version_compare('3.8', $wp_version) < 1) {
         $form['choose-icon'] = array('#name' => 'choose-icon', '#type' => 'button', '#value' => esc_attr__('Change icon', 'wpcf'), '#inline' => true, '#title' => __('Icon', 'wpcf'), '#pattern' => '<tr><td><LABEL></td><td><ERROR><BEFORE><ELEMENT><DESCRIPTION><AFTER></td></tr>', '#attributes' => array('data-wpcf-nonce' => wp_create_nonce('post-type-dashicons-list'), 'data-wpcf-post-type' => esc_attr($this->ct['slug']), 'data-wpcf-message-loading' => esc_attr__('Please Wait, Loading…', 'wpcf'), 'data-wpcf-title' => esc_attr__('Choose icon', 'wpcf'), 'data-wpcf-cancel' => esc_attr__('Cancel', 'wpcf'), 'data-wpcf-value' => esc_attr($menu_icon), 'class' => 'js-wpcf-choose-icon'), '#before' => sprintf('<div class="wpcf-types-menu-image dashicons-before dashicons-%s"><br></div>', esc_attr($menu_icon)));
         /**
          * clear ability to change for builitin post types
          */
         if ($this->ct['_builtin']) {
             $form['choose-icon']['#disable'] = 1;
             $form['choose-icon']['#description'] = __('This option is not available for built-in post types.', 'wpcf');
         }
     }
     $form['table-1-close'] = array('#type' => 'markup', '#markup' => '</tbody></table>', '_builtin' => true);
     $form['box-1-close'] = array('#type' => 'markup', '#markup' => '</div>', '_builtin' => true);
     /**
      * return form if current_user_can edit
      */
     if ($current_user_can_edit) {
         return $form;
     }
     return wpcf_admin_common_only_show($form);
 }
 protected function button_add_new($clasess = array())
 {
     $clasess[] = 'wpcf-fields-add-new';
     $clasess[] = 'js-wpcf-fields-add-new';
     return array('fields-button-add-' . rand() => array('#type' => 'button', '#value' => '<span class="dashicons dashicons-plus"></span> ' . __('Add New Field', 'wpcf'), '#attributes' => array('class' => esc_attr(implode(' ', $clasess)), 'data-wpcf-dialog-title' => esc_attr__('Add New Field', 'wpcf'), 'data-wpcf-id' => esc_attr($this->ct['id']), 'data-wpcf-message-loading' => esc_attr__('Please Wait, Loading…', 'wpcf'), 'data-wpcf-nonce' => wp_create_nonce('wpcf-edit-' . $this->ct['id']), 'data-wpcf-type' => $this->type, 'data-wpcf-page' => wpcf_getget('page')), '_builtin' => true, '#name' => 'fields-button-add'));
 }
 /**
  * Add a column for each term field on the term listing page.
  *
  * @param string[string] $columns Column definitions (column name => display name).
  * @return string[string] Updated column definitions.
  * @link https://make.wordpress.org/docs/plugin-developer-handbook/10-plugin-components/custom-list-table-columns/
  * @since 1.9.1
  */
 public function manage_term_listing_columns($columns)
 {
     $factory = Types_Field_Group_Term_Factory::get_instance();
     $taxonomy_slug = sanitize_text_field(wpcf_getget('taxonomy'));
     $groups = $factory->get_groups_by_taxonomy($taxonomy_slug);
     $columns_to_insert = array();
     foreach ($groups as $group) {
         foreach ($group->get_field_definitions() as $field_definition) {
             $columns_to_insert[self::LISTING_COLUMN_PREFIX . $field_definition->get_slug()] = $field_definition->get_display_name();
         }
     }
     $this->added_listing_columns = $columns_to_insert;
     // Insert before the last column, which displays counts of posts using the term (that's probably why column
     // has the label "Count" and name "posts" :-P).
     // If there is no "posts"=>"Count" column, insert at the end.
     if (isset($columns['posts']) && 'Count' == $columns['posts']) {
         $columns = Types_Utils::insert_at_position($columns, $columns_to_insert, array('key' => 'posts', 'where' => 'before'));
     } else {
         $columns = Types_Utils::insert_at_position($columns, $columns_to_insert, -1);
     }
     return $columns;
 }
Пример #11
0
/**
 * Important save_post hook.
 *
 * Core function. Works and stable. Do not move or change.
 * If required, add hooks only.
 *
 * @param int $post_ID
 * @param WP_Post $post
 *
 * @return bool
 */
function wpcf_admin_post_save_post_hook($post_ID, $post)
{
    if (defined('WPTOOLSET_FORMS_VERSION')) {
        // Apparently, some things are *slightly* different when saving a child post in the Post relationships metabox.
        // Ugly hack that will go away with m2m.
        //
        // Note: The types_updating_child_post filter is needed for a situation when user clicks on the Update button
        // for the parent post. In that case we don't get enough information to determine if a child post is being updated.
        $is_child_post_update = 'wpcf_ajax' == wpcf_getget('action') && 'pr_save_child_post' == wpcf_getget('wpcf_action') || apply_filters('types_updating_child_post', false);
        global $wpcf;
        $errors = false;
        // Do not save post if is type of
        if (in_array($post->post_type, array('revision', 'view', 'view-template', 'cred-form', 'cred-user-form', 'nav_menu_item', 'mediapage'))) {
            return false;
        }
        $_post_wpcf = array();
        if (!empty($_POST['wpcf'])) {
            $_post_wpcf = $_POST['wpcf'];
        }
        // handle checkbox
        if (array_key_exists('_wptoolset_checkbox', $_POST) && is_array($_POST['_wptoolset_checkbox'])) {
            foreach ($_POST['_wptoolset_checkbox'] as $key => $field_value) {
                $field_slug = preg_replace('/^wpcf\\-/', '', $key);
                if (array_key_exists($field_slug, $_post_wpcf)) {
                    continue;
                }
                $_post_wpcf[$field_slug] = false;
            }
        }
        // handle radios
        if (array_key_exists('_wptoolset_radios', $_POST) && is_array($_POST['_wptoolset_radios'])) {
            foreach ($_POST['_wptoolset_radios'] as $key => $field_value) {
                $field_slug = preg_replace('/^wpcf\\-/', '', $key);
                if (array_key_exists($field_slug, $_post_wpcf)) {
                    continue;
                }
                $_post_wpcf[$field_slug] = false;
            }
        }
        if (count($_post_wpcf)) {
            $add_error_message = true;
            if (isset($_POST['post_id']) && $_POST['post_id'] != $post_ID) {
                $add_error_message = false;
            }
            /**
             * check some attachment to delete
             */
            $delete_attachments = apply_filters('wpcf_delete_attachments', true);
            $images_to_delete = array();
            if ($delete_attachments && isset($_POST['wpcf']) && array_key_exists('delete-image', $_POST['wpcf']) && is_array($_POST['wpcf']['delete-image'])) {
                foreach ($_POST['wpcf']['delete-image'] as $image) {
                    $images_to_delete[$image] = 1;
                }
            }
            foreach ($_post_wpcf as $field_slug => $field_value) {
                // Get field by slug
                $field = wpcf_fields_get_field_by_slug($field_slug);
                if (empty($field)) {
                    continue;
                }
                // Skip copied fields
                if (isset($_POST['wpcf_repetitive_copy'][$field['slug']])) {
                    continue;
                }
                // This is (apparently) expected for repetitive fields...
                if ($is_child_post_update && types_is_repetitive($field)) {
                    $field_value = array($field_value);
                }
                $_field_value = !types_is_repetitive($field) ? array($field_value) : $field_value;
                // Set config
                $config = wptoolset_form_filter_types_field($field, $post_ID, $_post_wpcf);
                /**
                 * remove from images_to_delete if user add again
                 */
                if ($delete_attachments && 'image' == $config['type']) {
                    $images = $_field_value;
                    if (!is_array($images)) {
                        $images = array($images);
                    }
                    foreach ($images as $image) {
                        if (array_key_exists($image, $images_to_delete)) {
                            unset($images_to_delete[$image]);
                        }
                    }
                }
                /**
                 * add filter to remove field name from error message
                 */
                /** This filter is toolset-common/toolset-forms/classes/class.validation.php */
                add_filter('toolset_common_validation_add_field_name_to_error', '__return_false', 1234, 1);
                foreach ($_field_value as $_k => $_val) {
                    // Check if valid
                    $validation = wptoolset_form_validate_field('post', $config, $_val);
                    $conditional = wptoolset_form_conditional_check($config);
                    $not_valid = is_wp_error($validation) || !$conditional;
                    if ($add_error_message && is_wp_error($validation)) {
                        $errors = true;
                        $_errors = $validation->get_error_data();
                        $_msg = sprintf(__('Field "%s" not updated:', 'wpcf'), $field['name']);
                        wpcf_admin_message_store($_msg . ' ' . implode(', ', $_errors), 'error');
                    }
                    if ($not_valid) {
                        if (types_is_repetitive($field)) {
                            unset($field_value[$_k]);
                        } else {
                            break;
                        }
                    }
                }
                remove_filter('toolset_common_validation_add_field_name_to_error', '__return_false', 1234, 1);
                // Save field
                if (types_is_repetitive($field)) {
                    $wpcf->repeater->set($post_ID, $field);
                    $wpcf->repeater->save($field_value);
                } else {
                    if (!$not_valid) {
                        $wpcf->field->set($post_ID, $field);
                        $wpcf->field->save($field_value);
                    }
                }
                do_action('wpcf_post_field_saved', $post_ID, $field);
                // TODO Move to checkboxes
                if ($field['type'] == 'checkboxes') {
                    if (!empty($field['data']['options'])) {
                        $update_data = array();
                        foreach ($field['data']['options'] as $option_id => $option_data) {
                            if (!isset($_POST['wpcf'][$field['id']][$option_id])) {
                                if (isset($field['data']['save_empty']) && $field['data']['save_empty'] == 'yes') {
                                    $update_data[$option_id] = 0;
                                }
                            } else {
                                $update_data[$option_id] = $_POST['wpcf'][$field['id']][$option_id];
                            }
                        }
                        update_post_meta($post_ID, $field['meta_key'], $update_data);
                    }
                }
            }
            /**
             * delete images
             */
            if ($delete_attachments && !empty($images_to_delete)) {
                $args = array('post_parent' => $post_ID, 'posts_per_page' => -1);
                $children_array = get_children($args);
                foreach ($children_array as $child) {
                    if (!array_key_exists($child->guid, $images_to_delete)) {
                        continue;
                    }
                    wp_delete_attachment($child->ID);
                }
            }
        }
        if ($errors) {
            update_post_meta($post_ID, '__wpcf-invalid-fields', true);
        }
        do_action('wpcf_post_saved', $post_ID);
        return;
    }
    // OLD
    global $wpcf;
    // Basic cheks
    /*
     * Allow this hook to be triggered only if Types form is submitted
     */
    //    if ( !isset( $_POST['_wpcf_post_wpnonce'] ) || !wp_verify_nonce( $_POST['_wpcf_post_wpnonce'],
    //                    'update-' . $post->post_type . '_' . $post_ID ) ) {
    //        return false;
    //    }
    /*
     * Do not save post if is type of:
     * revision
     * attachment
     * wp-types-group
     * view
     * view-template
     * cred-form
     */
    if (in_array($post->post_type, $wpcf->excluded_post_types)) {
        return false;
    }
    /*
     *
     *
     * Get all groups connected to this $post
     */
    $groups = wpcf_admin_post_get_post_groups_fields($post);
    if (empty($groups)) {
        return false;
    }
    $all_fields = array();
    $_not_valid = array();
    $_error = false;
    /*
     *
     *
     * Loop over each group
     *
     * TODO Document this
     * Connect 'wpcf-invalid-fields' with all fields
     */
    foreach ($groups as $group) {
        if (isset($group['fields'])) {
            // Process fields
            $fields = wpcf_admin_post_process_fields($post, $group['fields'], true, false, 'validation');
            // Validate fields
            $form = wpcf_form_simple_validate($fields);
            $all_fields = $all_fields + $fields;
            // Collect all not valid fields
            if ($form->isError()) {
                $_error = true;
                // Set error only to true
                $_not_valid = array_merge($_not_valid, (array) $form->get_not_valid());
            }
        }
    }
    // Set fields
    foreach ($all_fields as $k => $v) {
        // only Types field
        if (empty($v['wpcf-id'])) {
            continue;
        }
        $_temp = new WPCF_Field();
        $_temp->set($wpcf->post, $v['wpcf-id']);
        $all_fields[$k]['_field'] = $_temp;
    }
    foreach ($_not_valid as $k => $v) {
        // only Types field
        if (empty($v['wpcf-id'])) {
            continue;
        }
        $_temp = new WPCF_Field();
        $_temp->set($wpcf->post, $v['wpcf-id']);
        $_not_valid[$k]['_field'] = $_temp;
    }
    /*
     *
     * Allow interaction here.
     * Conditional will set $error to false if field is conditional
     * and not submitted.
     */
    $error = apply_filters('wpcf_post_form_error', $_error, $_not_valid, $all_fields);
    $not_valid = apply_filters('wpcf_post_form_not_valid', $_not_valid, $_error, $all_fields);
    // Notify user about error
    if ($error) {
        wpcf_admin_message_store(__('Please check your input data', 'wpcf'), 'error');
    }
    /*
     * Save invalid elements so user can be informed after redirect.
     */
    if (!empty($not_valid)) {
        update_post_meta($post_ID, 'wpcf-invalid-fields', $not_valid);
    }
    /*
     *
     *
     *
     *
     * Save meta fields
     */
    if (!empty($_POST['wpcf'])) {
        foreach ($_POST['wpcf'] as $field_slug => $field_value) {
            // Get field by slug
            $field = wpcf_fields_get_field_by_slug($field_slug);
            if (empty($field)) {
                continue;
            }
            // Set field
            $wpcf->field->set($post_ID, $field);
            // Skip copied fields
            // CHECKPOINT
            if (isset($_POST['wpcf_repetitive_copy'][$field['slug']])) {
                continue;
            }
            // Don't save invalid
            // CHECKPOINT
            if (isset($not_valid[$field['slug']])) {
                continue;
            }
            /*
             *
             *
             * Saving fields
             * @since 1.2
             *
             * We changed way repetitive fields are saved.
             * On each save fields are rewritten and order is saved in
             * '_$slug-sort-order' meta field.
             */
            /*
             *
             * We marked fields as repetitive in POST['__wpcf_repetitive']
             * Without this check we won't save any.
             * @see WPCF_Repeater::get_fields_form()
             */
            if (isset($_POST['__wpcf_repetitive'][$wpcf->field->slug])) {
                /*
                 * Use here WPCF_Repeater class.
                 * WPCF_Repeater::set() - switches to current post
                 * WPCF_Repeater::save() - saves repetitive field
                 */
                $wpcf->repeater->set($post_ID, $field);
                $wpcf->repeater->save();
            } else {
                /*
                 * Use WPCF_Field::save()
                 */
                $wpcf->field->save();
            }
            do_action('wpcf_post_field_saved', $post_ID, $field);
        }
    }
    /*
     * Process checkboxes
     *
     * TODO Revise and remove
     * Since Types 1.1.5 we moved this check to embedded/includes/checkbox.php
     * checkbox.php added permanently to bootstrap.
     */
    foreach ($all_fields as $field) {
        if (!isset($field['#type'])) {
            continue;
        }
        //        if ( $field['#type'] == 'checkbox'
        //                && !isset( $_POST['wpcf'][$field['wpcf-slug']] ) ) {
        //            $field_data = wpcf_admin_fields_get_field( $field['wpcf-id'] );
        //            if ( isset( $field_data['data']['save_empty'] )
        //                    && $field_data['data']['save_empty'] == 'yes' ) {
        //                update_post_meta( $post_ID,
        //                        wpcf_types_get_meta_prefix( $field ) . $field['wpcf-slug'],
        //                        0 );
        //            } else {
        //                delete_post_meta( $post_ID,
        //                        wpcf_types_get_meta_prefix( $field ) . $field['wpcf-slug'] );
        //            }
        //        }
        if ($field['#type'] == 'checkboxes') {
            $field_data = wpcf_admin_fields_get_field($field['wpcf-id']);
            if (!empty($field_data['data']['options'])) {
                $update_data = array();
                foreach ($field_data['data']['options'] as $option_id => $option_data) {
                    if (!isset($_POST['wpcf'][$field['wpcf-slug']][$option_id])) {
                        if (isset($field_data['data']['save_empty']) && $field_data['data']['save_empty'] == 'yes') {
                            $update_data[$option_id] = 0;
                        }
                    } else {
                        $update_data[$option_id] = $_POST['wpcf'][$field['wpcf-slug']][$option_id];
                    }
                }
                update_post_meta($post_ID, wpcf_types_get_meta_prefix($field) . $field['wpcf-slug'], $update_data);
            }
        }
    }
    do_action('wpcf_post_saved', $post_ID);
}
 /**
  * Generate wrapper around form setup data.
  *
  * @param string $type
  * @param array $data
  * @param bool $render_closing_hr If true, render a hr tag at the end of the form section.
  *
  * @return array
  */
 protected function filter_wrap($type, $data = array(), $button_only = false, $render_closing_hr = true)
 {
     $data = wp_parse_args($data, array('nonce' => '', 'title' => '', 'value' => '', 'value_default' => ''));
     $form = array();
     $unique_id = wpcf_unique_id(serialize(func_get_args()));
     /**
      * form open
      */
     $form[$unique_id . '-open'] = array('#type' => 'markup', '#markup' => sprintf('<div id="%s" class="wpcf-filter-container js-wpcf-filter-container">', esc_attr($unique_id)));
     /**
      * header
      */
     if (!$button_only) {
         $form[$unique_id . '-header'] = array('#type' => 'markup', '#markup' => sprintf('<h3>%s</h3>', $data['title']));
     }
     /**
      * Description
      */
     if (!$button_only && isset($data['description'])) {
         $form[$unique_id . '-description'] = array('#type' => 'markup', '#markup' => wpautop($data['description']));
     }
     /**
      * content
      */
     if (!$button_only) {
         $form[$unique_id . '-content'] = array('#type' => 'markup', '#markup' => sprintf('<span class="js-wpcf-filter-ajax-response">%s</span>', empty($data['value']) ? $data['value_default'] : $data['value']), '#inline' => true);
     }
     /**
      * button
      */
     if ($this->current_user_can_edit) {
         $form[$unique_id . '-button'] = array('#type' => 'button', '#name' => esc_attr($unique_id . '-button'), '#value' => __('Edit', 'wpcf'), '#attributes' => array('class' => 'js-wpcf-filter-button-edit wpcf-filter-button-edit', 'data-wpcf-type' => esc_attr($type), 'data-wpcf-page' => esc_attr(wpcf_getget('page')), 'data-wpcf-nonce' => wp_create_nonce($type)), '#inline' => true, '#before' => '<div class="wpcf-filter-button-edit-container">', '#after' => '</div>');
         foreach ($data as $key => $value) {
             if (preg_match('/^data\\-wpcf\\-/', $key)) {
                 $form[$unique_id . '-button']['#attributes'][$key] = esc_attr($value);
             }
         }
     }
     /**
      * form close
      */
     $close_clear = $button_only || !$render_closing_hr ? '' : '<hr class="clear" />';
     $form[$unique_id . '-close'] = array('#type' => 'markup', '#markup' => $close_clear . '</div>');
     return $form;
 }
Пример #13
0
/**
 * The save_post hook.
 *
 * @param int $post_ID
 * @param WP_Post $post
 * @since unknown
 */
function wpcf_admin_post_save_post_hook($post_ID, $post)
{
    // Apparently, some things are *slightly* different when saving a child post in the Post relationships metabox.
    // Ugly hack that will go away with m2m.
    //
    // Note: The types_updating_child_post filter is needed for a situation when user clicks on the Update button
    // for the parent post. In that case we don't get enough information to determine if a child post is being updated.
    $is_child_post_update = 'wpcf_ajax' == wpcf_getget('action') && 'pr_save_child_post' == wpcf_getget('wpcf_action') || apply_filters('types_updating_child_post', false);
    global $wpcf;
    $errors = false;
    // Do not save post if is type of
    if (in_array($post->post_type, array('revision', 'view', 'view-template', 'cred-form', 'cred-user-form', 'nav_menu_item', 'mediapage'))) {
        return;
    }
    $_post_wpcf = array();
    if (!empty($_POST['wpcf'])) {
        $_post_wpcf = $_POST['wpcf'];
    }
    // handle checkbox
    if (array_key_exists('_wptoolset_checkbox', $_POST) && is_array($_POST['_wptoolset_checkbox'])) {
        foreach ($_POST['_wptoolset_checkbox'] as $key => $field_value) {
            $field_slug = preg_replace('/^wpcf\\-/', '', $key);
            if (array_key_exists($field_slug, $_post_wpcf)) {
                continue;
            }
            $_post_wpcf[$field_slug] = false;
        }
    }
    // handle radios
    if (array_key_exists('_wptoolset_radios', $_POST) && is_array($_POST['_wptoolset_radios'])) {
        foreach ($_POST['_wptoolset_radios'] as $key => $field_value) {
            $field_slug = preg_replace('/^wpcf\\-/', '', $key);
            if (array_key_exists($field_slug, $_post_wpcf)) {
                continue;
            }
            $_post_wpcf[$field_slug] = false;
        }
    }
    if (count($_post_wpcf)) {
        $add_error_message = true;
        if (isset($_POST['post_id']) && $_POST['post_id'] != $post_ID) {
            $add_error_message = false;
        }
        // check some attachment to delete
        $delete_attachments = apply_filters('wpcf_delete_attachments', true);
        $images_to_delete = array();
        if ($delete_attachments && isset($_POST['wpcf']) && array_key_exists('delete-image', $_POST['wpcf']) && is_array($_POST['wpcf']['delete-image'])) {
            foreach ($_POST['wpcf']['delete-image'] as $image) {
                $images_to_delete[$image] = 1;
            }
        }
        foreach ($_post_wpcf as $field_slug => $field_value) {
            // Get field by slug
            $field = wpcf_fields_get_field_by_slug($field_slug);
            if (empty($field)) {
                continue;
            }
            // Skip copied fields
            if (isset($_POST['wpcf_repetitive_copy'][$field['slug']])) {
                continue;
            }
            // This is (apparently) expected for repetitive fields...
            if ($is_child_post_update && types_is_repetitive($field)) {
                $field_value = array($field_value);
            }
            $_field_value = !types_is_repetitive($field) ? array($field_value) : $field_value;
            // Set config
            $config = wptoolset_form_filter_types_field($field, $post_ID, $_post_wpcf);
            // remove from images_to_delete if user add again
            if ($delete_attachments && 'image' == $config['type']) {
                $images = $_field_value;
                if (!is_array($images)) {
                    $images = array($images);
                }
                foreach ($images as $image) {
                    if (array_key_exists($image, $images_to_delete)) {
                        unset($images_to_delete[$image]);
                    }
                }
            }
            // add filter to remove field name from error message
            // This filter is toolset-common/toolset-forms/classes/class.validation.php
            add_filter('toolset_common_validation_add_field_name_to_error', '__return_false', 1234, 1);
            foreach ($_field_value as $_k => $_val) {
                // Check if valid
                $validation = wptoolset_form_validate_field('post', $config, $_val);
                $conditional = wptoolset_form_conditional_check($config);
                $not_valid = is_wp_error($validation) || !$conditional;
                if ($add_error_message && is_wp_error($validation)) {
                    $errors = true;
                    $_errors = $validation->get_error_data();
                    $_msg = sprintf(__('Field "%s" not updated:', 'wpcf'), $field['name']);
                    wpcf_admin_message_store($_msg . ' ' . implode(', ', $_errors), 'error');
                }
                if ($not_valid) {
                    if (types_is_repetitive($field)) {
                        unset($field_value[$_k]);
                    } else {
                        break;
                    }
                }
            }
            remove_filter('toolset_common_validation_add_field_name_to_error', '__return_false', 1234, 1);
            // Save field
            if (types_is_repetitive($field)) {
                $wpcf->repeater->set($post_ID, $field);
                $wpcf->repeater->save($field_value);
            } else {
                if (!$not_valid) {
                    $wpcf->field->set($post_ID, $field);
                    $wpcf->field->save($field_value);
                }
            }
            do_action('wpcf_post_field_saved', $post_ID, $field);
            // TODO Move to checkboxes
            if ($field['type'] == 'checkboxes') {
                if (!empty($field['data']['options'])) {
                    $update_data = array();
                    foreach ($field['data']['options'] as $option_id => $option_data) {
                        if (!isset($_POST['wpcf'][$field['id']][$option_id])) {
                            if (isset($field['data']['save_empty']) && $field['data']['save_empty'] == 'yes') {
                                $update_data[$option_id] = 0;
                            }
                        } else {
                            $update_data[$option_id] = $_POST['wpcf'][$field['id']][$option_id];
                        }
                    }
                    update_post_meta($post_ID, $field['meta_key'], $update_data);
                }
            }
        }
        // delete images
        if ($delete_attachments && !empty($images_to_delete)) {
            $args = array('post_parent' => $post_ID, 'posts_per_page' => -1);
            $children_array = get_children($args);
            foreach ($children_array as $child) {
                if (!array_key_exists($child->guid, $images_to_delete)) {
                    continue;
                }
                wp_delete_attachment($child->ID);
            }
        }
    }
    if ($errors) {
        update_post_meta($post_ID, '__wpcf-invalid-fields', true);
    }
    do_action('wpcf_post_saved', $post_ID);
    return;
}
Пример #14
0
 /**
  * Add a column for each term field on the term listing page.
  *
  * @param string[string] $columns Column definitions (column name => display name).
  * @return string[string] Updated column definitions.
  * @link https://make.wordpress.org/docs/plugin-developer-handbook/10-plugin-components/custom-list-table-columns/
  * @since 1.9.1
  */
 public function manage_term_listing_columns($columns)
 {
     $taxonomy_slug = wpcf_getget('taxonomy');
     $groups = WPCF_Field_Group_Term_Factory::get_instance()->get_groups_by_taxonomy($taxonomy_slug);
     $columns_to_insert = array();
     foreach ($groups as $group) {
         foreach ($group->get_field_definitions() as $field_definition) {
             $columns_to_insert[self::LISTING_COLUMN_PREFIX . $field_definition->get_slug()] = $field_definition->get_display_name();
         }
     }
     // Insert before the last column, which displays counts of posts using the term (that's probably why column
     // has the label "Count" and name "posts" :-P).
     $columns = WPCF_Utils::insert_at_position($columns, $columns_to_insert, array('key' => 'posts', 'where' => 'before'));
     return $columns;
 }
Пример #15
0
 /**
  * Current field domain.
  * 
  * @return string|null 
  * @since 2.0
  */
 private function get_current_domain()
 {
     if (null == $this->current_domain) {
         $this->current_domain = wpcf_getget(self::PARAM_DOMAIN, null, Types_Field_Utils::get_domains());
     }
     return $this->current_domain;
 }
 /**
  * Summary.
  *
  * Description.
  *
  * @since x.x.x
  * @access (for functions: only use if private)
  *
  * @see Function/method/class relied on
  * @link URL
  * @global type $varname Description.
  * @global type $varname Description.
  *
  * @param type $var Description.
  * @param type $var Optional. Description.
  * @return type Description.
  */
 public function form()
 {
     $this->save();
     // Flush rewrite rules if we're asked to do so.
     //
     // This must be done after all post types and taxonomies are registered, and they can be registered properly
     // only on 'init'. So after making changes, we need to reload the page and THEN flush.
     if ('1' == wpcf_getget('flush', '0')) {
         flush_rewrite_rules();
     }
     global $wpcf;
     $id = false;
     $update = false;
     $taxonomies = array();
     if (isset($_GET[$this->get_id])) {
         $id = sanitize_text_field($_GET[$this->get_id]);
     } elseif (isset($_POST[$this->get_id])) {
         $id = sanitize_text_field($_POST[$this->get_id]);
     }
     if ($id) {
         $taxonomies = $this->taxonomies->get();
         if (isset($taxonomies[$id])) {
             $this->ct = $taxonomies[$id];
             $update = true;
         } else {
             wpcf_admin_message(__('Wrong Taxonomy specified.', 'wpcf'), 'error');
             return false;
         }
     } else {
         $this->ct = wpcf_custom_taxonomies_default();
     }
     $current_user_can_edit = WPCF_Roles::user_can_edit('custom-taxonomy', $this->ct);
     /**
      * sanitize _builtin
      */
     if (!isset($this->ct['_builtin'])) {
         $this->ct['_builtin'] = false;
     }
     $form = $this->prepare_screen();
     if ($current_user_can_edit && $update) {
         $form['id'] = array('#type' => 'hidden', '#value' => $id, '#name' => 'ct[wpcf-tax]');
         $form['slug_conflict_check_nonce'] = array('#type' => 'hidden', '#value' => wp_create_nonce(Types_Ajax::CALLBACK_CHECK_SLUG_CONFLICTS), '#name' => 'types_check_slug_conflicts_nonce', '_builtin' => true);
     }
     /**
      * post icon field
      */
     $menu_icon = isset($this->ct['icon']) && !empty($this->ct['icon']) ? $this->ct['icon'] : 'admin-post';
     $form['icon'] = array('#type' => 'hidden', '#name' => 'ct[icon]', '#value' => $menu_icon, '#id' => 'wpcf-types-icon');
     $form['form-open'] = array('#type' => 'markup', '#markup' => sprintf('<div id="post-body-content" class="%s">', $current_user_can_edit ? '' : 'wpcf-types-read-only'), '_builtin' => true);
     $form['table-1-open'] = array('#type' => 'markup', '#markup' => '<table id="wpcf-types-form-name-table" class="wpcf-types-form-table widefat js-wpcf-slugize-container"><thead><tr><th colspan="2">' . __('Name and description', 'wpcf') . '</th></tr></thead><tbody>');
     $table_row = '<tr><td><LABEL></td><td><ERROR><BEFORE><ELEMENT><AFTER></td></tr>';
     $form['name'] = array('#type' => 'textfield', '#name' => 'ct[labels][name]', '#title' => __('Name plural', 'wpcf') . ' (<strong>' . __('required', 'wpcf') . '</strong>)', '#description' => '<strong>' . __('Enter in plural!', 'wpcf') . '.', '#value' => isset($this->ct['labels']['name']) ? $this->ct['labels']['name'] : '', '#validate' => array('required' => array('value' => true), 'maxlength' => array('value' => 30)), '#pattern' => $table_row, '#inline' => true, '#attributes' => array('placeholder' => __('Enter Taxonomy name plural', 'wpcf'), 'class' => 'widefat'));
     $form['name-singular'] = array('#type' => 'textfield', '#name' => 'ct[labels][singular_name]', '#title' => __('Name singular', 'wpcf') . ' (<strong>' . __('required', 'wpcf') . '</strong>)', '#description' => '<strong>' . __('Enter in singular!', 'wpcf') . '</strong><br />' . '.', '#value' => isset($this->ct['labels']['singular_name']) ? $this->ct['labels']['singular_name'] : '', '#validate' => array('required' => array('value' => true), 'maxlength' => array('value' => 30)), '#pattern' => $table_row, '#inline' => true, '#attributes' => array('placeholder' => __('Enter Taxonomy name singular', 'wpcf'), 'class' => 'widefat js-wpcf-slugize-source'));
     /*
      *
      * IF isset $_POST['slug'] it means form is not submitted
      */
     $attributes = array();
     if (!empty($_POST['ct']['slug'])) {
         $reserved = wpcf_is_reserved_name(sanitize_text_field($_POST['ct']['slug']), 'taxonomy');
         if (is_wp_error($reserved)) {
             $attributes = array('class' => 'wpcf-form-error', 'onclick' => 'jQuery(this).removeClass(\'wpcf-form-error\');');
         }
     }
     $form['slug'] = array('#type' => 'textfield', '#name' => 'ct[slug]', '#title' => __('Slug', 'wpcf') . ' (<strong>' . __('required', 'wpcf') . '</strong>)', '#description' => '<strong>' . __('Enter in singular!', 'wpcf') . '</strong><br />' . __('Machine readable name.', 'wpcf') . '<br />' . __('If not provided - will be created from singular name.', 'wpcf') . '<br />', '#value' => isset($this->ct['slug']) ? $this->ct['slug'] : '', '#pattern' => $table_row, '#inline' => true, '#validate' => array('required' => array('value' => true), 'nospecialchars' => array('value' => true), 'maxlength' => array('value' => 30)), '#attributes' => $attributes + array('maxlength' => '30', 'placeholder' => __('Enter Taxonomy slug', 'wpcf'), 'class' => 'widefat js-wpcf-slugize'));
     $form['description'] = array('#type' => 'textarea', '#name' => 'ct[description]', '#title' => __('Description', 'wpcf'), '#value' => isset($this->ct['description']) ? $this->ct['description'] : '', '#attributes' => array('rows' => 4, 'cols' => 60, 'placeholder' => __('Enter Taxonomy description', 'wpcf'), 'class' => 'hidden js-wpcf-description'), '#pattern' => $table_row, '#inline' => true, '#after' => $this->ct['_builtin'] ? __('This is built-in WordPress Taxonomy.', 'wpcf') : sprintf('<a class="js-wpcf-toggle-description hidden" href="#">%s</a>', __('Add description', 'wpcf')));
     $form['table-1-close'] = array('#type' => 'markup', '#markup' => '</tbody></table>');
     $form['box-1-close'] = array('#type' => 'markup', '#markup' => '</div>', '_builtin' => true);
     if ($this->ct['_builtin']) {
         $form['name']['#attributes']['readonly'] = 'readonly';
         $form['name-singular']['#attributes']['readonly'] = 'readonly';
         $form['slug']['#attributes']['readonly'] = 'readonly';
         $form['description']['#attributes']['readonly'] = 'readonly';
     }
     /**
      * return form if current_user_can edit
      */
     if ($current_user_can_edit) {
         return $form;
     }
     return wpcf_admin_common_only_show($form);
 }