294 lines
11 KiB
PHP
294 lines
11 KiB
PHP
<?php
|
|
/*
|
|
Plugin Name: CMB2 Field Type: Ajax Search
|
|
Plugin URI: https://github.com/rubengc/cmb2-field-ajax-search
|
|
GitHub Plugin URI: https://github.com/rubengc/cmb2-field-ajax-search
|
|
Description: CMB2 field type to attach posts, users or terms.
|
|
Version: 1.0.0
|
|
Author: Ruben Garcia
|
|
Author URI: http://rubengc.com/
|
|
License: GPLv2+
|
|
*/
|
|
|
|
// This plugin is based on CMB2 Field Type: Post Search Ajax (https://github.com/alexis-magina/cmb2-field-post-search-ajax)
|
|
// Special thanks to Magina (http://magina.fr/) for him awesome work
|
|
|
|
if( ! class_exists( 'CMB2_Field_Ajax_Search' ) ) {
|
|
|
|
/**
|
|
* Class CMB2_Field_Ajax_Search
|
|
*/
|
|
class CMB2_Field_Ajax_Search {
|
|
|
|
/**
|
|
* Current version number
|
|
*/
|
|
const VERSION = '1.0.0';
|
|
|
|
/**
|
|
* Initialize the plugin by hooking into CMB2
|
|
*/
|
|
public function __construct() {
|
|
add_action( 'admin_enqueue_scripts', array( $this, 'setup_admin_scripts' ) );
|
|
|
|
// Render
|
|
add_action( 'cmb2_render_post_ajax_search', array( $this, 'render' ), 10, 5 );
|
|
add_action( 'cmb2_render_user_ajax_search', array( $this, 'render' ), 10, 5 );
|
|
add_action( 'cmb2_render_term_ajax_search', array( $this, 'render' ), 10, 5 );
|
|
|
|
// Display
|
|
add_filter( 'cmb2_pre_field_display_post_ajax_search', array( $this, 'display' ), 10, 3 );
|
|
add_filter( 'cmb2_pre_field_display_user_ajax_search', array( $this, 'display' ), 10, 3 );
|
|
add_filter( 'cmb2_pre_field_display_term_ajax_search', array( $this, 'display' ), 10, 3 );
|
|
|
|
// Sanitize
|
|
add_action( 'cmb2_sanitize_post_ajax_search', array( $this, 'sanitize' ), 10, 4 );
|
|
add_action( 'cmb2_sanitize_user_ajax_search', array( $this, 'sanitize' ), 10, 4 );
|
|
add_action( 'cmb2_sanitize_term_ajax_search', array( $this, 'sanitize' ), 10, 4 );
|
|
|
|
// Ajax request
|
|
add_action( 'wp_ajax_cmb_ajax_search_get_results', array( $this, 'get_results' ) );
|
|
}
|
|
|
|
/**
|
|
* Render field
|
|
*/
|
|
public function render( $field, $value, $object_id, $object_type, $field_type ) {
|
|
$field_name = $field->_name();
|
|
$default_limit = 1;
|
|
|
|
// Current filter is cmb2_render_{$object_to_search}_ajax_search ( post, user or term )
|
|
$object_to_search = str_replace( 'cmb2_render_', '', str_replace( '_ajax_search', '', current_filter() ) );
|
|
|
|
if( $field->args( 'multiple' ) == true ) {
|
|
$default_limit = -1; // 0 or -1 means unlimited
|
|
|
|
?><ul id="<?php echo $field_name; ?>_results" class="cmb-ajax-search-results cmb-<?php echo $object_to_search; ?>-ajax-search-results"><?php
|
|
|
|
if( isset( $value ) && ! empty( $value ) ){
|
|
if( ! is_array( $value ) ) {
|
|
$value = array( $value );
|
|
}
|
|
|
|
foreach( $value as $val ) :
|
|
?>
|
|
<li>
|
|
<?php if( $field->args( 'sortable' ) ) : ?><span class="hndl"></span><?php endif; ?>
|
|
<input type="hidden" name="<?php echo $field_name; ?>[]" value="<?php echo $val; ?>">
|
|
<a href="<?php echo $this->object_link( $field_name, $val, $object_to_search ); ?>" target="_blank" class="edit-link">
|
|
<?php echo $this->object_text( $field_name, $val, $object_to_search ); ?>
|
|
</a>
|
|
<a class="remover"><span class="dashicons dashicons-no"></span><span class="dashicons dashicons-dismiss"></span></a>
|
|
</li>
|
|
<?php
|
|
endforeach;
|
|
}
|
|
|
|
?></ul><?php
|
|
|
|
$input_value = '';
|
|
} else {
|
|
if( is_array( $value ) ) {
|
|
$value = $value[0];
|
|
}
|
|
|
|
echo $field_type->input( array(
|
|
'type' => 'hidden',
|
|
'name' => $field_name,
|
|
'value' => $value,
|
|
'desc' => false
|
|
) );
|
|
|
|
$input_value = ( $value ? $this->object_text( $field_name, $value, $object_to_search ) : '' );
|
|
}
|
|
|
|
echo $field_type->input( array(
|
|
'type' => 'text',
|
|
'name' => $field_name . '_input',
|
|
'id' => $field_name . '_input',
|
|
'class' => 'cmb-ajax-search cmb-' . $object_to_search . '-ajax-search',
|
|
'value' => $input_value,
|
|
'desc' => false,
|
|
'data-multiple' => $field->args( 'multiple' ) ? $field->args( 'multiple' ) : '0',
|
|
'data-limit' => $field->args( 'limit' ) ? $field->args( 'limit' ) : $default_limit,
|
|
'data-sortable' => $field->args( 'sortable' ) ? $field->args( 'sortable' ) : '0',
|
|
'data-object-type' => $object_to_search,
|
|
'data-query-args' => $field->args( 'query_args' ) ? htmlspecialchars( json_encode( $field->args( 'query_args' ) ), ENT_QUOTES, 'UTF-8' ) : ''
|
|
) );
|
|
|
|
echo '<img src="'.admin_url( 'images/spinner.gif' ).'" class="cmb-ajax-search-spinner" />';
|
|
|
|
$field_type->_desc( true, true );
|
|
|
|
}
|
|
|
|
/**
|
|
* Display field
|
|
*/
|
|
public function display( $pre_output, $field, $display ) {
|
|
$object_type = str_replace( 'cmb2_pre_field_display_', '', str_replace( '_ajax_search', '', current_filter() ) );
|
|
|
|
ob_start();
|
|
|
|
$field->peform_param_callback( 'before_display_wrap' );
|
|
|
|
printf( "<div class=\"cmb-column %s\" data-fieldtype=\"%s\">\n", $field->row_classes( 'display' ), $field->type() );
|
|
|
|
$field->peform_param_callback( 'before_display' );
|
|
|
|
if( is_array( $field->value ) ) : ?>
|
|
<?php foreach( $field->value as $value ) : ?>
|
|
<a href="<?php echo $this->object_link( $field->args['id'], $value, $object_type ); ?>" class="edit-link">
|
|
<?php echo $this->object_text( $field->args['id'], $value, $object_type ); ?>
|
|
</a> <br>
|
|
<?php endforeach; ?>
|
|
<?php else : ?>
|
|
<a href="<?php echo $this->object_link( $field->args['id'], $field->value, $object_type ); ?>" class="edit-link">
|
|
<?php echo $this->object_text( $field->args['id'], $field->value, $object_type ); ?>
|
|
</a>
|
|
<?php endif;
|
|
|
|
$field->peform_param_callback( 'after_display' );
|
|
|
|
echo "\n</div>";
|
|
|
|
$field->peform_param_callback( 'after_display_wrap' );
|
|
|
|
$pre_output = ob_get_clean();
|
|
|
|
return $pre_output;
|
|
}
|
|
|
|
/**
|
|
* Optionally save the latitude/longitude values into two custom fields
|
|
*/
|
|
public function sanitize( $override_value, $value, $object_id, $field_args ) {
|
|
$fid = $field_args['id'];
|
|
|
|
if($field_args['render_row_cb'][0]->data_to_save[$field_args['id']]) {
|
|
$value = $field_args['render_row_cb'][0]->data_to_save[$field_args['id']];
|
|
} else {
|
|
$value = false;
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
* Enqueue scripts and styles
|
|
*/
|
|
public function setup_admin_scripts() {
|
|
|
|
wp_register_script( 'jquery-autocomplete', plugins_url( 'js/jquery.autocomplete.min.js', __FILE__ ), array( 'jquery' ), self::VERSION, true );
|
|
wp_register_script( 'cmb-ajax-search', plugins_url( 'js/ajax-search.js', __FILE__ ), array( 'jquery', 'jquery-autocomplete', 'jquery-ui-sortable' ), self::VERSION, true );
|
|
|
|
wp_localize_script( 'cmb-ajax-search', 'cmb_ajax_search', array(
|
|
'ajaxurl' => admin_url( 'admin-ajax.php' ),
|
|
'nonce' => wp_create_nonce( 'cmb_ajax_search_get_results' )
|
|
) );
|
|
|
|
wp_enqueue_script( 'cmb-ajax-search' );
|
|
wp_enqueue_style( 'cmb-ajax-search', plugins_url( 'css/ajax-search.css', __FILE__ ), array(), self::VERSION );
|
|
|
|
}
|
|
|
|
/**
|
|
* Ajax request : get results
|
|
*/
|
|
public function get_results() {
|
|
$nonce = $_POST['nonce'];
|
|
|
|
if ( ! wp_verify_nonce( $nonce, 'cmb_ajax_search_get_results' ) ) {
|
|
// Wrong nonce
|
|
die( json_encode( array(
|
|
'error' => __( 'Error : Unauthorized action' )
|
|
) ) );
|
|
} else if ( ( ! isset( $_POST['field_id'] ) || empty( $_POST['field_id'] ) )
|
|
|| ( ! isset( $_POST['object_type'] ) || empty( $_POST['object_type'] ) ) ) {
|
|
// Wrong request parameters (field_id and object_type are mandatory)
|
|
die( json_encode( array(
|
|
'error' => __( 'Error : Wrong request parameters' )
|
|
) ) );
|
|
} else {
|
|
$query_args = json_decode( stripslashes( htmlspecialchars_decode( $_POST['query_args'] ) ), true );
|
|
$data = array();
|
|
$results = array();
|
|
|
|
switch( $_POST['object_type'] ) {
|
|
case 'post':
|
|
$query_args['s'] = $_POST['query'];
|
|
$query = new WP_Query( $query_args );
|
|
$results = $query->posts;
|
|
break;
|
|
case 'user':
|
|
$query_args['search'] = '*' . $_POST['query'] . '*';
|
|
$query = new WP_User_Query( $query_args );
|
|
$results = $query->results;
|
|
break;
|
|
case 'term':
|
|
$query_args['search'] = $_POST['query'];
|
|
$query = new WP_Term_Query( $query_args );
|
|
$results = $query->terms;
|
|
break;
|
|
}
|
|
|
|
foreach ( $results as $result ) :
|
|
if( $_POST['object_type'] == 'term' ) {
|
|
$result_id = $result->term_id;
|
|
} else {
|
|
$result_id = $result->ID;
|
|
}
|
|
|
|
$data[] = array(
|
|
'id' => $result_id,
|
|
'value' => $this->object_text( $_POST['field_id'], $result_id, $_POST['object_type'] ),
|
|
'link' => $this->object_link( $_POST['field_id'], $result_id, $_POST['object_type'] )
|
|
);
|
|
endforeach;
|
|
|
|
wp_send_json( $data );
|
|
exit;
|
|
}
|
|
}
|
|
|
|
public function object_text( $field_id, $object_id, $object_type ) {
|
|
$text = '';
|
|
|
|
if( $object_type == 'post' ) {
|
|
$text = get_the_title( $object_id );
|
|
} else if( $object_type == 'user' ) {
|
|
$text = get_the_author_meta('display_name', $object_id);
|
|
} else if( $object_type == 'term' ) {
|
|
$term = get_term( $object_id );
|
|
|
|
$text = $term->name;
|
|
}
|
|
|
|
$text = apply_filters( "cmb_{$field_id}_ajax_search_result_text", $text, $object_id, $object_type );
|
|
|
|
return $text;
|
|
}
|
|
|
|
public function object_link( $field_id, $object_id, $object_type ) {
|
|
$link = '#';
|
|
|
|
if( $object_type == 'post' ) {
|
|
$link = get_edit_post_link( $object_id );
|
|
} else if( $object_type == 'user' ) {
|
|
$link = get_edit_user_link( $object_id );
|
|
} else if( $object_type == 'term' ) {
|
|
$link = get_edit_term_link( $object_id );
|
|
}
|
|
|
|
$link = apply_filters( "cmb_{$field_id}_ajax_search_result_link", $link, $object_id, $object_type );
|
|
|
|
return $link;
|
|
}
|
|
|
|
}
|
|
|
|
$cmb2_field_ajax_search = new CMB2_Field_Ajax_Search();
|
|
|
|
}
|
|
|