1 <?php
2
3 4 5 6 7
8 class Fieldmanager_Datasource_Post extends Fieldmanager_Datasource {
9
10 11 12 13
14 public $query_callback = Null;
15
16 17 18 19 20 21
22 public $query_args = array();
23
24 25 26 27 28
29 public $use_ajax = True;
30
31 32 33 34 35
36 public $reciprocal = Null;
37
38 39 40 41
42 public $show_date = False;
43
44 45 46 47
48 public $date_format = 'Y-m-d';
49
50 51 52 53
54 public $publish_with_parent = False;
55
56 57 58 59
60 public $save_to_post_parent = False;
61
62 63 64 65
66 public $only_save_to_post_parent = False;
67
68 public function __construct( $options = array() ) {
69 parent::__construct( $options );
70
71
72 if ( $this->only_save_to_post_parent ) {
73 $this->save_to_post_parent = true;
74 }
75 }
76
77 78 79 80 81
82 public function get_value( $value ) {
83 $id = intval( $value );
84 return $id ? get_the_title( $id ) : '';
85 }
86
87 88 89 90 91 92
93 public function get_items( $fragment = Null ) {
94 if ( is_callable( $this->query_callback ) ) {
95 return call_user_func( $this->query_callback, $fragment );
96 }
97 $default_args = array(
98 'numberposts' => 10,
99 'orderby' => 'post_date',
100 'order' => 'DESC',
101 'post_status' => 'publish',
102 'post_type' => 'any',
103 'suppress_filters' => False,
104 );
105 $post_args = array_merge( $default_args, $this->query_args );
106 $ret = array();
107 if ( $fragment ) {
108 $post_id = $exact_post = Null;
109 if ( preg_match( '/^https?\:/i', $fragment ) ) {
110 $url = esc_url( $fragment );
111 $url_parts = parse_url( $url );
112
113 if ( ! empty( $url_parts['query'] ) ) {
114 $get_vars = array();
115 parse_str( $url_parts['query'], $get_vars );
116 }
117
118 if ( ! empty( $get_vars['post'] ) ) {
119 $post_id = intval( $get_vars['post'] );
120 } elseif ( ! empty( $get_vars['p'] ) ) {
121 $post_id = intval( $get_vars['p'] );
122 } else {
123 $post_id = fm_url_to_post_id( $fragment );
124 }
125 } elseif ( is_numeric( $fragment ) ) {
126 $post_id = intval( $fragment );
127 }
128 if ( $post_id ) {
129 $exact_post = get_post( $post_id );
130 if ( $exact_post && (
131 $post_args['post_type'] == 'any' ||
132 $post_args['post_type'] == $exact_post->post_type ||
133 in_array( $exact_post->post_type, $post_args['post_type'] )
134 ) ) {
135 if ( $this->show_date ) {
136 $date_pad = ' (' . date( $this->date_format, strtotime( $exact_post->post_date ) ) . ')';
137 }
138 else {
139 $date_pad = '';
140 }
141 $ret[ $post_id ] = html_entity_decode( $exact_post->post_title ) . $date_pad;
142 }
143 }
144 $this->_fragment = $fragment;
145 add_filter( 'posts_where', array( $this, 'title_like' ), 10, 2 );
146 }
147 $posts = get_posts( $post_args );
148 if ( $fragment ) {
149 remove_filter( 'posts_where', array( $this, 'title_like' ), 10, 2 );
150 }
151 foreach ( $posts as $p ) {
152 if ( $this->show_date ) {
153 $date_pad = ' (' . date( $this->date_format, strtotime( $p->post_date ) ) . ')';
154 }
155 else {
156 $date_pad = '';
157 }
158 $ret[$p->ID] = $p->post_title . $date_pad;
159 }
160 return $ret;
161 }
162
163 164 165 166 167
168 public function get_ajax_action() {
169 if ( !empty( $this->ajax_action ) ) return $this->ajax_action;
170 $unique_key = json_encode( $this->query_args );
171 $unique_key .= (string) $this->query_callback;
172 return 'fm_datasource_post' . crc32( $unique_key );
173 }
174
175 176 177
178 public function title_like( $where, &$wp_query ) {
179 global $wpdb;
180 if ( method_exists( $wpdb, 'esc_like' ) ) {
181 $like = esc_sql( $wpdb->esc_like( $this->_fragment ) );
182 } else {
183 $like = esc_sql( like_escape( $this->_fragment ) );
184 }
185 $where .= " AND {$wpdb->posts}.post_title LIKE '%{$like}%'";
186 return $where;
187 }
188
189 190 191 192 193
194 public function presave_alter_values( Fieldmanager_Field $field, $values, $current_values ) {
195 if ( 'post' == $field->data_type && ! empty( $this->reciprocal ) && ! empty( $current_values ) && is_array( $current_values ) ) {
196 foreach ( $current_values as $reciprocal_post_id ) {
197 delete_post_meta( $reciprocal_post_id, $this->reciprocal, $field->data_id );
198 }
199 }
200
201 return $values;
202 }
203
204 205 206 207 208
209 public function presave( Fieldmanager_Field $field, $value, $current_value ) {
210 if ( empty( $value ) ) {
211 return;
212 }
213 $value = intval( $value );
214
215 if ( ! empty( $this->publish_with_parent ) || ! empty( $this->reciprocal ) ) {
216
217 if ( ! defined( 'DOING_CRON' ) || ! DOING_CRON ) {
218 $post_type_obj = get_post_type_object( get_post_type( $value ) );
219 if ( empty( $post_type_obj->cap->edit_post ) || ! current_user_can( $post_type_obj->cap->edit_post, $value ) ) {
220 wp_die( esc_html( sprintf( __( 'Tried to alter %s %d through field "%s", which user is not permitted to edit.', 'fieldmanager' ), $post_type_obj->name, $value, $field->name ) ) );
221 }
222 }
223 $this->presave_status_transition( $field, $value );
224 if ( $this->reciprocal ) {
225 add_post_meta( $value, $this->reciprocal, $field->data_id );
226 }
227 }
228
229 if ( $this->save_to_post_parent && 1 == $field->limit && 'post' == $field->data_type ) {
230 if ( ! wp_is_post_revision( $field->data_id ) ) {
231 Fieldmanager_Context_Post::safe_update_post(
232 array(
233 'ID' => $field->data_id,
234 'post_parent' => $value,
235 )
236 );
237 }
238 if ( $this->only_save_to_post_parent ) {
239 return array();
240 }
241 }
242
243 return $value;
244 }
245
246 247 248 249 250 251
252 public function presave_status_transition( Fieldmanager_Field $field, $value ) {
253
254 if ( $this->publish_with_parent && 'post' === $field->data_type && ! empty( $field->data_id ) && 'publish' === get_post_status( $field->data_id ) ) {
255
256 wp_update_post( array( 'ID' => $value, 'post_status' => 'publish' ) );
257 }
258 }
259
260 261 262 263 264 265 266 267
268 public function preload_alter_values( Fieldmanager_Field $field, $values ) {
269 if ( $this->only_save_to_post_parent ) {
270 $post_parent = wp_get_post_parent_id( $field->data_id );
271 if ( $post_parent ) {
272 return ( 1 == $field->limit && empty( $field->multiple ) ) ? $post_parent : array( $post_parent );
273 }
274 }
275 return $values;
276 }
277
278 279 280 281 282
283 public function get_view_link( $value ) {
284 return sprintf(
285 ' <a target="_new" class="fm-autocomplete-view-link %s" href="%s">%s</a>',
286 empty( $value ) ? 'fm-hidden' : '',
287 empty( $value ) ? '#' : esc_url( get_permalink( $value ) ),
288 esc_html__( 'View', 'fieldmanager' )
289 );
290 }
291
292 293 294 295 296
297 public function get_edit_link( $value ) {
298 return sprintf(
299 ' <a target="_new" class="fm-autocomplete-edit-link %s" href="%s">%s</a>',
300 empty( $value ) ? 'fm-hidden' : '',
301 empty( $value ) ? '#' : esc_url( get_edit_post_link( $value ) ),
302 esc_html__( 'Edit', 'fieldmanager' )
303 );
304 }
305
306 }
307
308 309 310 311 312 313 314
315 function fm_url_to_post_id( $url ) {
316 global $wp_rewrite;
317
318 $url = apply_filters('url_to_postid', $url);
319
320
321 if ( preg_match('#[?&](p|page_id|attachment_id)=(\d+)#', $url, $values ) ) {
322 $id = absint($values[2]);
323 if ( $id )
324 return $id;
325 }
326
327
328 $rewrite = $wp_rewrite->wp_rewrite_rules();
329
330
331 if ( empty( $rewrite ) )
332 return 0;
333
334
335 $url_split = explode( '#', $url );
336 $url = $url_split[0];
337
338
339 $url_split = explode('?', $url);
340 $url = $url_split[0];
341
342
343 if ( false !== strpos(home_url(), '://www.') && false === strpos($url, '://www.') )
344 $url = str_replace('://', '://www.', $url);
345
346
347 if ( false === strpos(home_url(), '://www.') )
348 $url = str_replace('://www.', '://', $url);
349
350
351 if ( !$wp_rewrite->using_index_permalinks() )
352 $url = str_replace('index.php/', '', $url);
353
354 if ( false !== strpos($url, home_url()) ) {
355
356 $url = str_replace(home_url(), '', $url);
357 } else {
358
359 $home_path = parse_url(home_url());
360 $home_path = isset( $home_path['path'] ) ? $home_path['path'] : '' ;
361 $url = str_replace($home_path, '', $url);
362 }
363
364
365 $url = trim($url, '/');
366
367 $request = $url;
368
369 $request_match = $request;
370 foreach ( (array)$rewrite as $match => $query) {
371
372
373 if ( !empty($url) && ($url != $request) && (strpos($match, $url) === 0) )
374 $request_match = $url . '/' . $request;
375
376 if ( preg_match("!^$match!", $request_match, $matches) ) {
377
378
379 $query = preg_replace("!^.+\?!", '', $query);
380
381
382 $query = addslashes(WP_MatchesMapRegex::apply($query, $matches));
383
384
385 global $wp;
386 parse_str($query, $query_vars);
387 $query = array();
388 foreach ( (array) $query_vars as $key => $value ) {
389 if ( in_array($key, $wp->public_query_vars) )
390 $query[$key] = $value;
391 }
392
393
394 foreach ( $GLOBALS['wp_post_types'] as $post_type => $t )
395 if ( $t->query_var )
396 $post_type_query_vars[$t->query_var] = $post_type;
397
398 foreach ( $wp->public_query_vars as $wpvar ) {
399 if ( isset( $wp->extra_query_vars[$wpvar] ) )
400 $query[$wpvar] = $wp->extra_query_vars[$wpvar];
401 elseif ( isset( $_POST[$wpvar] ) )
402 $query[$wpvar] = $_POST[$wpvar];
403 elseif ( isset( $_GET[$wpvar] ) )
404 $query[$wpvar] = $_GET[$wpvar];
405 elseif ( isset( $query_vars[$wpvar] ) )
406 $query[$wpvar] = $query_vars[$wpvar];
407
408 if ( !empty( $query[$wpvar] ) ) {
409 if ( ! is_array( $query[$wpvar] ) ) {
410 $query[$wpvar] = (string) $query[$wpvar];
411 } else {
412 foreach ( $query[$wpvar] as $vkey => $v ) {
413 if ( !is_object( $v ) ) {
414 $query[$wpvar][$vkey] = (string) $v;
415 }
416 }
417 }
418
419 if ( isset($post_type_query_vars[$wpvar] ) ) {
420 $query['post_type'] = $post_type_query_vars[$wpvar];
421 $query['name'] = $query[$wpvar];
422 }
423 }
424 }
425
426
427 $query = new WP_Query($query);
428 if ( !empty($query->posts) && $query->is_singular )
429 return $query->post->ID;
430 else
431 return 0;
432 }
433 }
434 return 0;
435 }
436