| 1 |
<?php |
| 2 |
/** |
| 3 |
* UI: 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 WP_Screen; |
| 16 |
use const Parsely\PARSELY_FILE; |
| 17 |
|
| 18 |
/** |
| 19 |
* Renders the wp-admin Parse.ly plugin settings page. |
| 20 |
* |
| 21 |
* @since 3.0.0 |
| 22 |
*/ |
| 23 |
final class Settings_Page { |
| 24 |
/** |
| 25 |
* Instance of Parsely class. |
| 26 |
* |
| 27 |
* @var Parsely |
| 28 |
*/ |
| 29 |
private $parsely; |
| 30 |
|
| 31 |
/** |
| 32 |
* Admin page name used for hook suffixes. |
| 33 |
* |
| 34 |
* @since 3.2.0 |
| 35 |
* |
| 36 |
* @var string |
| 37 |
*/ |
| 38 |
private $hook_suffix; |
| 39 |
|
| 40 |
/** |
| 41 |
* Screen options name. |
| 42 |
* |
| 43 |
* Name must end in `_page` so that set-screen-option hook is triggered for |
| 44 |
* WP < 5.4.2. |
| 45 |
* |
| 46 |
* @since 3.2.0 |
| 47 |
* |
| 48 |
* @var string |
| 49 |
*/ |
| 50 |
private $screen_options_name = 'wp_parsely_page'; |
| 51 |
|
| 52 |
/** |
| 53 |
* Constructor. |
| 54 |
* |
| 55 |
* @param Parsely $parsely Instance of Parsely class. |
| 56 |
*/ |
| 57 |
public function __construct( Parsely $parsely ) { |
| 58 |
$this->parsely = $parsely; |
| 59 |
} |
| 60 |
|
| 61 |
/** |
| 62 |
* Registers settings page. |
| 63 |
* |
| 64 |
* @since 3.0.0 |
| 65 |
*/ |
| 66 |
public function run(): void { |
| 67 |
add_action( 'admin_menu', array( $this, 'add_settings_sub_menu' ) ); |
| 68 |
add_action( 'admin_init', array( $this, 'initialize_settings' ) ); |
| 69 |
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_settings_assets' ) ); |
| 70 |
|
| 71 |
// Handle saving of screen options. |
| 72 |
add_filter( 'set-screen-option', array( $this, 'set_screen_option' ), 11, 3 ); |
| 73 |
// Render screen options. |
| 74 |
add_filter( 'screen_settings', array( $this, 'screen_settings' ), 10, 2 ); |
| 75 |
} |
| 76 |
|
| 77 |
/** |
| 78 |
* Enqueues all needed scripts and styles for Parse.ly plugin settings page. |
| 79 |
* |
| 80 |
* @param string $hook_suffix The current page being loaded. |
| 81 |
*/ |
| 82 |
public function enqueue_settings_assets( string $hook_suffix ): void { |
| 83 |
if ( 'settings_page_parsely' === $hook_suffix ) { |
| 84 |
add_filter( 'media_library_months_with_files', '__return_empty_array' ); |
| 85 |
wp_enqueue_media(); |
| 86 |
|
| 87 |
$admin_settings_asset = require plugin_dir_path( PARSELY_FILE ) . 'build/admin-settings.asset.php'; |
| 88 |
$built_assets_url = plugin_dir_url( PARSELY_FILE ) . '/build/'; |
| 89 |
|
| 90 |
wp_enqueue_script( |
| 91 |
'parsely-admin-settings', |
| 92 |
$built_assets_url . 'admin-settings.js', |
| 93 |
$admin_settings_asset['dependencies'], |
| 94 |
$admin_settings_asset['version'], |
| 95 |
true |
| 96 |
); |
| 97 |
|
| 98 |
wp_enqueue_style( |
| 99 |
'parsely-admin-settings', |
| 100 |
$built_assets_url . 'admin-settings.css', |
| 101 |
$admin_settings_asset['dependencies'], |
| 102 |
$admin_settings_asset['version'] |
| 103 |
); |
| 104 |
} |
| 105 |
} |
| 106 |
|
| 107 |
/** |
| 108 |
* Adds the Parse.ly settings page in WordPress settings menu. |
| 109 |
*/ |
| 110 |
public function add_settings_sub_menu(): void { |
| 111 |
$suffix = add_options_page( |
| 112 |
__( 'Parse.ly Settings', 'wp-parsely' ), |
| 113 |
__( 'Parse.ly', 'wp-parsely' ), |
| 114 |
Parsely::CAPABILITY, |
| 115 |
Parsely::MENU_SLUG, |
| 116 |
array( $this, 'display_settings' ) |
| 117 |
); |
| 118 |
|
| 119 |
if ( is_string( $suffix ) ) { |
| 120 |
$this->hook_suffix = $suffix; |
| 121 |
|
| 122 |
// Adds help text when admin page loads. |
| 123 |
add_action( 'load-' . $this->hook_suffix, array( $this, 'add_help_text' ) ); |
| 124 |
// Adds screen options when admin page loads. |
| 125 |
add_action( 'load-' . $this->hook_suffix, array( $this, 'add_screen_options' ) ); |
| 126 |
} |
| 127 |
} |
| 128 |
|
| 129 |
/** |
| 130 |
* Saves the screen option setting. |
| 131 |
* |
| 132 |
* Nonce is already checked in set_screen_options() - no need to check here. |
| 133 |
* |
| 134 |
* @since 3.2.0 |
| 135 |
* |
| 136 |
* @param mixed $screen_option The value to save instead of the option value. |
| 137 |
* Default false (to skip saving the current option). |
| 138 |
* @param string $option The option name. |
| 139 |
* @param mixed $value The option value. |
| 140 |
* @return mixed Updated option value. |
| 141 |
*/ |
| 142 |
public function set_screen_option( $screen_option, string $option, $value ) { |
| 143 |
if ( $this->screen_options_name === $option ) { |
| 144 |
// phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 145 |
if ( isset( $_POST[ $this->screen_options_name ] ) && is_array( $_POST[ $this->screen_options_name ] ) ) { |
| 146 |
// phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
| 147 |
$unslashed = wp_unslash( $_POST[ $this->screen_options_name ] ); |
| 148 |
$data = array_map( 'sanitize_text_field', $unslashed ); |
| 149 |
} |
| 150 |
$value = $data ?? array(); |
| 151 |
} |
| 152 |
return $value; |
| 153 |
} |
| 154 |
|
| 155 |
/** |
| 156 |
* Registers screen options. |
| 157 |
* |
| 158 |
* @since 3.2.0 |
| 159 |
*/ |
| 160 |
public function add_screen_options(): void { |
| 161 |
add_screen_option( |
| 162 |
'wp_parsely_screen_options_requires_recrawl', |
| 163 |
array( |
| 164 |
'label' => __( 'Requires Recrawl Settings', 'wp-parsely' ), |
| 165 |
'option' => 'requires-recrawl', |
| 166 |
) |
| 167 |
); |
| 168 |
add_screen_option( |
| 169 |
'wp_parsely_screen_options_advanced', |
| 170 |
array( |
| 171 |
'label' => __( 'Advanced Settings', 'wp-parsely' ), |
| 172 |
'option' => 'advanced', |
| 173 |
) |
| 174 |
); |
| 175 |
} |
| 176 |
|
| 177 |
/** |
| 178 |
* Renders the screen options block. |
| 179 |
* |
| 180 |
* @since 3.2.0 |
| 181 |
* |
| 182 |
* @param string $screen_settings Screen settings. |
| 183 |
* @param WP_Screen $screen WP_Screen object. |
| 184 |
* |
| 185 |
* @return string The filtered screen settings. |
| 186 |
*/ |
| 187 |
public function screen_settings( string $screen_settings, WP_Screen $screen ): string { |
| 188 |
if ( $this->hook_suffix !== $screen->base ) { |
| 189 |
return $screen_settings; |
| 190 |
} |
| 191 |
|
| 192 |
$current_screen = get_current_screen(); |
| 193 |
if ( null === $current_screen ) { |
| 194 |
return $screen_settings; |
| 195 |
} |
| 196 |
|
| 197 |
$user_meta = get_user_meta( get_current_user_id(), $this->screen_options_name, true ); |
| 198 |
|
| 199 |
ob_start(); |
| 200 |
?> |
| 201 |
<fieldset> |
| 202 |
<legend><?php esc_html_e( 'Show on screen', 'wp-parsely' ); ?></legend> |
| 203 |
<input type="hidden" name="wp_screen_options[option]" value="<?php echo esc_attr( $this->screen_options_name ); ?>" /> |
| 204 |
<input type="hidden" name="wp_screen_options[value]" value="yes" /> |
| 205 |
<?php |
| 206 |
foreach ( $current_screen->get_options() as $option ) { |
| 207 |
$checked = isset( $user_meta[ $option['option'] ] ); |
| 208 |
$name = $this->screen_options_name . '[' . $option['option'] . ']'; |
| 209 |
?> |
| 210 |
<label><input class="hide-section-tog" name="<?php echo esc_attr( $name ); ?>" type="checkbox" id="<?php echo esc_attr( $option['option'] ); ?>" value="true"<?php checked( $checked ); ?>><?php echo esc_html( $option['label'] ); ?></label> |
| 211 |
<?php |
| 212 |
} |
| 213 |
?> |
| 214 |
</fieldset> |
| 215 |
<?php |
| 216 |
submit_button( __( 'Apply', 'wp-parsely' ), 'primary', 'screen-options-apply' ); |
| 217 |
|
| 218 |
return ob_get_clean(); |
| 219 |
} |
| 220 |
|
| 221 |
/** |
| 222 |
* Adds the help tab to the settings page. |
| 223 |
* |
| 224 |
* @since 3.1.0 |
| 225 |
*/ |
| 226 |
public function add_help_text(): void { |
| 227 |
$screen = get_current_screen(); |
| 228 |
if ( null === $screen ) { |
| 229 |
return; |
| 230 |
} |
| 231 |
|
| 232 |
$screen->add_help_tab( |
| 233 |
array( |
| 234 |
'id' => 'overview', |
| 235 |
'title' => __( 'Overview', 'wp-parsely' ), |
| 236 |
'content' => '<p>' . __( 'The only required setting on this page is the Site ID. All of the other settings are optional.', 'wp-parsely' ) . '</p>' . |
| 237 |
'<p>' . __( 'You must click the Save Changes button at the bottom of the screen for new settings to take effect.', 'wp-parsely' ) . '</p>', |
| 238 |
) |
| 239 |
); |
| 240 |
$screen->add_help_tab( |
| 241 |
array( |
| 242 |
'id' => 'requires_recrawl', |
| 243 |
'title' => __( 'Requires Recrawl', 'wp-parsely' ), |
| 244 |
'content' => '<p>' . __( |
| 245 |
'Important: changing any of the values in the Requires Recrawl section on a site currently tracked with Parse.ly will require reprocessing of your Parse.ly data. |
| 246 |
Once you have changed a value and saved, please contact support@parsely.com to request a recrawl.', |
| 247 |
'wp-parsely' |
| 248 |
) . '</p>' . |
| 249 |
'<p>' . __( |
| 250 |
'If you can\'t see these settings, you will need to enable the Requires Recrawl Settings in the Screen Options.', |
| 251 |
'wp-parsely' |
| 252 |
) . '</p>', |
| 253 |
) |
| 254 |
); |
| 255 |
} |
| 256 |
|
| 257 |
/** |
| 258 |
* Displays the Parse.ly settings screen (options-general.php?page=[SLUG]). |
| 259 |
*/ |
| 260 |
public function display_settings(): void { |
| 261 |
if ( ! current_user_can( Parsely::CAPABILITY ) ) { |
| 262 |
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wp-parsely' ) ); |
| 263 |
} |
| 264 |
|
| 265 |
include plugin_dir_path( PARSELY_FILE ) . 'views/parsely-settings.php'; |
| 266 |
} |
| 267 |
|
| 268 |
/** |
| 269 |
* Initializes the settings for Parse.ly. |
| 270 |
*/ |
| 271 |
public function initialize_settings(): void { |
| 272 |
// All our options are actually stored in one single array to reduce DB queries. |
| 273 |
register_setting( |
| 274 |
Parsely::OPTIONS_KEY, |
| 275 |
Parsely::OPTIONS_KEY, |
| 276 |
array( $this, 'validate_options' ) |
| 277 |
); |
| 278 |
|
| 279 |
$user_meta = array_keys( (array) get_user_meta( get_current_user_id(), $this->screen_options_name, true ) ); |
| 280 |
|
| 281 |
$this->initialize_basic_section(); |
| 282 |
|
| 283 |
if ( in_array( 'requires-recrawl', $user_meta, true ) ) { |
| 284 |
$this->initialize_requires_recrawl_section(); |
| 285 |
} |
| 286 |
|
| 287 |
if ( in_array( 'advanced', $user_meta, true ) ) { |
| 288 |
$this->initialize_advanced_section(); |
| 289 |
} |
| 290 |
} |
| 291 |
|
| 292 |
/** |
| 293 |
* Registers section and settings for Basic section. |
| 294 |
* |
| 295 |
* @since 3.2.0 |
| 296 |
*/ |
| 297 |
private function initialize_basic_section(): void { |
| 298 |
add_settings_section( |
| 299 |
'basic_settings', |
| 300 |
__( 'Basic Settings', 'wp-parsely' ), |
| 301 |
'__return_null', |
| 302 |
Parsely::MENU_SLUG |
| 303 |
); |
| 304 |
|
| 305 |
// Get the API Key. |
| 306 |
$h = __( 'Your Site ID is typically your own site domain without <code>http(s)://</code> prefixes or trailing <code>/</code> (e.g. <code>mydomain.com</code>).', 'wp-parsely' ); |
| 307 |
$field_id = 'apikey'; |
| 308 |
$field_args = array( |
| 309 |
'option_key' => $field_id, |
| 310 |
'help_text' => $h, |
| 311 |
'label_for' => $field_id, |
| 312 |
'optional_args' => array( |
| 313 |
'required' => 'required', |
| 314 |
'placeholder' => 'mydomain.com', |
| 315 |
), |
| 316 |
|
| 317 |
); |
| 318 |
add_settings_field( |
| 319 |
$field_id, |
| 320 |
__( 'Parse.ly Site ID <em>(required)</em>', 'wp-parsely' ), |
| 321 |
array( $this, 'print_text_tag' ), |
| 322 |
Parsely::MENU_SLUG, |
| 323 |
'basic_settings', |
| 324 |
$field_args |
| 325 |
); |
| 326 |
|
| 327 |
/* translators: 1: Opening anchor tag markup, 2: Documentation URL, 3: Opening anchor tag markup continued, 4: Closing anchor tag */ |
| 328 |
$h = __( 'Your API secret is your secret code to <a href="https://www.parse.ly/help/api/analytics/">access our API</a>. It can be found at <code>dash.parsely.com/<var>yoursitedomain</var>/settings/api</code> (replace <var>yoursitedomain</var> with your domain name, e.g. <samp>mydomain.com</samp>).<br />If you haven\'t purchased access to the API and would like to do so, email your account manager or <a href="mailto:support@parsely.com">support@parsely.com</a>.', 'wp-parsely' ); |
| 329 |
$field_id = 'api_secret'; |
| 330 |
$field_args = array( |
| 331 |
'option_key' => $field_id, |
| 332 |
'help_text' => $h, |
| 333 |
'label_for' => $field_id, |
| 334 |
); |
| 335 |
add_settings_field( |
| 336 |
$field_id, |
| 337 |
__( 'Parse.ly API Secret', 'wp-parsely' ), |
| 338 |
array( $this, 'print_text_tag' ), |
| 339 |
Parsely::MENU_SLUG, |
| 340 |
'basic_settings', |
| 341 |
$field_args |
| 342 |
); |
| 343 |
|
| 344 |
$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' ); |
| 345 |
$field_id = 'metadata_secret'; |
| 346 |
$field_args = array( |
| 347 |
'option_key' => $field_id, |
| 348 |
'help_text' => $h, |
| 349 |
'label_for' => $field_id, |
| 350 |
); |
| 351 |
add_settings_field( |
| 352 |
$field_id, |
| 353 |
__( 'Parse.ly Metadata Secret', 'wp-parsely' ), |
| 354 |
array( $this, 'print_text_tag' ), |
| 355 |
Parsely::MENU_SLUG, |
| 356 |
'basic_settings', |
| 357 |
$field_args |
| 358 |
); |
| 359 |
|
| 360 |
// Logo. |
| 361 |
$field_help = __( 'Here you can specify your logo\'s URL by using the "Browse" button or typing the URL manually.', 'wp-parsely' ); |
| 362 |
$field_id = 'logo'; |
| 363 |
add_settings_field( |
| 364 |
$field_id, |
| 365 |
__( 'Logo', 'wp-parsely' ), |
| 366 |
array( $this, 'print_media_single_image' ), |
| 367 |
Parsely::MENU_SLUG, |
| 368 |
'basic_settings', |
| 369 |
array( |
| 370 |
'title' => __( 'Logo', 'wp-parsely' ), // Passed for legend element. |
| 371 |
'option_key' => $field_id, |
| 372 |
'label_for' => $field_id, |
| 373 |
'help_text' => $field_help, |
| 374 |
) |
| 375 |
); |
| 376 |
|
| 377 |
// Track logged-in users. |
| 378 |
$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' ); |
| 379 |
add_settings_field( |
| 380 |
'track_authenticated_users', |
| 381 |
__( 'Track Logged-in Users', 'wp-parsely' ), |
| 382 |
array( $this, 'print_binary_radio_tag' ), |
| 383 |
Parsely::MENU_SLUG, |
| 384 |
'basic_settings', |
| 385 |
array( |
| 386 |
'title' => __( 'Track Logged-in Users', 'wp-parsely' ), // Passed for legend element. |
| 387 |
'option_key' => 'track_authenticated_users', |
| 388 |
'help_text' => $h, |
| 389 |
) |
| 390 |
); |
| 391 |
|
| 392 |
// Disable JavaScript. |
| 393 |
$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. <span style="color:#d63638">WARNING:</span> 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' ); |
| 394 |
add_settings_field( |
| 395 |
'disable_javascript', |
| 396 |
__( 'Disable JavaScript', 'wp-parsely' ), |
| 397 |
array( $this, 'print_binary_radio_tag' ), |
| 398 |
Parsely::MENU_SLUG, |
| 399 |
'basic_settings', |
| 400 |
array( |
| 401 |
'title' => __( 'Disable JavaScript', 'wp-parsely' ), // Passed for legend element. |
| 402 |
'option_key' => 'disable_javascript', |
| 403 |
'help_text' => $h, |
| 404 |
) |
| 405 |
); |
| 406 |
|
| 407 |
if ( defined( 'AMP__VERSION' ) ) { |
| 408 |
// Disable AMP tracking. |
| 409 |
$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' ); |
| 410 |
add_settings_field( |
| 411 |
'disable_amp', |
| 412 |
__( 'Disable AMP Tracking', 'wp-parsely' ), |
| 413 |
array( $this, 'print_binary_radio_tag' ), |
| 414 |
Parsely::MENU_SLUG, |
| 415 |
'basic_settings', |
| 416 |
array( |
| 417 |
'title' => __( 'Disable AMP Tracking', 'wp-parsely' ), // Passed for legend element. |
| 418 |
'option_key' => 'disable_amp', |
| 419 |
'help_text' => $h, |
| 420 |
) |
| 421 |
); |
| 422 |
} |
| 423 |
} |
| 424 |
|
| 425 |
/** |
| 426 |
* Registers section and settings for Requires Recrawl section. |
| 427 |
* |
| 428 |
* @since 3.2.0 |
| 429 |
*/ |
| 430 |
private function initialize_requires_recrawl_section(): void { |
| 431 |
add_settings_section( |
| 432 |
'requires_recrawl_settings', |
| 433 |
__( 'Requires Recrawl Settings', 'wp-parsely' ), |
| 434 |
function (): void { |
| 435 |
echo '<strong>' . wp_kses_post( __( '<span style="color:#d63638">Important:</span> Changing any of these values below on a site currently tracked with Parse.ly will require reprocessing of your Parse.ly data.', 'wp-parsely' ) ) . '</strong><br />'; |
| 436 |
printf( |
| 437 |
/* translators: Mailto link */ |
| 438 |
esc_html__( 'Once you have changed a value and and saved, please contact %s to request a recrawl.', 'wp-parsely' ), |
| 439 |
wp_kses_post( '<a href="mailto:support@parsely.com?subject=' . rawurlencode( 'Please reprocess ' . $this->parsely->get_api_key() ) . '">support@parsely.com</a>' ) |
| 440 |
); |
| 441 |
}, |
| 442 |
Parsely::MENU_SLUG |
| 443 |
); |
| 444 |
|
| 445 |
// Allow use of custom taxonomy to populate articleSection in parselyPage; defaults to category. |
| 446 |
$field_id = 'track_post_types_as'; |
| 447 |
$field_help = __( 'By default, Parse.ly only tracks posts and pages. If you want to track other post types, select how you want to track them here.', 'wp-parsely' ); |
| 448 |
add_settings_field( |
| 449 |
$field_id, |
| 450 |
__( 'Track Post Types as', 'wp-parsely' ), |
| 451 |
array( $this, 'print_track_post_types_table' ), |
| 452 |
Parsely::MENU_SLUG, |
| 453 |
'requires_recrawl_settings', |
| 454 |
array( |
| 455 |
'title' => __( 'Track Post Types as', 'wp-parsely' ), |
| 456 |
'option_key' => $field_id, |
| 457 |
'help_text' => $field_help, |
| 458 |
) |
| 459 |
); |
| 460 |
|
| 461 |
// Metadata Format. |
| 462 |
/* translators: 1: Opening anchor tag markup, 2: Documentation URL, 3: Opening anchor tag markup continued, 4: Closing anchor tag */ |
| 463 |
$h = __( 'Choose the metadata format for our crawlers to access. Most publishers are fine with <a href="https://www.parse.ly/help/integration/jsonld/">JSON-LD</a>, but if you prefer to use our proprietary metadata format then you can do so here.', 'wp-parsely' ); |
| 464 |
$field_id = 'meta_type'; |
| 465 |
$field_args = array( |
| 466 |
'option_key' => $field_id, |
| 467 |
'help_text' => $h, |
| 468 |
// filter WordPress taxonomies under the hood that should not appear in dropdown. |
| 469 |
'select_options' => array( |
| 470 |
'json_ld' => 'json_ld', |
| 471 |
'repeated_metas' => 'repeated_metas', |
| 472 |
), |
| 473 |
'label_for' => Parsely::OPTIONS_KEY . "[$field_id]", |
| 474 |
); |
| 475 |
add_settings_field( |
| 476 |
$field_id, |
| 477 |
__( 'Metadata Format', 'wp-parsely' ), |
| 478 |
array( $this, 'print_select_tag' ), |
| 479 |
Parsely::MENU_SLUG, |
| 480 |
'requires_recrawl_settings', |
| 481 |
$field_args |
| 482 |
); |
| 483 |
|
| 484 |
// Content ID Prefix. |
| 485 |
$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' ); |
| 486 |
$field_id = 'content_id_prefix'; |
| 487 |
$field_args = array( |
| 488 |
'option_key' => $field_id, |
| 489 |
'optional_args' => array( |
| 490 |
'placeholder' => 'WP-', |
| 491 |
), |
| 492 |
'help_text' => $h, |
| 493 |
'label_for' => $field_id, |
| 494 |
); |
| 495 |
add_settings_field( |
| 496 |
$field_id, |
| 497 |
__( 'Content ID Prefix', 'wp-parsely' ), |
| 498 |
array( $this, 'print_text_tag' ), |
| 499 |
Parsely::MENU_SLUG, |
| 500 |
'requires_recrawl_settings', |
| 501 |
$field_args |
| 502 |
); |
| 503 |
|
| 504 |
// Use top-level categories. |
| 505 |
$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' ); |
| 506 |
add_settings_field( |
| 507 |
'use_top_level_cats', |
| 508 |
__( 'Use Top-Level Categories for Section', 'wp-parsely' ), |
| 509 |
array( $this, 'print_binary_radio_tag' ), |
| 510 |
Parsely::MENU_SLUG, |
| 511 |
'requires_recrawl_settings', |
| 512 |
array( |
| 513 |
'title' => __( 'Use Top-Level Categories for Section', 'wp-parsely' ), // Passed for legend element. |
| 514 |
'option_key' => 'use_top_level_cats', |
| 515 |
'help_text' => $h, |
| 516 |
) |
| 517 |
); |
| 518 |
|
| 519 |
// Allow use of custom taxonomy to populate articleSection in parselyPage; defaults to category. |
| 520 |
$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' ); |
| 521 |
$field_id = 'custom_taxonomy_section'; |
| 522 |
$field_args = array( |
| 523 |
'option_key' => $field_id, |
| 524 |
'help_text' => $h, |
| 525 |
// filter WordPress taxonomies under the hood that should not appear in dropdown. |
| 526 |
'select_options' => array_diff( |
| 527 |
get_taxonomies(), |
| 528 |
array( |
| 529 |
'post_tag', |
| 530 |
'nav_menu', |
| 531 |
'author', |
| 532 |
'link_category', |
| 533 |
'post_format', |
| 534 |
) |
| 535 |
), |
| 536 |
'label_for' => Parsely::OPTIONS_KEY . "[$field_id]", |
| 537 |
); |
| 538 |
add_settings_field( |
| 539 |
$field_id, |
| 540 |
__( 'Use Custom Taxonomy for Section', 'wp-parsely' ), |
| 541 |
array( $this, 'print_select_tag' ), |
| 542 |
Parsely::MENU_SLUG, |
| 543 |
'requires_recrawl_settings', |
| 544 |
$field_args |
| 545 |
); |
| 546 |
|
| 547 |
// Use categories and custom taxonomies as tags. |
| 548 |
$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' ); |
| 549 |
add_settings_field( |
| 550 |
'cats_as_tags', |
| 551 |
__( 'Add Categories to Tags', 'wp-parsely' ), |
| 552 |
array( $this, 'print_binary_radio_tag' ), |
| 553 |
Parsely::MENU_SLUG, |
| 554 |
'requires_recrawl_settings', |
| 555 |
array( |
| 556 |
'title' => __( 'Add Categories to Tags', 'wp-parsely' ), // Passed for legend element. |
| 557 |
'option_key' => 'cats_as_tags', |
| 558 |
'help_text' => $h, |
| 559 |
) |
| 560 |
); |
| 561 |
|
| 562 |
// Lowercase all tags. |
| 563 |
$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' ); |
| 564 |
add_settings_field( |
| 565 |
'lowercase_tags', |
| 566 |
__( 'Lowercase All Tags', 'wp-parsely' ), |
| 567 |
array( $this, 'print_binary_radio_tag' ), |
| 568 |
Parsely::MENU_SLUG, |
| 569 |
'requires_recrawl_settings', |
| 570 |
array( |
| 571 |
'title' => __( 'Lowercase All Tags', 'wp-parsely' ), // Passed for legend element. |
| 572 |
'option_key' => 'lowercase_tags', |
| 573 |
'help_text' => $h, |
| 574 |
) |
| 575 |
); |
| 576 |
|
| 577 |
$h = __( 'The plugin uses <code>http</code> canonical URLs by default. If this needs to be forced to use <code>https</code>, 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' ); |
| 578 |
add_settings_field( |
| 579 |
'force_https_canonicals', |
| 580 |
__( 'Force HTTPS Canonicals', 'wp-parsely' ), |
| 581 |
array( $this, 'print_binary_radio_tag' ), |
| 582 |
Parsely::MENU_SLUG, |
| 583 |
'requires_recrawl_settings', |
| 584 |
array( |
| 585 |
'title' => __( 'Force HTTPS Canonicals', 'wp-parsely' ), // Passed for legend element. |
| 586 |
'option_key' => 'force_https_canonicals', |
| 587 |
'help_text' => $h, |
| 588 |
) |
| 589 |
); |
| 590 |
} |
| 591 |
|
| 592 |
/** |
| 593 |
* Registers section and settings for Advanced section. |
| 594 |
* |
| 595 |
* @since 3.2.0 |
| 596 |
*/ |
| 597 |
private function initialize_advanced_section(): void { |
| 598 |
// These are Advanced Settings. |
| 599 |
add_settings_section( |
| 600 |
'advanced_settings', |
| 601 |
__( 'Advanced Settings', 'wp-parsely' ), |
| 602 |
'__return_null', |
| 603 |
Parsely::MENU_SLUG |
| 604 |
); |
| 605 |
|
| 606 |
// Disable autotrack. |
| 607 |
$h = __( 'The default behavior of the tracking code is to report an event as soon as the script has finished loading. This setting enables or disables that behavior. Only disable this if you plan to implement Dynamic Tracking yourself.', 'wp-parsely' ); |
| 608 |
add_settings_field( |
| 609 |
'disable_autotrack', |
| 610 |
__( 'Disable Autotracking', 'wp-parsely' ), |
| 611 |
array( $this, 'print_binary_radio_tag' ), |
| 612 |
Parsely::MENU_SLUG, |
| 613 |
'advanced_settings', |
| 614 |
array( |
| 615 |
'title' => __( 'Disable Autotracking', 'wp-parsely' ), // Passed for legend element. |
| 616 |
'option_key' => 'disable_autotrack', |
| 617 |
'help_text' => $h, |
| 618 |
) |
| 619 |
); |
| 620 |
|
| 621 |
// Clear metadata. |
| 622 |
$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.<br /><span style="color:#d63638">WARNING:</span> Do not do this unless explicitly instructed by Parse.ly Staff!', 'wp-parsely' ); |
| 623 |
add_settings_field( |
| 624 |
'parsely_wipe_metadata_cache', |
| 625 |
__( 'Wipe Parse.ly Metadata Info', 'wp-parsely' ), |
| 626 |
array( $this, 'print_checkbox_tag' ), |
| 627 |
Parsely::MENU_SLUG, |
| 628 |
'advanced_settings', |
| 629 |
array( |
| 630 |
'option_key' => 'parsely_wipe_metadata_cache', |
| 631 |
'help_text' => $h, |
| 632 |
) |
| 633 |
); |
| 634 |
} |
| 635 |
|
| 636 |
/** |
| 637 |
* Prints out the description text, if there is any. |
| 638 |
* |
| 639 |
* @since 3.1.0 |
| 640 |
* |
| 641 |
* @param array $args The arguments for the form field. May contain 'help_text'. |
| 642 |
*/ |
| 643 |
public function print_description_text( $args ): void { |
| 644 |
echo isset( $args['help_text'] ) ? '<p class="description" id="' . esc_attr( $args['option_key'] ) . '-description">' . wp_kses_post( $args['help_text'] ) . '</p>' : ''; |
| 645 |
} |
| 646 |
|
| 647 |
/** |
| 648 |
* Prints out an input text tag. |
| 649 |
* |
| 650 |
* @param array $args The arguments for text tag. |
| 651 |
*/ |
| 652 |
public function print_text_tag( array $args ): void { |
| 653 |
$options = $this->parsely->get_options(); |
| 654 |
$name = $args['option_key']; |
| 655 |
$value = $options[ $name ] ?? ''; |
| 656 |
$optional_args = $args['optional_args'] ?? array(); |
| 657 |
$id = esc_attr( $name ); |
| 658 |
$name = Parsely::OPTIONS_KEY . "[$id]"; |
| 659 |
$value = esc_attr( $value ); |
| 660 |
$accepted_args = array( 'placeholder', 'required' ); |
| 661 |
|
| 662 |
echo sprintf( "<input type='text' name='%s' id='%s' value='%s'", esc_attr( $name ), esc_attr( $id ), esc_attr( $value ) ); |
| 663 |
if ( $args['help_text'] ) { |
| 664 |
echo ' aria-describedby="' . esc_attr( $id ) . '-description"'; |
| 665 |
} |
| 666 |
foreach ( $optional_args as $key => $val ) { |
| 667 |
if ( \in_array( $key, $accepted_args, true ) ) { |
| 668 |
echo ' ' . esc_attr( $key ) . '="' . esc_attr( $val ) . '"'; |
| 669 |
} |
| 670 |
} |
| 671 |
echo ' />'; |
| 672 |
|
| 673 |
$this->print_description_text( $args ); |
| 674 |
} |
| 675 |
|
| 676 |
/** |
| 677 |
* Prints a checkbox tag in the settings page. |
| 678 |
* |
| 679 |
* @param array $args Arguments to print to checkbox tag. |
| 680 |
*/ |
| 681 |
public function print_checkbox_tag( array $args ): void { |
| 682 |
$options = $this->parsely->get_options(); |
| 683 |
$name = $args['option_key']; |
| 684 |
$value = $options[ $name ]; |
| 685 |
$id = esc_attr( $name ); |
| 686 |
$name = Parsely::OPTIONS_KEY . "[$id]"; |
| 687 |
|
| 688 |
echo sprintf( "<input type='checkbox' name='%s' id='%s_true' value='true' ", esc_attr( $name ), esc_attr( $id ) ); |
| 689 |
if ( $args['help_text'] ) { |
| 690 |
echo ' aria-describedby="' . esc_attr( $id ) . '-description"'; |
| 691 |
} |
| 692 |
echo checked( true === $value, true, false ); |
| 693 |
echo sprintf( " /> <label for='%s_true'>%s</label>", esc_attr( $id ), esc_html__( 'Yes', 'wp-parsely' ) ); |
| 694 |
|
| 695 |
$this->print_description_text( $args ); |
| 696 |
} |
| 697 |
|
| 698 |
/** |
| 699 |
* Prints out the select tags |
| 700 |
* |
| 701 |
* @param array $args The arguments for the select dropdowns. |
| 702 |
*/ |
| 703 |
public function print_select_tag( array $args ): void { |
| 704 |
$options = $this->parsely->get_options(); |
| 705 |
$name = $args['option_key']; |
| 706 |
$select_options = $args['select_options']; |
| 707 |
$selected = $options[ $name ] ?? null; |
| 708 |
$id = esc_attr( $name ); |
| 709 |
$name = Parsely::OPTIONS_KEY . "[$id]"; |
| 710 |
|
| 711 |
echo sprintf( "<select name='%s' id='%s'", esc_attr( $name ), esc_attr( $name ) ); |
| 712 |
if ( $args['help_text'] ) { |
| 713 |
echo ' aria-describedby="' . esc_attr( $id ) . '-description"'; |
| 714 |
} |
| 715 |
echo '>'; |
| 716 |
|
| 717 |
foreach ( $select_options as $key => $val ) { |
| 718 |
echo '<option value="' . esc_attr( $key ) . '" '; |
| 719 |
echo selected( $selected, $key, false ) . '>'; |
| 720 |
echo esc_html( $val ); |
| 721 |
echo '</option>'; |
| 722 |
} |
| 723 |
echo '</select>'; |
| 724 |
|
| 725 |
$this->print_description_text( $args ); |
| 726 |
} |
| 727 |
|
| 728 |
/** |
| 729 |
* Prints out the radio buttons. |
| 730 |
* |
| 731 |
* @param array $args The arguments for the radio buttons. |
| 732 |
*/ |
| 733 |
public function print_binary_radio_tag( array $args ): void { |
| 734 |
$options = $this->parsely->get_options(); |
| 735 |
$name = $args['option_key']; |
| 736 |
$value = $options[ $name ]; |
| 737 |
$id = esc_attr( $name ); |
| 738 |
$name = Parsely::OPTIONS_KEY . "[$id]"; |
| 739 |
?> |
| 740 |
<fieldset> |
| 741 |
<legend class="screen-reader-text"><span><?php echo esc_html( $args['title'] ); ?></span></legend> |
| 742 |
<p> |
| 743 |
<label for="<?php echo esc_attr( "{$id}_true" ); ?>"> |
| 744 |
<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' ); ?> |
| 745 |
</label> |
| 746 |
<br /> |
| 747 |
<label for="<?php echo esc_attr( "{$id}_false" ); ?>"> |
| 748 |
<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' ); ?> |
| 749 |
</label> |
| 750 |
</p> |
| 751 |
</fieldset> |
| 752 |
<?php |
| 753 |
$this->print_description_text( $args ); |
| 754 |
} |
| 755 |
|
| 756 |
/** |
| 757 |
* Prints out a "single-image browse control" which includes a text input to |
| 758 |
* store image path and a button to browse for images. |
| 759 |
* |
| 760 |
* @param array $args The arguments for the control. |
| 761 |
*/ |
| 762 |
public function print_media_single_image( array $args ): void { |
| 763 |
$key = $args['option_key']; |
| 764 |
$input_value = $this->parsely->get_options()[ $key ]; |
| 765 |
$input_name = Parsely::OPTIONS_KEY . "[$key]"; |
| 766 |
$button_text = __( 'Browse', 'wp-parsely' ); |
| 767 |
?> |
| 768 |
|
| 769 |
<fieldset class="media-single-image" id="media-single-image-<?php echo esc_attr( $key ); ?>"> |
| 770 |
<legend class="screen-reader-text"><span><?php echo esc_html( $args['title'] ); ?></span></legend> |
| 771 |
<input class="file-path" type="text" name="<?php echo esc_attr( $input_name ); ?>" id="logo" value="<?php echo esc_attr( $input_value ); ?>" /> |
| 772 |
<button data-option="<?php echo esc_attr( $key ); ?>" class="browse button" type="button"><?php echo esc_html( $button_text ); ?></button> |
| 773 |
</fieldset> |
| 774 |
|
| 775 |
<?php |
| 776 |
$this->print_description_text( $args ); |
| 777 |
} |
| 778 |
|
| 779 |
/** |
| 780 |
* Prints out the post tracking options table. |
| 781 |
* |
| 782 |
* @since 3.2.0 |
| 783 |
* |
| 784 |
* @param array<string, string> $args The arguments used in the output HTML elements. |
| 785 |
*/ |
| 786 |
public function print_track_post_types_table( array $args ): void { |
| 787 |
$option_key = esc_attr( $args['option_key'] ); |
| 788 |
$post_types = get_post_types( array( 'public' => true ) ); |
| 789 |
$values = $this->get_tracking_values_for_display(); |
| 790 |
?> |
| 791 |
<fieldset> |
| 792 |
<legend class="screen-reader-text"><span><?php echo esc_html( $args['title'] ); ?></span></legend> |
| 793 |
<table class="form-table widefat striped" id="track-post-types"> |
| 794 |
<caption class="screen-reader-text"><?php echo esc_html( $args['title'] ); ?></caption> |
| 795 |
<thead> |
| 796 |
<tr> |
| 797 |
<th scope="col"><?php echo esc_html__( 'Post Type', 'wp-parsely' ); ?></th> |
| 798 |
<th id="track-post-types--post" scope="col"><?php echo esc_html__( 'Track as Post', 'wp-parsely' ); ?></th> |
| 799 |
<th id="track-post-types--page" scope="col"><?php echo esc_html__( 'Track as Page', 'wp-parsely' ); ?></th> |
| 800 |
<th id="track-post-types--none" scope="col"><?php echo esc_html__( 'Do not track', 'wp-parsely' ); ?></th> |
| 801 |
</tr> |
| 802 |
</thead> |
| 803 |
<tbody> |
| 804 |
<?php |
| 805 |
foreach ( $post_types as $post_type ) { |
| 806 |
$group_name = "parsely[{$option_key}][{$post_type}]"; |
| 807 |
$id_post = "{$option_key}_{$post_type}_post"; |
| 808 |
$id_page = "{$option_key}_{$post_type}_page"; |
| 809 |
$id_none = "{$option_key}_{$post_type}_none"; |
| 810 |
$value = $values[ $post_type ] ?? 'none'; |
| 811 |
?> |
| 812 |
<tr> |
| 813 |
<th scope="row"><?php echo esc_html( $post_type ); ?></th> |
| 814 |
<td> |
| 815 |
<label aria-labelledby="track-post-types--post" for="<?php echo esc_attr( $id_post ); ?>"> |
| 816 |
<input id="<?php echo esc_attr( $id_post ); ?>" name="<?php echo esc_attr( $group_name ); ?>" type="radio" value="post" <?php checked( $value, 'post' ); ?> /> |
| 817 |
</label> |
| 818 |
</td> |
| 819 |
<td> |
| 820 |
<label aria-labelledby="track-post-types--page" for="<?php echo esc_attr( $id_page ); ?>"> |
| 821 |
<input id="<?php echo esc_attr( $id_page ); ?>" name="<?php echo esc_attr( $group_name ); ?>" type="radio" value="page" <?php checked( $value, 'page' ); ?> /> |
| 822 |
</label> |
| 823 |
</td> |
| 824 |
<td> |
| 825 |
<label aria-labelledby="track-post-types--none" for="<?php echo esc_attr( $id_none ); ?>"> |
| 826 |
<input id="<?php echo esc_attr( $id_none ); ?>" name="<?php echo esc_attr( $group_name ); ?>" type="radio" value="none" <?php checked( $value, 'none' ); ?> /> |
| 827 |
</label> |
| 828 |
</td> |
| 829 |
</tr> |
| 830 |
<?php } ?> |
| 831 |
</tbody> |
| 832 |
</table> |
| 833 |
</fieldset> |
| 834 |
<?php |
| 835 |
$this->print_description_text( $args ); |
| 836 |
} |
| 837 |
|
| 838 |
/** |
| 839 |
* Returns the custom post type tracking values in a format that is easily |
| 840 |
* consumable by the print_track_post_types_table() function. |
| 841 |
* |
| 842 |
* @since 3.2.0 |
| 843 |
* |
| 844 |
* @return array<string, string> Key-value pairs with post type and their 'track as' value. |
| 845 |
*/ |
| 846 |
public function get_tracking_values_for_display(): array { |
| 847 |
$options = $this->parsely->get_options(); |
| 848 |
$types = array( 'post', 'page' ); |
| 849 |
$result = array(); |
| 850 |
|
| 851 |
foreach ( $types as $type ) { |
| 852 |
$array_key = "track_{$type}_types"; |
| 853 |
if ( array_key_exists( $array_key, $options ) ) { |
| 854 |
foreach ( $options[ $array_key ] as $post_type ) { |
| 855 |
$result[ $post_type ] = $type; |
| 856 |
} |
| 857 |
} |
| 858 |
} |
| 859 |
|
| 860 |
return $result; |
| 861 |
} |
| 862 |
|
| 863 |
/** |
| 864 |
* Validates the options provided by the user. |
| 865 |
* |
| 866 |
* @param array $input Options from the settings page. |
| 867 |
* @return array List of validated input settings. |
| 868 |
*/ |
| 869 |
public function validate_options( array $input ): array { |
| 870 |
$options = $this->parsely->get_options(); |
| 871 |
|
| 872 |
if ( empty( $input['apikey'] ) ) { |
| 873 |
add_settings_error( |
| 874 |
Parsely::OPTIONS_KEY, |
| 875 |
'apikey', |
| 876 |
__( 'Please specify the Site ID', 'wp-parsely' ) |
| 877 |
); |
| 878 |
} else { |
| 879 |
$api_key = $this->sanitize_api_key( $input['apikey'] ); |
| 880 |
if ( false === $this->validate_api_key( $api_key ) ) { |
| 881 |
add_settings_error( |
| 882 |
Parsely::OPTIONS_KEY, |
| 883 |
'apikey', |
| 884 |
__( 'Your Parse.ly Site ID looks incorrect, it should look like "example.com".', 'wp-parsely' ) |
| 885 |
); |
| 886 |
} else { |
| 887 |
$input['apikey'] = $api_key; |
| 888 |
} |
| 889 |
} |
| 890 |
|
| 891 |
$input['api_secret'] = sanitize_text_field( $input['api_secret'] ); |
| 892 |
|
| 893 |
if ( ! empty( $input['metadata_secret'] ) ) { |
| 894 |
if ( strlen( $input['metadata_secret'] ) !== 10 ) { |
| 895 |
add_settings_error( |
| 896 |
Parsely::OPTIONS_KEY, |
| 897 |
'metadata_secret', |
| 898 |
__( 'Metadata secret is incorrect. Please contact Parse.ly support!', 'wp-parsely' ) |
| 899 |
); |
| 900 |
} elseif ( isset( $input['parsely_wipe_metadata_cache'] ) && 'true' === $input['parsely_wipe_metadata_cache'] ) { |
| 901 |
delete_post_meta_by_key( 'parsely_metadata_last_updated' ); |
| 902 |
|
| 903 |
wp_schedule_event( time() + 100, 'everytenminutes', 'parsely_bulk_metas_update' ); |
| 904 |
$input['parsely_wipe_metadata_cache'] = false; |
| 905 |
} |
| 906 |
} |
| 907 |
|
| 908 |
if ( empty( $input['logo'] ) ) { |
| 909 |
$input['logo'] = self::get_logo_default(); |
| 910 |
} |
| 911 |
|
| 912 |
// Validate 'Track post type as'. |
| 913 |
$this->validate_options_post_type_tracking( $input ); |
| 914 |
|
| 915 |
// Track authenticated users. |
| 916 |
if ( 'true' !== $input['track_authenticated_users'] && 'false' !== $input['track_authenticated_users'] ) { |
| 917 |
add_settings_error( |
| 918 |
Parsely::OPTIONS_KEY, |
| 919 |
'track_authenticated_users', |
| 920 |
__( 'Value passed for track_authenticated_users must be either "true" or "false".', 'wp-parsely' ) |
| 921 |
); |
| 922 |
} else { |
| 923 |
$input['track_authenticated_users'] = 'true' === $input['track_authenticated_users']; |
| 924 |
} |
| 925 |
|
| 926 |
if ( 'true' !== $input['disable_javascript'] && 'false' !== $input['disable_javascript'] ) { |
| 927 |
add_settings_error( |
| 928 |
Parsely::OPTIONS_KEY, |
| 929 |
'disable_javascript', |
| 930 |
__( 'Value passed for disable_javascript must be either "Yes" or "No".', 'wp-parsely' ) |
| 931 |
); |
| 932 |
} else { |
| 933 |
$input['disable_javascript'] = 'true' === $input['disable_javascript']; |
| 934 |
} |
| 935 |
|
| 936 |
if ( ! isset( $input['disable_autotrack'] ) ) { |
| 937 |
$input['disable_autotrack'] = $options['disable_autotrack']; |
| 938 |
} elseif ( 'true' !== $input['disable_autotrack'] && 'false' !== $input['disable_autotrack'] ) { |
| 939 |
add_settings_error( |
| 940 |
Parsely::OPTIONS_KEY, |
| 941 |
'disable_autotrack', |
| 942 |
__( 'Value passed for disable_autotrack must be either "Yes" or "No".', 'wp-parsely' ) |
| 943 |
); |
| 944 |
} else { |
| 945 |
$input['disable_autotrack'] = 'true' === $input['disable_autotrack']; |
| 946 |
} |
| 947 |
|
| 948 |
// Allow for Disable AMP setting to be conditionally included on the page. |
| 949 |
// If it's not shown, then set the value as what was previously saved. |
| 950 |
if ( ! isset( $input['disable_amp'] ) ) { |
| 951 |
$input['disable_amp'] = 'true'; |
| 952 |
if ( false === $options['disable_amp'] ) { |
| 953 |
$input['disable_amp'] = 'false'; |
| 954 |
} |
| 955 |
} |
| 956 |
|
| 957 |
if ( 'true' !== $input['disable_amp'] && 'false' !== $input['disable_amp'] ) { |
| 958 |
add_settings_error( |
| 959 |
Parsely::OPTIONS_KEY, |
| 960 |
'disable_amp', |
| 961 |
__( 'Value passed for disable_amp must be either "true" or "false".', 'wp-parsely' ) |
| 962 |
); |
| 963 |
} else { |
| 964 |
$input['disable_amp'] = 'true' === $input['disable_amp']; |
| 965 |
} |
| 966 |
|
| 967 |
$input['api_secret'] = sanitize_text_field( $input['api_secret'] ); |
| 968 |
|
| 969 |
// Custom taxonomy as section. |
| 970 |
if ( ! isset( $input['meta_type'] ) ) { |
| 971 |
$input['meta_type'] = $options['meta_type']; |
| 972 |
} else { |
| 973 |
$input['meta_type'] = sanitize_text_field( $input['meta_type'] ); |
| 974 |
} |
| 975 |
|
| 976 |
// Content ID prefix. |
| 977 |
if ( ! isset( $input['content_id_prefix'] ) ) { |
| 978 |
$input['content_id_prefix'] = $options['content_id_prefix']; |
| 979 |
} else { |
| 980 |
$input['content_id_prefix'] = sanitize_text_field( $input['content_id_prefix'] ); |
| 981 |
} |
| 982 |
|
| 983 |
// Allow for Top-level categories setting to be conditionally included on the page. |
| 984 |
// If it's not shown, then set the value as what was previously saved. |
| 985 |
if ( ! isset( $input['use_top_level_cats'] ) ) { |
| 986 |
$input['use_top_level_cats'] = 'true'; |
| 987 |
if ( false === $options['use_top_level_cats'] ) { |
| 988 |
$input['use_top_level_cats'] = 'false'; |
| 989 |
} |
| 990 |
} |
| 991 |
|
| 992 |
// Top-level categories. |
| 993 |
if ( 'true' !== $input['use_top_level_cats'] && 'false' !== $input['use_top_level_cats'] ) { |
| 994 |
add_settings_error( |
| 995 |
Parsely::OPTIONS_KEY, |
| 996 |
'use_top_level_cats', |
| 997 |
__( 'Value passed for use_top_level_cats must be either "true" or "false".', 'wp-parsely' ) |
| 998 |
); |
| 999 |
} else { |
| 1000 |
$input['use_top_level_cats'] = 'true' === $input['use_top_level_cats']; |
| 1001 |
} |
| 1002 |
|
| 1003 |
// Custom taxonomy as section. |
| 1004 |
if ( ! isset( $input['custom_taxonomy_section'] ) ) { |
| 1005 |
$input['custom_taxonomy_section'] = $options['custom_taxonomy_section']; |
| 1006 |
} else { |
| 1007 |
$input['custom_taxonomy_section'] = sanitize_text_field( $input['custom_taxonomy_section'] ); |
| 1008 |
} |
| 1009 |
|
| 1010 |
// Allow for Categories as Tags setting to be conditionally included on the page. |
| 1011 |
// If it's not shown, then set the value as what was previously saved. |
| 1012 |
if ( ! isset( $input['cats_as_tags'] ) ) { |
| 1013 |
$input['cats_as_tags'] = 'true'; |
| 1014 |
if ( false === $options['cats_as_tags'] ) { |
| 1015 |
$input['cats_as_tags'] = 'false'; |
| 1016 |
} |
| 1017 |
} |
| 1018 |
|
| 1019 |
// Child categories as tags. |
| 1020 |
if ( 'true' !== $input['cats_as_tags'] && 'false' !== $input['cats_as_tags'] ) { |
| 1021 |
add_settings_error( |
| 1022 |
Parsely::OPTIONS_KEY, |
| 1023 |
'cats_as_tags', |
| 1024 |
__( 'Value passed for cats_as_tags must be either "true" or "false".', 'wp-parsely' ) |
| 1025 |
); |
| 1026 |
} else { |
| 1027 |
$input['cats_as_tags'] = 'true' === $input['cats_as_tags']; |
| 1028 |
} |
| 1029 |
|
| 1030 |
// Allow for Lowercase Tags setting to be conditionally included on the page. |
| 1031 |
// If it's not shown, then set the value as what was previously saved. |
| 1032 |
if ( ! isset( $input['lowercase_tags'] ) ) { |
| 1033 |
$input['lowercase_tags'] = 'true'; |
| 1034 |
if ( false === $options['lowercase_tags'] ) { |
| 1035 |
$input['lowercase_tags'] = 'false'; |
| 1036 |
} |
| 1037 |
} |
| 1038 |
|
| 1039 |
// Lowercase tags. |
| 1040 |
if ( 'true' !== $input['lowercase_tags'] && 'false' !== $input['lowercase_tags'] ) { |
| 1041 |
add_settings_error( |
| 1042 |
Parsely::OPTIONS_KEY, |
| 1043 |
'lowercase_tags', |
| 1044 |
__( 'Value passed for lowercase_tags must be either "true" or "false".', 'wp-parsely' ) |
| 1045 |
); |
| 1046 |
} else { |
| 1047 |
$input['lowercase_tags'] = 'true' === $input['lowercase_tags']; |
| 1048 |
} |
| 1049 |
|
| 1050 |
// Allow for Force HTTPS Canonical setting to be conditionally included on the page. |
| 1051 |
// If it's not shown, then set the value as what was previously saved. |
| 1052 |
if ( ! isset( $input['force_https_canonicals'] ) ) { |
| 1053 |
$input['force_https_canonicals'] = 'true'; |
| 1054 |
if ( false === $options['force_https_canonicals'] ) { |
| 1055 |
$input['force_https_canonicals'] = 'false'; |
| 1056 |
} |
| 1057 |
} |
| 1058 |
|
| 1059 |
if ( 'true' !== $input['force_https_canonicals'] && 'false' !== $input['force_https_canonicals'] ) { |
| 1060 |
add_settings_error( |
| 1061 |
Parsely::OPTIONS_KEY, |
| 1062 |
'force_https_canonicals', |
| 1063 |
__( 'Value passed for force_https_canonicals must be either "true" or "false".', 'wp-parsely' ) |
| 1064 |
); |
| 1065 |
} else { |
| 1066 |
$input['force_https_canonicals'] = 'true' === $input['force_https_canonicals']; |
| 1067 |
} |
| 1068 |
|
| 1069 |
return $input; |
| 1070 |
} |
| 1071 |
|
| 1072 |
/** |
| 1073 |
* Validates the passed API key. |
| 1074 |
* |
| 1075 |
* Accepts a www prefix and up to 3 periods. |
| 1076 |
* |
| 1077 |
* Valid examples: 'test.com', 'www.test.com', 'subdomain.test.com', |
| 1078 |
* 'www.subdomain.test.com', 'subdomain.subdomain.test.com'. |
| 1079 |
* |
| 1080 |
* Invalid examples: 'test', 'test.com/', 'http://test.com', 'https://test.com', |
| 1081 |
* 'www.subdomain.subdomain.test.com'. |
| 1082 |
* |
| 1083 |
* @since 3.3.0 |
| 1084 |
* |
| 1085 |
* @param string $api_key The API key to be validated. |
| 1086 |
* @return bool |
| 1087 |
*/ |
| 1088 |
private function validate_api_key( string $api_key ): bool { |
| 1089 |
$key_format = '/^((\w+)\.)?(([\w-]+)?)(\.[\w-]+){1,2}$/'; |
| 1090 |
|
| 1091 |
return 1 === preg_match( $key_format, $api_key ); |
| 1092 |
} |
| 1093 |
|
| 1094 |
/** |
| 1095 |
* Sanitizes the passed API key. |
| 1096 |
* |
| 1097 |
* @since 3.3.0 |
| 1098 |
* |
| 1099 |
* @param string $api_key The API key to be sanitized. |
| 1100 |
* @return string |
| 1101 |
*/ |
| 1102 |
private function sanitize_api_key( string $api_key ): string { |
| 1103 |
return strtolower( sanitize_text_field( $api_key ) ); |
| 1104 |
} |
| 1105 |
|
| 1106 |
/** |
| 1107 |
* Receives the $input array from the validate_options() function and |
| 1108 |
* validate post tracking options. |
| 1109 |
* |
| 1110 |
* This function will mutate the $input array. |
| 1111 |
* |
| 1112 |
* @since 3.2.0 |
| 1113 |
* |
| 1114 |
* @param array $input Array passed to validate_options() function. |
| 1115 |
*/ |
| 1116 |
private function validate_options_post_type_tracking( array &$input ): void { |
| 1117 |
$options = $this->parsely->get_options(); |
| 1118 |
$posts = 'track_post_types'; |
| 1119 |
$pages = 'track_page_types'; |
| 1120 |
$track_as = 'track_post_types_as'; |
| 1121 |
$input[ $posts ] = $options[ $posts ]; |
| 1122 |
$input[ $pages ] = $options[ $pages ]; |
| 1123 |
|
| 1124 |
if ( isset( $input[ $track_as ] ) && is_array( $input[ $track_as ] ) && 0 < count( $input[ $track_as ] ) ) { |
| 1125 |
$post_types = get_post_types( array( 'public' => true ) ); |
| 1126 |
$temp_posts = array(); |
| 1127 |
$temp_pages = array(); |
| 1128 |
|
| 1129 |
// Create temporary Post and Page arrays, disallowing non-existent post types. |
| 1130 |
foreach ( $input[ $track_as ] as $key => $value ) { |
| 1131 |
if ( false === in_array( $key, $post_types, true ) ) { |
| 1132 |
continue; |
| 1133 |
} |
| 1134 |
|
| 1135 |
if ( 'post' === $value ) { |
| 1136 |
$temp_posts[] = $key; |
| 1137 |
} elseif ( 'page' === $value ) { |
| 1138 |
$temp_pages[] = $key; |
| 1139 |
} |
| 1140 |
} |
| 1141 |
|
| 1142 |
// Cleanup and sanitized values assignment. |
| 1143 |
$input [ $posts ] = self::sanitize_option_array( $temp_posts ); |
| 1144 |
$input [ $pages ] = self::sanitize_option_array( $temp_pages ); |
| 1145 |
} |
| 1146 |
|
| 1147 |
if ( isset( $input[ $track_as ] ) ) { |
| 1148 |
unset( $input[ $track_as ] ); |
| 1149 |
} |
| 1150 |
} |
| 1151 |
|
| 1152 |
/** |
| 1153 |
* Returns default logo if one can be found. |
| 1154 |
* |
| 1155 |
* @return string |
| 1156 |
*/ |
| 1157 |
private static function get_logo_default(): string { |
| 1158 |
$custom_logo_id = get_theme_mod( 'custom_logo' ); |
| 1159 |
if ( $custom_logo_id ) { |
| 1160 |
$logo_attrs = wp_get_attachment_image_src( $custom_logo_id, 'full' ); |
| 1161 |
if ( $logo_attrs ) { |
| 1162 |
return $logo_attrs[0]; |
| 1163 |
} |
| 1164 |
} |
| 1165 |
|
| 1166 |
// get_site_icon_url returns an empty string if one isn't found, |
| 1167 |
// which is what we want to use as the default anyway. |
| 1168 |
return get_site_icon_url(); |
| 1169 |
} |
| 1170 |
|
| 1171 |
/** |
| 1172 |
* Sanitizes all elements in an option array. |
| 1173 |
* |
| 1174 |
* @param array $array Array of options to be sanitized. |
| 1175 |
* @return array |
| 1176 |
*/ |
| 1177 |
private static function sanitize_option_array( array $array ): array { |
| 1178 |
$new_array = $array; |
| 1179 |
foreach ( $array as $key => $val ) { |
| 1180 |
$new_array[ $key ] = sanitize_text_field( $val ); |
| 1181 |
} |
| 1182 |
return $new_array; |
| 1183 |
} |
| 1184 |
} |
| 1185 |
|