PluginProbe
ShiftController Employee Shift Scheduling / 4.9.95
ShiftController Employee Shift Scheduling v4.9.95
4.9.97 4.9.96 4.9.95 4.9.74 4.9.75 4.9.76 4.9.77 4.9.78 4.9.84 4.9.85 4.9.87 4.9.91 4.9.92 trunk 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 3.2.4 All 38 releases
shiftcontroller / hc3 / crud / wordpress / custompost.php

custompost.php in ShiftController Employee Shift Scheduling 4.9.95, at hc3/crud/wordpress/custompost.php

697 lines 15.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php if (! defined('ABSPATH')) exit; // Exit if accessed directly
2 class HC3_Crud_Wordpress_CustomPost implements HC3_ICrud
3 {
4 protected $wp_type = NULL;
5 protected $core_fields = array();
6 protected $withMeta = FALSE;
7
8 protected $fields_to_me = array('ID' => 'id', 'post_status' => 'status');
9 protected $fields_to_wp = array('id' => 'ID', 'status' => 'post_status');
10
11 protected $idField = 'id';
12
13 static $read_query_cache = array();
14 protected $read_use_cache = TRUE;
15
16 protected $default_sort = array();
17
18 public function __construct( $postType, $convertToMe = array(), $convertToWp = array() )
19 {
20 $this->wp_type = $postType;
21
22 if( ! post_type_exists($this->wp_type) ){
23 // echo "REGISTERING POST TYPE '" . $this->wp_type . "'<br>";
24 register_post_type(
25 $this->wp_type,
26 array(
27 // 'public' => TRUE,
28 'public' => FALSE,
29 // 'publicly_queryable' => TRUE,
30 'publicly_queryable' => false,
31 'has_archive' => FALSE,
32 'exclude_from_search' => TRUE,
33 'show_in_menu' => FALSE,
34 'show_in_nav_menus' => FALSE,
35 'show_in_rest' => TRUE,
36
37 // 'show_in_menu' => TRUE,
38 // 'show_in_nav_menus' => TRUE,
39 // 'show_in_rest' => TRUE,
40 // 'show_ui' => TRUE,
41 // 'menu_position' => 5,
42 )
43 );
44
45 add_filter( 'user_has_cap', array($this, 'wpAllowEditPost'), 10, 3 );
46 }
47
48 if( $convertToMe ){
49 foreach( $convertToMe as $k => $v ){
50 $this->fields_to_me[ $k ] = $v;
51 }
52 }
53
54 if( $convertToWp ){
55 foreach( $convertToWp as $k => $v ){
56 $this->fields_to_wp[ $k ] = $v;
57 }
58 }
59 }
60
61 public function withMeta()
62 {
63 $this->withMeta = TRUE;
64 return $this;
65 }
66
67 public function wpAllowEditPost( $allcaps, $cap, $args )
68 {
69 if ( 'edit_post' != $args[0] ){
70 return $allcaps;
71 }
72
73 if( ! isset($args[2]) ){
74 return $allcaps;
75 }
76
77 // Load the post data:
78 $post = get_post( $args[2] );
79
80 if( ! ($post && isset($post->post_type)) ){
81 return $allcaps;
82 }
83
84 if( $post->post_type != $this->wp_type ){
85 return $allcaps;
86 }
87
88 $allcaps[ $cap[0] ] = TRUE;
89 return $allcaps;
90 }
91
92 public function convert_to_wp( $values )
93 {
94 $core_values = array();
95 $meta_values = array();
96
97 foreach( $values as $k => $v ){
98 if( isset($this->fields_to_wp[$k]) ){
99 $wp_k = $this->fields_to_wp[$k];
100 $core_values[$wp_k] = $v;
101 }
102 else {
103 $meta_values[ (string) $k ] = $v;
104 }
105 }
106
107 $return = array( $core_values, $meta_values );
108 return $return;
109 }
110
111 public function set_search_in( $fields = array() ){
112 $this->search_in = $fields;
113 return $this;
114 }
115
116 // READ
117 public function read_prepare_query( $args = array() )
118 {
119 $q = array(
120 'post_type' => $this->wp_type,
121 'post_status' => array('any', 'trash', 'draft'),
122 'perm' => 'readable',
123 // 'no_found_rows' => FALSE,
124 );
125
126 $meta_query = array();
127
128 foreach( $args['WHERE'] as $w ){
129 list( $k, $compare, $v ) = $w;
130 if( 'NOTIN' == $compare ){
131 $compare = 'NOT IN';
132 }
133
134 $test = array($k => array($compare, $v));
135 list( $core_where, $meta_where ) = $this->convert_to_wp( $test );
136
137 // echo 'CORE WHERE';
138 // _print_r( $core_where );
139 // echo 'META WHERE';
140 // _print_r( $meta_where );
141
142 // don't query main table except ID, post_name, post_title as it's too difficult at the moment
143 if( $core_where ){
144 foreach( $core_where as $k => $more ){
145 list( $compare, $v ) = $more;
146 switch( $k ){
147 case 'ID':
148 switch( $compare ){
149 case '=':
150 $q['p'] = $v;
151 break;
152 case '<>':
153 $q['post__not_in'] = array($v);
154 break;
155 case 'IN':
156 $q['post__in'] = $v;
157 break;
158 case 'NOTIN':
159 case 'NOT IN':
160 if( ! is_array($v) ){
161 $v = array($v);
162 }
163 $q['post__not_in'] = $v;
164 break;
165 }
166 break;
167
168 case 'post_name':
169 switch( $compare ){
170 case '=':
171 $q['post_name__in'] = array($v);
172 break;
173 case 'IN':
174 $q['post_name__in'] = $v;
175 break;
176 }
177 break;
178
179 case 'post_title':
180 switch( $compare ){
181 case '=':
182 $q['title'] = $v;
183 break;
184 }
185 break;
186
187 case 'post_status':
188 switch( $compare ){
189 case '=':
190 case 'IN':
191 $q['post_status'] = $v;
192 break;
193 }
194 break;
195 }
196 }
197 }
198
199 if( $meta_where ){
200 foreach( $meta_where as $k => $more ){
201 list( $compare, $v ) = $more;
202 $meta_query[] = array(
203 'key' => $k,
204 'compare' => $compare,
205 'value' => $v,
206 );
207 }
208 }
209 }
210 if( $meta_query ){
211 $meta_query['relation'] = 'AND';
212 }
213 // _print_r( $q );
214 // exit;
215
216 if( $args['SORT'] ){
217 $wp_orderby = array();
218
219 $sort = array();
220 foreach( $args['SORT'] as $s ){
221 $sort[$s[0]] = $s[1];
222 }
223
224 list( $sort_core, $sort_meta ) = $this->convert_to_wp( $sort );
225
226 if( $sort_core ){
227 $wp_orderby = array_merge( $wp_orderby, $sort_core );
228 }
229
230 if( $sort_meta ){
231 $meta_orderby = array();
232 foreach( $sort_meta as $k => $v ){
233 $meta_query[ $k . '_clause' ] = array(
234 'key' => $k,
235 );
236 $meta_orderby[ $k . '_clause' ] = $v;
237 }
238 $wp_orderby = array_merge( $wp_orderby, $meta_orderby );
239 }
240
241 $q['orderby'] = $wp_orderby;
242 }
243
244 if( $args['LIMIT'] ){
245 $q['posts_per_page'] = $args['LIMIT'][0];
246 if( $args['LIMIT'][1] ){
247 $q['offset'] = $args['LIMIT'][1];
248 }
249 }
250 else {
251 $q['posts_per_page'] = -1;
252 }
253
254 if( $args['SEARCH'] && $this->search_in ){
255 $search = array();
256 reset( $this->search_in );
257 foreach( $this->search_in as $k ){
258 $search[$k] = $args['SEARCH'];
259 }
260 list( $core_search, $meta_search ) = $this->convert_to_wp( $search );
261
262 if( $core_search ){
263 $q['s'] = $args['SEARCH'];
264 }
265
266 if( $meta_search ){
267 $submeta_query = array();
268 $submeta_query['relation'] = 'OR';
269
270 foreach( $meta_search as $k2 => $v2 ){
271 $submeta_query[] = array(
272 'key' => $k2,
273 'value' => $v2,
274 'compare' => 'LIKE',
275 );
276 }
277
278 $meta_query[] = $submeta_query;
279 }
280 }
281
282 if( $meta_query ){
283 $q['meta_query'] = $meta_query;
284 }
285
286 return $q;
287 }
288
289 public function count( $args = array() )
290 {
291 $return = NULL;
292
293 if( NULL === $args ){
294 return $return;
295 }
296
297 $args = HC3_Functions::tempCrudPrepareArgs( $args, $this->idField );
298
299 if( $this->read_use_cache ){
300 $cache_key = $this->wp_type . ':count' . json_encode($args);
301 if( array_key_exists($cache_key, self::$read_query_cache) ){
302 // echo "ON CACHE: '$sql'<br>";
303 $return = self::$read_query_cache[$cache_key];
304 return $return;
305 }
306 }
307
308 $q = $this->read_prepare_query( $args );
309
310 if( $q !== NULL ){
311 $wp_query = new WP_Query( $q );
312 $return = $wp_query->found_posts;
313 }
314
315 return $return;
316 }
317
318 public function read( $args = array() )
319 {
320 $return = array();
321
322 if( NULL === $args ){
323 return $return;
324 }
325
326 $args = array_merge( $this->default_sort, $args );
327
328 $args = HC3_Functions::tempCrudPrepareArgs( $args, $this->idField );
329
330 if( $this->read_use_cache ){
331 $cache_key = $this->wp_type . ':' . json_encode($args);
332 if( isset(self::$read_query_cache[$cache_key]) ){
333 // echo "ON CACHE: '$cache_key'<br>";
334 $return = self::$read_query_cache[$cache_key];
335 return $return;
336 }
337 }
338
339 $q = $this->read_prepare_query( $args );
340
341 // $args = array(
342 // 'post_type' => 'your_post_type',
343 // 'post_status' => 'publish',
344
345 // 'meta_query' => array(
346 // 'relation' => 'AND',
347 // array(
348 // 'key' => 'longitude-key',
349 // 'value' => '',
350 // 'compare' => 'NOT'
351 // ),
352 // array(
353 // 'key' => 'latitude-key',
354 // 'value' => '',
355 // 'compare' => 'NOT'
356 // ),
357 // array(
358 // 'key' => 'name-key',
359 // 'value' => '',
360 // 'compare' => 'NOT'
361 // ),
362 // )
363 // );
364 if( $q !== NULL ){
365 // echo 'QUERY<br>';
366 // _print_r( $q );
367 // exit;
368
369 // _print_r( $q );
370 $wp_query = new WP_Query( $q );
371 $posts = $wp_query->get_posts();
372
373 // echo "POSTS";
374 // _print_r( $posts );
375 // global $wpdb;
376 // _print_r( $wpdb->queries );
377 // exit;
378 $return = array();
379 $count = count($posts);
380 for( $ii = 0; $ii < $count; $ii++ ){
381 $meta = get_metadata( 'post', $posts[$ii]->ID );
382 $values = array_map( function($n){return $n[0];}, $meta );
383 $keys = array_keys( $values );
384 foreach( $keys as $k ){
385 $metaK = 'meta_' . $k;
386 $values[ $metaK ] = $values[$k];
387 }
388 reset( $this->fields_to_me );
389 foreach( $this->fields_to_me as $wp_field => $my_field ){
390 $values[ $my_field ] = $posts[$ii]->{$wp_field};
391 }
392
393 $key_id = $values[ $this->idField ];
394 $return[ $key_id ] = $values;
395 }
396 }
397
398 if( $this->read_use_cache ){
399 self::$read_query_cache[$cache_key] = $return;
400 }
401
402 return $return;
403 }
404
405 // CREATE
406 public function sqlValues( array $values, $many = false )
407 {
408 $ret = '';
409
410 // fields
411 $fields = $many ? array_keys( current($values) ) : array_keys( $values );
412 $ret .= '(' . join(', ', $fields) . ')';
413
414 // values
415 $arrayOfValues = $many ? $values : [ $values ];
416
417 $sqlArg = array();
418 $retValue = array();
419 foreach( $arrayOfValues as $thisValues ){
420 $thisSv = [];
421 foreach( $fields as $k ){
422 $v = $thisValues[ $k ];
423 $isInt = is_numeric( $v ) && ( strlen($v) < 12 );
424 $sqlArg[] = $v;
425
426 if( $isInt ){
427 $thisSv[] = '%d';
428 // $sv[] = '%d';
429 }
430 else {
431 $thisSv[] = '%s';
432 // $sv[] = '%s';
433 }
434 }
435 $retValue[] = '(' . join(', ', $thisSv) . ')';
436 }
437
438 $ret .= ' VALUES ' . join( ', ', $retValue );
439
440 global $wpdb;
441 $ret = $wpdb->prepare( $ret, $sqlArg );
442
443 return $ret;
444 }
445
446 public function createDirect( $values )
447 {
448 $ret = $values;
449
450 list( $coreValues, $metaValues ) = $this->convert_to_wp( $values );
451
452 $now = time();
453 $postDate = date( "Y-m-d H:i:s", $now );
454 $postDateGmt = gmdate( "Y-m-d H:i:s", $now );
455 $postAuthor = get_current_user_id();
456
457 $default = array(
458 'post_content' => '',
459 'post_title' => '',
460 'post_excerpt' => '',
461 'post_password' => '',
462 'post_name' => '',
463 'to_ping' => '',
464 'pinged' => '',
465 'post_content_filtered' => '',
466 'guid' => '',
467 'post_mime_type' => '',
468
469 'post_date' => $postDate,
470 'post_date_gmt' => $postDateGmt,
471 'post_modified' => $postDate,
472 'post_modified_gmt' => $postDateGmt,
473
474 'post_author' => $postAuthor,
475 'comment_status' => 'closed',
476 );
477
478 $coreValues['post_type'] = $this->wp_type;
479 if( ! array_key_exists('post_status', $coreValues) ){
480 $coreValues['post_status'] = 'publish';
481 }
482
483 $coreValues += $default;
484
485 global $wpdb;
486
487 $tableName = $wpdb->prefix . 'posts';
488 $sqlValues = $this->sqlValues( $coreValues );
489 $sql = 'INSERT INTO ' . $tableName . ' ' . $sqlValues;
490
491 $res = $wpdb->query( $sql );
492
493 if( is_wp_error($res) ){
494 $error = '__Database Error__' . ': ' . $res->get_error_message();
495 throw new Exception( $error );
496 }
497
498 $id = $wpdb->insert_id;
499 $ret['id'] = $id;
500
501 // insert meta
502 if( ! $metaValues ){
503 return $ret;
504 }
505
506 $arrayOfMeta = array();
507 foreach( $metaValues as $k => $v ){
508 $arrayOfMeta[] = array(
509 'post_id' => $id,
510 'meta_key' => $k,
511 'meta_value' => $v
512 );
513 }
514
515 $tableName = $wpdb->prefix . 'postmeta';
516 $sqlValues = $this->sqlValues( $arrayOfMeta, true );
517 $sql = 'INSERT INTO ' . $tableName . ' ' . $sqlValues;
518
519 $res = $wpdb->query( $sql );
520
521 if( is_wp_error($res) ){
522 $error = '__Database Error__' . ': ' . $res->get_error_message();
523 throw new Exception( $error );
524 }
525
526 return $ret;
527 }
528
529 /*
530 wp_insert_post then directly meta
531 */
532 public function createSemiDirect( $values )
533 {
534 $ret = $values;
535
536 list( $coreValues, $metaValues ) = $this->convert_to_wp( $values );
537
538 $coreValues['post_type'] = $this->wp_type;
539 if( ! array_key_exists('post_status', $coreValues) ){
540 $coreValues['post_status'] = 'publish';
541 }
542
543 $res = wp_insert_post( $coreValues, true );
544
545 if( is_wp_error($res) ){
546 $error = '__Database Error__' . ': ' . $res->get_error_message();
547 throw new Exception( $error );
548 }
549
550 $id = $res;
551
552 $ret['id'] = $id;
553
554 // insert meta
555 if( ! $metaValues ){
556 return $ret;
557 }
558
559 $arrayOfMeta = array();
560 foreach( $metaValues as $k => $v ){
561 $arrayOfMeta[] = array(
562 'post_id' => $id,
563 'meta_key' => $k,
564 'meta_value' => $v
565 );
566 }
567
568 global $wpdb;
569
570 $tableName = $wpdb->prefix . 'postmeta';
571 $sqlValues = $this->sqlValues( $arrayOfMeta, true );
572 $sql = 'INSERT INTO ' . $tableName . ' ' . $sqlValues;
573
574 $res = $wpdb->query( $sql );
575
576 if( is_wp_error($res) ){
577 $error = '__Database Error__' . ': ' . $res->get_error_message();
578 throw new Exception( $error );
579 }
580
581 return $ret;
582 }
583
584 public function create( $values )
585 {
586 $ret = $this->createSemiDirect( $values );
587 return $ret;
588
589 $return = $values;
590
591 list( $core_values, $meta_values ) = $this->convert_to_wp( $values );
592
593 $postarr = $core_values;
594 $postarr['post_type'] = $this->wp_type;
595
596 if( ! array_key_exists('post_status', $postarr) ){
597 $postarr['post_status'] = 'publish';
598 }
599
600 if( $meta_values ){
601 $postarr['meta_input'] = $meta_values;
602 }
603
604 $id = wp_insert_post( $postarr, TRUE );
605
606 if( is_wp_error($id) ){
607 $error = '__Database Error__' . ': ' . $id->get_error_message();
608 throw new Exception( $error );
609 }
610
611 $return['id'] = $id;
612 return $return;
613 }
614
615 // UPDATE
616 public function update( $id, $values )
617 {
618 /* disable Aruba high speed cache plugin */
619 if( function_exists('ahsc_set_transient') ){
620 ahsc_set_transient( 'ahsc_is_purged', time(), MINUTE_IN_SECONDS );
621 }
622
623 $return = TRUE;
624
625 if( ! $id ){
626 return;
627 }
628
629 $values[$this->idField] = $id;
630 $return = $values;
631
632 unset( $values['id'] );
633 list( $core_values, $meta_values ) = $this->convert_to_wp( $values );
634
635 if( $core_values ){
636 $core_values['ID'] = $id;
637 wp_update_post( $core_values );
638 }
639
640 if( $meta_values ){
641 foreach( $meta_values as $k => $v ){
642 update_post_meta( $id, $k, $v );
643 }
644 }
645
646 return $return;
647 }
648
649 public function updateMeta( $id, $values )
650 {
651 $return = TRUE;
652
653 if( ! $id ){
654 return;
655 }
656
657 if( $values ){
658 foreach( $values as $k => $v ){
659 $k = (string) $k;
660 update_post_meta( $id, $k, $v );
661 }
662 }
663
664 return $return;
665 }
666
667
668 // DELETE
669 public function delete( $id )
670 {
671 $return = FALSE;
672
673 if( ! $id ){
674 return $return;
675 }
676
677 $return = wp_delete_post( $id, TRUE );
678 return $return;
679 }
680
681 public function deleteAll()
682 {
683 global $wpdb;
684
685 $sql = '
686 DELETE `posts`, `pm`
687 FROM `' . $wpdb->prefix . 'posts` AS `posts`
688 LEFT JOIN `' . $wpdb->prefix . 'postmeta` AS `pm` ON `pm`.`post_id` = `posts`.`ID`
689 WHERE `posts`.`post_type` = \'' . $this->wp_type . '\'';
690
691 $result = $wpdb->query($sql);
692
693 $return = TRUE;
694 return $return;
695 }
696 }
697