Advertisement
htdat

wpseo-sitemaps-filter.php_fix sitemap WordPress SEO and WPML

Mar 30th, 2015
897
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 13.80 KB | None | 0 0
  1. <?php
  2. /** fix sitemap WordPress SEO and WPML 3.1.9.3. Sample problem: https://wpml.org/forums/topic/404-error-on-subdomains-sitemap-using-yoast/#post-584821
  3.  * WP SEO by Yoast sitemap filter class
  4.  *
  5.  * @version 1.0.2
  6.  */
  7. class WPSEO_XML_Sitemaps_Filter {
  8.  
  9.     protected $wp_home_url, $active_languages, $current_domain, $home_pages;
  10.  
  11.     public function __construct() {
  12.  
  13.         // Set home URL before filtered
  14.         $this->wp_home_url = get_home_url();
  15.  
  16.         // Debug - disable sitemap caching
  17.         if ( defined( 'WPML_WPSEO_DEBUG' ) && WPML_WPSEO_DEBUG ) {
  18.             add_filter( 'wpseo_enable_xml_sitemap_transient_caching',
  19.                         array($this, 'enable_caching_filter') );
  20.         }
  21.         // Sure hook
  22.         add_filter( 'wpseo_build_sitemap_post_type',
  23.                     array($this, 'build_sitemap_post_type_filter') );
  24.         // Early actions for per_domain
  25.         if ( $this->is_per_domain() ) {
  26.             // List domains on WP SEO 'Sitemap' screen
  27.             add_action( 'wpseo_xmlsitemaps_config', array($this, 'list_domains') );
  28.             // Fix for top 'Sitemap Index' link
  29.             if ( $this->is_xsl_request() || $this->is_sitemap_request() ) {
  30.                 // Set current domain
  31.                 $this->set_current_domain();
  32.                 add_filter( 'home_url', array($this, 'home_url_filter'), 1, 4 );
  33.             }
  34.         }
  35.     }
  36.  
  37.     public function build_sitemap_post_type_filter( $sitemap_type ) {
  38.  
  39.         global $sitepress;
  40.  
  41.         // Set active languages
  42.         $this->active_languages = $sitepress->get_active_languages();
  43.  
  44.         if ( $this->is_per_domain() ) {
  45.             // Fix home URL
  46.             add_filter( 'home_url', array( $this, 'home_url_filter' ), 1, 4 );
  47.             // Fix stylesheet URL if per_domain (considered as cross site URL)
  48.             add_filter( 'wpseo_stylesheet_url', array($this, 'stylesheet_url_filter') );
  49.             // Set current domain
  50.             $this->set_current_domain();
  51.         }
  52.  
  53.         // Same as WP SEO check
  54.         if ( $sitemap_type == 1 ) {
  55.             if ( $this->is_per_domain() ) {
  56.                 // Apply post filters
  57.                 $this->apply_post_filters();
  58.             }
  59.             // Index sitemap
  60.             add_filter( 'post_type_archive_link',
  61.                         array($this, 'post_type_archive_link_filter'), 10, 2 );
  62.             // Exclude post type filter
  63.             add_filter( 'wpseo_sitemap_exclude_post_type',
  64.                         array($this, 'exclude_post_type_filter'), 10, 2 );
  65.             // Exclude taxonomy filter
  66.             add_filter( 'wpseo_sitemap_exclude_taxonomy',
  67.                         array($this, 'exclude_taxonomy_filter'), 10, 2 );
  68.         } else if ( post_type_exists( $sitemap_type ) ) {
  69.             // Post type sitemap
  70.             add_filter( 'post_type_archive_link',
  71.                         array($this, 'post_type_archive_link_filter'), 10, 2 );
  72.             if ( $this->is_per_domain() ) {
  73.                 // Apply post filters
  74.                 $this->apply_post_filters();
  75.             }
  76.             if ( $sitemap_type == 'page' ) {
  77.                 if ( !$this->is_per_domain() ) {
  78.                     // Collect home pages ID
  79.                     $this->home_pages = array();
  80.                     foreach ( $this->active_languages as $l ) {
  81.                         if ( $l['code'] == $sitepress->get_default_language() ) {
  82.                             continue;
  83.                         }
  84.                         $this->home_pages[$l['code']] = icl_object_id(
  85.                             get_option( 'page_on_front' ), 'page', false, $l['code'] );
  86.                     }
  87.                     add_filter( 'wpseo_sitemap_entry',
  88.                                 array($this, 'page_entry_filter'), 10, 3 );
  89.                 }
  90.                 if ( $this->wpml_root_page() ) {
  91.                     add_filter( 'wpseo_posts_where',
  92.                                 array($this, 'wpml_root_page_posts_where_filter'), 10, 2 );
  93.                 }
  94.             }
  95.         } elseif ( $tax = get_taxonomy( $sitemap_type ) ) {
  96.             // Taxonomy sitemap
  97.         } elseif ( $sitemap_type == 'author' ) {
  98.             // Author sitemap
  99.         }
  100.  
  101.         return $sitemap_type;
  102.     }
  103.  
  104.     public function list_domains() {
  105.         global $sitepress;
  106.         echo '<h2>WPML</h2>';
  107.         echo __('Sitemaps for each languages can be accessed here:', 'sitepress') . '<ul>';
  108.         foreach ($sitepress->get_ls_languages() as $lang) {
  109.             $url = $lang['url'] . 'sitemap_index.xml';
  110.             echo '<li>' . $lang['translated_name'] . ' <a href="' . $url
  111.                  . '" target="_blank">' . $url . '</a></li>';
  112.         }
  113.         echo '</ul>';
  114.     }
  115.  
  116.     /**
  117.      * WP SEO early collects un-filtered home_url(), causing linking to default language.
  118.      */
  119.     public function home_url_filter( $url ) {
  120.         if ( !empty( $this->current_domain ) && strpos( $url, $this->wp_home_url ) === 0 ) {
  121.             $url = substr_replace( $url, $this->current_domain, 0, strlen( $this->wp_home_url ) );
  122.         }
  123.         return $url;
  124.     }
  125.  
  126.     public function enable_caching_filter(){
  127.         return false;
  128.     }
  129.  
  130.     /**
  131.      * Filters post type archive link if slugs translated.
  132.      */
  133.     public function post_type_archive_link_filter( $link, $post_type ) {
  134.         global $sitepress, $wp_rewrite;
  135.         $settings = icl_get_setting( 'posts_slug_translation', array() );
  136.         $translate = !empty( $settings['types'][$post_type] );
  137.         if ( $translate && class_exists( 'WPML_Slug_Translation') ) {
  138.             $post_type_obj = get_post_type_object($post_type);
  139.             $translated_slug = WPML_Slug_Translation::get_translated_slug( $post_type,
  140.                                                                            $sitepress->get_current_language() );
  141.             if ( get_option( 'permalink_structure' )
  142.                  && is_array( $post_type_obj->rewrite ) ) {
  143.                 $struct = ( true === $post_type_obj->has_archive ) ? $translated_slug : $post_type_obj->has_archive;
  144.                 if ( $post_type_obj->rewrite['with_front'] ) {
  145.                     $struct = $wp_rewrite->front . $struct;
  146.                 } else {
  147.                     $struct = $wp_rewrite->root . $struct;
  148.                 }
  149.                 $link = home_url( user_trailingslashit( $struct,
  150.                                                         'post_type_archive' ) );
  151.             } else {
  152.                 $link = home_url( '?post_type=' . $translated_slug );
  153.             }
  154.         }
  155.         return $link;
  156.     }
  157.  
  158.     public function typecount_join_filter($join, $post_type){
  159.         global $wpdb, $sitepress;
  160.  
  161.         if($sitepress->is_translated_post_type($post_type)){
  162.             $join .= " INNER JOIN {$wpdb->prefix}icl_translations
  163.                       ON $wpdb->posts.ID = {$wpdb->prefix}icl_translations.element_id";
  164.         }
  165.  
  166.         return $join;
  167.     }
  168.  
  169.     public function typecount_where_filter($where, $post_type){
  170.         global $wpdb, $sitepress;
  171.  
  172.         if($sitepress->is_translated_post_type($post_type)){
  173.             $sitemap_language = $this->is_per_domain() ? $sitepress->get_current_language() : $sitepress->get_default_language();
  174.             $where .= $wpdb->prepare(" AND {$wpdb->prefix}icl_translations.language_code = %s
  175.                        AND {$wpdb->prefix}icl_translations.element_type = %s", $sitemap_language, "post_{$post_type}");
  176.         }
  177.  
  178.         return $where;
  179.     }
  180.  
  181.     public function posts_join_filter($join, $post_type){
  182.         global $wpdb, $sitepress;
  183.  
  184.         if ( $sitepress->is_translated_post_type( $post_type ) ) {
  185.             $join .= " INNER JOIN {$wpdb->prefix}icl_translations
  186.                        ON $wpdb->posts.ID = {$wpdb->prefix}icl_translations.element_id";
  187.         }
  188.  
  189.         return $join;
  190.     }
  191.  
  192.     public function posts_where_filter($where, $post_type){
  193.         global $wpdb, $sitepress;
  194.  
  195.         if ( $sitepress->is_translated_post_type( $post_type ) ) {
  196.             $sitemap_language = $this->is_per_domain() ? $sitepress->get_current_language() : $sitepress->get_default_language();
  197.             $where .= $wpdb->prepare(" AND {$wpdb->prefix}icl_translations.language_code = %s
  198.                        AND {$wpdb->prefix}icl_translations.element_type = %s ", $sitemap_language, "post_{$post_type}");
  199.         }
  200.  
  201.         return $where;
  202.     }
  203.  
  204.     /**
  205.      * Filters home page URLs. If there is page_on_front,
  206.      * adjust URL to e.g. http://site.com/es
  207.      * do not leave actual page name e.g. http://site.com/es/sample-page
  208.      * Handle wpml_root_page if necessary.
  209.      */
  210.     public function page_entry_filter( $url, $post_type, $post ) {
  211.         global $sitepress;
  212.         if ( get_option( 'page_on_front' ) ) {
  213.             // If post ID in home_pages
  214.             if ( $lang = array_search( $post->ID, $this->home_pages ) ) {
  215.                 $url['loc'] = $sitepress->language_url( $lang );
  216.             }
  217.         }
  218.         // If wpml_root_page but wpml_root_path used, show default permalink
  219.         if ( $this->get_wpml_root_page_id() == $post->ID && $this->wpml_root_path() ) {
  220.             remove_filter( 'page_link', array( 'WPML_Root_Page', 'filter_root_permalink' ), 10, 2 );
  221.             $url['loc'] = get_permalink( $post->ID );
  222.         }
  223.  
  224.         return $url;
  225.     }
  226.  
  227.     /**
  228.      * WP SEO should not list un-translatable post types on non-default language domains.
  229.      */
  230.     public function exclude_post_type_filter( $false, $post_type ) {
  231.         global $sitepress;
  232.         return $this->is_per_domain()
  233.                && $sitepress->get_current_language() != $sitepress->get_default_language()
  234.                && !$sitepress->is_translated_post_type($post_type) ? true : $false;
  235.     }
  236.  
  237.     /**
  238.      * WP SEO should not list un-translatable taxonomies on non-default language domains.
  239.      */
  240.     public function exclude_taxonomy_filter( $false, $tax ) {
  241.         global $sitepress;
  242.         return $this->is_per_domain()
  243.                && $sitepress->get_current_language() != $sitepress->get_default_language()
  244.                && !$sitepress->is_translated_taxonomy($tax) ? true : $false;
  245.     }
  246.  
  247.     /**
  248.      * WP SEO uses URL for default domain but it's not allowed to use XSL from other domains.
  249.      */
  250.     public function stylesheet_url_filter( $stylesheet ){
  251.         global $sitepress;
  252.         return '<?xml-stylesheet type="text/xsl" href="'
  253.                . preg_replace( '/(^http[s]?:)/', '', esc_url( $sitepress->language_url( $sitepress->get_current_language() ) ) )
  254.                . '/main-sitemap.xsl"?>';
  255.     }
  256.  
  257.     public function is_per_domain() {
  258.         return icl_get_setting( 'language_negotiation_type', false ) == 2;
  259.     }
  260.  
  261.     public function is_as_param() {
  262.         return icl_get_setting( 'language_negotiation_type', false ) == 3;
  263.     }
  264.  
  265.     public function is_default_language_in_directory() {
  266.         $settings = icl_get_setting( 'urls', array() );
  267.         return icl_get_setting( 'language_negotiation_type', false ) == 1
  268.                && !empty($settings['directory_for_default_language'] );
  269.     }
  270.  
  271.     /**
  272.      * Returns WPML root page ID if set and used.
  273.      */
  274.     public function wpml_root_page() {
  275.         $settings = icl_get_setting( 'urls', array() );
  276.         return $this->is_default_language_in_directory()
  277.                && isset( $settings['show_on_root'] ) && $settings['show_on_root'] == 'page'
  278.                && !empty( $settings['root_page'] ) ? $settings['root_page'] : null;
  279.     }
  280.  
  281.     public function get_wpml_root_page_id() {
  282.         $settings = icl_get_setting( 'urls', array() );
  283.         return !empty( $settings['root_page'] ) ? $settings['root_page'] : null;
  284.     }
  285.  
  286.     /**
  287.      * Returns WPML root path if set and used.
  288.      */
  289.     public function wpml_root_path() {
  290.         $settings = icl_get_setting( 'urls', array() );
  291.         return $this->is_default_language_in_directory()
  292.                && isset( $settings['show_on_root'] )
  293.                && $settings['show_on_root'] == 'html_file'
  294.                && !empty( $settings['root_html_file_path'] ) ? $settings['root_html_file_path'] : null;
  295.     }
  296.  
  297.     public function is_xsl_request() {
  298.         return basename( $_SERVER['REQUEST_URI'] ) == 'main-sitemap.xsl';
  299.     }
  300.  
  301.     /**
  302.      * Checks if sitemap request, use only if absolutely necessary (early hooks).
  303.      * Sitemaps can have numeration e.g. sitemap-attachments1.xml.
  304.      */
  305.     public function is_sitemap_request() {
  306.         return !empty( $_REQUEST['sitemap'] )
  307.                || basename( $_SERVER['REQUEST_URI'] ) == 'sitemap_index.xml'
  308.                || preg_match( "/sitemap(\d+)?.xml$/", $_SERVER['REQUEST_URI'] );
  309.     }
  310.  
  311.     public function wpml_root_page_posts_where_filter( $where, $post_type ) {
  312.         global $wpdb;
  313.  
  314.         $where .= $wpdb->prepare( " AND ID != %d ", WPML_Root_Page::get_root_id() );
  315.  
  316.         return $where;
  317.     }
  318.  
  319.     protected function set_current_domain() {
  320.         if ( is_null( $this->current_domain ) ) {
  321.             global $sitepress;
  322.             $settings = icl_get_setting( 'language_domains', array() );
  323.             $current_lang = $sitepress->get_current_language();
  324.             $this->current_domain = isset( $settings[$current_lang] ) ? $settings[$current_lang] : false;
  325.         }
  326.     }
  327.  
  328.     public function apply_post_filters() {
  329.         add_filter( 'wpseo_typecount_join',
  330.                     array($this, 'typecount_join_filter'), 10, 2 );
  331.         add_filter( 'wpseo_typecount_where',
  332.                     array($this, 'typecount_where_filter'), 10, 2 );
  333.         add_filter( 'wpseo_posts_join',
  334.                     array($this, 'posts_join_filter'), 10, 2 );
  335.         add_filter( 'wpseo_posts_where',
  336.                     array($this, 'posts_where_filter'), 10, 2 );
  337.     }
  338.  
  339. }
  340.  
  341. $wpseo_xml_filter = new WPSEO_XML_Sitemaps_Filter();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement