PLL_Links_Directory

Links model for use when the language code is added in url as a directory for example mysite.com/en/something implements the "links_model interface".

Defined (1)

The class is defined in the following location(s).

/include/links-directory.php  
  1. class PLL_Links_Directory extends PLL_Links_Permalinks { 
  2.  
  3. /** 
  4. * Constructor 
  5. * @since 1.2 
  6. * @param object $model PLL_Model instance 
  7. */ 
  8. public function __construct( &$model ) { 
  9. parent::__construct( $model ); 
  10.  
  11. if ( did_action( 'pll_init' ) ) { 
  12. $this->init(); 
  13. } else { 
  14. add_action( 'pll_init', array( $this, 'init' ) ); 
  15.  
  16. /** 
  17. * Called only at first object creation to avoid duplicating filters when switching blog 
  18. * @since 1.6 
  19. */ 
  20. public function init() { 
  21. if ( did_action( 'setup_theme' ) ) { 
  22. $this->add_permastruct(); 
  23. } else { 
  24. add_action( 'setup_theme', array( $this, 'add_permastruct' ), 2 ); 
  25.  
  26. // Make sure to prepare rewrite rules when flushing 
  27. add_action( 'pre_option_rewrite_rules', array( $this, 'prepare_rewrite_rules' ) ); 
  28.  
  29. /** 
  30. * Adds the language code in url 
  31. * links_model interface 
  32. * @since 1.2 
  33. * @param string $url url to modify 
  34. * @param object $lang language 
  35. * @return string modified url 
  36. */ 
  37. public function add_language_to_link( $url, $lang ) { 
  38. if ( ! empty( $lang ) ) { 
  39. $base = $this->options['rewrite'] ? '' : 'language/'; 
  40. $slug = $this->options['default_lang'] == $lang->slug && $this->options['hide_default'] ? '' : $base . $lang->slug . '/'; 
  41. if ( false === strpos( $url, $this->home . '/' . $this->root . $slug ) ) { 
  42. return str_replace( $this->home . '/' . $this->root, $this->home . '/' . $this->root . $slug, $url ); 
  43. return $url; 
  44.  
  45. /** 
  46. * Returns the url without language code 
  47. * links_model interface 
  48. * @since 1.2 
  49. * @param string $url url to modify 
  50. * @return string modified url 
  51. */ 
  52. function remove_language_from_link( $url ) { 
  53. foreach ( $this->model->get_languages_list() as $language ) { 
  54. if ( ! $this->options['hide_default'] || $this->options['default_lang'] != $language->slug ) { 
  55. $languages[] = $language->slug; 
  56.  
  57. if ( ! empty( $languages ) ) { 
  58. $pattern = str_replace( '/', '\/', $this->home . '/' . $this->root ); 
  59. $pattern = '#' . $pattern . ( $this->options['rewrite'] ? '' : 'language\/' ) . '('.implode( '|', $languages ).')(\/|$)#'; 
  60. $url = preg_replace( $pattern, $this->home . '/' . $this->root, $url ); 
  61. return $url; 
  62.  
  63. /** 
  64. * Returns the language based on language code in url 
  65. * links_model interface 
  66. * @since 1.2 
  67. * @since 2.0 add $url argument 
  68. * @param string $url optional, defaults to current url 
  69. * @return string language slug 
  70. */ 
  71. public function get_language_from_url( $url = '' ) { 
  72. if ( empty( $url ) ) { 
  73. $path = $_SERVER['REQUEST_URI']; 
  74. } else { 
  75. $path = parse_url( $url, PHP_URL_PATH ); 
  76.  
  77. $pattern = parse_url( $this->home . '/' . $this->root . ( $this->options['rewrite'] ? '' : 'language/' ), PHP_URL_PATH ); 
  78. $pattern = str_replace( '/', '\/', $pattern ); 
  79. $pattern = '#' . $pattern . '('. implode( '|', $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) . ')(\/|$)#'; 
  80. return preg_match( $pattern, trailingslashit( $path ), $matches ) ? $matches[1] : ''; // $matches[1] is the slug of the requested language 
  81.  
  82. /** 
  83. * Returns the home url 
  84. * links_model interface 
  85. * @since 1.3.1 
  86. * @param object $lang PLL_Language object 
  87. * @return string 
  88. */ 
  89. public function home_url( $lang ) { 
  90. $base = $this->options['rewrite'] ? '' : 'language/'; 
  91. $slug = $this->options['default_lang'] == $lang->slug && $this->options['hide_default'] ? '' : '/' . $this->root . $base . $lang->slug; 
  92. return trailingslashit( $this->home . $slug ); 
  93.  
  94. /** 
  95. * Optionaly removes 'language' in permalinks so that we get http://www.myblog/en/ instead of http://www.myblog/language/en/ 
  96. * @since 1.2 
  97. */ 
  98. function add_permastruct() { 
  99. // Language information always in front of the uri ( 'with_front' => false ) 
  100. // The 3rd parameter structure has been modified in WP 3.4 
  101. // Leads to error 404 for pages when there is no language created yet 
  102. if ( $this->model->get_languages_list() ) { 
  103. add_permastruct( 'language', $this->options['rewrite'] ? '%language%' : 'language/%language%', array( 'with_front' => false ) ); 
  104.  
  105. /** 
  106. * Prepares rewrite rules filters 
  107. * @since 0.8.1 
  108. * @param array $pre not used 
  109. * @return unmodified $pre 
  110. */ 
  111. public function prepare_rewrite_rules( $pre ) { 
  112. // Don't modify the rules if there is no languages created yet 
  113. // Make sure to add filter only once and if all custom post types and taxonomies have been registered 
  114. if ( $this->model->get_languages_list() && did_action( 'wp_loaded' ) && ! has_filter( 'language_rewrite_rules', '__return_empty_array' ) ) { 
  115. // Suppress the rules created by WordPress for our taxonomy 
  116. add_filter( 'language_rewrite_rules', '__return_empty_array' ); 
  117.  
  118. foreach ( $this->get_rewrite_rules_filters() as $type ) { 
  119. add_filter( $type . '_rewrite_rules', array( $this, 'rewrite_rules' ) ); 
  120.  
  121. add_filter( 'rewrite_rules_array', array( $this, 'rewrite_rules' ) ); // needed for post type archives 
  122. return $pre; 
  123.  
  124. /** 
  125. * The rewrite rules ! 
  126. * always make sure the default language is at the end in case the language information is hidden for default language 
  127. * thanks to brbrbr http://wordpress.org/support/topic/plugin-polylang-rewrite-rules-not-correct 
  128. * @since 0.8.1 
  129. * @param array $rules rewrite rules 
  130. * @return array modified rewrite rules 
  131. */ 
  132. public function rewrite_rules( $rules ) { 
  133. $filter = str_replace( '_rewrite_rules', '', current_filter() ); 
  134.  
  135. global $wp_rewrite; 
  136. $newrules = array(); 
  137.  
  138. $languages = $this->model->get_languages_list( array( 'fields' => 'slug' ) ); 
  139. if ( $this->options['hide_default'] ) { 
  140. $languages = array_diff( $languages, array( $this->options['default_lang'] ) ); 
  141.  
  142. if ( ! empty( $languages ) ) { 
  143. $slug = $wp_rewrite->root . ( $this->options['rewrite'] ? '' : 'language/' ) . '(' . implode( '|', $languages ) . ')/'; 
  144.  
  145. // For custom post type archives 
  146. $cpts = array_intersect( $this->model->get_translated_post_types(), get_post_types( array( '_builtin' => false ) ) ); 
  147. $cpts = $cpts ? '#post_type=(' . implode( '|', $cpts ) . ')#' : ''; 
  148.  
  149. foreach ( $rules as $key => $rule ) { 
  150. // Special case for translated post types and taxonomies to allow canonical redirection 
  151. if ( $this->options['force_lang'] && in_array( $filter, array_merge( $this->model->get_translated_post_types(), $this->model->get_translated_taxonomies() ) ) ) { 
  152.  
  153. /** 
  154. * Filters the rewrite rules to modify 
  155. * @since 1.9.1 
  156. * @param bool $modify whether to modify or not the rule, defaults to true 
  157. * @param array $rule original rewrite rule 
  158. * @param string $filter current set of rules being modified 
  159. * @param string|bool $archive custom post post type archive name or false if it is not a cpt archive 
  160. */ 
  161. if ( isset( $slug ) && apply_filters( 'pll_modify_rewrite_rule', true, array( $key => $rule ), $filter, false ) ) { 
  162. $newrules[ $slug . str_replace( $wp_rewrite->root, '', ltrim( $key, '^' ) ) ] = str_replace( 
  163. array( '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '[1]', '?' ),  
  164. array( '[9]', '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '?lang=$matches[1]&' ),  
  165. $rule 
  166. ); // Should be enough! 
  167.  
  168. $newrules[ $key ] = $rule; 
  169.  
  170. // Rewrite rules filtered by language 
  171. elseif ( in_array( $filter, $this->always_rewrite ) || in_array( $filter, $this->model->get_filtered_taxonomies() ) || ( $cpts && preg_match( $cpts, $rule, $matches ) && ! strpos( $rule, 'name=' ) ) || ( 'rewrite_rules_array' != $filter && $this->options['force_lang'] ) ) { 
  172.  
  173. /** This filter is documented in include/links-directory.php */ 
  174. if ( apply_filters( 'pll_modify_rewrite_rule', true, array( $key => $rule ), $filter, empty( $matches[1] ) ? false : $matches[1] ) ) { 
  175. if ( isset( $slug ) ) { 
  176. $newrules[ $slug . str_replace( $wp_rewrite->root, '', ltrim( $key, '^' ) ) ] = str_replace( 
  177. array( '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '[1]', '?' ),  
  178. array( '[9]', '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '?lang=$matches[1]&' ),  
  179. $rule 
  180. ); // Should be enough! 
  181.  
  182. if ( $this->options['hide_default'] ) { 
  183. $newrules[ $key ] = str_replace( '?', '?lang=' . $this->options['default_lang'] . '&', $rule ); 
  184. } else { 
  185. $newrules[ $key ] = $rule; 
  186.  
  187. // Unmodified rules 
  188. else { 
  189. $newrules[ $key ] = $rule; 
  190.  
  191. // The home rewrite rule 
  192. if ( 'root' == $filter && isset( $slug ) ) { 
  193. $newrules[ $slug . '?$' ] = $wp_rewrite->index.'?lang=$matches[1]'; 
  194.  
  195. return $newrules;