Passed
Push — master ( 2e4958...c7e94e )
by Warwick
03:30
created

MAG_CMB2_Field_Post_Search_Ajax::get_instance()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 6
rs 10
1
<?php
2
/**
3
 * Class MAG_CMB2_Field_Post_Search_Ajax
4
 */
5
6
if ( ! class_exists( 'MAG_CMB2_Field_Post_Search_Ajax' ) ) {
7
8
	/**
9
	 * The LSX Post Search Field
10
	 */
11
	class MAG_CMB2_Field_Post_Search_Ajax {
12
13
		/**
14
		 * Current version number
15
		 */
16
		const VERSION = '1.0.0';
17
18
		/**
19
		 * The url which is used to load local resources
20
		 * 
21
		 * @var string
22
		 */
23
		protected static $url = '';
24
25
		/**
26
		 * Holds class instance
27
		 *
28
		 * @since 1.0.0
29
		 *
30
		 * @var      object \MAG_CMB2_Field_Post_Search_Ajax
31
		 */
32
		protected static $instance = null;
33
34
		/**
35
		 * Initialize the plugin by hooking into CMB2
36
		 */
37
		public function __construct() {
38
			add_action( 'cmb2_render_post_search_ajax', array( $this, 'render' ), 10, 5 );
39
			add_action( 'cmb2_sanitize_post_search_ajax', array( $this, 'sanitize' ), 10, 4 );
40
			add_action( 'wp_ajax_cmb_post_search_ajax_get_results', array( $this, 'cmb_post_search_ajax_get_results' ) );
41
		}
42
43
		/**
44
		 * Return an instance of this class.
45
		 *
46
		 * @since 1.0.0
47
		 *
48
		 * @return    object \MAG_CMB2_Field_Post_Search_Ajax    A single instance of this class.
49
		 */
50
		public static function get_instance() {
51
			// If the single instance hasn't been set, set it now.
52
			if ( null === self::$instance ) {
53
				self::$instance = new self();
54
			}
55
			return self::$instance;
56
		}
57
58
		/**
59
		 * Render field
60
		 */
61
		public function render( $field, $value, $object_id, $object_type, $field_type ) {	
62
			$this->setup_admin_scripts();
63
			$field_name = $field->_name();
64
65
			if ( $field->args( 'limit' ) > 1 ) {
66
67
				echo '<ul class="cmb-post-search-ajax-results" id="' . $field_name . '_results">';
68
				if ( isset( $value ) && ! empty( $value ) ) {
69
					if ( ! is_array( $value ) ) {
70
						$value = array( $value );
71
					}
72
					$value = array_unique( $value );
73
					foreach ( $value as $val ) {
74
						$handle = ( $field->args( 'sortable' ) ) ? '<span class="hndl"></span>' : '';
75
						$li_css = '';
76
						if ( $field->args( 'object_type' ) == 'user' ) {
77
							$guid  = get_edit_user_link( $val );
78
							$user  = get_userdata( $val );
79
							$title = $user->display_name;
80
						} else {
81
							$guid  = get_edit_post_link( $val );
82
							$title = get_the_title( $val );
83
							if ( 'trash' === get_post_status( $val ) ) {
84
								$li_css = 'display:none;';
85
							}
86
						}
87
						echo '<li style="' . $li_css . '">' . $handle . '<input type="hidden" name="' . $field_name . '_results[]" value="' . $val . '"><a href="' . $guid . '" target="_blank" class="edit-link">' . $title . '</a><a class="remover"><span class="dashicons dashicons-no"></span><span class="dashicons dashicons-dismiss"></span></a></li>';
88
					}
89
				}
90
				echo '</ul>';
91
				$field_value = '';
92
			} else {
93
				if ( is_array( $value ) ) {
94
					$value = $value[0];
95
				}
96
				if ( $field->args( 'object_type' ) == 'user' ) {
97
					$field_value = ( $value ? get_userdata( $value )->display_name : '' );
98
				} else {
99
					$field_value = ( $value ? get_the_title( $value ) : '' );
100
				}
101
				echo $field_type->input( 
102
					array(
103
						'type'  => 'hidden',
104
						'name'  => $field_name . '_results',
105
						'value' => $value,
106
						'desc'  => false,
107
					)
108
				);
109
				if ( isset( $field->group ) ) {
110
					$store_name = str_replace( '][', '_', $field_name );
111
					$store_name = str_replace( ']', '', $store_name );
112
					$store_name = str_replace( '[', '_', $store_name );
113
114
					echo $field_type->input(
115
						array(
116
							'type'  => 'hidden',
117
							'id'    => $field_name . '_store',
118
							'name'  => $store_name . '_store',
119
							'class' => 'cmb-post-search-ajax-store',
120
							'value' => $value,
121
							'desc'  => false,
122
						)
123
					);
124
				}
125
			}
126
127
			echo $field_type->input( 
128
				array( 
129
					'type' 			=> 'text',
130
					'name' 			=> $field_name,
131
					'id'			=> $field_name,
132
					'class'			=> 'cmb-post-search-ajax',
133
					'value' 		=> $field_value,
134
					'desc'			=> false,
135
					'data-limit'	=> $field->args( 'limit' ) ? $field->args( 'limit' ) : '1',
136
					'data-sortable'	=> $field->args( 'sortable' ) ? $field->args( 'sortable' ) : '0',
137
					'data-object'	=> $field->args( 'object_type' ) ? $field->args( 'object_type' ) : 'post',
138
					'data-queryargs'=> $field->args( 'query_args' ) ? htmlspecialchars( json_encode( $field->args( 'query_args' ) ), ENT_QUOTES, 'UTF-8' ) : ''
139
				)
140
			);
141
142
			echo '<img src="' . admin_url( 'images/spinner.gif' ) . '" class="cmb-post-search-ajax-spinner" />';
143
144
			$field_type->_desc( true, true );
145
146
		}
147
148
		/**
149
		 * Optionally save the latitude/longitude values into two custom fields
150
		 */
151
		public function sanitize( $override_value, $value, $object_id, $field_args ) {
152
			$fid = '';
153
			if ( isset( $field_args['id'] ) ) {
154
				$fid = $field_args['id'];
155
			}
156
157
			// IF the field is in a repeatable group, then get the info from the post data.
158
			if ( isset( $field_args['render_row_cb'][0]->group ) && ! empty( $field_args['render_row_cb'][0]->group ) ) {
159
				$new_index = '';
160
161
				$data_to_save = $field_args['render_row_cb'][0]->group->args['render_row_cb'][0]->data_to_save;
162
				$oid          = $field_args['_name'];
163
				$iid          = $field_args['_id'];
164
				$oid          = explode( '[', $oid );
165
				if ( is_array( $oid ) ) {
0 ignored issues
show
introduced by
The condition is_array($oid) is always true.
Loading history...
166
					$oid = $oid[0];
167
				}
168
169
				if ( isset( $data_to_save[ $oid ] ) && ! empty( $data_to_save[ $oid ] ) ) {
170
					foreach( $data_to_save[ $oid ] as $index => $svalues ) {
171
						if ( isset( $svalues[ $iid ] ) && $value === $svalues[ $iid ] ) {
172
							$new_index = $index;
173
						}
174
					}
175
				}
176
177
				if ( '' !== $new_index ) {
178
					$new_index = $oid . '_' . $new_index . '_' . $iid . '_store';
179
180
					if ( ! empty( $data_to_save[ $new_index ] ) ) {
181
						$value = $data_to_save[ $new_index ];
182
					}
183
				} else {
184
					$value = false;
185
				}
186
			} else if ( ! empty( $field_args['render_row_cb'][0]->data_to_save[ $fid . '_results' ] ) ) {
187
				$value = $field_args['render_row_cb'][0]->data_to_save[ $fid . '_results' ];
188
			} else {
189
				$value = false;
190
			}
191
192
			return $value;
193
		}
194
195
		/**
196
		 * Defines the url which is used to load local resources. Based on, and uses, 
197
		 * the CMB2_Utils class from the CMB2 library.
198
		 */
199
		public static function url( $path = '' ) {
200
			if ( self::$url ) {
201
				return self::$url . $path;
202
			}
203
204
			/**
205
			 * Set the variable cmb2_fpsa_dir
206
			 */
207
			$cmb2_fpsa_dir = trailingslashit( dirname( __FILE__ ) );
208
209
			/**
210
			 * Use CMB2_Utils to gather the url from cmb2_fpsa_dir
211
			 */	
212
			$cmb2_fpsa_url = CMB2_Utils::get_url_from_dir( $cmb2_fpsa_dir );
213
214
			/**
215
			 * Filter the CMB2 FPSA location url
216
			 */
217
			self::$url = trailingslashit( apply_filters( 'cmb2_fpsa_url', $cmb2_fpsa_url, self::VERSION ) );
218
219
			return self::$url . $path;
220
		}
221
222
		/**
223
		 * Enqueue scripts and styles
224
		 */
225
		public function setup_admin_scripts() {
226
227
			wp_register_script( 'jquery-devautocomplete', self::url( 'js/jquery.autocomplete.min.js' ), array( 'jquery' ), self::VERSION );
228
			wp_register_script( 'mag-post-search-ajax', self::url( 'js/mag-post-search-ajax.js' ), array( 'jquery', 'jquery-devautocomplete', 'jquery-ui-sortable' ), self::VERSION );
229
			wp_localize_script( 'mag-post-search-ajax', 'psa', array(
230
				'ajaxurl' 	=> admin_url( 'admin-ajax.php' ),
231
				'nonce'		=> wp_create_nonce( 'mag_cmb_post_search_ajax_get_results' )
232
			) ); 
233
			wp_enqueue_script( 'mag-post-search-ajax' );
234
			wp_enqueue_style( 'mag-post-search-ajax', self::url( 'css/mag-post-search-ajax.css' ), array(), self::VERSION );
235
236
		}
237
238
		/**
239
		 * Ajax request : get results
240
		 */
241
		public function cmb_post_search_ajax_get_results() {
242
			$nonce = sanitize_text_field( $_POST['psacheck'] );
243
			if ( ! wp_verify_nonce( $nonce, 'mag_cmb_post_search_ajax_get_results' ) ) {
244
				die( json_encode( array( 'error' => __( 'Error : Unauthorized action' ) ) ) );
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
245
			} else {
246
				$args      = json_decode( stripslashes( htmlspecialchars_decode( sanitize_text_field( $_POST['query_args'] ) ) ), true );
247
				$args['s'] = sanitize_text_field( $_POST['query'] );
248
				$datas     = array();
249
				if ( $_POST['object'] == 'user' ) {
250
251
					$args['search'] = '*' . esc_attr( sanitize_text_field( $_POST['query'] ) ) . '*';
252
					$users          = new WP_User_Query( $args );
253
					$results        = $users->get_results();
254
255
					if ( ! empty( $results ) ) {
256
						foreach ( $results as $result ){
257
							$user_info = get_userdata( $result->ID );
258
							// Define filter "mag_cmb_post_search_ajax_result" to allow customize ajax results.
259
							$datas[] = apply_filters( 'mag_cmb_post_search_ajax_result', array(
260
								'value' => $user_info->display_name,
261
								'data'  => $result->ID,
262
								'guid'  => get_edit_user_link( $result->ID ),
263
							) );
264
						}
265
					}
266
				} else {
267
					$results 	= new WP_Query( $args );
268
					if ( $results->have_posts() ) :
269
						while ( $results->have_posts() ) : $results->the_post();
270
							// Define filter "mag_cmb_post_search_ajax_result" to allow customize ajax results.
271
							$datas[] = apply_filters( 'mag_cmb_post_search_ajax_result', array(
272
								'value' => get_the_title() . ' - ' . '#' . get_the_ID(),
0 ignored issues
show
Bug introduced by
Are you sure get_the_ID() of type false|integer can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

272
								'value' => get_the_title() . ' - ' . '#' . /** @scrutinizer ignore-type */ get_the_ID(),
Loading history...
273
								'data'	=> get_the_ID(),
274
								'guid'	=> get_edit_post_link(),
275
							) );
276
						endwhile;
277
					endif;
278
				}
279
				wp_reset_postdata();
280
				die( json_encode( $datas ) );
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
281
			}
282
		}
283
	}
284
}
285