PluginProbe ʕ •ᴥ•ʔ
Custom Post Type Permalinks / 3.5.3
Custom Post Type Permalinks v3.5.3
1.2.0 1.3.0 1.3.1 1.4.0 1.5.1 1.5.2 1.5.4 2.0.0 2.0.1 2.0.2 2.1.1 2.1.2 2.1.3 2.2.0 3.0.0 3.0.1 3.1.0 3.1.1 3.1.3 3.1.4 3.1.5 3.2.0 3.2.1 3.2.2 3.3.0 3.3.1 3.3.4 3.3.5 3.4.0 3.4.0-rc.1 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.5.2 3.5.3 3.5.4 3.5.5 trunk 0.6 0.6.1 0.6.2 0.7 0.7.1 0.7.10 0.7.2 0.7.2.1 0.7.3 0.7.3.1 0.7.4 0.7.4.1 0.7.5 0.7.5.1 0.7.5.2 0.7.5.6 0.7.6 0.7.8 0.7.9 0.7.9.1 0.7.9.2 0.8 0.8.1 0.8.6 0.8.7 0.8.7.1 0.8.7.5 0.8.7.6 0.9 0.9.1 0.9.2.1 0.9.3.1 0.9.3.2 0.9.3.3 0.9.5 0.9.5.1 0.9.5.2 0.9.5.3 0.9.5.4 0.9.5.6 0.9.6 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.1.0
custom-post-type-permalinks / CPTP / Module / Permalink.php
custom-post-type-permalinks / CPTP / Module Last commit date
Admin.php 5 years ago FlushRules.php 8 years ago GetArchives.php 5 years ago Option.php 5 years ago Permalink.php 1 year ago Rewrite.php 1 year ago Setting.php 6 years ago
Permalink.php
446 lines
1 <?php
2 /**
3 * Override Output Permalinks
4 *
5 * @package Custom_Post_Type_Permalinks
6 */
7
8 /**
9 * CPTP_Module_Permalink
10 *
11 * @since 0.9.4
12 * */
13 class CPTP_Module_Permalink extends CPTP_Module {
14
15
16 /**
17 * Add Filter Hooks.
18 */
19 public function add_hook() {
20 add_filter(
21 'post_type_link',
22 array( $this, 'post_type_link' ),
23 apply_filters( 'cptp_post_type_link_priority', 0 ),
24 4
25 );
26
27 add_filter(
28 'term_link',
29 array( $this, 'term_link' ),
30 apply_filters( 'cptp_term_link_priority', 0 ),
31 3
32 );
33
34 add_filter(
35 'attachment_link',
36 array( $this, 'attachment_link' ),
37 apply_filters( 'cptp_attachment_link_priority', 20 ),
38 2
39 );
40
41 add_filter(
42 'wpml_st_post_type_link_filter_original_slug',
43 array( $this, 'replace_post_slug_with_placeholder' ),
44 10,
45 3
46 );
47 }
48
49
50 /**
51 *
52 * Fix permalinks output.
53 *
54 * @param String $post_link link url.
55 * @param WP_Post $post post object.
56 * @param String $leavename for edit.php.
57 *
58 * @return string
59 * @version 2.0
60 */
61 public function post_type_link( $post_link, $post, $leavename ) {
62 /**
63 * WP_Rewrite.
64 *
65 * @var WP_Rewrite $wp_rewrite
66 */
67 global $wp_rewrite;
68
69 if ( ! $wp_rewrite->using_permalinks() ) {
70 return $post_link;
71 }
72
73 $draft_or_pending = isset( $post->post_status ) && in_array(
74 $post->post_status,
75 array(
76 'draft',
77 'pending',
78 'auto-draft',
79 ),
80 true
81 );
82 if ( $draft_or_pending && ! $leavename ) {
83 return $post_link;
84 }
85
86 $post_type = $post->post_type;
87 $pt_object = get_post_type_object( $post_type );
88
89 if ( false === $pt_object->rewrite ) {
90 return $post_link;
91 }
92
93 if ( ! in_array( $post->post_type, CPTP_Util::get_post_types(), true ) ) {
94 return $post_link;
95 }
96
97 $permalink = $wp_rewrite->get_extra_permastruct( $post_type );
98
99 $permalink = str_replace( '%post_id%', $post->ID, $permalink );
100 $permalink = str_replace( CPTP_Module_Rewrite::get_slug_placeholder( $post_type ), $pt_object->rewrite['slug'], $permalink );
101
102 // has parent.
103 $parentsDirs = '';
104 if ( $pt_object->hierarchical ) {
105 if ( ! $leavename ) {
106 $postId = $post->ID;
107 while ( $parent = get_post( $postId )->post_parent ) {
108 $parentsDirs = get_post( $parent )->post_name . '/' . $parentsDirs;
109 $postId = $parent;
110 }
111 }
112 }
113
114 $permalink = str_replace( '%' . $post_type . '%', $parentsDirs . '%' . $post_type . '%', $permalink );
115
116 if ( ! $leavename ) {
117 $permalink = str_replace( '%' . $post_type . '%', $post->post_name, $permalink );
118 }
119
120 // %post_id%/attachment/%attachement_name%;
121 $id = filter_input( INPUT_GET, 'post' );
122 if ( 'attachment' === $post->post_type ) {
123 if ( null !== $id && intval( $id ) !== $post->ID ) {
124 $parent_structure = trim( CPTP_Util::get_permalink_structure( $post->post_type ), '/' );
125 $parent_dirs = explode( '/', $parent_structure );
126 if ( is_array( $parent_dirs ) ) {
127 $last_dir = array_pop( $parent_dirs );
128 } else {
129 $last_dir = $parent_dirs;
130 }
131
132 if ( '%post_id%' === $parent_structure || '%post_id%' === $last_dir ) {
133 $permalink = untrailingslashit( $permalink ) . '/attachment/';
134 }
135 }
136 }
137
138 $search = array();
139 $replace = array();
140
141 $replace_tag = $this->create_taxonomy_replace_tag( $post->ID, $permalink );
142 $search = $search + $replace_tag['search'];
143 $replace = $replace + $replace_tag['replace'];
144
145 // from get_permalink.
146 $category = '';
147 if ( false !== strpos( $permalink, '%category%' ) ) {
148 $categories = get_the_category( $post->ID );
149 if ( $categories ) {
150 $categories = CPTP_Util::sort_terms( $categories );
151 $category_object = reset( $categories );
152 // phpcs:ignore
153 $category_object = apply_filters( 'post_link_category', $category_object, $categories, $post );
154
155 /**
156 * Filters the category for a post of a custom post type.
157 *
158 * @since 3.4.0
159 *
160 * @param WP_Term $category_object Selected category.
161 * @param WP_Term[] $categories Categories set in post.
162 * @param WP_Post $post Post object.
163 */
164 $category_object = apply_filters( 'cptp_post_link_category', $category_object, $categories, $post );
165 $category_object = get_term( $category_object, 'category' );
166 $category = $category_object->slug;
167 if ( $category_object->parent ) {
168 $parent = $category_object->parent;
169 $category = get_category_parents( $parent, false, '/', true ) . $category;
170 }
171 }
172 // show default category in permalinks, without
173 // having to assign it explicitly.
174 if ( empty( $category ) ) {
175 $default_category = get_term( get_option( 'default_category' ), 'category' );
176 $category = is_wp_error( $default_category ) ? '' : $default_category->slug;
177 }
178 }
179
180 $author = '';
181 if ( false !== strpos( $permalink, '%author%' ) ) {
182 $authordata = get_userdata( $post->post_author );
183 $author = $authordata->user_nicename;
184 }
185
186 $post_date = strtotime( $post->post_date );
187 $permalink = str_replace(
188 array(
189 '%year%',
190 '%monthnum%',
191 '%day%',
192 '%hour%',
193 '%minute%',
194 '%second%',
195 '%category%',
196 '%author%',
197 ),
198 array(
199 gmdate( 'Y', $post_date ),
200 gmdate( 'm', $post_date ),
201 gmdate( 'd', $post_date ),
202 gmdate( 'H', $post_date ),
203 gmdate( 'i', $post_date ),
204 gmdate( 's', $post_date ),
205 $category,
206 $author,
207 ),
208 $permalink
209 );
210 $permalink = str_replace( $search, $replace, $permalink );
211 $permalink = home_url( $permalink );
212
213 return $permalink;
214 }
215
216
217 /**
218 * Create %tax% -> term
219 *
220 * @param int $post_id post id.
221 * @param string $permalink permalink uri.
222 *
223 * @return array
224 */
225 private function create_taxonomy_replace_tag( $post_id, $permalink ) {
226 $search = array();
227 $replace = array();
228
229 $post = get_post( $post_id );
230 $taxonomies = CPTP_Util::get_taxonomies( true );
231
232 // %taxnomomy% -> parent/child
233 foreach ( $taxonomies as $taxonomy => $objects ) {
234 if ( false !== strpos( $permalink, '%' . $taxonomy . '%' ) ) {
235 $terms = get_the_terms( $post_id, $taxonomy );
236
237 if ( $terms && ! is_wp_error( $terms ) ) {
238 $parents = array_map( array( __CLASS__, 'get_term_parent' ), $terms );
239 $newTerms = array();
240 foreach ( $terms as $key => $term ) {
241 if ( ! in_array( $term->term_id, $parents, true ) ) {
242 $newTerms[] = $term;
243 }
244 }
245
246 $term_obj = reset( $newTerms );
247
248 /**
249 * Filters the term for a post of a custom post type.
250 *
251 * @since 3.4.0
252 *
253 * @param WP_Term $term_obj Selected term.
254 * @param WP_Term[] $terms Terms set in post.
255 * @param WP_Taxonomy $taxonomy Taxonomy object.
256 * @param WP_Post $post Post object.
257 */
258 $term_obj = apply_filters( 'cptp_post_link_term', $term_obj, $terms, $taxonomy, $post );
259 $term_slug = $term_obj->slug;
260
261 if ( isset( $term_obj->parent ) && $term_obj->parent ) {
262 $term_slug = CPTP_Util::get_taxonomy_parents_slug( $term_obj->parent, $taxonomy, '/', true ) . $term_slug;
263 }
264 }
265
266 if ( isset( $term_slug ) ) {
267 $search[] = '%' . $taxonomy . '%';
268 $replace[] = $term_slug;
269 }
270 }
271 }
272
273 return array(
274 'search' => $search,
275 'replace' => $replace,
276 );
277 }
278
279 /**
280 * Get parent from term Object
281 *
282 * @param WP_Term $term Term Object.
283 *
284 * @return mixed
285 */
286 private static function get_term_parent( $term ) {
287 if ( isset( $term->parent ) && $term->parent > 0 ) {
288 return $term->parent;
289 }
290 }
291
292
293 /**
294 * Fix attachment output
295 *
296 * @param string $link permalink URI.
297 * @param int $post_id Post ID.
298 *
299 * @return string
300 * @since 0.8.2
301 *
302 * @version 1.0
303 */
304 public function attachment_link( $link, $post_id ) {
305 /**
306 * WP_Rewrite.
307 *
308 * @var WP_Rewrite $wp_rewrite
309 */
310 global $wp_rewrite;
311
312 if ( ! $wp_rewrite->using_permalinks() ) {
313 return $link;
314 }
315
316 $post = get_post( $post_id );
317 if ( ! $post->post_parent ) {
318 return $link;
319 }
320
321 $post_parent = get_post( $post->post_parent );
322 if ( ! $post_parent ) {
323 return $link;
324 }
325
326 $pt_object = get_post_type_object( $post_parent->post_type );
327
328 if ( empty( $pt_object->rewrite ) ) {
329 return $link;
330 }
331
332 if ( ! in_array( $post->post_type, CPTP_Util::get_post_types(), true ) ) {
333 return $link;
334 }
335
336 $permalink = CPTP_Util::get_permalink_structure( $post_parent->post_type );
337 $post_type = get_post_type_object( $post_parent->post_type );
338
339 if ( empty( $post_type->_builtin ) ) {
340 if ( strpos( $permalink, '%postname%' ) < strrpos( $permalink, '%post_id%' ) && false === strrpos( $link, 'attachment/' ) ) {
341 $link = str_replace( $post->post_name, 'attachment/' . $post->post_name, $link );
342 }
343 }
344
345 return $link;
346 }
347
348 /**
349 * Fix taxonomy link outputs.
350 *
351 * @param string $termlink link URI.
352 * @param Object $term Term Object.
353 * @param Object $taxonomy Taxonomy Object.
354 *
355 * @return string
356 * @since 0.6
357 * @version 1.0
358 */
359 public function term_link( $termlink, $term, $taxonomy ) {
360 /**
361 * WP_Rewrite.
362 *
363 * @var WP_Rewrite $wp_rewrite
364 */
365 global $wp_rewrite;
366
367 if ( ! $wp_rewrite->using_permalinks() ) {
368 return $termlink;
369 }
370
371 if ( CPTP_Util::get_no_taxonomy_structure() ) {
372 return $termlink;
373 }
374
375 $taxonomy = get_taxonomy( $taxonomy );
376
377 if ( empty( $taxonomy ) ) {
378 return $termlink;
379 }
380
381 if ( $taxonomy->_builtin ) {
382 return $termlink;
383 }
384
385 if ( ! $taxonomy->public ) {
386 return $termlink;
387 }
388
389 $wp_home = rtrim( home_url(), '/' );
390
391 if ( in_array( get_post_type(), $taxonomy->object_type, true ) ) {
392 $post_type = get_post_type();
393 } else {
394 $post_type = $taxonomy->object_type[0];
395 }
396
397 $front = substr( $wp_rewrite->front, 1 );
398 $termlink = str_replace( $front, '', $termlink );// remove front.
399
400 $post_type_obj = get_post_type_object( $post_type );
401
402 if ( empty( $post_type_obj ) ) {
403 return $termlink;
404 }
405
406 if ( ! isset( $post_type_obj->rewrite['slug'] ) || ! isset( $post_type_obj->rewrite['with_front'] ) ) {
407 return $termlink;
408 }
409
410 $slug = $post_type_obj->rewrite['slug'];
411 $with_front = $post_type_obj->rewrite['with_front'];
412
413 if ( $with_front ) {
414 $slug = $front . $slug;
415 }
416
417 if ( ! empty( $slug ) ) {
418 $termlink = str_replace( $wp_home, $wp_home . '/' . $slug, $termlink );
419 }
420
421 if ( false !== $taxonomy->rewrite && ! $taxonomy->rewrite['hierarchical'] ) {
422 $termlink = str_replace( $term->slug . '/', CPTP_Util::get_taxonomy_parents_slug( $term->term_id, $taxonomy->name, '/', true ), $termlink );
423 }
424
425 return $termlink;
426 }
427
428 /**
429 * This filter is needed for WPML's compatibility. It will return
430 * the slug placeholder instead of the original CPT slug.
431 *
432 * @param string $original_slug The original CPT slug.
433 * @param string $post_link The post link.
434 * @param WP_Post $post The post.
435 *
436 * @return string
437 */
438 public function replace_post_slug_with_placeholder( $original_slug, $post_link, $post ) {
439 if ( ! in_array( $post->post_type, CPTP_Util::get_post_types(), true ) ) {
440 return $original_slug;
441 }
442
443 return CPTP_Module_Rewrite::get_slug_placeholder( $post->post_type );
444 }
445 }
446