: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Prepares the replace vars for localization.
* @return string[] Replace vars.
private function get_replace_vars() {
$cached_replacement_vars = [];
foreach ( $vars_to_cache as $var ) {
$cached_replacement_vars[ $var ] = wpseo_replace_vars( '%%' . $var . '%%', $this->get_metabox_post() );
// Merge custom replace variables with the WordPress ones.
return array_merge( $cached_replacement_vars, $this->get_custom_replace_vars( $this->get_metabox_post() ) );
* Returns the list of replace vars that should be hidden inside the editor.
* @return string[] The hidden replace vars.
protected function get_hidden_replace_vars() {
return ( new WPSEO_Replace_Vars() )->get_hidden_replace_vars();
* Prepares the recommended replace vars for localization.
* @return array<string[]> Recommended replacement variables.
private function get_recommended_replace_vars() {
$recommended_replace_vars = new WPSEO_Admin_Recommended_Replace_Vars();
// What is recommended depends on the current context.
$post_type = $recommended_replace_vars->determine_for_post( $this->get_metabox_post() );
return $recommended_replace_vars->get_recommended_replacevars_for( $post_type );
* Gets the custom replace variables for custom taxonomies and fields.
* @param WP_Post $post The post to check for custom taxonomies and fields.
* @return array<string[]> Array containing all the replacement variables.
private function get_custom_replace_vars( $post ) {
'custom_fields' => $this->get_custom_fields_replace_vars( $post ),
'custom_taxonomies' => $this->get_custom_taxonomies_replace_vars( $post ),
* Gets the custom replace variables for custom taxonomies.
* @param WP_Post $post The post to check for custom taxonomies.
* @return array<string[]> Array containing all the replacement variables.
private function get_custom_taxonomies_replace_vars( $post ) {
$taxonomies = get_object_taxonomies( $post, 'objects' );
$custom_replace_vars = [];
foreach ( $taxonomies as $taxonomy_name => $taxonomy ) {
if ( is_string( $taxonomy ) ) { // If attachment, see https://core.trac.wordpress.org/ticket/37368 .
$taxonomy_name = $taxonomy;
$taxonomy = get_taxonomy( $taxonomy_name );
if ( $taxonomy->_builtin && $taxonomy->public ) {
$custom_replace_vars[ $taxonomy_name ] = [
'name' => $taxonomy->name,
'description' => $taxonomy->description,
return $custom_replace_vars;
* Gets the custom replace variables for custom fields.
* @param WP_Post $post The post to check for custom fields.
* @return array<string[]> Array containing all the replacement variables.
private function get_custom_fields_replace_vars( $post ) {
$custom_replace_vars = [];
// If no post object is passed, return the empty custom_replace_vars array.
if ( ! is_object( $post ) ) {
return $custom_replace_vars;
$custom_fields = get_post_custom( $post->ID );
// If $custom_fields is an empty string or generally not an array, return early.
if ( ! is_array( $custom_fields ) ) {
return $custom_replace_vars;
$meta = YoastSEO()->meta->for_post( $post->ID );
return $custom_replace_vars;
// Simply concatenate all fields containing replace vars so we can handle them all with a single regex find.
$replace_vars_fields = implode(
$meta->presentation->title,
$meta->presentation->meta_description,
preg_match_all( '/%%cf_([A-Za-z0-9_]+)%%/', $replace_vars_fields, $matches );
$fields_to_include = $matches[1];
foreach ( $custom_fields as $custom_field_name => $custom_field ) {
// Skip private custom fields.
if ( substr( $custom_field_name, 0, 1 ) === '_' ) {
// Skip custom fields that are not used, new ones will be fetched dynamically.
if ( ! in_array( $custom_field_name, $fields_to_include, true ) ) {
// Skip custom field values that are serialized.
if ( is_serialized( $custom_field[0] ) ) {
$custom_replace_vars[ $custom_field_name ] = $custom_field[0];
return $custom_replace_vars;
* Checks if the page is the post overview page.
* @param string $page The page to check for the post overview page.
* @return bool Whether or not the given page is the post overview page.
public static function is_post_overview( $page ) {
return $page === 'edit.php';
* Checks if the page is the post edit page.
* @param string $page The page to check for the post edit page.
* @return bool Whether or not the given page is the post edit page.
public static function is_post_edit( $page ) {
return $page === 'post.php'
|| $page === 'post-new.php';
* Retrieves the product title.
* @return string The product title.
protected function get_product_title() {
return YoastSEO()->helpers->product->get_product_name();