356 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			356 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/**
 | 
						|
 * Divi integration.
 | 
						|
 *
 | 
						|
 * @since      0.9.0
 | 
						|
 * @package    RankMath
 | 
						|
 * @subpackage RankMath\Core
 | 
						|
 * @author     Rank Math <support@rankmath.com>
 | 
						|
 */
 | 
						|
 | 
						|
namespace RankMath\Divi;
 | 
						|
 | 
						|
use RankMath\KB;
 | 
						|
use RankMath\Helper;
 | 
						|
use RankMath\Helpers\Editor;
 | 
						|
use RankMath\Helpers\Str;
 | 
						|
use RankMath\Schema\DB as Schema_DB;
 | 
						|
use RankMath\Schema\Admin as Schema_Admin;
 | 
						|
use RankMath\Traits\Hooker;
 | 
						|
use RankMath\Admin\Metabox\Screen;
 | 
						|
use WP_Dependencies;
 | 
						|
 | 
						|
defined( 'ABSPATH' ) || exit;
 | 
						|
 | 
						|
/**
 | 
						|
 * Divi class.
 | 
						|
 */
 | 
						|
class Divi {
 | 
						|
 | 
						|
	use Hooker;
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Screen object.
 | 
						|
	 *
 | 
						|
	 * @var Screen
 | 
						|
	 */
 | 
						|
	private $screen;
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Class constructor.
 | 
						|
	 */
 | 
						|
	public function __construct() {
 | 
						|
		$this->action( 'wp', 'init' );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Intialize.
 | 
						|
	 */
 | 
						|
	public function init() {
 | 
						|
		if ( ! $this->can_add_seo_tab() ) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		$this->screen = new Screen();
 | 
						|
		$this->screen->load_screen( 'post' );
 | 
						|
 | 
						|
		$this->action( 'template_redirect', 'set_window_lodash', 0 );
 | 
						|
		$this->action( 'wp_enqueue_scripts', 'register_rankmath_react' );
 | 
						|
		$this->action( 'wp_enqueue_scripts', 'add_json_data', 0 );
 | 
						|
		$this->action( 'wp_footer', 'footer_enqueue_scripts', 11 );
 | 
						|
		remove_action( 'wp_footer', [ rank_math()->json, 'output' ], 0 );
 | 
						|
		add_action( 'wp_footer', [ rank_math()->json, 'output' ], 11 );
 | 
						|
		$this->filter( 'script_loader_tag', 'add_et_tag', 10, 3 );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Set the global lodash variable.
 | 
						|
	 *
 | 
						|
	 * Lodash's `noConflict` would prevent UnderscoreJS from taking over the underscore (_)
 | 
						|
	 * global variable. Because Underscore.js will later also be assigned to the underscore (_)
 | 
						|
	 * global this function should run as early as possible.
 | 
						|
	 */
 | 
						|
	public function set_window_lodash() {
 | 
						|
		wp_register_script( 'rm-set-window-lodash', '', [ 'lodash' ], rank_math()->version, false );
 | 
						|
		wp_enqueue_script( 'rm-set-window-lodash' );
 | 
						|
		wp_add_inline_script(
 | 
						|
			'rm-set-window-lodash',
 | 
						|
			join(
 | 
						|
				"\r\n ",
 | 
						|
				[
 | 
						|
					'window.isLodash = function() {',
 | 
						|
					"if ( typeof window._ !== 'function' || typeof window._.forEach !== 'function' ) {",
 | 
						|
					'return false;',
 | 
						|
					'}',
 | 
						|
					'var isLodash = true;',
 | 
						|
					'window._.forEach(',
 | 
						|
					"[ 'cloneDeep', 'at', 'add', 'ary', 'attempt' ],",
 | 
						|
					'function( fn ) {',
 | 
						|
					"if ( isLodash && typeof window._[ fn ] !== 'function' ) {",
 | 
						|
					'isLodash = false;',
 | 
						|
					'}',
 | 
						|
					'}',
 | 
						|
					');',
 | 
						|
					'return isLodash;',
 | 
						|
					'}',
 | 
						|
					'if ( window.isLodash() ) { window.lodash = window._.noConflict(); }',
 | 
						|
				]
 | 
						|
			)
 | 
						|
		);
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Register RankMath React and ReactDOM.
 | 
						|
	 *
 | 
						|
	 * Registers the native WP version of react with a custom handle for use in the
 | 
						|
	 * RankMath module. Divi builder dequeues and deregisters native WP react scripts
 | 
						|
	 * and replaces them with their own copy of React. Their copy might not be of the
 | 
						|
	 * same version as the one RankMath requires.
 | 
						|
	 */
 | 
						|
	public function register_rankmath_react() {
 | 
						|
		$path   = site_url( '/wp-includes/js/dist/vendor/' );
 | 
						|
		$suffix = wp_scripts_get_suffix();
 | 
						|
		wp_register_script( 'rm-react', "{$path}react{$suffix}.js", [ 'wp-polyfill', 'react' ], '16.13.1', true );
 | 
						|
		wp_register_script( 'rm-react-dom', "{$path}react-dom{$suffix}.js", [ 'rm-react', 'react-dom' ], '16.13.1', true );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Add JSON data.
 | 
						|
	 */
 | 
						|
	public function add_json_data() {
 | 
						|
 | 
						|
		if ( Helper::has_cap( 'onpage_snippet' ) ) {
 | 
						|
 | 
						|
			// Schema.
 | 
						|
			$schemas = $this->get_schema_data( get_the_ID() );
 | 
						|
			Helper::add_json( 'schemas', $schemas );
 | 
						|
			Helper::add_json( 'customSchemaImage', esc_url( rank_math()->plugin_url() . 'includes/modules/schema/assets/img/custom-schema-builder.jpg' ) );
 | 
						|
 | 
						|
			// Trends.
 | 
						|
			$trends_upgrade_link = KB::get( 'pro', 'Divi General Tab Trends' );
 | 
						|
			Helper::add_json( 'trendsUpgradeLink', esc_url_raw( $trends_upgrade_link ) );
 | 
						|
			Helper::add_json( 'trendsPreviewImage', esc_url( rank_math()->plugin_url() . 'assets/admin/img/trends-preview.jpg' ) );
 | 
						|
		}
 | 
						|
 | 
						|
		Helper::add_json(
 | 
						|
			'api',
 | 
						|
			[
 | 
						|
				'root'  => esc_url_raw( get_rest_url() ),
 | 
						|
				'nonce' => ( wp_installing() && ! is_multisite() ) ? '' : wp_create_nonce( 'wp_rest' ),
 | 
						|
			]
 | 
						|
		);
 | 
						|
 | 
						|
		Helper::add_json(
 | 
						|
			'keywordsApi',
 | 
						|
			[
 | 
						|
				'url' => 'https://api.rankmath.com/ltkw/v1/',
 | 
						|
			]
 | 
						|
		);
 | 
						|
 | 
						|
		Helper::add_json( 'links', KB::get_links() );
 | 
						|
 | 
						|
		Helper::add_json(
 | 
						|
			'validationl10n',
 | 
						|
			[
 | 
						|
				'regexErrorDefault'    => __( 'Please use the correct format.', 'rank-math' ),
 | 
						|
				'requiredErrorDefault' => __( 'This field is required.', 'rank-math' ),
 | 
						|
				'emailErrorDefault'    => __( 'Please enter a valid email address.', 'rank-math' ),
 | 
						|
				'urlErrorDefault'      => __( 'Please enter a valid URL.', 'rank-math' ),
 | 
						|
			]
 | 
						|
		);
 | 
						|
 | 
						|
		Helper::add_json( 'capitalizeTitle', Helper::get_settings( 'titles.capitalize_titles' ) );
 | 
						|
		Helper::add_json( 'blogName', get_bloginfo( 'name' ) );
 | 
						|
 | 
						|
		if ( is_admin_bar_showing() && Helper::has_cap( 'admin_bar' ) ) {
 | 
						|
			Helper::add_json( 'objectID', get_the_ID() );
 | 
						|
			Helper::add_json( 'objectType', 'post' );
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Enqueue scripts.
 | 
						|
	 */
 | 
						|
	public function footer_enqueue_scripts() {
 | 
						|
		/**
 | 
						|
		 * Allow other plugins to enqueue/dequeue admin styles or scripts before plugin assets.
 | 
						|
		 */
 | 
						|
		$this->do_action( 'admin/before_editor_scripts' );
 | 
						|
 | 
						|
		$divi_deps = [
 | 
						|
			'jquery',
 | 
						|
			'lodash',
 | 
						|
			'rm-react',
 | 
						|
			'rm-react-dom',
 | 
						|
			'rm-set-window-lodash',
 | 
						|
			'et-dynamic-asset-helpers',
 | 
						|
			'wp-api-fetch',
 | 
						|
			'wp-block-editor',
 | 
						|
			'wp-components',
 | 
						|
			'wp-compose',
 | 
						|
			'wp-core-data',
 | 
						|
			'wp-data',
 | 
						|
			'wp-element',
 | 
						|
			'wp-hooks',
 | 
						|
			'wp-media-utils',
 | 
						|
			'rank-math-analyzer',
 | 
						|
			'rank-math-app',
 | 
						|
		];
 | 
						|
 | 
						|
		if ( is_admin_bar_showing() && Helper::has_cap( 'admin_bar' ) ) {
 | 
						|
			wp_enqueue_style( 'rank-math', rank_math()->assets() . 'css/rank-math.css', null, rank_math()->version );
 | 
						|
			wp_enqueue_script( 'rank-math', rank_math()->assets() . 'js/rank-math.js', [ 'jquery' ], rank_math()->version, true );
 | 
						|
		}
 | 
						|
 | 
						|
		wp_enqueue_style( 'rank-math-common', rank_math()->plugin_url() . 'assets/admin/css/common.css', null, rank_math()->version );
 | 
						|
		wp_enqueue_style( 'wp-components' );
 | 
						|
		wp_enqueue_style( 'rank-math-editor', rank_math()->plugin_url() . 'includes/3rdparty/divi/assets/css/divi.css', [], rank_math()->version );
 | 
						|
 | 
						|
		wp_register_script( 'rank-math-analyzer', rank_math()->plugin_url() . 'assets/admin/js/analyzer.js', null, rank_math()->version, true );
 | 
						|
		wp_enqueue_script( 'rank-math-editor', rank_math()->plugin_url() . 'includes/3rdparty/divi/assets/js/divi.js', $divi_deps, rank_math()->version, true );
 | 
						|
		wp_enqueue_script( 'rank-math-divi-iframe', rank_math()->plugin_url() . 'includes/3rdparty/divi/assets/js/divi-iframe.js', [ 'jquery', 'lodash' ], rank_math()->version, true );
 | 
						|
 | 
						|
		if ( Helper::is_module_active( 'rich-snippet' ) ) {
 | 
						|
			wp_enqueue_style( 'rank-math-schema', rank_math()->plugin_url() . 'includes/modules/schema/assets/css/schema.css', [ 'wp-components' ], rank_math()->version );
 | 
						|
 | 
						|
			wp_enqueue_script( 'rank-math-schema', rank_math()->plugin_url() . 'includes/modules/schema/assets/js/schema-gutenberg.js', [ 'rank-math-editor' ], rank_math()->version, true );
 | 
						|
			wp_set_script_translations( 'rank-math-schema', 'rank-math', rank_math()->plugin_dir() . 'languages/' );
 | 
						|
		}
 | 
						|
 | 
						|
		rank_math()->variables->setup();
 | 
						|
		rank_math()->variables->setup_json();
 | 
						|
 | 
						|
		$this->screen->localize();
 | 
						|
 | 
						|
		$this->print_react_containers();
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Allow other plugins to enqueue/dequeue admin styles or scripts after plugin assets.
 | 
						|
		 */
 | 
						|
		$this->do_action( 'admin/editor_scripts' );
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Add et attributes to script tags.
 | 
						|
	 *
 | 
						|
	 * @param string $tag The <script> tag for the enqueued script.
 | 
						|
	 * @param string $handle The script's registered handle.
 | 
						|
	 * @param string $src The script's source URL.
 | 
						|
	 *
 | 
						|
	 * @return string
 | 
						|
	 */
 | 
						|
	public function add_et_tag( $tag, $handle, $src ) {
 | 
						|
		$script_handles = [
 | 
						|
			'rm-react',
 | 
						|
			'rm-react-dom',
 | 
						|
			'lodash',
 | 
						|
			'moment',
 | 
						|
			'rank-math',
 | 
						|
			'rank-math-analyzer',
 | 
						|
			'rank-math-schema',
 | 
						|
			'rank-math-editor',
 | 
						|
			'rank-math-content-ai',
 | 
						|
			'rank-math-app',
 | 
						|
			// Scripts required by pro version.
 | 
						|
			'wp-plugins',
 | 
						|
			'jquery-ui-autocomplete',
 | 
						|
			'rank-math-pro-editor',
 | 
						|
			'rank-math-schema-pro',
 | 
						|
			'rank-math-pro-schema-filters',
 | 
						|
			'rank-math-pro-news',
 | 
						|
		];
 | 
						|
 | 
						|
		$exclude_handles = [
 | 
						|
			'wp-util',
 | 
						|
			'wp-backbone',
 | 
						|
			'wp-plupload',
 | 
						|
			'wp-mediaelement',
 | 
						|
			'wp-color-picker',
 | 
						|
			'wp-color-picker-alpha',
 | 
						|
			'wp-embed',
 | 
						|
			'wp-hooks',
 | 
						|
		];
 | 
						|
 | 
						|
		if ( in_array( $handle, $exclude_handles, true ) ) {
 | 
						|
			return $tag;
 | 
						|
		}
 | 
						|
 | 
						|
		if ( Str::starts_with( 'wp-', $handle ) || in_array( $handle, $script_handles, true ) ) {
 | 
						|
			// These tags load in parent window only, not in Divi iframe.
 | 
						|
			return '<script type="text/javascript" src="' . $src . '" class="et_fb_ignore_iframe"></script>' . "\n"; // phpcs:ignore
 | 
						|
		}
 | 
						|
 | 
						|
		return $tag;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Print React containers onto the screen.
 | 
						|
	 */
 | 
						|
	public function print_react_containers() {
 | 
						|
		echo '<div id="rank-math-rm-app-root" class="et_fb_ignore_iframe"></div>';
 | 
						|
		echo '<div id="rank-math-rm-settings-bar-root" class="et_fb_ignore_iframe"></div>';
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Can add SEO in Divi Page Builder.
 | 
						|
	 *
 | 
						|
	 * @return bool
 | 
						|
	 */
 | 
						|
	private function can_add_seo_tab() {
 | 
						|
		if (
 | 
						|
			! Helper::is_divi_frontend_editor() ||
 | 
						|
			! defined( 'ET_BUILDER_PRODUCT_VERSION' ) ||
 | 
						|
			! version_compare( '4.9.2', ET_BUILDER_PRODUCT_VERSION, 'le' )
 | 
						|
		) {
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Filter to show/hide SEO Tab in Divi Editor.
 | 
						|
		 */
 | 
						|
		if ( ! $this->do_filter( 'divi/add_seo_tab', true ) ) {
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		$post_type = get_post_type();
 | 
						|
		if ( $post_type && ! Helper::get_settings( 'titles.pt_' . $post_type . '_add_meta_box' ) ) {
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		return Editor::can_add_editor();
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get Schema Data.
 | 
						|
	 *
 | 
						|
	 * @param int $post_id Post ID.
 | 
						|
	 *
 | 
						|
	 * @return array $schemas Schema Data.
 | 
						|
	 */
 | 
						|
	private function get_schema_data( $post_id ) {
 | 
						|
		$schemas = Schema_DB::get_schemas( $post_id );
 | 
						|
		if ( ! empty( $schemas ) || metadata_exists( 'post', $post_id, 'rank_math_rich_snippet' ) ) {
 | 
						|
			return $schemas;
 | 
						|
		}
 | 
						|
 | 
						|
		$post_type    = get_post_type( $post_id );
 | 
						|
		$default_type = ucfirst( Helper::get_default_schema_type( $post_id ) );
 | 
						|
		if ( ! $default_type ) {
 | 
						|
			return [];
 | 
						|
		}
 | 
						|
 | 
						|
		$schemas['new-9999'] = [
 | 
						|
			'@type'    => $default_type,
 | 
						|
			'metadata' => [
 | 
						|
				'title'     => Helper::sanitize_schema_title( $default_type ),
 | 
						|
				'type'      => 'template',
 | 
						|
				'shortcode' => uniqid( 's-' ),
 | 
						|
				'isPrimary' => true,
 | 
						|
			],
 | 
						|
		];
 | 
						|
 | 
						|
		return $schemas;
 | 
						|
	}
 | 
						|
}
 |