PluginProbe
Polylang / 3.8.6
Polylang v3.8.6
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 / src / term-slug.php

term-slug.php in Polylang 3.8.6, at src/term-slug.php

191 lines 4.9 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 * Class for handling term slugs.
8 *
9 * @since 3.7
10 */
11 class PLL_Term_Slug {
12
13 /**
14 * @var PLL_Model
15 */
16 private $model;
17
18 /**
19 * @var string
20 */
21 private $slug;
22
23 /**
24 * @var string
25 */
26 private $taxonomy;
27
28 /**
29 * @var string
30 */
31 private $name;
32
33 /**
34 * @var int
35 */
36 private $term_id;
37
38 /**
39 * @var PLL_Language
40 */
41 private $lang;
42
43 /**
44 * @var int
45 */
46 private $parent;
47
48 /**
49 * Constructor.
50 *
51 * @since 3.7
52 *
53 * @param PLL_Model $model Instance of PLL_Model.
54 * @param string $slug The term slug.
55 * @param string $taxonomy The term taxonomy.
56 * @param string $name The term name.
57 * @param int $term_id The term ID if exists, or 0 if there's no need to know that we are editing an existing term.
58 */
59 public function __construct( PLL_Model $model, string $slug, string $taxonomy, string $name, int $term_id = 0 ) {
60 $this->model = $model;
61 $this->slug = $slug;
62 $this->taxonomy = $taxonomy;
63 $this->name = $name;
64 $this->term_id = $term_id;
65 }
66
67 /**
68 * Tells if the suffix can be added or not.
69 *
70 * @since 3.7
71 *
72 * @return bool True if the suffix can be added, false otherwise.
73 */
74 private function can_add_suffix() {
75 /**
76 * Filters the subsequently inserted term language.
77 *
78 * @since 3.3
79 *
80 * @param PLL_Language|null $lang Found language object, null otherwise.
81 * @param string $taxonomy Term taxonomy.
82 * @param string $slug Term slug.
83 */
84 $lang = apply_filters( 'pll_inserted_term_language', null, $this->taxonomy, $this->slug );
85 if ( ! $lang instanceof PLL_Language ) {
86 return false;
87 }
88 $this->lang = $lang;
89
90 $this->parent = 0;
91 if ( is_taxonomy_hierarchical( $this->taxonomy ) ) {
92 /**
93 * Filters the subsequently inserted term parent.
94 *
95 * @since 3.3
96 *
97 * @param int $parent Parent term ID, 0 if none.
98 * @param string $taxonomy Term taxonomy.
99 * @param string $slug Term slug.
100 */
101 $this->parent = apply_filters( 'pll_inserted_term_parent', 0, $this->taxonomy, $this->slug );
102
103 $this->slug .= $this->maybe_get_parent_suffix();
104 }
105
106 if ( ! $this->slug ) {
107 if ( $this->model->term_exists( $this->name, $this->taxonomy, $this->parent, $this->lang ) ) {
108 // Returns the current empty slug if the term exists with the same name and an empty slug.
109 // Same as WP does when providing a term with a name that already exists and no slug.
110 return false;
111 } else {
112 $this->slug = sanitize_title( $this->name );
113 }
114 }
115
116 // Check if the slug exists globally, excluding the current term if we're editing.
117 $args = array(
118 'slug' => $this->slug,
119 'taxonomy' => $this->taxonomy,
120 'hide_empty' => false,
121 'fields' => 'ids',
122 'lang' => '', // Disable Polylang language filter.
123 'update_term_meta_cache' => false, // Don't need term meta.
124 );
125
126 $terms = get_terms( $args );
127
128 // Return true if the slug is already used by another term (excluding the term being edited).
129 return is_array( $terms ) && ! empty( array_diff( $terms, array( $this->term_id ) ) );
130 }
131
132 /**
133 * Returns the parent suffix for the slug only if parent slug is the same as the given one.
134 * Recursively appends the parents slugs like WordPress does.
135 *
136 * @since 3.3
137 * @since 3.7 Moved from `PLL_Share_Term_Slug` to `PLL_Term_Slug`.
138 *
139 * @return string Parents slugs if they are the same as the child slug, empty string otherwise.
140 */
141 private function maybe_get_parent_suffix() {
142 $parent_suffix = '';
143 $the_parent = get_term( $this->parent, $this->taxonomy );
144
145 if ( ! $the_parent instanceof WP_Term || $the_parent->slug !== $this->slug ) {
146 return $parent_suffix;
147 }
148
149 /**
150 * Mostly copied from {@see wp_unique_term_slug()}.
151 */
152 while ( ! empty( $the_parent ) ) {
153 $parent_term = get_term( $the_parent, $this->taxonomy );
154 if ( ! $parent_term instanceof WP_Term ) {
155 break;
156 }
157 $parent_suffix .= '-' . $parent_term->slug;
158 if ( ! term_exists( $this->slug . $parent_suffix ) ) {
159 break;
160 }
161 $the_parent = $parent_term->parent;
162 }
163
164 return $parent_suffix;
165 }
166
167 /**
168 * Returns the term slug, suffixed or not.
169 *
170 * @since 3.7
171 *
172 * @param string $separator The separator for the slug suffix.
173 * @return string The slug with or without suffix.
174 */
175 public function get_suffixed_slug( string $separator ): string {
176 if ( ! $this->can_add_suffix() ) {
177 return $this->slug;
178 }
179
180 $term_id = (int) $this->model->term_exists_by_slug( $this->slug, $this->lang, $this->taxonomy, $this->parent );
181
182 // If no term exists in the given language with that slug, it can be created, or if we are editing the existing term.
183 if ( ! $term_id || $this->term_id === $term_id ) {
184 return $this->slug . $separator . $this->lang->slug;
185 }
186
187 // Different term exists in same language: no suffix, WordPress will handle uniqueness.
188 return $this->slug;
189 }
190 }
191