PluginProbe
Polylang / 3.0.2
Polylang v3.0.2
3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 3.0.3 All 233 releases
polylang / include / translated-post.php

translated-post.php in Polylang 3.0.2, at include/translated-post.php

269 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package Polylang
4 */
5
6 /**
7 * Setups the posts languages and translations model
8 *
9 * @since 1.8
10 */
11 class PLL_Translated_Post extends PLL_Translated_Object {
12
13 /**
14 * Constructor.
15 *
16 * @since 1.8
17 *
18 * @param PLL_Model $model PLL_Model instance.
19 */
20 public function __construct( &$model ) {
21 // init properties
22 $this->object_type = null; // For taxonomies
23 $this->type = 'post'; // For capabilities
24 $this->tax_language = 'language';
25 $this->tax_translations = 'post_translations';
26 $this->tax_tt = 'term_taxonomy_id';
27
28 parent::__construct( $model );
29
30 // registers completely the language taxonomy
31 add_action( 'setup_theme', array( $this, 'register_taxonomy' ), 1 );
32
33 // setups post types to translate
34 add_action( 'registered_post_type', array( $this, 'registered_post_type' ) );
35
36 // forces updating posts cache
37 add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
38 }
39
40 /**
41 * Store the post language in the database.
42 *
43 * @since 0.6
44 *
45 * @param int $post_id Post id.
46 * @param int|string|PLL_Language $lang Language (term_id or slug or object).
47 * @return void
48 */
49 public function set_language( $post_id, $lang ) {
50 $old_lang = $this->get_language( $post_id );
51 $old_lang = $old_lang ? $old_lang->slug : '';
52
53 $lang = $this->model->get_language( $lang );
54 $lang = $lang ? $lang->slug : '';
55
56 if ( $old_lang !== $lang ) {
57 wp_set_post_terms( (int) $post_id, $lang, 'language' );
58 }
59 }
60
61 /**
62 * Returns the language of a post
63 *
64 * @since 0.1
65 *
66 * @param int $post_id post id
67 * @return PLL_Language|false PLL_Language object, false if no language is associated to that post
68 */
69 public function get_language( $post_id ) {
70 $lang = $this->get_object_term( $post_id, 'language' );
71 return ( $lang ) ? $this->model->get_language( $lang ) : false;
72 }
73
74 /**
75 * Deletes a translation.
76 *
77 * @since 0.5
78 *
79 * @param int $id Post id.
80 * @return void
81 */
82 public function delete_translation( $id ) {
83 parent::delete_translation( $id );
84 wp_set_object_terms( $id, array(), $this->tax_translations );
85 }
86
87 /**
88 * A join clause to add to sql queries when filtering by language is needed directly in query
89 *
90 * @since 1.2
91 *
92 * @param string $alias Alias for $wpdb->posts table
93 * @return string join clause
94 */
95 public function join_clause( $alias = '' ) {
96 global $wpdb;
97 if ( empty( $alias ) ) {
98 $alias = $wpdb->posts;
99 }
100 return " INNER JOIN $wpdb->term_relationships AS pll_tr ON pll_tr.object_id = $alias.ID";
101 }
102
103 /**
104 * Register the language taxonomy
105 *
106 * @since 1.2
107 *
108 * @return void
109 */
110 public function register_taxonomy() {
111 register_taxonomy(
112 'language',
113 $this->model->get_translated_post_types(),
114 array(
115 'labels' => array(
116 'name' => __( 'Languages', 'polylang' ),
117 'singular_name' => __( 'Language', 'polylang' ),
118 'all_items' => __( 'All languages', 'polylang' ),
119 ),
120 'public' => false,
121 'show_ui' => false, // hide the taxonomy on admin side, needed for WP 4.4.x
122 'show_in_nav_menus' => false, // no metabox for nav menus, needed for WP 4.4.x
123 'publicly_queryable' => true, // since WP 4.5
124 'query_var' => 'lang',
125 'rewrite' => $this->model->options['force_lang'] < 2, // no rewrite for domains and sub-domains
126 '_pll' => true, // polylang taxonomy
127 )
128 );
129 }
130
131 /**
132 * Check if registered post type must be translated
133 *
134 * @since 1.2
135 *
136 * @param string $post_type post type name
137 * @return void
138 */
139 public function registered_post_type( $post_type ) {
140 if ( $this->model->is_translated_post_type( $post_type ) ) {
141 register_taxonomy_for_object_type( 'language', $post_type );
142 register_taxonomy_for_object_type( 'post_translations', $post_type );
143 }
144 }
145
146 /**
147 * Forces calling 'update_object_term_cache' when querying posts or pages.
148 * This is especially useful for nav menus with a lot of pages as, without doing this,
149 * we would have one query per page in the menu to get the page language for the permalink.
150 *
151 * @since 1.8
152 *
153 * @param WP_Query $query Reference to the query object.
154 * @return void
155 */
156 public function pre_get_posts( $query ) {
157 if ( ! empty( $query->query['post_type'] ) && $this->model->is_translated_post_type( $query->query['post_type'] ) ) {
158 $query->query_vars['update_post_term_cache'] = true;
159 }
160 }
161
162 /**
163 * Checks if the current user can read the post
164 *
165 * @since 1.5
166 *
167 * @param int $post_id Post ID
168 * @param string $context Optional, 'edit' or 'view', defaults to 'view'.
169 * @return bool
170 */
171 public function current_user_can_read( $post_id, $context = 'view' ) {
172 $post = get_post( $post_id );
173
174 if ( empty( $post ) ) {
175 return false;
176 }
177
178 if ( 'inherit' === $post->post_status && $post->post_parent ) {
179 $post = get_post( $post->post_parent );
180
181 if ( empty( $post ) ) {
182 return false;
183 }
184 }
185
186 if ( 'inherit' === $post->post_status || in_array( $post->post_status, get_post_stati( array( 'public' => true ) ) ) ) {
187 return true;
188 }
189
190 // Follow WP practices, which shows links to private posts ( when readable ), but not for draft posts ( ex: get_adjacent_post_link() )
191 if ( in_array( $post->post_status, get_post_stati( array( 'private' => true ) ) ) ) {
192 $post_type_object = get_post_type_object( $post->post_type );
193 $user = wp_get_current_user();
194 return is_user_logged_in() && ( current_user_can( $post_type_object->cap->read_private_posts ) || $user->ID == $post->post_author ); // Comparison must not be strict!
195 }
196
197 // In edit context, show draft and future posts.
198 if ( 'edit' === $context ) {
199 $states = get_post_stati(
200 array(
201 'protected' => true,
202 'show_in_admin_all_list' => true,
203 )
204 );
205
206 if ( in_array( $post->post_status, $states ) ) {
207 $user = wp_get_current_user();
208 return is_user_logged_in() && ( current_user_can( 'edit_posts' ) || $user->ID == $post->post_author ); // Comparison must not be strict!
209 }
210 }
211
212 return false;
213 }
214
215 /**
216 * Returns a list of posts in a language ( $lang )
217 * not translated in another language ( $untranslated_in ).
218 *
219 * @since 2.6
220 *
221 * @param string $type Post type.
222 * @param PLL_Language $untranslated_in The language the posts must not be translated in.
223 * @param PLL_Language $lang Language of the searched posts.
224 * @param string $search Limit the results to the posts matching this string.
225 * @return WP_Post[] Array of posts.
226 */
227 public function get_untranslated( $type, $untranslated_in, $lang, $search = '' ) {
228 $return = array();
229
230 // Don't order by title: see https://wordpress.org/support/topic/find-translated-post-when-10-is-not-enough
231 $args = array(
232 's' => $search,
233 'suppress_filters' => 0, // To make the post_fields filter work
234 'lang' => 0, // Avoid admin language filter
235 'numberposts' => 20, // Limit to 20 posts
236 'post_status' => 'any',
237 'post_type' => $type,
238 'tax_query' => array(
239 array(
240 'taxonomy' => 'language',
241 'field' => 'term_taxonomy_id', // WP 3.5+
242 'terms' => $lang->term_taxonomy_id,
243 ),
244 ),
245 );
246
247 /**
248 * Filter the query args when auto suggesting untranslated posts in the Languages metabox
249 * This should help plugins to fix some edge cases
250 *
251 * @see https://wordpress.org/support/topic/find-translated-post-when-10-is-not-enough
252 *
253 * @since 1.7
254 *
255 * @param array $args WP_Query arguments
256 */
257 $args = apply_filters( 'pll_ajax_posts_not_translated_args', $args );
258 $posts = get_posts( $args );
259
260 foreach ( $posts as $post ) {
261 if ( $post instanceof WP_Post && ! $this->get_translation( $post->ID, $untranslated_in ) && $this->current_user_can_read( $post->ID, 'edit' ) ) {
262 $return[] = $post;
263 }
264 }
265
266 return $return;
267 }
268 }
269