33Plugin Name: WP Permastructure
44Plugin URI: https://github.com/interconnectit/wp-permastructure
55Description: Adds the ability to define permalink structures for any custom post type using rewrite tags.
6- Version: 1.5.1
6+ Version: 1.6.0
77Author: Robert O'Rourke
88Author URI: http://interconnectit.com
99License: GPLv2 or later
3131/**
3232 * Changelog
3333 *
34+ * 1.6: Sort permastructs by length for specifity, allow filtering whether to expand hierarchical terms
35+ * 1.5: Ensure rewrites prefixed with taxonomies are checked before the taxonomies themselves
3436 * 1.4: Handles sample filters without the need for the get post call
3537 * 1.3: Fixed permalink sanitisation, was truncating the third placeholder for some reason
3638 * 1.2: Fixed attachment URL rewrites, fixed edge case where permastruct is %postname% only
@@ -211,6 +213,11 @@ public function add_permastructs( $rules ) {
211213 $ permastructs [ $ type ->rewrite [ 'permastruct ' ] ][] = $ type ->name ;
212214 }
213215
216+ // Sort permastructs by longest to shortest, e.g. higher specificity to lower.
217+ uksort ( $ permastructs , function ( $ a , $ b ) {
218+ return mb_strlen ( $ b ) <=> mb_strlen ( $ a );
219+ } );
220+
214221 $ rules = array ();
215222
216223 // add our permastructs scoped to the post types - overwriting any keys that already exist
@@ -225,7 +232,7 @@ public function add_permastructs( $rules ) {
225232 $ post_type_rules_temp = $ wp_rewrite ->generate_rewrite_rules ( $ struct , EP_PERMALINK , false , true , false , false , true );
226233 foreach ( $ post_type_rules_temp as $ regex => $ query ) {
227234 if ( preg_match ( '/(&|\?)(cpage|attachment|p|name|pagename)=/ ' , $ query ) ) {
228- $ post_type_query = ( count ( $ post_types ) < 2 ? '&post_type= ' . $ post_types [ 0 ] : '&post_type[]= ' . join ( '&post_type[]= ' , array_unique ( $ post_types ) ) );
235+ $ post_type_query = ( count ( $ post_types ) < 2 ? '&post_type= ' . $ post_types [0 ] : '&post_type[]= ' . join ( '&post_type[]= ' , array_unique ( $ post_types ) ) );
229236 $ rules [ $ regex ] = $ query . ( preg_match ( '/(&|\?)(attachment|pagename)=/ ' , $ query ) ? '' : $ post_type_query );
230237 // Ensure permalinks that match a custom taxonomy path don't get swallowed.
231238 $ wp_rewrite ->extra_rules_top [ $ regex ] = $ rules [ $ regex ];
@@ -314,11 +321,8 @@ public function parse_permalinks( $post_link, $post, $leavename, $sample = false
314321 if ( strpos ( $ permalink , '% ' . $ taxonomy . '% ' ) !== false ) {
315322 $ terms = get_the_terms ( $ post ->ID , $ taxonomy );
316323 if ( $ terms && ! is_wp_error ( $ terms ) ) {
317- if ( function_exists ( 'wp_list_sort ' ) ) {
318- $ terms = wp_list_sort ( $ terms , 'term_id ' , 'ASC ' ); // order by term_id ASC
319- } else {
320- usort ( $ terms , '_usort_terms_by_ID ' ); // order by term_id ASC
321- }
324+ // order by term_id ASC.
325+ $ terms = wp_list_sort ( $ terms , 'term_id ' , 'ASC ' );
322326
323327 /**
324328 * Filter the term that gets used in the `$tax` permalink token.
@@ -329,8 +333,17 @@ public function parse_permalinks( $post_link, $post, $leavename, $sample = false
329333 */
330334 $ term_object = apply_filters ( "post_link_ {$ taxonomy }" , reset ( $ terms ), $ terms , $ post );
331335
336+ /**
337+ * Filter whether to expand child term paths.
338+ *
339+ * @param bool $allow_hierarchy Whether to expand child terms to include term parents.
340+ * @param WP_Term $term Current term object selected.
341+ * @param WP_Post $post The post in question.
342+ */
343+ $ allow_hierarchy = apply_filters ( "post_link_ {$ taxonomy }_allow_hierarchy " , $ taxonomy_object ->hierarchical , $ term_object , $ post );
344+
332345 $ term = $ term_object ->slug ;
333- if ( $ taxonomy_object -> hierarchical && $ parent = $ term_object ->parent ) {
346+ if ( $ allow_hierarchy && $ parent = $ term_object ->parent ) {
334347 $ term = get_term_parents ( $ parent , $ taxonomy , false , '/ ' , true ) . $ term ;
335348 }
336349 }
0 commit comments