resolver = $resolver; $this->field_map = $field_map; $this->post_access_checker = $post_access_checker; $this->indexable_to_postmeta = $indexable_to_postmeta; $this->indexable_builder = $indexable_builder; } /** * Updates the SEO data of the post matching the input and returns its new state. * * Only fields present in the input are changed (patch semantics); a present but * empty value clears the field. * * @param array $input The input identifying the post plus the SEO fields to change. * * @return array|WP_Error The updated SEO data, or an error. */ public function update_post_seo_data( array $input ) { $indexable = $this->resolver->resolve_one( $input ); if ( $indexable instanceof WP_Error ) { return $indexable; } // The capability gate on the ability is site-wide; the write itself is // only allowed on posts the user could also edit through the regular editors. $can_edit = $this->post_access_checker->ensure_can_edit( (int) $indexable->object_id ); if ( $can_edit instanceof WP_Error ) { return $can_edit; } $changed_columns = $this->field_map->apply_to_indexable( $input, $indexable ); foreach ( $changed_columns as $column ) { $this->indexable_to_postmeta->map_column_to_postmeta( $indexable, $column, true ); } // A post-meta write does not trigger the indexable watcher, so rebuild the read model // explicitly from the meta we just wrote. $rebuilt = $this->indexable_builder->build_for_id_and_type( (int) $indexable->object_id, 'post', $indexable ); if ( ! $rebuilt ) { return new WP_Error( 'yoast_seo_post_data_unavailable', \__( 'The post SEO data was saved but the indexable could not be rebuilt.', 'wordpress-seo' ), [ 'status' => 500 ], ); } return $this->field_map->to_seo_array( $rebuilt ); } }