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

admin-head.php in WPSSO Core – Complete Schema Markup and Meta Tags 22.7.0, at lib/admin-head.php

466 lines 15.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * License: GPLv3
4 * License URI: https://www.gnu.org/licenses/gpl.txt
5 * Copyright 2012-2026 Jean-Sebastien Morisset (https://wpsso.com/)
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9
10 die( 'These aren\'t the droids you\'re looking for.' );
11 }
12
13 if ( ! defined( 'WPSSO_PLUGINDIR' ) ) {
14
15 die( 'Do. Or do not. There is no try.' );
16 }
17
18 if ( ! class_exists( 'WpssoAdminHead' ) ) {
19
20 class WpssoAdminHead {
21
22 private $p; // Wpsso class object.
23
24 /*
25 * Instantiated by WpssoAdmin->__construct().
26 */
27 public function __construct( &$plugin ) {
28
29 $this->p =& $plugin;
30
31 if ( $this->p->debug->enabled ) {
32
33 $this->p->debug->mark();
34 }
35
36 $doing_ajax = SucomUtilWP::doing_ajax();
37
38 if ( ! $doing_ajax ) {
39
40 require_once WPSSO_PLUGINDIR . 'lib/admin-head-suggest.php';
41
42 new WpssoAdminHeadSuggest( $plugin );
43
44 add_action( 'admin_head', array( $this, 'wp_config_check' ), -300 );
45 add_action( 'admin_head', array( $this, 'wp_php_versions' ), -200 ); // Requires 'manage_options' capability.
46 add_action( 'admin_head', array( $this, 'pending_updates' ), -100 ); // Requires 'update_plugins' capability.
47 add_action( 'admin_head', array( $this->p->util, 'log_is_functions' ), 10 );
48 add_action( 'admin_head', array( $this->p->util->cache, 'show_admin_notices' ), -1000 );
49 add_action( 'admin_head', array( $this, 'timed_notices' ), 200 ); // Requires 'manage_options' capability.
50 }
51 }
52
53 public function wp_config_check() {
54
55 if ( $this->p->debug->enabled ) {
56
57 $this->p->debug->mark();
58 }
59
60 $user_id = get_current_user_id();
61
62 if ( ! $user_id ) { // Nobody there.
63
64 return; // Stop here.
65 }
66
67 global $wp_version;
68
69 /*
70 * Skip if a previous config check for this WordPress version was successful.
71 */
72 if ( $wp_version === get_option( WPSSO_WP_CONFIG_CHECK_NAME, $default = false ) ) {
73
74 return; // Stop here.
75 }
76
77 /*
78 * Check for a PHP variable in the WP_HOME constant value.
79 */
80 if ( $file_path = SucomUtilWP::get_wp_config_file_path() ) {
81
82 $stripped_php = SucomUtil::get_stripped_php( $file_path );
83
84 if ( preg_match( '/define\( *[\'"]WP_HOME[\'"][^\)]*\$/', $stripped_php ) ) {
85
86 $notice_key = 'notice-wp-config-php-variable-home';
87
88 $notice_msg = $this->p->msgs->get( $notice_key );
89
90 $this->p->notice->err( $notice_msg, $user_id, $notice_key );
91
92 return; // Stop here.
93 }
94 }
95
96 /*
97 * Check for an IP address in the home URL value.
98 */
99 $is_public = get_option( 'blog_public' );
100
101 if ( $is_public ) {
102
103 $home_url = SucomUtilWP::raw_get_home_url();
104
105 if ( preg_match( '/^([a-z]+):\/\/([0-9\.]+)(:[0-9]+)?$/i', $home_url ) ) {
106
107 $general_settings_url = get_admin_url( $blog_id = null, 'options-general.php' );
108 $reading_settings_url = get_admin_url( $blog_id = null, 'options-reading.php' );
109
110 $notice_msg = sprintf( __( 'The WordPress <a href="%1$s">Search Engine Visibility</a> option is set to allow search engines and social sites to access this site, but your <a href="%2$s">Site Address URL</a> value is an IP address (%3$s).', 'wpsso' ), $reading_settings_url, $general_settings_url, $home_url ) . ' ';
111
112 $notice_msg .= __( 'Please update your Search Engine Visibility option to discourage search engines from indexing this site, or use a fully qualified domain name as your Site Address URL.', 'wpsso' );
113
114 $notice_key = 'notice-wp-config-home-url-ip-address';
115
116 $this->p->notice->warn( $notice_msg, $user_id, $notice_key );
117
118 return; // Stop here.
119 }
120 }
121
122 /*
123 * Mark the config check for this WordPress version as successful.
124 */
125 update_option( WPSSO_WP_CONFIG_CHECK_NAME, $wp_version, $autoload = false );
126 }
127
128 public function wp_php_versions() {
129
130 if ( current_user_can( 'manage_options' ) ) {
131
132 $user_id = get_current_user_id();
133
134 foreach ( array( 'wp', 'php' ) as $key ) {
135
136 if ( isset( WpssoConfig::$cf[ $key ][ 'rec_version' ] ) ) {
137
138 switch ( $key ) {
139
140 case 'wp':
141
142 global $wp_version;
143
144 $app_version = $wp_version;
145 $dismiss_time = MONTH_IN_SECONDS;
146
147 break;
148
149 case 'php':
150
151 $app_version = phpversion();
152 $dismiss_time = 3 * MONTH_IN_SECONDS;
153
154 break;
155
156 default:
157
158 continue 2; // Get another $key.
159 }
160
161 $app_label = WpssoConfig::$cf[ $key ][ 'label' ];
162 $rec_version = WpssoConfig::$cf[ $key ][ 'rec_version' ];
163
164 if ( version_compare( $app_version, $rec_version, '<' ) ) {
165
166 $warn_msg = $this->p->msgs->get( 'notice-recommend-version', array(
167 'app_label' => $app_label,
168 'app_version' => $app_version,
169 'rec_version' => WpssoConfig::$cf[ $key ][ 'rec_version' ],
170 'version_url' => WpssoConfig::$cf[ $key ][ 'version_url' ],
171 ) );
172
173 $notice_key = 'notice-recommend-version-' . $key . '-' . $rec_version;
174
175 $this->p->notice->warn( $warn_msg, $user_id, $notice_key, $dismiss_time );
176 }
177 }
178 }
179 }
180 }
181
182 /*
183 * Show a notice if there are pending WPSSO plugin updates and the user can update plugins.
184 */
185 public function pending_updates() {
186
187 if ( current_user_can( 'update_plugins' ) ) {
188
189 $update_count = SucomPlugin::get_update_count( $plugin_prefix = 'wpsso' );
190
191 if ( $update_count > 0 ) {
192
193 $p_info = $this->p->cf[ 'plugin' ][ 'wpsso' ];
194 $p_name_transl = _x( $p_info[ 'name' ], 'plugin name', 'wpsso' );
195 $notice_key = 'pending-updates-for-wpsso-and-addons';
196 $dismiss_time = MONTH_IN_SECONDS;
197
198 $notice_msg = sprintf( _n( 'There is <a href="%1$s">%2$d pending update for the %3$s plugin and its add-on(s)</a>.',
199 'There are <a href="%1$s">%2$d pending updates for the %3$s plugin and its add-on(s)</a>.', $update_count, 'wpsso' ),
200 self_admin_url( 'update-core.php' ), $update_count, $p_name_transl ) . ' ';
201
202 $notice_msg .= _n( 'Please install this update at your earliest convenience.',
203 'Please install these updates at your earliest convenience.', $update_count, 'wpsso' );
204
205 $this->p->notice->inf( $notice_msg, null, $notice_key, $dismiss_time );
206 }
207 }
208 }
209
210 /*
211 * Show a single notice at a time.
212 */
213 public function timed_notices() {
214
215 if ( current_user_can( 'manage_options' ) ) {
216
217 if ( ! $this->single_notice_review() ) {
218
219 if ( ! $this->single_notice_upsell() ) {
220
221 // Add more timed notices here as needed.
222 }
223 }
224 }
225 }
226
227 /*
228 * This method is called by timed_notices() if WordPress can dismiss notices and the user can manage options.
229 *
230 * These private notice functions should return the number of notices shown.
231 */
232 private function single_notice_review() {
233
234 $form = $this->p->admin->get_form_object( $menu_ext = 'wpsso' ); // Return and maybe set/reset the WpssoAdmin->form value.
235 $user_id = get_current_user_id();
236 $ext_reg = $this->p->util->reg->get_ext_reg();
237 $week_ago_secs = time() - ( 1 * WEEK_IN_SECONDS );
238 $dismiss_time = true; // Allow the notice to be dismissed forever.
239
240 /*
241 * Use the transient cache to show only one notice per day.
242 */
243 $cache_md5_pre = 'wpsso_';
244 $cache_exp_secs = DAY_IN_SECONDS;
245 $cache_salt = __METHOD__ . '(user_id:' . $user_id . ')';
246 $cache_id = $cache_md5_pre . md5( $cache_salt );
247
248 $showing_ext = get_transient( $cache_id ); // Returns an empty string or the $notice_key value.
249
250 foreach ( $this->p->cf[ 'plugin' ] as $ext => $ext_info ) {
251
252 if ( empty( $ext_info[ 'name' ] ) ) { // Just in case.
253
254 continue;
255 }
256
257 $p_info = $this->p->cf[ 'plugin' ][ 'wpsso' ];
258 $p_name_transl = _x( $p_info[ 'name' ], 'plugin name', 'wpsso' );
259 $ext_name_transl = _x( $ext_info[ 'name' ], 'plugin name', 'wpsso' );
260 $ext_desc_transl = _x( $ext_info[ 'desc' ], 'plugin description', 'wpsso' );
261
262 /*
263 * Make sure the plugin is installed (ie. it has a version number).
264 */
265 if ( empty( $ext_info[ 'version' ] ) ) {
266
267 continue; // Get the next plugin.
268 }
269
270 /*
271 * Make sure we have wordpress.org review URL.
272 */
273 if ( empty( $ext_info[ 'url' ][ 'review' ] ) ) {
274
275 continue; // Get the next plugin.
276 }
277
278 /*
279 * The user has already dismissed this notice.
280 */
281 $notice_key = 'timed-notice-' . $ext . '-plugin-review';
282
283 if ( $this->p->notice->is_dismissed( $notice_key, $user_id ) ) {
284
285 /*
286 * The single notice per day period has not expired yet.
287 */
288 if ( $showing_ext === $notice_key ) {
289
290 return 0; // Stop here.
291 }
292
293 continue; // Get the next plugin.
294
295 /*
296 * Make sure we have an activation time.
297 */
298 } elseif ( empty( $ext_reg[ $ext . '_activate_time' ] ) ) {
299
300 continue; // Get the next plugin.
301
302 /*
303 * Activated less than a week ago.
304 */
305 } elseif ( $ext_reg[ $ext . '_activate_time' ] > $week_ago_secs ) {
306
307 continue; // Get the next plugin.
308
309 /*
310 * Make sure we only show this single notice for the next day.
311 */
312 } elseif ( empty( $showing_ext ) || $showing_ext === '1' ) {
313
314 set_transient( $cache_id, $notice_key, $cache_exp_secs );
315
316 /*
317 * We're not showing this plugin right now.
318 */
319 } elseif ( $showing_ext !== $notice_key ) {
320
321 continue; // Get the next plugin.
322 }
323
324 $activated_ago = human_time_diff( time(), $ext_reg[ $ext . '_activate_time' ] );
325 $ext_type_transl = WpssoConfig::get_ext_type_transl( $ext );
326 $wp_plugin_link = '<a href="' . $ext_info[ 'url' ][ 'home' ] . '">' . $ext_name_transl . '</a>';
327 $wp_plugin_link_desc = $wp_plugin_link . ' (' . trim( $ext_desc_transl, '.' ) . ')';
328
329 /*
330 * Rate plugin action button.
331 */
332 $rate_plugin_label = sprintf( __( 'Rate the %1$s %2$s', 'wpsso' ), $ext_info[ 'short' ], $ext_type_transl );
333 $rate_plugin_clicked = '<p>' . __( 'Thank you!', 'wpsso' ) . '</p>';
334 $rate_plugin_button = '<div class="notice-single-button">' . $form->get_button( $rate_plugin_label, 'button-primary dismiss-on-click',
335 '', $ext_info[ 'url' ][ 'review' ], true, false, array( 'dismiss-msg' => $rate_plugin_clicked ) ) . '</div>';
336
337 /*
338 * Already rated action button.
339 */
340 $already_rated_label = sprintf( __( 'I\'ve already rated the %2$s', 'wpsso' ), $ext_info[ 'short' ], $ext_type_transl );
341 $already_rated_clicked = '<p>' . __( 'Thank you!', 'wpsso' ) . '</p>';
342 $already_rated_button = '<div class="notice-single-button">' . $form->get_button( $already_rated_label, 'button-secondary dismiss-on-click',
343 '', '', false, false, array( 'dismiss-msg' => $already_rated_clicked ) ) . '</div>';
344
345 /*
346 * The notice message.
347 */
348 $notice_msg = '<div style="display:table-cell;">';
349 $notice_msg .= '<p style="margin-right:30px;">' . $this->p->admin->get_ext_img_icon( $ext ) . '</p>';
350 $notice_msg .= '</div>';
351 $notice_msg .= '<div style="display:table-cell;vertical-align:top;">';
352 $notice_msg .= '<p><strong>';
353
354 // translators: %1$s is the plugin name, %2$s is the plugin type (ie. "plugin" or "add-on"), and %3$s is a measure of time.
355 $notice_msg .= sprintf( __( 'The %1$s %2$s was activated %3$s ago.', 'wpsso' ),
356 $wp_plugin_link, $ext_type_transl, $activated_ago ) . ' ';
357
358 $notice_msg .= '</strong></p><p>';
359
360 // translators: %1$s is the plugin type (ie. "plugin" or "add-on").
361 $notice_msg .= sprintf( __( 'Please encourage your %1$s %2$s developers by rating the %2$s.', 'wpsso' ),
362 $wp_plugin_link, $ext_type_transl ) . ' ';
363
364 $notice_msg .= '</p><p>';
365
366 // translators: %1$s is the plugin type (ie. "plugin" or "add-on").
367 $notice_msg .= sprintf( __( 'It only takes a moment, and it really does encourage us to keep improving the %1$s.', 'wpsso' ),
368 $ext_type_transl ) . ' ' . convert_smilies( ':-)' ) . ' ';
369
370 $notice_msg .= '</p>';
371 $notice_msg .= '<div class="notice-actions">';
372 $notice_msg .= $rate_plugin_button . $already_rated_button;
373 $notice_msg .= '</div>';
374 $notice_msg .= '</div>';
375
376 $this->p->notice->nag( $notice_msg, $user_id, $notice_key, $dismiss_time );
377
378 return 1; // Show only one notice at a time.
379 }
380
381 return 0;
382 }
383
384 /*
385 * This method is called by timed_notices() if WordPress can dismiss notices and the user can manage options.
386 *
387 * These private notice functions should return the number of notices shown.
388 */
389 private function single_notice_upsell() {
390
391 $pkg_info = $this->p->util->get_pkg_info(); // Uses a local cache.
392
393 if ( $pkg_info[ 'wpsso' ][ 'pdir' ] ) {
394
395 return 0;
396 }
397
398 $ext_reg = $this->p->util->reg->get_ext_reg();
399 $months_ago_secs = time() - ( 2 * MONTH_IN_SECONDS );
400
401 if ( empty( $ext_reg[ 'wpsso_install_time' ] ) || $ext_reg[ 'wpsso_install_time' ] > $months_ago_secs ) {
402
403 return 0;
404 }
405
406 $form = $this->p->admin->get_form_object( $menu_ext = 'wpsso' ); // Return and maybe set/reset the WpssoAdmin->form value.
407 $user_id = get_current_user_id();
408 $p_info = $this->p->cf[ 'plugin' ][ 'wpsso' ];
409 $p_name_transl = _x( $p_info[ 'name' ], 'plugin name', 'wpsso' );
410 $p_purchase_url = $p_info[ 'url' ][ 'purchase' ];
411 $wp_plugin_link = '<a href="' . $p_info[ 'url' ][ 'home' ] . '">' . $p_name_transl . '</a>';
412 $pkg_pro_transl = _x( $this->p->cf[ 'packages' ][ 'pro' ], 'package name', 'wpsso' );
413 $pkg_std_transl = _x( $this->p->cf[ 'packages' ][ 'std' ], 'package name', 'wpsso' );
414 $notice_key = 'timed-notice-wpsso-pro-purchase-notice';
415 $dismiss_time = true; // Allow the notice to be dismissed forever.
416 $installed_ago = human_time_diff( time(), $ext_reg[ 'wpsso_install_time' ] );
417 $ext_type_transl = WpssoConfig::get_ext_type_transl( 'wpsso' );
418
419 /*
420 * The action buttons.
421 */
422 $purchase_label = sprintf( __( 'View the %s edition prices', 'wpsso' ), $pkg_pro_transl );
423 $purchase_clicked = '<p>' . sprintf( __( 'Thank you for supporting the continued development of %s.', 'wpsso' ), $p_name_transl ) . '</p>';
424 $purchase_button = '<div class="notice-single-button">' . $form->get_button( $purchase_label, 'button-primary dismiss-on-click',
425 '', $p_purchase_url, true, false, array( 'dismiss-msg' => $purchase_clicked ) ) . '</div>';
426
427 $no_thanks_label = sprintf( __( 'I\'ll stay with the %s edition', 'wpsso' ), $pkg_std_transl );
428 $no_thanks_clicked = '<p>' . sprintf( __( 'Please consider supporting the development of %s in the future.', 'wpsso' ), $p_name_transl ) . ' ' .
429 __( 'Thank you.', 'wpsso' ) . '</p>';
430 $no_thanks_button = '<div class="notice-single-button">' . $form->get_button( $no_thanks_label, 'button-secondary dismiss-on-click',
431 '', '', false, false, array( 'dismiss-msg' => $no_thanks_clicked ) ) . '</div>';
432
433 /*
434 * The notice message.
435 */
436 $notice_msg = '<div style="display:table-cell;">';
437 $notice_msg .= '<p style="margin-right:30px;">' . $this->p->admin->get_ext_img_icon( 'wpsso' ) . '</p>';
438 $notice_msg .= '</div>';
439 $notice_msg .= '<div style="display:table-cell;vertical-align:top;">';
440 $notice_msg .= '<p><strong>';
441
442 // translators: %1$s is the plugin name, %2$s is the plugin type (ie. "plugin" or "add-on"), and %3$s is a measure of time.
443 $notice_msg .= sprintf( __( 'The %1$s %2$s was installed %3$s ago.', 'wpsso' ),
444 $wp_plugin_link, $ext_type_transl, $installed_ago ) . ' ';
445
446 $notice_msg .= '</strong></p><p>';
447
448 $notice_msg .= sprintf( __( 'Have you thought about purchasing the %s edition?', 'wpsso' ), $pkg_pro_transl ) . ' ';
449
450 $notice_msg .= sprintf( __( 'The %s edition includes loads of extra features!', 'wpsso' ), $pkg_pro_transl ) . ' ';
451
452 $notice_msg .= convert_smilies( ':-)' ) . ' ';
453
454 $notice_msg .= '</p>';
455 $notice_msg .= '<div class="notice-actions">';
456 $notice_msg .= $purchase_button . $no_thanks_button;
457 $notice_msg .= '</div>';
458 $notice_msg .= '</div>';
459
460 $this->p->notice->nag( $notice_msg, $user_id, $notice_key, $dismiss_time );
461
462 return 1;
463 }
464 }
465 }
466