|
@@ -1,0 +1,881 @@ |
|
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.7.0 |
|
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
|
+} |