meta_helper = $meta_helper; } /** * Writes the title for a post. * * @param Update_Type $type The appearance the title belongs to. * @param int $post_id The ID of the post. * @param string $title The title to write. * * @return void */ public function write_title( Update_Type $type, int $post_id, string $title ): void { $key = $type->is_social() ? 'opengraph-title' : 'title'; $this->write( $key, $post_id, $title ); } /** * Writes the description for a post. * * @param Update_Type $type The appearance the description belongs to. * @param int $post_id The ID of the post. * @param string $description The description to write. * * @return void */ public function write_description( Update_Type $type, int $post_id, string $description ): void { $key = $type->is_social() ? 'opengraph-description' : 'metadesc'; $this->write( $key, $post_id, $description ); } /** * Writes the focus keyphrase for a post. The focus keyphrase is channel-agnostic, * so it does not depend on the update type. * * Returns the sanitized value that was actually stored, so callers can detect * when the input was silently altered (e.g. HTML stripped by sanitize_text_field). * * @param int $post_id The ID of the post. * @param string $focus_keyphrase The focus keyphrase to write. * * @return string The sanitized focus keyphrase that was persisted. */ public function write_focus_keyphrase( int $post_id, string $focus_keyphrase ): string { return $this->write( 'focuskw', $post_id, $focus_keyphrase ); } /** * Writes a per-field score for a post. * * The score is routed through the same sanitization as a normal post save, which clamps it to a * 0-100 integer. * * @param int $post_id The ID of the post. * @param string $key The score meta key (without prefix) to write. * @param int $score The 0-100 score to write. * * @return void */ public function write_score( int $post_id, string $key, int $score ): void { $this->write( $key, $post_id, (string) $score ); } /** * Sanitizes and persists a value under the given meta key. * * Returns the sanitized value so callers that need the stored value (e.g. to echo * it back in the REST response) do not have to re-read from the database. * * @param string $key The meta key (without prefix) to store the value under. * @param int $post_id The ID of the post. * @param string $value The value to write. * * @return string The sanitized value that was persisted. */ private function write( string $key, int $post_id, string $value ): string { $sanitized = $this->sanitize( $key, $value ); $this->meta_helper->set_value( $key, $sanitized, $post_id ); return $sanitized; } /** * Sanitizes a value the same way the post editor sanitizes meta values. * * Registered fields are routed through the canonical meta sanitizer so the * field-specific handling and the `wpseo_sanitize_post_meta_*` filter run, matching * a normal post save. Fields that are not registered (for example the Open Graph * fields when social appearance is disabled) have no canonical sanitize callback, so * they fall back to plain text sanitization. * * @param string $key The meta key (without prefix) the value is stored under. * @param string $value The value to sanitize. * * @return string The sanitized value. */ private function sanitize( string $key, string $value ): string { $meta_key = WPSEO_Meta::$meta_prefix . $key; if ( isset( WPSEO_Meta::$fields_index[ $meta_key ] ) ) { return WPSEO_Meta::sanitize_post_meta( $value, $meta_key ); } return WPSEO_Utils::sanitize_text_field( \trim( $value ) ); } }