EVOLUTION-MANAGER
Edit File: class-aio-rich-snippet.php
<?php /** * The AIO Schema Rich Snippets Import Class * * @since 0.9.0 * @package RankMath * @subpackage RankMath\Admin\Importers * @author Rank Math <support@rankmath.com> */ namespace RankMath\Admin\Importers; use RankMath\Helper; use RankMath\Admin\Admin_Helper; use RankMath\Helpers\DB; use RankMath\Helpers\Str; defined( 'ABSPATH' ) || exit; /** * Import_AIO_Rich_Snippet class. */ class AIO_Rich_Snippet extends Plugin_Importer { /** * The plugin name. * * @var string */ protected $plugin_name = 'AIO Schema Rich Snippet'; /** * Plugin options meta key. * * @var string */ protected $meta_key = '_bsf_post_type'; /** * Option keys to import and clean. * * @var array */ protected $option_keys = [ 'bsf_', 'bsf_%' ]; /** * Choices keys to import. * * @var array */ protected $choices = [ 'postmeta' ]; /** * Import post meta of plugin. * * @return array */ protected function postmeta() { $this->set_pagination( $this->get_post_ids( true ) ); // Set Converter. foreach ( $this->get_post_ids() as $snippet_post ) { $type = $this->is_allowed_type( $snippet_post->meta_value ); $meta_keys = $this->get_metakeys( $type ); if ( false === $type || false === $meta_keys ) { continue; } $this->set_postmeta( $snippet_post->post_id, $type, $meta_keys ); } return $this->get_pagination_arg(); } /** * Set snippet meta. * * @param int $post_id Post ID. * @param string $type Type to get keys for. * @param array $meta_keys Array of meta keys to save. */ private function set_postmeta( $post_id, $type, $meta_keys ) { $data = []; foreach ( $meta_keys as $snippet_key => $snippet_value ) { $value = get_post_meta( $post_id, '_bsf_' . $snippet_key, true ); $this->validate_schema_data( $data, $value, $snippet_value ); } if ( empty( $data ) ) { return; } // Convert post now. $data['@type'] = $this->validate_type( $type ); $data['metadata'] = [ 'title' => Helper::sanitize_schema_title( $data['@type'] ), 'type' => 'template', 'isPrimary' => 1, 'shortcode' => uniqid( 's-' ), ]; update_post_meta( $post_id, 'rank_math_schema_' . $data['@type'], $data ); } /** * Validate schema type. * * @param string $type Schema Type. */ private function validate_type( $type ) { if ( 'software' === $type ) { return 'SoftwareApplication'; } if ( 'video' === $type ) { return 'VideoObject'; } return ucfirst( $type ); } /** * Validate schema data. * * @param array $data Schema entity data. * @param string $value Entity value. * @param string $key Entity key. */ private function validate_schema_data( &$data, $value, $key ) { if ( ! Str::contains( '.', $key ) ) { $data[ $key ] = $value; return; } $element = explode( '.', $key ); if ( 2 === count( $element ) ) { $this->add_type( $data[ $element[0] ], $element[0] ); $data[ $element[0] ][ $element[1] ] = $value; return; } if ( count( $element ) > 2 ) { $this->add_type( $data[ $element[0] ], $element[0] ); $this->add_type( $data[ $element[0] ][ $element[1] ], $element[1] ); $data[ $element[0] ][ $element[1] ][ $element[2] ] = $value; } } /** * Add property type. * * @param array $data Schema entity data. * @param string $key Entity key. */ private function add_type( &$data, $key ) { if ( 'location' === $key ) { $data['@type'] = 'Place'; } if ( 'address' === $key ) { $data['@type'] = 'PostalAddress'; } if ( 'offers' === $key ) { $data['@type'] = 'Offer'; } if ( 'brand' === $key ) { $data['@type'] = 'Brand'; } if ( 'review' === $key ) { $data['@type'] = 'Review'; } if ( 'reviewRating' === $key ) { $data['@type'] = 'Rating'; } if ( 'nutrition' === $key ) { $data['@type'] = 'NutritionInformation'; } } /** * Get the actions which can be performed for the plugin. * * @return array */ public function get_choices() { return [ 'postmeta' => esc_html__( 'Import Schemas', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Import all Schema data for Posts, Pages, and custom post types.', 'rank-math' ) ), ]; } /** * Get all post IDs of all allowed post types only. * * @param bool $count If we need count only for pagination purposes. * @return int|array */ protected function get_post_ids( $count = false ) { $paged = $this->get_pagination_arg( 'page' ); $table = DB::query_builder( 'postmeta' )->where( 'meta_key', '_bsf_post_type' ); return $count ? absint( $table->selectCount( 'meta_id' )->getVar() ) : $table->page( $paged - 1, $this->items_per_page )->get(); } /** * Get snippet types. * * @return array */ private function get_types() { return [ '2' => 'event', '5' => 'person', '6' => 'product', '7' => 'recipe', '8' => 'software', '9' => 'video', '10' => 'article', '11' => 'service', ]; } /** * Is snippet type allowed. * * @param string $type Type to check. * * @return bool */ private function is_allowed_type( $type ) { $types = $this->get_types(); return isset( $types[ $type ] ) ? $types[ $type ] : false; } /** * Get meta keys hash to import. * * @param string $type Type to get keys for. * * @return array */ private function get_metakeys( $type ) { $hash = [ 'event' => $this->get_event_fields(), 'product' => $this->get_product_fields(), 'recipe' => $this->get_recipe_fields(), 'software' => $this->get_software_fields(), 'video' => $this->get_video_fields(), 'article' => [ 'article_name' => 'headline', 'article_desc' => 'description', ], 'person' => [ 'people_fn' => 'name', 'people_nickname' => 'description', 'people_job_title' => 'jobTitle', 'people_street' => 'address.streetAddress', 'people_local' => 'address.addressLocality', 'people_region' => 'address.addressRegion', 'people_postal' => 'address.postalCode', ], 'service' => [ 'service_type' => 'serviceType', 'service_desc' => 'description', ], ]; return isset( $hash[ $type ] ) ? $hash[ $type ] : false; } /** * Get event fields. * * @return array */ private function get_event_fields() { return [ 'event_title' => 'name', 'event_desc' => 'description', 'event_organization' => 'location.name', 'event_street' => 'location.address.streetAddress', 'event_local' => 'location.address.addressLocality', 'event_region' => 'location.address.addressRegion', 'event_postal_code' => 'location.address.postalCode', 'event_start_date' => 'startDate', 'event_end_date' => 'endDate', 'event_price' => 'offers.price', 'event_cur' => 'offers.priceCurrency', 'event_ticket_url' => 'offers.url', ]; } /** * Get product fields. * * @return array */ private function get_product_fields() { return [ 'product_brand' => 'brand.name', 'product_name' => 'name', 'product_price' => 'offers.price', 'product_cur' => 'offers.priceCurrency', 'product_status' => 'offers.availability', ]; } /** * Get recipe fields. * * @return array */ private function get_recipe_fields() { return [ 'recipes_name' => 'name', 'recipes_desc' => 'description', 'recipes_preptime' => 'prepTime', 'recipes_cooktime' => 'cookTime', 'recipes_totaltime' => 'totalTime', 'recipes_ingredient' => 'recipeIngredient', 'recipes_nutrition' => 'nutrition.calories', ]; } /** * Get software fields. * * @return array */ private function get_software_fields() { return [ 'software_rating' => 'review.reviewRating.ratingValue', 'software_price' => 'offers.price', 'software_cur' => 'offers.priceCurrency', 'software_name' => 'name', 'software_os' => 'operatingSystem', 'software_cat' => 'applicationCategory', ]; } /** * Get video fields. * * @return array */ private function get_video_fields() { return [ 'video_title' => 'name', 'video_desc' => 'description', 'video_thumb' => 'thumbnailUrl', 'video_url' => 'contentUrl', 'video_emb_url' => 'embedUrl', 'video_duration' => 'duration', ]; } }