Commit realizado el 12:13:52 08-04-2024
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
@@ -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 '/';
|
||||
}
|
||||
}
|
@@ -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 ] : [];
|
||||
}
|
||||
}
|
@@ -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() ] : '';
|
||||
}
|
||||
}
|
@@ -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
@@ -0,0 +1 @@
|
||||
<?php // Silence is golden.
|
Reference in New Issue
Block a user