*/ class Amp_WP_Public { /** * The ID of this plugin. * * @since 1.0.0 * @access private * @var string $plugin_name The ID of this plugin. */ private $plugin_name; /** * The version of this plugin. * * @since 1.0.0 * @access private * @var string $version The current version of this plugin. */ private $version; /** * Default endpoint for AMP URL of site. * this cna can overridden by filter * * @since 1.0.4 */ const SLUG = 'amp'; /** * Default Endpoint for AMP URL of Site. * This cna Can Be Overridden by Filter * * @var string * * @since 1.0.0 * */ const AMP_WP_STARTPOINT = self::SLUG; /** * pre_get_posts hook priority * * @var int * * @since 1.0.0 */ const AMP_WP_ISOLATE_QUERY_HOOK_PRIORITY = 100; /** * Store amp_wp_head action callbacks * * @see amp_wp_collect_and_remove_head_actions * * @var array * * @since 1.0.0 */ private $head_actions; /** * Store Array of Posts Id to Exlucde Transform Permalinks to Amp * * Array structure: array { * 'post id' => dont care, * ... * } * * @see amp_wp_transform_post_link_to_amp * * @var array * * @since 1.0.0 */ public $excluded_posts_id = array(); /** * Initialize the class and set its properties. * * @param string $plugin_name The name of the plugin. * @param string $version The version of this plugin. * @since 1.0.0 */ public function __construct($plugin_name, $version) { $this->plugin_name = $plugin_name; $this->version = $version; // Setup Initial Configurations for AMP WP add_action('amp_wp_default_configurations', array( $this, 'default_configurations' )); $this->register_autoload(); // Registers the AMP Rewrite Rules add_filter('init', array($this, 'amp_wp_add_rewrite')); add_filter('init', array($this, 'amp_wp_append_index_rewrite_rule')); // Check Plugin Compatibility add_filter('template_redirect', array($this, 'amp_wp_plugins_compatibility')); // Initialize AMP Components add_filter('init', array($this, 'amp_wp_include_components')); // Changes Page Template File With AMP Template File add_action('template_include', array($this, 'amp_wp_include_template_file'), 9999); // Override Template File add_filter('comments_template', array($this, 'amp_wp_override_comments_template'), 9999); // Initialize AMP Theme and It’s Functionality add_action('after_setup_theme', array($this, 'amp_wp_template_functions'), 1); // Replace All Links Inside Contents to AMP Version. // Stops User to Go Outside of AMP Version. add_action('wp', array($this, 'amp_wp_replace_internal_links_with_amp_version')); // Registers All Components Scripts Into the Header Style and Scripts add_action('amp_wp_template_enqueue_scripts', array($this, 'amp_wp_enqueue_components_scripts')); // Let the Components to Do Their Functionality in Head add_action('amp_wp_template_head', array($this, 'amp_wp_trigger_component_head'), 0); // Collect All Output to Can Enqueue Only Needed Scripts and Styles in Pages. add_action('amp_wp_template_head', array($this, 'amp_wp_buffer_head_start'), 1); add_action('amp_wp_template_footer', array($this, 'amp_wp_buffer_head_end'), 999); // Collect and Rollback All Main Query Posts to Disable Thirdparty Codes to Change Main Query! // Action After 1000 Priority Can Work add_action( 'pre_get_posts', array( $this, 'amp_wp_isolate_pre_get_posts_start'), 1); add_action( 'pre_get_posts', array( $this, 'amp_wp_isolate_pre_get_posts_end'), self::AMP_WP_ISOLATE_QUERY_HOOK_PRIORITY); add_action('template_redirect', array($this, 'amp_wp_redirect_endpoint_url')); add_filter('redirect_canonical', array($this, 'amp_wp_fix_prevent_extra_redirect_single_pagination')); add_action('request', array($this, 'amp_wp_fix_search_page_queries')); // Auto Redirect Mobile Users add_action('template_redirect', array($this, 'amp_wp_auto_redirect_to_amp'), 1); // Init AMP WP JSON-LD add_action('template_redirect', 'Amp_WP_Public::amp_wp_init_json_ld', 1); $this->amp_wp_fix_front_page_display_options(); } /** * Setup Initial Configurations for AMP WP * * @since 1.2.1 */ public function default_configurations() { $this->amp_wp_add_rewrite(); set_transient( 'amp-wp-flush-rules', true ); // Initial Post Values Setup $post_value = array(); $post_value['show_thumbnail'] = 1; $post_value['show_comments'] = 1; $post_value['show_related_posts'] = 1; $post_value['show_related_post_count'] = 6; $post_value['show_related_post_algorithm'] = 'cat'; $post_value['social_share_on_post'] = 'show'; $post_value['social_share_on_post_count'] = 'total'; $post_value['social_share_on_post_link_format'] = 'standard'; add_option( 'amp_wp_post_settings', $post_value ); // Initial Page Values Setup $page_value = array(); $page_value['amp_on_home'] = 1; $page_value['slider_on_home'] = 1; $page_value['home_page_layout'] = 'listing-2'; $page_value['amp_on_search'] = 1; $page_value['archive_page_layout'] = 'listing-2'; $page_value['social_share_on_page'] = 'hide'; add_option( 'amp_wp_page_settings', $page_value ); // Initial Advanced Settings Setup $advanced_settings_value = array(); $advanced_settings_value['mobile_auto_redirect'] = 1; add_option( 'amp_wp_advanced_settings', $advanced_settings_value ); } /** * Register an autoloader for Better AMP classes * * @since 1.0.0 */ public function register_autoload() { spl_autoload_register( array( __CLASS__, 'autoload_amp_classes' ) ); } /** * Autoload handler for better AMP classes only * * @param string $class_name class to include * * @since 1.0.0 */ public static function autoload_amp_classes( $class_name ) { if ( substr( $class_name, 0, 7 ) !== 'Amp_WP_' ) { return; } $is_interface = substr( $class_name, - 10 ) === '_Interface'; $class_name_prefix = $is_interface ? 'interface-' : 'class-'; $sanitized_class_name = strtolower( $class_name ); $sanitized_class_name = str_replace( '_', '-', $sanitized_class_name ); // Remove interface suffix if( $is_interface ) { $sanitized_class_name = substr( $sanitized_class_name, 0, - 10 ); } $class_file = AMPWP_TEMPLATE_DIR_PATH . 'includes/' . $class_name_prefix . $sanitized_class_name . '.php'; if ( file_exists( $class_file ) ) { require_once $class_file; } } /** * Callback: Add rewrite rules * Action: init * * @version 1.0.0 * @since 1.0.0 */ public function amp_wp_add_rewrite() { amp_wp_add_rewrite_startpoint( self::AMP_WP_STARTPOINT, EP_ALL ); /** * "Automattic AMP" Plugin Compatibility */ $amp_qv = defined('AMP_WP_QUERY_VAR') ? AMP_WP_QUERY_VAR : 'amp'; add_rewrite_endpoint($amp_qv, EP_PERMALINK); } /** * Add a Rewrite Rule to Detect site.com/amp/ Requests * * @version 1.0.0 * @since 1.0.0 * * @return array */ public function amp_wp_append_index_rewrite_rule() { add_rewrite_rule(self::AMP_WP_STARTPOINT . '/?$', "index.php?amp=index", 'top'); } /** * Change most popular cache plugins in amp version to compatible with it * * @since 1.0.0 */ public function amp_wp_plugins_compatibility() { if (!is_amp_wp()) { return; } /** * W3 total cache */ add_filter('w3tc_minify_js_enable', '__return_false'); add_filter('w3tc_minify_css_enable', '__return_false'); /** * WP Rocket */ if( defined( 'WP_ROCKET_VERSION' ) ) { if( !defined( 'DONOTMINIFYCSS' ) ) { define( 'DONOTMINIFYCSS', true ); } if( !defined( 'DONOTMINIFYJS' ) ) { define( 'DONOTMINIFYJS', true ); } // Disable WP Rocket lazy load add_filter('do_rocket_lazyload', '__return_false', PHP_INT_MAX); add_filter('do_rocket_lazyload_iframes', '__return_false', PHP_INT_MAX); // Disable HTTP protocol removing on script, link, img, srcset and form tags. remove_filter('rocket_buffer', '__rocket_protocol_rewrite', PHP_INT_MAX); remove_filter('wp_calculate_image_srcset', '__rocket_protocol_rewrite_srcset', PHP_INT_MAX); // Disable Concatenate Google Fonts add_filter('get_rocket_option_minify_google_fonts', '__return_false', PHP_INT_MAX); // Disable CSS & JS magnification add_filter('get_rocket_option_minify_js', '__return_false', PHP_INT_MAX); add_filter('get_rocket_option_minify_css', '__return_false', PHP_INT_MAX); } /** * WP Speed of Light * * https://wordpress.org/plugins-wp/wp-speed-of-light/ */ if (defined('WPSOL_VERSION')) { add_filter('wpsol_filter_js_noptimize', '__return_true', PHP_INT_MAX); add_filter('wpsol_filter_css_noptimize', '__return_true', PHP_INT_MAX); } /** * Lazy Load * https://wordpress.org/plugins/lazy-load/ */ if (class_exists('LazyLoad_Images')) { add_filter('lazyload_is_enabled', '__return_false', PHP_INT_MAX); } /** * Lazy Load XT * https://wordpress.org/plugins/lazy-load-xt/ */ if (class_exists('Image_Lazy_Load')) { global $lazyloadxt; if (is_object($lazyloadxt)) { remove_filter('the_content', array($lazyloadxt, 'filter_html')); remove_filter('widget_text', array($lazyloadxt, 'filter_html')); remove_filter('post_thumbnail_html', array($lazyloadxt, 'filter_html')); remove_filter('get_avatar', array($lazyloadxt, 'filter_html')); } } /* * * * Facebook Comments Plugin * https://wordpress.org/plugins/facebook-comments-plugin/ */ if (function_exists('fbcommentshortcode')) { remove_action('wp_footer', 'fbmlsetup', 100); remove_filter('the_content', 'fbcommentbox', 100); remove_filter('widget_text', 'do_shortcode'); } /* * * * Yoast SEO * https://wordpress.org/plugins/wordpress-seo/ */ if (defined('WPSEO_VERSION')) { if (class_exists('WPSEO_OpenGraph')) { add_action('amp_wp_template_head', array($this, 'amp_wp_yoast_seo_metatags_compatibility')); } if (is_home() && !amp_wp_is_static_home_page() && self::amp_wp_get_option('show_on_front') === 'page') { add_filter('pre_get_document_title', 'Amp_WP_Public::amp_wp_yoast_seo_homepage_title', 99); } if (is_home()) { add_filter('amp_wp_json_ld_website', 'Amp_WP_Public::amp_wp_yoast_seo_homepage_json_ld'); } } /* * * * Ultimate Tweaker * https://ultimate-tweaker.com/ */ if (class_exists('ultimate_tweaker_Plugin_File') && defined('UT_VERSION')) { amp_wp_remove_class_filter('post_thumbnail_html', 'OT_media_image_no_width_height_Tweak', '_do', 10); amp_wp_remove_class_filter('image_send_to_editor', 'OT_media_image_no_width_height_Tweak', '_do', 10); } /** * WPO Tweaks * * https://servicios.ayudawp.com/ */ if (function_exists('wpo_tweaks_init')) { remove_filter('script_loader_tag', 'wpo_defer_parsing_of_js'); } } /** * Include Active Template functions.php File If Exits * * Callback: include * action: after_setup_theme * * @since 1.0.0 */ public function amp_wp_template_functions() { if (file_exists(AMPWP_TEMPLATE_DIR_PATH . 'includes/functions/amp-wp-template-functions.php')) { require_once AMPWP_TEMPLATE_DIR_PATH . 'includes/functions/amp-wp-template-functions.php'; } } /** * Callback: Include registered AMP components * Action: init * * @since 1.0.0 */ public function amp_wp_include_components() { include AMPWP_TEMPLATE_DIR_PATH . 'includes/components/class-amp-wp-img-component.php'; include AMPWP_TEMPLATE_DIR_PATH . 'includes/components/class-amp-wp-iframe-component.php'; include AMPWP_TEMPLATE_DIR_PATH . 'includes/components/class-amp-wp-carousel-component.php'; } /** * Callback: Include AMP template file in AMP pages * Action: template_include * * @param string $template_file_path Original Template File Path * * @access public * @version 1.0.0 * @since 1.0.0 * * @return string */ public function amp_wp_include_template_file($template_file_path) { if( !is_amp_wp() ) { return $template_file_path; } $include = $this->amp_wp_template_loader(); if ($include) { return $include; } } /** * Load a Template * * Handles Template Usage so That We Can Use Our Own Templates Instead of the Themes * * Templates are in the 'templates' folder. amp-wp looks for theme. * overrides in /yourtheme/amp-wp/ by default. * * @see Template Hierarchy Reference https://developer.wordpress.org/files/2014/10/wp-hierarchy.png * @param mixed $template * @return string */ public function amp_wp_template_loader() { if (amp_wp_is_static_home_page()) { $template = amp_wp_static_home_page_template(); $this->amp_wp_set_page_query(apply_filters('amp_wp_template_page_on_front', 0)); } elseif (is_home()) { $template = amp_wp_home_template(); } elseif (is_post_type_archive()) { $template = amp_wp_archive_post_type_template(); } elseif (is_archive()) { $template = amp_wp_archive_template(); } elseif (is_attachment()) { $template = amp_wp_attachment_template(); remove_filter('the_content', 'prepend_attachment'); } elseif (is_single()) { $template = amp_wp_single_template(); } elseif (is_page()) { $template = amp_wp_page_template(); } elseif (is_404()) { $template = amp_wp_404_template(); } elseif (is_search()) { $template = amp_wp_search_template(); } elseif (is_embed()) { return $template; } else { $template = amp_wp_index_template(); } return $template; } /** * Replace amp comment file with theme file * * @param string $file * * @since 1.0.0 * @return string */ public function amp_wp_override_comments_template($file) { if (is_amp_wp()) { if ($path = amp_wp_locate_template(basename($file))) { return $path; } } return $file; } /** * Replaces All Website Internal Links With AMP Version * * @hooked wp * * @param WP $wp * * @since 1.0.0 * @return string */ public function amp_wp_replace_internal_links_with_amp_version($wp) { if (empty($wp->query_vars['amp'])) { return; } add_filter('nav_menu_link_attributes', array('Amp_WP_Content_Sanitizer', 'replace_href_with_amp')); add_filter('the_content', array('Amp_WP_Content_Sanitizer', 'transform_all_links_to_amp')); add_filter('author_link', array('Amp_WP_Content_Sanitizer', 'transform_to_amp_url')); add_filter('term_link', array('Amp_WP_Content_Sanitizer', 'transform_to_amp_url')); add_filter('post_link', array($this, 'amp_wp_transform_post_link_to_amp'), 20, 2); add_filter('page_link', array($this, 'amp_wp_transform_post_link_to_amp'), 20, 2); add_filter('attachment_link', array('Amp_WP_Content_Sanitizer', 'transform_to_amp_url')); add_filter('post_type_link', array('Amp_WP_Content_Sanitizer', 'transform_to_amp_url')); } /** * Transform allowed posts URL to AMP * * @param string $url The Post’s Permalink * @param WP_Post|int $post The post object/id of the post. * * @since 1.0.0 * @return string */ public function amp_wp_transform_post_link_to_amp($url, $post) { $post_id = isset($post->ID) ? $post->ID : $post; if (isset($this->excluded_posts_id[$post_id])) { return $url; } return Amp_WP_Content_Sanitizer::transform_to_amp_url($url); } /** * Append AMP Components JavaScript If AMP Version Requested * * @access public * @version 1.0.0 * @since 1.0.0 */ public function amp_wp_enqueue_components_scripts() { $deps = array('ampproject'); amp_wp_enqueue_script($deps[0], 'https://cdn.ampproject.org/v0.js'); // Enqueues all needed scripts of components with 'ampproject' dependency $this->amp_wp_call_components_method('enqueue_amp_scripts', $deps); if (current_theme_supports('amp-wp-navigation') && current_theme_supports('amp-wp-has-nav-child')) { amp_wp_enqueue_script('amp-accordion', 'https://cdn.ampproject.org/v0/amp-accordion-0.1.js'); } if (current_theme_supports('amp-wp-form')) { amp_wp_enqueue_script('amp-form', 'https://cdn.ampproject.org/v0/amp-form-0.1.js'); } } /** * Callback: Fire head method of component for following purpose: * 1) Component able to add_filter or add_action if needed * 2) Create fresh instance of each component and cache * * Action: amp_wp_template_head * * @version 1.0.0 * @since 1.0.0 */ public function amp_wp_trigger_component_head() { $this->amp_wp_call_components_method('head'); } /** * Callback: Starts the Collecting Output to Enable Components to Add Style Into Head * Print Theme Completely Then Fire amp_wp_head() Callbacks and Append It Before * * Action: amp_wp_template_head * * @see amp_wp_buffer_head_end * * @version 1.0.0 * @since 1.0.0 */ public function amp_wp_buffer_head_start() { remove_action(current_action(), array($this, __FUNCTION__), 1); $this->amp_wp_collect_and_remove_head_actions(); ob_start(); } /** * Collect amp_wp_head actions and remove those actions * * @see amp_wp_head * * @since 1.0.0 */ public function amp_wp_collect_and_remove_head_actions() { $actions = &$GLOBALS['wp_filter']['amp_wp_template_head']; $this->head_actions = $actions; $actions = array(); } /** * Callback: Fire amp_wp_head() and print buffered output * Action: amp_wp_template_head * * @see amp_wp_buffer_head_start * * @version 1.0.0 * @since 1.0.0 */ public function amp_wp_buffer_head_end() { $content = ob_get_clean(); $prepend = ''; if (!amp_wp_is_customize_preview()) { $prepend .= ''; /** * Convert Output to Valid AMP HTML */ $instance = new Amp_WP_Html_Util(); $instance->loadHTML('' . $content . '', null, false); preg_match('#(<\s*body[^>]*>)#isx', $content, $match); $prepend .= isset($match[1]) ? $match[1] : ''; // open body tag $this->amp_wp_render_content($instance, true); // Convert HTML top amp html // @see Amp_WP_Component::enqueue_amp_tags_script $this->amp_wp_call_components_method('enqueue_amp_tags_script', $instance); $content = $instance->get_content(true); // End convert output to valid amp html } $GLOBALS['wp_filter']['amp_wp_template_head'] = $this->head_actions; $this->head_actions = array(); do_action('amp_wp_template_head'); echo $prepend, $content; } /** * Transforms HTML Content to AMP Content * * todo: Add File Caching * * @param Amp_WP_Html_Util $instance * @param boolean $sanitize * * @since 1.0.0 */ public function amp_wp_render_content(Amp_WP_Html_Util $instance, $sanitize = false) { $this->amp_wp_call_components_method('render', $instance); if ($sanitize) { $sanitizer = new Amp_WP_Content_Sanitizer($instance); $sanitizer->sanitize(); } } /** * Fire specific method of all components * * @param string $method_name component method * * @param mixed $param * * @return mixed * @since 1.0.0 * */ public function amp_wp_call_components_method($method_name, $param = null) { global $amp_wp_registered_components; if (!$amp_wp_registered_components) { return $param; } // collect and prepare method arguments $args = func_get_args(); $args = array_slice($args, 1); if (!isset($args[0])) { $args[0] = null; } // iterate registered components and call method on them foreach ($amp_wp_registered_components as $component) { $instance = Amp_WP_Component::instance($component['component_class']); if ($this->_amp_wp_can_call_component_method($instance, $method_name, $args)) { $args[0] = call_user_func_array(array($instance, $method_name), $args); } } return $args[0]; } /** * Determines that method exists and is callable on object instance * * @param Amp_WP_Component $instance Live object of Amp_WP_Component * @param string $method_name Method of object * @param array $args * * @access private * @since 1.0.0 * * @return bool */ private function _amp_wp_can_call_component_method(&$instance, &$method_name, &$args) { $return = is_callable(array($instance, $method_name)); switch ($method_name) { case 'enqueue_amp_scripts': $return = $return && $instance->can_enqueue_scripts(); break; } return $return; } /** * Callback: Prevent Third Party Codes to Change the Main Query on AMP Version * * You Can Add Action To 'pre_get_posts' With Priority Greater Than 1000 to Change It. * * Action: pre_get_posts * * @see amp_wp_isolate_pre_get_posts_end * * @param WP_Query $wp_query * * @access public * @version 1.0.0 * @since 1.0.0 */ public function amp_wp_isolate_pre_get_posts_start($wp_query) { global $amp_wp_isolate_pre_get_posts; if (is_amp_wp($wp_query) && !is_admin() && $wp_query->is_main_query()) { $amp_wp_isolate_pre_get_posts = $wp_query->query_vars; } } /** * Rollback the Main Query Vars. * * @see 'amp_wp_isolate_pre_get_posts_end' for more documentation * * Action: pre_get_posts * @version 1.0.0 * @since 1.0.0 * * @param WP_Query $wp_query */ public function amp_wp_isolate_pre_get_posts_end(&$wp_query) { global $amp_wp_isolate_pre_get_posts; if (is_amp_wp($wp_query) && !is_admin() && $wp_query->is_main_query()) { if ($amp_wp_isolate_pre_get_posts) { $wp_query->query_vars = $amp_wp_isolate_pre_get_posts; unset($amp_wp_isolate_pre_get_posts); } } } /** * Handy fix for changing search query * * @param mixed $q * * @access public * @version 1.0.0 * @since 1.0.0 * * @return mixed */ public function amp_wp_fix_search_page_queries($q) { if (!empty($q['amp']) && !empty($q['s'])) { $q['post_type'] = array('post'); } return $q; } /** * "Automattic AMP" Plugin Compatibility * * Redirect AMP URLs With AMP Endpoint to New AMP URL * * @access public * @version 1.0.0 * @since 1.0.0 */ public function amp_wp_redirect_endpoint_url() { if( !amp_wp_get_permalink_structure() ) { return; } if( amp_wp_url_format() === 'start-point' ) { $this->redirect_to_start_point_amp(); } else { $this->redirect_to_end_point_amp(); } } /** * Redirect end-point AMP URLs to start-point * * @since 1.0.4 */ public function redirect_to_start_point_amp() { $amp_qv = defined('AMP_WP_QUERY_VAR') ? AMP_WP_QUERY_VAR : 'amp'; if (get_query_var($amp_qv, false) === false) { if (!is_404()) { # /amp at the end of some urls cause 404 error return; } } $path = amp_wp_get_wp_installation_slug(); $request_url = str_replace($path, '', $_SERVER['REQUEST_URI']); $url_prefix = preg_quote( amp_wp_permalink_prefix(), '#' ); preg_match("#^/*$url_prefix(.*?)/$amp_qv/*$#", $request_url, $automattic_amp_match); if( !$this->amp_version_exists() ) { if( !empty( $automattic_amp_match[1] ) ) { $redirect_url = home_url( $automattic_amp_match[1] ); } elseif (preg_match("#^/*$amp_qv/+(.*?)/*$#", $request_url, $matched)) { $redirect_url = home_url($matched[1]); } else { $redirect_url = amp_wp_get_canonical_url(); } if( $redirect_url ) { wp_redirect($redirect_url); exit; } } if( !empty( $automattic_amp_match[1] ) ) { $new_amp_url = Amp_WP_Content_Sanitizer::transform_to_amp_url( site_url( $automattic_amp_match[1] ) ); $new_amp_url = trailingslashit( $new_amp_url ); if( $new_amp_url && trim( str_replace( site_url(), '', $new_amp_url), '/' ) !== trim($request_url, '/' ) ) { wp_redirect( $new_amp_url, 301 ); exit; } } } /** * Redirect end-point AMP URLs to end-point * * @since 1.0.4 */ public function redirect_to_end_point_amp() { $request_url = str_replace( amp_wp_get_wp_installation_slug(), '', $_SERVER['REQUEST_URI'] ); if( !preg_match( '#^/?([^/]+)(.+)#', $request_url, $match ) ) { return; } if( $match[1] !== Amp_WP_Public::SLUG ) { return; } $new_amp_url = trailingslashit( Amp_WP_Content_Sanitizer::transform_to_amp_url( home_url( $match[2] ) ) ); if ( $new_amp_url && trim( $match[2], '/' ) !== '' ) { wp_redirect( $new_amp_url, 301 ); exit; } } /** * Prevent Redirect Pages Within Single Post * * @param bool $redirect * * @access public * @since 1.0.0 * * @return bool */ public function amp_wp_fix_prevent_extra_redirect_single_pagination($redirect) { if ($redirect && is_amp_wp() && get_query_var('page') > 1) { return false; } return $redirect; } /** * Get Requested Page URL * * @access public * @version 1.0.0 * @since 1.0.0 * * @return string */ public static function amp_wp_get_requested_page_url() { if (isset($_SERVER['HTTP_HOST'])) { $requested_url = is_ssl() ? 'https://' : 'http://'; $requested_url .= $_SERVER['HTTP_HOST']; $requested_url .= $_SERVER['REQUEST_URI']; return $requested_url; } return ''; } /** * Redirect Users to AMP Version of the Page Automatically * * @access public * @version 1.0.0 * @since 1.0.0 */ public function amp_wp_auto_redirect_to_amp() { if (is_amp_wp()) { return; } if (!apply_filters('amp_wp_template_auto_redirect', false)) { return; } if (!empty($_GET['amp-wp-skip-redirect']) || !empty($_COOKIE['amp-wp-skip-redirect'])) { if (!isset($_COOKIE['amp-wp-skip-redirect'])) { setcookie('amp-wp-skip-redirect', true, time() + DAY_IN_SECONDS, '/'); } return; } else { if (isset($_COOKIE['amp-wp-skip-redirect'])) { unset($_COOKIE['amp-wp-skip-redirect']); } } // if post have not AMP version if (!$this->amp_version_exists()) { return; } if (wp_is_mobile()) { $requested_url = self::amp_wp_get_requested_page_url(); $amp_permalink = Amp_WP_Content_Sanitizer::transform_to_amp_url($requested_url); if ($requested_url && $amp_permalink && $amp_permalink !== $requested_url) { wp_redirect($amp_permalink); exit; } } elseif (Amp_WP_Public::amp_wp_have_cache_plugin()) { // Adds advanced javascript code to page to redirect page in front end! // Last and safest way to redirect but it will have a little delay! add_action('wp_print_scripts', array($this, 'amp_wp_print_mobile_redirect_script')); } } /** * Is Any Caching Plugin Install on This WordPress Installation * * @access public * @version 1.0.0 * @since 1.0.0 * * @return bool */ public function amp_wp_have_cache_plugin() { if (defined('WP_CACHE') && WP_CACHE) { return true; } // Fix for "WP Fastest Cache" plugin if( $plugins = array_flip( wp_get_active_and_valid_plugins() ) ) { return isset( $plugins[WP_PLUGIN_DIR . '/wp-fastest-cache/wpFastestCache.php'] ); } return false; } /** * Print Script to Redirect Mobile Devices to AMP Version * * @access public * @version 1.0.0 * @since 1.0.0 * @since 1.0.4 Fix: Mobile users force redirect. */ public function amp_wp_print_mobile_redirect_script() { $requested_url = self::amp_wp_get_requested_page_url(); $amp_permalink = Amp_WP_Content_Sanitizer::transform_to_amp_url($requested_url); if (!$requested_url || !$amp_permalink || $amp_permalink === $requested_url) { return; } $script = file_get_contents( amp_wp_min_suffix( AMPWP_PATH . 'public/js/mobile_redirect', '.js' ) ); $script = str_replace( '%%amp_permalink%%', $amp_permalink, $script ); ?> array(), 'disabled_taxonomies' => array(), 'disabled_homepage' => false, 'disabled_search' => false, ) ); } if (is_singular()) { $post_id = get_queried_object_id(); } elseif (is_home() && amp_wp_is_static_home_page()) { $post_id = intval(apply_filters('amp_wp_template_page_on_front', 0)); } else { $post_id = 0; } if ($post_id) { //if( get_post_meta( $post_id, 'disable-amp-wp', true ) || isset( $this->excluded_posts_id[$post_id] ) ) { if (get_post_meta($post_id, 'disable-amp-wp', true)) { return false; } } if( empty( $filters ) ) { return true; } if ( is_home() || is_front_page() ) { return !$filters['disabled_homepage']; } if (is_search()) { return !$filters['disabled_search']; } if (is_singular()) { return !in_array(get_queried_object()->post_type, $filters['disabled_post_types']); } if (is_post_type_archive()) { $queried_object = get_queried_object(); if ($queried_object instanceof WP_Post_Type) { # WP >= 4.6.0 $post_type = $queried_object->name; } elseif ($queried_object instanceof WP_Post) { # WP < 4.6.0 $post_type = $queried_object->post_type; } else { return false; } return !in_array($post_type, $filters['disabled_post_types']); } if (is_tax() || is_category() || is_tag()) { return !in_array(get_queried_object()->taxonomy, $filters['disabled_taxonomies']); } return true; } /** * Prints meta tags with using Yoast SEO Open Graph feature. */ public function amp_wp_yoast_seo_metatags_compatibility() { // Remove canonical from in Yoast to generate correct canonical amp_wp_remove_class_action('wpseo_head', 'WPSEO_Frontend', 'canonical', 20); do_action('wpseo_opengraph'); } /** * Sync non-amp Homepage Title With AMP Version * * @param string $title * * @access public * @version 1.0.0 * @since 1.0.0 * * @return string */ public static function amp_wp_yoast_seo_homepage_title($title) { if (( $post_id = self::amp_wp_get_option('page_on_front') ) && is_callable('WPSEO_Frontend::get_instance')) { $post = get_post($post_id); if ($post instanceof WP_Post) { $wp_seo = WPSEO_Frontend::get_instance(); if ($new_title = $wp_seo->get_content_title($post)) { return $new_title; } } } return $title; } /** * Sync json-ld Data With Yoast SEO Plugin * * @param array $data * * @since 1.0.0 * @return array */ public static function amp_wp_yoast_seo_homepage_json_ld($data) { if (is_callable('WPSEO_Options::get_options')) { $options = WPSEO_Options::get_options(array('wpseo', 'wpseo_social')); if (!empty($options['website_name'])) { $data['name'] = $options['website_name']; } if (!empty($options['alternate_website_name'])) { $data['alternateName'] = $options['alternate_website_name']; unset($data['description']); } } return $data; } /** * Get WordPress option * * @param string $option * @param mixed $default * * @since 1.0.0 * @return mixed */ public static function amp_wp_get_option($option, $default = false) { $tmp = isset($GLOBALS['_amp_bypass_option']) ? $GLOBALS['_amp_bypass_option'] : false; $GLOBALS['_amp_bypass_option'] = true; $results = get_option($option, $default); $GLOBALS['_amp_bypass_option'] = $tmp; return $results; } }