PluginProbe
Parse.ly / 3.0.0
Parse.ly v3.0.0
3.24.1 3.24.0 3.23.7 3.23.6 3.23.5 3.23.4 3.23.3 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.17.0 3.18.0 3.18.1 3.19.0 3.19.1 3.19.2 3.19.3 3.2.0 3.2.1 3.20.0 3.20.1 3.20.2 3.20.3 All 105 releases
wp-parsely / src / UI / class-settings-page.php

class-settings-page.php in Parse.ly 3.0.0, at src/UI/class-settings-page.php

822 lines 29.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Parsely settings page class
4 *
5 * @package Parsely
6 * @since 3.0.0
7 */
8
9 declare(strict_types=1);
10
11 namespace Parsely\UI;
12
13 use Parsely\Parsely;
14
15 use const Parsely\PARSELY_FILE;
16
17 /**
18 * Render the wp-admin Parse.ly plugin settings page
19 *
20 * @since 3.0.0
21 */
22 final class Settings_Page {
23 /**
24 * Instance of Parsely class.
25 *
26 * @var Parsely
27 */
28 private $parsely;
29
30 /**
31 * Constructor.
32 *
33 * @param Parsely $parsely Instance of Parsely class.
34 */
35 public function __construct( Parsely $parsely ) {
36 $this->parsely = $parsely;
37 }
38
39 /**
40 * Register settings page.
41 *
42 * @since 3.0.0
43 *
44 * @return void
45 */
46 public function run(): void {
47 add_action( 'admin_head-settings_page_parsely', array( $this, 'add_admin_header' ) );
48 add_action( 'admin_menu', array( $this, 'add_settings_sub_menu' ) );
49 add_action( 'admin_init', array( $this, 'initialize_settings' ) );
50 }
51
52 /**
53 * Include the Parse.ly admin header.
54 *
55 * @return void
56 */
57 public function add_admin_header(): void {
58 // TODO: Extract style to CSS file.
59 echo '
60 <style>
61 #wp-parsely_version { color: #777; font-size: 12px; margin-left: 1em; }
62 .help-text { width: 75%; }
63 </style>
64 ';
65
66 $admin_script_asset = require plugin_dir_path( PARSELY_FILE ) . 'build/admin-page.asset.php';
67 wp_enqueue_script(
68 'wp-parsely-admin',
69 plugin_dir_url( PARSELY_FILE ) . 'build/admin-page.js',
70 $admin_script_asset['dependencies'],
71 Parsely::get_asset_cache_buster(),
72 true
73 );
74
75 wp_set_script_translations( 'wp-parsely-admin', 'wp-parsely' );
76 }
77
78 /**
79 * Parse.ly settings page in WordPress settings menu.
80 *
81 * @return void
82 */
83 public function add_settings_sub_menu(): void {
84 add_options_page(
85 __( 'Parse.ly Settings', 'wp-parsely' ),
86 __( 'Parse.ly', 'wp-parsely' ),
87 Parsely::CAPABILITY,
88 Parsely::MENU_SLUG,
89 array( $this, 'display_settings' )
90 );
91 }
92
93 /**
94 * Parse.ly settings screen ( options-general.php?page=[MENU_SLUG] ).
95 *
96 * @return void
97 */
98 public function display_settings(): void {
99 if ( ! current_user_can( Parsely::CAPABILITY ) ) {
100 wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wp-parsely' ) );
101 }
102
103 include plugin_dir_path( PARSELY_FILE ) . 'views/parsely-settings.php';
104 }
105
106 /**
107 * Initialize the settings for Parsely.
108 *
109 * @return void
110 */
111 public function initialize_settings(): void {
112 // All our options are actually stored in one single array to reduce DB queries.
113 register_setting(
114 Parsely::OPTIONS_KEY,
115 Parsely::OPTIONS_KEY,
116 array( $this, 'validate_options' )
117 );
118
119 // These are the Required Settings.
120 add_settings_section(
121 'required_settings',
122 __( 'Required Settings', 'wp-parsely' ),
123 '__return_null',
124 Parsely::MENU_SLUG
125 );
126
127 // Get the API Key.
128 $h = __( 'Your Site ID is your own site domain ( e.g. `mydomain.com` )', 'wp-parsely' );
129 $field_id = 'apikey';
130 $field_args = array(
131 'option_key' => $field_id,
132 'help_text' => $h,
133 'label_for' => $field_id,
134 );
135 add_settings_field(
136 $field_id,
137 __( 'Parse.ly Site ID', 'wp-parsely' ),
138 array( $this, 'print_text_tag' ),
139 Parsely::MENU_SLUG,
140 'required_settings',
141 $field_args
142 );
143
144 // These are the Optional Settings.
145 add_settings_section(
146 'optional_settings',
147 __( 'Optional Settings', 'wp-parsely' ),
148 '__return_null',
149 Parsely::MENU_SLUG
150 );
151
152 /* translators: 1: Opening anchor tag markup, 2: Documentation URL, 3: Opening anchor tag markup continued, 4: Closing anchor tag */
153 $h = __( 'Your API secret is your secret code to %1$s%2$s%3$saccess our API.%4$s It can be found at dash.parsely.com/yoursitedomain/settings/api ( replace yoursitedomain with your domain name, e.g. `mydomain.com` ) If you haven\'t purchased access to the API, and would like to do so, email your account manager or support@parsely.com!', 'wp-parsely' );
154 $h_link = 'https://www.parse.ly/help/api/analytics/';
155 $field_id = 'api_secret';
156 $field_args = array(
157 'option_key' => $field_id,
158 'help_text' => $h,
159 'help_link' => $h_link,
160 'label_for' => $field_id,
161 );
162 add_settings_field(
163 $field_id,
164 __( 'Parse.ly API Secret', 'wp-parsely' ),
165 array( $this, 'print_text_tag' ),
166 Parsely::MENU_SLUG,
167 'optional_settings',
168 $field_args
169 );
170
171 $h = __( 'Your metadata secret is given to you by Parse.ly support. DO NOT enter anything here unless given to you by Parse.ly support!', 'wp-parsely' );
172 $h_link = 'https://www.parse.ly/help/api/analytics/';
173 $field_id = 'metadata_secret';
174 $field_args = array(
175 'option_key' => $field_id,
176 'help_text' => $h,
177 'help_link' => $h_link,
178 'label_for' => $field_id,
179 );
180 add_settings_field(
181 $field_id,
182 __( 'Parse.ly Metadata Secret', 'wp-parsely' ),
183 array( $this, 'print_text_tag' ),
184 Parsely::MENU_SLUG,
185 'optional_settings',
186 $field_args
187 );
188
189 // Clear metadata.
190 $h = __( 'Check this radio button and hit "Save Changes" to clear all metadata information for Parse.ly posts and re-send all metadata to Parse.ly. WARNING: do not do this unless explicitly instructed by Parse.ly Staff!', 'wp-parsely' );
191 add_settings_field(
192 'parsely_wipe_metadata_cache',
193 __( 'Wipe Parse.ly Metadata Info', 'wp-parsely' ),
194 array( $this, 'print_checkbox_tag' ),
195 Parsely::MENU_SLUG,
196 'optional_settings',
197 array(
198 'option_key' => 'parsely_wipe_metadata_cache',
199 'help_text' => $h,
200 'requires_recrawl' => false,
201 )
202 );
203
204 /* translators: 1: Opening anchor tag markup, 2: Documentation URL, 3: Opening anchor tag markup continued, 4: Closing anchor tag */
205 $h = __( 'Choose the metadata format for our crawlers to access. Most publishers are fine with JSON-LD ( %1$s%2$s%3$shttps://www.parse.ly/help/integration/jsonld/%4$s ), but if you prefer to use our proprietary metadata format then you can do so here.', 'wp-parsely' );
206 $h_link = 'https://www.parse.ly/help/integration/jsonld/';
207 $field_id = 'meta_type';
208 $field_args = array(
209 'option_key' => $field_id,
210 'help_text' => $h,
211 'help_link' => $h_link,
212 // filter WordPress taxonomies under the hood that should not appear in dropdown.
213 'select_options' => array(
214 'json_ld' => 'json_ld',
215 'repeated_metas' => 'repeated_metas',
216 ),
217 'requires_recrawl' => true,
218 'label_for' => Parsely::OPTIONS_KEY . "[$field_id]",
219 );
220 add_settings_field(
221 $field_id,
222 __( 'Metadata Format', 'wp-parsely' ),
223 array( $this, 'print_select_tag' ),
224 Parsely::MENU_SLUG,
225 'optional_settings',
226 $field_args
227 );
228
229 $h = __( 'If you want to specify the url for your logo, you can do so here.', 'wp-parsely' );
230 $field_id = 'logo';
231 $field_args = array(
232 'option_key' => $field_id,
233 'help_text' => $h,
234 'label_for' => $field_id,
235 );
236 add_settings_field(
237 $field_id,
238 __( 'Logo', 'wp-parsely' ),
239 array( $this, 'print_text_tag' ),
240 Parsely::MENU_SLUG,
241 'optional_settings',
242 $field_args
243 );
244
245 // Content ID Prefix.
246 $h = __( 'If you use more than one content management system (e.g. WordPress and Drupal), you may end up with duplicate content IDs. Adding a Content ID Prefix will ensure the content IDs from WordPress will not conflict with other content management systems. We recommend using "WP-" for your prefix.', 'wp-parsely' );
247 $field_id = 'content_id_prefix';
248 $field_args = array(
249 'option_key' => $field_id,
250 'optional_args' => array(
251 'placeholder' => 'WP-',
252 ),
253 'help_text' => $h,
254 'requires_recrawl' => true,
255 'label_for' => $field_id,
256 );
257 add_settings_field(
258 $field_id,
259 __( 'Content ID Prefix', 'wp-parsely' ),
260 array( $this, 'print_text_tag' ),
261 Parsely::MENU_SLUG,
262 'optional_settings',
263 $field_args
264 );
265
266 // Disable JavaScript.
267 $h = __( 'If you use a separate system for JavaScript tracking ( Tealium / Segment / Google Tag Manager / other tag manager solution ) you may want to use that instead of having the plugin load the tracker. WARNING: disabling this option will also disable the "Personalize Results" section of the recommended widget! We highly recommend leaving this option set to "No"!', 'wp-parsely' );
268 add_settings_field(
269 'disable_javascript',
270 __( 'Disable JavaScript', 'wp-parsely' ),
271 array( $this, 'print_binary_radio_tag' ),
272 Parsely::MENU_SLUG,
273 'optional_settings',
274 array(
275 'title' => __( 'Disable JavaScript', 'wp-parsely' ), // Passed for legend element.
276 'option_key' => 'disable_javascript',
277 'help_text' => $h,
278 'requires_recrawl' => false,
279 )
280 );
281
282 // Disable amp tracking.
283 $h = __( 'If you use a separate system for JavaScript tracking on AMP pages ( Tealium / Segment / Google Tag Manager / other tag manager solution ) you may want to use that instead of having the plugin load the tracker.', 'wp-parsely' );
284 add_settings_field(
285 'disable_amp',
286 __( 'Disable AMP Tracking', 'wp-parsely' ),
287 array( $this, 'print_binary_radio_tag' ),
288 Parsely::MENU_SLUG,
289 'optional_settings',
290 array(
291 'title' => __( 'Disable AMP Tracking', 'wp-parsely' ), // Passed for legend element.
292 'option_key' => 'disable_amp',
293 'help_text' => $h,
294 'requires_recrawl' => false,
295 )
296 );
297
298 // Use top-level categories.
299 $h = __( 'The plugin will use the first category assigned to a post. With this option selected, if you post a story to News > National > Florida, the plugin will use the "News" for the section name in your dashboard instead of "Florida".', 'wp-parsely' );
300 add_settings_field(
301 'use_top_level_cats',
302 __( 'Use Top-Level Categories for Section', 'wp-parsely' ),
303 array( $this, 'print_binary_radio_tag' ),
304 Parsely::MENU_SLUG,
305 'optional_settings',
306 array(
307 'title' => __( 'Use Top-Level Categories for Section', 'wp-parsely' ), // Passed for legend element.
308 'option_key' => 'use_top_level_cats',
309 'help_text' => $h,
310 'requires_recrawl' => true,
311 )
312 );
313
314 // Allow use of custom taxonomy to populate articleSection in parselyPage; defaults to category.
315 $h = __( 'By default, the section value in your Parse.ly dashboard maps to a post\'s category. You can optionally choose a custom taxonomy, if you\'ve created one, to populate the section value instead.', 'wp-parsely' );
316 $field_id = 'custom_taxonomy_section';
317 $field_args = array(
318 'option_key' => $field_id,
319 'help_text' => $h,
320 // filter WordPress taxonomies under the hood that should not appear in dropdown.
321 'select_options' => array_diff( get_taxonomies(), array( 'post_tag', 'nav_menu', 'author', 'link_category', 'post_format' ) ),
322 'requires_recrawl' => true,
323 'label_for' => Parsely::OPTIONS_KEY . "[$field_id]",
324 );
325 add_settings_field(
326 $field_id,
327 __( 'Use Custom Taxonomy for Section', 'wp-parsely' ),
328 array( $this, 'print_select_tag' ),
329 Parsely::MENU_SLUG,
330 'optional_settings',
331 $field_args
332 );
333
334 // Use categories and custom taxonomies as tags.
335 $h = __( 'You can use this option to add all assigned categories and taxonomies to your tags. For example, if you had a post assigned to the categories: "Business/Tech", "Business/Social", your tags would include "Business/Tech" and "Business/Social" in addition to your other tags.', 'wp-parsely' );
336 add_settings_field(
337 'cats_as_tags',
338 __( 'Add Categories to Tags', 'wp-parsely' ),
339 array( $this, 'print_binary_radio_tag' ),
340 Parsely::MENU_SLUG,
341 'optional_settings',
342 array(
343 'title' => __( 'Add Categories to Tags', 'wp-parsely' ), // Passed for legend element.
344 'option_key' => 'cats_as_tags',
345 'help_text' => $h,
346 'requires_recrawl' => true,
347 )
348 );
349
350 // Track logged-in users.
351 $h = __( 'By default, the plugin will track the activity of users that are logged into this site. You can change this setting to only track the activity of anonymous visitors. Note: You will no longer see the Parse.ly tracking code on your site if you browse while logged in.', 'wp-parsely' );
352 add_settings_field(
353 'track_authenticated_users',
354 __( 'Track Logged-in Users', 'wp-parsely' ),
355 array( $this, 'print_binary_radio_tag' ),
356 Parsely::MENU_SLUG,
357 'optional_settings',
358 array(
359 'title' => __( 'Track Logged-in Users', 'wp-parsely' ), // Passed for legend element.
360 'option_key' => 'track_authenticated_users',
361 'help_text' => $h,
362 'requires_recrawl' => false,
363 )
364 );
365
366 // Lowercase all tags.
367 $h = __( 'By default, the plugin will use lowercase versions of your tags to correct for potential misspellings. You can change this setting to ensure that tag names are used verbatim.', 'wp-parsely' );
368 add_settings_field(
369 'lowercase_tags',
370 __( 'Lowercase All Tags', 'wp-parsely' ),
371 array( $this, 'print_binary_radio_tag' ),
372 Parsely::MENU_SLUG,
373 'optional_settings',
374 array(
375 'title' => __( 'Lowercase All Tags', 'wp-parsely' ), // Passed for legend element.
376 'option_key' => 'lowercase_tags',
377 'help_text' => $h,
378 'requires_recrawl' => true,
379 )
380 );
381
382 $h = __( 'The plugin uses http canonical URLs by default. If this needs to be forced to use https, set this option to true. Note: the default is fine for almost all publishers, it\'s unlikely you\'ll have to change this unless directed to do so by a Parse.ly support rep.', 'wp-parsely' );
383 add_settings_field(
384 'force_https_canonicals',
385 __( 'Force HTTPS canonicals', 'wp-parsely' ),
386 array( $this, 'print_binary_radio_tag' ),
387 Parsely::MENU_SLUG,
388 'optional_settings',
389 array(
390 'title' => __( 'Force HTTPS canonicals', 'wp-parsely' ), // Passed for legend element.
391 'option_key' => 'force_https_canonicals',
392 'help_text' => $h,
393 'requires_recrawl' => true,
394 )
395 );
396
397 // Allow use of custom taxonomy to populate articleSection in parselyPage; defaults to category.
398 $h = __( 'By default, Parse.ly only tracks the default post type as a post page. If you want to track custom post types, select them here!', 'wp-parsely' );
399 $field_id = 'track_post_types';
400 $field_args = array(
401 'option_key' => $field_id,
402 'help_text' => $h,
403 'select_options' => get_post_types( array( 'public' => true ) ),
404 'requires_recrawl' => true,
405 'label_for' => Parsely::OPTIONS_KEY . "[$field_id]",
406 );
407 add_settings_field(
408 $field_id,
409 __( 'Post Types To Track', 'wp-parsely' ),
410 array( $this, 'print_multiple_checkboxes' ),
411 Parsely::MENU_SLUG,
412 'optional_settings',
413 $field_args
414 );
415
416 // Allow use of custom taxonomy to populate articleSection in parselyPage; defaults to category.
417 $h = __( 'By default, Parse.ly only tracks the default page type as a non-post page. If you want to track custom post types as non-post pages, select them here!', 'wp-parsely' );
418 $field_id = 'track_page_types';
419 $field_args = array(
420 'option_key' => 'track_page_types',
421 'help_text' => $h,
422 'select_options' => get_post_types( array( 'public' => true ) ),
423 'requires_recrawl' => true,
424 'label_for' => Parsely::OPTIONS_KEY . "[$field_id]",
425 );
426 add_settings_field(
427 'track_page_types',
428 __( 'Page Types To Track', 'wp-parsely' ),
429 array( $this, 'print_multiple_checkboxes' ),
430 Parsely::MENU_SLUG,
431 'optional_settings',
432 $field_args
433 );
434
435 // Dynamic tracking note.
436 add_settings_field(
437 'dynamic_tracking_note',
438 __( 'Note: ', 'wp-parsely' ),
439 array( $this, 'print_dynamic_tracking_note' ),
440 Parsely::MENU_SLUG,
441 'optional_settings'
442 );
443 }
444
445 /**
446 * Validate the options provided by the user
447 *
448 * @param array $input Options from the settings page.
449 * @return array List of validated input settings.
450 */
451 public function validate_options( array $input ): array {
452 if ( empty( $input['apikey'] ) ) {
453 add_settings_error(
454 Parsely::OPTIONS_KEY,
455 'apikey',
456 __( 'Please specify the Site ID', 'wp-parsely' )
457 );
458 } else {
459 $input['apikey'] = strtolower( $input['apikey'] );
460 $input['apikey'] = sanitize_text_field( $input['apikey'] );
461 if ( strpos( $input['apikey'], '.' ) === false || strpos( $input['apikey'], ' ' ) !== false ) {
462 add_settings_error(
463 Parsely::OPTIONS_KEY,
464 'apikey',
465 __( 'Your Parse.ly Site ID looks incorrect, it should look like "example.com".', 'wp-parsely' )
466 );
467 }
468 }
469 // these can't be null, if somebody accidentally deselected them just reset to default.
470 if ( ! isset( $input['track_post_types'] ) ) {
471 $input['track_post_types'] = array( 'post' );
472 }
473 if ( ! isset( $input['track_page_types'] ) ) {
474 $input['track_page_types'] = array( 'page' );
475 }
476
477 if ( empty( $input['logo'] ) ) {
478 $input['logo'] = self::get_logo_default();
479 }
480
481 $input['track_post_types'] = self::validate_option_array( $input['track_post_types'] );
482 $input['track_page_types'] = self::validate_option_array( $input['track_page_types'] );
483
484 $input['api_secret'] = sanitize_text_field( $input['api_secret'] );
485 // Content ID prefix.
486 $input['content_id_prefix'] = sanitize_text_field( $input['content_id_prefix'] );
487 $input['custom_taxonomy_section'] = sanitize_text_field( $input['custom_taxonomy_section'] );
488
489 // Custom taxonomy as section.
490 // Top-level categories.
491 if ( 'true' !== $input['use_top_level_cats'] && 'false' !== $input['use_top_level_cats'] ) {
492 add_settings_error(
493 Parsely::OPTIONS_KEY,
494 'use_top_level_cats',
495 __( 'Value passed for use_top_level_cats must be either "true" or "false".', 'wp-parsely' )
496 );
497 } else {
498 $input['use_top_level_cats'] = 'true' === $input['use_top_level_cats'];
499 }
500
501 // Child categories as tags.
502 if ( 'true' !== $input['cats_as_tags'] && 'false' !== $input['cats_as_tags'] ) {
503 add_settings_error(
504 Parsely::OPTIONS_KEY,
505 'cats_as_tags',
506 __( 'Value passed for cats_as_tags must be either "true" or "false".', 'wp-parsely' )
507 );
508 } else {
509 $input['cats_as_tags'] = 'true' === $input['cats_as_tags'];
510 }
511
512 // Track authenticated users.
513 if ( 'true' !== $input['track_authenticated_users'] && 'false' !== $input['track_authenticated_users'] ) {
514 add_settings_error(
515 Parsely::OPTIONS_KEY,
516 'track_authenticated_users',
517 __( 'Value passed for track_authenticated_users must be either "true" or "false".', 'wp-parsely' )
518 );
519 } else {
520 $input['track_authenticated_users'] = 'true' === $input['track_authenticated_users'];
521 }
522
523 // Lowercase tags.
524 if ( 'true' !== $input['lowercase_tags'] && 'false' !== $input['lowercase_tags'] ) {
525 add_settings_error(
526 Parsely::OPTIONS_KEY,
527 'lowercase_tags',
528 __( 'Value passed for lowercase_tags must be either "true" or "false".', 'wp-parsely' )
529 );
530 } else {
531 $input['lowercase_tags'] = 'true' === $input['lowercase_tags'];
532 }
533
534 if ( 'true' !== $input['force_https_canonicals'] && 'false' !== $input['force_https_canonicals'] ) {
535 add_settings_error(
536 Parsely::OPTIONS_KEY,
537 'force_https_canonicals',
538 __( 'Value passed for force_https_canonicals must be either "true" or "false".', 'wp-parsely' )
539 );
540 } else {
541 $input['force_https_canonicals'] = 'true' === $input['force_https_canonicals'];
542 }
543
544 if ( 'true' !== $input['disable_javascript'] && 'false' !== $input['disable_javascript'] ) {
545 add_settings_error(
546 Parsely::OPTIONS_KEY,
547 'disable_javascript',
548 __( 'Value passed for disable_javascript must be either "true" or "false".', 'wp-parsely' )
549 );
550 } else {
551 $input['disable_javascript'] = 'true' === $input['disable_javascript'];
552 }
553
554 if ( 'true' !== $input['disable_amp'] && 'false' !== $input['disable_amp'] ) {
555 add_settings_error(
556 Parsely::OPTIONS_KEY,
557 'disable_amp',
558 __( 'Value passed for disable_amp must be either "true" or "false".', 'wp-parsely' )
559 );
560 } else {
561 $input['disable_amp'] = 'true' === $input['disable_amp'];
562 }
563
564 if ( ! empty( $input['metadata_secret'] ) ) {
565 if ( strlen( $input['metadata_secret'] ) !== 10 ) {
566 add_settings_error(
567 Parsely::OPTIONS_KEY,
568 'metadata_secret',
569 __( 'Metadata secret is incorrect. Please contact Parse.ly support!', 'wp-parsely' )
570 );
571 } elseif ( 'true' === $input['parsely_wipe_metadata_cache'] ) {
572 delete_post_meta_by_key( 'parsely_metadata_last_updated' );
573
574 wp_schedule_event( time() + 100, 'everytenminutes', 'parsely_bulk_metas_update' );
575 $input['parsely_wipe_metadata_cache'] = false;
576 }
577 }
578
579 return $input;
580 }
581
582 /**
583 * Print out the radio buttons.
584 *
585 * @param array $args The arguments for text tag.
586 * @return void
587 */
588 public function print_text_tag( array $args ): void {
589 $options = $this->parsely->get_options();
590 $name = $args['option_key'];
591 $value = $options[ $name ] ?? '';
592 $optional_args = $args['optional_args'] ?? array();
593 $id = esc_attr( $name );
594 $name = Parsely::OPTIONS_KEY . "[$id]";
595 $value = esc_attr( $value );
596 $accepted_args = array( 'placeholder' );
597
598 if ( isset( $args['help_text'] ) ) {
599 echo '<div class="parsely-form-controls" data-has-help-text="true">';
600 }
601 if ( isset( $args['requires_recrawl'] ) && true === $args['requires_recrawl'] ) {
602 echo '<div class="parsely-form-controls" data-requires-recrawl="true">';
603 }
604
605 echo sprintf( "<input type='text' name='%s' id='%s' value='%s'", esc_attr( $name ), esc_attr( $id ), esc_attr( $value ) );
606 foreach ( $optional_args as $key => $val ) {
607 if ( in_array( $key, $accepted_args, true ) ) {
608 echo ' ' . esc_attr( $key ) . '="' . esc_attr( $val ) . '"';
609 }
610 }
611 echo ' />';
612
613 if ( isset( $args['help_text'] ) ) {
614 if ( isset( $args['help_link'] ) ) {
615 echo ' <div class="help-text" id="' .
616 esc_attr( $args['option_key'] ) .
617 '_help_text"><p class="description">' .
618 sprintf( esc_html( $args['help_text'] ), '<a href="', esc_url( $args['help_link'] ), '">', '</a>' ) .
619 '</p>' .
620 '</div>';
621 } else {
622 echo ' <div class="help-text" id="' .
623 esc_attr( $args['option_key'] ) .
624 '_help_text"><p class="description">' .
625 esc_html( $args['help_text'] ) . '</p>' .
626 '</div>';
627 }
628 }
629 }
630
631 /**
632 * Prints a checkbox tag in the settings page.
633 *
634 * @param array $args Arguments to print to checkbox tag.
635 * @return void
636 */
637 public function print_checkbox_tag( array $args ): void {
638 $options = $this->parsely->get_options();
639 $name = $args['option_key'];
640 $value = $options[ $name ];
641 $id = esc_attr( $name );
642 $name = Parsely::OPTIONS_KEY . "[$id]";
643
644 if ( isset( $args['help_text'] ) ) {
645 echo '<div class="parsely-form-controls" data-has-help-text="true">';
646 }
647 if ( isset( $args['requires_recrawl'] ) && true === $args['requires_recrawl'] ) {
648 echo '<div class="parsely-form-controls" data-requires-recrawl="true">';
649 }
650
651 echo sprintf( "<input type='checkbox' name='%s' id='%s_true' value='true' ", esc_attr( $name ), esc_attr( $id ) );
652 echo checked( true === $value, true, false );
653 echo sprintf( " /> <label for='%s_true'>%s</label>", esc_attr( $id ), esc_html__( 'Yes', 'wp-parsely' ) );
654
655 if ( isset( $args['help_text'] ) ) {
656 echo '<div class="help-text"><p class="description">' . esc_html( $args['help_text'] ) . '</p></div>';
657 }
658 echo '</div>';
659 }
660
661 /**
662 * Print out the select tags
663 *
664 * @param array $args The arguments for the select dropdowns.
665 * @return void
666 */
667 public function print_select_tag( array $args ): void {
668 $options = $this->parsely->get_options();
669 $name = $args['option_key'];
670 $select_options = $args['select_options'];
671 $selected = $options[ $name ] ?? null;
672 $id = esc_attr( $name );
673 $name = Parsely::OPTIONS_KEY . "[$id]";
674
675 if ( isset( $args['help_text'] ) ) {
676 echo '<div class="parsely-form-controls" data-has-help-text="true">';
677 }
678 if ( isset( $args['requires_recrawl'] ) && true === $args['requires_recrawl'] ) {
679 echo '<div class="parsely-form-controls" data-requires-recrawl="true">';
680 }
681
682 echo sprintf( "<select name='%s' id='%s'>", esc_attr( $name ), esc_attr( $name ) );
683
684 foreach ( $select_options as $key => $val ) {
685 echo '<option value="' . esc_attr( $key ) . '" ';
686 echo selected( $selected, $key, false ) . '>';
687 echo esc_html( $val );
688 echo '</option>';
689 }
690 echo '</select>';
691
692 if ( isset( $args['help_text'] ) ) {
693 if ( isset( $args['help_link'] ) ) {
694 echo '<div class="help-text"> <p class="description">' .
695 sprintf( esc_html( $args['help_text'] ), '<a href="', esc_url( $args['help_link'] ), '">', '</a>' ) .
696 '</p></div>';
697 } else {
698 echo '<div class="help-text"> <p class="description">' . esc_html( $args['help_text'] ) . '</p></div>';
699 }
700 }
701 echo '</div>';
702 }
703
704 /**
705 * Print out the radio buttons
706 *
707 * @param array $args The arguments for the radio buttons.
708 * @return void
709 */
710 public function print_binary_radio_tag( array $args ): void {
711 $options = $this->parsely->get_options();
712 $name = $args['option_key'];
713 $value = $options[ $name ];
714 $id = esc_attr( $name );
715 $name = Parsely::OPTIONS_KEY . "[$id]";
716
717 $has_help_text = isset( $args['help_text'] ) ? ' data-has-help-text="true"' : '';
718 $requires_recrawl = isset( $args['requires_recrawl'] ) && true === $args['requires_recrawl'] ? ' data-requires-recrawl="true"' : '';
719 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- static text attribute key-value. ?>
720 <fieldset class="parsely-form-controls" <?php echo $has_help_text . $requires_recrawl; ?>>
721 <legend class="screen-reader-text"><span><?php echo esc_html( $args['title'] ); ?></span></legend>
722 <p>
723 <label for="<?php echo esc_attr( "{$id}_true" ); ?>">
724 <input type="radio" name="<?php echo esc_attr( $name ); ?>" id="<?php echo esc_attr( "{$id}_true" ); ?>" value="true"<?php checked( $value ); ?> /><?php echo esc_html__( 'Yes', 'wp-parsely' ); ?>
725 </label>
726 <br />
727 <label for="<?php echo esc_attr( "{$id}_false" ); ?>">
728 <input type="radio" name="<?php echo esc_attr( $name ); ?>" id="<?php echo esc_attr( "{$id}_false" ); ?>" value="false"<?php checked( $value, false ); ?> /><?php echo esc_html__( 'No', 'wp-parsely' ); ?>
729 </label>
730 </p>
731 <?php
732 if ( isset( $args['help_text'] ) ) {
733 ?>
734 <div class="help-text"><p class="description .help-text"><?php echo esc_html( $args['help_text'] ); ?></p></div>
735 <?php
736 }
737 ?>
738 </fieldset>
739 <?php
740 }
741
742 /**
743 * Prints out multiple selection in the form of checkboxes
744 *
745 * @param array $args The arguments for the checkboxes.
746 * @return void
747 */
748 public function print_multiple_checkboxes( array $args ): void {
749 $options = $this->parsely->get_options();
750 $select_options = $args['select_options'];
751 $id = esc_attr( $args['option_key'] );
752 $name = Parsely::OPTIONS_KEY . "[$id]";
753
754 if ( isset( $args['help_text'] ) ) {
755 echo '<div class="parsely-form-controls" data-has-help-text="true">';
756 }
757 if ( isset( $args['requires_recrawl'] ) && true === $args['requires_recrawl'] ) {
758 echo '<div class="parsely-form-controls" data-requires-recrawl="true">';
759 }
760
761 foreach ( $select_options as $key => $val ) {
762 $selected = in_array( $val, $options[ $args['option_key'] ], true );
763 echo sprintf( '<p><input type="checkbox" name="%1$s[]" id="%1$s-%2$s" value="%2$s" ', esc_attr( $name ), esc_attr( $key ) );
764 echo checked( true === $selected, true, false );
765 echo sprintf( ' /> <label for="%1$s-%2$s">%2$s</label></p>', esc_attr( $name ), esc_attr( $val ) );
766 }
767
768 if ( isset( $args['help_text'] ) ) {
769 echo '<div class="help-text"><p class="description">' . esc_html( $args['help_text'] ) . '</p></div>';
770 }
771 echo '</div>';
772 }
773
774 /**
775 * Show our note about dynamic tracking.
776 *
777 * @return void
778 */
779 public function print_dynamic_tracking_note(): void {
780 printf(
781 /* translators: 1: Documentation URL 2: Documentation URL */
782 wp_kses_post( __( 'This plugin does not currently support dynamic tracking ( the tracking of multiple pageviews on a single page). Some common use-cases for dynamic tracking are slideshows or articles loaded via AJAX calls in single-page applications -- situations in which new content is loaded without a full page refresh. Tracking these events requires manually implementing additional JavaScript above <a href="%1$s">the standard Parse.ly include</a> that the plugin injects into your page source. Please consult <a href="%2$s">the Parse.ly documentation on dynamic tracking</a> for instructions on implementing dynamic tracking, or contact Parse.ly support (<a href="%3$s">support@parsely.com</a> ) for additional assistance.', 'wp-parsely' ) ),
783 esc_url( 'http://www.parsely.com/help/integration/basic/' ),
784 esc_url( 'https://www.parsely.com/help/integration/dynamic/' ),
785 esc_url( 'mailto:support@parsely.com' )
786 );
787 }
788
789 /**
790 * Returns default logo if one can be found.
791 *
792 * @return string
793 */
794 private static function get_logo_default(): string {
795 $custom_logo_id = get_theme_mod( 'custom_logo' );
796 if ( $custom_logo_id ) {
797 $logo_attrs = wp_get_attachment_image_src( $custom_logo_id, 'full' );
798 if ( $logo_attrs ) {
799 return $logo_attrs[0];
800 }
801 }
802
803 // get_site_icon_url returns an empty string if one isn't found,
804 // which is what we want to use as the default anyway.
805 return get_site_icon_url();
806 }
807
808 /**
809 * Validate options from an array.
810 *
811 * @param array $array Array of options to be sanitized.
812 * @return array
813 */
814 private static function validate_option_array( array $array ): array {
815 $new_array = $array;
816 foreach ( $array as $key => $val ) {
817 $new_array[ $key ] = sanitize_text_field( $val );
818 }
819 return $new_array;
820 }
821 }
822