an_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-' * '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; } }