PluginProbe
WPSSO Core – Complete Schema Markup and Meta Tags / 22.7.0
WPSSO Core – Complete Schema Markup and Meta Tags v22.7.0
22.7.0 22.6.1 22.6.0 22.5.3 22.5.2 22.5.1 22.4.0 22.3.0 22.2.1 22.2.0 22.1.3 22.1.2 22.1.1 22.1.0 22.0.0 21.13.3 21.13.2 trunk 21.13.1
wpsso / lib / com / util-wp.php

util-wp.php in WPSSO Core – Complete Schema Markup and Meta Tags 22.7.0, at lib/com/util-wp.php

2,965 lines 71.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * License: GPLv3
4 * License URI: https://www.gnu.org/licenses/gpl.txt
5 * Copyright 2012-2026 Jean-Sebastien Morisset (https://surniaulula.com/)
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9
10 die( 'These aren\'t the droids you\'re looking for.' );
11 }
12
13 if ( ! class_exists( 'SucomUtil' ) ) {
14
15 require_once dirname( __FILE__ ) . '/util.php';
16 }
17
18 If ( ! class_exists( 'SucomUtilWP' ) ) {
19
20 class SucomUtilWP extends SucomUtil {
21
22 protected static $locale_cache = array(); // Used by clear_locale_cache() and get_locale().
23
24 public function __construct() {}
25
26 /*
27 * DOING CHECK METHODS:
28 *
29 * doing_ajax()
30 * doing_autosave()
31 * doing_block_editor()
32 * doing_cron()
33 * doing_frontend()
34 * doing_iframe()
35 * doing_rest()
36 * doing_xmlrpc()
37 */
38 public static function doing_ajax() {
39
40 if ( function_exists( 'wp_doing_ajax' ) ) {
41
42 return wp_doing_ajax();
43 }
44
45 return defined( 'DOING_AJAX' ) ? DOING_AJAX : false;
46 }
47
48 public static function doing_autosave() {
49
50 return defined( 'DOING_AUTOSAVE' ) ? DOING_AUTOSAVE : false;
51 }
52
53 public static function doing_block_editor() {
54
55 static $local_cache = null;
56
57 if ( null !== $local_cache ) {
58
59 return $local_cache;
60 }
61
62 $post_id = false;
63 $can_edit_id = false;
64 $can_edit_type = false;
65 $req_action = empty( $_REQUEST[ 'action' ] ) ? false : sanitize_text_field( $_REQUEST[ 'action' ] );
66 $is_meta_box = empty( $_REQUEST[ 'meta-box-loader' ] ) && empty( $_REQUEST[ 'meta_box' ] ) ? false : true;
67 $is_gutenbox = empty( $_REQUEST[ 'gutenberg_meta_boxes' ] ) ? false : true;
68 $is_classic = isset( $_REQUEST[ 'classic-editor' ] ) && empty( $_REQUEST[ 'classic-editor' ] ) ? false : true;
69
70 if ( ! empty( $_REQUEST[ 'post_ID' ] ) && is_numeric( $_REQUEST[ 'post_ID' ] ) ) {
71
72 $post_id = SucomUtil::sanitize_int( $_REQUEST[ 'post_ID' ] ); // Returns integer or null.
73
74 } elseif ( ! empty( $_REQUEST[ 'post' ] ) && is_numeric( $_REQUEST[ 'post' ] ) ) {
75
76 $post_id = SucomUtil::sanitize_int( $_REQUEST[ 'post' ] ); // Returns integer or null.
77 }
78
79 if ( $post_id ) {
80
81 if ( function_exists( 'use_block_editor_for_post' ) ) {
82
83 /*
84 * Calling use_block_editor_for_post() in WordPress v5.0 during post save crashes the web
85 * browser. See https://core.trac.wordpress.org/ticket/45253 for details. Only call
86 * use_block_editor_for_post() if using WordPress v5.2 or newer.
87 */
88 global $wp_version;
89
90 if ( version_compare( $wp_version, '5.2', '<' ) ) {
91
92 $can_edit_id = true;
93
94 } elseif ( use_block_editor_for_post( $post_id ) ) {
95
96 $can_edit_id = true;
97 }
98
99 } elseif ( function_exists( 'gutenberg_can_edit_post' ) ) {
100
101 if ( gutenberg_can_edit_post( $post_id ) ) {
102
103 $can_edit_id = true;
104 }
105 }
106
107 /*
108 * If we can edit the post ID, then check if we can edit the post type.
109 */
110 if ( $can_edit_id ) {
111
112 $post_type_name = get_post_type( $post_id );
113
114 if ( $post_type_name ) {
115
116 if ( function_exists( 'use_block_editor_for_post_type' ) ) {
117
118 if ( use_block_editor_for_post_type( $post_type_name ) ) {
119
120 $can_edit_type = true;
121 }
122
123 } elseif ( function_exists( 'gutenberg_can_edit_post_type' ) ) {
124
125 if ( gutenberg_can_edit_post_type( $post_type_name ) ) {
126
127 $can_edit_type = true;
128 }
129 }
130 }
131 }
132
133 } else return $local_cache = false; // No post ID = No block editor.
134
135 if ( $can_edit_id && $can_edit_type ) {
136
137 if ( $is_gutenbox ) {
138
139 $local_cache = true;
140
141 } elseif ( $is_meta_box ) {
142
143 $local_cache = true;
144
145 } elseif ( ! $is_classic ) {
146
147 $local_cache = true;
148
149 } elseif ( $post_id && 'edit' === $req_action ) {
150
151 $local_cache = true;
152 }
153 }
154
155 return $local_cache;
156 }
157
158 public static function doing_cron() {
159
160 if ( function_exists( 'wp_doing_cron' ) ) {
161
162 return wp_doing_cron();
163 }
164
165 return defined( 'DOING_CRON' ) ? DOING_CRON : false;
166 }
167
168 public static function doing_dev() {
169
170 static $local_cache = null;
171
172 if ( null !== $local_cache ) {
173
174 return $local_cache;
175 }
176
177 if ( function_exists( 'wp_get_environment_type' ) ) { // Since WP v5.5.
178
179 /*
180 * Returns 'local', 'development', 'staging', or 'production'.
181 */
182 if ( 'development' === wp_get_environment_type() ) {
183
184 return $local_cache = true;
185 }
186 }
187
188 return $local_cache = false;
189 }
190
191 public static function doing_frontend() {
192
193 if ( is_admin() ) {
194
195 return false;
196
197 } elseif ( self::doing_cron() ) {
198
199 return false;
200
201 } elseif ( self::doing_ajax() ) {
202
203 return true; // An ajax call can be from the front or back-end.
204
205 } elseif ( self::doing_rest() ) {
206
207 return false;
208
209 } else return true;
210 }
211
212 public static function doing_iframe() {
213
214 return defined( 'IFRAME_REQUEST' ) ? true : false;
215 }
216
217 public static function doing_rest() {
218
219 if ( empty( $_SERVER[ 'REQUEST_URI' ] ) ) {
220
221 return false;
222 }
223
224 $rest_prefix = trailingslashit( rest_get_url_prefix() );
225
226 return strpos( $_SERVER[ 'REQUEST_URI' ], $rest_prefix ) !== false ? true : false;
227 }
228
229 public static function doing_xmlrpc() {
230
231 return defined( 'XMLRPC_REQUEST' ) ? true : false;
232 }
233
234 /*
235 * IS CHECK METHODS:
236 *
237 * is_amp()
238 * is_home_page()
239 * is_home_posts()
240 * is_mod_screen_obj()
241 * is_mod_post_type()
242 * is_post_page()
243 * is_post_type()
244 * is_post_type_archive()
245 * is_post_type_public()
246 * is_term_page()
247 * is_term_tax_slug()
248 * is_toplevel_edit()
249 * is_user_page()
250 */
251 public static function is_amp() {
252
253 static $local_cache = null;
254
255 if ( null !== $local_cache ) {
256
257 return $local_cache;
258 }
259
260 if ( is_admin() ) {
261
262 return $local_cache = false;
263
264 /*
265 * The amp_is_request() function cannot be called before the 'wp' action has run, so if the 'wp'
266 * action has not run, leave the $local_cache as null to allow for future checks.
267 */
268 } elseif ( function_exists( 'amp_is_request' ) ) {
269
270 if ( did_action( 'wp' ) ) {
271
272 return $local_cache = amp_is_request();
273
274 } else return $local_cache; // Return null.
275
276 } elseif ( function_exists( 'is_amp_endpoint' ) ) {
277
278 return $local_cache = is_amp_endpoint();
279
280 } elseif ( function_exists( 'ampforwp_is_amp_endpoint' ) ) {
281
282 return $local_cache = ampforwp_is_amp_endpoint();
283
284 } elseif ( defined( 'AMP_QUERY_VAR' ) ) {
285
286 return $local_cache = get_query_var( AMP_QUERY_VAR, false ) ? true : false;
287 }
288
289 return $local_cache = false;
290 }
291
292 public static function is_home_page( $use_post = false ) {
293
294 $is_home_page = false;
295
296 $post_id = 'page' === get_option( 'show_on_front' ) ? (int) get_option( 'page_on_front' ) : 0;
297
298 if ( $post_id > 0 ) { // The 'page_on_front' option post ID.
299
300 if ( is_numeric( $use_post ) && (int) $use_post === $post_id ) {
301
302 $is_home_page = true;
303
304 } elseif ( $post_id === self::get_post_object( $use_post, $output = 'id' ) ) {
305
306 $is_home_page = true;
307 }
308 }
309
310 return apply_filters( 'sucom_is_home_page', $is_home_page, $use_post );
311 }
312
313 public static function is_home_posts( $use_post = false ) {
314
315 $is_home_posts = false;
316
317 $post_id = 'page' === get_option( 'show_on_front' ) ? (int) get_option( 'page_for_posts' ) : 0;
318
319 if ( $post_id > 0 ) { // The 'page_for_posts' option post ID.
320
321 if ( is_numeric( $use_post ) && (int) $post_id === $use_post ) {
322
323 $is_home_posts = true;
324
325 } elseif ( $post_id === self::get_post_object( $use_post, $output = 'id' ) ) {
326
327 $is_home_posts = true;
328 }
329
330 } elseif ( false === $use_post && is_home() && is_front_page() ) {
331
332 $is_home_posts = true;
333 }
334
335 return apply_filters( 'sucom_is_home_posts', $is_home_posts, $use_post );
336 }
337
338 public static function is_mod_screen_obj( array $mod ) {
339
340 if ( ! is_admin() ) { // Front-end does not have a screen.
341
342 return false;
343 }
344
345 if ( empty( $mod[ 'id' ] ) || ! is_numeric( $mod[ 'id' ] ) ) {
346
347 return false;
348 }
349
350 $screen_base = self::get_screen_base();
351
352 if ( empty( $mod[ 'name' ] ) || $mod[ 'name' ] !== $screen_base ) {
353
354 return false;
355 }
356
357 $obj_id = null;
358
359 switch ( $screen_base ) {
360
361 case 'post':
362
363 $obj_id = self::get_request_value( 'post_ID', 'POST' );
364
365 if ( '' === $obj_id ) {
366
367 $obj_id = self::get_request_value( 'post', 'GET' );
368 }
369
370 break;
371
372 case 'term':
373
374 $obj_id = self::get_request_value( 'tag_ID' );
375
376 break;
377
378 case 'user':
379
380 $obj_id = self::get_request_value( 'user_id' );
381
382 break;
383
384 default:
385
386 return false;
387
388 break;
389 }
390
391 if ( ! $obj_id || ! is_numeric( $obj_id ) ) {
392
393 return false;
394 }
395
396 if ( (int) $obj_id === $mod[ 'id' ] ) {
397
398 return true;
399 }
400
401 return false;
402 }
403
404 /*
405 * See WpssoIntegEcomWooCommerce->filter_attached_image_ids().
406 * See WpssoIntegEcomWooCommerce->filter_get_md_defaults().
407 * See WpssoIntegEcomWooCommerce->filter_og_seed().
408 * See WpssoIntegEcomWooCommerce->filter_tag_names_seed().
409 * See WpssoIntegEcomWooCommerce->filter_import_product_attributes().
410 * See WpssoIntegEcomWooCommerce->add_mt_product().
411 */
412 public static function is_mod_post_type( array $mod, $post_type ) {
413
414 if ( $mod[ 'is_post' ] && $mod[ 'id' ] && $mod[ 'post_type' ] === $post_type ) {
415
416 return true;
417 }
418
419 return false;
420 }
421
422 public static function is_post_page( $use_post = false ) {
423
424 $is_post_page = false;
425
426 if ( is_numeric( $use_post ) && $use_post > 0 ) {
427
428 $is_post_page = self::post_exists( $use_post );
429
430 } elseif ( true === $use_post && ! empty( $GLOBALS[ 'post' ]->ID ) ) {
431
432 $is_post_page = true;
433
434 } elseif ( false === $use_post && is_singular() ) {
435
436 $is_post_page = true;
437
438 } elseif ( false === $use_post && is_post_type_archive() ) {
439
440 $is_post_page = true;
441
442 } elseif ( ! is_home() && is_front_page() && 'page' === get_option( 'show_on_front' ) ) { // Static front page.
443
444 $is_post_page = true;
445
446 } elseif ( is_home() && ! is_front_page() && 'page' === get_option( 'show_on_front' ) ) { // Static posts page.
447
448 $is_post_page = true;
449
450 } elseif ( is_admin() ) {
451
452 $screen_base = self::get_screen_base();
453
454 if ( $screen_base === 'post' ) {
455
456 $is_post_page = true;
457
458 } elseif ( false === $screen_base && // Called too early for screen.
459 ( '' !== self::get_request_value( 'post_ID', 'POST' ) || // Uses sanitize_text_field().
460 '' !== self::get_request_value( 'post', 'GET' ) ) ) {
461
462 $is_post_page = true;
463
464 } elseif ( 'post-new' === basename( $_SERVER[ 'PHP_SELF' ], '.php' ) ) {
465
466 $is_post_page = true;
467 }
468 }
469
470 return apply_filters( 'sucom_is_post_page', $is_post_page, $use_post );
471 }
472
473 public static function is_post_type( $post_obj, $post_type ) {
474
475 if ( ! empty( $post_obj->post_type ) && $post_obj->post_type === $post_type ) {
476
477 return true;
478 }
479
480 return false;
481 }
482
483 public static function is_post_type_archive( $post_type_obj, $post_slug ) {
484
485 $is_post_type_archive = false;
486
487 if ( $post_type_obj && $post_slug && is_string( $post_slug ) ) { // Just in case.
488
489 if ( is_string( $post_type_obj ) ) {
490
491 $post_type_obj = get_post_type_object( $post_type_obj );
492 }
493
494 if ( ! is_object( $post_type_obj ) ) { // Just in case.
495
496 return $is_post_type_archive;
497 }
498
499 if ( ! empty( $post_type_obj->has_archive ) ) {
500
501 $archive_slug = $post_type_obj->has_archive;
502
503 if ( true === $archive_slug ) {
504
505 $archive_slug = $post_type_obj->rewrite[ 'slug' ];
506 }
507
508 if ( $post_slug === $archive_slug ) {
509
510 $is_post_type_archive = true;
511 }
512 }
513 }
514
515 return $is_post_type_archive;
516 }
517
518 /*
519 * $mixed = WP_Post | post ID | post type name.
520 */
521 public static function is_post_type_public( $mixed ) {
522
523 $post_type_name = null;
524
525 if ( is_object( $mixed ) || is_numeric( $mixed ) ) {
526
527 $post_type_name = get_post_type( $mixed );
528
529 } else $post_type_name = $mixed; // Post type name.
530
531 if ( $post_type_name ) {
532
533 $args = array( 'name' => $post_type_name, 'public' => 1 );
534
535 $post_types = get_post_types( $args, $output = 'names', $operator = 'and' );
536
537 if ( isset( $post_types[ 0 ] ) && $post_types[ 0 ] === $post_type_name ) {
538
539 return true;
540 }
541 }
542
543 return false;
544 }
545
546 public static function is_term_page( $term_id = 0, $tax_slug = '' ) {
547
548 $is_term_page = false;
549
550 if ( is_numeric( $term_id ) && $term_id > 0 ) {
551
552 /*
553 * Note that term_exists() requires an integer ID, not a string ID.
554 */
555 $is_term_page = term_exists( (int) $term_id, $tax_slug );
556
557 } elseif ( is_tax() || is_category() || is_tag() ) {
558
559 $is_term_page = true;
560
561 } elseif ( is_admin() ) {
562
563 $screen_base = self::get_screen_base();
564
565 if ( 'term' === $screen_base ) {
566
567 $is_term_page = true;
568
569 } elseif ( ( false === $screen_base || $screen_base === 'edit-tags' ) &&
570 ( '' !== self::get_request_value( 'taxonomy' ) &&
571 '' !== self::get_request_value( 'tag_ID' ) ) ) {
572
573 $is_term_page = true;
574 }
575 }
576
577 return apply_filters( 'sucom_is_term_page', $is_term_page );
578 }
579
580 /*
581 * See WpssoIntegEcomWooCommerce->filter_term_image_ids().
582 */
583 public static function is_term_tax_slug( $term_id, $tax_slug ) {
584
585 static $local_cache = array();
586
587 if ( isset( $local_cache[ $term_id ][ $tax_slug ] ) ) { // Boolean value.
588
589 return $local_cache[ $term_id ][ $tax_slug ];
590
591 } elseif ( ! isset( $local_cache[ $term_id ] ) ) $local_cache[ $term_id ] = array();
592
593 $term_obj = get_term_by( 'id', $term_id, $tax_slug, OBJECT, 'raw' );
594
595 if ( ! empty( $term_obj->term_id ) && ! empty( $term_obj->taxonomy ) && $term_obj->taxonomy === $tax_slug ) {
596
597 return $local_cache[ $term_id ][ $tax_slug ] = true;
598 }
599
600 return $local_cache[ $term_id ][ $tax_slug ] = false;
601 }
602
603 /*
604 * See WpssoScript->admin_enqueue_scripts().
605 * See WpssoStyle->admin_enqueue_styles().
606 */
607 public static function is_toplevel_edit( $hook_name ) {
608
609 if ( false !== strpos( $hook_name, 'toplevel_page_' ) ) {
610
611 if ( 'edit' === self::get_request_value( 'action', 'GET' ) && (int) self::get_request_value( 'post', 'GET' ) > 0 ) {
612
613 return true;
614 }
615
616 if ( 'create_new' === self::get_request_value( 'action', 'GET' ) && 'edit' === self::get_request_value( 'return', 'GET' ) ) {
617
618 return true;
619 }
620 }
621
622 return false;
623 }
624
625 public static function is_user_page( $user_id = 0 ) {
626
627 $is_user_page = false;
628
629 if ( is_numeric( $user_id ) && $user_id > 0 ) {
630
631 $is_user_page = self::user_exists( $user_id );
632
633 } elseif ( is_author() ) {
634
635 $is_user_page = true;
636
637 } elseif ( is_admin() ) {
638
639 $screen_base = self::get_screen_base();
640
641 if ( false !== $screen_base ) {
642
643 switch ( $screen_base ) {
644
645 case 'profile': // User profile page.
646 case 'user-edit': // User editing page.
647 case ( 0 === strpos( $screen_base, 'profile_page_' ) ? true : false ): // Your profile page.
648 case ( 0 === strpos( $screen_base, 'users_page_' ) ? true : false ): // Users settings page.
649
650 $is_user_page = true;
651
652 break;
653 }
654
655 } elseif ( '' !== self::get_request_value( 'user_id' ) || // Called too early for screen.
656 'profile' === basename( $_SERVER[ 'PHP_SELF' ], '.php' ) ) {
657
658 $is_user_page = true;
659 }
660 }
661
662 return apply_filters( 'sucom_is_user_page', $is_user_page );
663 }
664
665 /*
666 * DISABLED CHECK METHODS:
667 *
668 * sitemaps_disabled()
669 */
670 public static function sitemaps_disabled() {
671
672 return self::sitemaps_enabled() ? false : true;
673 }
674
675 /*
676 * ENABLED CHECK METHODS:
677 *
678 * oembed_enabled()
679 * sitemaps_enabled()
680 */
681 public static function oembed_enabled() {
682
683 if ( function_exists( 'get_oembed_response_data' ) ) {
684
685 return true;
686 }
687
688 return false;
689 }
690
691 public static function sitemaps_enabled() {
692
693 static $locale_cache = null;
694
695 if ( null !== $locale_cache ) {
696
697 return $locale_cache;
698 }
699
700 global $wp_sitemaps;
701
702 if ( is_callable( array( $wp_sitemaps, 'sitemaps_enabled' ) ) ) { // Since WP v5.5.
703
704 return $locale_cache = (bool) $wp_sitemaps->sitemaps_enabled();
705 }
706
707 return $locale_cache = false;
708 }
709
710 /*
711 * EXISTS CHECK METHODS:
712 *
713 * comment_exists()
714 * post_exists()
715 * role_exists()
716 * term_exists()
717 * user_exists()
718 */
719 public static function comment_exists( $comment_id ) {
720
721 return self::table_row_id_exists( 'comments', $comment_id ); // Uses a local cache.
722 }
723
724 /*
725 * See WpssoIntegEcomWooCommerce->check_woocommerce_pages().
726 */
727 public static function post_exists( $post_id ) {
728
729 return self::table_row_id_exists( 'posts', $post_id ); // Uses a local cache.
730 }
731
732 public static function role_exists( $role ) {
733
734 $exists = false;
735
736 if ( ! empty( $role ) ) { // Just in case.
737
738 if ( function_exists( 'wp_roles' ) ) {
739
740 $exists = wp_roles()->is_role( $role );
741
742 } else $exists = $GLOBALS[ 'wp_roles' ]->is_role( $role );
743 }
744
745 return $exists;
746 }
747
748 public static function term_exists( $term_id ) {
749
750 return self::table_row_id_exists( 'terms', $term_id ); // Uses a local cache.
751 }
752
753 public static function user_exists( $user_id ) {
754
755 return self::table_row_id_exists( 'users', $user_id ); // Uses a local cache.
756 }
757
758 public static function table_index_exists( $table, $index ) {
759
760 global $wpdb;
761
762 $sql = 'SELECT 1 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s AND INDEX_NAME = %s';
763
764 return $wpdb->get_var( $wpdb->prepare( $sql, DB_NAME, $wpdb->$table, $index ) ) ? true : false;
765 }
766
767 private static function table_row_id_exists( $table, $row_id ) {
768
769 if ( $table && is_numeric( $row_id ) && $row_id > 0 ) {
770
771 static $local_cache = array();
772
773 $row_id = (int) $row_id; // Cast as integer for the cache index.
774
775 if ( isset( $local_cache[ $table ][ $row_id ] ) ) {
776
777 return $local_cache[ $table ][ $row_id ];
778
779 } elseif ( ! isset( $local_cache[ $table ] ) ) {
780
781 $local_cache[ $table ] = array();
782 }
783
784 global $wpdb;
785
786 $sql = 'SELECT COUNT(ID) FROM ' . $wpdb->$table . ' WHERE ID = %d';
787
788 return $local_cache[ $table ][ $row_id ] = $wpdb->get_var( $wpdb->prepare( $sql, $row_id ) ) ? true : false;
789 }
790
791 return false;
792 }
793
794 /*
795 * GET COMMENT METHODS:
796 *
797 * get_comment_object()
798 */
799 public static function get_comment_object( $comment_id = 0, $output = 'object' ) {
800
801 $comment_obj = null;
802
803 if ( $comment_id instanceof WP_Comment ) {
804
805 $comment_obj = $comment_id;
806
807 } elseif ( is_numeric( $comment_id ) && $comment_id > 0 ) {
808
809 $comment_obj = get_comment( (int) $comment_id, OBJECT );
810
811 } elseif ( is_admin() ) {
812
813 if ( 'editcomment' === self::get_request_value( 'action' ) &&
814 '' !== ( $comment_id = self::get_request_value( 'c' ) ) ) {
815
816 $comment_obj = get_comment( (int) $comment_id, OBJECT );
817 }
818 }
819
820 $comment_obj = apply_filters( 'sucom_get_comment_object', $comment_obj, $comment_id );
821
822 if ( $comment_obj instanceof WP_Comment ) { // Just in case.
823
824 switch ( $output ) {
825
826 case 'id':
827 case 'ID':
828 case 'comment_id':
829
830 return isset( $comment_obj->comment_ID ) ? (int) $comment_obj->comment_ID : 0; // Cast as integer.
831
832 default:
833
834 return $comment_obj;
835 }
836 }
837
838 return false;
839 }
840
841 /*
842 * GET POST METHODS:
843 *
844 * get_post_object()
845 * get_post_type_archive_labels()
846 * get_post_type_archives()
847 * get_post_type_labels()
848 * get_post_types()
849 * get_posts()
850 * maybe_load_post()
851 */
852 public static function get_post_object( $use_post = false, $output = 'object' ) {
853
854 $post_obj = null;
855
856 if ( $use_post instanceof WP_Post ) {
857
858 $post_obj = $use_post;
859
860 } elseif ( is_numeric( $use_post ) && $use_post > 0 ) {
861
862 $post_obj = get_post( $use_post, OBJECT, $filter = 'raw' );
863
864 } elseif ( true === $use_post && ! empty( $GLOBALS[ 'post' ]->ID ) ) {
865
866 $post_obj = $GLOBALS[ 'post' ];
867
868 } elseif ( false === $use_post && apply_filters( 'sucom_is_post_page', ( is_singular() ? true : false ), $use_post ) ) {
869
870 $post_obj = get_queried_object();
871
872 } elseif ( ! is_home() && is_front_page() && 'page' === get_option( 'show_on_front' ) ) { // Static front page.
873
874 $post_obj = get_post( get_option( 'page_on_front' ), OBJECT, $filter = 'raw' );
875
876 } elseif ( is_home() && ! is_front_page() && 'page' === get_option( 'show_on_front' ) ) { // Static posts page.
877
878 $post_obj = get_post( get_option( 'page_for_posts' ), OBJECT, $filter = 'raw' );
879
880 } elseif ( is_admin() ) {
881
882 if ( '' !== ( $post_id = self::get_request_value( 'post_ID', 'POST' ) ) ||
883 '' !== ( $post_id = self::get_request_value( 'post', 'GET' ) ) ) {
884
885 $post_obj = get_post( $post_id, OBJECT, $filter = 'raw' );
886 }
887 }
888
889 $post_obj = apply_filters( 'sucom_get_post_object', $post_obj, $use_post );
890
891 if ( $post_obj instanceof WP_Post ) { // Just in case.
892
893 switch ( $output ) {
894
895 case 'id':
896 case 'ID':
897 case 'post_id':
898
899 return isset( $post_obj->ID ) ? (int) $post_obj->ID : 0; // Cast as integer.
900
901 default:
902
903 return $post_obj;
904 }
905 }
906
907 return false;
908 }
909
910 public static function get_post_type_archive_labels( $val_prefix = '', $label_prefix = '' ) {
911
912 $objects = self::get_post_type_archives( $output = 'objects' );
913
914 return self::get_post_type_labels( $val_prefix, $label_prefix, $objects );
915 }
916
917 /*
918 * Note that 'has_archive' = 1 will not match post types that are registered with a string in 'has_archive'. Use
919 * 'has_archive' = true to include the WooCommerce product archive page (ie. 'has_archive' = 'shop').
920 */
921 public static function get_post_type_archives( $output = 'objects', $sort = false, $args = null ) {
922
923 if ( ! is_array( $args ) ) {
924
925 $args = array();
926 }
927
928 if ( empty( $args[ 'has_archive' ] ) || 1 === $args[ 'has_archive' ] ) {
929
930 $args[ 'has_archive' ] = true;
931 }
932
933 return self::get_post_types( $output, $sort, $args );
934 }
935
936 public static function get_post_type_labels( $val_prefix = '', $label_prefix = '', $objects = null ) {
937
938 $values = array();
939
940 if ( ! is_string( $val_prefix ) ) { // Just in case.
941
942 return $values;
943 }
944
945 if ( null === $objects ) {
946
947 $objects = self::get_post_types( $output = 'objects', $sort = true );
948 }
949
950 if ( is_array( $objects ) ) { // Just in case.
951
952 foreach ( $objects as $obj ) {
953
954 if ( is_object( $obj ) ) { // Just in case.
955
956 $obj_label = self::get_object_label( $obj );
957
958 $values[ $val_prefix . $obj->name ] = trim( $label_prefix . ' ' . $obj_label );
959
960 } else SucomUtil::safe_error_log( __METHOD__ . ' error: post type object not an object: ' . print_r( $obj, true ) );
961 }
962 }
963
964 return $values;
965 }
966
967 /*
968 * Returns post types registered as 'public' = true and 'show_ui' = true by default.
969 *
970 * Note that the 'wp_block' custom post type for reusable blocks is registered as 'public' = false and 'show_ui' = true.
971 *
972 * $output = objects | names
973 */
974 public static function get_post_types( $output = 'objects', $sort = false, $args = null ) {
975
976 $def_args = array( 'public' => true, 'show_ui' => true );
977
978 if ( null === $args ) {
979
980 $args = $def_args;
981
982 } elseif ( is_array( $args ) ) {
983
984 $args = array_merge( $def_args, $args );
985
986 } else return array();
987
988 $operator = 'and';
989
990 $post_types = get_post_types( $args, $output, $operator );
991
992 if ( $sort ) {
993
994 if ( 'objects' === $output ) {
995
996 self::sort_objects_by_label( $post_types );
997
998 } else asort( $post_types );
999 }
1000
1001 return apply_filters( 'sucom_get_post_types', $post_types, $output, $args );
1002 }
1003
1004 /*
1005 * Alternative to the WordPress get_posts() function which sets 'ignore_sticky_posts' and 'no_found_rows' to true.
1006 *
1007 * Calls WP_Query->query() with the supplied arguments.
1008 *
1009 * See wordpress/wp-includes/post.php.
1010 * See WpssoPost->get_posts_ids().
1011 * See WpssoPost->get_public_ids().
1012 * See WpssoTerm->get_posts_ids().
1013 * See WpssoUser->get_posts_ids().
1014 */
1015 public static function get_posts( $args ) {
1016
1017 /*
1018 * Query argument sanitation.
1019 *
1020 * See wordpress/wp-includes/post.php.
1021 */
1022 if ( ! empty( $args[ 'post_type' ] ) ) {
1023
1024 if ( empty( $args[ 'post_status' ] ) ) {
1025
1026 $args[ 'post_status' ] = 'attachment' === $args[ 'post_type' ] ? 'inherit' : 'publish';
1027 }
1028 }
1029
1030 if ( ! empty( $args[ 'numberposts' ] ) && empty( $args[ 'posts_per_page' ] ) ) {
1031
1032 $args[ 'posts_per_page' ] = $args[ 'numberposts' ];
1033
1034 unset( $args[ 'numberposts' ] );
1035 }
1036
1037 if ( ! empty( $args[ 'category' ] ) ) {
1038
1039 $args[ 'cat' ] = $args[ 'category' ];
1040
1041 unset( $args[ 'category' ] );
1042 }
1043
1044 if ( ! empty( $args[ 'include' ] ) ) {
1045
1046 $args[ 'post__in' ] = wp_parse_id_list( $args[ 'include' ] );
1047
1048 $args[ 'posts_per_page' ] = count( $args[ 'post__in' ] ); // Only the number of posts included.
1049
1050 unset( $args[ 'include' ] );
1051 }
1052
1053 if ( ! empty( $args[ 'exclude' ] ) ) {
1054
1055 $args[ 'post__not_in' ] = wp_parse_id_list( $args[ 'exclude' ] );
1056
1057 unset( $args[ 'exclude' ] );
1058 }
1059
1060 /*
1061 * If the query arguments do not limit the number of posts returned with 'paged' and 'posts_per_page', then
1062 * use a while loop to save memory and fetch a default of 1000 posts at a time.
1063 */
1064 $wp_query = new WP_Query;
1065 $has_nopaging = isset( $args[ 'nopaging' ] ) && $args[ 'nopaging' ] ? true : false;
1066 $has_paged = isset( $args[ 'paged' ] ) && false !== $args[ 'paged' ] ? true : false;
1067 $has_ppp = isset( $args[ 'posts_per_page' ] ) && -1 !== $args[ 'posts_per_page' ] ? true : false;
1068
1069 if ( defined( 'SUCOM_GET_POSTS_DEBUG_LOG' ) && SUCOM_GET_POSTS_DEBUG_LOG ) {
1070
1071 error_log( print_r( $args, true ) );
1072 }
1073
1074 if ( ! $has_nopaging && ! $has_paged && ! $has_ppp ) {
1075
1076 $args[ 'paged' ] = 1;
1077
1078 $args[ 'posts_per_page' ] = defined( 'SUCOM_GET_POSTS_WHILE_PPP' ) ? SUCOM_GET_POSTS_WHILE_PPP : 1000;
1079
1080 /*
1081 * Setting the offset parameter overrides/ignores the paged parameter and breaks pagination.
1082 *
1083 * See https://developer.wordpress.org/reference/classes/wp_query/.
1084 */
1085 unset( $args[ 'offset' ] );
1086
1087 $posts = array();
1088
1089 while ( $result = $wp_query->query( $args ) ) { // Return an array of post objects or post IDs.
1090
1091 $posts = array_merge( $posts, $result );
1092
1093 $args[ 'paged' ]++; // Get the next page.
1094 }
1095
1096 } else $posts = $wp_query->query( $args );
1097
1098 return $posts;
1099 }
1100
1101 public static function maybe_load_post( $mixed, $force = false ) {
1102
1103 if ( empty( $mixed ) ) { // Just in case.
1104
1105 return false;
1106 }
1107
1108 global $post;
1109
1110 if ( $mixed instanceof WP_Post ) {
1111
1112 if ( $force || ! isset( $post->ID ) || (int) $post->ID !== (int) $mixed->ID ) {
1113
1114 $post = $mixed;
1115 }
1116
1117 } elseif ( is_numeric( $mixed ) ) {
1118
1119 if ( $force || ! isset( $post->ID ) || (int) $post->ID !== (int) $mixed ) {
1120
1121 $post = self::get_post_object( $mixed, $output = 'object' );
1122
1123 return true;
1124 }
1125 }
1126
1127 return false;
1128 }
1129
1130 /*
1131 * GET TAXONOMY METHODS:
1132 *
1133 * get_taxonomies()
1134 * get_taxonomy_labels()
1135 */
1136 public static function get_taxonomies( $output = 'objects', $sort = false, $args = null ) {
1137
1138 $def_args = array( 'public' => true, 'show_ui' => true );
1139
1140 if ( null === $args ) {
1141
1142 $args = $def_args;
1143
1144 } elseif ( is_array( $args ) ) {
1145
1146 $args = array_merge( $def_args, $args );
1147
1148 } else return array();
1149
1150 $operator = 'and';
1151 $taxonomies = get_taxonomies( $args, $output, $operator );
1152
1153 if ( $sort ) {
1154
1155 if ( 'objects' === $output ) {
1156
1157 self::sort_objects_by_label( $taxonomies );
1158
1159 } else asort( $post_types );
1160 }
1161
1162 return apply_filters( 'sucom_get_taxonomies', $taxonomies, $output, $args );
1163 }
1164
1165 public static function get_taxonomy_labels( $val_prefix = '', $label_prefix = '', $objects = null ) {
1166
1167 $values = array();
1168
1169 if ( ! is_string( $val_prefix ) ) { // Just in case.
1170
1171 return $values;
1172 }
1173
1174 if ( null === $objects ) {
1175
1176 $objects = self::get_taxonomies( $output = 'objects', $sort = true );
1177 }
1178
1179 if ( is_array( $objects ) ) { // Just in case.
1180
1181 foreach ( $objects as $obj ) {
1182
1183 if ( is_object( $obj ) ) { // Just in case.
1184
1185 $obj_label = self::get_object_label( $obj );
1186
1187 $values[ $val_prefix . $obj->name ] = trim( $label_prefix . ' ' . $obj_label );
1188 }
1189 }
1190 }
1191
1192 asort( $values ); // Sort by label.
1193
1194 return $values;
1195 }
1196
1197 /*
1198 * GET TERM METHODS:
1199 *
1200 * get_term_object()
1201 */
1202 public static function get_term_object( $term_id = 0, $tax_slug = '', $output = 'object' ) {
1203
1204 $term_obj = null;
1205
1206 if ( $term_id instanceof WP_Term ) { // Just in case.
1207
1208 $term_obj = $term_id;
1209
1210 } elseif ( is_numeric( $term_id ) && $term_id > 0 ) {
1211
1212 $term_obj = get_term( (int) $term_id, (string) $tax_slug, OBJECT, 'raw' );
1213
1214 } elseif ( apply_filters( 'sucom_is_term_page', is_tax() ) || is_tag() || is_category() ) {
1215
1216 $term_obj = get_queried_object();
1217
1218 } elseif ( is_admin() ) {
1219
1220 if ( '' !== ( $tax_slug = self::get_request_value( 'taxonomy' ) ) &&
1221 '' !== ( $term_id = self::get_request_value( 'tag_ID' ) ) ) {
1222
1223 $term_obj = get_term( (int) $term_id, (string) $tax_slug, OBJECT, 'raw' );
1224 }
1225 }
1226
1227 $term_obj = apply_filters( 'sucom_get_term_object', $term_obj, $term_id, $tax_slug );
1228
1229 if ( $term_obj instanceof WP_Term ) { // Just in case.
1230
1231 switch ( $output ) {
1232
1233 case 'id':
1234 case 'ID':
1235 case 'term_id':
1236
1237 return isset( $term_obj->term_id ) ? (int) $term_obj->term_id : 0; // Cast as integer.
1238
1239 case 'taxonomy':
1240
1241 return isset( $term_obj->taxonomy ) ? (string) $term_obj->taxonomy : ''; // Cast as string.
1242
1243 default:
1244
1245 return $term_obj;
1246 }
1247 }
1248
1249 return false;
1250 }
1251
1252 /*
1253 * GET USER METHODS:
1254 *
1255 * get_user_object()
1256 * get_users_names()
1257 * get_users_ids()
1258 */
1259 public static function get_user_object( $user_id = 0, $output = 'object' ) {
1260
1261 $user_obj = null;
1262
1263 if ( $user_id instanceof WP_User ) {
1264
1265 $user_obj = $user_id;
1266
1267 } elseif ( is_numeric( $user_id ) && $user_id > 0 ) {
1268
1269 $user_obj = get_userdata( $user_id );
1270
1271 } elseif ( apply_filters( 'sucom_is_user_page', is_author() ) ) {
1272
1273 $user_obj = get_query_var( 'author_name' ) ?
1274 get_user_by( 'slug', get_query_var( 'author_name' ) ) :
1275 get_userdata( get_query_var( 'author' ) );
1276
1277 } elseif ( is_admin() ) {
1278
1279 if ( '' === ( $user_id = self::get_request_value( 'user_id' ) ) ) { // Uses sanitize_text_field().
1280
1281 $user_id = get_current_user_id();
1282 }
1283
1284 $user_obj = get_userdata( $user_id );
1285 }
1286
1287 $user_obj = apply_filters( 'sucom_get_user_object', $user_obj, $user_id );
1288
1289 if ( $user_obj instanceof WP_User ) { // Just in case.
1290
1291 switch ( $output ) {
1292
1293 case 'id':
1294 case 'ID':
1295 case 'user_id':
1296
1297 return isset( $user_obj->ID ) ? (int) $user_obj->ID : 0; // Cast as integer.
1298
1299 default:
1300
1301 return $user_obj;
1302 }
1303 }
1304
1305 return false;
1306 }
1307
1308 /*
1309 * Note that the 'wp_capabilities' meta value is a serialized array, so WordPress uses a LIKE query to match any
1310 * string within the serialized array.
1311 *
1312 * Example query:
1313 *
1314 * SELECT wp_users.ID,wp_users.display_name
1315 * FROM wp_users
1316 * INNER JOIN wp_usermeta
1317 * ON ( wp_users.ID = wp_usermeta.user_id )
1318 * WHERE 1=1
1319 * AND ( ( ( wp_usermeta.meta_key = 'wp_capabilities'
1320 * AND wp_usermeta.meta_value LIKE '%\"person\"%' ) ) )
1321 * ORDER BY display_name ASC
1322 *
1323 * If using the $limit argument, you must keep calling get_users_names() until it returns false.
1324 */
1325 public static function get_users_names( $role = '', $blog_id = null, $limit = null ) {
1326
1327 static $offset = null;
1328
1329 if ( empty( $blog_id ) ) {
1330
1331 $blog_id = get_current_blog_id();
1332 }
1333
1334 if ( is_numeric( $limit ) ) {
1335
1336 $offset = null === $offset ? 0 : $offset + $limit;
1337 }
1338
1339 /*
1340 * See https://developer.wordpress.org/reference/classes/wp_user_query/.
1341 */
1342 $user_args = array(
1343 'blog_id' => $blog_id,
1344 'offset' => null === $offset ? '' : $offset, // Default value should be an empty string.
1345 'number' => null === $limit ? '' : $limit, // Default value should be an empty string.
1346 'order' => 'ASC', // Sort alphabetically by display name.
1347 'orderby' => 'display_name',
1348 'role' => $role,
1349 'fields' => array( // Save memory and return only specific fields.
1350 'ID',
1351 'display_name',
1352 )
1353 );
1354
1355 $users_names = array();
1356
1357 /*
1358 * See https://developer.wordpress.org/reference/classes/WP_User_Query/prepare_query/.
1359 */
1360 foreach ( get_users( $user_args ) as $user_obj ) {
1361
1362 $users_names[ $user_obj->ID ] = $user_obj->display_name;
1363 }
1364
1365 if ( null !== $offset ) { // Null, 0, or multiple of $limit integer.
1366
1367 if ( empty( $users_names ) ) {
1368
1369 $offset = null; // Allow the next call to start fresh.
1370
1371 return false; // Break the calling while loop.
1372 }
1373 }
1374
1375 return $users_names;
1376 }
1377
1378 /*
1379 * If using the $limit argument, you must keep calling get_users_ids() until it returns false.
1380 *
1381 * See WpssoRegister->uninstall_plugin().
1382 * See WpssoUser->remove_person_role().
1383 */
1384 public static function get_users_ids( $blog_id = null, $role = '', $limit = null ) {
1385
1386 static $offset = null;
1387
1388 if ( empty( $blog_id ) ) {
1389
1390 $blog_id = get_current_blog_id();
1391 }
1392
1393 if ( is_numeric( $limit ) ) {
1394
1395 $offset = null === $offset ? 0 : $offset + $limit;
1396 }
1397
1398 $user_args = array(
1399 'blog_id' => $blog_id,
1400 'offset' => null === $offset ? '' : $offset, // Default value should be an empty string.
1401 'number' => null === $limit ? '' : $limit, // Default value should be an empty string.
1402 'order' => 'DESC', // Newest users first.
1403 'orderby' => 'ID',
1404 'role' => $role,
1405 'fields' => array( // Save memory and return only specific fields.
1406 'ID',
1407 )
1408 );
1409
1410 $users_ids = array();
1411
1412 /*
1413 * See https://developer.wordpress.org/reference/classes/WP_User_Query/prepare_query/.
1414 */
1415 foreach ( get_users( $user_args ) as $user_obj ) {
1416
1417 $users_ids[] = $user_obj->ID;
1418 }
1419
1420 if ( null !== $offset ) { // Null, 0, or multiple of $limit integer.
1421
1422 if ( empty( $users_ids ) ) {
1423
1424 $offset = null; // Allow the next call to start fresh.
1425
1426 return false; // Break the calling while loop.
1427 }
1428 }
1429
1430 return $users_ids;
1431 }
1432
1433 /*
1434 * OBJECT HANDLING METHODS:
1435 *
1436 * get_object_label()
1437 * sort_objects_by_label()
1438 *
1439 * Add the slug (ie. name) to custom post type and taxonomy labels.
1440 */
1441 public static function get_object_label( $obj ) {
1442
1443 if ( is_object( $obj ) ) { // Just in case.
1444
1445 if ( empty( $obj->_builtin ) ) { // Custom post type or taxonomy.
1446
1447 return $obj->label . ' [' . $obj->name . ']';
1448 }
1449
1450 return $obj->label;
1451 }
1452
1453 return '';
1454 }
1455
1456 public static function sort_objects_by_label( array &$objects ) {
1457
1458 $assoc = array();
1459 $sorted = array();
1460
1461 foreach ( $objects as $num => $obj ) {
1462
1463 if ( is_object( $obj ) ) { // Just in case.
1464
1465 if ( ! empty( $obj->labels->name ) ) {
1466
1467 $sort_key = $obj->labels->name . '-' . $num;
1468
1469 } elseif ( ! empty( $obj->label ) ) {
1470
1471 $sort_key = $obj->label . '-' . $num;
1472
1473 } else $sort_key = $obj->name . '-' . $num;
1474
1475 $assoc[ $sort_key ] = $num; // Make sure key is sortable and unique.
1476 }
1477 }
1478
1479 ksort( $assoc );
1480
1481 foreach ( $assoc as $sort_key => $num ) {
1482
1483 $sorted[] = $objects[ $num ];
1484 }
1485
1486 unset( $assoc );
1487
1488 return $objects = $sorted;
1489 }
1490
1491 /*
1492 * GET ROLES METHODS:
1493 *
1494 * get_roles_users_names()
1495 * get_roles_users_ids()
1496 * get_roles_users_select()
1497 */
1498 public static function get_roles_users_names( array $roles, $blog_id = null ) {
1499
1500 if ( empty( $roles ) ) {
1501
1502 return array();
1503 };
1504
1505 if ( empty( $blog_id ) ) {
1506
1507 $blog_id = get_current_blog_id();
1508 }
1509
1510 $users_names = array();
1511
1512 foreach ( $roles as $role ) {
1513
1514 while ( $role_users = self::get_users_names( $role, $blog_id, $limit = 1000 ) ) {
1515
1516 /*
1517 * The union operator (+) gives priority to values in the first array, while
1518 * array_replace() gives priority to values in the the second array.
1519 */
1520 $users_names = $users_names + $role_users; // Maintains numeric index.
1521 }
1522 }
1523
1524 self::natasort( $users_names ); // Maintain ID => display_name association.
1525
1526 return $users_names;
1527 }
1528
1529 /*
1530 * See WpssoUpgrade->options().
1531 */
1532 public static function get_roles_users_ids( array $roles, $blog_id = null ) {
1533
1534 /*
1535 * Get the user ID => name associative array, and keep only the array keys.
1536 */
1537 $users_ids = array_keys( self::get_roles_users_names( $roles, $blog_id ) );
1538
1539 rsort( $users_ids ); // Newest user first.
1540
1541 return $users_ids;
1542 }
1543
1544 /*
1545 * See WpssoUser->get_persons_names().
1546 */
1547 public static function get_roles_users_select( array $roles, $blog_id = null, $add_none = true ) {
1548
1549 $user_select = self::get_roles_users_names( $roles, $blog_id );
1550
1551 if ( $add_none ) {
1552
1553 /*
1554 * The union operator (+) gives priority to values in the first array, while array_replace() gives
1555 * priority to values in the the second array.
1556 */
1557 $user_select = array( 'none' => 'none' ) + $user_select; // Maintains numeric index.
1558 }
1559
1560 return $user_select;
1561 }
1562
1563 /*
1564 * GET SITE INFORMATION METHODS:
1565 *
1566 * get_home_url()
1567 * get_minimum_image_wh()
1568 * get_screen_base()
1569 * get_screen_id()
1570 * get_site_name()
1571 * get_site_name_alt()
1572 * get_site_description()
1573 * get_wp_config_file_path()
1574 * get_wp_url()
1575 *
1576 * Returns the website URL from the options array, or the WordPress get_home_url() value.
1577 *
1578 * $mixed = 'default' | 'current' | post ID | $mod array
1579 */
1580 public static function get_home_url( array $opts = array(), $mixed = 'current' ) {
1581
1582 if ( ! class_exists( 'SucomUtilOptions' ) ) {
1583
1584 require_once dirname( __FILE__ ) . '/util-options.php';
1585 }
1586
1587 $home_url = empty( $opts ) ? '' : SucomUtilOptions::get_key_value( 'site_home_url', $opts, $mixed );
1588
1589 if ( empty( $home_url ) ) { // Fallback to default WordPress value.
1590
1591 $home_url = get_home_url( $blog_id = null, $path = '/', $scheme = null );
1592 }
1593
1594 return apply_filters( 'sucom_get_home_url', $home_url );
1595 }
1596
1597 /*
1598 * Returns array( $min_width, $min_height, $size_count ).
1599 *
1600 * See WpssoMedia->show_post_upload_ui_message().
1601 */
1602 public static function get_minimum_image_wh() {
1603
1604 static $local_cache = null;
1605
1606 if ( null !== $local_cache ) {
1607
1608 return $local_cache;
1609 }
1610
1611 global $_wp_additional_image_sizes;
1612
1613 $min_width = 0;
1614 $min_height = 0;
1615 $size_count = 0;
1616
1617 foreach ( $_wp_additional_image_sizes as $size_name => $size_info ) {
1618
1619 $size_count++;
1620
1621 if ( isset( $_wp_additional_image_sizes[ $size_name ][ 'width' ] ) ) {
1622
1623 $width = intval( $_wp_additional_image_sizes[ $size_name ][ 'width' ] );
1624
1625 } else $width = get_option( $size_name . '_size_w' ); // Returns false by default.
1626
1627 if ( isset( $_wp_additional_image_sizes[ $size_name ][ 'height' ] ) ) {
1628
1629 $height = intval( $_wp_additional_image_sizes[ $size_name ][ 'height' ] );
1630
1631 } else $height = get_option( $size_name . '_size_h' ); // Returns false by default.
1632
1633 if ( isset( $_wp_additional_image_sizes[ $size_name ][ 'crop' ] ) ) {
1634
1635 $crop = $_wp_additional_image_sizes[ $size_name ][ 'crop' ];
1636
1637 } else $crop = get_option( $size_name . '_crop' ); // Returns false by default.
1638
1639 if ( ! is_array( $crop ) ) {
1640
1641 $crop = empty( $crop ) ? false : true;
1642 }
1643
1644 if ( $crop ) {
1645
1646 if ( $width > $min_width ) {
1647
1648 $min_width = $width;
1649 }
1650
1651 if ( $height > $min_height ) {
1652
1653 $min_height = $height;
1654 }
1655
1656 } elseif ( $width < $height ) {
1657
1658 if ( $width > $min_width ) {
1659
1660 $min_width = $width;
1661 }
1662
1663 } else {
1664
1665 if ( $height > $min_height ) {
1666
1667 $min_height = $height;
1668 }
1669 }
1670 }
1671
1672 return $local_cache = array( $min_width, $min_height, $size_count );
1673 }
1674
1675 /*
1676 * Returns false or the admin screen base string.
1677 */
1678 public static function get_screen_base( $screen = null ) {
1679
1680 if ( null === $screen || ! is_object( $screen ) ) {
1681
1682 if ( function_exists( 'get_current_screen' ) ) { // Just in case.
1683
1684 $screen = get_current_screen();
1685 }
1686 }
1687
1688 if ( isset( $screen->base ) ) {
1689
1690 return $screen->base;
1691 }
1692
1693 return false;
1694 }
1695
1696 /*
1697 * Returns false or the admin screen id string.
1698 */
1699 public static function get_screen_id( $screen = null ) {
1700
1701 if ( null === $screen || ! is_object( $screen ) ) {
1702
1703 if ( function_exists( 'get_current_screen' ) ) { // Just in case.
1704
1705 $screen = get_current_screen();
1706 }
1707 }
1708
1709 if ( isset( $screen->id ) ) {
1710
1711 return $screen->id;
1712 }
1713
1714 return false;
1715 }
1716
1717 /*
1718 * Site Title.
1719 *
1720 * Returns a custom site name or the default WordPress site name.
1721 *
1722 * $mixed = 'default' | 'current' | post ID | $mod array
1723 */
1724 public static function get_site_name( array $opts = array(), $mixed = 'current' ) {
1725
1726 if ( ! class_exists( 'SucomUtilOptions' ) ) {
1727
1728 require_once dirname( __FILE__ ) . '/util-options.php';
1729 }
1730
1731 $site_name = empty( $opts ) ? '' : SucomUtilOptions::get_key_value( 'site_name', $opts, $mixed );
1732
1733 if ( empty( $site_name ) ) { // Fallback to default WordPress value.
1734
1735 $site_name = get_bloginfo( $show = 'name', $filter = 'raw' );
1736 }
1737
1738 return $site_name;
1739 }
1740
1741 /*
1742 * Site Alternate Title.
1743 *
1744 * Returns a custom site alternate name or an empty string.
1745 *
1746 * $mixed = 'default' | 'current' | post ID | $mod array
1747 */
1748 public static function get_site_name_alt( array $opts, $mixed = 'current' ) {
1749
1750 if ( ! class_exists( 'SucomUtilOptions' ) ) {
1751
1752 require_once dirname( __FILE__ ) . '/util-options.php';
1753 }
1754
1755 return empty( $opts ) ? '' : SucomUtilOptions::get_key_value( 'site_name_alt', $opts, $mixed );
1756 }
1757
1758 /*
1759 * Site Tagline.
1760 *
1761 * Returns a custom site description or the default WordPress site description / tagline.
1762 *
1763 * $mixed = 'default' | 'current' | post ID | $mod array
1764 */
1765 public static function get_site_description( array $opts = array(), $mixed = 'current' ) {
1766
1767 if ( ! class_exists( 'SucomUtilOptions' ) ) {
1768
1769 require_once dirname( __FILE__ ) . '/util-options.php';
1770 }
1771
1772 $site_desc = empty( $opts ) ? '' : SucomUtilOptions::get_key_value( 'site_desc', $opts, $mixed );
1773
1774 if ( empty( $site_desc ) ) { // Fallback to default WordPress value.
1775
1776 $site_desc = get_bloginfo( $show = 'description', $filter = 'raw' );
1777 }
1778
1779 return $site_desc;
1780 }
1781
1782 public static function get_wp_config_file_path() {
1783
1784 $parent_abspath = trailingslashit( dirname( ABSPATH ) );
1785
1786 if ( file_exists( ABSPATH . 'wp-config.php' ) ) {
1787
1788 return ABSPATH . 'wp-config.php';
1789
1790 } elseif ( file_exists( $parent_abspath . 'wp-config.php' ) && ! file_exists( $parent_abspath . 'wp-settings.php' ) ) {
1791
1792 return $parent_abspath . 'wp-config.php';
1793 }
1794
1795 return false;
1796 }
1797
1798 /*
1799 * Returns the WordPress installation URL from the options array, or the WordPress get_site_url() value.
1800 *
1801 * $mixed = 'default' | 'current' | post ID | $mod array
1802 */
1803 public static function get_wp_url( array $opts = array(), $mixed = 'current' ) {
1804
1805 if ( ! class_exists( 'SucomUtilOptions' ) ) {
1806
1807 require_once dirname( __FILE__ ) . '/util-options.php';
1808 }
1809
1810 $wp_url = empty( $opts ) ? '' : SucomUtilOptions::get_key_value( 'site_wp_url', $opts, $mixed );
1811
1812 if ( empty( $wp_url ) ) { // Fallback to default WordPress value.
1813
1814 $wp_url = get_site_url( $blog_id = null, $path = '/', $scheme = null );
1815 }
1816
1817 return apply_filters( 'sucom_get_wp_url', $wp_url );
1818 }
1819
1820 /*
1821 * GET LOCALE METHODS:
1822 *
1823 * clear_locale_cache()
1824 * get_available_feed_locale_names()
1825 * get_available_locale_names()
1826 * get_available_locales()
1827 * get_locale()
1828 */
1829 public static function clear_locale_cache() {
1830
1831 self::$locale_cache = array();
1832 }
1833
1834 /*
1835 * Returns an associative array with locale keys and native names (example: 'en_US' => 'English (United States)').
1836 */
1837 public static function get_available_feed_locale_names() {
1838
1839 $locale_names = self::get_available_locale_names(); // Uses a local cache.
1840
1841 $locale_names = apply_filters( 'sucom_available_feed_locale_names', $locale_names );
1842
1843 return $locale_names;
1844 }
1845
1846 /*
1847 * Returns an associative array with locale keys and native names (example: 'en_US' => 'English (United States)').
1848 */
1849 public static function get_available_locale_names() {
1850
1851 static $local_cache = null;
1852
1853 if ( null !== $local_cache ) {
1854
1855 return $local_cache;
1856 }
1857
1858 require_once trailingslashit( ABSPATH ) . 'wp-admin/includes/translation-install.php';
1859
1860 $translations = wp_get_available_translations(); // Array of translations, each an array of data, keyed by the language.
1861 $avail_locales = self::get_available_locales(); // Uses a local cache.
1862 $local_cache = array();
1863
1864 foreach ( $avail_locales as $locale ) {
1865
1866 if ( isset( $translations[ $locale ][ 'native_name' ] ) ) {
1867
1868 $native_name = $translations[ $locale ][ 'native_name' ];
1869
1870 } elseif ( 'en' === $locale || 'en_US' === $locale ) {
1871
1872 $native_name = 'English (United States)';
1873
1874 } else $native_name = $locale;
1875
1876 $local_cache[ $locale ] = $native_name;
1877 }
1878
1879 $local_cache = apply_filters( 'sucom_available_locale_names', $local_cache );
1880
1881 return $local_cache;
1882 }
1883
1884 /*
1885 * Returns an array of locales.
1886 *
1887 * See https://developer.wordpress.org/reference/functions/get_available_languages/.
1888 */
1889 public static function get_available_locales() {
1890
1891 static $local_cache = null;
1892
1893 if ( null !== $local_cache ) {
1894
1895 return $local_cache;
1896 }
1897
1898 $def_locale = self::get_locale( 'default' ); // Uses a local cache.
1899 $local_cache = get_available_languages();
1900
1901 if ( ! is_array( $local_cache ) ) { // Just in case.
1902
1903 $local_cache = array( $def_locale );
1904
1905 } elseif ( ! in_array( $def_locale, $local_cache ) ) { // Just in case.
1906
1907 $local_cache[] = $def_locale;
1908 }
1909
1910 sort( $local_cache );
1911
1912 $local_cache = apply_filters( 'sucom_available_locales', $local_cache );
1913
1914 return $local_cache;
1915 }
1916
1917 /*
1918 * $mixed = 'default' | 'current' | post ID | $mod array
1919 */
1920 public static function get_locale( $mixed = 'current', $read_cache = true ) {
1921
1922 if ( empty( $mixed ) ) $mixed = 'current'; // Just in case.
1923
1924 /*
1925 * Note that the sort order, page number, locale, amp and embed checks are provided by
1926 * WpssoHead->get_head_cache_index() and not SucomUtil::get_mod_salt().
1927 *
1928 * Example cache salts:
1929 *
1930 * 'post:123_type:page'
1931 * 'post:123_type:product_is_pta' // WooCommerce shop page.
1932 * 'term:123_tax:product_cat' // WooCommerce category page.
1933 */
1934 $cache_salt = is_array( $mixed ) ? self::get_mod_salt( $mixed ) : $mixed;
1935
1936 if ( $read_cache ) {
1937
1938 if ( isset( self::$locale_cache[ $cache_salt ] ) ) {
1939
1940 return self::$locale_cache[ $cache_salt ];
1941 }
1942 }
1943
1944 if ( 'default' === $mixed ) {
1945
1946 global $wp_local_package;
1947
1948 if ( isset( $wp_local_package ) ) $locale = $wp_local_package;
1949
1950 if ( defined( 'WPLANG' ) ) $locale = WPLANG;
1951
1952 /*
1953 * The database 'WPLANG' values override the 'WPLANG' constant.
1954 */
1955 $db_locale = get_option( 'WPLANG' );
1956
1957 if ( false === $db_locale && is_multisite() ) $db_locale = get_site_option( 'WPLANG' );
1958
1959 if ( false !== $db_locale ) $locale = $db_locale;
1960
1961 } elseif ( 'current' === $mixed || is_array( $mixed ) ) {
1962
1963 $locale = get_locale();
1964
1965 } elseif ( 'user' === $mixed ) {
1966
1967 $locale = get_user_locale();
1968
1969 } elseif ( is_string( $mixed ) ) {
1970
1971 $locale_names = self::get_available_locale_names(); // Uses a local cache.
1972
1973 if ( isset( $locale_names[ $mixed ] ) ) $locale = $mixed;
1974 }
1975
1976 if ( empty( $locale ) ) $locale = 'en_US'; // Just in case.
1977
1978 /*
1979 * Filtered by WpssoIntegLangPolylang->filter_get_locale() and WpssoIntegLangWpml->filter_get_locale().
1980 */
1981 $locale = apply_filters( 'sucom_get_locale', $locale, $mixed );
1982
1983 return self::$locale_cache[ $cache_salt ] = $locale;
1984 }
1985
1986 /*
1987 * ACTION AND FILTER METHODS:
1988 *
1989 * do_shortcode_names()
1990 * get_filter_hook_ids()
1991 * get_filter_hook_names()
1992 * get_filter_hook_function()
1993 * remove_action_hook_name()
1994 * remove_filter_hook_name()
1995 */
1996 public static function do_shortcode_names( array $do_names, $content, $ignore_html = false ) {
1997
1998 if ( ! empty( $do_names ) ) { // Just in case.
1999
2000 global $shortcode_tags;
2001
2002 $saved_tags = $shortcode_tags; // Save the original registered shortcodes.
2003
2004 $shortcode_tags = array(); // Init a new empty global shortcode tags array.
2005
2006 foreach ( $do_names as $key ) {
2007
2008 if ( isset( $saved_tags[ $key ] ) ) {
2009
2010 $shortcode_tags[ $key ] = $saved_tags[ $key ];
2011 }
2012 }
2013
2014 if ( ! empty( $shortcode_tags ) ) { // Just in case.
2015
2016 $content = do_shortcode( $content, $ignore_html );
2017 }
2018
2019 $shortcode_tags = $saved_tags; // Restore the original registered shortcodes.
2020 }
2021
2022 return $content;
2023 }
2024
2025 public static function get_filter_hook_ids( $filter_name ) {
2026
2027 global $wp_filter;
2028
2029 $hook_ids = array();
2030
2031 if ( isset( $wp_filter[ $filter_name ]->callbacks ) ) {
2032
2033 foreach ( $wp_filter[ $filter_name ]->callbacks as $hook_prio => $hook_group ) {
2034
2035 foreach ( $hook_group as $hook_id => $hook_info ) {
2036
2037 $hook_ids[] = $hook_id;
2038 }
2039 }
2040 }
2041
2042 return $hook_ids;
2043 }
2044
2045 public static function get_filter_hook_names( $filter_name ) {
2046
2047 global $wp_filter;
2048
2049 $hook_names = array();
2050
2051 if ( isset( $wp_filter[ $filter_name ]->callbacks ) ) {
2052
2053 foreach ( $wp_filter[ $filter_name ]->callbacks as $hook_prio => $hook_group ) {
2054
2055 foreach ( $hook_group as $hook_id => $hook_info ) {
2056
2057 /*
2058 * Returns a function name or a class static method name.
2059 *
2060 * Class object methods are returned as class static method names.
2061 */
2062 if ( $hook_name = self::get_filter_hook_function( $hook_info ) ) {
2063
2064 $hook_names[] = $hook_name;
2065 }
2066 }
2067 }
2068 }
2069
2070 return $hook_names;
2071 }
2072
2073 /*
2074 * Returns a function name or a class static method name.
2075 *
2076 * Class object methods are returned as class static method names.
2077 */
2078 public static function get_filter_hook_function( array $hook_info ) {
2079
2080 $hook_name = '';
2081
2082 if ( isset( $hook_info[ 'function' ] ) ) {
2083
2084 /*
2085 * The callback hook is a dynamic or static method.
2086 */
2087 if ( is_array( $hook_info[ 'function' ] ) ) {
2088
2089 $class_name = '';
2090 $function_name = '';
2091
2092 /*
2093 * The callback hook is a dynamic method.
2094 */
2095 if ( is_object( $hook_info[ 'function' ][ 0 ] ) ) {
2096
2097 $class_name = get_class( $hook_info[ 'function' ][ 0 ] );
2098
2099 /*
2100 * The callback hook is a static method.
2101 */
2102 } elseif ( is_string( $hook_info[ 'function' ][ 0 ] ) ) {
2103
2104 $class_name = $hook_info[ 'function' ][ 0 ];
2105 }
2106
2107 if ( is_string( $hook_info[ 'function' ][ 1 ] ) ) {
2108
2109 $function_name = $hook_info[ 'function' ][ 1 ];
2110 }
2111
2112 /*
2113 * Return a static method name.
2114 */
2115 $hook_name = $class_name . '::' . $function_name;
2116
2117 /*
2118 * The callback hook is a function.
2119 */
2120 } elseif ( is_string( $hook_info[ 'function' ] ) ) {
2121
2122 $hook_name = $hook_info[ 'function' ];
2123 }
2124 }
2125
2126 return $hook_name;
2127 }
2128
2129 public static function remove_action_hook_name( $filter_name, $hook_name ) {
2130
2131 self::remove_filter_hook_name( $filter_name, $hook_name );
2132 }
2133
2134 /*
2135 * Filters and actions are both saved in the $wp_filter global variable.
2136 *
2137 * Loop through all action/filter hooks and remove any that match the given function or static method name.
2138 *
2139 * Note that class object methods are matched using a class static method name.
2140 */
2141 public static function remove_filter_hook_name( $filter_name, $hook_name ) {
2142
2143 global $wp_filter;
2144
2145 if ( isset( $wp_filter[ $filter_name ]->callbacks ) ) {
2146
2147 foreach ( $wp_filter[ $filter_name ]->callbacks as $hook_prio => $hook_group ) {
2148
2149 foreach ( $hook_group as $hook_id => $hook_info ) {
2150
2151 /*
2152 * Returns a function name or a class static method name.
2153 *
2154 * Class object methods are returned as class static method names.
2155 */
2156 if ( self::get_filter_hook_function( $hook_info ) === $hook_name ) {
2157
2158 unset( $wp_filter[ $filter_name ]->callbacks[ $hook_prio ][ $hook_id ] );
2159 }
2160 }
2161 }
2162 }
2163 }
2164
2165 /*
2166 * CACHE HANDLING METHODS:
2167 *
2168 * get_update_meta_cache().
2169 * update_transient_array().
2170 */
2171 public static function get_update_meta_cache( $obj_id, $meta_type ) {
2172
2173 if ( ! is_numeric( $obj_id ) || empty( $meta_type ) ) {
2174
2175 return array();
2176 }
2177
2178 $obj_id = absint( $obj_id );
2179
2180 if ( ! $obj_id ) return array();
2181
2182 /*
2183 * WordPress stores data using a post, term, or user ID, along with a group string.
2184 *
2185 * Example: wp_cache_get( 1, 'user_meta' );
2186 *
2187 * Returns (bool|mixed) false on failure to retrieve contents or the cache contents on success.
2188 *
2189 * $found (bool) Whether the key was found in the cache (passed by reference) - disambiguates a return of false.
2190 */
2191 $found = null;
2192
2193 $metadata = wp_cache_get( $obj_id, $meta_type . '_meta', $force = false, $found );
2194
2195 if ( $found ) return $metadata;
2196
2197 /*
2198 * $meta_type (string) Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user',
2199 * or any other object type with an associated meta table.
2200 *
2201 * Returns (array|false) metadata cache for the specified objects, or false on failure.
2202 */
2203 $metadata = update_meta_cache( $meta_type, array( $obj_id ) );
2204
2205 return $metadata[ $obj_id ];
2206 }
2207
2208 /*
2209 * Update the cached array and maintain the existing transient expiration time.
2210 */
2211 public static function update_transient_array( $cache_id, $cache_array, $cache_exp_secs ) {
2212
2213 $current_time = time();
2214 $reset_at_secs = 300;
2215
2216 /*
2217 * If the $cache_array already has a '__created_at' value, then calculate how long until the transient
2218 * object expires, and set the transient with that new expiration seconds.
2219 */
2220 if ( isset( $cache_array[ '__created_at' ] ) ) {
2221
2222 /*
2223 * Adjust the expiration time by removing the difference (current time less creation time) from the
2224 * desired transient expiration seconds.
2225 */
2226 $transient_exp_secs = $cache_exp_secs - ( $current_time - $cache_array[ '__created_at' ] );
2227
2228 /*
2229 * If we're 300 seconds (5 minutes) or less from the transient expiring, then renew the transient
2230 * creation and expiration times.
2231 */
2232 if ( $transient_exp_secs < $reset_at_secs ) {
2233
2234 $transient_exp_secs = $cache_exp_secs;
2235
2236 $cache_array[ '__created_at' ] = $current_time;
2237 }
2238
2239 } else {
2240
2241 $transient_exp_secs = $cache_exp_secs;
2242
2243 $cache_array[ '__created_at' ] = $current_time;
2244 }
2245
2246 set_transient( $cache_id, $cache_array, $transient_exp_secs );
2247
2248 return $transient_exp_secs;
2249 }
2250
2251 /*
2252 * OPTIONS KEY METHODS:
2253 *
2254 * add_options_key()
2255 * delete_options_key()
2256 * get_options_key()
2257 * update_options_key()
2258 * add_site_options_key()
2259 * delete_site_options_key()
2260 * get_site_options_key()
2261 * update_site_options_key()
2262 *
2263 * Add an element to an options array, if the array key does not already exist.
2264 */
2265 public static function add_options_key( $options_name, $key, $value ) {
2266
2267 return self::update_options_key( $options_name, $key, $value, $protect = true, $site = false );
2268 }
2269
2270 /*
2271 * Delete an element from an options array, if the array key exists.
2272 */
2273 public static function delete_options_key( $options_name, $key, $site = false ) {
2274
2275 $opts = $site ? get_site_option( $options_name, $default = array() ) : get_option( $options_name, $default = array() );
2276
2277 if ( ! array_key_exists( $key, $opts ) ) { // Nothing to do.
2278
2279 return false; // No update.
2280 }
2281
2282 unset( $opts[ $key ] );
2283
2284 if ( empty( $opts ) ) { // Just in case.
2285
2286 return $site ? delete_site_option( $options_name ) : delete_option( $options_name );
2287 }
2288
2289 return $site ? update_site_option( $options_name, $opts ) : update_option( $options_name, $opts );
2290 }
2291
2292 /*
2293 * Get an element from an options array. Returns null if the array key does not exist.
2294 */
2295 public static function get_options_key( $options_name, $key, $site = false ) {
2296
2297 $opts = $site ? get_site_option( $options_name, $default = array() ) : get_option( $options_name, $default = array() );
2298
2299 if ( array_key_exists( $key, $opts ) ) {
2300
2301 return $opts[ $key ];
2302 }
2303
2304 return null; // No value.
2305 }
2306
2307 /*
2308 * Update an options array element, if the array key does not exit, or its value is different.
2309 *
2310 * Use $protect = true to prevent overwriting an existing value.
2311 */
2312 public static function update_options_key( $options_name, $key, $value, $protect = false, $site = false ) {
2313
2314 $opts = $site ? get_site_option( $options_name, $default = array() ) : get_option( $options_name, $default = array() );
2315
2316 if ( array_key_exists( $key, $opts ) ) {
2317
2318 if ( $protect ) { // Prevent overwriting an existing value.
2319
2320 return false; // No update.
2321
2322 } elseif ( $value === $opts[ $key ] ) { // Nothing to do.
2323
2324 return false; // No update.
2325 }
2326 }
2327
2328 $opts[ $key ] = $value;
2329
2330 return $site ? update_site_option( $options_name, $opts ) : update_option( $options_name, $opts );
2331 }
2332
2333 /*
2334 * Add an element to a site options array, if the array key does not already exist.
2335 */
2336 public static function add_site_options_key( $options_name, $key, $value ) {
2337
2338 return self::update_options_key( $options_name, $key, $value, $protect = true, $site = true );
2339 }
2340
2341 /*
2342 * Delete an element from a site options array, if the array key exists.
2343 */
2344 public static function delete_site_options_key( $options_name, $key ) {
2345
2346 return self::delete_options_key( $options_name, $key, $site = true );
2347 }
2348
2349 /*
2350 * Get an element from a site options array. Returns null if the array key does not exist.
2351 */
2352 public static function get_site_options_key( $options_name, $key ) {
2353
2354 return self::get_options_key( $options_name, $key, $site = true );
2355 }
2356
2357 /*
2358 * Update a site options array element, if the array key does not exit, or its value is different.
2359 *
2360 * Use $protect = true to prevent overwriting an existing value.
2361 */
2362 public static function update_site_options_key( $options_name, $key, $value, $protect = false ) {
2363
2364 return self::update_options_key( $options_name, $key, $value, $protect, $site = true );
2365 }
2366
2367 /*
2368 * RAW UNFILTERED METHODS:
2369 *
2370 * raw_update_post()
2371 * raw_update_post_title()
2372 * raw_update_post_title_content()
2373 * raw_metadata_exists()
2374 * raw_wp_get_shortlink()
2375 * raw_home_url()
2376 * raw_get_home_url()
2377 * raw_site_url()
2378 * raw_get_site_url()
2379 * raw_set_url_scheme()
2380 * raw_add_option()
2381 * raw_delete_option()
2382 * raw_get_option()
2383 * raw_update_option()
2384 * raw_do_option()
2385 * raw_delete_transient()
2386 * raw_get_transient()
2387 * raw_set_transient()
2388 */
2389 public static function raw_update_post( $post_id, array $args ) {
2390
2391 if ( wp_is_post_revision( $post_id ) ) {
2392
2393 $post_id = wp_is_post_revision( $post_id );
2394 }
2395
2396 if ( ! is_numeric( $post_id ) ) { // Just in case.
2397
2398 return false;
2399 }
2400
2401 global $wpdb;
2402
2403 $post_id = absint( $post_id );
2404
2405 $where = array( 'ID' => $post_id );
2406
2407 foreach ( $args as $field => $value ) {
2408
2409 $args[ $field ] = sanitize_post_field( $field, $value, $post_id, $context = 'db' );
2410 }
2411
2412 $wpdb->update( $wpdb->posts, $args, $where );
2413
2414 clean_post_cache( $post_id );
2415 }
2416
2417 public static function raw_update_post_title( $post_id, $post_title ) {
2418
2419 $post_title = sanitize_text_field( $post_title );
2420 $post_name = sanitize_title( $post_title );
2421
2422 $args = array(
2423 'post_title' => $post_title,
2424 'post_name' => $post_name,
2425 );
2426
2427 self::raw_update_post( $post_id, $args );
2428 }
2429
2430 public static function raw_update_post_title_content( $post_id, $post_title, $post_content ) {
2431
2432 $post_title = sanitize_text_field( $post_title );
2433 $post_name = sanitize_title( $post_title );
2434 $post_content = wp_kses_post( $post_content ); // KSES (Kses Strips Evil Scripts).
2435
2436 $args = array(
2437 'post_title' => $post_title,
2438 'post_name' => $post_name,
2439 'post_content' => $post_content,
2440 );
2441
2442 self::raw_update_post( $post_id, $args );
2443 }
2444
2445 public static function raw_metadata_exists( $meta_type, $obj_id, $meta_key ) {
2446
2447 $metadata = self::get_update_meta_cache( $obj_id, $meta_type );
2448
2449 return isset( $metadata[ $obj_id ][ $meta_key ] ) ? true : false;
2450 }
2451
2452 /*
2453 * Unfiltered version of wp_get_shortlink() from wordpress/wp-includes/link-template.php
2454 *
2455 * Last synchronized with WordPress v5.0.3 on 2019/01/29.
2456 */
2457 public static function raw_wp_get_shortlink( $id = 0, $context = 'post', $allow_slugs = true ) {
2458
2459 $post_id = 0;
2460
2461 if ( 'query' === $context && is_singular() ) {
2462
2463 $post_id = get_queried_object_id();
2464
2465 $post = get_post( $post_id );
2466
2467 } elseif ( 'post' === $context ) {
2468
2469 $post = get_post( $id );
2470
2471 if ( ! empty( $post->ID ) ) {
2472
2473 $post_id = $post->ID;
2474 }
2475 }
2476
2477 $shortlink = '';
2478
2479 if ( ! empty( $post_id ) ) {
2480
2481 $post_type_obj = get_post_type_object( $post->post_type );
2482
2483 if ( 'page' === $post->post_type &&
2484 (int) $post->ID === (int) get_option( 'page_on_front' ) &&
2485 'page' === get_option( 'show_on_front' ) ) {
2486
2487 $shortlink = self::raw_home_url( '/' );
2488
2489 } elseif ( ! empty( $post_type_obj->public ) ) {
2490
2491 $shortlink = self::raw_home_url( '?p=' . $post_id );
2492 }
2493 }
2494
2495 return $shortlink;
2496 }
2497
2498 /*
2499 * Unfiltered version of home_url() from wordpress/wp-includes/link-template.php
2500 *
2501 * Last synchronized with WordPress v6.6.2 on 2024/09/16.
2502 */
2503 public static function raw_home_url( $path = '', $scheme = null ) {
2504
2505 return self::raw_get_home_url( null, $path, $scheme );
2506 }
2507
2508 /*
2509 * Unfiltered version of get_home_url() from wordpress/wp-includes/link-template.php
2510 *
2511 * Last synchronized with WordPress v6.6.2 on 2024/09/16.
2512 */
2513 public static function raw_get_home_url( $blog_id = null, $path = '', $scheme = null ) {
2514
2515 $is_multisite = is_multisite();
2516
2517 if ( $is_multisite && ! empty( $blog_id ) ) {
2518
2519 switch_to_blog( $blog_id );
2520 }
2521
2522 /*
2523 * The WordPress _config_wp_home() function is hooked to the 'option_home' filter in order to override the
2524 * database value. Since we're not using the default filters, check for WP_HOME or WP_SITEURL and update
2525 * the stored database value if necessary.
2526 *
2527 * The homepage of the website:
2528 *
2529 * WP_HOME
2530 * home_url()
2531 * get_home_url()
2532 * Site Address (URL)
2533 * http://example.com
2534 *
2535 * The WordPress installation (ie. where you can reach the site by adding /wp-admin):
2536 *
2537 * WP_SITEURL
2538 * site_url()
2539 * get_site_url()
2540 * WordPress Address (URL)
2541 * http://example.com/wp/
2542 *
2543 * The WordPress _config_wp_home() function is unhooked for multisites as WP_HOME and WP_SITEURL are not
2544 * used in a multisite configuration. If this is a multisite, ignore the WP_HOME and WP_SITEURL values.
2545 *
2546 * See wordpress/wp-includes/ms-default-filters.php
2547 */
2548 if ( ! $is_multisite ) {
2549
2550 if ( defined( 'WP_HOME' ) && WP_HOME ) {
2551
2552 $url = untrailingslashit( WP_HOME );
2553
2554 $db_url = self::raw_do_option( $action = 'get', $opt_name = 'home' );
2555
2556 if ( $db_url !== $url ) {
2557
2558 self::raw_do_option( $action = 'update', $opt_name = 'home', $url );
2559 }
2560 }
2561 }
2562
2563 $url = self::raw_do_option( $action = 'get', $opt_name = 'home' );
2564
2565 if ( $is_multisite && ! empty( $blog_id ) ) {
2566
2567 restore_current_blog();
2568 }
2569
2570 if ( ! in_array( $scheme, array( 'http', 'https', 'relative' ), $strict = true ) ) {
2571
2572 $scheme = is_ssl() ? 'https' : wp_parse_url( $url, PHP_URL_SCHEME );
2573 }
2574
2575 $url = self::raw_set_url_scheme( $url, $scheme );
2576
2577 if ( $path && is_string( $path ) ) {
2578
2579 $url .= '/' . ltrim( $path, '/' );
2580 }
2581
2582 return $url;
2583 }
2584
2585
2586 /*
2587 * Unfiltered version of site_url() from wordpress/wp-includes/link-template.php
2588 *
2589 * Last synchronized with WordPress v6.6.2 on 2024/09/16.
2590 */
2591 public static function raw_site_url( $path = '', $scheme = null ) {
2592
2593 return self::raw_get_site_url( null, $path, $scheme );
2594 }
2595
2596 /*
2597 * Unfiltered version of get_site_url() from wordpress/wp-includes/link-template.php
2598 *
2599 * Last synchronized with WordPress v6.6.2 on 2024/09/16.
2600 */
2601 public static function raw_get_site_url( $blog_id = null, $path = '', $scheme = null ) {
2602
2603 $is_multisite = is_multisite();
2604
2605 if ( $is_multisite && ! empty( $blog_id ) ) {
2606
2607 switch_to_blog( $blog_id );
2608 }
2609
2610 /*
2611 * The WordPress _config_wp_home() function is hooked to the 'option_home' filter in order to override the
2612 * database value. Since we're not using the default filters, check for WP_HOME or WP_SITEURL and update
2613 * the stored database value if necessary.
2614 *
2615 * The homepage of the website:
2616 *
2617 * WP_HOME
2618 * home_url()
2619 * get_home_url()
2620 * Site Address (URL)
2621 * http://example.com
2622 *
2623 * The WordPress installation (ie. where you can reach the site by adding /wp-admin):
2624 *
2625 * WP_SITEURL
2626 * site_url()
2627 * get_site_url()
2628 * WordPress Address (URL)
2629 * http://example.com/wp/
2630 *
2631 * The WordPress _config_wp_home() function is unhooked for multisites as WP_HOME and WP_SITEURL are not
2632 * used in a multisite configuration. If this is a multisite, ignore the WP_HOME and WP_SITEURL values.
2633 *
2634 * See wordpress/wp-includes/ms-default-filters.php
2635 */
2636 if ( ! $is_multisite ) {
2637
2638 if ( ! $is_multisite && defined( 'WP_SITEURL' ) && WP_SITEURL ) {
2639
2640 $url = untrailingslashit( WP_SITEURL );
2641
2642 $db_url = self::raw_do_option( $action = 'get', $opt_name = 'siteurl' );
2643
2644 if ( $db_url !== $url ) {
2645
2646 self::raw_do_option( $action = 'update', $opt_name = 'siteurl', $url );
2647 }
2648 }
2649 }
2650
2651 $url = self::raw_do_option( $action = 'get', $opt_name = 'siteurl' );
2652
2653 if ( $is_multisite && ! empty( $blog_id ) ) {
2654
2655 restore_current_blog();
2656 }
2657
2658 $url = self::raw_set_url_scheme( $url, $scheme );
2659
2660 if ( $path && is_string( $path ) ) {
2661
2662 $url .= '/' . ltrim( $path, '/' );
2663 }
2664
2665 return $url;
2666 }
2667
2668 /*
2669 * Unfiltered version of set_url_scheme() from wordpress/wp-includes/link-template.php
2670 *
2671 * Last synchronized with WordPress v6.6.2 on 2024/09/16.
2672 */
2673 private static function raw_set_url_scheme( $url, $scheme = null ) {
2674
2675 if ( ! $scheme ) {
2676
2677 $scheme = is_ssl() ? 'https' : 'http';
2678
2679 } elseif ( 'admin' === $scheme || 'login' === $scheme || 'login_post' === $scheme || 'rpc' === $scheme ) {
2680
2681 $scheme = is_ssl() || force_ssl_admin() ? 'https' : 'http';
2682
2683 } elseif ( 'http' !== $scheme && 'https' !== $scheme && 'relative' !== $scheme ) {
2684
2685 $scheme = is_ssl() ? 'https' : 'http';
2686 }
2687
2688 $url = trim( $url );
2689
2690 if ( str_starts_with( $url, '//' ) ) {
2691
2692 $url = 'http:' . $url;
2693 }
2694
2695 if ( 'relative' === $scheme ) {
2696
2697 $url = ltrim( preg_replace( '#^\w+://[^/]*#', '', $url ) );
2698
2699 if ( '' !== $url && '/' === $url[ 0 ] ) {
2700
2701 $url = '/' . ltrim( $url, "/ \t\n\r\0\x0B" );
2702 }
2703
2704 } else $url = preg_replace( '#^\w+://#', $scheme . '://', $url );
2705
2706 return $url;
2707 }
2708
2709 /*
2710 * Temporarily removes filter and action hooks before calling add_option().
2711 */
2712 public static function raw_add_option( $opt_name, $value = '', $deprecated = '', $autoload = null ) {
2713
2714 return self::raw_do_option( __FUNCTION__, $opt_name, $value, $default = false, $autoload );
2715 }
2716
2717 /*
2718 * Temporarily removes filter and action hooks before calling delete_option().
2719 */
2720 public static function raw_delete_option( $opt_name ) {
2721
2722 return self::raw_do_option( __FUNCTION__, $opt_name, $value = null, $default = false, $autoload = null );
2723 }
2724
2725 /*
2726 * Temporarily removes filter and action hooks before calling get_option().
2727 */
2728 public static function raw_get_option( $opt_name, $default = false ) {
2729
2730 return self::raw_do_option( __FUNCTION__, $opt_name, $value = null, $default, $autoload = null );
2731 }
2732
2733 /*
2734 * Temporarily removes filter and action hooks before calling update_option().
2735 */
2736 public static function raw_update_option( $opt_name, $value, $autoload = null ) {
2737
2738 return self::raw_do_option( __FUNCTION__, $opt_name, $value, $default = false, $autoload );
2739 }
2740
2741 /*
2742 * Temporarily removes filter and action hooks before calling add_option(), delete_option(), get_option(), and
2743 * update_option().
2744 */
2745 public static function raw_do_option( $action, $opt_name, $value = null, $default = false, $autoload = null ) {
2746
2747 global $wp_filter, $wp_actions;
2748
2749 $saved_filter = $wp_filter; // Save filters.
2750 $saved_actions = $wp_actions; // Save actions.
2751
2752 $wp_filter = array(); // Remove all filters.
2753 $wp_actions = array(); // Remove all actions.
2754
2755 $success = null;
2756 $old_value = $default;
2757
2758 switch( $action ) {
2759
2760 case 'add':
2761 case 'add_option':
2762 case 'raw_add_option':
2763
2764 $success = add_option( $opt_name, $value, $deprecated = '', $autoload );
2765
2766 break;
2767
2768 case 'delete':
2769 case 'delete_option':
2770 case 'raw_delete_option':
2771
2772 $success = delete_option( $opt_name );
2773
2774 break;
2775
2776 case 'get':
2777 case 'get_option':
2778 case 'raw_get_option':
2779
2780 $success = get_option( $opt_name, $default );
2781
2782 break;
2783
2784 case 'update':
2785 case 'update_option':
2786 case 'raw_update_option':
2787
2788 $old_value = get_option( $opt_name, $default );
2789
2790 $success = update_option( $opt_name, $value, $autoload );
2791
2792 break;
2793 }
2794
2795 $wp_filter = $saved_filter; // Restore filters.
2796 $wp_actions = $saved_actions; // Restore actions.
2797
2798 unset( $saved_filter, $saved_actions );
2799
2800 switch( $action ) {
2801
2802 case 'update':
2803 case 'update_option':
2804 case 'raw_update_option':
2805
2806 switch( $opt_name ) {
2807
2808 case 'home':
2809
2810 do_action( 'sucom_update_option_' . $opt_name, $old_value, $value, $opt_name );
2811
2812 break;
2813 }
2814
2815 break;
2816 }
2817
2818 return $success;
2819 }
2820
2821 /*
2822 * Last synchronized with WordPress v6.6.2 on 2024/09/30.
2823 *
2824 * See https://core.trac.wordpress.org/browser/tags/6.6.2/src/wp-includes/option.php#L1348
2825 */
2826 public static function raw_delete_transient( $transient ) {
2827
2828 if ( wp_using_ext_object_cache() || wp_installing() ) {
2829
2830 $result = wp_cache_delete( $transient, 'transient' );
2831
2832 } else {
2833
2834 $option_timeout = '_transient_timeout_' . $transient;
2835 $option = '_transient_' . $transient;
2836 $result = delete_option( $option );
2837
2838 if ( $result ) {
2839
2840 delete_option( $option_timeout );
2841 }
2842 }
2843
2844 return $result;
2845 }
2846
2847 /*
2848 * Last synchronized with WordPress v6.6.2 on 2024/09/30.
2849 *
2850 * See https://core.trac.wordpress.org/browser/tags/6.6.2/src/wp-includes/option.php#L1399.
2851 */
2852 public static function raw_get_transient( $transient ) {
2853
2854 if ( wp_using_ext_object_cache() || wp_installing() ) {
2855
2856 $value = wp_cache_get( $transient, 'transient' );
2857
2858 } else {
2859
2860 $transient_option = '_transient_' . $transient;
2861
2862 if ( ! wp_installing() ) {
2863
2864 /*
2865 * If option is not in alloptions, it is not autoloaded and thus has a timeout.
2866 */
2867 $alloptions = wp_load_alloptions();
2868
2869 if ( ! isset( $alloptions[ $transient_option ] ) ) {
2870
2871 $transient_timeout = '_transient_timeout_' . $transient;
2872
2873 $timeout = get_option( $transient_timeout ); // Returns false by default.
2874
2875 if ( false !== $timeout && $timeout < time() ) {
2876
2877 delete_option( $transient_option );
2878 delete_option( $transient_timeout );
2879
2880 $value = false;
2881 }
2882 }
2883 }
2884
2885 if ( ! isset( $value ) ) {
2886
2887 $value = get_option( $transient_option ); // Returns false by default.
2888 }
2889 }
2890
2891 return $value;
2892 }
2893
2894 /*
2895 * Last synchronized with WordPress v6.6.2 on 2024/09/30.
2896 *
2897 * See https://core.trac.wordpress.org/browser/tags/6.6.2/src/wp-includes/option.php#L1477.
2898 */
2899 public static function raw_set_transient( $transient, $value, $expiration = 0 ) {
2900
2901 $expiration = (int) $expiration;
2902
2903 if ( wp_using_ext_object_cache() || wp_installing() ) {
2904
2905 $result = wp_cache_set( $transient, $value, 'transient', $expiration );
2906
2907 } else {
2908
2909 $transient_timeout = '_transient_timeout_' . $transient;
2910 $transient_option = '_transient_' . $transient;
2911
2912 if ( false === get_option( $transient_option ) ) { // Returns false by default.
2913
2914 $autoload = 'yes';
2915
2916 /*
2917 * If we have an expiration time, do not autoload the transient.
2918 */
2919 if ( $expiration ) {
2920
2921 $autoload = 'no';
2922
2923 add_option( $transient_timeout, time() + $expiration, '', 'no' );
2924 }
2925
2926 $result = add_option( $transient_option, $value, '', $autoload );
2927
2928 } else {
2929
2930 /*
2931 * If an expiration time is provided, but the existing transient does not have a timeout
2932 * value, delete, then re-create the transient with an expiration time.
2933 */
2934 $update = true;
2935
2936 if ( $expiration ) {
2937
2938 if ( false === get_option( $transient_timeout ) ) { // Returns false by default.
2939
2940 delete_option( $transient_option );
2941
2942 add_option( $transient_timeout, time() + $expiration, '', 'no' );
2943
2944 $result = add_option( $transient_option, $value, '', 'no' );
2945
2946 $update = false;
2947
2948 } else {
2949
2950 update_option( $transient_timeout, time() + $expiration );
2951 }
2952 }
2953
2954 if ( $update ) {
2955
2956 $result = update_option( $transient_option, $value );
2957 }
2958 }
2959 }
2960
2961 return $result;
2962 }
2963 }
2964 }
2965