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
← All changes | lib/com/util-wp.php +2964 -0 22.5.222.7.0 View file →
@@ -1,0 +1,2964 @@
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 +}