PluginProbe
WPSSO Core – Complete Schema Markup and Meta Tags / trunk
WPSSO Core – Complete Schema Markup and Meta Tags vtrunk
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 / wpsso.php

wpsso.php in WPSSO Core – Complete Schema Markup and Meta Tags trunk, at wpsso.php

882 lines 25.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * Plugin Name: WPSSO Core
4 * Plugin Slug: wpsso
5 * Text Domain: wpsso
6 * Domain Path: /languages
7 * Plugin URI: https://wpsso.com/extend/plugins/wpsso/
8 * Assets URI: https://surniaulula.github.io/wpsso/assets/
9 * Author: JS Morisset
10 * Author URI: https://wpsso.com/
11 * License: GPLv3
12 * License URI: https://www.gnu.org/licenses/gpl.txt
13 * Description: Present your content at its best for social sites and search results, no matter how URLs are shared, reshared, messaged, posted, embedded, or crawled.
14 * Requires PHP: 7.4.33
15 * Requires At Least: 6.0
16 * Tested Up To: 7.1
17 * WC Tested Up To: 11.1.0
18 * Version: 22.6.1
19 *
20 * Version Numbering: {major}.{minor}.{bugfix}[-{stage}.{level}]
21 *
22 * {major} Major structural code changes and/or incompatible API changes (ie. breaking changes).
23 * {minor} New functionality was added or improved in a backwards-compatible manner.
24 * {bugfix} Backwards-compatible bug fixes or small improvements.
25 * {stage}.{level} Pre-production release: dev < a (alpha) < b (beta) < rc (release candidate).
26 *
27 * Copyright 2012-2026 Jean-Sebastien Morisset (https://wpsso.com/)
28 */
29
30 if ( ! defined( 'ABSPATH' ) ) {
31
32 die( 'These aren\'t the droids you\'re looking for.' );
33 }
34
35 if ( ! class_exists( 'Wpsso' ) ) {
36
37 class Wpsso {
38
39 /*
40 * Library class object variables.
41 */
42 public $admin; // WpssoAdmin (admin menus and settings page loader) class object.
43 public $cache; // SucomCache (object and file caching) class object.
44 public $check; // WpssoCheck class object.
45 public $comment; // WpssoComment class object (extends WpssoAbstractWpMeta).
46 public $conflict; // WpssoConflict (admin plugin conflict checks) class object.
47 public $debug; // SucomDebug or SucomNoDebug class object.
48 public $edit; // WpssoEdit class object.
49 public $head; // WpssoHead class object.
50 public $loader; // WpssoLoader class object.
51 public $media; // WpssoMedia (images, videos, etc.) class object.
52 public $msgs; // WpssoMessages (admin tooltip messages) class object.
53 public $notice; // SucomNotice or SucomNoNotice class object.
54 public $opt; // WpssoOptions class object.
55 public $page; // WpssoPage (page title, desc, etc.) class object.
56 public $post; // WpssoPost class object (extends WpssoAbstractWpMeta).
57 public $reg; // WpssoRegister class object.
58 public $script; // WpssoScript (admin jquery tooltips) class object.
59 public $style; // WpssoStyle (admin styles) class object.
60 public $term; // WpssoTerm class object (extends WpssoAbstractWpMeta).
61 public $user; // WpssoUser class object (extends WpssoAbstractWpMeta).
62 public $util; // WpssoUtil (extends SucomUtil) class object.
63
64 /*
65 * Library class object variables for meta tags and markup.
66 */
67 public $link_rel; // WpssoLinkRel class object.
68 public $meta_name; // WpssoMetaName class object.
69 public $oembed; // WpssoOembed class object.
70 public $og; // WpssoOpenGraph class object.
71 public $pinterest; // WpssoPinterest class object.
72 public $schema; // WpssoSchema class object.
73 public $tc; // WpssoTwitterCard class object.
74
75 /*
76 * Reference variables (config, options, modules, etc.).
77 */
78 public $id = 'wpsso'; // Plugin id.
79 public $cf = array(); // Config array from WpssoConfig::get_config().
80 public $avail = array(); // Third-party plugin checks.
81 public $options = array(); // Blog options array.
82 public $site_options = array(); // Multisite options array.
83 public $sc = array(); // Loaded shortcode objects.
84
85 private static $instance = null; // Wpsso class object.
86
87 /*
88 * Wpsso constructor.
89 */
90 public function __construct() {
91
92 $plugin_file = __FILE__;
93 $plugin_dir = trailingslashit( dirname( $plugin_file ) );
94
95 require_once $plugin_dir . 'lib/config.php';
96
97 $this->cf = WpssoConfig::get_config();
98
99 WpssoConfig::set_constants( $plugin_file );
100
101 WpssoConfig::require_libs( $plugin_file ); // Includes the register.php class library.
102
103 $this->reg = new WpssoRegister( $this ); // Activate, deactivate, uninstall hooks.
104
105 /*
106 * The WordPress 'init' action fires after WordPress has finished loading, but before any headers are sent.
107 *
108 * Most of WordPress is loaded at this stage, and the user is authenticated. WordPress continues to load on
109 * the 'init' hook (e.g. widgets), and many plugins instantiate themselves on it for all sorts of reasons
110 * (e.g. they need a user, a taxonomy, etc.).
111 */
112 add_action( 'init', array( $this, 'set_config' ), WPSSO_INIT_CONFIG_PRIORITY ); // Runs at init -10.
113 add_action( 'widgets_init', array( $this, 'register_widgets' ), 10 ); // Runs at init 1.
114 add_action( 'init', array( $this, 'set_options' ), WPSSO_INIT_OPTIONS_PRIORITY ); // Runs at init 9.
115 add_action( 'init', array( $this, 'set_objects' ), WPSSO_INIT_OBJECTS_PRIORITY ); // Runs at init 10.
116 add_action( 'init', array( $this, 'init_shortcodes' ), WPSSO_INIT_SHORTCODES_PRIORITY ); // Runs at init 11.
117 add_action( 'init', array( $this, 'init_plugin' ), WPSSO_INIT_PLUGIN_PRIORITY ); // Runs at init 12.
118
119 /*
120 * The 'wpsso_init_textdomain' action is run after the $check, $avail, and $debug properties have been instantiated.
121 */
122 add_action( 'wpsso_init_textdomain', array( $this, 'init_textdomain' ), -1000, 0 );
123
124 /*
125 * The 'change_locale' action also runs the 'wpsso_init_textdomain' action.
126 */
127 add_action( 'change_locale', array( $this, 'change_locale' ), -1000, 1 );
128
129 /*
130 * If the "Use Plugin MO Translations" option is enabled, returns the file path to the plugin or add-on mo file.
131 */
132 add_filter( 'load_textdomain_mofile', array( $this, 'textdomain_mofile' ), 10, 3 );
133
134 /*
135 * Declare compatibility with WooCommerce features.
136 */
137 if ( ! empty( $this->cf[ 'plugin' ][ 'wpsso' ][ 'wc_compat' ] ) ) {
138
139 $wc_compat = $this->cf[ 'plugin' ][ 'wpsso' ][ 'wc_compat' ];
140
141 add_action( 'before_woocommerce_init', function () use ( $plugin_file, $wc_compat ) {
142
143 if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
144
145 foreach ( $wc_compat as $feature ) {
146
147 \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( $feature, $plugin_file, true );
148 }
149 }
150 }, 10, 0 );
151
152 unset( $wc_compat );
153 }
154
155 unset( $plugin_file, $plugin_dir );
156
157 }
158
159 public static function &get_instance() {
160
161 if ( null === self::$instance ) {
162
163 self::$instance = new self;
164 }
165
166 return self::$instance;
167 }
168
169 /*
170 * Force a refresh of the plugin config.
171 *
172 * Runs at init priority -10 and called by WpssoRegister->activate_plugin() as well.
173 */
174 public function set_config( $activate = false ) {
175
176 $this->cf = WpssoConfig::get_config( $read_cache = false );
177 }
178
179 /*
180 * Runs at init 1.
181 */
182 public function register_widgets() {
183
184 /*
185 * Load lib/widget/* library files.
186 */
187 $classnames = $this->get_lib_classnames( 'widget' ); // Always returns an array.
188
189 foreach ( $classnames as $id => $classname ) {
190
191 register_widget( $classname );
192 }
193 }
194
195 /*
196 * Runs at init priority 9.
197 *
198 * Called by WpssoRegister->activate_plugin() as well.
199 */
200 public function set_options( $activate = false ) {
201
202 if ( $activate && defined( 'WPSSO_RESET_ON_ACTIVATE' ) && WPSSO_RESET_ON_ACTIVATE ) {
203
204 delete_option( WPSSO_OPTIONS_NAME );
205
206 $this->options = false;
207
208 } else $this->options = get_option( WPSSO_OPTIONS_NAME );
209
210 if ( ! is_array( $this->options ) ) {
211
212 /*
213 * The set_options() action is run before the set_objects() action, where the WpssoOptions class is
214 * instantiated, so the WpssoOptions->get_defaults() method is not available yet. Load the defaults
215 * directly from the config array and trigget a defaults reload in set_objects().
216 */
217 $this->options = $this->cf[ 'opt' ][ 'defaults' ];
218
219 $this->options[ '__reload_defaults' ] = true;
220 }
221
222 if ( is_multisite() ) {
223
224 $this->site_options = get_site_option( WPSSO_SITE_OPTIONS_NAME );
225
226 if ( ! is_array( $this->site_options ) ) {
227
228 $this->site_options = $this->cf[ 'opt' ][ 'site_defaults' ];
229
230 $this->site_options[ '__reload_defaults' ] = true;
231 }
232
233 if ( is_array( $this->options ) && is_array( $this->site_options ) ) {
234
235 $blog_id = get_current_blog_id();
236
237 $defined_constants = get_defined_constants( $categorize = true );
238
239 foreach ( $this->site_options as $key => $val ) {
240
241 if ( false !== strpos( $key, ':use' ) ) {
242
243 continue;
244
245 } elseif ( isset( $this->site_options[ $key . ':use' ] ) ) {
246
247 switch ( $this->site_options[ $key . ':use' ] ) {
248
249 case 'force':
250
251 $this->options[ $key ] = $this->site_options[ $key ];
252 $this->options[ $key . ':disabled' ] = true;
253
254 break;
255
256 case 'empty': // Blank string, null, false, or 0.
257
258 if ( empty( $this->options[ $key ] ) ) {
259
260 $this->options[ $key ] = $this->site_options[ $key ];
261 }
262
263 break;
264 }
265 }
266
267 $constant_name = 'WPSSO_ID_' . $blog_id . '_OPT_' . strtoupper( $key );
268
269 if ( isset( $defined_constants[ 'user' ][ $constant_name ] ) ) {
270
271 $this->options[ $key ] = $defined_constants[ 'user' ][ $constant_name ];
272
273 $this->options[ $key . ':disabled' ] = true;
274 }
275 }
276 }
277 }
278 }
279
280 /*
281 * Runs at init priority 10.
282 *
283 * Called by WpssoRegister->activate_plugin() as well.
284 */
285 public function set_objects( $activate = false ) {
286
287 $is_doing = array(
288 'admin' => is_admin(),
289 'ajax' => SucomUtilWP::doing_ajax(),
290 'cron' => SucomUtilWP::doing_cron(),
291 'dev' => SucomUtilWP::doing_dev(),
292 );
293
294 /*
295 * Check for defined constants (in order):
296 *
297 * WPSSO_CRON_DEBUG_LOG
298 * WPSSO_CRON_DEBUG_HTML
299 * WPSSO_AJAX_DEBUG_LOG
300 * WPSSO_AJAX_DEBUG_HTML
301 * WPSSO_ADMIN_DEBUG_LOG
302 * WPSSO_ADMIN_DEBUG_HTML
303 * WPSSO_DEBUG_LOG
304 * WPSSO_DEBUG_HTML
305 */
306 $debug_log = $this->get_const_status( 'DEBUG_LOG', $is_doing );
307 $debug_html = $this->get_const_status( 'DEBUG_HTML', $is_doing );
308
309 $this->check = new WpssoCheck( $this );
310
311 $this->avail = $this->check->get_avail(); // Uses $this->options for availability checks.
312
313 /*
314 * Make sure a debug object variable is always available.
315 */
316 if ( null === $debug_html ) { // Constant not defined.
317
318 $debug_html = empty( $this->options[ 'plugin_debug_html' ] ) ? false : true;
319 }
320
321 if ( $debug_log || $debug_html ) {
322
323 require_once WPSSO_PLUGINDIR . 'lib/com/debug.php'; // Only load class when needed.
324
325 $this->debug = new SucomDebug( $this, array(
326 'log' => $debug_log,
327 'html' => $debug_html,
328 ) );
329
330 if ( $this->debug->enabled ) {
331
332 global $wp_version;
333
334 $this->debug->log( __METHOD__ . ' init ' . WPSSO_INIT_OBJECTS_PRIORITY );
335 $this->debug->log( 'debug enabled on ' . gmdate( 'c' ) );
336 $this->debug->log( 'PHP version ' . phpversion() );
337 $this->debug->log( 'WP version ' . $wp_version );
338 $this->debug->log( 'WP home URL ' . get_home_url() );
339 $this->debug->log( 'WP site URL ' . get_site_url() );
340 $this->debug->log_arr( 'generator', $this->check->get_ext_gen_list() );
341 $this->debug->log_arr( 'avail', $this->avail );
342 }
343
344 } else $this->debug = new SucomNoDebug(); // Class always loaded in WpssoConfig::require_libs().
345
346 if ( $this->debug->enabled ) {
347
348 $this->debug->mark_diff( 'debug class loaded' );
349 }
350
351 /*
352 * The 'wpsso_init_textdomain' action is run after the $check, $avail, and $debug properties have been instantiated.
353 *
354 * The WordPress 'change_locale' action also runs the 'wpsso_init_textdomain' action.
355 */
356 do_action( 'wpsso_init_textdomain' );
357
358 /*
359 * Make sure a notice object variable is always available.
360 */
361 if ( $is_doing[ 'admin' ] || $is_doing[ 'cron' ] ) {
362
363 require_once WPSSO_PLUGINDIR . 'lib/messages.php'; // Only load class when needed.
364 require_once WPSSO_PLUGINDIR . 'lib/com/notice.php'; // Only load class when needed.
365
366 $this->msgs = new WpssoMessages( $this ); // Admin tooltip messages.
367 $this->notice = new SucomNotice( $this );
368
369 } else $this->notice = new SucomNoNotice(); // Class always loaded in WpssoConfig::require_libs().
370
371 if ( $this->debug->enabled ) {
372
373 $this->debug->mark_diff( 'notice class loaded' );
374 }
375
376 $this->cache = new SucomCache( $this );
377 $this->util = new WpssoUtil( $this ); // Extends SucomUtil.
378 $this->opt = new WpssoOptions( $this );
379
380 do_action( 'wpsso_init_options' );
381
382 $this->script = new WpssoScript( $this );
383 $this->style = new WpssoStyle( $this );
384
385 /*
386 * Note that when running a cron task, admin is false.
387 */
388 if ( $is_doing[ 'admin' ] ) {
389
390 require_once WPSSO_PLUGINDIR . 'lib/admin.php'; // Only load class when needed.
391 require_once WPSSO_PLUGINDIR . 'lib/conflict.php'; // Only load class when needed.
392 require_once WPSSO_PLUGINDIR . 'lib/edit.php'; // Only load class when needed.
393 require_once WPSSO_PLUGINDIR . 'lib/com/form.php'; // Only load class when needed.
394
395 $this->admin = new WpssoAdmin( $this ); // Admin menus and settings pages.
396 $this->conflict = new WpssoConflict( $this ); // Admin plugin conflict checks.
397 $this->edit = new WpssoEdit( $this ); // Admin editing page metabox.
398 }
399
400 /*
401 * Setup media and module classes:
402 *
403 * $comment
404 * $media
405 * $page
406 * $post
407 * $term
408 * $user
409 */
410 $this->comment = new WpssoComment( $this ); // Extends WpssoAbstractWpMeta.
411 $this->media = new WpssoMedia( $this );
412 $this->page = new WpssoPage( $this );
413 $this->post = new WpssoPost( $this ); // Extends WpssoAbstractWpMeta.
414 $this->term = new WpssoTerm( $this ); // Extends WpssoAbstractWpMeta.
415 $this->user = new WpssoUser( $this ); // Extends WpssoAbstractWpMeta.
416
417 if ( $this->debug->enabled ) {
418
419 $this->debug->mark_diff( 'media and module classes loaded' );
420 }
421
422 /*
423 * Setup classe for meta tags and Schema markup:
424 *
425 * $head
426 * $link_rel
427 * $meta_name
428 * $og
429 * $pinterest
430 * $schema
431 * $tc
432 * $loader
433 */
434 $this->head = new WpssoHead( $this );
435 $this->link_rel = new WpssoLinkRel( $this ); // Link relation tags.
436 $this->meta_name = new WpssoMetaName( $this ); // Meta name tags.
437 $this->oembed = new WpssoOembed( $this ); // Oembed response data.
438 $this->og = new WpssoOpenGraph( $this ); // Open Graph meta tags.
439 $this->pinterest = new WpssoPinterest( $this ); // Pinterest image markup.
440 $this->schema = new WpssoSchema( $this ); // Schema json data.
441 $this->tc = new WpssoTwitterCard( $this ); // X (Twitter) Card meta tags.
442
443 if ( $this->debug->enabled ) {
444
445 $this->debug->mark_diff( 'meta tags and schema classes loaded' );
446 }
447
448 do_action( 'wpsso_init_objects_preloader' );
449
450 $this->loader = new WpssoLoader( $this ); // Modules loader.
451
452 do_action( 'wpsso_init_objects' );
453
454 if ( $this->debug->enabled ) {
455
456 $this->debug_reminder( $is_doing );
457
458 $this->debug->mark_diff( 'objects defined' );
459 }
460 }
461
462 /*
463 * Runs at init priority 11.
464 */
465 public function init_shortcodes() {
466
467 if ( $this->debug->enabled ) {
468
469 $this->debug->mark( 'init shortcodes' ); // Begin timer.
470 }
471
472 /*
473 * Load lib/shortcode/* library files.
474 */
475 $classnames = $this->get_lib_classnames( 'shortcode' ); // Always returns an array.
476
477 foreach ( $classnames as $id => $classname ) {
478
479 /*
480 * Note that Wpsso->sc[ 'schema' ] is used by WpssoSscFilters->filter_json_data_graph_element().
481 */
482 if ( ! isset( $this->sc[ $id ] ) ) { // Just in case.
483
484 $this->sc[ $id ] = new $classname( $this );
485
486 if ( $this->debug->enabled ) {
487
488 $this->debug->mark_diff( 'added ' . $id . ' shortcode' );
489 }
490 }
491 }
492
493 if ( $this->debug->enabled ) {
494
495 $this->debug->mark( 'init shortcodes' ); // Begin timer.
496 }
497 }
498
499 /*
500 * Runs at init priority 12.
501 */
502 public function init_plugin() {
503
504 if ( $this->debug->enabled ) {
505
506 $this->debug_hooks();
507 }
508
509 /*
510 * All WPSSO Core objects are instantiated and configured.
511 *
512 * See SucomAbstractAddOn->init_plugin_notices().
513 */
514 do_action( 'wpsso_init_plugin' );
515 }
516
517 /*
518 * The 'wpsso_init_textdomain' action is run after the $check, $avail, and $debug properties are instantiated.
519 */
520 public function init_textdomain() {
521
522 load_plugin_textdomain( 'wpsso', false, 'wpsso/languages/' );
523 }
524
525 /*
526 * The 'change_locale' action also runs the 'wpsso_init_textdomain' action.
527 */
528 public function change_locale( $locale ) {
529
530 do_action( 'wpsso_init_textdomain' );
531 }
532
533 /*
534 * If the "Use Plugin MO Translations" option is enabled, returns the file path to the plugin or add-on mo file.
535 */
536 public function textdomain_mofile( $wp_mofile, $domain ) {
537
538 if ( empty( $this->options[ 'plugin_load_mofiles' ] ) ) { // Nothing to do.
539
540 return $wp_mofile;
541 }
542
543 if ( 0 === strpos( $domain, 'wpsso' ) ) { // Optimize.
544
545 foreach ( $this->cf[ 'plugin' ] as $ext => $info ) {
546
547 if ( empty( $info[ 'slug' ] ) ) { // Just in case.
548
549 continue;
550
551 } elseif ( $domain === $info[ 'slug' ] ) {
552
553 $languages_mofile = 'languages/' . basename( $wp_mofile );
554
555 if ( $plugin_mofile = WpssoConfig::get_ext_file_path( $ext, $languages_mofile ) ) {
556
557 global $l10n;
558
559 unset( $l10n[ $domain ] ); // Prevent merging.
560
561 return $plugin_mofile;
562 }
563
564 break; // Stop here.
565 }
566 }
567 }
568
569 return $wp_mofile;
570 }
571
572 /*
573 * Check for defined constants (in order):
574 *
575 * WPSSO_CRON_DEBUG_LOG
576 * WPSSO_CRON_DEBUG_HTML
577 * WPSSO_AJAX_DEBUG_LOG
578 * WPSSO_AJAX_DEBUG_HTML
579 * WPSSO_ADMIN_DEBUG_LOG
580 * WPSSO_ADMIN_DEBUG_HTML
581 * WPSSO_DEBUG_LOG
582 * WPSSO_DEBUG_HTML
583 *
584 * See Wpsso->get_const_status().
585 * See Wpsso->get_const_status_transl().
586 */
587 public function get_const( $const_suffix, $is_doing = null ) {
588
589 if ( ! is_array( $is_doing ) ) {
590
591 $is_doing = array(
592 'admin' => is_admin(),
593 'ajax' => SucomUtilWP::doing_ajax(),
594 'cron' => SucomUtilWP::doing_cron(),
595 'dev' => SucomUtilWP::doing_dev(),
596 );
597 }
598
599 if ( $is_doing[ 'cron' ] && defined( 'WPSSO_CRON_' . $const_suffix ) ) {
600
601 return 'WPSSO_CRON_' . $const_suffix;
602
603 } elseif ( $is_doing[ 'ajax' ] && defined( 'WPSSO_AJAX_' . $const_suffix ) ) {
604
605 return 'WPSSO_AJAX_' . $const_suffix;
606
607 } elseif ( $is_doing[ 'admin' ] && defined( 'WPSSO_ADMIN_' . $const_suffix ) ) {
608
609 return 'WPSSO_ADMIN_' . $const_suffix;
610
611 } elseif ( defined( 'WPSSO_' . $const_suffix ) ) {
612
613 return 'WPSSO_' . $const_suffix;
614 }
615
616 return null; // Constant not defined.
617 }
618
619 /*
620 * See Wpsso->set_objects().
621 * See WpssoSubmenuAdvanced->get_table_rows().
622 */
623 public function get_const_status( $const_suffix, $is_doing = null ) {
624
625 $const_name = $this->get_const( $const_suffix, $is_doing ); // Returns null if constant not defined.
626
627 return $const_name ? constant( $const_name ) : null;
628 }
629
630 /*
631 * See WpssoSubmenuAdvanced->get_table_rows().
632 */
633 public function get_const_status_transl( $const_suffix, $is_doing = null ) {
634
635 $const_name = $this->get_const( $const_suffix, $is_doing ); // Returns null if constant not defined.
636
637 if ( $const_name ) {
638
639 if ( constant( $const_name ) ) {
640
641 return sprintf( _x( '(%s constant is true)', 'option comment', 'wpsso' ), $const_name );
642 }
643
644 return sprintf( _x( '(%s constant is false)', 'option comment', 'wpsso' ), $const_name );
645 }
646
647 return '';
648 }
649
650 public function get_lib_classnames( $type_dir ) {
651
652 $classnames = array();
653
654 foreach ( $this->cf[ 'plugin' ] as $ext => $info ) {
655
656 if ( ! isset( $info[ 'lib' ][ $type_dir ] ) ) {
657
658 continue;
659
660 } elseif ( ! is_array( $info[ 'lib' ][ $type_dir ] ) ) {
661
662 continue;
663 }
664
665 foreach ( $info[ 'lib' ][ $type_dir ] as $sub_dir => $libs ) {
666
667 if ( is_array( $libs ) ) {
668
669 /*
670 * Skip loading admin library modules if not in admin back-end.
671 */
672 if ( 'admin' === $sub_dir && ! is_admin() ) {
673
674 continue;
675 }
676
677 foreach ( $libs as $id => $label ) {
678
679 $lib_path = $type_dir . '/' . $sub_dir . '/' . $id;
680
681 $classname = apply_filters( $ext . '_load_lib', false, $lib_path );
682
683 if ( is_string( $classname ) && class_exists( $classname ) ) {
684
685 $classnames[ $sub_dir . '-' . $id ] = $classname;
686 }
687 }
688
689 } elseif ( is_string( $libs ) ) {
690
691 $id = $sub_dir;
692 $label = $libs;
693 $lib_path = $type_dir . '/' . $id;
694 $classname = apply_filters( $ext . '_load_lib', false, $lib_path );
695
696 if ( is_string( $classname ) && class_exists( $classname ) ) {
697
698 $classnames[ $id ] = $classname;
699 }
700 }
701 }
702 }
703
704 return $classnames;
705 }
706
707 public function get_options( $opt_key = false, $def_value = null ) {
708
709 if ( false !== $opt_key ) {
710
711 if ( isset( $this->options[ $opt_key ] ) ) {
712
713 return $this->options[ $opt_key ];
714 }
715
716 return $def_value;
717 }
718
719 return $this->options;
720 }
721
722 public function debug_hooks() {
723
724 /*
725 * Show debug messages after the head and footer sections.
726 *
727 * Do not include the "shutdown" action as that would create HTML after the html closing tag.
728 */
729 foreach ( array( 'wp_head', 'wp_footer', 'admin_head', 'admin_footer' ) as $action ) {
730
731 add_action( $action, array( $this, 'show_debug' ), PHP_INT_MAX );
732 }
733
734 /*
735 * Show plugin settings just after the footer section.
736 */
737 foreach ( array( 'wp_footer', 'admin_footer' ) as $action ) {
738
739 add_action( $action, array( $this, 'show_config' ), PHP_INT_MAX );
740 }
741 }
742
743 /*
744 * Only runs when debug is enabled.
745 */
746 public function show_debug() {
747
748 echo "\n\n" . '<!-- wpsso doing action "' . current_action() . '" -->' . "\n\n";
749
750 $this->debug->show_html( null, 'debug log' );
751 }
752
753 /*
754 * Only runs when debug is enabled.
755 */
756 public function show_config() {
757
758 if ( ! $this->debug->enabled ) { // Just in case.
759
760 return;
761 }
762
763 $this->debug->mark();
764
765 /*
766 * Show constants.
767 */
768 $defined_constants = get_defined_constants( $categorize = true );
769 $defined_constants[ 'user' ][ 'WPSSO_NONCE_NAME' ] = '********';
770
771 if ( is_multisite() ) {
772
773 $this->debug->log_arr( 'multisite constants', SucomUtil::preg_grep_keys( '/^(MULTISITE|^SUBDOMAIN_INSTALL|.*_SITE)$/',
774 $defined_constants[ 'user' ] ) );
775 }
776
777 $this->debug->log_arr( 'wpsso constants', SucomUtil::preg_grep_keys( '/^WPSSO_/', $defined_constants[ 'user' ] ) );
778
779 /*
780 * Show active plugins.
781 */
782 $this->debug->log_arr( 'active plugins', SucomPlugin::get_active_plugins() );
783
784 /*
785 * Show available modules.
786 */
787 $this->debug->log_arr( 'available features', $this->avail );
788
789 /*
790 * Show all plugin options.
791 */
792 $opts = $this->options;
793
794 foreach ( $opts as $key => $val ) {
795
796 switch ( $key ) {
797
798 case ( false !== strpos( $key, '_js_' ) ? true : false ):
799 case ( false !== strpos( $key, '_css_' ) ? true : false ):
800 case ( preg_match( '/(_css|_js|_html)$/', $key ) ? true : false ):
801 case ( preg_match( '/_(key|secret|tid|token)$/', $key ) ? true : false ):
802
803 if ( '' !== $opts[ $key ] ) $opts[ $key ] = '[removed]';
804
805 break;
806 }
807 }
808
809 $this->debug->log_arr( 'wpsso settings', $opts );
810
811 $this->debug->mark();
812
813 $this->debug->show_html();
814 }
815
816 private function debug_reminder( array $is_doing ) {
817
818 if ( $this->debug->is_enabled( 'log' ) ) {
819
820 $this->debug->log( 'WP debug log mode is active' );
821 }
822
823 if ( $this->debug->is_enabled( 'html' ) ) {
824
825 $this->debug->log( 'HTML debug mode is active' );
826 }
827
828 if ( $is_doing[ 'admin' ] && ! $is_doing[ 'dev' ] ) {
829
830 $info = $this->cf[ 'plugin' ][ 'wpsso' ];
831 $notice_msg = '';
832 $notice_key = 'debug-mode-is-active';
833 $dismiss_time = 12 * HOUR_IN_SECONDS;
834
835 if ( $this->debug->is_enabled( 'log' ) ) {
836
837 $notice_key .= '-with-debug-log';
838
839 $notice_msg .= __( 'WP debug logging mode is active - debug messages are being sent to the WordPress debug log.', 'wpsso' ) . ' ';
840 }
841
842 if ( $this->debug->is_enabled( 'html' ) ) {
843
844 $notice_key .= '-with-html-comments';
845
846 $notice_msg .= __( 'HTML debug mode is active - debug messages are being added to webpages as hidden HTML comments.', 'wpsso' ) . ' ';
847 }
848
849 /*
850 * WP debug logging and/or HTML debug mode is active.
851 */
852 if ( $notice_msg ) {
853
854 $notice_msg .= sprintf( __( 'The %s plugin\'s debug mode generates thousands of messages during page load, which affects website performance.', 'wpsso' ), $info[ 'name' ] ) . ' ';
855
856 $notice_msg .= __( 'Don\'t forget to disable debug mode when debugging is complete.', 'wpsso' );
857
858 $this->notice->warn( $notice_msg, null, $notice_key, $dismiss_time );
859 }
860
861 /*
862 * WPSSO_CACHE_DISABLE constant is true or the 'plugin_cache_disable' option is checked.
863 */
864 if ( $this->util->cache->is_disabled() ) {
865
866 $notice_msg = sprintf( __( 'The %s plugin\'s cache feature is disabled for debugging, which affects website performance.', 'wpsso' ), $info[ 'name' ] ) . ' ';
867
868 $notice_msg .= __( 'Don\'t forget to re-enable caching when debugging is complete.', 'wpsso' );
869
870 $notice_key = 'plugin-cache-is-disabled';
871
872 $this->notice->warn( $notice_msg, null, $notice_key, $dismiss_time );
873 }
874 }
875 }
876 }
877
878 global $wpsso;
879
880 $wpsso =& Wpsso::get_instance();
881 }
882