Commit realizado el 12:13:52 08-04-2024

This commit is contained in:
Pagina Web Monito
2024-04-08 12:13:55 -04:00
commit 0c33094de9
7815 changed files with 1365694 additions and 0 deletions

View File

@@ -0,0 +1,584 @@
<?php
/**
* The abstract class for plugins import to inherit from
*
* @since 0.9.0
* @package RankMath
* @subpackage RankMath\Admin\Importers
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\Admin\Importers;
use Exception;
use RankMath\Helper;
use RankMath\Traits\Ajax;
use RankMath\Traits\Meta;
use RankMath\Traits\Hooker;
use RankMath\Admin\Admin_Helper;
use RankMath\Helpers\DB;
use RankMath\Helpers\Param;
use RankMath\Helpers\Attachment;
defined( 'ABSPATH' ) || exit;
/**
* Plugin_Importer class.
*/
abstract class Plugin_Importer {
use Hooker, Ajax, Meta;
/**
* The plugin name.
*
* @var string
*/
protected $plugin_name;
/**
* The plugin file.
*
* @var string
*/
protected $plugin_file;
/**
* Plugin options meta key.
*
* @var string
*/
protected $meta_key;
/**
* Option keys to import and clean.
*
* @var array
*/
protected $option_keys;
/**
* Table names to drop while cleaning.
*
* @var array
*/
protected $table_names;
/**
* Choices keys to import.
*
* @var array
*/
protected $choices;
/**
* Number of items to parse per page.
*
* @var int
*/
protected $items_per_page = 100;
/**
* Pagination arguments.
*
* @var array
*/
protected $_pagination_args = [];
/**
* General settings.
*
* @var array
*/
protected $settings;
/**
* Titles settings.
*
* @var array
*/
protected $titles;
/**
* Sitemap settings.
*
* @var array
*/
protected $sitemap;
/**
* Class constructor.
*
* @param string $plugin_file Plugins file.
*/
public function __construct( $plugin_file ) {
$this->plugin_file = $plugin_file;
}
/**
* Get the name of the plugin we're importing from.
*
* @return string Plugin name.
*/
public function get_plugin_name() {
return $this->plugin_name;
}
/**
* Get the plugin file of the plugin we're importing from.
*
* @return string Plugin file
*/
public function get_plugin_file() {
return $this->plugin_file;
}
/**
* Get the actions which can be performed for the plugin.
*
* @return array
*/
public function get_choices() {
if ( empty( $this->choices ) ) {
return [];
}
return array_intersect_key(
[
'settings' => esc_html__( 'Import Settings', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Import plugin settings, global meta, sitemap settings, etc.', 'rank-math' ) ),
'postmeta' => esc_html__( 'Import Post Meta', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Import meta information of your posts/pages like the focus keyword, titles, descriptions, robots meta, OpenGraph info, etc.', 'rank-math' ) ),
'termmeta' => esc_html__( 'Import Term Meta', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Import data like category, tag, and CPT meta data from SEO.', 'rank-math' ) ),
'usermeta' => esc_html__( 'Import Author Meta', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Import meta information like titles, descriptions, focus keyword, robots meta, etc., of your author archive pages.', 'rank-math' ) ),
'redirections' => esc_html__( 'Import Redirections', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Import all the redirections you have already set up in Yoast Premium.', 'rank-math' ) ),
'blocks' => esc_html__( 'Import Blocks', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Import and convert all compatible blocks in post contents.', 'rank-math' ) ),
'locations' => esc_html__( 'Import Locations', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Import Locations Settings from Yoast plugin.', 'rank-math' ) ),
'news' => esc_html__( 'Import News Settings', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Import News Settings from Yoast News Add-on.', 'rank-math' ) ),
'video' => esc_html__( 'Import Video Sitemap Settings', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Import Video Sitemap Settings from Yoast Video Add-on.', 'rank-math' ) ),
],
array_combine(
$this->choices,
$this->choices
)
);
}
/**
* Check if import is needed from this plugin.
*
* @return bool Whether there is something to import.
*/
public function run_detect() {
return true === $this->has_options() ? true : $this->has_postmeta();
}
/**
* Delete all plugin data from the database.
*
* @return bool
*/
public function run_cleanup() {
if ( ! $this->run_detect() ) {
return false;
}
$result = $this->drop_custom_tables();
$result = $this->clean_meta_table();
$result = $this->clean_options();
return $result;
}
/**
* Run importer.
*
* @throws Exception Throws error if no perform function founds.
*
* @param string $perform The action to perform when running import action.
*/
public function run_import( $perform ) {
if ( ! method_exists( $this, $perform ) ) {
throw new Exception( esc_html__( 'Unable to perform action this time.', 'rank-math' ) );
}
/**
* Number of items to import per run.
*
* @param int $items_per_page Default 100.
*/
$this->items_per_page = absint( $this->do_filter( 'importers/items_per_page', 100 ) );
$status = new Status();
$result = $this->$perform();
$is_success = is_array( $result ) || true === $result;
$status->set_action( $perform );
$status->set_status( $is_success );
$message = $this->format_message( $result, $perform, $status->get_message() );
if ( is_scalar( $result ) ) {
$result = [];
}
if ( $is_success ) {
$result['message'] = $message;
$this->success( $result );
}
$result['error'] = $message;
$this->error( $result );
}
/**
* Get success message.
*
* @param array $result Array of result.
* @param string $action Action performed.
* @param string $message Message to format.
*
* @return mixed
*/
private function format_message( $result, $action, $message ) {
if ( 'blocks' === $action || 'recalculate' === $action ) {
return is_array( $result ) ? sprintf( $message, $result['start'], $result['end'], $result['total_items'] ) : $result;
}
if ( 'postmeta' === $action || 'usermeta' === $action ) {
return sprintf( $message, $result['start'], $result['end'], $result['total_items'] );
}
if ( 'termmeta' === $action || 'redirections' === $action ) {
return sprintf( $message, $result['count'] );
}
return $message;
}
/**
* Deactivate plugin action.
*/
protected function deactivate() {
if ( is_plugin_active( $this->get_plugin_file() ) ) {
deactivate_plugins( $this->get_plugin_file() );
}
return true;
}
/**
* Replace settings based on key/value hash.
*
* @param array $hash Array of hash for search and replace.
* @param array $source Array for source where to search.
* @param array $destination Array for destination where to save.
* @param bool $convert (Optional) Conversion type. Default: false.
*/
protected function replace( $hash, $source, &$destination, $convert = false ) {
foreach ( $hash as $search => $replace ) {
if ( ! isset( $source[ $search ] ) ) {
continue;
}
$destination[ $replace ] = false === $convert ? $source[ $search ] : $this->$convert( $source[ $search ] );
}
}
/**
* Replace meta based on key/value hash.
*
* @param array $hash Array of hash for search and replace.
* @param array $source Array for source where to search.
* @param int $object_id Object id for destination where to save.
* @param string $object_type Object type for destination where to save.
* @param bool $convert (Optional) Conversion type. Default: false.
*/
protected function replace_meta( $hash, $source, $object_id, $object_type, $convert = false ) {
foreach ( $hash as $search => $replace ) {
$value = ! empty( $source[ $search ] ) ? $source[ $search ] : $this->get_meta( $object_type, $object_id, $search );
if ( empty( $value ) ) {
continue;
}
$this->update_meta(
$object_type,
$object_id,
$replace,
false !== $convert ? $this->$convert( $value ) : $value
);
}
}
/**
* Replace an image to its URL and ID.
*
* @param string $source Source image url.
* @param array|callable $destination Destination array.
* @param string $image Image field key to save url.
* @param string $image_id Image id field key to save id.
* @param int $object_id Object ID either post ID, term ID or user ID.
*/
protected function replace_image( $source, $destination, $image, $image_id, $object_id = null ) {
if ( empty( $source ) ) {
return;
}
$attachment_id = Attachment::get_by_url( $source );
if ( 1 > $attachment_id ) {
return;
}
if ( is_null( $object_id ) ) {
$destination[ $image ] = $source;
$destination[ $image_id ] = $attachment_id;
return;
}
$this->update_meta( $destination, $object_id, $image, $source );
$this->update_meta( $destination, $object_id, $image_id, $attachment_id );
}
/**
* Convert bool value to switch.
*
* @param mixed $value Value to convert.
* @return string
*/
protected function convert_bool( $value ) {
if ( true === boolval( $value ) ) {
return 'on';
}
if ( false === boolval( $value ) ) {
return 'off';
}
return $value;
}
/**
* Set variable that twitter is using facebook data or not.
*
* @param string $object_type Object type for destination where to save.
* @param int $object_id Object id for destination where to save.
*/
protected function is_twitter_using_facebook( $object_type, $object_id ) {
$keys = [
'rank_math_twitter_title',
'rank_math_twitter_description',
'rank_math_twitter_image',
];
foreach ( $keys as $key ) {
if ( ! empty( $this->get_meta( $object_type, $object_id, $key, true ) ) ) {
$this->update_meta( $object_type, $object_id, 'rank_math_twitter_use_facebook', 'off' );
break;
}
}
}
/**
* Convert Yoast / AIO SEO variables if needed.
*
* @param string $string Value to convert.
* @return string
*/
protected function convert_variables( $string ) {
return str_replace( '%%', '%', $string );
}
/**
* Set pagination arguments.
*
* @param int $total_items Number of total items to set pagination.
*/
protected function set_pagination( $total_items = 0 ) {
$args = [
'total_pages' => 0,
'total_items' => $total_items,
'per_page' => $this->items_per_page,
];
// Total Pages.
if ( ! $args['total_pages'] && $args['per_page'] > 0 ) {
$args['total_pages'] = ceil( $args['total_items'] / $args['per_page'] );
}
// Current Page.
$pagenum = Param::request( 'paged', 0, FILTER_VALIDATE_INT );
if ( isset( $args['total_pages'] ) && $pagenum > $args['total_pages'] ) {
$pagenum = $args['total_pages'];
}
$args['page'] = max( 1, $pagenum );
// Start n End.
$args['start'] = ( ( $args['page'] - 1 ) * $this->items_per_page ) + 1;
$args['end'] = min( $args['page'] * $this->items_per_page, $total_items );
$this->_pagination_args = $args;
}
/**
* Get pagination arguments.
*
* @param bool $key If any specific data is required from arguments.
* @return mixed
*/
protected function get_pagination_arg( $key = false ) {
if ( false === $key ) {
return $this->_pagination_args;
}
return isset( $this->_pagination_args[ $key ] ) ? $this->_pagination_args[ $key ] : false;
}
/**
* 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( 'posts' )->whereIn( 'post_type', Helper::get_accessible_post_types() );
return $count ? absint( $table->selectCount( 'ID', 'total' )->getVar() ) :
$table->select( 'ID' )->page( $paged - 1, $this->items_per_page )->get();
}
/**
* Get all user IDs.
*
* @param bool $count If we need count only for pagination purposes.
* @return int|array
*/
protected function get_user_ids( $count = false ) {
$paged = $this->get_pagination_arg( 'page' );
$table = DB::query_builder( 'users' );
return $count ? absint( $table->selectCount( 'ID', 'total' )->getVar() ) :
$table->select( 'ID' )->page( $paged - 1, $this->items_per_page )->get();
}
/**
* Get system settings.
*/
protected function get_settings() {
$all_opts = rank_math()->settings->all_raw();
$this->settings = $all_opts['general'];
$this->titles = $all_opts['titles'];
$this->sitemap = $all_opts['sitemap'];
}
/**
* Update system settings.
*/
protected function update_settings() {
Helper::update_all_settings(
$this->settings,
$this->titles,
$this->sitemap
);
}
/**
* Clean meta table for post, term and user.
*
* @return bool
*/
private function clean_meta_table() {
if ( empty( $this->meta_key ) ) {
return false;
}
$result = false;
$result = DB::query_builder( 'usermeta' )->whereLike( 'meta_key', $this->meta_key )->delete();
$result = DB::query_builder( 'termmeta' )->whereLike( 'meta_key', $this->meta_key )->delete();
$result = DB::query_builder( 'postmeta' )->whereLike( 'meta_key', $this->meta_key )->delete();
return $result;
}
/**
* Clean options table.
*
* @return bool
*/
private function clean_options() {
if ( empty( $this->option_keys ) ) {
return false;
}
$table = DB::query_builder( 'options' );
foreach ( $this->option_keys as $option_key ) {
$table->orWhereLike( 'option_name', $option_key );
}
return $table->delete();
}
/**
* Drop custom tables for plugins.
*
* @return bool
*/
private function drop_custom_tables() {
global $wpdb;
if ( empty( $this->table_names ) ) {
return false;
}
foreach ( $this->table_names as $table ) {
$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}{$table}" );
}
return true;
}
/**
* Check if plugin has options.
*
* @return bool
*/
private function has_options() {
if ( empty( $this->option_keys ) ) {
return false;
}
$table = DB::query_builder( 'options' )->select( 'option_id' );
foreach ( $this->option_keys as $option_key ) {
if ( '%' === substr( $option_key, -1 ) ) {
$table->orWhereLike( 'option_name', substr( $option_key, 0, -1 ), '' );
} else {
$table->orWhere( 'option_name', $option_key );
}
}
return absint( $table->getVar() ) > 0 ? true : false;
}
/**
* Check if plugin has postmeta.
*
* @return bool
*/
private function has_postmeta() {
if ( empty( $this->meta_key ) ) {
return false;
}
$result = DB::query_builder( 'postmeta' )->select( 'meta_id' )->whereLike( 'meta_key', $this->meta_key, '' )->getVar();
return absint( $result ) > 0 ? true : false;
}
/**
* Recalculate SEO scores.
*/
private function recalculate() {
$this->set_pagination( \RankMath\Tools\Update_Score::get()->find( false ) );
$return = $this->get_pagination_arg();
$data = \RankMath\Tools\Update_Score::get()->update_seo_score();
$return['data'] = $data;
return $return;
}
}

View File

@@ -0,0 +1,361 @@
<?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',
];
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,200 @@
<?php
/**
* The functionality to detect whether we should import from another SEO plugin.
*
* @since 0.9.0
* @package RankMath
* @subpackage RankMath\Admin\Importers
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\Admin\Importers;
use RankMath\Traits\Hooker;
defined( 'ABSPATH' ) || exit;
/**
* Detector class.
*/
class Detector {
use Hooker;
/**
* Plugins we can import from.
*
* @var array
*/
public static $plugins = null;
/**
* Detects whether we can import anything or not.
*
* @return array List of plugins we can import from.
*/
public function detect() {
$this->requirements();
if ( ! is_null( self::$plugins ) ) {
return self::$plugins;
}
self::$plugins = [];
$plugins = $this->get();
foreach ( $plugins as $slug => $plugin ) {
if ( ! $this->is_detectable( $plugin, $plugins ) ) {
continue;
}
$this->can_import( $slug, $plugin );
}
return self::$plugins;
}
/**
* Run import class.
*
* @param Plugin_Importer $importer The importer that needs to perform this action.
* @param string $action The action to perform.
* @param string $perform The action to perform when running import action.
*/
public function run( $importer, $action = 'detect', $perform = '' ) {
if ( 'cleanup' === $action ) {
return $importer->run_cleanup();
} elseif ( 'import' === $action ) {
return $importer->run_import( $perform );
}
return $importer->run_detect();
}
/**
* Run action by slug.
*
* @param string $slug The importer slug that needs to perform this action.
* @param string $action The action to perform.
* @param string $perform The action to perform when running import action.
*/
public static function run_by_slug( $slug, $action, $perform = '' ) {
$detector = new self();
$importers = $detector->get();
if ( ! isset( $importers[ $slug ] ) ) {
return false;
}
$importer = $importers[ $slug ];
$importer = new $importer['class']( $importer['file'] );
$status = $detector->run( $importer, $action, $perform );
return \compact( 'importer', 'status' );
}
/**
* Deactivate all plugins.
*/
public static function deactivate_all() {
$detector = new Detector();
$plugins = $detector->get();
foreach ( $plugins as $plugin ) {
deactivate_plugins( $plugin['file'] );
}
}
/**
* Get the list of available importers.
*
* @return array Available importers.
*/
public function get() {
return $this->do_filter(
'importers/detect_plugins',
[
'yoast' => [
'class' => '\\RankMath\\Admin\\Importers\\Yoast',
'file' => 'wordpress-seo/wp-seo.php',
'premium' => 'yoast-premium',
],
'seopress' => [
'class' => '\\RankMath\\Admin\\Importers\\SEOPress',
'file' => 'wp-seopress/seopress.php',
],
'aioseo' => [
'class' => '\\RankMath\\Admin\\Importers\\AIOSEO',
'file' => 'all-in-one-seo-pack/all_in_one_seo_pack.php',
'premium' => 'all-in-one-seo-pack-pro',
],
'all-in-one-seo-pack-pro' => [
'class' => '\\RankMath\\Admin\\Importers\\AIOSEO',
'file' => 'all-in-one-seo-pack-pro/all_in_one_seo_pack.php',
'parent' => 'aioseo',
],
'yoast-premium' => [
'class' => '\\RankMath\\Admin\\Importers\\Yoast',
'file' => 'wordpress-seo-premium/wp-seo-premium.php',
'parent' => 'yoast',
],
'aio-rich-snippet' => [
'class' => '\\RankMath\\Admin\\Importers\\AIO_Rich_Snippet',
'file' => 'all-in-one-schemaorg-rich-snippets/index.php',
],
'wp-schema-pro' => [
'class' => '\\RankMath\\Admin\\Importers\\WP_Schema_Pro',
'file' => 'wp-schema-pro/wp-schema-pro.php',
],
'redirections' => [
'class' => '\\RankMath\\Admin\\Importers\\Redirections',
'file' => 'redirection/redirection.php',
],
]
);
}
/**
* Check requirements.
*/
private function requirements() {
if ( ! function_exists( 'is_plugin_active' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
}
/**
* Can import plugin data.
*
* @param string $slug Plugin slug.
* @param array $plugin Plugin data.
*/
private function can_import( $slug, $plugin ) {
$importer = new $plugin['class']( $plugin['file'] );
if ( $importer->run_detect() ) {
self::$plugins[ $slug ] = [
'name' => $importer->get_plugin_name(),
'file' => $importer->get_plugin_file(),
'choices' => $importer->get_choices(),
];
}
}
/**
* Check if plugin is detectable.
*
* @param array $check Plugin to check.
* @param array $plugins Plugins data.
*
* @return bool
*/
private function is_detectable( $check, $plugins ) {
// Check if parent is set.
if ( isset( $check['parent'] ) && isset( self::$plugins[ $check['parent'] ] ) ) {
return false;
}
// Check if plugin has premium and it is active.
if ( isset( $check['premium'] ) && is_plugin_active( $plugins[ $check['premium'] ]['file'] ) ) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,104 @@
<?php
/**
* The Redirections 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\Redirections\Redirection;
defined( 'ABSPATH' ) || exit;
/**
* Redirections class.
*/
class Redirections extends Plugin_Importer {
/**
* The plugin name.
*
* @var string
*/
protected $plugin_name = 'Redirections';
/**
* Option keys to import and clean.
*
* @var array
*/
protected $option_keys = [ 'redirection_options' ];
/**
* Choices keys to import.
*
* @var array
*/
protected $choices = [ 'redirections' ];
/**
* Import redirections of plugin.
*
* @return bool
*/
protected function redirections() {
global $wpdb;
$count = 0;
$rows = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}redirection_items" );
if ( empty( $rows ) ) {
return false;
}
foreach ( (array) $rows as $row ) {
$item = Redirection::from(
[
'sources' => [
[
'pattern' => $row->url,
'comparison' => empty( $row->regex ) ? 'exact' : 'regex',
],
],
'url_to' => $this->get_url_to( $row ),
'header_code' => $row->action_code,
'status' => 'disabled' === $row->status ? 'inactive' : 'active',
]
);
$id = $item->save();
if ( false !== $id ) {
do_action( 'rank_math/redirection/after_import', $id, $row );
$count++;
}
}
Helper::update_modules( [ 'redirections' => 'on' ] );
return compact( 'count' );
}
/**
* Get validated url to value
*
* @param object $row Current row we are processing.
* @return string
*/
private function get_url_to( $row ) {
$data = maybe_unserialize( $row->action_data );
if ( is_array( $data ) && ( isset( $data['url'] ) || isset( $data['url_from'] ) ) ) {
return isset( $data['url'] ) ? $data['url'] : $data['url_from'];
}
if ( is_string( $row->action_data ) ) {
return $row->action_data;
}
return '/';
}
}

View File

@@ -0,0 +1,845 @@
<?php
/**
* The SEOPress Import Class
*
* @since 1.0.24
* @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\Redirections\Redirection;
use RankMath\Schema\JsonLD;
use RankMath\Schema\Singular;
use RankMath\Helpers\DB;
defined( 'ABSPATH' ) || exit;
/**
* SEOPress class.
*/
class SEOPress extends Plugin_Importer {
/**
* The plugin name.
*
* @var string
*/
protected $plugin_name = 'SEOPress';
/**
* Plugin options meta key.
*
* @var string
*/
protected $meta_key = 'seopress';
/**
* Option keys to import and clean.
*
* @var array
*/
protected $option_keys = [ 'seopress', 'seopress_%' ];
/**
* Choices keys to import.
*
* @var array
*/
protected $choices = [ 'settings', 'postmeta', 'termmeta', 'redirections' ];
/**
* JsonLD.
*
* @var JsonLD
*/
private $json_ld;
/**
* Singular.
*
* @var Singular
*/
private $single;
/**
* Convert SEOPress variables if needed.
*
* @param string $string Value to convert.
*
* @return string
*/
public function convert_variables( $string ) {
$string = str_replace( '%%sitetitle%%', '%sitename%', $string );
$string = str_replace( '%%tagline%%', '%sitedesc%', $string );
$string = str_replace( '%%post_title%%', '%title%', $string );
$string = str_replace( '%%post_excerpt%%', '%excerpt%', $string );
$string = str_replace( '%%post_date%%', '%date%', $string );
$string = str_replace( '%%post_modified_date%%', '%modified%', $string );
$string = str_replace( '%post_author%%', '%name%', $string );
$string = str_replace( '%%post_category%%', '%category%', $string );
$string = str_replace( '%%post_tag%%', '%tag%', $string );
$string = str_replace( '%%_category_title%%', '%term%', $string );
$string = str_replace( '%%_category_description%%', '%term_description%', $string );
$string = str_replace( '%%tag_title%%', '%term%', $string );
$string = str_replace( '%%tag_description%%', '%term_description%', $string );
$string = str_replace( '%%term_title%%', '%term%', $string );
$string = str_replace( '%%term_description%%', '%term_description%', $string );
$string = str_replace( '%%search_keywords%%', '%search_query%', $string );
$string = str_replace( '%%current_pagination%%', '%page%', $string );
$string = str_replace( '%%cpt_plural%%', '%pt_plural%', $string );
$string = str_replace( '%%archive_title%%', '%title%', $string );
$string = str_replace( '%%archive_date%%', '%currentdate%', $string );
$string = str_replace( '%%archive_date_day%%', '%currentday%', $string );
$string = str_replace( '%%archive_date_month%%', '%currentmonth%', $string );
$string = str_replace( '%%archive_date_year%%', '%year%', $string );
$string = str_replace( '%%currentdate%%', '%currentdate%', $string );
$string = str_replace( '%%currentday%%', '%currentday%', $string );
$string = str_replace( '%%currentmonth%%', '%currentmonth%', $string );
$string = str_replace( '%%currentyear%%', '%currentyear%', $string );
$string = str_replace( '%%currenttime%%', '%time%', $string );
$string = str_replace( '%%author_bio%%', '%user_description%', $string );
$string = str_replace( '%%wc_single_cat%%', '%term%', $string );
$string = str_replace( '%%wc_single_tag%%', '%term%', $string );
$string = str_replace( '%%wc_single_short_desc%%', '%wc_shortdesc%', $string );
$string = str_replace( '%%wc_single_price%%', '%wc_price%', $string );
return str_replace( '%%', '%', $string );
}
/**
* Deactivate plugin action.
*/
protected function deactivate() {
if ( is_plugin_active( $this->get_plugin_file() ) ) {
deactivate_plugins( $this->get_plugin_file() );
deactivate_plugins( 'wp-seopress-pro/seopress-pro.php' );
}
return true;
}
/**
* Import settings of plugin.
*
* @return bool
*/
protected function settings() {
$this->get_settings();
$seopress_titles = get_option( 'seopress_titles_option_name' );
$seopress_sitemap = get_option( 'seopress_xml_sitemap_option_name' );
$seopress_local = get_option( 'seopress_pro_option_name' );
// Titles & Descriptions.
$hash = [
'seopress_titles_archives_author_disable' => 'disable_author_archives',
'seopress_titles_archives_date_disable' => 'disable_date_archives',
'seopress_titles_home_site_title' => 'homepage_title',
'seopress_titles_home_site_desc' => 'homepage_description',
'seopress_titles_archives_author_title' => 'author_archive_title',
'seopress_titles_archives_author_desc' => 'author_archive_description',
'seopress_titles_archives_date_title' => 'date_archive_title',
'seopress_titles_archives_date_desc' => 'date_archive_description',
'seopress_titles_archives_search_title' => 'search_title',
'seopress_titles_archives_404_title' => '404_title',
];
$this->replace( $hash, $seopress_titles, $this->titles, 'convert_variables' );
$this->replace( $hash, $seopress_titles, $this->titles, 'convert_bool' );
$this->titles['title_separator'] = \RankMath\CMB2::sanitize_htmlentities( $seopress_titles['seopress_titles_sep'] );
$this->titles['date_archive_robots'] = ! empty( $seopress_titles['seopress_titles_archives_date_noindex'] ) ? [ 'noindex' ] : [];
$this->set_robots( 'author', ! empty( $seopress_titles['seopress_titles_archives_author_noindex'] ), '' );
$this->update_modules( $seopress_local, $seopress_sitemap );
$this->social_settings();
$this->advanced_settings();
$this->post_type_settings( $seopress_titles, $seopress_sitemap );
$this->taxonomies_settings( $seopress_titles, $seopress_sitemap );
$this->local_seo_settings( $seopress_local );
$this->update_settings();
return true;
}
/**
* Import post meta of plugin.
*
* @return array
*/
protected function postmeta() {
$this->set_pagination( $this->get_post_ids( true ) );
$post_ids = $this->get_post_ids();
$this->set_primary_term( $post_ids );
$hash = [
'_seopress_titles_title' => 'rank_math_title',
'_seopress_titles_desc' => 'rank_math_description',
'_seopress_analysis_target_kw' => 'rank_math_focus_keyword',
'_seopress_robots_canonical' => 'rank_math_canonical_url',
'_seopress_social_fb_title' => 'rank_math_facebook_title',
'_seopress_social_fb_desc' => 'rank_math_facebook_description',
'_seopress_social_fb_img' => 'rank_math_facebook_image',
'_seopress_social_twitter_title' => 'rank_math_twitter_title',
'_seopress_social_twitter_desc' => 'rank_math_twitter_description',
'_seopress_social_twitter_img' => 'rank_math_twitter_image',
'_seopress_robots_breadcrumbs' => 'rank_math_breadcrumb_title',
];
// Set Converter.
$this->json_ld = new JsonLD();
$this->single = new Singular();
foreach ( $post_ids as $post ) {
$post_id = $post->ID;
$this->replace_meta( $hash, null, $post_id, 'post', 'convert_variables' );
delete_post_meta( $post_id, 'rank_math_permalink' );
$this->replace_image( get_post_meta( $post_id, '_seopress_social_fb_img', true ), 'post', 'rank_math_facebook_image', 'rank_math_facebook_image_id', $post_id );
$this->replace_image( get_post_meta( $post_id, '_seopress_social_twitter_img', true ), 'post', 'rank_math_twitter_image', 'rank_math_twitter_image_id', $post_id );
$this->is_twitter_using_facebook( 'post', $post_id );
$this->set_object_robots( $post_id, 'post' );
$this->set_schema_data( $post_id );
$this->set_object_redirection( $post_id, 'post' );
}
return $this->get_pagination_arg();
}
/**
* Import term meta of plugin.
*
* @return array
*/
protected function termmeta() {
$count = 0;
$terms = new \WP_Term_Query(
[
'meta_key' => '_seopress_titles_title',
'fields' => 'ids',
'hide_empty' => false,
'get' => 'all',
]
);
if ( empty( $terms ) || is_wp_error( $terms ) ) {
return false;
}
$hash = [
'_seopress_titles_title' => 'rank_math_title',
'_seopress_titles_desc' => 'rank_math_description',
'_seopress_robots_canonical' => 'rank_math_canonical_url',
'_seopress_social_fb_title' => 'rank_math_facebook_title',
'_seopress_social_fb_desc' => 'rank_math_facebook_description',
'_seopress_social_fb_img' => 'rank_math_facebook_image',
'_seopress_social_twitter_title' => 'rank_math_twitter_title',
'_seopress_social_twitter_desc' => 'rank_math_twitter_description',
'_seopress_social_twitter_img' => 'rank_math_twitter_image',
];
foreach ( $terms->get_terms() as $term_id ) {
$count++;
$this->replace_meta( $hash, [], $term_id, 'term', 'convert_variables' );
delete_term_meta( $term_id, 'rank_math_permalink' );
$this->is_twitter_using_facebook( 'term', $term_id );
$this->set_object_robots( $term_id, 'term' );
$this->set_object_redirection( $term_id, 'term' );
}
return compact( 'count' );
}
/**
* Imports redirections data.
*
* @return array
*/
protected function redirections() {
$redirections = get_posts(
[
'posts_per_page' => -1,
'post_type' => 'seopress_404',
]
);
if ( empty( $redirections ) ) {
return false;
}
$count = 0;
foreach ( $redirections as $redirection ) {
$data = [
'source' => $redirection->post_title,
'destination' => get_post_meta( $redirection->ID, '_seopress_redirections_value', true ),
'code' => get_post_meta( $redirection->ID, '_seopress_redirections_type', true ),
'status' => 'publish' === $redirection->post_status ? true : false,
];
if ( false !== $this->save_redirection( $data ) ) {
$count++;
}
}
return compact( 'count' );
}
/**
* Update Modules.
*
* @param array $seopress_local Local SEO Settings.
* @param array $seopress_sitemap Sitemap Settings.
*/
private function update_modules( $seopress_local, $seopress_sitemap ) {
$seopress_toggle = get_option( 'seopress_toggle' );
// Enable/Disable Modules.
$modules = [
'local-seo' => ! empty( $seopress_toggle['toggle-local-business'] ) ? 'on' : 'off',
'sitemap' => ! empty( $seopress_toggle['toggle-xml-sitemap'] ) && ! empty( $seopress_sitemap['seopress_xml_sitemap_general_enable'] ) ? 'on' : 'off',
'rich-snippet' => ! empty( $seopress_toggle['toggle-rich-snippets'] ) ? 'on' : 'off',
'404-monitor' => ! empty( $seopress_toggle['toggle-404'] ) && ! empty( $seopress_local['seopress_404_enable'] ) ? 'on' : 'off',
];
foreach ( $modules as $key => $value ) {
Helper::update_modules( [ $key => $value ] );
}
}
/**
* Save redirection.
*
* @param WP_Post $redirection Redirection object.
*
* @return mixed
*/
private function save_redirection( $redirection ) {
if ( empty( $redirection['source'] ) || empty( $redirection['destination'] ) ) {
return false;
}
$item = Redirection::from(
[
'sources' => [
[
'pattern' => $redirection['source'],
'comparison' => 'exact',
],
],
'url_to' => $redirection['destination'],
'header_code' => $redirection['code'],
'status' => $redirection['status'] ? 'active' : 'inactive',
]
);
return $item->save();
}
/**
* Social settings.
*/
private function social_settings() {
$social = get_option( 'seopress_social_option_name' );
$hash = [
'seopress_social_accounts_facebook' => 'social_url_facebook',
'seopress_social_facebook_link_ownership_id' => 'facebook_author_urls',
'seopress_social_facebook_img' => 'open_graph_image',
'seopress_social_facebook_admin_id' => 'facebook_admin_id',
'seopress_social_facebook_app_id' => 'facebook_app_id',
'seopress_social_accounts_twitter' => 'twitter_author_names',
'seopress_social_knowledge_name' => 'knowledgegraph_name',
'seopress_social_knowledge_img' => 'knowledgegraph_logo',
];
$this->replace( $hash, $social, $this->titles );
$additional_urls = [];
foreach ( [ 'pinterest', 'instagram', 'youtube', 'linkedin' ] as $service ) {
if ( ! empty( $social[ "seopress_social_accounts_{$service}" ] ) ) {
$additional_urls[] = $social[ "seopress_social_accounts_{$service}" ];
}
}
if ( ! empty( $additional_urls ) ) {
$this->titles['social_additional_profiles'] = implode( PHP_EOL, $additional_urls );
}
// OpenGraph.
if ( isset( $social['og_default_image'] ) ) {
$this->replace_image( $social['og_default_image'], $this->titles, 'open_graph_image', 'open_graph_image_id' );
}
if ( isset( $social['og_frontpage_image'] ) ) {
$this->replace_image( $social['og_frontpage_image'], $this->titles, 'homepage_facebook_image', 'homepage_facebook_image_id' );
}
// Phone Numbers.
if ( ! empty( $social['seopress_social_knowledge_phone'] ) ) {
$this->titles['phone_numbers'] = [
[
'type' => $social['seopress_social_knowledge_contact_type'],
'number' => $social['seopress_social_knowledge_phone'],
],
];
}
$this->titles['knowledgegraph_type'] = isset( $social['seopress_social_knowledge_type'] ) && 'organization' === strtolower( $social['seopress_social_knowledge_type'] ) ? 'company' : 'person';
}
/**
* Post type settings.
*
* @param array $seopress_titles Titles & Meta Settings.
* @param array $seopress_sitemap Sitemap Settings.
*/
private function post_type_settings( $seopress_titles, $seopress_sitemap ) {
foreach ( Helper::get_accessible_post_types() as $post_type ) {
$this->titles[ "pt_{$post_type}_title" ] = isset( $seopress_titles['seopress_titles_single_titles'][ $post_type ] ) ? $this->convert_variables( $seopress_titles['seopress_titles_single_titles'][ $post_type ]['title'] ) : '';
$this->titles[ "pt_{$post_type}_description" ] = isset( $seopress_titles['seopress_titles_single_titles'][ $post_type ] ) ? $this->convert_variables( $seopress_titles['seopress_titles_single_titles'][ $post_type ]['description'] ) : '';
$this->set_robots(
"pt_{$post_type}",
! empty( $seopress_titles['seopress_titles_single_titles'][ $post_type ]['noindex'] ),
! empty( $seopress_titles['seopress_titles_single_titles'][ $post_type ]['nofollow'] )
);
$enable_sitemap = $this->enable_sitemap( 'post_types', $post_type, $seopress_sitemap );
$this->sitemap[ "pt_{$post_type}_sitemap" ] = $enable_sitemap ? 'on' : 'off';
if ( 'attachment' === $post_type && $enable_sitemap ) {
$this->settings['attachment_redirect_urls'] = 'off';
}
}
}
/**
* Taxonomies settings.
*
* @param array $seopress_titles Titles & Meta Settings.
* @param array $seopress_sitemap Sitemap Settings.
*/
private function taxonomies_settings( $seopress_titles, $seopress_sitemap ) {
foreach ( Helper::get_accessible_taxonomies() as $taxonomy => $object ) {
$this->titles[ "tax_{$taxonomy}_title" ] = ! empty( $seopress_titles['seopress_titles_tax_titles'][ $taxonomy ]['title'] ) ? $this->convert_variables( $seopress_titles['seopress_titles_tax_titles'][ $taxonomy ]['title'] ) : '';
$this->titles[ "tax_{$taxonomy}_description" ] = ! empty( $seopress_titles['seopress_titles_tax_titles'][ $taxonomy ]['description'] ) ? $this->convert_variables( $seopress_titles['seopress_titles_tax_titles'][ $taxonomy ]['description'] ) : '';
$this->set_robots(
"tax_{$taxonomy}",
! empty( $seopress_titles['seopress_titles_tax_titles'][ $taxonomy ]['noindex'] ),
! empty( $seopress_titles['seopress_titles_tax_titles'][ $taxonomy ]['nofollow'] )
);
$this->sitemap[ "tax_{$taxonomy}_sitemap" ] = $this->enable_sitemap( 'taxonomies', $taxonomy, $seopress_sitemap ) ? 'on' : 'off';
}
}
/**
* Whether to enable sitemap.
*
* @param string $object_prefix post_types/taxonomies.
* @param string $object_type Current object type.
* @param string $seopress_sitemap Sitemap settings.
*
* @return bool
*/
private function enable_sitemap( $object_prefix, $object_type, $seopress_sitemap ) {
return ! empty( $seopress_sitemap[ "seopress_xml_sitemap_{$object_prefix}_list" ][ $object_type ]['include'] );
}
/**
* Set robots settings.
*
* @param string $prefix Setting key prefix.
* @param bool $noindex Is noindex.
* @param bool $nofollow Is nofollow.
*/
private function set_robots( $prefix, $noindex, $nofollow ) {
if ( $noindex || $nofollow ) {
$robots = "{$prefix}_robots";
$custom = "{$prefix}_custom_robots";
// Settings.
$this->titles[ $custom ] = 'on';
$this->titles[ $robots ][] = $noindex ? 'noindex' : '';
$this->titles[ $robots ][] = $nofollow ? 'nofollow' : '';
$this->titles[ $robots ] = array_unique( $this->titles[ $robots ] );
}
}
/**
* Set Advanced settings.
*/
private function advanced_settings() {
$seopress_advanced = get_option( 'seopress_advanced_option_name' );
$hash = [
'seopress_advanced_advanced_google' => 'google_verify',
'seopress_advanced_advanced_bing' => 'bing_verify',
'seopress_advanced_advanced_yandex' => 'yandex_verify',
'seopress_advanced_advanced_pinterest' => 'pinterest_verify',
];
$this->replace( $hash, $seopress_advanced, $this->settings );
$this->replace( $hash, $seopress_advanced, $this->settings, 'convert_bool' );
$this->settings['attachment_redirect_urls'] = ! empty( $seopress_advanced['seopress_advanced_advanced_attachments'] ) ? 'on' : 'off';
$this->settings['strip_category_base'] = ! empty( $seopress_advanced['seopress_advanced_advanced_category_url'] ) ? 'on' : 'off';
$set_alt = ! empty( $seopress_advanced['seopress_advanced_advanced_image_auto_alt_editor'] ) ? 'on' : 'off';
$set_title = ! empty( $seopress_advanced['seopress_advanced_advanced_image_auto_title_editor'] ) ? 'on' : 'off';
$this->settings['add_img_alt'] = $set_alt;
$this->settings['add_img_title'] = $set_title;
$this->settings['img_alt_format'] = 'on' === $set_alt ? ' %filename%' : '';
$this->settings['img_title_format'] = 'on' === $set_title ? ' %filename%' : '';
}
/**
* Local SEO settings.
*
* @param array $seopress_local Local SEOPress data.
*/
private function local_seo_settings( $seopress_local ) {
if ( empty( $seopress_local ) ) {
return;
}
// Breadcrumbs.
$hash = [
'seopress_breadcrumbs_i18n_home' => 'breadcrumbs_home_label',
'seopress_breadcrumbs_i18n_search' => 'breadcrumbs_search_format',
'seopress_breadcrumbs_i18n_404' => 'breadcrumbs_404_label',
'seopress_breadcrumbs_enable' => 'breadcrumbs',
];
$this->replace( $hash, $seopress_local, $this->settings );
$this->replace( $hash, $seopress_local, $this->settings, 'convert_bool' );
$this->settings['breadcrumbs_separator'] = \RankMath\CMB2::sanitize_htmlentities( $seopress_local['seopress_breadcrumbs_separator'] );
$hash = [
'seopress_local_business_type' => 'local_business_type',
'seopress_local_business_price_range' => 'price_range',
'seopress_local_business_url' => 'url',
];
$this->replace( $hash, $seopress_local, $this->titles, 'convert_variables' );
// Street Address.
$address = [];
$hash = [
'seopress_local_business_street_address' => 'streetAddress',
'seopress_local_business_address_locality' => 'addressLocality',
'seopress_local_business_address_region' => 'addressRegion',
'seopress_local_business_postal_code' => 'postalCode',
'seopress_local_business_address_country' => 'addressCountry',
];
$this->replace( $hash, $seopress_local, $address );
$this->titles['local_address'] = $address;
// Coordinates.
if ( ! empty( $seopress_local['seopress_local_business_lat'] ) && ! empty( $seopress_local['seopress_local_business_lon'] ) ) {
$this->titles['geo'] = $seopress_local['seopress_local_business_lat'] . ', ' . $seopress_local['seopress_local_business_lon'];
}
$this->seopress_pro_settings( $seopress_local );
$this->seopress_set_opening_hours( $seopress_local );
}
/**
* 404 settings.
*
* @param array $seopress_local SEOPress Pro Settings.
*/
private function seopress_pro_settings( $seopress_local ) {
Helper::update_modules( [ 'redirections' => 'on' ] );
$hash = [
'seopress_rss_before_html' => 'rss_before_content',
'seopress_rss_after_html' => 'rss_after_content',
'seopress_404_redirect_custom_url' => 'redirections_custom_url',
'seopress_404_redirect_status_code' => 'redirections_header_code',
];
$this->replace( $hash, $seopress_local, $this->settings );
$this->settings['redirections_fallback'] = 'none' === $seopress_local['seopress_404_redirect_home'] ? 'default' : ( 'home' === $seopress_local['seopress_404_redirect_home'] ? 'homepage' : 'custom' );
}
/**
* Set Opening Hours.
*
* @param array $seopress_local SEOPress Pro Settings.
*/
private function seopress_set_opening_hours( $seopress_local ) {
$hash = [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ];
$data = [];
foreach ( $seopress_local['seopress_local_business_opening_hours'] as $key => $opening_hour ) {
if ( isset( $opening_hour['open'] ) ) {
continue;
}
$data[] = [
'day' => $hash[ $key ],
'time' => $opening_hour['start']['hours'] . ':' . $opening_hour['start']['mins'] . '-' . $opening_hour['end']['hours'] . ':' . $opening_hour['end']['mins'],
];
}
$this->titles['opening_hours'] = $data;
}
/**
* Set schema data.
*
* @param int $post_id Post ID.
*/
private function set_schema_data( $post_id ) {
if ( ! $type = get_post_meta( $post_id, '_seopress_pro_rich_snippets_type', true ) ) { // phpcs:ignore
return;
}
if ( $meta_keys = $this->get_schema_metakeys( $type ) ) { // phpcs:ignore
$schema_type = 's' === substr( $type, -1 ) ? substr( $type, 0, -1 ) : $type;
update_post_meta( $post_id, 'rank_math_rich_snippet', $schema_type );
foreach ( $meta_keys as $meta_key => $data ) {
$value = $this->get_snippet_value( $post_id, $meta_key );
if ( $value && 'events_location_address' === $meta_key ) {
$value = [ 'streetAddress' => $value ];
}
update_post_meta( $post_id, "rank_math_snippet_{$data}", $value );
}
// Convert post now.
$data = $this->json_ld->get_old_schema( $post_id, $this->single );
if ( isset( $data['richSnippet'] ) ) {
$data = $data['richSnippet'];
$type = $data['@type'];
$data['metadata'] = [
'title' => $type,
'type' => 'template',
];
update_post_meta( $post_id, 'rank_math_schema_' . $type, $data );
}
}
}
/**
* Set object redirection.
*
* @param int $object_id Object id for destination.
* @param string $object_type Object type for destination.
*/
private function set_object_redirection( $object_id, $object_type ) {
$source_url = 'term' === $object_type ? get_term_link( $object_id ) : get_permalink( $object_id );
if ( is_wp_error( $source_url ) ) { // phpcs:ignore
return;
}
$hash = [
'_seopress_redirections_type' => 'redirection_header_code',
'_seopress_redirections_value' => 'redirection_url_to',
];
$this->replace_meta( $hash, null, $object_id, $object_type, 'convert_variables' );
$redirection = [
'source' => trim( parse_url( $source_url, PHP_URL_PATH ), '/' ),
'destination' => $this->get_meta( $object_type, $object_id, '_seopress_redirections_value' ),
'code' => $this->get_meta( $object_type, $object_id, '_seopress_redirections_type' ),
'status' => $this->get_meta( $object_type, $object_id, '_seopress_redirections_enabled' ),
];
$this->save_redirection( $redirection );
}
/**
* Get snippet value.
*
* @param int $post_id Post ID.
* @param int $meta_key Meta key.
*
* @return string $value Snippet value
*/
private function get_snippet_value( $post_id, $meta_key ) {
$prefix = in_array( $meta_key, [ 'events_offers_valid_from_date', 'events_offers_valid_from_time' ], true ) ? '_seopress_rich_snippets_' : '_seopress_pro_rich_snippets_';
$value = get_post_meta( $post_id, $prefix . $meta_key, true );
if ( in_array( $meta_key, [ 'recipes_prep_time', 'recipes_cook_time', 'videos_duration' ], true ) ) {
$value .= 'M';
}
$hash = [
'events_start_date' => 'events_start_time',
'events_end_date' => 'events_end_time',
'events_offers_valid_from_date' => 'events_offers_valid_from_time',
];
if ( isset( $hash[ $meta_key ] ) ) {
$time = get_post_meta( $post_id, $prefix . $hash[ $meta_key ], true );
$value = strtotime( $value . ' ' . $time );
}
return $value;
}
/**
* Get schema meta keys.
*
* @param string $type Type of snippet.
*
* @return array
*/
private function get_schema_metakeys( $type ) {
$hash = [
'articles' => [
'article_type' => 'article_type',
'article_title' => 'name',
],
'recipes' => [
'recipes_name' => 'name',
'recipes_desc' => 'desc',
'recipes_cat' => 'recipe_type',
'recipes_prep_time' => 'recipe_preptime',
'recipes_cook_time' => 'recipe_cooktime',
'recipes_calories' => 'recipe_calories',
'recipes_yield' => 'recipe_yield',
'recipes_ingredient' => 'recipe_ingredients',
],
'courses' => [
'courses_title' => 'name',
'courses_desc' => 'desc',
'courses_school' => 'course_provider',
'courses_website' => 'course_provider_url',
],
'videos' => [
'videos_name' => 'name',
'videos_description' => 'desc',
'videos_img' => 'rank_math_twitter_title',
'videos_url' => 'video_url',
'videos_duration' => 'video_duration',
],
'events' => [
'events_type' => 'event_type',
'events_name' => 'name',
'events_desc' => 'desc',
'events_location_address' => 'event_address',
'events_location_name' => 'event_venue',
'events_location_url' => 'event_venue_url',
'events_start_date' => 'event_startdate',
'events_end_date' => 'event_enddate',
'events_offers_price' => 'event_price',
'events_offers_price_currency' => 'event_currency',
'events_offers_url' => 'event_ticketurl',
'events_offers_availability' => 'event_availability',
'events_offers_valid_from_date' => 'event_availability_starts',
'events_performer' => 'event_performer',
],
'products' => [
'product_description' => 'desc',
'product_name' => 'name',
'product_price_currency' => 'product_currency',
'product_price' => 'product_price',
],
'review' => [
'review_item' => 'name',
'item_name' => 'desc',
'review_rating' => 'review_rating_value',
],
];
return isset( $hash[ $type ] ) ? $hash[ $type ] : false;
}
/**
* Set primary term for post
*
* @param int[] $post_ids Post IDs.
*/
private function set_primary_term( $post_ids ) {
$post_ids = wp_list_pluck( $post_ids, 'ID' );
$table = DB::query_builder( 'postmeta' );
$results = $table->whereLike( 'meta_key', '_seopress_robots_primary_cat' )->whereIn( 'post_id', $post_ids )->get();
foreach ( $results as $result ) {
if ( 'none' !== $result->meta_value ) {
update_post_meta( $result->post_id, 'rank_math_primary_category', $result->meta_value );
}
}
}
/**
* Set post/term robots.
*
* @param int $object_id Object id.
* @param string $object_type Object type.
*/
private function set_object_robots( $object_id, $object_type ) {
// Early bail if robots data is set in Rank Math plugin.
if ( ! empty( $this->get_meta( $object_type, $object_id, 'rank_math_robots' ) ) ) {
return;
}
$current = $this->get_robots_by_hash( $object_id, $object_type );
$is_noindex = in_array( 'noindex', $current, true );
$is_nofollow = in_array( 'nofollow', $current, true );
if ( ! $is_noindex || ! $is_nofollow ) {
$robots = $this->get_default_robots( $object_id, $object_type );
$current[] = ! $is_nofollow && ! empty( $robots['nofollow'] ) ? 'nofollow' : '';
// Keep global no index status.
if ( ! empty( $robots['noindex'] ) ) {
unset( $current['index'] );
$current[] = 'noindex';
}
}
$this->update_meta( $object_type, $object_id, 'rank_math_robots', array_unique( $current ) );
}
/**
* Get by meta hash.
*
* @param int $object_id Object id.
* @param string $object_type Object type.
*
* @return array Array of robots data.
*/
private function get_robots_by_hash( $object_id, $object_type ) {
$current = [];
$hash = [
'_seopress_robots_index' => 'noindex',
'_seopress_robots_follow' => 'nofollow',
'_seopress_robots_imageindex' => 'noimageindex',
'_seopress_robots_archive' => 'noarchive',
'_seopress_robots_snippet' => 'nosnippet',
];
foreach ( $hash as $source => $value ) {
if ( ! empty( $this->get_meta( $object_type, $object_id, $source ) ) ) {
$current[] = $value;
}
}
return $current;
}
/**
* Get default robots data from settings.
*
* @param int $object_id Object id.
* @param string $object_type Object type.
*
* @return array Array of robots data.
*/
private function get_default_robots( $object_id, $object_type ) {
$seopress_titles = get_option( 'seopress_titles_option_name' );
if ( 'post' === $object_type ) {
$post_type = get_post_type( $object_id );
return isset( $seopress_titles['seopress_titles_single_titles'][ $post_type ] ) ? $seopress_titles['seopress_titles_single_titles'][ $post_type ] : [];
}
$term = get_term( $object_id );
return isset( $seopress_titles['seopress_titles_tax_titles'][ $term->taxonomy ] ) ? $seopress_titles['seopress_titles_tax_titles'][ $term->taxonomy ] : [];
}
}

View File

@@ -0,0 +1,137 @@
<?php
/**
* The Status.
*
* @since 0.9.0
* @package RankMath
* @subpackage RankMath\Admin\Importers
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\Admin\Importers;
defined( 'ABSPATH' ) || exit;
/**
* Status class.
*/
class Status {
/**
* The status.
*
* @var bool
*/
private $status = false;
/**
* The message.
*
* @var string
*/
private $message = '';
/**
* The action being performed.
*
* @var string
*/
private $action;
/**
* Get the status.
*
* @return bool Status.
*/
public function is_success() {
return $this->status;
}
/**
* Get the message.
*
* @return string Status message.
*/
public function get_message() {
if ( '' === $this->message ) {
return $this->get_default_message();
}
return $this->message;
}
/**
* Get the action.
*
* @return string Action type.
*/
public function get_action() {
return $this->action;
}
/**
* Set the status.
*
* @param string $status Status.
*/
public function set_status( $status ) {
$this->status = $status;
}
/**
* Set the message.
*
* @param string $message Status message.
*/
public function set_message( $message ) {
$this->message = $message;
}
/**
* Set the action.
*
* @param string $action Action performing.
*/
public function set_action( $action ) {
$this->action = $action;
}
/**
* Get default message.
*
* @return string
*/
private function get_default_message() {
$hash = [
'settings' => esc_html__( 'Settings imported successfully.', 'rank-math' ),
'news' => esc_html__( 'News Settings imported successfully.', 'rank-math' ),
'video' => esc_html__( 'Video Settings imported successfully.', 'rank-math' ),
'deactivate' => esc_html__( 'Plugin deactivated successfully.', 'rank-math' ),
/* translators: start, end, total */
'postmeta' => esc_html__( 'Imported post meta for posts %1$s - %2$s out of %3$s ', 'rank-math' ),
/* translators: total */
'termmeta' => esc_html__( 'Imported term meta for %s terms.', 'rank-math' ),
/* translators: start, end, total */
'usermeta' => esc_html__( 'Imported user meta for users %1$s - %2$s out of %3$s ', 'rank-math' ),
/* translators: total */
'redirections' => esc_html__( 'Imported %s redirections.', 'rank-math' ),
/* translators: start, end, total */
'blocks' => esc_html__( 'Imported blocks from posts %1$s - %2$s out of %3$s ', 'rank-math' ),
/* translators: start, end, total */
'recalculate' => esc_html__( 'Recalculating scores for posts %1$s - %2$s... ', 'rank-math' ),
];
if ( false === $this->is_success() ) {
$hash = [
'settings' => esc_html__( 'Settings import failed.', 'rank-math' ),
'postmeta' => esc_html__( 'Posts meta import failed.', 'rank-math' ),
'termmeta' => esc_html__( 'Term meta import failed.', 'rank-math' ),
'usermeta' => esc_html__( 'User meta import failed.', 'rank-math' ),
'redirections' => esc_html__( 'There are no redirection to import.', 'rank-math' ),
'blocks' => esc_html__( 'Blocks import failed.', 'rank-math' ),
];
}
return isset( $hash[ $this->get_action() ] ) ? $hash[ $this->get_action() ] : '';
}
}

View File

@@ -0,0 +1,794 @@
<?php
/**
* The WP Schema Pro 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\Str;
defined( 'ABSPATH' ) || exit;
/**
* WP_Schema_Pro class.
*/
class WP_Schema_Pro extends Plugin_Importer {
/**
* The plugin name.
*
* @var string
*/
protected $plugin_name = 'WP Schema Pro';
/**
* Plugin options meta key.
*
* @var string
*/
protected $meta_key = 'bsf-aiosrs';
/**
* Option keys to import and clean.
*
* @var array
*/
protected $option_keys = [ 'wp-schema-pro-general-settings', 'wp-schema-pro-social-profiles', 'wp-schema-pro-global-schemas' ];
/**
* Choices keys to import.
*
* @var array
*/
protected $choices = [ 'settings', 'postmeta' ];
/**
* Convert Schema Pro variables if needed.
*
* @param string $string Value to convert.
*
* @return string
*/
public function convert_variables( $string ) {
$string = str_replace( 'blogname', '%sitename%', $string );
$string = str_replace( 'blogdescription', '%sitedesc%', $string );
$string = str_replace( 'site_url', get_bloginfo( 'url' ), $string );
$string = str_replace( 'site_logo', get_theme_mod( 'custom_logo' ), $string );
$string = str_replace( 'featured_image', '', $string );
$string = str_replace( 'featured_img', '', $string );
$string = str_replace( 'post_title', '%seo_title%', $string );
$string = str_replace( 'post_excerpt', '%seo_description%', $string );
$string = str_replace( 'post_content', '%seo_description%', $string );
$string = str_replace( 'post_date', '%date%', $string );
$string = str_replace( 'post_modified', '%modified%', $string );
$string = str_replace( 'post_permalink', '', $string );
$string = str_replace( 'author_name', '%name%', $string );
$string = str_replace( 'author_first_name', '%name%', $string );
$string = str_replace( 'author_last_name', '%name%', $string );
$string = str_replace( 'author_image', '', $string );
return $string;
}
/**
* Import settings of plugin.
*
* @return bool
*/
protected function settings() {
$this->get_settings();
$schema_general = get_option( 'wp-schema-pro-general-settings' );
$schema_social = get_option( 'wp-schema-pro-social-profiles' );
$schema_global = get_option( 'wp-schema-pro-global-schemas' );
// Knowledge Graph Logo.
if ( isset( $schema_general['site-logo-custom'] ) ) {
$this->replace_image( $schema_general['site-logo-custom'], $this->titles, 'knowledgegraph_logo', 'knowledgegraph_logo_id' );
}
// General.
$hash = [ 'site-represent' => 'knowledgegraph_type' ];
$has_key = 'person' === $schema_general['site-represent'] ? 'person-name' : 'site-name';
$hash[ $has_key ] = 'knowledgegraph_name';
$this->replace( $hash, $schema_general, $this->titles );
$this->titles['local_seo'] = isset( $schema_general['site-represent'] ) && ! empty( $yoast_titles['site-represent'] ) ? 'on' : 'off';
// Social.
$hash = [
'facebook' => 'social_url_facebook',
'twitter' => 'twitter_author_names',
];
$this->replace( $hash, $schema_social, $this->titles );
// About & Contact Page.
$hash = [
'about-page' => 'local_seo_about_page',
'contact-page' => 'local_seo_contact_page',
];
$this->replace( $hash, $schema_global, $this->titles );
$this->update_settings();
return true;
}
/**
* Import post meta of plugin.
*
* @return array
*/
protected function postmeta() {
$this->set_pagination( $this->get_post_ids( true ) );
foreach ( $this->get_post_ids() as $snippet_post ) {
$post_id = $snippet_post->ID;
$snippet = $this->get_snippet_details( $post_id );
if ( ! $snippet ) {
continue;
}
$this->update_postmeta( $post_id, $snippet );
}
return $this->get_pagination_arg();
}
/**
* Update post meta.
*
* @param int $post_id Post ID.
* @param array $snippet Snippet data.
*/
private function update_postmeta( $post_id, $snippet ) {
$type = $snippet['type'];
$hash = $this->get_schema_types();
if ( ! isset( $hash[ $type ] ) ) {
return;
}
$details = $snippet['details'];
$methods = [
'work-example' => 'get_book_editions',
'steps' => 'get_howto_steps',
'tool' => 'get_howto_tools',
'supply' => 'get_howto_supplies',
'rating' => 'get_rating',
];
$data = [];
foreach ( $hash[ $type ] as $snippet_key => $snippet_value ) {
$method = isset( $methods[ $snippet_key ] ) ? $methods[ $snippet_key ] : 'get_schema_meta';
$value = $this->$method( $details, $snippet_key, $post_id, $snippet, $snippet_value );
$this->validate_schema_data( $data, $value, $snippet_value, $snippet_key );
}
if ( ! empty( $data ) ) {
if ( isset( $data['schema-type'] ) ) {
$type = $data['schema-type'];
unset( $data['schema-type'] );
}
$type = $this->sanitize_schema_type( $type );
$data['@type'] = $type;
$data['metadata'] = [
'title' => Helper::sanitize_schema_title( $type ),
'type' => 'template',
'isPrimary' => 1,
'shortcode' => uniqid( 's-' ),
];
$type = in_array( $type, [ 'BlogPosting', 'NewsArticle' ], true ) ? 'Article' : $type;
update_post_meta( $post_id, 'rank_math_schema_' . $type, $data );
}
}
/**
* Validate schema data.
*
* @param array $data Schema entity data.
* @param string $value Entity value.
* @param string $key Entity key.
* @param string $snippet_key Snippet key.
*/
private function validate_schema_data( &$data, $value, $key, $snippet_key ) {
if ( 'question-answer' === $snippet_key && ! empty( $value ) ) {
foreach ( $value as $question ) {
$data[ $key ][] = [
'@type' => 'Question',
'name' => $question['question'],
'acceptedAnswer' => [
'@type' => 'Answer',
'text' => $question['answer'],
],
];
}
return;
}
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 || 'jobLocation' === $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';
}
if ( 'baseSalary' === $key ) {
$data['@type'] = 'MonetaryAmount';
}
if ( 'value' === $key ) {
$data['@type'] = 'QuantitativeValue';
}
if ( 'performer' === $key ) {
$data['@type'] = 'Person';
}
if ( 'provider' === $key || 'hiringOrganization' === $key ) {
$data['@type'] = 'Organization';
}
}
/**
* Get ratings value.
*
* @param array $details Array of details.
* @param string $snippet_key Snippet key.
* @param string $post_id Post ID.
* @param array $snippet Snippet data.
* @param string $snippet_value Snippet value.
* @return string
*/
private function get_rating( $details, $snippet_key, $post_id, $snippet, $snippet_value ) {
return get_post_meta( $post_id, 'bsf-schema-pro-rating-' . $snippet['id'], true );
}
/**
* Get post meta for schema plugin
*
* @param array $details Array of details.
* @param string $snippet_key Snippet key.
* @param string $post_id Post ID.
* @param array $snippet Snippet data.
* @param string $snippet_value Snippet value.
* @return string
*/
private function get_schema_meta( $details, $snippet_key, $post_id, $snippet, $snippet_value ) {
$value = isset( $details[ $snippet_key ] ) ? $details[ $snippet_key ] : '';
if ( 'custom-text' === $value ) {
$value = isset( $details[ $snippet_key . '-custom-text' ] ) ? $details[ $snippet_key . '-custom-text' ] : '';
}
if ( 'create-field' === $value ) {
$value = get_post_meta( $post_id, $snippet['type'] . '-' . $snippet['id'] . '-' . $snippet_key, true );
}
if ( 'specific-field' === $value ) {
$key = isset( $details[ $snippet_key . '-specific-field' ] ) ? $details[ $snippet_key . '-specific-field' ] : '';
$value = get_post_meta( $post_id, $key, true );
}
return $this->convert_variables( $value );
}
/**
* Get Book Editions.
*
* @param array $details Array of details.
* @param string $snippet_key Snippet key.
* @param string $post_id Post ID.
* @param array $snippet Snippet data.
* @param string $snippet_value Snippet value.
* @return string
*/
private function get_howto_steps( $details, $snippet_key, $post_id, $snippet, $snippet_value ) {
$steps = get_post_meta( $post_id, "how-to-{$snippet['id']}-steps", true );
if ( empty( $steps ) ) {
return [];
}
$data = [];
foreach ( $steps as $step ) {
$entity = [
'@type' => 'HowToStep',
'name' => $step['name'],
'url' => $step['url'],
];
if ( ! empty( $step['description'] ) ) {
$entity['itemListElement'] = [
'@type' => 'HowToDirection',
'text' => $step['description'],
];
}
if ( ! empty( $step['image'] ) ) {
$entity['image'] = [
'@type' => 'ImageObject',
'text' => wp_get_attachment_url( $step['image'] ),
];
}
$data[] = $entity;
}
return $data;
}
/**
* Get Book Editions.
*
* @param array $details Array of details.
* @param string $snippet_key Snippet key.
* @param string $post_id Post ID.
* @param array $snippet Snippet data.
* @param string $snippet_value Snippet value.
* @return string
*/
private function get_howto_tools( $details, $snippet_key, $post_id, $snippet, $snippet_value ) {
$tools = get_post_meta( $post_id, "how-to-{$snippet['id']}-tool", true );
if ( empty( $tools ) ) {
return [];
}
$data = [];
foreach ( $tools as $tool ) {
$data[] = [
'@type' => 'HowToTool',
'name' => $tool['name'],
];
}
return $data;
}
/**
* Get Book Editions.
*
* @param array $details Array of details.
* @param string $snippet_key Snippet key.
* @param string $post_id Post ID.
* @param array $snippet Snippet data.
* @param string $snippet_value Snippet value.
* @return string
*/
private function get_howto_supplies( $details, $snippet_key, $post_id, $snippet, $snippet_value ) {
$supplies = get_post_meta( $post_id, "how-to-{$snippet['id']}-supply", true );
if ( empty( $supplies ) ) {
return [];
}
$data = [];
foreach ( $supplies as $supply ) {
$data[] = [
'@type' => 'HowToSupply',
'name' => $supply['name'],
];
}
return $data;
}
/**
* Get Book Editions.
*
* @param array $details Array of details.
* @param string $snippet_key Snippet key.
* @param string $post_id Post ID.
* @param array $snippet Snippet data.
* @param string $snippet_value Snippet value.
* @return string
*/
private function get_book_editions( $details, $snippet_key, $post_id, $snippet, $snippet_value ) {
if ( empty( $details[ $snippet_key ] ) ) {
return '';
}
$editions = [];
$data = [
'details' => $details,
'snippet_key' => $snippet_key,
'post_id' => $post_id,
'snippet' => $snippet,
'snippet_value' => $snippet_value,
];
foreach ( $details[ $snippet_key ] as $key => $edition ) {
$editions[] = [
'book_edition' => $this->normalize_edition( $key . '-book-edition', $edition['book-edition'], $data ),
'isbn' => $this->normalize_edition( $key . '-serial-number', $edition['serial-number'], $data ),
'url' => $this->normalize_edition( $key . '-url-template', $edition['url-template'], $data ),
'book_format' => $this->normalize_edition( $key . '-book-format', $edition['book-format'], $data ),
];
}
return $editions;
}
/**
* Normalize Book Edition.
*
* @param string $key Custom field key.
* @param string $value Custom field value.
* @param array $data Snippet data.
* @return string
*/
private function normalize_edition( $key, $value, $data ) {
if ( ! $value ) {
return '';
}
$hash = [
'custom-text' => 'get_custom_text',
'create-field' => 'get_created_field',
'specific-field' => 'get_specific_field',
];
if ( isset( $hash[ $value ] ) ) {
$method = $hash[ $value ];
$value = $this->$method( $key, $value, $data );
}
return $this->convert_variables( $value );
}
/**
* Get Custom Text added in the Settings.
*
* @param string $key Custom field key.
* @param string $value Custom field value.
* @param array $data Snippet data.
* @return string
*/
private function get_custom_text( $key, $value, $data ) {
$key = $data['snippet_key'] . '-custom-text';
return isset( $data['details'][ $key ] ) ? $data['details'][ $key ] : '';
}
/**
* Get Created field value added in the post metabox.
*
* @param string $key Custom field key.
* @param string $value Custom field value.
* @param array $data Snippet data.
* @return string
*/
private function get_created_field( $key, $value, $data ) {
$meta_key = $data['snippet']['type'] . '-' . $data['snippet']['id'] . '-' . $data['snippet_key'] . '-' . $key;
return get_post_meta( $data['post_id'], $meta_key, true );
}
/**
* Get Specific Custom field value.
*
* @param string $key Custom field key.
* @param string $value Custom field value.
* @param array $data Snippet data.
* @return string
*/
private function get_specific_field( $key, $value, $data ) {
$key = isset( $data['details'][ $data[ $snippet_key . '-specific-field' ] ] ) ? $data['details'][ $data[ $snippet_key . '-specific-field' ] ] : '';
return get_post_meta( $data['post_id'], $key, true );
}
/**
* Sanitize schema type before saving
*
* @param string $type Schema type to sanitize.
* @return string
*/
private function sanitize_schema_type( $type ) {
$hash = [
'job-posting' => 'JobPosting',
'video-object' => 'VideoObject',
'software-application' => 'SoftwareApplication',
'faq' => 'FAQPage',
'how-to' => 'HowTo',
];
$type = in_array( $type, [ 'AdvertiserContentArticle', 'Report', 'SatiricalArticle', 'ScholarlyArticle', 'TechArticle' ], true )
? 'Article'
: $type;
return isset( $hash[ $type ] ) ? $hash[ $type ] : ucfirst( $type );
}
/**
* Get Snippet Details stored in aiosrs-schema posts
*
* @param int $post_id Post ID.
* @return array
*/
private function get_snippet_details( $post_id ) {
global $wpdb;
$post_type = addcslashes( get_post_type( $post_id ), '_' );
$query = "SELECT p.ID, pm.meta_value FROM {$wpdb->postmeta} as pm
INNER JOIN {$wpdb->posts} as p ON pm.post_id = p.ID
WHERE pm.meta_key = 'bsf-aiosrs-schema-location'
AND p.post_type = 'aiosrs-schema'
AND p.post_status = 'publish'";
$orderby = ' ORDER BY p.post_date DESC LIMIT 1';
$meta_args = "pm.meta_value LIKE '%\"basic-global\"%'";
$meta_args .= " OR pm.meta_value LIKE '%\"basic-singulars\"%'";
$meta_args .= " OR pm.meta_value LIKE '%\"{$post_type}|all\"%'";
$meta_args .= " OR pm.meta_value LIKE '%\"post-{$post_id}\"%'";
$local_posts = $wpdb->get_col( $query . ' AND (' . $meta_args . ')' . $orderby ); // phpcs:ignore
if ( empty( $local_posts ) ) {
return false;
}
$current_page_data = [];
foreach ( $local_posts as $local_post ) {
$snippet_type = get_post_meta( $local_post, 'bsf-aiosrs-schema-type', true );
return [
'id' => $local_post,
'type' => $snippet_type,
'details' => get_post_meta( $local_post, 'bsf-aiosrs-' . $snippet_type, true ),
];
}
}
/**
* Get the actions which can be performed for the plugin.
*
* @return array
*/
public function get_choices() {
return [
'settings' => esc_html__( 'Import Settings', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Plugin settings and site-wide meta data.', 'rank-math' ) ),
'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 schema types
*
* @return array
*/
private function get_schema_types() {
return [
'event' => $this->get_event_fields(),
'job-posting' => $this->get_job_posting_fields(),
'product' => $this->get_product_fields(),
'recipe' => $this->get_recipe_fields(),
'software-application' => $this->get_software_fields(),
'video-object' => $this->get_video_fields(),
'article' => [
'name' => 'headline',
'description' => 'description',
'schema-type' => 'schema-type',
],
'book' => [
'name' => 'name',
'url' => 'url',
'author' => 'author.name',
'work-example' => 'book_editions',
'rating' => 'review.reviewRating.ratingValue',
],
'course' => [
'name' => 'name',
'description' => 'description',
'orgnization-name' => 'provider.name',
'same-as' => 'provider.sameAs',
'rating' => 'review.reviewRating.ratingValue',
],
'person' => [
'name' => 'name',
'email' => 'email',
'gender' => 'gender',
'job-title' => 'jobTitle',
'street' => 'address.streetAddress',
'locality' => 'address.addressLocality',
'region' => 'address.addressRegion',
'postal' => 'address.postalCode',
'country' => 'address.addressCountry',
],
'service' => [
'name' => 'name',
'description' => 'description',
'type' => 'serviceType',
'price-range' => 'offers.price',
],
'faq' => [
'question-answer' => 'mainEntity',
],
'how-to' => [
'name' => 'name',
'description' => 'description',
'total-time' => 'totalTime',
'steps' => 'step',
'supply' => 'supply',
'tool' => 'tool',
],
];
}
/**
* Get event fields.
*
* @return array
*/
private function get_event_fields() {
return [
'name' => 'name',
'description' => 'description',
'schema-type' => 'schema-type',
'event-status' => 'eventStatus',
'event-attendance-mode' => 'eventAttendanceMode',
'start-date' => 'startDate',
'end-date' => 'endDate',
'location' => 'location.name',
'location-street' => 'location.address.streetAddress',
'location-locality' => 'location.address.addressLocality',
'location-region' => 'location.address.addressRegion',
'location-postal' => 'location.address.postalCode',
'location-country' => 'location.address.addressCountry',
'ticket-buy-url' => 'offers.url',
'price' => 'offers.price',
'currency' => 'offers.priceCurrency',
'avail' => 'offers.availability',
'performer' => 'performer.name',
'rating' => 'review.reviewRating.ratingValue',
];
}
/**
* Get job_posting fields.
*
* @return array
*/
private function get_job_posting_fields() {
return [
'title' => 'title',
'description' => 'description',
'job-type' => 'employmentType',
'start-date' => 'datePosted',
'expiry-date' => 'validThrough',
'orgnization-name' => 'hiringOrganization.name',
'same-as' => 'hiringOrganization.sameAs',
'organization-logo' => 'hiringOrganization.logo',
'location-street' => 'jobLocation.address.streetAddress',
'location-locality' => 'jobLocation.address.addressLocality',
'location-region' => 'jobLocation.address.addressRegion',
'location-postal' => 'jobLocation.address.postalCode',
'location-country' => 'jobLocation.address.addressCountry',
'salary' => 'baseSalary.value.value',
'salary-currency' => 'baseSalary.currency',
'salary-unit' => 'baseSalary.value.unitText',
];
}
/**
* Get product fields.
*
* @return array
*/
private function get_product_fields() {
return [
'name' => 'name',
'description' => 'description',
'sku' => 'sku',
'brand-name' => 'brand.name',
'price' => 'offers.price',
'currency' => 'offers.priceCurrency',
'avail' => 'offers.availability',
'price-valid-until' => 'offers.priceValidUntil',
'rating' => 'review.reviewRating.ratingValue',
];
}
/**
* Get recipe fields.
*
* @return array
*/
private function get_recipe_fields() {
return [
'name' => 'name',
'description' => 'description',
'recipe-category' => 'recipeCategory',
'recipe-cuisine' => 'recipeCuisine',
'recipe-yield' => 'recipeYield',
'recipe-keywords' => 'keywords',
'nutrition' => 'nutrition.calories',
'preperation-time' => 'prepTime',
'cook-time' => 'cookTime',
'ingredients' => 'recipeIngredient',
'rating' => 'review.reviewRating.ratingValue',
];
}
/**
* Get software fields.
*
* @return array
*/
private function get_software_fields() {
return [
'name' => 'name',
'rating' => 'review.reviewRating.ratingValue',
'price' => 'offers.price',
'currency' => 'offers.priceCurrency',
'operating-system' => 'operatingSystem',
'category' => 'applicationCategory',
];
}
/**
* Get video fields.
*
* @return array
*/
private function get_video_fields() {
return [
'name' => 'name',
'description' => 'description',
'content-url' => 'contentUrl',
'embed-url' => 'embedUrl',
'duration' => 'duration',
'rating' => 'review.reviewRating.ratingValue',
];
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
<?php // Silence is golden.