ID; echo '

' . esc_html__( 'AI readiness (E-E-A-T)', 'acid-aeo' ) . '

'; echo '

' . esc_html__( 'Used in the author’s Person schema node, so an answer engine can attribute what it quotes.', 'acid-aeo' ) . '

'; wp_nonce_field( self::NONCE, self::NONCE . '_nonce' ); echo ''; $this->text_row( self::JOB_TITLE, __( 'Job title', 'acid-aeo' ), $this->meta( $user_id, self::JOB_TITLE ), __( 'For example: Lead Developer.', 'acid-aeo' ) ); $this->textarea_row( self::SAME_AS, __( 'Social profile URLs', 'acid-aeo' ), $this->meta( $user_id, self::SAME_AS ), __( 'One URL per line: LinkedIn, GitHub, X, a personal site.', 'acid-aeo' ) ); $this->text_row( self::KNOWS_ABOUT, __( 'Expertise topics', 'acid-aeo' ), $this->meta( $user_id, self::KNOWS_ABOUT ), __( 'Comma separated, for example: WordPress, UX research, SEO.', 'acid-aeo' ) ); $this->text_row( self::ALUMNI_OF, __( 'Alma mater', 'acid-aeo' ), $this->meta( $user_id, self::ALUMNI_OF ), __( 'The school or university this author graduated from.', 'acid-aeo' ) ); echo ''; } /** * Saves the section from a profile screen. * * @param mixed $user_id ID of the user being saved. * @return void */ public function save( $user_id ): void { $user_id = (int) $user_id; if ( $user_id <= 0 || ! current_user_can( 'edit_user', $user_id ) ) { return; } $nonce = isset( $_POST[ self::NONCE . '_nonce' ] ) ? sanitize_text_field( wp_unslash( $_POST[ self::NONCE . '_nonce' ] ) ) : ''; if ( '' === $nonce || ! wp_verify_nonce( $nonce, self::NONCE ) ) { return; } update_user_meta( $user_id, self::JOB_TITLE, sanitize_text_field( $this->posted( self::JOB_TITLE ) ) ); update_user_meta( $user_id, self::SAME_AS, $this->urls( $this->posted( self::SAME_AS ) ) ); update_user_meta( $user_id, self::KNOWS_ABOUT, sanitize_text_field( $this->posted( self::KNOWS_ABOUT ) ) ); update_user_meta( $user_id, self::ALUMNI_OF, sanitize_text_field( $this->posted( self::ALUMNI_OF ) ) ); } /** * One submitted field, unslashed and sanitized as plain text. * * Line breaks survive, because the profile URLs arrive one per line; every * caller narrows the value further for its own field. * * The caller has already verified the nonce and the capability. * * @param string $field Field name. * @return string Sanitized value, empty when the field was not posted. */ private function posted( string $field ): string { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Verified in save(), which is this method's only caller. if ( ! isset( $_POST[ $field ] ) || ! is_scalar( $_POST[ $field ] ) ) { return ''; } // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Verified in save(), which is this method's only caller. return sanitize_textarea_field( (string) wp_unslash( $_POST[ $field ] ) ); } /** * Keeps the lines of a textarea that are valid URLs. * * @param string $value Raw textarea value. * @return string One URL per line. */ private function urls( string $value ): string { $lines = preg_split( '/\R/', $value ); $urls = []; foreach ( is_array( $lines ) ? $lines : [] as $line ) { $url = esc_url_raw( trim( $line ) ); if ( '' !== $url ) { $urls[] = $url; } } return implode( "\n", array_unique( $urls ) ); } /** * One user meta value as a string. * * @param int $user_id User ID. * @param string $key Meta key. * @return string Meta value. */ private function meta( int $user_id, string $key ): string { $value = get_user_meta( $user_id, $key, true ); return is_scalar( $value ) ? (string) $value : ''; } /** * Renders one single line field. * * @param string $field Field name and meta key. * @param string $label Translated label. * @param string $value Current value. * @param string $description Translated help text. * @return void */ private function text_row( string $field, string $label, string $value, string $description ): void { printf( '

%4$s

', esc_attr( $field ), esc_html( $label ), esc_attr( $value ), esc_html( $description ) ); } /** * Renders one multi line field. * * @param string $field Field name and meta key. * @param string $label Translated label. * @param string $value Current value. * @param string $description Translated help text. * @return void */ private function textarea_row( string $field, string $label, string $value, string $description ): void { printf( '

%4$s

', esc_attr( $field ), esc_html( $label ), esc_textarea( $value ), esc_html( $description ) ); } }