123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905 |
- <?php
- /**
- * WPSEO plugin file.
- *
- * @package WPSEO\Internals\Options
- */
- /**
- * Option: wpseo_titles.
- */
- class WPSEO_Option_Titles extends WPSEO_Option {
- /**
- * Option name.
- *
- * @var string
- */
- public $option_name = 'wpseo_titles';
- /**
- * Array of defaults for the option.
- *
- * Shouldn't be requested directly, use $this->get_defaults();
- *
- * {@internal Note: Some of the default values are added via the translate_defaults() method.}}
- *
- * @var array
- */
- protected $defaults = [
- // Non-form fields, set via (ajax) function.
- 'title_test' => 0,
- // Form fields.
- 'forcerewritetitle' => false,
- 'separator' => 'sc-dash',
- 'title-home-wpseo' => '%%sitename%% %%page%% %%sep%% %%sitedesc%%', // Text field.
- 'title-author-wpseo' => '', // Text field.
- 'title-archive-wpseo' => '%%date%% %%page%% %%sep%% %%sitename%%', // Text field.
- 'title-search-wpseo' => '', // Text field.
- 'title-404-wpseo' => '', // Text field.
- 'metadesc-home-wpseo' => '', // Text area.
- 'metadesc-author-wpseo' => '', // Text area.
- 'metadesc-archive-wpseo' => '', // Text area.
- 'rssbefore' => '', // Text area.
- 'rssafter' => '', // Text area.
- 'noindex-author-wpseo' => false,
- 'noindex-author-noposts-wpseo' => true,
- 'noindex-archive-wpseo' => true,
- 'disable-author' => false,
- 'disable-date' => false,
- 'disable-post_format' => false,
- 'disable-attachment' => true,
- 'is-media-purge-relevant' => false,
- 'breadcrumbs-404crumb' => '', // Text field.
- 'breadcrumbs-display-blog-page' => true,
- 'breadcrumbs-boldlast' => false,
- 'breadcrumbs-archiveprefix' => '', // Text field.
- 'breadcrumbs-enable' => false,
- 'breadcrumbs-home' => '', // Text field.
- 'breadcrumbs-prefix' => '', // Text field.
- 'breadcrumbs-searchprefix' => '', // Text field.
- 'breadcrumbs-sep' => '»', // Text field.
- 'website_name' => '',
- 'person_name' => '',
- 'person_logo' => '',
- 'person_logo_id' => 0,
- 'alternate_website_name' => '',
- 'company_logo' => '',
- 'company_logo_id' => 0,
- 'company_name' => '',
- 'company_or_person' => 'company',
- 'company_or_person_user_id' => false,
- 'stripcategorybase' => false,
- /**
- * Uses enrich_defaults to add more along the lines of:
- * - 'title-' . $pt->name => ''; // Text field.
- * - 'metadesc-' . $pt->name => ''; // Text field.
- * - 'noindex-' . $pt->name => false;
- * - 'showdate-' . $pt->name => false;
- * - 'display-metabox-pt-' . $pt->name => false;
- *
- * - 'title-ptarchive-' . $pt->name => ''; // Text field.
- * - 'metadesc-ptarchive-' . $pt->name => ''; // Text field.
- * - 'bctitle-ptarchive-' . $pt->name => ''; // Text field.
- * - 'noindex-ptarchive-' . $pt->name => false;
- *
- * - 'title-tax-' . $tax->name => '''; // Text field.
- * - 'metadesc-tax-' . $tax->name => ''; // Text field.
- * - 'noindex-tax-' . $tax->name => false;
- * - 'display-metabox-tax-' . $tax->name => false;
- */
- ];
- /**
- * Used for "caching" during pageload.
- *
- * @var array
- */
- protected $enriched_defaults = null;
- /**
- * Array of variable option name patterns for the option.
- *
- * @var array
- */
- protected $variable_array_key_patterns = [
- 'title-',
- 'metadesc-',
- 'noindex-',
- 'showdate-',
- 'display-metabox-pt-',
- 'bctitle-ptarchive-',
- 'post_types-',
- 'taxonomy-',
- ];
- /**
- * Array of sub-options which should not be overloaded with multi-site defaults.
- *
- * @var array
- */
- public $ms_exclude = [
- /* Theme dependent. */
- 'title_test',
- 'forcerewritetitle',
- ];
- /**
- * Add the actions and filters for the option.
- *
- * @todo [JRF => testers] Check if the extra actions below would run into problems if an option
- * is updated early on and if so, change the call to schedule these for a later action on add/update
- * instead of running them straight away.
- */
- protected function __construct() {
- parent::__construct();
- add_action( 'update_option_' . $this->option_name, [ 'WPSEO_Utils', 'clear_cache' ] );
- add_action( 'init', [ $this, 'end_of_init' ], 999 );
- add_action( 'registered_post_type', [ $this, 'invalidate_enrich_defaults_cache' ] );
- add_action( 'unregistered_post_type', [ $this, 'invalidate_enrich_defaults_cache' ] );
- add_action( 'registered_taxonomy', [ $this, 'invalidate_enrich_defaults_cache' ] );
- add_action( 'unregistered_taxonomy', [ $this, 'invalidate_enrich_defaults_cache' ] );
- add_filter( 'admin_title', [ 'Yoast_Input_Validation', 'add_yoast_admin_document_title_errors' ] );
- }
- /**
- * Make sure we can recognize the right action for the double cleaning.
- */
- public function end_of_init() {
- do_action( 'wpseo_double_clean_titles' );
- }
- /**
- * Get the singleton instance of this class.
- *
- * @return self
- */
- public static function get_instance() {
- if ( ! ( self::$instance instanceof self ) ) {
- self::$instance = new self();
- }
- return self::$instance;
- }
- /**
- * Get the available separator options.
- *
- * @return array
- */
- public function get_separator_options() {
- $separators = wp_list_pluck( self::get_separator_option_list(), 'option' );
- /**
- * Allow altering the array with separator options.
- *
- * @api array $separator_options Array with the separator options.
- */
- $filtered_separators = apply_filters( 'wpseo_separator_options', $separators );
- if ( is_array( $filtered_separators ) && $filtered_separators !== [] ) {
- $separators = array_merge( $separators, $filtered_separators );
- }
- return $separators;
- }
- /**
- * Get the available separator options aria-labels.
- *
- * @return array Array with the separator options aria-labels.
- */
- public function get_separator_options_for_display() {
- $separators = $this->get_separator_options();
- $separator_list = self::get_separator_option_list();
- $separator_options = [];
- foreach ( $separators as $key => $label ) {
- $aria_label = isset( $separator_list[ $key ]['label'] ) ? $separator_list[ $key ]['label'] : '';
- $separator_options[ $key ] = [
- 'label' => $label,
- 'aria_label' => $aria_label,
- ];
- }
- return $separator_options;
- }
- /**
- * Translate strings used in the option defaults.
- *
- * @return void
- */
- public function translate_defaults() {
- /* translators: 1: Author name; 2: Site name. */
- $this->defaults['title-author-wpseo'] = sprintf( __( '%1$s, Author at %2$s', 'wordpress-seo' ), '%%name%%', '%%sitename%%' ) . ' %%page%% ';
- /* translators: %s expands to the search phrase. */
- $this->defaults['title-search-wpseo'] = sprintf( __( 'You searched for %s', 'wordpress-seo' ), '%%searchphrase%%' ) . ' %%page%% %%sep%% %%sitename%%';
- $this->defaults['title-404-wpseo'] = __( 'Page not found', 'wordpress-seo' ) . ' %%sep%% %%sitename%%';
- /* translators: 1: link to post; 2: link to blog. */
- $this->defaults['rssafter'] = sprintf( __( 'The post %1$s appeared first on %2$s.', 'wordpress-seo' ), '%%POSTLINK%%', '%%BLOGLINK%%' );
- $this->defaults['breadcrumbs-404crumb'] = __( 'Error 404: Page not found', 'wordpress-seo' );
- $this->defaults['breadcrumbs-archiveprefix'] = __( 'Archives for', 'wordpress-seo' );
- $this->defaults['breadcrumbs-home'] = __( 'Home', 'wordpress-seo' );
- $this->defaults['breadcrumbs-searchprefix'] = __( 'You searched for', 'wordpress-seo' );
- }
- /**
- * Add dynamically created default options based on available post types and taxonomies.
- *
- * @return void
- */
- public function enrich_defaults() {
- $enriched_defaults = $this->enriched_defaults;
- if ( null !== $enriched_defaults ) {
- $this->defaults += $enriched_defaults;
- return;
- }
- $enriched_defaults = [];
- /*
- * Retrieve all the relevant post type and taxonomy arrays.
- *
- * WPSEO_Post_Type::get_accessible_post_types() should *not* be used here.
- * These are the defaults and can be prepared for any public post type.
- */
- $post_type_objects = get_post_types( [ 'public' => true ], 'objects' );
- if ( $post_type_objects ) {
- /* translators: %s expands to the name of a post type (plural). */
- $archive = sprintf( __( '%s Archive', 'wordpress-seo' ), '%%pt_plural%%' );
- foreach ( $post_type_objects as $pt ) {
- $enriched_defaults[ 'title-' . $pt->name ] = '%%title%% %%page%% %%sep%% %%sitename%%'; // Text field.
- $enriched_defaults[ 'metadesc-' . $pt->name ] = ''; // Text area.
- $enriched_defaults[ 'noindex-' . $pt->name ] = false;
- $enriched_defaults[ 'showdate-' . $pt->name ] = false;
- $enriched_defaults[ 'display-metabox-pt-' . $pt->name ] = true;
- $enriched_defaults[ 'post_types-' . $pt->name . '-maintax' ] = 0; // Select box.
- if ( ! $pt->_builtin && WPSEO_Post_Type::has_archive( $pt ) ) {
- $enriched_defaults[ 'title-ptarchive-' . $pt->name ] = $archive . ' %%page%% %%sep%% %%sitename%%'; // Text field.
- $enriched_defaults[ 'metadesc-ptarchive-' . $pt->name ] = ''; // Text area.
- $enriched_defaults[ 'bctitle-ptarchive-' . $pt->name ] = ''; // Text field.
- $enriched_defaults[ 'noindex-ptarchive-' . $pt->name ] = false;
- }
- }
- }
- $taxonomy_objects = get_taxonomies( [ 'public' => true ], 'object' );
- if ( $taxonomy_objects ) {
- /* translators: %s expands to the variable used for term title. */
- $archives = sprintf( __( '%s Archives', 'wordpress-seo' ), '%%term_title%%' );
- foreach ( $taxonomy_objects as $tax ) {
- $enriched_defaults[ 'title-tax-' . $tax->name ] = $archives . ' %%page%% %%sep%% %%sitename%%'; // Text field.
- $enriched_defaults[ 'metadesc-tax-' . $tax->name ] = ''; // Text area.
- $enriched_defaults[ 'display-metabox-tax-' . $tax->name ] = true;
- $enriched_defaults[ 'noindex-tax-' . $tax->name ] = ( $tax->name === 'post_format' );
- if ( ! $tax->_builtin ) {
- $enriched_defaults[ 'taxonomy-' . $tax->name . '-ptparent' ] = 0; // Select box;.
- }
- }
- }
- $this->enriched_defaults = $enriched_defaults;
- $this->defaults += $enriched_defaults;
- }
- /**
- * Invalidates enrich_defaults() cache.
- *
- * Called from actions:
- * - (un)registered_post_type
- * - (un)registered_taxonomy
- *
- * @return void
- */
- public function invalidate_enrich_defaults_cache() {
- $this->enriched_defaults = null;
- }
- /**
- * Validate the option.
- *
- * @param array $dirty New value for the option.
- * @param array $clean Clean value for the option, normally the defaults.
- * @param array $old Old value of the option.
- *
- * @return array Validated clean value for the option to be saved to the database.
- */
- protected function validate_option( $dirty, $clean, $old ) {
- $allowed_post_types = $this->get_allowed_post_types();
- foreach ( $clean as $key => $value ) {
- $switch_key = $this->get_switch_key( $key );
- switch ( $switch_key ) {
- /* Breadcrumbs text fields. */
- case 'breadcrumbs-404crumb':
- case 'breadcrumbs-archiveprefix':
- case 'breadcrumbs-home':
- case 'breadcrumbs-prefix':
- case 'breadcrumbs-searchprefix':
- case 'breadcrumbs-sep':
- if ( isset( $dirty[ $key ] ) ) {
- $clean[ $key ] = wp_kses_post( $dirty[ $key ] );
- }
- break;
- /*
- * Text fields.
- */
- /*
- * Covers:
- * 'title-home-wpseo', 'title-author-wpseo', 'title-archive-wpseo',
- * 'title-search-wpseo', 'title-404-wpseo'
- * 'title-' . $pt->name
- * 'title-ptarchive-' . $pt->name
- * 'title-tax-' . $tax->name
- */
- case 'website_name':
- case 'alternate_website_name':
- case 'title-':
- if ( isset( $dirty[ $key ] ) ) {
- $clean[ $key ] = WPSEO_Utils::sanitize_text_field( $dirty[ $key ] );
- }
- break;
- case 'company_or_person':
- if ( isset( $dirty[ $key ] ) ) {
- if ( in_array( $dirty[ $key ], [ 'company', 'person' ], true ) ) {
- $clean[ $key ] = $dirty[ $key ];
- }
- else {
- $defaults = $this->get_defaults();
- $clean[ $key ] = $defaults['company_or_person'];
- }
- }
- break;
- case 'company_logo':
- case 'person_logo':
- $this->validate_url( $key, $dirty, $old, $clean );
- break;
- /*
- * Covers:
- * 'metadesc-home-wpseo', 'metadesc-author-wpseo', 'metadesc-archive-wpseo'
- * 'metadesc-' . $pt->name
- * 'metadesc-ptarchive-' . $pt->name
- * 'metadesc-tax-' . $tax->name
- * and also:
- * 'bctitle-ptarchive-' . $pt->name
- */
- case 'metadesc-':
- case 'bctitle-ptarchive-':
- case 'company_name':
- case 'person_name':
- if ( isset( $dirty[ $key ] ) && $dirty[ $key ] !== '' ) {
- $clean[ $key ] = WPSEO_Utils::sanitize_text_field( $dirty[ $key ] );
- }
- break;
- /*
- * Covers: 'rssbefore', 'rssafter'
- */
- case 'rssbefore':
- case 'rssafter':
- if ( isset( $dirty[ $key ] ) ) {
- $clean[ $key ] = wp_kses_post( $dirty[ $key ] );
- }
- break;
- /* 'post_types-' . $pt->name . '-maintax' fields. */
- case 'post_types-':
- $post_type = str_replace( [ 'post_types-', '-maintax' ], '', $key );
- $taxonomies = get_object_taxonomies( $post_type, 'names' );
- if ( isset( $dirty[ $key ] ) ) {
- if ( $taxonomies !== [] && in_array( $dirty[ $key ], $taxonomies, true ) ) {
- $clean[ $key ] = $dirty[ $key ];
- }
- elseif ( (string) $dirty[ $key ] === '0' || (string) $dirty[ $key ] === '' ) {
- $clean[ $key ] = 0;
- }
- elseif ( sanitize_title_with_dashes( $dirty[ $key ] ) === $dirty[ $key ] ) {
- // Allow taxonomies which may not be registered yet.
- $clean[ $key ] = $dirty[ $key ];
- }
- else {
- if ( isset( $old[ $key ] ) ) {
- $clean[ $key ] = sanitize_title_with_dashes( $old[ $key ] );
- }
- /*
- * @todo [JRF => whomever] Maybe change the untranslated $pt name in the
- * error message to the nicely translated label ?
- */
- add_settings_error(
- $this->group_name, // Slug title of the setting.
- $key, // Suffix-id for the error message box.
- /* translators: %s expands to a post type. */
- sprintf( __( 'Please select a valid taxonomy for post type "%s"', 'wordpress-seo' ), $post_type ), // The error message.
- 'error' // Error type, either 'error' or 'updated'.
- );
- }
- }
- elseif ( isset( $old[ $key ] ) ) {
- $clean[ $key ] = sanitize_title_with_dashes( $old[ $key ] );
- }
- unset( $taxonomies, $post_type );
- break;
- /* 'taxonomy-' . $tax->name . '-ptparent' fields. */
- case 'taxonomy-':
- if ( isset( $dirty[ $key ] ) ) {
- if ( $allowed_post_types !== [] && in_array( $dirty[ $key ], $allowed_post_types, true ) ) {
- $clean[ $key ] = $dirty[ $key ];
- }
- elseif ( (string) $dirty[ $key ] === '0' || (string) $dirty[ $key ] === '' ) {
- $clean[ $key ] = 0;
- }
- elseif ( sanitize_key( $dirty[ $key ] ) === $dirty[ $key ] ) {
- // Allow taxonomies which may not be registered yet.
- $clean[ $key ] = $dirty[ $key ];
- }
- else {
- if ( isset( $old[ $key ] ) ) {
- $clean[ $key ] = sanitize_key( $old[ $key ] );
- }
- /*
- * @todo [JRF =? whomever] Maybe change the untranslated $tax name in the
- * error message to the nicely translated label ?
- */
- $tax = str_replace( [ 'taxonomy-', '-ptparent' ], '', $key );
- add_settings_error(
- $this->group_name, // Slug title of the setting.
- '_' . $tax, // Suffix-ID for the error message box.
- /* translators: %s expands to a taxonomy slug. */
- sprintf( __( 'Please select a valid post type for taxonomy "%s"', 'wordpress-seo' ), $tax ), // The error message.
- 'error' // Error type, either 'error' or 'updated'.
- );
- unset( $tax );
- }
- }
- elseif ( isset( $old[ $key ] ) ) {
- $clean[ $key ] = sanitize_key( $old[ $key ] );
- }
- break;
- case 'company_or_person_user_id':
- case 'company_logo_id':
- case 'person_logo_id':
- case 'title_test': /* Integer field - not in form. */
- if ( isset( $dirty[ $key ] ) ) {
- $int = WPSEO_Utils::validate_int( $dirty[ $key ] );
- if ( $int !== false && $int >= 0 ) {
- $clean[ $key ] = $int;
- }
- }
- elseif ( isset( $old[ $key ] ) ) {
- $int = WPSEO_Utils::validate_int( $old[ $key ] );
- if ( $int !== false && $int >= 0 ) {
- $clean[ $key ] = $int;
- }
- }
- break;
- /* Separator field - Radio. */
- case 'separator':
- if ( isset( $dirty[ $key ] ) && $dirty[ $key ] !== '' ) {
- // Get separator fields.
- $separator_fields = $this->get_separator_options();
- // Check if the given separator exists.
- if ( isset( $separator_fields[ $dirty[ $key ] ] ) ) {
- $clean[ $key ] = $dirty[ $key ];
- }
- }
- break;
- /*
- * Boolean fields.
- */
- /*
- * Covers:
- * 'noindex-author-wpseo', 'noindex-author-noposts-wpseo', 'noindex-archive-wpseo'
- * 'noindex-' . $pt->name
- * 'noindex-ptarchive-' . $pt->name
- * 'noindex-tax-' . $tax->name
- * 'forcerewritetitle':
- * 'noodp':
- * 'noydir':
- * 'disable-author':
- * 'disable-date':
- * 'disable-post_format';
- * 'noindex-'
- * 'showdate-'
- * 'showdate-'. $pt->name
- * 'display-metabox-pt-'
- * 'display-metabox-pt-'. $pt->name
- * 'display-metabox-tax-'
- * 'display-metabox-tax-' . $tax->name
- * 'breadcrumbs-display-blog-page'
- * 'breadcrumbs-boldlast'
- * 'breadcrumbs-enable'
- * 'stripcategorybase'
- * 'is-media-purge-relevant'
- */
- default:
- $clean[ $key ] = ( isset( $dirty[ $key ] ) ? WPSEO_Utils::validate_bool( $dirty[ $key ] ) : false );
- break;
- }
- }
- return $clean;
- }
- /**
- * Retrieve a list of the allowed post types as breadcrumb parent for a taxonomy.
- * Helper method for validation.
- *
- * {@internal Don't make static as new types may still be registered.}}
- *
- * @return array
- */
- protected function get_allowed_post_types() {
- $allowed_post_types = [];
- /*
- * WPSEO_Post_Type::get_accessible_post_types() should *not* be used here.
- */
- $post_types = get_post_types( [ 'public' => true ], 'objects' );
- if ( get_option( 'show_on_front' ) === 'page' && get_option( 'page_for_posts' ) > 0 ) {
- $allowed_post_types[] = 'post';
- }
- if ( is_array( $post_types ) && $post_types !== [] ) {
- foreach ( $post_types as $type ) {
- if ( WPSEO_Post_Type::has_archive( $type ) ) {
- $allowed_post_types[] = $type->name;
- }
- }
- }
- return $allowed_post_types;
- }
- /**
- * Clean a given option value.
- *
- * @param array $option_value Old (not merged with defaults or filtered) option value to
- * clean according to the rules for this option.
- * @param string $current_version Optional. Version from which to upgrade, if not set,
- * version specific upgrades will be disregarded.
- * @param array $all_old_option_values Optional. Only used when importing old options to have
- * access to the real old values, in contrast to the saved ones.
- *
- * @return array Cleaned option.
- */
- protected function clean_option( $option_value, $current_version = null, $all_old_option_values = null ) {
- static $original = null;
- // Double-run this function to ensure renaming of the taxonomy options will work.
- if ( ! isset( $original )
- && has_action( 'wpseo_double_clean_titles', [ $this, 'clean' ] ) === false
- ) {
- add_action( 'wpseo_double_clean_titles', [ $this, 'clean' ] );
- $original = $option_value;
- }
- /*
- * Move options from very old option to this one.
- *
- * {@internal Don't rename to the 'current' names straight away as that would prevent
- * the rename/unset combi below from working.}}
- *
- * @todo [JRF] Maybe figure out a smarter way to deal with this.
- */
- $old_option = null;
- if ( isset( $all_old_option_values ) ) {
- // Ok, we have an import.
- if ( isset( $all_old_option_values['wpseo_indexation'] ) && is_array( $all_old_option_values['wpseo_indexation'] ) && $all_old_option_values['wpseo_indexation'] !== [] ) {
- $old_option = $all_old_option_values['wpseo_indexation'];
- }
- }
- else {
- $old_option = get_option( 'wpseo_indexation' );
- }
- if ( is_array( $old_option ) && $old_option !== [] ) {
- $move = [
- 'noindexauthor' => 'noindex-author',
- 'disableauthor' => 'disable-author',
- 'noindexdate' => 'noindex-archive',
- 'noindexcat' => 'noindex-category',
- 'noindextag' => 'noindex-post_tag',
- 'noindexpostformat' => 'noindex-post_format',
- ];
- foreach ( $move as $old => $new ) {
- if ( isset( $old_option[ $old ] ) && ! isset( $option_value[ $new ] ) ) {
- $option_value[ $new ] = $old_option[ $old ];
- }
- }
- unset( $move, $old, $new );
- }
- unset( $old_option );
- // Fix wrongness created by buggy version 1.2.2.
- if ( isset( $option_value['title-home'] ) && $option_value['title-home'] === '%%sitename%% - %%sitedesc%% - 12345' ) {
- $option_value['title-home-wpseo'] = '%%sitename%% - %%sitedesc%%';
- }
- /*
- * Renaming these options to avoid ever overwritting these if a (bloody stupid) user /
- * programmer would use any of the following as a custom post type or custom taxonomy:
- * 'home', 'author', 'archive', 'search', '404', 'subpages'.
- *
- * Similarly, renaming the tax options to avoid a custom post type and a taxonomy
- * with the same name occupying the same option.
- */
- $rename = [
- 'title-home' => 'title-home-wpseo',
- 'title-author' => 'title-author-wpseo',
- 'title-archive' => 'title-archive-wpseo',
- 'title-search' => 'title-search-wpseo',
- 'title-404' => 'title-404-wpseo',
- 'metadesc-home' => 'metadesc-home-wpseo',
- 'metadesc-author' => 'metadesc-author-wpseo',
- 'metadesc-archive' => 'metadesc-archive-wpseo',
- 'noindex-author' => 'noindex-author-wpseo',
- 'noindex-archive' => 'noindex-archive-wpseo',
- ];
- foreach ( $rename as $old => $new ) {
- if ( isset( $option_value[ $old ] ) && ! isset( $option_value[ $new ] ) ) {
- $option_value[ $new ] = $option_value[ $old ];
- unset( $option_value[ $old ] );
- }
- }
- unset( $rename, $old, $new );
- /*
- * {@internal This clean-up action can only be done effectively once the taxonomies
- * and post_types have been registered, i.e. at the end of the init action.}}
- */
- if ( isset( $original ) && current_filter() === 'wpseo_double_clean_titles' || did_action( 'wpseo_double_clean_titles' ) > 0 ) {
- $rename = [
- 'title-' => 'title-tax-',
- 'metadesc-' => 'metadesc-tax-',
- 'noindex-' => 'noindex-tax-',
- 'tax-hideeditbox-' => 'hideeditbox-tax-',
- ];
- $taxonomy_names = get_taxonomies( [ 'public' => true ], 'names' );
- $post_type_names = get_post_types( [ 'public' => true ], 'names' );
- $defaults = $this->get_defaults();
- if ( $taxonomy_names !== [] ) {
- foreach ( $taxonomy_names as $tax ) {
- foreach ( $rename as $old_prefix => $new_prefix ) {
- if (
- ( isset( $original[ $old_prefix . $tax ] ) && ! isset( $original[ $new_prefix . $tax ] ) )
- && ( ! isset( $option_value[ $new_prefix . $tax ] )
- || ( isset( $option_value[ $new_prefix . $tax ] )
- && $option_value[ $new_prefix . $tax ] === $defaults[ $new_prefix . $tax ] ) )
- ) {
- $option_value[ $new_prefix . $tax ] = $original[ $old_prefix . $tax ];
- /*
- * Check if there is a cpt with the same name as the tax,
- * if so, we should make sure that the old setting hasn't been removed.
- */
- if ( ! isset( $post_type_names[ $tax ] ) && isset( $option_value[ $old_prefix . $tax ] ) ) {
- unset( $option_value[ $old_prefix . $tax ] );
- }
- else {
- if ( isset( $post_type_names[ $tax ] ) && ! isset( $option_value[ $old_prefix . $tax ] ) ) {
- $option_value[ $old_prefix . $tax ] = $original[ $old_prefix . $tax ];
- }
- }
- if ( $old_prefix === 'tax-hideeditbox-' ) {
- unset( $option_value[ $old_prefix . $tax ] );
- }
- }
- }
- }
- }
- unset( $rename, $taxonomy_names, $post_type_names, $defaults, $tax, $old_prefix, $new_prefix );
- }
- /*
- * Make sure the values of the variable option key options are cleaned as they
- * may be retained and would not be cleaned/validated then.
- */
- if ( is_array( $option_value ) && $option_value !== [] ) {
- foreach ( $option_value as $key => $value ) {
- $switch_key = $this->get_switch_key( $key );
- // Similar to validation routine - any changes made there should be made here too.
- switch ( $switch_key ) {
- /* Text fields. */
- case 'title-':
- case 'metadesc-':
- case 'bctitle-ptarchive-':
- $option_value[ $key ] = WPSEO_Utils::sanitize_text_field( $value );
- break;
- case 'separator':
- if ( ! array_key_exists( $value, $this->get_separator_options() ) ) {
- $option_value[ $key ] = false;
- }
- break;
- /*
- * Boolean fields.
- */
- /*
- * Covers:
- * 'noindex-'
- * 'showdate-'
- * 'hideeditbox-'
- */
- default:
- $option_value[ $key ] = WPSEO_Utils::validate_bool( $value );
- break;
- }
- }
- unset( $key, $value, $switch_key );
- }
- return $option_value;
- }
- /**
- * Make sure that any set option values relating to post_types and/or taxonomies are retained,
- * even when that post_type or taxonomy may not yet have been registered.
- *
- * {@internal Overrule the abstract class version of this to make sure one extra renamed
- * variable key does not get removed. IMPORTANT: keep this method in line with
- * the parent on which it is based!}}
- *
- * @param array $dirty Original option as retrieved from the database.
- * @param array $clean Filtered option where any options which shouldn't be in our option
- * have already been removed and any options which weren't set
- * have been set to their defaults.
- *
- * @return array
- */
- protected function retain_variable_keys( $dirty, $clean ) {
- if ( ( is_array( $this->variable_array_key_patterns ) && $this->variable_array_key_patterns !== [] ) && ( is_array( $dirty ) && $dirty !== [] ) ) {
- // Add the extra pattern.
- $patterns = $this->variable_array_key_patterns;
- $patterns[] = 'tax-hideeditbox-';
- /**
- * Allow altering the array with variable array key patterns.
- *
- * @api array $patterns Array with the variable array key patterns.
- */
- $patterns = apply_filters( 'wpseo_option_titles_variable_array_key_patterns', $patterns );
- foreach ( $dirty as $key => $value ) {
- // Do nothing if already in filtered option array.
- if ( isset( $clean[ $key ] ) ) {
- continue;
- }
- foreach ( $patterns as $pattern ) {
- if ( strpos( $key, $pattern ) === 0 ) {
- $clean[ $key ] = $value;
- break;
- }
- }
- }
- }
- return $clean;
- }
- /**
- * Retrieves a list of separator options.
- *
- * @return array An array of the separator options.
- */
- protected static function get_separator_option_list() {
- $separators = [
- 'sc-dash' => [
- 'option' => '-',
- 'label' => __( 'Dash', 'wordpress-seo' ),
- ],
- 'sc-ndash' => [
- 'option' => '–',
- 'label' => __( 'En dash', 'wordpress-seo' ),
- ],
- 'sc-mdash' => [
- 'option' => '—',
- 'label' => __( 'Em dash', 'wordpress-seo' ),
- ],
- 'sc-colon' => [
- 'option' => ':',
- 'label' => __( 'Colon', 'wordpress-seo' ),
- ],
- 'sc-middot' => [
- 'option' => '·',
- 'label' => __( 'Middle dot', 'wordpress-seo' ),
- ],
- 'sc-bull' => [
- 'option' => '•',
- 'label' => __( 'Bullet', 'wordpress-seo' ),
- ],
- 'sc-star' => [
- 'option' => '*',
- 'label' => __( 'Asterisk', 'wordpress-seo' ),
- ],
- 'sc-smstar' => [
- 'option' => '⋆',
- 'label' => __( 'Low asterisk', 'wordpress-seo' ),
- ],
- 'sc-pipe' => [
- 'option' => '|',
- 'label' => __( 'Vertical bar', 'wordpress-seo' ),
- ],
- 'sc-tilde' => [
- 'option' => '~',
- 'label' => __( 'Small tilde', 'wordpress-seo' ),
- ],
- 'sc-laquo' => [
- 'option' => '«',
- 'label' => __( 'Left angle quotation mark', 'wordpress-seo' ),
- ],
- 'sc-raquo' => [
- 'option' => '»',
- 'label' => __( 'Right angle quotation mark', 'wordpress-seo' ),
- ],
- 'sc-lt' => [
- 'option' => '<',
- 'label' => __( 'Less than sign', 'wordpress-seo' ),
- ],
- 'sc-gt' => [
- 'option' => '>',
- 'label' => __( 'Greater than sign', 'wordpress-seo' ),
- ],
- ];
- /**
- * Allows altering the separator options array.
- *
- * @api array $separators Array with the separator options.
- */
- $separator_list = apply_filters( 'wpseo_separator_option_list', $separators );
- if ( ! is_array( $separator_list ) ) {
- return $separators;
- }
- return $separator_list;
- }
- }
|