/wp-content/plugins/sitepress-multilingual-cms/inc/wpseo-sitemaps-filter.php

https://bitbucket.org/acipriani/madeinapulia.com · PHP · 399 lines · 238 code · 50 blank · 111 comment · 52 complexity · b1ccad3e830315781e7822f8143a8753 MD5 · raw file

  1. <?php
  2. /**
  3. * WP SEO by Yoast sitemap filter class
  4. *
  5. * - Languages per domain
  6. * -- Filters home_url
  7. * -- Adds post types and taxonomies in different languages to index sitemap
  8. * --- Filters JOIN, WHERE to limit posts only to sitemap language (if any)
  9. * otherwise will show posts for current language domain
  10. * --- Filters sitemap XSL (removed)
  11. * --- Fixes WP SEO post type if sitemap name contains language info
  12. * --- Fixes modification date for posts
  13. * -- Handles sitemap language (post-en-sitemap.xml {post_type}-{lang}-sitemap.xml)
  14. * (removed because it's not needed with current logic)
  15. *
  16. * - Languages per directory (and GET var)
  17. * -- Filters sitemap entries for home pages (to show language root instead of pagename)
  18. *
  19. *
  20. * Changelog
  21. *
  22. * 1.0.1
  23. * - Added filtering home_url
  24. * - Added summary to WP SEO admin screen
  25. * - Added filtering/fixing home URLs filter_home_pages()
  26. * (negotiation directory and query var)
  27. * - Added filtering/fixing list entries filter_entry()
  28. * - Removed/fixed outdated code in set_stylesheet() and add_to_index()
  29. * - Fixed get_sitemap_language()
  30. * - Removed filtering XSL stylesheet (URL is adjusted)
  31. * - Removed add_to_index (not needed with current logic)
  32. *
  33. * @version 1.0.1
  34. */
  35. class WPSEO_XML_Sitemaps_Filter {
  36. protected $_active_languages, $_is_per_domain, $_default_home_url, $_current_home_url;
  37. public function __construct() {
  38. global $sitepress, $sitepress_settings;
  39. $this->_is_per_domain = isset( $sitepress_settings['language_negotiation_type'] ) && $sitepress_settings['language_negotiation_type'] == 2;
  40. $this->_active_languages = $sitepress->get_active_languages();
  41. // Add summary on WP SEO admin screen
  42. if ( $this->_is_per_domain ){
  43. add_action( 'wpseo_xmlsitemaps_config', array($this, 'summary') );
  44. }
  45. // Triggered when sitemap or XSL is requested
  46. if ( !empty( $_REQUEST['sitemap'] )
  47. || basename( $_SERVER['REQUEST_URI'] ) == 'sitemap_index.xml'
  48. || strpos( basename( $_SERVER['REQUEST_URI'] ), '-sitemap.xml' ) !== false
  49. || basename( $_SERVER['REQUEST_URI'] ) == 'main-sitemap.xsl' ) {
  50. if ( $this->_is_per_domain
  51. && $sitepress->get_default_language() != $sitepress->get_current_language()){
  52. add_action( 'init', array($this, 'init') );
  53. // add_filter( 'wpseo_sitemap_index', array($this, 'add_to_index') );
  54. add_action( 'wpseo_xmlsitemaps_config', array($this, 'summary') );
  55. $this->_default_home_url = home_url();
  56. $this->_current_home_url = $sitepress_settings['language_domains'][$sitepress->get_current_language()];
  57. add_filter( 'home_url', array( $this, 'home_url' ), 1, 4 );
  58. add_filter( 'post_type_archive_link', array( $this, 'post_type_archive_link' ), 10, 2 );
  59. }
  60. if ( !$this->_is_per_domain && get_option( 'page_on_front' ) ) {
  61. add_filter( 'wpseo_sitemap_entry',
  62. array($this, 'filter_home_pages'), 10, 3 );
  63. }
  64. }
  65. }
  66. /**
  67. * Init if languages per domain.
  68. */
  69. public function init() {
  70. add_filter( 'wpseo_typecount_join', array( $this, 'typecount_join' ), 10, 2 );
  71. add_filter( 'wpseo_typecount_where', array( $this, 'typecount_where' ), 10, 2 );
  72. add_filter( 'wpseo_posts_join', array( $this, 'posts_join' ), 10, 2 );
  73. add_filter( 'wpseo_posts_where', array( $this, 'posts_where' ), 10, 2 );
  74. // add_filter( 'wpseo_stylesheet_url', array( $this, 'set_stylesheet' ) );
  75. // add_filter( 'wpseo_build_sitemap_post_type', array( $this, 'get_post_type' ) );
  76. }
  77. /**
  78. * Adds sitemap info on WP SEO admin screen.
  79. *
  80. * @global type $sitepress
  81. */
  82. public function summary() {
  83. global $sitepress;
  84. echo '<h2>WPML</h2>';
  85. echo __('Sitemaps for each languages can be accessed here:', 'sitepress') . '<ul>';
  86. foreach ($sitepress->get_ls_languages() as $lang) {
  87. $url = $lang['url'] . 'sitemap_index.xml';
  88. echo '<li>' . $lang['translated_name'] . ' <a href="' . $url
  89. . '" target="_blank">' . $url . '</a></li>';
  90. }
  91. echo '</ul>';
  92. }
  93. /**
  94. * Adds active languages sitemap links to sitemap_index.xml
  95. * @param type $str
  96. *
  97. * @TODO Remove - not needed since 1.0.1
  98. */
  99. function add_to_index( $str ) {
  100. global $sitepress, $sitepress_settings, $wpdb;
  101. // Deprecated call
  102. $options = version_compare( WPSEO_VERSION, '1.5.0', '>=' ) ? WPSEO_Options::get_all() : get_wpseo_options();
  103. $default_language = $sitepress->get_default_language();
  104. $current_language = $sitepress->get_current_language();
  105. foreach($sitepress->get_active_languages() as $lang_code => $array){
  106. if(isset($sitepress_settings['language_domains'][$lang_code])){
  107. $home_url = $sitepress_settings['language_domains'][$lang_code];
  108. } else {
  109. $home_url = home_url();
  110. }
  111. foreach (get_post_types(array('public' => true)) as $post_type) {
  112. $sitepress->switch_lang($lang_code);
  113. $count = get_posts(array('post_type' => $post_type, 'post_status' => 'publish', 'suppress_filters' => 0));
  114. $sitepress->switch_lang($current_language);
  115. if(count($count) > 0 && $sitepress->is_translated_post_type($post_type)){
  116. if (empty($options['post_types-'.$post_type.'-not_in_sitemap']) && $lang_code !== $default_language){
  117. $filename = $post_type .'-'. $lang_code .'-sitemap.xml';
  118. $date = $this->get_last_mod_date($post_type, $lang_code);
  119. $str .= '<sitemap>' . "\n";
  120. $str .= '<loc>' . $home_url . '/' . $filename . '</loc>' . "\n";
  121. $str .= '<lastmod>' . $date . '</lastmod>' . "\n";
  122. $str .= '</sitemap>' . "\n";
  123. }
  124. }
  125. }
  126. foreach ( get_taxonomies( array('public' => true) ) as $tax ) {
  127. $sitepress->switch_lang($lang_code);
  128. $count = get_terms($tax, array('suppress_filters' => 0));
  129. $sitepress->switch_lang($current_language);
  130. if ( count($count) > 0 && $sitepress->is_translated_taxonomy($tax)){
  131. if (empty($options['taxonomies-'.$tax.'-not_in_sitemap']) && $lang_code !== $default_language){
  132. $filename = $tax .'-'. $lang_code .'-sitemap.xml';
  133. $date = $this->get_last_mod_date('post', $lang_code);
  134. $str .= '<sitemap>' . "\n";
  135. $str .= '<loc>' . $home_url . '/' . $filename . '</loc>' . "\n";
  136. $str .= '<lastmod>' . $date . '</lastmod>' . "\n";
  137. $str .= '</sitemap>' . "\n";
  138. }
  139. }
  140. }
  141. }
  142. return $str;
  143. }
  144. /**
  145. * Filters WPSEO typecount SQL query
  146. */
  147. function typecount_join($join, $post_type){
  148. global $wpdb, $sitepress;
  149. if($sitepress->is_translated_post_type($post_type)){
  150. $join .= " INNER JOIN {$wpdb->prefix}icl_translations
  151. ON $wpdb->posts.ID = {$wpdb->prefix}icl_translations.element_id";
  152. }
  153. return $join;
  154. }
  155. function typecount_where($where, $post_type){
  156. global $wpdb, $sitepress;
  157. $sitemap_language = $this->get_sitemap_language();
  158. if($sitepress->is_translated_post_type($post_type)){
  159. $where .= " AND {$wpdb->prefix}icl_translations.language_code = '{$sitemap_language}'
  160. AND {$wpdb->prefix}icl_translations.element_type = 'post_{$post_type}'";
  161. }
  162. return $where;
  163. }
  164. /**
  165. * Filters WPSEO posts query
  166. */
  167. function posts_join($join, $post_type){
  168. global $wpdb, $sitepress;
  169. if($sitepress->is_translated_post_type($post_type)){
  170. $join .= " INNER JOIN {$wpdb->prefix}icl_translations
  171. ON $wpdb->posts.ID = {$wpdb->prefix}icl_translations.element_id";
  172. }
  173. return $join;
  174. }
  175. function posts_where($where, $post_type){
  176. global $wpdb, $sitepress;
  177. if($sitepress->is_translated_post_type($post_type)){
  178. $sitemap_language = $this->get_sitemap_language();
  179. $where .= " AND {$wpdb->prefix}icl_translations.language_code = '{$sitemap_language}'
  180. AND {$wpdb->prefix}icl_translations.element_type = 'post_{$post_type}'";
  181. }
  182. return $where;
  183. }
  184. /**
  185. * Filters XML sitemap stylesheet
  186. *
  187. * @TODO Remove - not needed since 1.0.1
  188. */
  189. function set_stylesheet( $stylesheet ){
  190. // Deprecated
  191. if ( version_compare( WPSEO_VERSION, '1.4.25', '<=' ) ) {
  192. global $sitepress_settings;
  193. if(@$sitepress_settings['language_domains'][$this->get_sitemap_language()]){
  194. $language_domain = $sitepress_settings['language_domains'][$this->get_sitemap_language()];
  195. $wpseo_dirname = str_replace('wp-seo.php', '', WPSEO_BASENAME);
  196. $wpseo_domain_path = $language_domain . '/wp-content/plugins/' . $wpseo_dirname;
  197. $this->stylesheet = '<?xml-stylesheet type="text/xsl" href="'.$wpseo_domain_path.'css/xml-sitemap.xsl"?>';
  198. } else {
  199. $this->stylesheet = '<?xml-stylesheet type="text/xsl" href="'
  200. . plugins_url( 'css/xml-sitemap.xsl', WPSEO_BASENAME )
  201. . '"?>';
  202. }
  203. return $this->stylesheet;
  204. } else {
  205. return '<?xml-stylesheet type="text/xsl" href="'
  206. . preg_replace( '/(^http[s]?:)/', '',
  207. esc_url( $this->_current_home_url ) )
  208. . '/main-sitemap.xsl"?>';
  209. }
  210. return $stylesheet;
  211. }
  212. /**
  213. * Get post type from sitemap name
  214. *
  215. * @TODO Remove - not needed since 1.0.1
  216. */
  217. function get_post_type($post_type){
  218. if($post_type !== '1'){ // sitemap_index.xml
  219. $get_sitemap_name = basename($_SERVER['REQUEST_URI']);
  220. $post_type = explode("-", $get_sitemap_name);
  221. $post_type = $post_type[0];
  222. }
  223. return $post_type;
  224. }
  225. /**
  226. * Get sitemap language from sitemap name
  227. *
  228. * @TODO Remove - not needed since 1.0.1
  229. */
  230. function get_sitemap_language(){
  231. global $sitepress;
  232. $get_sitemap_name = basename($_SERVER['REQUEST_URI']);
  233. $sitemap_language = explode("-", $get_sitemap_name);
  234. if(isset($sitemap_language[1])){
  235. $sitemap_language = $sitemap_language[1];
  236. }
  237. foreach($sitepress->get_active_languages() as $language_code => $array){
  238. $active_languages[] = $language_code;
  239. }
  240. if(!in_array($sitemap_language, $active_languages)){
  241. // This should be current language, already determined by WPML
  242. $sitemap_language = ICL_LANGUAGE_CODE;//$sitepress->get_default_language();
  243. }
  244. return $sitemap_language;
  245. }
  246. /**
  247. * Get last sitemap post type modified date by language
  248. * @param type $post_type
  249. * @param type $language_code
  250. */
  251. function get_last_mod_date($post_type, $language_code){
  252. global $wpdb;
  253. $date = $wpdb->get_var( "SELECT post_modified_gmt, ID FROM $wpdb->posts
  254. INNER JOIN {$wpdb->prefix}icl_translations
  255. ON $wpdb->posts.ID = {$wpdb->prefix}icl_translations.element_id
  256. WHERE $wpdb->posts.post_status = 'publish'
  257. AND $wpdb->posts.post_type = '$post_type'
  258. AND {$wpdb->prefix}icl_translations.language_code = '$language_code'
  259. ORDER BY post_modified_gmt DESC LIMIT 1 OFFSET 0");
  260. $date = strtotime($date);
  261. $date = date( 'c', $date );
  262. if(!isset($date)){
  263. $result = strtotime( get_lastpostmodified( 'gmt' ) );
  264. $date = date( 'c', $result );
  265. }
  266. return $date;
  267. }
  268. /**
  269. * Filters home page URLs.
  270. *
  271. * If there is page_on_front, adjust URL to e.g. http://site.com/es
  272. * do not leave actual page name e.g. http://site.com/es/sample-page
  273. *
  274. * @global type $sitepress
  275. * @param type $url
  276. * @param type $post_type
  277. * @param type $post
  278. * @return type
  279. */
  280. public function filter_home_pages( $url, $post_type, $post ) {
  281. // Basic check
  282. if ( empty( $post->ID ) || !isset( $post->post_type )
  283. || $post->post_type != 'page' ) {
  284. return $url;
  285. }
  286. // Collect info on home IDs
  287. static $home_pages;
  288. if ( is_null( $home_pages ) ) {
  289. foreach ( $this->_active_languages as $l ) {
  290. if ( $l['code'] == ICL_LANGUAGE_CODE ) continue;
  291. $home_pages[$l['code']] = icl_object_id( get_option( 'page_on_front' ),
  292. 'page', false, $l['code'] );
  293. }
  294. }
  295. // Is done?
  296. if ( empty( $home_pages ) ) {
  297. remove_filter( 'wpseo_sitemap_entry', array( $this, 'filter_home_pages' ), 10 );
  298. return $url;
  299. }
  300. // If post ID in home_pages
  301. global $sitepress;
  302. if ( $lang = array_search( $post->ID, $home_pages ) ) {
  303. $url['loc'] = $sitepress->language_url( $lang );
  304. unset( $home_pages[$lang] );
  305. }
  306. return $url;
  307. }
  308. /**
  309. * Filters home URL.
  310. *
  311. * @param string $url
  312. * @return bool|string
  313. */
  314. public function home_url( $url ) {
  315. return str_replace( $this->_default_home_url, $this->_current_home_url, $url );
  316. }
  317. /**
  318. * Filters post type archive link if slugs translated.
  319. *
  320. * @TODO WPML do not filter archive link if post type slugs are translated
  321. *
  322. * @param type $link
  323. * @param type $post_type
  324. */
  325. public function post_type_archive_link( $link, $post_type ) {
  326. global $sitepress, $sitepress_settings, $wp_rewrite;
  327. $translate = !empty( $sitepress_settings['posts_slug_translation']['types'][$post_type] );
  328. if ( $translate && class_exists( 'WPML_Slug_Translation') ) {
  329. $post_type_obj = get_post_type_object($post_type);
  330. $translated_slug = WPML_Slug_Translation::get_translated_slug( $post_type,
  331. $sitepress->get_current_language() );
  332. if ( get_option( 'permalink_structure' )
  333. && is_array( $post_type_obj->rewrite ) ) {
  334. $struct = ( true === $post_type_obj->has_archive ) ? $translated_slug : $post_type_obj->has_archive;
  335. if ( $post_type_obj->rewrite['with_front'] ) {
  336. $struct = $wp_rewrite->front . $struct;
  337. } else {
  338. $struct = $wp_rewrite->root . $struct;
  339. }
  340. $link = home_url( user_trailingslashit( $struct,
  341. 'post_type_archive' ) );
  342. } else {
  343. $link = home_url( '?post_type=' . $translated_slug );
  344. }
  345. }
  346. return $link;
  347. }
  348. }
  349. $wpseo_xml_filter = new WPSEO_XML_Sitemaps_Filter();