File "data.php"
Full Path: /home/fresvfqn/waterdamagerestorationandrepairsmithtown.com/wp-content/plugins/surerank/inc/schema/data.php
File size: 11.6 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* Data Class
*
* Responsible for collecting and processing data for schemas.
*
* @since 1.0.0
* @package SureRank
*/
namespace SureRank\Inc\Schema;
use SureRank\Inc\Frontend\Breadcrumbs;
use SureRank\Inc\Frontend\Description;
use SureRank\Inc\Traits\Get_Instance;
use WP_Post;
use WP_Term;
use WP_User;
/**
* Data Class
*
* Responsible for collecting and processing data for schemas.
*
* @since 1.0.0
*/
class Data {
use Get_Instance;
/**
* Holds the collected schema data.
*
* @var array<string, mixed>
*/
private $data = [];
/**
* Holds the queried object.
*
* @var mixed
*/
private $queried_object = null;
/**
* Collects all data for schema rendering.
*
* @return array<string, mixed>Collected schema data.
*/
public function collect() {
$this->data = [
'post' => $this->get_post_data(),
'term' => $this->get_term_data(),
'author' => $this->get_author_data(),
'user' => $this->get_user_data(),
'site' => $this->get_site_data(),
'current' => $this->get_current_data(),
'schemas' => $this->get_schema_links(),
];
$this->data = apply_filters( 'surerank_schema_data', $this->data );
// Normalize post content and calculate word count.
if ( isset( $this->data['post']['content'] ) ) {
$post_content = esc_html( (string) $this->data['post']['content'] );
$this->data['post']['content'] = $post_content;
$this->data['post']['word_count'] = str_word_count( $post_content );
}
return $this->data;
}
/**
* Retrieves schema links.
*
* @return array<string, mixed>The schema links data.
*/
public function get_schema_links() {
$schemas = Schemas::get_instance()->get_active_schemas();
$data = [];
return $this->get_schema_links_data( $schemas );
}
/**
* Retrieves schema links data.
*
* @param array<string, mixed> $schemas The schema data.
* @return array<string, mixed>The schema links data.
*/
public function get_schema_links_data( array $schemas ) {
$data = [];
foreach ( $schemas as $schema ) {
$id = $this->get_id( $schema );
if ( $this->add_breadcrumb( $schema ) ) {
continue;
}
$data[ $id ] = [
'@id' => $this->get_id_value( $schema ),
];
}
return $data;
}
/**
* Adds a breadcrumb to a schema.
*
* @param array<string, mixed> $schema The schema data.
* @return bool True if the breadcrumb should be added, false otherwise.
*/
public function add_breadcrumb( array $schema ): bool {
$rules = $schema['not_show_on']['rules'] ?? [];
if ( is_front_page() && in_array( 'special-front', $rules ) && 'BreadcrumbList' === $schema['type'] ) {
return true;
}
return false;
}
/**
* Retrieves the ID for a schema.
*
* @param array<string, mixed> $schema The schema array.
* @return string The sanitized schema ID.
*/
public function get_id( array $schema ): string {
$label = $this->get( $schema, 'fields._label', $schema['type'] );
return $this->sanitize_id( $label );
}
/**
* Retrieves the ID value for a schema.
*
* @param array<string, mixed> $schema The schema array.
* @return string The ID value.
*/
public function get_id_value( array $schema ): string {
$id = $this->get( $schema, 'fields.@id', '%current.url%#%id%' );
return str_replace( '%id%', $this->get_id( $schema ), $id );
}
/**
* Retrieves a value from an array using dot notation.
*
* @param array<string, mixed> $array The array to search.
* @param string $key The dot-notated key.
* @param mixed $default The default value if the key is not found.
* @return mixed The value from the array or the default value.
*/
public function get( $array, $key, $default = null ) {
if ( ! $key ) {
return $array;
}
$keys = explode( '.', $key );
foreach ( $keys as $key ) {
if ( isset( $array[ $key ] ) ) {
$array = $array[ $key ];
} else {
return $default;
}
}
return $array;
}
/**
* Retrieves the schema data.
*
* @param array<string, mixed> $schema The schema data.
* @return array<string, mixed>The schema data.
*/
public static function get_schema_type( $schema ) {
$fields = $schema['fields'] ?? [];
$label = self::get_instance()->get_id( $schema );
if ( isset( $fields['@id'] ) ) {
$fields['@id'] = str_replace( '%id%', $label, $fields['@id'] );
}
return $fields;
}
/**
* Retrieves the queried object and caches it.
*
* @return mixed The queried object.
*/
private function get_queried_object() {
if ( null === $this->queried_object ) {
$this->queried_object = \get_queried_object();
}
return $this->queried_object;
}
/**
* Retrieves post data.
*
* @return array<string, mixed>The post data.
*/
private function get_post_data() {
$post = $this->get_queried_object();
if ( ! $post instanceof WP_Post ) {
return [];
}
if ( ! $post->ID ) {
return [];
}
$taxonomies = Helper::get_instance()->get_taxonomies();
$taxonomies_data = [];
foreach ( $taxonomies as $taxonomy ) {
$taxonomies_data[ $taxonomy['slug'] ] = $this->get_terms( $post->ID, $taxonomy['slug'] );
}
return [
'ID' => (int) $post->ID,
'title' => sanitize_text_field( $post->post_title ),
'excerpt' => Description::get_instance()->post( $post->ID ),
'content' => sanitize_text_field( $post->post_content ),
'url' => get_permalink( $post ),
'slug' => sanitize_title( $post->post_name ),
'date' => get_the_date( 'c', $post ),
'modified_date' => get_the_modified_date( 'c', $post ),
'created_date' => get_the_date( 'c', $post ),
'thumbnail' => get_the_post_thumbnail_url( $post->ID, 'full' ),
'comment_count' => (int) $post->comment_count,
'tags' => sanitize_text_field( $this->get_terms( $post->ID, 'post_tag' ) ),
'categories' => sanitize_text_field( $this->get_terms( $post->ID, 'category' ) ),
'custom_field' => array_map( 'sanitize_text_field', $this->get_custom_field_data( $post->ID ) ),
'taxonomies' => array_map( 'sanitize_text_field', $this->get_taxonomies_for_post( $post->ID ) ),
'tax' => $taxonomies_data,
];
}
/**
* Retrieves term data.
*
* @return array<string, mixed>The term data.
*/
private function get_term_data() {
$term = $this->get_queried_object();
if ( ! $term instanceof WP_Term ) {
return [];
}
if ( ! $term->term_id ) {
return [];
}
return [
'ID' => (int) $term->term_id,
'name' => sanitize_text_field( $term->name ),
'slug' => sanitize_title( $term->slug ),
'taxonomy' => sanitize_text_field( $term->taxonomy ),
'description' => Description::get_instance()->taxonomy( $term->term_id ),
'url' => get_term_link( $term->term_id ),
];
}
/**
* Retrieves author data for the current post.
*
* @return array<string, mixed>The author data.
*/
private function get_author_data() {
$post_id = get_the_ID();
if ( ! $post_id ) {
return [];
}
$author_id = (int) get_post_field( 'post_author', $post_id );
return $this->get_user( $author_id );
}
/**
* Retrieves current user data.
*
* @return array<string, mixed>The current user data.
*/
private function get_user_data() {
return $this->get_user( get_current_user_id() );
}
/**
* Retrieves user data by ID.
*
* @param int $user_id The user ID.
* @return array<string, mixed>The user data.
*/
private function get_user( int $user_id ) {
$user = get_userdata( $user_id );
if ( ! $user instanceof WP_User ) {
return [];
}
return [
'ID' => (int) $user->ID,
'first_name' => sanitize_text_field( $user->first_name ),
'last_name' => sanitize_text_field( $user->last_name ),
'username' => sanitize_text_field( $user->user_login ),
'display_name' => sanitize_text_field( $user->display_name ),
'nickname' => sanitize_text_field( $user->nickname ),
'email' => sanitize_email( $user->user_email ),
'website_url' => esc_url( $user->user_url ),
'nicename' => sanitize_title( $user->user_nicename ),
'description' => esc_html( $user->description ),
'posts_url' => get_author_posts_url( $user->ID ),
'avatar' => get_avatar_url( $user->ID ),
];
}
/**
* Retrieves site data.
*
* @return array<string, mixed>The site data.
*/
private function get_site_data() {
return [
'title' => get_bloginfo( 'name' ),
'description' => get_bloginfo( 'description' ),
'url' => home_url( '/' ),
'language' => get_locale(),
'icon' => get_site_icon_url(),
];
}
/**
* Retrieves current page data.
*
* @return array<string, mixed>The current page data.
*/
private function get_current_data() {
global $wp;
$bread = Breadcrumbs::get_instance()->get_crumbs();
$breadcrumbs = [];
foreach ( $bread as $index => $crumb ) {
$breadcrumbs[] = [
'@type' => 'ListItem',
'position' => $index + 1,
'item' => [
'@id' => $crumb['link'],
'name' => $crumb['name'],
],
];
}
return [
'url' => home_url( $wp->request ),
'breadcrumbs' => $breadcrumbs,
'title' => $this->get_title(),
];
}
/**
* Retrieves the title.
*
* @return string The title.
*/
private function get_title(): string {
$post = ! is_singular() ? $this->get_queried_object() : get_post();
if ( $post instanceof WP_Post ) {
return $post->post_title;
}
if ( $post instanceof WP_Term ) {
return $post->name;
}
if ( $post instanceof WP_User ) {
return $post->display_name;
}
return get_the_title();
}
/**
* Retrieves terms for a post by taxonomy.
*
* @param int $post_id The post ID.
* @param string $taxonomy The taxonomy slug.
* @return string The terms as a comma-separated string.
*/
private function get_terms( int $post_id, string $taxonomy ): string {
$terms = get_the_terms( $post_id, $taxonomy );
return is_array( $terms ) ? implode( ', ', wp_list_pluck( $terms, 'name' ) ) : '';
}
/**
* Retrieves taxonomies for a post.
*
* @param int $post_id The post ID.
* @return array<string, mixed>The taxonomies data.
*/
private function get_taxonomies_for_post( int $post_id ) {
$taxonomies = get_object_taxonomies( 'post', 'objects' );
$data = [];
foreach ( $taxonomies as $taxonomy ) {
$terms = get_the_terms( $post_id, $taxonomy->name );
if ( $terms && ! is_wp_error( $terms ) ) {
$data[ $taxonomy->name ] = wp_list_pluck( $terms, 'name' );
}
}
return $data;
}
/**
* Retrieves custom field data for a post.
*
* @param int $post_id The post ID.
* @return array<string, mixed>The custom field data.
*/
private function get_custom_field_data( int $post_id ) {
$meta_values = get_post_meta( $post_id );
if ( empty( $meta_values ) || ! is_array( $meta_values ) ) {
return [];
}
// Filter out meta values that are not arrays or are empty.
return array_map(
static function ( $value ) {
return reset( $value );
},
$meta_values
);
}
/**
* Sanitizes a string for use as an ID.
*
* @param string $text The input text.
* @return string The sanitized ID.
*/
private function sanitize_id( $text ) {
if ( ! $text || ! is_string( $text ) ) {
return '';
}
$id = sanitize_title( $text );
$id = preg_replace( '/[^a-z0-9_]/', '_', (string) $id ); // Only accepts alphanumeric and underscores.
$id = preg_replace( '/[ _]{2,}/', '_', (string) $id ); // Remove duplicated `_`.
$id = trim( (string) $id, '_' ); // Trim `_`.
$id = preg_replace( '/^\d+/', '', (string) $id ); // Don't start with numbers.
$id = trim( (string) $id, '_' ); // Trim `_` again.
return esc_attr( $id );
}
}