1343 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			1343 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/**
 | 
						|
 * The AIO SEO 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;
 | 
						|
use RankMath\Helpers\DB;
 | 
						|
 | 
						|
defined( 'ABSPATH' ) || exit;
 | 
						|
 | 
						|
/**
 | 
						|
 * AIOSEO class.
 | 
						|
 */
 | 
						|
class AIOSEO extends Plugin_Importer {
 | 
						|
 | 
						|
	/**
 | 
						|
	 * The plugin name.
 | 
						|
	 *
 | 
						|
	 * @var string
 | 
						|
	 */
 | 
						|
	protected $plugin_name = 'All In One SEO Pack';
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Plugin options meta key.
 | 
						|
	 *
 | 
						|
	 * @var string
 | 
						|
	 */
 | 
						|
	protected $meta_key = '_aioseop_';
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Option keys to import and clean.
 | 
						|
	 *
 | 
						|
	 * @var array
 | 
						|
	 */
 | 
						|
	protected $option_keys = [ 'aioseo_options' ];
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Choices keys to import.
 | 
						|
	 *
 | 
						|
	 * @var array
 | 
						|
	 */
 | 
						|
	protected $choices = [ 'settings', 'postmeta', 'termmeta', 'usermeta', 'redirections', 'locations' ];
 | 
						|
 | 
						|
	/**
 | 
						|
	 * AIOSEO settings.
 | 
						|
	 *
 | 
						|
	 * @var array
 | 
						|
	 */
 | 
						|
	private $aio_settings = [];
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get the actions which can be performed for the plugin.
 | 
						|
	 *
 | 
						|
	 * @return array
 | 
						|
	 */
 | 
						|
	public function get_choices() {
 | 
						|
		$choices = [
 | 
						|
			'settings' => esc_html__( 'Import Settings', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Import AIO SEO 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 titles, descriptions, robots meta, OpenGraph info, etc.', 'rank-math' ) ),
 | 
						|
			'usermeta' => esc_html__( 'Import Author Meta', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Import Social URLs of your author archive pages.', 'rank-math' ) ),
 | 
						|
		];
 | 
						|
 | 
						|
		if ( DB::check_table_exists( 'aioseo_terms' ) ) {
 | 
						|
			$choices['termmeta'] = esc_html__( 'Import Term Meta', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Import meta information of your terms like the titles, descriptions, robots meta, OpenGraph info, etc.', 'rank-math' ) );
 | 
						|
		}
 | 
						|
 | 
						|
		if ( DB::check_table_exists( 'aioseo_redirects' ) ) {
 | 
						|
			$choices['redirections'] = esc_html__( 'Import Redirections', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Import all the redirections you have already set up in AIO SEO Premium.', 'rank-math' ) );
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $this->get_location_ids( true ) ) ) {
 | 
						|
			$choices['locations'] = esc_html__( 'Import Locations', 'rank-math' ) . Admin_Helper::get_tooltip( esc_html__( 'Import Locations Settings.', 'rank-math' ) );
 | 
						|
		}
 | 
						|
 | 
						|
		return $choices;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Convert Yoast / AIO SEO variables if needed.
 | 
						|
	 *
 | 
						|
	 * @param string $string Value to convert.
 | 
						|
	 * @return string
 | 
						|
	 */
 | 
						|
	public function convert_variables( $string ) {
 | 
						|
		$string = str_replace( '#site_title', '%sitename%', $string );
 | 
						|
		$string = str_replace( '#tagline', '%sitedesc%', $string );
 | 
						|
		$string = str_replace( '#separator_sa', '%sep%', $string );
 | 
						|
		$string = str_replace( '#post_title', '%title%', $string );
 | 
						|
		$string = str_replace( '#post_excerpt', '%excerpt%', $string );
 | 
						|
		$string = str_replace( '#post_content', '%excerpt%', $string );
 | 
						|
		$string = str_replace( '#taxonomy_description', '%term_description%', $string );
 | 
						|
		$string = str_replace( '#category_description', '%term_description%', $string );
 | 
						|
		$string = str_replace( '#taxonomy_title', '%term%', $string );
 | 
						|
		$string = str_replace( '#category', '%term%', $string );
 | 
						|
		$string = str_replace( '#author_first_name #author_last_name', '%name%', $string );
 | 
						|
		$string = str_replace( '#current_year', '%currentyear%', $string );
 | 
						|
		$string = str_replace( '#current_date', '%currentdate%', $string );
 | 
						|
		$string = str_replace( '#current_day', '%currentday%', $string );
 | 
						|
		$string = str_replace( '#current_month', '%currentmonth%', $string );
 | 
						|
		$string = str_replace( '#post_date', '%date%', $string );
 | 
						|
		$string = str_replace( '#search_term', '%search_query%', $string );
 | 
						|
		$string = str_replace( '#author_link', '%AUTHORLINK%', $string );
 | 
						|
		$string = str_replace( '#post_link', '%POSTLINK%', $string );
 | 
						|
		$string = str_replace( '#site_link', '%BLOGLINK%', $string );
 | 
						|
		$string = str_replace( '#author_name', '%name%', $string );
 | 
						|
		$string = str_replace( '#author_bio', '%user_description%', $string );
 | 
						|
		$string = str_replace( '#archive_date', '%date%', $string );
 | 
						|
		$string = str_replace( '#breadcrumb_archive_post_type_name', '%s', $string );
 | 
						|
		$string = str_replace( '#breadcrumb_search_string', '%s', $string );
 | 
						|
 | 
						|
		return $string;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import settings of plugin.
 | 
						|
	 *
 | 
						|
	 * @return bool
 | 
						|
	 */
 | 
						|
	protected function settings() {
 | 
						|
		$this->get_settings();
 | 
						|
		$this->aio_settings = json_decode( get_option( 'aioseo_options' ), true );
 | 
						|
 | 
						|
		$this->general_settings();
 | 
						|
		$this->sitemap_settings();
 | 
						|
		$this->titles_settings();
 | 
						|
		$this->pro_settings();
 | 
						|
		$this->update_settings();
 | 
						|
 | 
						|
		return true;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Imports redirections data.
 | 
						|
	 *
 | 
						|
	 * @return array
 | 
						|
	 */
 | 
						|
	protected function redirections() {
 | 
						|
		$count        = 0;
 | 
						|
		$table        = DB::query_builder( 'aioseo_redirects' );
 | 
						|
		$redirections = $table->select( '*' )->get();
 | 
						|
 | 
						|
		if ( empty( $redirections ) ) {
 | 
						|
			return compact( 'count' );
 | 
						|
		}
 | 
						|
 | 
						|
		Helper::update_modules( [ 'redirections' => 'on' ] );
 | 
						|
		foreach ( $redirections as $redirection ) {
 | 
						|
			if ( false !== $this->save_redirection( (array) $redirection ) ) {
 | 
						|
				$count++;
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		return compact( 'count' );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Save redirection.
 | 
						|
	 *
 | 
						|
	 * @param array $redirection Redirection object.
 | 
						|
	 *
 | 
						|
	 * @return mixed
 | 
						|
	 */
 | 
						|
	private function save_redirection( $redirection ) {
 | 
						|
		if (
 | 
						|
			empty( $redirection['source_url'] ) ||
 | 
						|
			empty( $redirection['type'] ) ||
 | 
						|
			! in_array( $redirection['type'], [ '301', '302', '307', '410', '451' ], true )
 | 
						|
		) {
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		$item = Redirection::from(
 | 
						|
			[
 | 
						|
				'sources'     => [
 | 
						|
					[
 | 
						|
						'ignore'     => ! empty( $redirection['ignore_case'] ) ? 'case' : '',
 | 
						|
						'pattern'    => $redirection['source_url'],
 | 
						|
						'comparison' => isset( $redirection['source_url_match'] ) && 'regex' === $redirection['source_url_match'] ? 'regex' : 'exact',
 | 
						|
					],
 | 
						|
				],
 | 
						|
				'url_to'      => isset( $redirection['target_url'] ) ? $redirection['target_url'] : '',
 | 
						|
				'header_code' => isset( $redirection['type'] ) ? $redirection['type'] : '301',
 | 
						|
				'status'      => empty( $redirection['enabled'] ) ? 'inactive' : 'active',
 | 
						|
			]
 | 
						|
		);
 | 
						|
 | 
						|
		return $item->save();
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import General Settings.
 | 
						|
	 */
 | 
						|
	private function general_settings() {
 | 
						|
		if ( ! empty( $this->aio_settings['rssContent'] ) ) {
 | 
						|
			$hash = [
 | 
						|
				'before' => 'rss_before_content',
 | 
						|
				'after'  => 'rss_after_content',
 | 
						|
			];
 | 
						|
			$this->replace( $hash, $this->aio_settings['rssContent'], $this->settings, 'convert_variables' );
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $this->aio_settings['breadcrumbs'] ) ) {
 | 
						|
			$hash = [
 | 
						|
				'enable'             => 'breadcrumbs',
 | 
						|
				'separator'          => 'breadcrumbs_separator',
 | 
						|
				'homepageLabel'      => 'breadcrumbs_home_label',
 | 
						|
				'breadcrumbPrefix'   => 'breadcrumbs_prefix',
 | 
						|
				'archiveFormat'      => 'breadcrumbs_archive_format',
 | 
						|
				'searchResultFormat' => 'breadcrumbs_search_format',
 | 
						|
				'errorFormat404'     => 'breadcrumbs_404_label',
 | 
						|
				'showCurrentItem'    => 'breadcrumbs_remove_post_title',
 | 
						|
			];
 | 
						|
			$this->replace( $hash, $this->aio_settings['breadcrumbs'], $this->settings, 'convert_variables' );
 | 
						|
			$this->replace( [ 'homepageLink' => 'breadcrumbs_home' ], $this->aio_settings['breadcrumbs'], $this->settings, 'convert_bool' );
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $this->aio_settings['webmasterTools'] ) ) {
 | 
						|
			$hash = [
 | 
						|
				'google'    => 'google_verify',
 | 
						|
				'bing'      => 'bing_verify',
 | 
						|
				'baidu'     => 'baidu_verify',
 | 
						|
				'yandex'    => 'yandex_verify',
 | 
						|
				'pinterest' => 'pinterest_verify',
 | 
						|
			];
 | 
						|
			$this->replace( $hash, $this->aio_settings['webmasterTools'], $this->settings );
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Sitemap settings.
 | 
						|
	 */
 | 
						|
	private function sitemap_settings() {
 | 
						|
		if ( empty( $this->aio_settings['sitemap'] ) ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$sitemap_settings = $this->aio_settings['sitemap'];
 | 
						|
		$general          = ! empty( $sitemap_settings['general'] ) ? $sitemap_settings['general'] : [];
 | 
						|
		if ( empty( $general ) ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		// Sitemap.
 | 
						|
		if ( isset( $general['enable'] ) ) {
 | 
						|
			Helper::update_modules( [ 'sitemap' => 'on' ] );
 | 
						|
		}
 | 
						|
 | 
						|
		$this->sitemap['items_per_page'] = $general['linksPerIndex'];
 | 
						|
 | 
						|
		$all = ! empty( $general['postTypes']['all'] );
 | 
						|
		foreach ( Helper::get_accessible_post_types() as $post_type ) {
 | 
						|
			$this->sitemap[ "pt_{$post_type}_sitemap" ] = $all || in_array( $post_type, $general['postTypes']['included'], true ) ? 'on' : 'off';
 | 
						|
		}
 | 
						|
 | 
						|
		$all = ! empty( $general['taxonomies']['all'] );
 | 
						|
		foreach ( Helper::get_accessible_taxonomies() as $taxonomy => $object ) {
 | 
						|
			$this->sitemap[ "tax_{$taxonomy}_sitemap" ] = $all || in_array( $taxonomy, $general['taxonomies']['included'], true ) ? 'on' : 'off';
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $general['advancedSettings'] ) ) {
 | 
						|
			$this->sitemap_advanced_settings( $general['advancedSettings'] );
 | 
						|
		}
 | 
						|
 | 
						|
		// HTML Sitemap.
 | 
						|
		if ( isset( $sitemap_settings['html'] ) ) {
 | 
						|
			$this->html_sitemap_settings( $sitemap_settings['html'] );
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import Pro Settings.
 | 
						|
	 */
 | 
						|
	private function pro_settings() {
 | 
						|
		$settings = get_option( 'aioseo_options_pro' );
 | 
						|
		if ( empty( $settings ) ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$settings = json_decode( $settings, true );
 | 
						|
		$this->news_sitemap_settings( $settings );
 | 
						|
		$this->video_sitemap_settings( $settings );
 | 
						|
		$this->image_seo_settings( $settings );
 | 
						|
		$this->local_seo_settings( $settings );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import Local SEO Settings.
 | 
						|
	 *
 | 
						|
	 * @param array $settings Pro Settings.
 | 
						|
	 */
 | 
						|
	private function local_seo_settings( $settings ) {
 | 
						|
		if ( empty( $settings['localBusiness'] ) ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		Helper::update_modules( [ 'local-seo' => 'on' ] );
 | 
						|
		$local_settings = $settings['localBusiness'];
 | 
						|
		$business       = $local_settings['locations']['business'];
 | 
						|
 | 
						|
		$hash = [
 | 
						|
			'name'         => 'knowledgegraph_name',
 | 
						|
			'image'        => 'knowledgegraph_logo',
 | 
						|
			'businessType' => 'local_business_type',
 | 
						|
		];
 | 
						|
		$this->replace( $hash, $business, $this->titles );
 | 
						|
		$this->titles['url'] = $business['urls']['website'];
 | 
						|
 | 
						|
		// Street Address.
 | 
						|
		$address = [];
 | 
						|
		$hash    = [
 | 
						|
			'streetLine1' => 'streetAddress',
 | 
						|
			'city'        => 'addressLocality',
 | 
						|
			'state'       => 'addressRegion',
 | 
						|
			'zipCode'     => 'postalCode',
 | 
						|
			'country'     => 'addressCountry',
 | 
						|
		];
 | 
						|
		$this->replace( $hash, $business['address'], $address );
 | 
						|
		if ( ! empty( $business['address']['streetLine2'] ) ) {
 | 
						|
			$address['streetAddress'] = $address['streetAddress'] . ', ' . $business['address']['streetLine2'];
 | 
						|
		}
 | 
						|
		$this->titles['local_address'] = $address;
 | 
						|
 | 
						|
		if ( ! empty( $business['contact'] ) ) {
 | 
						|
			$this->titles['email'] = $business['contact']['email'];
 | 
						|
 | 
						|
			$this->titles['phone_numbers'][] = [
 | 
						|
				'type'   => 'customer support',
 | 
						|
				'number' => $business['contact']['phone'],
 | 
						|
			];
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $business['payment'] ) ) {
 | 
						|
			$this->titles['price_range'] = $business['payment']['priceRange'];
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $local_settings['openingHours'] ) ) {
 | 
						|
			$this->add_opening_hours( $local_settings['openingHours'] );
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import Opening Hours Settings.
 | 
						|
	 *
 | 
						|
	 * @param array $opening_hours Opening Hours.
 | 
						|
	 */
 | 
						|
	private function add_opening_hours( $opening_hours ) {
 | 
						|
		$data = [];
 | 
						|
		foreach ( $opening_hours['days'] as $day => $opening_hour ) {
 | 
						|
			if ( ! empty( $opening_hour['closed'] ) ) {
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
 | 
						|
			$data[] = [
 | 
						|
				'day'  => ucfirst( $day ),
 | 
						|
				'time' => $opening_hour['openTime'] . '-' . $opening_hour['closeTime'],
 | 
						|
			];
 | 
						|
		}
 | 
						|
 | 
						|
		$this->titles['opening_hours'] = $data;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import Image SEO Settings.
 | 
						|
	 *
 | 
						|
	 * @param array $settings Pro Settings.
 | 
						|
	 */
 | 
						|
	private function image_seo_settings( $settings ) {
 | 
						|
		if ( empty( $settings['image']['format'] ) ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		Helper::update_modules( [ 'image-seo' => 'on' ] );
 | 
						|
		$format = $settings['image']['format'];
 | 
						|
		if ( ! empty( $format['title'] ) ) {
 | 
						|
			$this->settings['add_img_title'] = $this->convert_variables( $format['title'] );
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $format['altTag'] ) ) {
 | 
						|
			$this->settings['add_img_title'] = $this->convert_variables( $format['altTag'] );
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import Video Sitemap Settings.
 | 
						|
	 *
 | 
						|
	 * @param array $settings Pro Settings.
 | 
						|
	 */
 | 
						|
	private function video_sitemap_settings( $settings ) {
 | 
						|
		if ( empty( $settings['sitemap']['video'] ) ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
		$video_settings = $settings['sitemap']['video'];
 | 
						|
		if ( ! empty( $video_settings['enable'] ) ) {
 | 
						|
			Helper::update_modules( [ 'video-sitemap' => 'on' ] );
 | 
						|
		}
 | 
						|
 | 
						|
		$this->sitemap['video_sitemap_post_type'] = $video_settings['postTypes']['all'] ? array_keys( Helper::get_accessible_post_types() ) : $video_settings['postTypes']['included'];
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import News Sitemap Settings.
 | 
						|
	 *
 | 
						|
	 * @param array $settings Pro Settings.
 | 
						|
	 */
 | 
						|
	private function news_sitemap_settings( $settings ) {
 | 
						|
		if ( empty( $settings['sitemap']['news'] ) ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
		$news_settings = $settings['sitemap']['news'];
 | 
						|
		if ( ! empty( $news_settings['enable'] ) ) {
 | 
						|
			Helper::update_modules( [ 'news-sitemap' => 'on' ] );
 | 
						|
		}
 | 
						|
 | 
						|
		$this->sitemap['news_sitemap_publication_name'] = ! empty( $news_settings['publicationName'] ) ? $news_settings['publicationName'] : '';
 | 
						|
		$this->sitemap['news_sitemap_post_type']        = $news_settings['postTypes']['all'] ? array_keys( Helper::get_accessible_post_types() ) : $news_settings['postTypes']['included'];
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import Sitemap Advanced Settings.
 | 
						|
	 *
 | 
						|
	 * @param array $settings Sitemap Settings.
 | 
						|
	 */
 | 
						|
	private function sitemap_advanced_settings( $settings ) {
 | 
						|
		if ( ! empty( $settings['excludePosts'] ) ) {
 | 
						|
			$exclude_posts = [];
 | 
						|
			foreach ( $settings['excludePosts'] as $exclude_post ) {
 | 
						|
				$exclude_post    = json_decode( $exclude_post, true );
 | 
						|
				$exclude_posts[] = ! empty( $exclude_post['value'] ) ? $exclude_post['value'] : '';
 | 
						|
			}
 | 
						|
 | 
						|
			$this->sitemap['exclude_posts'] = implode( ', ', $exclude_posts );
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $settings['excludeTerms'] ) ) {
 | 
						|
			$exclude_terms = [];
 | 
						|
			foreach ( $settings['excludeTerms'] as $exclude_term ) {
 | 
						|
				$exclude_term    = json_decode( $exclude_term, true );
 | 
						|
				$exclude_terms[] = ! empty( $exclude_term['value'] ) ? $exclude_term['value'] : '';
 | 
						|
			}
 | 
						|
 | 
						|
			$this->sitemap['exclude_terms'] = $exclude_terms;
 | 
						|
		}
 | 
						|
 | 
						|
		$this->sitemap['include_images'] = ! empty( $settings['excludeImages'] ) ? 'off' : 'on';
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import HTML Sitemap Settings.
 | 
						|
	 *
 | 
						|
	 * @param array $settings HTML Settings.
 | 
						|
	 */
 | 
						|
	private function html_sitemap_settings( $settings ) {
 | 
						|
		if ( empty( $settings ) ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$this->sitemap['html_sitemap']         = $settings['enable'] ? 'on' : 'off';
 | 
						|
		$this->sitemap['html_sitemap_display'] = empty( $settings['pageUrl'] ) ? 'shortcode' : 'page';
 | 
						|
		if ( ! empty( $settings['pageUrl'] ) ) {
 | 
						|
			$page = get_page_by_path( basename( $settings['pageUrl'] ) );
 | 
						|
			if ( ! empty( $page ) ) {
 | 
						|
				$this->sitemap['html_sitemap_page'] = $page->ID;
 | 
						|
			} else {
 | 
						|
				// Create a new page with the sitemap page url.
 | 
						|
				$this->sitemap['html_sitemap_page'] = wp_insert_post(
 | 
						|
					[
 | 
						|
						'post_title'   => __( 'HTML Sitemap', 'rank-math' ),
 | 
						|
						'post_content' => '',
 | 
						|
						'post_status'  => 'publish',
 | 
						|
						'post_type'    => 'page',
 | 
						|
						'post_name'    => basename( $settings['pageUrl'] ),
 | 
						|
					]
 | 
						|
				);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $settings['postTypes']['all'] ) ) {
 | 
						|
			$post_types = Helper::get_accessible_post_types();
 | 
						|
			$post_types = array_keys( $post_types );
 | 
						|
			foreach ( $post_types as $post_type ) {
 | 
						|
				$this->sitemap[ 'pt_' . $post_type . '_html_sitemap' ] = in_array( $post_type, $settings['postTypes']['included'], true ) ? 'on' : 'off';
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			foreach ( $settings['postTypes']['included'] as $post_type ) {
 | 
						|
				$this->sitemap[ 'pt_' . $post_type . '_html_sitemap' ] = 'on';
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $settings['taxonomies']['all'] ) ) {
 | 
						|
			$taxonomies = Helper::get_accessible_taxonomies();
 | 
						|
			$taxonomies = array_keys( $taxonomies );
 | 
						|
			foreach ( $taxonomies as $taxonomy ) {
 | 
						|
				$this->sitemap[ 'tax_' . $taxonomy . '_html_sitemap' ] = in_array( $taxonomy, $settings['taxonomies']['included'], true ) ? 'on' : 'off';
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			foreach ( $settings['taxonomies']['included'] as $taxonomy ) {
 | 
						|
				$this->sitemap[ 'tax_' . $taxonomy . '_html_sitemap' ] = 'on';
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import Titles & Meta Settings.
 | 
						|
	 */
 | 
						|
	private function titles_settings() {
 | 
						|
		$settings = $this->aio_settings['searchAppearance'];
 | 
						|
		$hash     = [
 | 
						|
			'separator'       => 'title_separator',
 | 
						|
			'siteTitle'       => 'homepage_title',
 | 
						|
			'metaDescription' => 'homepage_description',
 | 
						|
		];
 | 
						|
 | 
						|
		$this->replace( $hash, $settings['global'], $this->titles, 'convert_variables' );
 | 
						|
 | 
						|
		$this->titles['noindex_empty_taxonomies'] = $settings['advanced']['noIndexEmptyCat'];
 | 
						|
		$this->titles['knowledgegraph_type']      = 'organization' === $settings['global']['schema']['siteRepresents'] ? 'company' : 'person';
 | 
						|
		$this->titles['knowledgegraph_name']      = $settings['global']['schema']['organizationName'];
 | 
						|
		$this->titles['knowledgegraph_logo']      = $settings['global']['schema']['organizationLogo'];
 | 
						|
 | 
						|
		$robots = $this->get_robots_data( $settings['advanced']['globalRobotsMeta'] );
 | 
						|
 | 
						|
		$this->titles['robots_global']          = $robots['robots'];
 | 
						|
		$this->titles['advanced_robots_global'] = $robots['advanced_robots'];
 | 
						|
 | 
						|
		$this->social_settings();
 | 
						|
		$this->archive_settings();
 | 
						|
		$this->post_types_settings();
 | 
						|
		$this->taxonomies_settings();
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import Social Settings.
 | 
						|
	 */
 | 
						|
	private function social_settings() {
 | 
						|
		if ( empty( $this->aio_settings['social'] ) ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$hash = [
 | 
						|
			'adminId'   => 'facebook_admin_id',
 | 
						|
			'appId'     => 'facebook_app_id',
 | 
						|
			'authorUrl' => 'facebook_author_urls',
 | 
						|
		];
 | 
						|
		$this->replace( $hash, $this->aio_settings['social']['facebook']['advanced'], $this->titles );
 | 
						|
 | 
						|
		$hash = [
 | 
						|
			'title'       => 'homepage_facebook_title',
 | 
						|
			'description' => 'homepage_facebook_description',
 | 
						|
			'image'       => 'homepage_facebook_image',
 | 
						|
		];
 | 
						|
		$this->replace( $hash, $this->aio_settings['social']['facebook']['homePage'], $this->titles );
 | 
						|
 | 
						|
		$profiles        = $this->aio_settings['social']['profiles'];
 | 
						|
		$profile_urls    = $profiles['urls'];
 | 
						|
		$fb_url          = $profile_urls['facebookPageUrl'];
 | 
						|
		$tw_url          = $profile_urls['twitterUrl'];
 | 
						|
		$additional_urls = $profiles['additionalUrls'];
 | 
						|
 | 
						|
		$profile_urls = array_map(
 | 
						|
			function( $url ) use ( $fb_url, $tw_url ) {
 | 
						|
				return $url !== $fb_url && $url !== $tw_url ? $url : false;
 | 
						|
			},
 | 
						|
			$profile_urls
 | 
						|
		);
 | 
						|
 | 
						|
		$urls = array_filter( array_values( $profile_urls ) );
 | 
						|
		array_merge( $urls, explode( "\n", $additional_urls ) );
 | 
						|
 | 
						|
		$this->titles['social_additional_profiles'] = implode( PHP_EOL, $urls );
 | 
						|
		$this->titles['social_url_facebook']        = $fb_url;
 | 
						|
		$this->titles['twitter_author_names']       = str_replace( 'https://twitter.com/', '', $tw_url );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Archive settings.
 | 
						|
	 */
 | 
						|
	private function archive_settings() {
 | 
						|
		$settings = $this->aio_settings['searchAppearance']['archives'];
 | 
						|
		$author   = $settings['author'];
 | 
						|
		$hash     = [
 | 
						|
			'title'           => 'author_archive_title',
 | 
						|
			'metaDescription' => 'author_archive_description',
 | 
						|
		];
 | 
						|
		$this->replace( $hash, $author, $this->titles, 'convert_variables' );
 | 
						|
		$this->titles['disable_author_archives'] = $author['show'] ? 'off' : 'on';
 | 
						|
		$this->titles['author_add_meta_box']     = $author['advanced']['showMetaBox'];
 | 
						|
		$this->titles['author_custom_robots']    = ! $author['advanced']['robotsMeta']['default'];
 | 
						|
		$robots                                  = $this->get_robots_data( $author['advanced']['robotsMeta'] );
 | 
						|
		$this->titles['author_robots']           = $robots['robots'];
 | 
						|
		$this->titles['author_advanced_robots']  = $robots['advanced_robots'];
 | 
						|
 | 
						|
		$date = $settings['date'];
 | 
						|
		$hash = [
 | 
						|
			'title'           => 'date_archive_title',
 | 
						|
			'metaDescription' => 'date_archive_description',
 | 
						|
		];
 | 
						|
		$this->replace( $hash, $date, $this->titles, 'convert_variables' );
 | 
						|
		$this->titles['disable_date_archives'] = $date['show'] ? 'off' : 'on';
 | 
						|
		$robots                                = $this->get_robots_data( $date['advanced']['robotsMeta'] );
 | 
						|
		$this->titles['date_archive_robots']   = $robots['robots'];
 | 
						|
		$this->titles['date_advanced_robots']  = $robots['advanced_robots'];
 | 
						|
 | 
						|
		$this->titles['search_title'] = $this->convert_variables( $settings['search']['title'] );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Post Types settings.
 | 
						|
	 */
 | 
						|
	private function post_types_settings() {
 | 
						|
		$settings = $this->aio_settings['searchAppearance']['dynamic']['postTypes'];
 | 
						|
		foreach ( Helper::get_accessible_post_types() as $post_type ) {
 | 
						|
			if ( empty( $settings[ $post_type ] ) ) {
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
 | 
						|
			$hash = [
 | 
						|
				'title'           => "pt_{$post_type}_title",
 | 
						|
				'metaDescription' => "pt_{$post_type}_description",
 | 
						|
				'customFields'    => "pt_{$post_type}_analyze_fields",
 | 
						|
			];
 | 
						|
			$this->replace( $hash, $settings[ $post_type ], $this->titles, 'convert_variables' );
 | 
						|
 | 
						|
			if ( ! empty( $settings[ $post_type ]['schemaType'] ) ) {
 | 
						|
				$schema_type = strtolower( $settings[ $post_type ]['schemaType'] );
 | 
						|
				if ( in_array( $schema_type, [ 'article', 'book', 'course', 'dataset', 'event', 'jobposting', 'movie', 'music', 'person', 'product', 'recipe', 'restaurant', 'service', 'software', 'video' ], true ) ) {
 | 
						|
					$this->titles[ "pt_{$post_type}_default_rich_snippet" ] = $schema_type;
 | 
						|
					$this->titles[ "pt_{$post_type}_default_article_type" ] = $settings[ $post_type ]['articleType'];
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			$robots = $settings[ $post_type ]['advanced']['robotsMeta'];
 | 
						|
			if ( ! empty( $robots['default'] ) ) {
 | 
						|
				$this->titles[ "pt_{$post_type}_custom_robots" ] = 'off';
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
 | 
						|
			$robots = $this->get_robots_data( $robots );
 | 
						|
			$this->titles[ "pt_{$post_type}_custom_robots" ]   = 'on';
 | 
						|
			$this->titles[ "pt_{$post_type}_robots" ]          = $robots['robots'];
 | 
						|
			$this->titles[ "pt_{$post_type}_advanced_robots" ] = $robots['advanced_robots'];
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Taxonomies settings.
 | 
						|
	 */
 | 
						|
	private function taxonomies_settings() {
 | 
						|
		if ( ! isset( $this->aio_settings['searchAppearance']['dynamic']['taxonomies'] ) ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$settings = $this->aio_settings['searchAppearance']['dynamic']['taxonomies'];
 | 
						|
		foreach ( Helper::get_accessible_taxonomies() as $taxonomy => $tax_obj ) {
 | 
						|
			if ( empty( $settings[ $taxonomy ] ) ) {
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
 | 
						|
			$hash = [
 | 
						|
				'title'           => "tax_{$taxonomy}_title",
 | 
						|
				'metaDescription' => "tax_{$taxonomy}_description",
 | 
						|
			];
 | 
						|
			$this->replace( $hash, $settings[ $taxonomy ], $this->titles, 'convert_variables' );
 | 
						|
 | 
						|
			$robots                                   = $this->get_robots_data( $settings[ $taxonomy ]['advanced']['robotsMeta'] );
 | 
						|
			$this->titles[ "tax_{$taxonomy}_robots" ] = $robots['robots'];
 | 
						|
			$this->titles[ "tax_{$taxonomy}_advanced_robots" ] = $robots['advanced_robots'];
 | 
						|
			$this->titles[ "tax_{$taxonomy}_add_meta_box" ]    = ! empty( $settings[ $taxonomy ]['show'] ) ? 'on' : '';
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Function to get Robots data.
 | 
						|
	 *
 | 
						|
	 * @param  array $aioseo_robots AIOSEO robots.
 | 
						|
	 * @return array Robots data.
 | 
						|
	 */
 | 
						|
	private function get_robots_data( $aioseo_robots ) {
 | 
						|
		$robots          = [];
 | 
						|
		$advanced_robots = [];
 | 
						|
		$keys            = [
 | 
						|
			'maxSnippet'      => 'max-snippet',
 | 
						|
			'maxVideoPreview' => 'max-video-preview',
 | 
						|
			'maxImagePreview' => 'max-image-preview',
 | 
						|
		];
 | 
						|
		foreach ( $aioseo_robots as $key => $value ) {
 | 
						|
			if ( in_array( $key, [ 'noindex', 'nofollow', 'noarchive', 'noimageindex', 'nosnippet' ], true ) && $value ) {
 | 
						|
				$robots[] = $key;
 | 
						|
			}
 | 
						|
 | 
						|
			if ( in_array( $key, [ 'maxSnippet', 'maxVideoPreview', 'maxImagePreview' ], true ) && $value ) {
 | 
						|
				$advanced_robots[ $keys[ $key ] ] = $value;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		$robots[] = ! in_array( 'noindex', $robots, true ) ? 'index' : '';
 | 
						|
 | 
						|
		return [
 | 
						|
			'robots'          => $robots,
 | 
						|
			'advanced_robots' => $advanced_robots,
 | 
						|
		];
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import post meta of plugin.
 | 
						|
	 *
 | 
						|
	 * @return array
 | 
						|
	 */
 | 
						|
	protected function postmeta() {
 | 
						|
		$this->set_pagination( $this->get_posts( true ) );
 | 
						|
		$posts = $this->get_posts();
 | 
						|
 | 
						|
		foreach ( $posts as $post ) {
 | 
						|
			$post_id = (int) $post->post_id;
 | 
						|
			$post    = (array) $post;
 | 
						|
			$hash    = [
 | 
						|
				'title'                    => 'rank_math_title',
 | 
						|
				'description'              => 'rank_math_description',
 | 
						|
				'canonical_url'            => 'rank_math_canonical_url',
 | 
						|
				'og_title'                 => 'rank_math_facebook_title',
 | 
						|
				'og_description'           => 'rank_math_facebook_description',
 | 
						|
				'og_image_custom_url'      => 'rank_math_facebook_image',
 | 
						|
				'twitter_title'            => 'rank_math_twitter_title',
 | 
						|
				'twitter_description'      => 'rank_math_twitter_description',
 | 
						|
				'twitter_image_custom_url' => 'rank_math_twitter_image',
 | 
						|
			];
 | 
						|
			$this->replace_meta( $hash, $post, $post_id, 'post', 'convert_variables' );
 | 
						|
			$this->replace_meta( [ 'twitter_use_og' => 'rank_math_twitter_use_facebook' ], $post, $post_id, 'post', 'convert_bool' );
 | 
						|
			$this->set_object_robots( $post_id, $post, 'post' );
 | 
						|
			$this->set_keywords( $post_id, $post, 'post' );
 | 
						|
			$this->add_schema_data( $post_id, $post );
 | 
						|
		}
 | 
						|
 | 
						|
		return $this->get_pagination_arg();
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import term meta of plugin.
 | 
						|
	 *
 | 
						|
	 * @return array
 | 
						|
	 */
 | 
						|
	protected function termmeta() {
 | 
						|
		$this->set_pagination( $this->get_terms( true ) );
 | 
						|
		$terms = $this->get_terms();
 | 
						|
 | 
						|
		foreach ( $terms as $term ) {
 | 
						|
			$term_id = $term->term_id;
 | 
						|
			$term    = (array) $term;
 | 
						|
			$hash    = [
 | 
						|
				'title'                    => 'rank_math_title',
 | 
						|
				'description'              => 'rank_math_description',
 | 
						|
				'canonical_url'            => 'rank_math_canonical_url',
 | 
						|
				'og_title'                 => 'rank_math_facebook_title',
 | 
						|
				'og_description'           => 'rank_math_facebook_description',
 | 
						|
				'og_image_custom_url'      => 'rank_math_facebook_image',
 | 
						|
				'twitter_title'            => 'rank_math_twitter_title',
 | 
						|
				'twitter_description'      => 'rank_math_twitter_description',
 | 
						|
				'twitter_image_custom_url' => 'rank_math_twitter_image',
 | 
						|
			];
 | 
						|
			$this->replace_meta( $hash, $term, $term_id, 'term', 'convert_variables' );
 | 
						|
			$this->replace_meta( [ 'twitter_use_og' => 'rank_math_twitter_use_facebook' ], $term, $term_id, 'term', 'convert_bool' );
 | 
						|
			$this->set_object_robots( $term_id, $term, 'term' );
 | 
						|
			$this->set_keywords( $term_id, $term, 'term' );
 | 
						|
		}
 | 
						|
 | 
						|
		return [ 'count' => count( $terms ) ];
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import user meta of plugin.
 | 
						|
	 *
 | 
						|
	 * @return array
 | 
						|
	 */
 | 
						|
	protected function usermeta() {
 | 
						|
		$this->set_pagination( $this->get_user_ids( true ) );
 | 
						|
		$user_ids = $this->get_user_ids();
 | 
						|
 | 
						|
		$hash = [
 | 
						|
			'wpseo_title'    => 'rank_math_title',
 | 
						|
			'wpseo_desc'     => 'rank_math_description',
 | 
						|
			'wpseo_metadesc' => 'rank_math_description',
 | 
						|
		];
 | 
						|
 | 
						|
		foreach ( $user_ids as $user ) {
 | 
						|
			$userid = $user->ID;
 | 
						|
 | 
						|
			$facebook_url = get_user_meta( $userid, 'aioseo_facebook_page_url', true );
 | 
						|
			if ( $facebook_url ) {
 | 
						|
				update_user_meta( $userid, 'facebook', $facebook_url );
 | 
						|
			}
 | 
						|
 | 
						|
			$twitter_url = get_user_meta( $userid, 'aioseo_twitter_url', true );
 | 
						|
			if ( $twitter_url ) {
 | 
						|
				update_user_meta( $userid, 'twitter', str_replace( 'https://twitter.com/', '', $twitter_url ) );
 | 
						|
			}
 | 
						|
 | 
						|
			$social_urls = [];
 | 
						|
			foreach ( [ 'aioseo_instagram_url', 'aioseo_pinterest_url', 'aioseo_youtube_url', 'aioseo_linkedin_url', 'aioseo_tumblr_url', 'aioseo_yelp_page_url', 'aioseo_sound_cloud_url', 'aioseo_wikipedia_url', 'aioseo_myspace_url' ] as $key ) {
 | 
						|
				$social_urls[] = get_user_meta( $userid, $key, true );
 | 
						|
			}
 | 
						|
 | 
						|
			$additional_urls = get_user_meta( 4, 'aioseo_profiles_additional_urls', true );
 | 
						|
			if ( $additional_urls ) {
 | 
						|
				$social_urls = array_merge( $social_urls, explode( "\n", $additional_urls ) );
 | 
						|
			}
 | 
						|
 | 
						|
			if ( ! empty( $social_urls ) ) {
 | 
						|
				update_user_meta( $userid, 'additional_profile_urls', implode( ' ', array_filter( $social_urls ) ) );
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		return $this->get_pagination_arg();
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Deactivate plugin action.
 | 
						|
	 */
 | 
						|
	protected function deactivate() {
 | 
						|
		if ( is_plugin_active( $this->get_plugin_file() ) ) {
 | 
						|
			deactivate_plugins( $this->get_plugin_file() );
 | 
						|
			deactivate_plugins( 'aioseo-image-seo/aioseo-image-seo.php' );
 | 
						|
			deactivate_plugins( 'aioseo-local-business/aioseo-local-business.php' );
 | 
						|
			deactivate_plugins( 'aioseo-news-sitemap/aioseo-news-sitemap.php' );
 | 
						|
			deactivate_plugins( 'aioseo-video-sitemap/aioseo-video-sitemap.php' );
 | 
						|
			deactivate_plugins( 'aioseo-local-business/aioseo-local-business.php' );
 | 
						|
			deactivate_plugins( 'aioseo-redirects/aioseo-redirects.php' );
 | 
						|
		}
 | 
						|
 | 
						|
		return true;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get all post IDs of all allowed post types only.
 | 
						|
	 *
 | 
						|
	 * @param bool $count If we need count only for pagination purposes.
 | 
						|
	 * @return int|array
 | 
						|
	 */
 | 
						|
	private function get_posts( $count = false ) {
 | 
						|
		$paged = $this->get_pagination_arg( 'page' );
 | 
						|
		$table = DB::query_builder( 'aioseo_posts' );
 | 
						|
 | 
						|
		return $count ? absint( $table->selectCount( 'ID', 'total' )->getVar() ) :
 | 
						|
			$table->select( '*' )->page( $paged - 1, $this->items_per_page )->get();
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get all post IDs of all allowed post types only.
 | 
						|
	 *
 | 
						|
	 * @param bool $count If we need count only for pagination purposes.
 | 
						|
	 * @return int|array
 | 
						|
	 */
 | 
						|
	private function get_terms( $count = false ) {
 | 
						|
		$paged = $this->get_pagination_arg( 'page' );
 | 
						|
		$table = DB::query_builder( 'aioseo_terms' );
 | 
						|
 | 
						|
		return $count ? absint( $table->selectCount( 'ID', 'total' )->getVar() ) :
 | 
						|
			$table->select( '*' )->page( $paged - 1, $this->items_per_page )->get();
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import Schema Data.
 | 
						|
	 *
 | 
						|
	 * @param int   $post_id Post ID.
 | 
						|
	 * @param array $post    Post data.
 | 
						|
	 */
 | 
						|
	private function add_schema_data( $post_id, $post ) {
 | 
						|
		if ( empty( $post['schema_type'] ) || ! in_array( $post['schema_type'], [ 'SoftwareApplication', 'Product', 'Recipe', 'Course' ], true ) ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$type   = strtolower( $post['schema_type'] );
 | 
						|
		$type   = 'softwareapplication' === $type ? 'software' : $type;
 | 
						|
		$schema = json_decode( $post['schema_type_options'], true );
 | 
						|
		$data   = $this->$type( $schema[ $type ] );
 | 
						|
		$schema = [
 | 
						|
			'metadata' => [
 | 
						|
				'title'                   => $data['@type'],
 | 
						|
				'isPrimary'               => true,
 | 
						|
				'type'                    => 'template',
 | 
						|
				'reviewLocation'          => 'custom',
 | 
						|
				'reviewLocationShortcode' => '[rank_math_rich_snippet]',
 | 
						|
			],
 | 
						|
		] + $data;
 | 
						|
 | 
						|
		update_post_meta( $post_id, 'rank_math_schema_' . $schema['@type'], $schema );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import Software Schema Data.
 | 
						|
	 *
 | 
						|
	 * @param array $data Software schema data.
 | 
						|
	 */
 | 
						|
	private function software( $data ) {
 | 
						|
		$schema = [
 | 
						|
			'@type'               => 'SoftwareApplication',
 | 
						|
			'name'                => ! empty( $data['name'] ) ? $data['name'] : '%seo_title%',
 | 
						|
			'applicationCategory' => $data['category'],
 | 
						|
			'offers'              => [
 | 
						|
				'@type'         => 'Offer',
 | 
						|
				'price'         => $data['price'],
 | 
						|
				'priceCurrency' => $data['currency'],
 | 
						|
			],
 | 
						|
		];
 | 
						|
 | 
						|
		if ( ! empty( $data['operatingSystems'] ) ) {
 | 
						|
			$operating_system = array_map(
 | 
						|
				function( $system ) {
 | 
						|
					return $system['value'];
 | 
						|
				},
 | 
						|
				json_decode( $data['operatingSystems'], true )
 | 
						|
			);
 | 
						|
 | 
						|
			$schema['operatingSystem'] = implode( ', ', $operating_system );
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $data['reviews'] ) ) {
 | 
						|
			$reviews          = json_decode( $data['reviews'][0], true );
 | 
						|
			$schema['review'] = [
 | 
						|
				'@type'         => 'Review',
 | 
						|
				'datePublished' => '%date(Y-m-dTH:i:sP)%',
 | 
						|
				'dateModified'  => '%modified(Y-m-dTH:i:sP)%',
 | 
						|
				'author'        => [
 | 
						|
					'@type' => 'Person',
 | 
						|
					'name'  => '%name%',
 | 
						|
				],
 | 
						|
				'reviewRating'  => [
 | 
						|
					'@type'       => 'Rating',
 | 
						|
					'ratingValue' => ! empty( $reviews['rating'] ) ? $reviews['rating'] : '',
 | 
						|
				],
 | 
						|
			];
 | 
						|
		}
 | 
						|
 | 
						|
		return $schema;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import Product Schema Data.
 | 
						|
	 *
 | 
						|
	 * @param array $data Product schema data.
 | 
						|
	 */
 | 
						|
	private function product( $data ) {
 | 
						|
		return [
 | 
						|
			'@type'       => 'Product',
 | 
						|
			'name'        => ! empty( $data['name'] ) ? $data['name'] : '%seo_title%',
 | 
						|
			'description' => ! empty( $data['description'] ) ? $data['description'] : '%seo_description%',
 | 
						|
			'gtin8'       => $data['identifier'],
 | 
						|
			'brand'       => [
 | 
						|
				'@type' => 'Brand',
 | 
						|
				'name'  => $data['brand'],
 | 
						|
			],
 | 
						|
			'offers'      => [
 | 
						|
				'@type'           => 'Offer',
 | 
						|
				'price'           => $data['price'],
 | 
						|
				'priceCurrency'   => $data['currency'],
 | 
						|
				'priceValidUntil' => $data['priceValidUntil'],
 | 
						|
				'availability'    => str_replace( 'https://schema.org/', '', $data['availability'] ),
 | 
						|
			],
 | 
						|
		];
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import Course Schema Data.
 | 
						|
	 *
 | 
						|
	 * @param array $data Course schema data.
 | 
						|
	 */
 | 
						|
	private function course( $data ) {
 | 
						|
		return [
 | 
						|
			'@type'       => 'Course',
 | 
						|
			'name'        => $data['name'],
 | 
						|
			'description' => $data['description'],
 | 
						|
			'provider'    => [
 | 
						|
				'@type' => 'Organization',
 | 
						|
				'name'  => $data['provider'],
 | 
						|
			],
 | 
						|
		];
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import Recipe Schema Data.
 | 
						|
	 *
 | 
						|
	 * @param array $data Recipe schema data.
 | 
						|
	 */
 | 
						|
	private function recipe( $data ) {
 | 
						|
		$schema = [
 | 
						|
			'@type'          => 'Recipe',
 | 
						|
			'name'           => $data['name'],
 | 
						|
			'recipeCategory' => $data['dishType'],
 | 
						|
			'recipeCuisine'  => $data['cuisineType'],
 | 
						|
			'prepTime'       => "PT{$data['preparationTime']}M",
 | 
						|
			'cookTime'       => "PT{$data['cookingTime']}M",
 | 
						|
			'recipeYield'    => "PT{$data['servings']}M",
 | 
						|
			'nutrition'      => [
 | 
						|
				'@type'    => 'NutritionInformation',
 | 
						|
				'calories' => $data['calories'],
 | 
						|
			],
 | 
						|
		];
 | 
						|
 | 
						|
		if ( ! empty( $data['keywords'] ) ) {
 | 
						|
			$keywords = array_map(
 | 
						|
				function( $keyword ) {
 | 
						|
					return $keyword['value'];
 | 
						|
				},
 | 
						|
				json_decode( $data['keywords'], true )
 | 
						|
			);
 | 
						|
 | 
						|
			$schema['keywords'] = implode( ', ', $keywords );
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $data['ingredients'] ) ) {
 | 
						|
			$schema['recipeIngredient'] = array_map(
 | 
						|
				function( $ingredient ) {
 | 
						|
					return $ingredient['value'];
 | 
						|
				},
 | 
						|
				json_decode( $data['ingredients'], true )
 | 
						|
			);
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $data['instructions'] ) ) {
 | 
						|
			$schema['recipeInstructions'] = [
 | 
						|
				'@type'           => 'HowToSection',
 | 
						|
				'itemListElement' => [],
 | 
						|
			];
 | 
						|
 | 
						|
			foreach ( $data['instructions'] as $instruction ) {
 | 
						|
				$instruction_data = json_decode( $instruction, true );
 | 
						|
 | 
						|
				$schema['recipeInstructions']['itemListElement'][] = [
 | 
						|
					'@type' => 'HowtoStep',
 | 
						|
					'text'  => $instruction_data['content'],
 | 
						|
				];
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		return $schema;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Set Keywords.
 | 
						|
	 *
 | 
						|
	 * @param int    $object_id   Object ID.
 | 
						|
	 * @param array  $object      Object data.
 | 
						|
	 * @param string $object_type Current Object type.
 | 
						|
	 */
 | 
						|
	private function set_keywords( $object_id, $object, $object_type ) {
 | 
						|
		$keywords   = [];
 | 
						|
		$keyphrases = json_decode( $object['keyphrases'], true );
 | 
						|
 | 
						|
		if ( ! empty( $keyphrases['focus']['keyphrase'] ) ) {
 | 
						|
			$keywords[] = $keyphrases['focus']['keyphrase'];
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $keyphrases['additional'] ) ) {
 | 
						|
			foreach ( $keyphrases['additional'] as $keyword ) {
 | 
						|
				$keywords[] = $keyword['keyphrase'];
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		if ( empty( $keywords ) ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$this->update_meta( $object_type, $object_id, 'rank_math_focus_keyword', implode( ',', $keywords ) );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Set object robots meta.
 | 
						|
	 *
 | 
						|
	 * @param int    $object_id   Object ID.
 | 
						|
	 * @param array  $object      Object data.
 | 
						|
	 * @param string $object_type Current Object type.
 | 
						|
	 */
 | 
						|
	private function set_object_robots( $object_id, $object, $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' ) ) || ! empty( $object['robots_default'] ) ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		// ROBOTS.
 | 
						|
		$robots = [];
 | 
						|
		foreach ( [ 'robots_noindex', 'robots_noarchive', 'robots_nosnippet', 'robots_nofollow', 'robots_noimageindex' ] as $key ) {
 | 
						|
			if ( empty( $object[ $key ] ) ) {
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
 | 
						|
			$robots[] = str_replace( 'robots_', '', $key );
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! in_array( 'noindex', $robots, true ) ) {
 | 
						|
			$robots[] = 'index';
 | 
						|
		}
 | 
						|
		$this->update_meta( $object_type, $object_id, 'rank_math_robots', array_unique( $robots ) );
 | 
						|
 | 
						|
		$advanced_robots = [];
 | 
						|
		$keys            = [
 | 
						|
			'robots_max_snippet'      => 'max-snippet',
 | 
						|
			'robots_max_videopreview' => 'max-video-preview',
 | 
						|
			'robots_max_imagepreview' => 'max-image-preview',
 | 
						|
		];
 | 
						|
		foreach ( [ 'robots_max_snippet', 'robots_max_videopreview', 'robots_max_imagepreview' ] as $key ) {
 | 
						|
			if ( empty( $object[ $key ] ) ) {
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
 | 
						|
			$advanced_robots[ $keys[ $key ] ] = $object[ $key ];
 | 
						|
		}
 | 
						|
 | 
						|
		$this->update_meta( $object_type, $object_id, 'rank_math_advanced_robots', array_unique( $advanced_robots ) );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * 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 = isset( $source[ $search ] ) ? $source[ $search ] : $this->get_meta( $object_type, $object_id, $search );
 | 
						|
			if ( ! isset( $value ) ) {
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
 | 
						|
			$this->update_meta(
 | 
						|
				$object_type,
 | 
						|
				$object_id,
 | 
						|
				$replace,
 | 
						|
				false !== $convert ? $this->$convert( $value ) : $value
 | 
						|
			);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import Locations data from Yoast Local plugin.
 | 
						|
	 *
 | 
						|
	 * @return array
 | 
						|
	 */
 | 
						|
	protected function locations() {
 | 
						|
		$this->import_locations_terms();
 | 
						|
		$this->set_pagination( $this->get_location_ids( true ) );
 | 
						|
		$locations = $this->get_location_ids();
 | 
						|
		foreach ( $locations as $location ) {
 | 
						|
			$args = (array) $location;
 | 
						|
			unset( $args['ID'] );
 | 
						|
			$args['post_type'] = 'rank_math_locations';
 | 
						|
 | 
						|
			$post_id = wp_insert_post( $args );
 | 
						|
			if ( is_wp_error( $post_id ) ) {
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
 | 
						|
			$post_terms = wp_get_object_terms( $location->ID, 'aioseo-location-category', [ 'fields' => 'slugs' ] );
 | 
						|
			if ( ! empty( $post_terms ) && ! is_wp_error( $post_terms ) ) {
 | 
						|
				wp_set_object_terms( $post_id, $post_terms, 'rank_math_location_category', false );
 | 
						|
			}
 | 
						|
 | 
						|
			$this->locations_meta( $location->ID, $post_id );
 | 
						|
		}
 | 
						|
 | 
						|
		return $this->get_pagination_arg();
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import Locations terms.
 | 
						|
	 */
 | 
						|
	private function import_locations_terms() {
 | 
						|
		$terms = get_terms( 'aioseo-location-category' );
 | 
						|
		if ( empty( $terms ) || is_wp_error( $terms ) ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		foreach ( $terms as $term ) {
 | 
						|
			wp_insert_term( $term->name, 'rank_math_location_category', $term );
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Import Locations metadata.
 | 
						|
	 *
 | 
						|
	 * @param int $old_post_id Yoast's location id.
 | 
						|
	 * @param int $new_post_id Newly created location id.
 | 
						|
	 */
 | 
						|
	private function locations_meta( $old_post_id, $new_post_id ) {
 | 
						|
		$metas = DB::query_builder( 'aioseo_posts' )->where( 'post_id', $old_post_id )->select()->one();
 | 
						|
		if ( empty( $metas->local_seo ) ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$locations_data = json_decode( $metas->local_seo, true );
 | 
						|
		$locations_meta = ! empty( $locations_data['locations'] ) ? $locations_data['locations']['business'] : [];
 | 
						|
		$opening_hours  = ! empty( $locations_data['openingHours'] ) ? $locations_data['openingHours'] : [];
 | 
						|
 | 
						|
		$schema = [
 | 
						|
			'metadata'   => [
 | 
						|
				'type'           => 'template',
 | 
						|
				'shortcode'      => uniqid( 's-' ),
 | 
						|
				'isPrimary'      => true,
 | 
						|
				'title'          => 'Local Business',
 | 
						|
				'use_24h_format' => ! empty( $opening_hours['use24hFormat'] ),
 | 
						|
				'open247'        => ! empty( $opening_hours['alwaysOpen'] ),
 | 
						|
				'timeZone'       => ! empty( $opening_hours['timezone'] ),
 | 
						|
			],
 | 
						|
			'@type'      => $locations_meta['businessType'],
 | 
						|
			'name'       => ! empty( $locations_meta['name'] ) ? $locations_meta['name'] : '%seo_title%',
 | 
						|
			'url'        => ! empty( $locations_meta['urls'] ) ? $locations_meta['urls']['website'] : '%url%',
 | 
						|
			'address'    => ! empty( $locations_meta['address'] ) ? $this->replace_address( $locations_meta['address'] ) : '',
 | 
						|
			'areaServed' => ! empty( $locations_meta['areaServed'] ) ? $locations_meta['areaServed'] : '',
 | 
						|
		];
 | 
						|
 | 
						|
		if ( ! empty( $locations_meta['contact'] ) ) {
 | 
						|
			$contact             = $locations_meta['contact'];
 | 
						|
			$schema['email']     = ! empty( $contact['email'] ) ? $contact['email'] : '';
 | 
						|
			$schema['telephone'] = ! empty( $contact['phone'] ) ? $contact['phone'] : '';
 | 
						|
			$schema['faxNumber'] = ! empty( $contact['fax'] ) ? $contact['fax'] : '';
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $locations_meta['ids'] ) ) {
 | 
						|
			$ids             = $locations_meta['ids'];
 | 
						|
			$schema['vatID'] = ! empty( $ids['vat'] ) ? $ids['vat'] : '';
 | 
						|
			$schema['taxID'] = ! empty( $ids['tax'] ) ? $ids['tax'] : '';
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $locations_meta['payment'] ) ) {
 | 
						|
			$payment                   = $locations_meta['payment'];
 | 
						|
			$schema['priceRange']      = ! empty( $payment['priceRange'] ) ? $payment['priceRange'] : '';
 | 
						|
			$schema['paymentAccepted'] = ! empty( $payment['methods'] ) ? $payment['methods'] : '';
 | 
						|
 | 
						|
			if ( ! empty( $payment['currenciesAccepted'] ) ) {
 | 
						|
				$schema['currenciesAccepted'] = implode(
 | 
						|
					', ',
 | 
						|
					array_map(
 | 
						|
						function( $value ) {
 | 
						|
							return $value['value'];
 | 
						|
						},
 | 
						|
						json_decode( $payment['currenciesAccepted'], true )
 | 
						|
					)
 | 
						|
				);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $locations_meta['image'] ) ) {
 | 
						|
			$schema['logo'] = [
 | 
						|
				'@type' => 'ImageObject',
 | 
						|
				'url'   => $locations_meta['image'],
 | 
						|
			];
 | 
						|
		}
 | 
						|
 | 
						|
		$schema['openingHoursSpecification'] = $this->replace_opening_hours( $opening_hours['days'] );
 | 
						|
 | 
						|
		update_post_meta( $new_post_id, 'rank_math_schema_' . $schema['@type'], $schema );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Replace Opening Hours data.
 | 
						|
	 *
 | 
						|
	 * @param array $opening_hours Opening Hours data.
 | 
						|
	 * @return array Processed data.
 | 
						|
	 */
 | 
						|
	private function replace_opening_hours( $opening_hours ) {
 | 
						|
		$data = [];
 | 
						|
		$days = [ 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday' ];
 | 
						|
		foreach ( $days as $day ) {
 | 
						|
			if ( ! empty( $opening_hours[ $day ]['closed'] ) ) {
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
 | 
						|
			if ( ! empty( $opening_hours[ $day ]['open24h'] ) ) {
 | 
						|
				$opens  = '00:00';
 | 
						|
				$closes = '23:59';
 | 
						|
			} else {
 | 
						|
				$opens  = ! empty( $opening_hours[ $day ]['openTime'] ) ? $opening_hours[ $day ]['openTime'] : '';
 | 
						|
				$closes = ! empty( $opening_hours[ $day ]['closeTime'] ) ? $opening_hours[ $day ]['closeTime'] : '';
 | 
						|
			}
 | 
						|
 | 
						|
			if ( ! $opens ) {
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
 | 
						|
			$data[ $day ] = [
 | 
						|
				'@type'     => 'OpeningHoursSpecification',
 | 
						|
				'dayOfWeek' => ucfirst( $day ),
 | 
						|
				'opens'     => $opens,
 | 
						|
				'closes'    => $closes,
 | 
						|
			];
 | 
						|
		}
 | 
						|
 | 
						|
		return array_values( $data );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Replace Address data.
 | 
						|
	 *
 | 
						|
	 * @param array $address Address data.
 | 
						|
	 * @return array Processed data.
 | 
						|
	 */
 | 
						|
	private function replace_address( $address ) {
 | 
						|
		$data = [
 | 
						|
			'@type' => 'PostalAddress',
 | 
						|
		];
 | 
						|
		$hash = [
 | 
						|
			'streetLine1' => 'streetAddress',
 | 
						|
			'streetLine2' => 'addressLocality',
 | 
						|
			'state'       => 'addressRegion',
 | 
						|
			'zipCode'     => 'postalCode',
 | 
						|
			'country'     => 'addressCountry',
 | 
						|
		];
 | 
						|
 | 
						|
		foreach ( $hash as $key => $value ) {
 | 
						|
			$data[ $value ] = isset( $address[ $key ] ) ? $address[ $key ] : '';
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $address['city'] ) ) {
 | 
						|
			$data['addressLocality'] = $data['addressLocality'] . ', ' . $address['city'];
 | 
						|
		}
 | 
						|
 | 
						|
		return $data;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get all location IDs.
 | 
						|
	 *
 | 
						|
	 * @param bool $count If we need count only for pagination purposes.
 | 
						|
	 * @return int|array
 | 
						|
	 */
 | 
						|
	private function get_location_ids( $count = false ) {
 | 
						|
		$paged = $this->get_pagination_arg( 'page' );
 | 
						|
		$table = DB::query_builder( 'posts' )->where( 'post_type', 'aioseo-location' );
 | 
						|
 | 
						|
		return $count ? absint( $table->selectCount( 'ID', 'total' )->getVar() ) :
 | 
						|
			$table->select()->page( $paged - 1, $this->items_per_page )->get();
 | 
						|
	}
 | 
						|
}
 |