File "model.php"
Full Path: /www/wwwroot/shphe-en.com/wp-content/plugins/admin-columns-pro/classes/inline-edit/classes/model.php
File size: 33.44 KB
MIME-type: --
Charset: utf-8
<?php
/**
* Storage model for editability
* This class can be extended for different storage models, such as post, user and taxonomy storage models
*
* @since 1.0
* @abstract
*/
abstract class CACIE_Editable_Model {
/**
* Main storage model class instance
*
* @since 1.0
* @var CPAC_Storage_Model
* @access protected
*/
public $storage_model;
/**
* Enable inline edit for Custom Fields
*
* @since 3.1.2
*/
protected $is_custom_field_editable;
/**
* Get default properties of editability of column types
* The array returned for each column type key contains information about the editability of a column type
* For example, it usually holds the editability type in $array['type'], which can be, for example, "text" or "select" or "email"
* For getting the editability information for an instance of a column, see CACIE_Editable_Model::get_editable()
*
* @since 1.0
* @abstract
*
* @return array List of editability information per column ([column_type] => (array) [editable])
*/
abstract function get_editables_data();
/**
* Save a column for a certain entry
* Called on a succesful AJAX request
*
* @since 1.0
* @abstract
*
* @param int $id Post ID
* @param CPAC_Column $column Column object instance
* @param mixed $value Value to be saved
*/
abstract function column_save( $id, $column, $value );
/**
* Get the available items on the current page for passing them to JS
*
* @since 1.0
* @abstract
*
* @return array Items on the current page ([entry_id] => (array) [entry_data])
*/
abstract function get_items();
/**
* Output value for WP default column
*
* @since 1.0
* @abstract
*
* @param CPAC_Column $column Column Object
* @param int $id Entry ID
*/
abstract function manage_value( $column, $id );
/**
* Constructor
*
* @since 1.0
*
* @param CPAC_Storage_Model $storage_model Main storage model class instance
*/
function __construct( $storage_model ) {
$this->storage_model = $storage_model;
$this->is_custom_field_editable = $this->storage_model->get_general_option( 'custom_field_editable' );
// Enable inline edit per column
add_action( "cac/columns/storage_key={$this->storage_model->key}", array( $this, 'enable_inlineedit' ) );
// Add columns to javascript
add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ), 20 );
// Save column value from inline edit
add_action( 'wp_ajax_cacie_column_save', array( $this, 'ajax_column_save' ) );
// Save user preference of the edititability state
add_action( 'wp_ajax_cacie_editability_state_save', array( $this, 'ajax_editability_state_save' ) );
// Get options for editable field by ajax
add_action( 'wp_ajax_cacie_get_options', array( $this, 'ajax_get_options' ) );
}
/**
* Check whether a column is editable
*
* @since 1.0
*
* @param array $column Column options
* @return bool Whether the column is editable
*/
public function is_editable( $column ) {
$is_editable = false;
switch ( $column->properties->type ) {
// ACF
case 'column-acf_field':
if ( ! method_exists( $column, 'get_field' ) ) {
break;
}
$acf_field = $column->get_field();
if ( ! isset( $acf_field['type'] ) ) {
break;
}
switch ( $acf_field['type'] ) {
case 'checkbox':
case 'color_picker':
case 'date_picker':
//case 'date_time_picker':
case 'email':
case 'file':
case 'gallery':
//case 'google_map':
case 'image':
//case 'message':
case 'number':
case 'page_link':
case 'password':
case 'post_object':
case 'radio':
//case 'relationship':
//case 'repeater':
case 'select':
case 'taxonomy':
case 'text':
case 'textarea':
case 'true_false':
case 'url':
case 'user':
case 'wysiwyg':
$is_editable = true;
break;
}
break;
// Custom Fields
case 'column-meta':
/**
* Filter for making all custom fields editable. Only use this
* when you are well aware of any formatting and validating rules
* on how your custom field value are stored.
*
* @since 3.1.2
*
* @param bool $is_editable Set tot true to make all custom fields fields editable.
*/
if ( $this->is_custom_field_editable ) {
switch ( $column->options->field_type ) {
case '' :
case 'checkmark' :
case 'color' :
case 'excerpt' :
case 'image' :
case 'library_id' :
case 'numeric' :
case 'title_by_id' :
case 'user_by_id' :
$is_editable = true;
break;
case 'date' :
$is_editable = true;
// @todo: the datepicker conflicts with ACF 'jquery-ui-datepicker' on upload.php
if ( class_exists('acf') && 'media' === $column->storage_model->type ) {
$is_editable = false;
}
break;
}
}
break;
}
return $is_editable;
}
/**
* @since 3.5
*/
protected function get_list_selector() {
return '#the-list';
}
/**
* Admin scripts
*
* @since 1.0
*/
public function scripts() {
if ( ! $this->storage_model->is_columns_screen() ) {
return;
}
// Allow JS to access the column and item data for this storage model on the edit page
wp_localize_script( 'cacie-admin-edit', 'CACIE_List_Selector', $this->get_list_selector() );
wp_localize_script( 'cacie-admin-edit', 'CACIE_Storage_Model', $this->storage_model->key );
wp_localize_script( 'cacie-admin-edit', 'CACIE_Columns', $this->get_columns() );
wp_localize_script( 'cacie-admin-edit', 'CACIE_Items', $this->get_items() );
wp_localize_script( 'cacie-admin-edit', 'CACIE', array(
'inline_edit' => array(
'active' => $this->get_editability_preference()
)
) );
}
/**
* Get list of options for posts selection
*
* Results are formatted as an array of post types, the key being the post type name, the value
* being an array with two keys: label (the post type label) and options, an array of options (posts)
* for this post type, with the post IDs as keys and the post titles as values
*
* @since 1.0
* @uses WP_Query
*
* @param array $query_args Additional query arguments for WP_Query
* @return array List of options, grouped by posttype
*/
public function get_posts_options( $query_args = array() ) {
$options = array();
$args = wp_parse_args( $query_args, array(
'posts_per_page' => 100, // max 100 records in case we get a very large db
'post_type' => 'any',
'orderby' => 'title',
'order' => 'ASC'
) );
if ( $posts = get_posts( $args ) ) {
foreach ( $posts as $post ) {
if ( ! isset( $options[ $post->post_type ] ) ) {
$options[ $post->post_type ] = array(
'label' => $post->post_type,
'options' => array()
);
}
$options[ $post->post_type ]['options'][ $post->ID ] = $post->post_title;
}
}
return $options;
}
/**
* Get list of options for users selection
*
* Results are formatted as an array of roles, the key being the role name, the value
* being an array with two keys: label (the role label) and options, an array of options (users)
* for this role, with the user IDs as keys and the user display names as values
*
* @since 1.0
* @uses WP_User_Query
*
* @param array $query_args Additional query arguments for WP_User_query
* @param object $column_object CPAC_Column object
* @return array List of options, grouped by author role
*/
public function get_users_options( $query_args = array(), $column_object = null ) {
global $wp_roles;
$options = array();
$query_args = wp_parse_args( $query_args, array(
'orderby' => 'display_name',
'number' => 100 // max 100 records in case we get a very large db
) );
if ( isset( $query_args['search'] ) && ! isset( $query_args['search_columns'] ) ) {
$query_args['search_columns'] = array( 'ID', 'user_login', 'user_nicename', 'user_email', 'user_url' );
}
// Get all users
$users_query = new WP_User_Query( $query_args );
$users = $users_query->get_results();
// Get roles
$roles = $wp_roles->roles;
// Generate options by grouping users by role
foreach ( $users as $user ) {
$role = CACIE_Roles::get_user_role( $user->ID );
// User name
$name = $user->display_name;
// If the column is an author name column, we use the name format set in the column
// instead of the normal display name
if ( is_a( $column_object, 'CPAC_Column_Post_Author_Name' ) ) {
$name = $column_object->get_display_name( $user->ID );
}
if ( ! isset( $options[ $role ] ) ) {
$options[ $role ] = array(
'label' => translate_user_role( $roles[ $role ]['name'] ),
'options' => array()
);
}
$options[ $role ]['options'][ $user->ID ] = esc_attr( $name );
}
return $options;
}
/**
* AJAX callback for retrieving options for a column
* Results can be formatted in two ways: an array of options ([value] => [label]) or
* an array of option groups ([group key] => [group]) with [group] being an array with
* two keys: label (the label displayed for the group) and options (an array ([value] => [label])
* of options)
*
* @since 1.0
*
* @return array List of options, possibly grouped
*/
public function ajax_get_options() {
if ( $this->storage_model->key != $_REQUEST['storage_model'] ) {
return;
}
$options = array();
if ( empty( $_GET['column'] ) ) {
wp_send_json_error( __( 'Invalid request.', 'codepress-admin-columns' ) );
}
$column = $this->storage_model->get_column_by_name( $_GET['column'] );
if ( empty( $column ) ) {
wp_send_json_error( __( 'Invalid column.', 'codepress-admin-columns' ) );
}
$search = isset( $_GET['searchterm'] ) ? $_GET['searchterm'] : '';
// Custom Field
if ( 'column-meta' == $column->properties->type ) {
switch ( $column->options->field_type ) {
case 'title_by_id':
$options = $this->get_posts_options( array( 's' => $search ) );
break;
case 'user_by_id':
$options = $this->get_users_options( array(
'search' => '*' . $search . '*'
) );
break;
}
}
// ACF
else if ( 'column-acf_field' == $column->properties->type ) {
switch ( $column->get_field_type() ) {
case 'page_link':
case 'post_object':
// ACF 5
if ( function_exists( 'acf_get_setting' ) ) {
$field = ( $column->get_field_type() == 'post_object' ) ? new acf_field_post_object() : new acf_field_page_link();
$choices = $field->get_choices( array(
's' => $search,
'field_key' => $column->get_field_key(),
'post_id' => $_GET['item_id']
) );
$options = array();
foreach ( $choices as $choice ) {
if ( ! isset( $choice['id'] ) ) {
$options[ $choice['text'] ] = array(
'label' => $choice['text'],
'options' => array()
);
foreach ( $choice['children'] as $subchoice ) {
$options[ $choice['text'] ]['options'][ $subchoice['id'] ] = $subchoice['text'];
}
}
else {
$options[ $choice['id'] ] = $choice['text'];
}
}
}
// ACF 4
else {
$field = $column->get_field();
$post_type = 'any';
if ( ! empty( $field['post_type'] ) ) {
$post_type = $field['post_type'];
}
$options = $this->get_posts_options( array( 's' => $search, 'post_type' => $post_type ) );
}
break;
case 'user':
if ( function_exists( 'acf_get_setting' ) ) {
$field = new acf_field_user();
$choices = $field->get_choices( array(
's' => $search,
'field_key' => $column->get_field_key(),
'post_id' => $_GET['item_id']
) );
$options = array();
foreach ( $choices as $choice ) {
if ( ! isset( $choice['id'] ) ) {
$options[ $choice['text'] ] = array(
'label' => $choice['text'],
'options' => array()
);
foreach ( $choice['children'] as $subchoice ) {
$options[ $choice['text'] ]['options'][ $subchoice['id'] ] = $subchoice['text'];
}
}
else {
$options[ $choice['id'] ] = $choice['text'];
}
}
}
else {
$options = $this->get_users_options( array(
'search' => '*' . $search . '*'
) );
}
break;
}
}
// Author
else if ( in_array( $column->properties->type, array(
'author',
'column-author_name',
'column-user' // comment column
) ) ) {
$options = $this->get_users_options( array(
'search' => '*' . $search . '*'
) );
}
// Post parent
else if ( $column->properties->type == 'column-parent' ) {
$options = $this->get_posts_options( array( 's' => $search, 'post_type' => $column->get_post_type() ) );
}
// WooCommerce: Upsells
// WooCommerce: Crosssells
// WooCommerce: Included Products
// WooCommerce: Excluded Products
else if ( in_array( $column->properties->type, array(
'column-wc-upsells',
'column-wc-crosssells',
'column-wc-exclude_products',
'column-wc-include_products'
) ) ) {
$args = array(
'post_type' => 'product',
'post_status' => 'any',
's' => $search,
'fields' => 'ids',
'posts_per_page' => 60
);
$args2 = array(
'post_type' => 'product',
'post_status' => 'any',
'meta_query' => array(
array(
'key' => '_sku',
'value' => $search,
'compare' => 'LIKE'
)
),
'fields' => 'ids',
'posts_per_page' => 60
);
$posts = array_unique( array_merge( get_posts( $args ), get_posts( $args2 ) ) );
$options = array();
foreach ( $posts as $post ) {
$product = get_product( $post );
$options[ $post ] = $product->get_formatted_name();
}
}
else if ( $column->properties->type == 'column-wc-parent' ) {
$args = array(
'post_type' => 'product',
'post_status' => 'any',
'posts_per_page' => 100,
's' => $search,
'tax_query' => array(
array(
'taxonomy' => 'product_type',
'field' => 'slug',
'terms' => 'grouped'
)
),
'fields' => 'ids',
);
$posts = get_posts( $args );
$options = array();
foreach ( $posts as $post ) {
$product = get_product( $post );
$name = str_replace( '– ', '', $product->get_formatted_name() ); // removes arrow
$options[ $post ] = $name;
}
}
// Third party
else if ( method_exists( $column, 'get_editable_ajax_options' ) ) {
$options = $column->get_editable_ajax_options( $_GET, $this );
}
wp_send_json_success( $this->format_options( $options ) );
}
/**
* Get total post count
* Used to determine whether post dropdowns should be populated directly or through AJAX
*
* @since 1.0
*
* @return int Total amount of published posts amongst all post types
*/
protected function get_total_post_count() {
$count = 0;
if ( $posttypes = get_post_types() ) {
foreach ( $posttypes as $posttype ) {
$counter = wp_count_posts( $posttype );
$count += $counter->publish;
}
}
return $count;
}
/**
* Get total user count
* Used to determine whether user dropdowns should be populated directly or through AJAX
*
* @since 1.0
*
* @return int Total number of users registered
*/
protected function get_total_user_count() {
$count = count_users();
return $count['total_users'];
}
/**
* Check if the columns is editable and if the user enabled editing for this column
*
* @since 1.1
*
* @param object CPAC_Column
* @return bool
*/
public function is_edit_enabled( $column ) {
if ( ! isset( $column->properties->is_editable ) || ! $column->properties->is_editable || ! isset( $column->options ) || ! isset( $column->options->edit ) || $column->options->edit != 'on' ) {
return false;
}
return true;
}
/**
* Settings based on ACF field type
* @since 3.6
*/
private function get_acf_editable_settings_by_field( $field ) {
$editable = array();
switch ( $field['type'] ) {
case 'checkbox':
$editable['type'] = 'checklist';
break;
case 'color_picker':
$editable['type'] = 'text';
break;
case 'date_picker':
$editable['type'] = 'date';
break;
case 'email':
$editable['type'] = 'email';
break;
case 'file':
// @todo Implement "attachment" type
$editable['type'] = 'attachment';
if ( empty( $field['required'] ) ) {
$editable['clear_button'] = true;
}
break;
case 'gallery':
$editable['type'] = 'media';
$editable['multiple'] = true;
$editable['attachment']['disable_select_current'] = true;
break;
case 'image':
$editable['type'] = 'media';
$editable['attachment']['library']['type'] = 'image';
if ( empty( $field['required'] ) ) {
$editable['clear_button'] = true;
}
break;
case 'number':
$editable['type'] = 'number';
$editable['range_step'] = 'any';
break;
case 'taxonomy':
$editable['type'] = 'select';
$editable['advanced_dropdown'] = true;
break;
case 'page_link':
case 'post_object':
if ( ! function_exists( 'acf_get_setting' ) || version_compare( acf_get_setting( 'version' ), '5.1.0' ) >= 0 ) {
$editable['type'] = 'select2_dropdown';
$editable['ajax_populate'] = true;
$editable['advanced_dropdown'] = true;
$editable['formatted_value'] = 'post';
}
if ( $field['multiple'] == 0 && $field['allow_null'] == 1 ) {
$editable['clear_button'] = true;
}
break;
case 'password':
$editable['type'] = 'password';
break;
case 'radio':
$editable['type'] = 'select';
break;
case 'select':
$editable['type'] = 'select';
$editable['advanced_dropdown'] = true;
break;
case 'text':
$editable['type'] = 'text';
break;
case 'textarea':
$editable['type'] = 'textarea';
break;
case 'true_false':
$editable['type'] = 'togglable';
$editable['options'] = array( '0', '1' );
break;
case 'url':
$editable['type'] = 'url';
break;
case 'user':
if ( ! function_exists( 'acf_get_setting' ) || version_compare( acf_get_setting( 'version' ), '5.1.0' ) >= 0 ) {
$editable['type'] = 'select2_dropdown';
$editable['ajax_populate'] = true;
$editable['advanced_dropdown'] = true;
$editable['formatted_value'] = 'user';
}
break;
case 'wysiwyg':
$editable['type'] = 'textarea';
break;
/*case 'repeater':
if ( ! empty( $field['sub_fields'] ) ) {
foreach ( $field['sub_fields'] as $sub_field ) {
if ( $sub_field['key'] === $column['sub_field'] ) {
$editable = $this->get_acf_editable_settings_by_field( $sub_field, $column );
}
}
}
break;*/
}
return $editable;
}
/**
* Get the editability options for a single column
* The array returned contains information about the editability of a column
* For example, it usually holds the editability type in $array['type'], which can be, for example, "text" or "select" or "email"
*
* @since 1.0
*
* @param array|string $column Column options or column name. In case a column name is provided, the column object is fetched based on the name
* @return bool|array Returns false if the column is not editable, an array with editability settings otherwise
*/
public function get_editable( $column ) {
// Get column data by column name
if ( is_string( $column ) ) {
$columns = $this->storage_model->get_stored_columns();
if ( empty( $columns[ $column ] ) ) {
return false;
}
$column = $columns[ $column ];
}
// Edit possible for this column type
if ( ! isset( $column['edit'] ) || $column['edit'] != 'on' ) {
return false;
}
// Get default column editable data
$editables = $this->get_editables_data();
$editable = ! empty( $editables[ $column['type'] ] ) ? $editables[ $column['type'] ] : array();
// ACF Field
switch ( $column['type'] ) {
// ACF Field
case 'column-acf_field' :
// make sure acf and the add-on are still active...
if ( ! function_exists( 'acf' ) || ! function_exists( 'cpac_get_acf_field' ) ) {
return false;
}
// Load field settings from ACF
if ( $field = cpac_get_acf_field( $column['field'] ) ) {
$editable['advanced_dropdown'] = false;
// add acf editable settings
$editable = array_merge( $editable, $this->get_acf_editable_settings_by_field( $field ) );
// Create an advanced dropdown menu
if ( $editable['advanced_dropdown'] ) {
if ( ! empty( $field['multiple'] ) || ( ! empty( $field['field_type'] ) && in_array( $field['field_type'], array( 'checkbox', 'multi_select' ) ) ) ) {
$editable['type'] = 'select2_dropdown';
$editable['multiple'] = true;
}
else {
if ( ! empty( $field['allow_null'] ) ) {
if ( $field['type'] == 'taxonomy' ) {
$option_null = array(
'' => __( 'None' )
);
}
else {
$option_null = array(
'null' => __( '- Select -', 'codepress-admin-columns' )
);
}
if ( ! isset( $editable['options'] ) || ! is_array( $editable['options'] ) ) {
$editable['options'] = array();
}
$editable['options'] = $option_null + $editable['options'];
}
}
}
if ( ! empty( $field['required'] ) ) {
$editable['required'] = true;
}
if ( ! empty( $field['placeholder'] ) ) {
$editable['placeholder'] = $field['placeholder'];
}
if ( ! empty( $field['maxlength'] ) ) {
$editable['maxlength'] = $field['maxlength'];
}
if ( ! empty( $field['min'] ) ) {
$editable['range_min'] = $field['min'];
}
if ( ! empty( $field['max'] ) ) {
$editable['range_max'] = $field['max'];
}
if ( ! empty( $field['step'] ) ) {
$editable['range_step'] = $field['step'];
}
if ( ! empty( $field['library'] ) ) {
if ( $field['library'] == 'uploadedTo' ) {
$editable['attachment']['library']['uploaded_to_post'] = true;
}
}
if ( empty( $field['ajax_populate'] ) ) {
// Options from ACF
$fieldoptions = new CACIE_ACF_FieldOptions();
$options = $fieldoptions->get_field_options( $field );
if ( $options !== false ) {
$editable['options'] = $options;
}
}
}
break;
// Custom Fields
case 'column-meta' :
switch( $column['field_type'] ) {
case 'excerpt' :
$editable['type'] = 'textarea';
break;
case 'checkmark' :
$editable['type'] = 'togglable';
$editable['options'] = array( '0', '1' );
break;
case 'library_id' :
$editable['type'] = 'attachment';
$editable['clear_button'] = true;
break;
case 'title_by_id' :
$editable['type'] = 'select2_dropdown';
$editable['ajax_populate'] = true;
break;
case 'user_by_id' :
$editable['type'] = 'select2_dropdown';
$editable['ajax_populate'] = true;
break;
default :
$editable['type'] = 'text';
}
break;
// Taxonomy column
case 'column-taxonomy' :
case 'categories' :
case 'tags' :
if ( isset( $column['enable_term_creation'] ) && 'on' == $column['enable_term_creation'] ) {
$editable['type'] = 'select2_tags';
}
else {
$editable['type'] = 'select2_dropdown';
$editable['multiple'] = true;
}
break;
}
// Developers can define editable settings with their column by using get_editable_settings();
if ( empty( $editable ) ) {
if ( $_column = $this->storage_model->get_column_by_name( $column['column-name'] ) ) {
if ( method_exists( $_column, 'get_editable_settings' ) ) {
$editable = $_column->get_editable_settings();
}
}
}
// Add all available options if we are not using ajax, and they haven't been set yet
if ( empty( $editable['ajax_populate'] ) ) {
// Fetch column options, and only use them if an array of options is passed
$options = $this->get_column_options( $column );
if ( $options !== false ) {
$editable['options'] = $options;
}
if ( ! empty( $editable['options'] ) ) {
$editable['options'] = $this->format_options( $editable['options'] );
}
}
// deprecated
$editable = apply_filters( 'cacie/inline_edit/options', $editable, $column );
/**
* Filters the options for the editable field.
*
* @since 3.2.2
* @param array $editable List of edit options ([type] => [field_type] )
* @param array $column Stored column settings
*/
return apply_filters( 'cac/editable/options', $editable, $column, $this );
}
/**
* Get a list of editable columns, with the default column options and an
* addon_cacie array key, containing the add-on data
*
* @since 1.0
*
* @return array List of columns ([column_name] => [column_options])
*/
public function get_columns() {
// Editable columns
$columns = array();
if ( $stored_columns = $this->storage_model->get_stored_columns() ) {
foreach ( $stored_columns as $column_name => $column ) {
if ( false !== ( $editable = $this->get_editable( $column ) ) ) {
$columns[ $column_name ] = $column;
$columns[ $column_name ]['addon_cacie'] = array( 'editable' => $editable );
}
}
}
return $columns;
}
/**
* Get possible options for column with a defined set of possible options
*
* @since 1.0
*
* @param array $column Column array with column options
* @return array List of options with option value as key and option label as value
*/
public function get_column_options( $column ) {
return false;
}
/**
* Ajax callback for storing user preference of the default state of editability on an overview page
*
* @since 3.2.1
*/
public function ajax_editability_state_save() {
if ( $this->storage_model->key != $_POST['storage_model'] ) {
return;
}
$is_enabled = $_POST['value'] ? '1' : '0';
update_user_meta( get_current_user_id(), 'cacie_editability_state' . $this->storage_model->key, $is_enabled );
exit( $is_enabled );
}
/**
* Get editability preference
*
* @since 3.2.1
*/
public function get_editability_preference() {
$is_active = '1' === get_user_meta( get_current_user_id(), 'cacie_editability_state' . $this->storage_model->key, true );
/**
* Filters the default state of editability of cells on overview pages
*
* @since 3.0.9
*
* @param $is_active bool Whether the default state is active (true) or inactive (false)
*/
$is_active = apply_filters( 'cacie/inline_edit/active', $is_active );
$is_active = apply_filters( 'cacie/inline_edit/active/storage_key=' . $this->storage_model->key, $is_active );
return $is_active;
}
/**
* Ajax callback for saving a column
*
* @since 1.0
*/
public function ajax_column_save() {
if ( $this->storage_model->key != $_POST['storage_model'] ) {
return;
}
// Basic request validation
if ( empty( $_POST['plugin_id'] ) || empty( $_POST['pk'] ) || empty( $_POST['column'] ) ) {
wp_send_json_error( __( 'Required fields missing.', 'codepress-admin-columns' ) );
}
// Get ID of entry to edit
if ( ! ( $id = intval( $_POST['pk'] ) ) ) {
wp_send_json_error( __( 'Invalid item ID.', 'codepress-admin-columns' ) );
}
// Get column instance
$column = $this->storage_model->get_column_by_name( $_POST['column'] );
if ( ! $column ) {
wp_send_json_error( __( 'Invalid column.', 'codepress-admin-columns' ) );
}
$value = isset( $_POST['value'] ) ? $_POST['value'] : '';
/**
* Filter for changing the value before storing it to the DB
*
* @since 3.2.1
*
* @param mixed $value Value send from inline edit ajax callback
* @param object CPAC_Column instance
* @param int $id ID
*/
$value = apply_filters( 'cac/inline-edit/ajax-column-save/value', $value, $column, $id );
// Store column
$save_result = $this->column_save( $id, $column, $value );
if ( is_wp_error( $save_result ) ) {
status_header( 400 );
echo $save_result->get_error_message();
exit;
}
ob_start();
// WP default column
if ( $column->properties->default ) {
$this->manage_value( $column, $id );
}
// Taxonomy
else if ( 'taxonomy' == $this->storage_model->type ) {
echo $this->storage_model->manage_value( '', $column->properties->name, $id );
}
// Custom Admin column
else {
echo $this->storage_model->manage_value( $column->properties->name, $id );
}
$contents = ob_get_clean();
/**
* Fires after a inline-edit succesfully saved a value
*
* @since ????
*
* @param CPAC_Column $column Column instance
* @param int $id Item ID
* @param string $value User submitted input
* @param object $this CACIE_Editable_Model $editable_model_instance Editability model instance
*/
do_action( 'cac/inline-edit/after_ajax_column_save', $column, $id, $value, $this );
$jsondata = array(
'success' => true,
'data' => array(
'value' => $contents
)
);
// We don't want a Nullable rawvalue in our JSON because select2 will break
$raw_value = $this->get_column_editability_value( $column, $id );
if ( NULL !== $raw_value ) {
$jsondata['data']['rawvalue'] = $this->get_column_editability_value( $column, $id );
}
if ( is_callable( array( $column, 'get_item_data' ) ) ) {
$jsondata['data']['itemdata'] = $column->get_item_data( $id );
}
wp_send_json( $jsondata );
}
/**
* Add the option of inline editing to columns
*
* @since 1.0
*/
public function enable_inlineedit( $columns ) {
foreach ( $columns as $column ) {
if ( $this->is_editable( $column ) ) {
// Enable editing
$column->set_properties( 'is_editable', true );
}
}
}
/**
* Update Meta
*
* @since 1.0
*/
protected function update_meta( $id, $meta_key, $value ) {
update_metadata( $this->storage_model->meta_type, $id, $meta_key, $value );
}
/**
* Format options to be in JS
*
* @since 1.0
*
* @param array $options List of options, possibly with option groups
* @return array Formatted option list
*/
public function format_options( $options ) {
$newoptions = array();
if ( $options ) {
foreach ( $options as $index => $option ) {
if ( is_array( $option ) && isset( $option['options'] ) ) {
$option['options'] = $this->format_options( $option['options'] );
$newoptions[] = $option;
}
else {
$newoptions[] = array(
'value' => $index,
'label' => $option
);
}
}
}
return $newoptions;
}
/**
* @since ?
*/
public function get_formatted_value( $column, $raw_value ) {
$formattedvalues = NULL;
$editable = $this->get_editable( $column->properties->name );
$formatted_value = isset( $editable['formatted_value'] ) ? $editable['formatted_value'] : '';
switch ( $formatted_value ) {
case 'post' :
$formattedvalues = array();
if ( ! empty( $raw_value ) ) {
foreach ( (array) $raw_value as $id ) {
$formattedvalues[ $id ] = get_post_field( 'post_title', $id );
}
}
break;
case 'user' :
$formattedvalues = array();
if ( ! empty( $raw_value ) ) {
foreach ( (array) $raw_value as $id ) {
$user = get_user_by( 'id', $id );
if ( is_a( $user, 'WP_User' ) ) {
$formattedvalues[ $id ] = $user->display_name;
}
}
}
break;
case 'wc_product' :
$formattedvalues = array();
if ( ! empty( $raw_value ) ) {
foreach ( (array) $raw_value as $id ) {
if ( $product = get_product( $id ) ) {
$formattedvalues[ $id ] = $product->get_title();
}
}
}
break;
}
return $formattedvalues;
}
/**
* Get term options for a taxonomy
*
* @since 1.0
*
* @param string $taxonomy Taxonomy name
* @param string $default Default option ( key is always zero )
* @return List of term options (term_id => name)
*/
public function get_term_options( $taxonomy, $default = '' ) {
$options = array();
if ( $default ) {
$options[0] = $default;
}
$terms = get_terms( $taxonomy, array(
'hide_empty' => 0,
));
if ( $terms && ! is_wp_error( $terms ) ) {
foreach ( $terms as $term ) {
$options[ $term->term_id ] = $term->name;
}
}
return $options;
}
/**
* Update post terms
*
* @since 1.0
*
* @param mixed $post Post object or post ID. Pass NULL to use the current post in the loop.
* @param array $term_ids Term IDs (int) or names (string, will be added as new term if it doesn't exist yet) to be stored
* @param string $taxonomy Taxonomy to set the terms for
*/
public function set_post_terms( $post, $term_ids, $taxonomy ) {
$post = get_post( $post );
if ( ! $post ) {
return;
}
// Filter list of terms
if ( empty( $term_ids ) ) {
$term_ids = array();
}
$term_ids = array_unique( (array) $term_ids );
// maybe create terms?
$created_term_ids = array();
foreach ( (array) $term_ids as $index => $term_id ) {
if ( is_numeric( $term_id ) ) {
continue;
}
if ( $term = get_term_by( 'name', $term_id, $taxonomy ) ) {
$term_ids[ $index ] = $term->term_id;
}
else {
$created_term = wp_insert_term( $term_id, $taxonomy );
$created_term_ids[] = $created_term['term_id'];
}
}
// merge
$term_ids = array_merge( $created_term_ids, $term_ids );
//to make sure the terms IDs is integers:
$term_ids = array_map( 'intval', (array) $term_ids );
$term_ids = array_unique( $term_ids );
if ( $taxonomy == 'category' && is_object_in_taxonomy( $post->post_type, 'category' ) ) {
wp_set_post_categories( $post->ID, $term_ids );
}
else if ( $taxonomy == 'post_tag' && is_object_in_taxonomy( $post->post_type, 'post_tag' ) ) {
wp_set_post_tags( $post->ID, $term_ids );
}
else {
wp_set_object_terms( $post->ID, $term_ids, $taxonomy );
}
}
/**
* Get editability value for a column
*
* @since 3.4
*
* @param CPAC_Column $column Column
* @param integer $id Item ID
* @return mixed Raw value
*/
public function get_column_editability_value( $column, $id ) {
if ( ! $column->properties->default ) {
return $column->get_raw_value( $id );
}
return NULL;
}
}