PluginProbe ʕ •ᴥ•ʔ
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 24.5
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v24.5
27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 19.1 19.10 19.11 19.12 19.13 19.14 19.2 19.3 19.4 19.5 19.5.1 19.6 19.6.1 19.7 19.7.1 19.7.2 19.8 19.9 20.0 20.1 20.10 20.11 20.12 20.13 20.2 20.2.1 20.3 20.4 20.5 20.6 20.7 20.8 20.9 21.0 21.1 21.2 21.3 21.4 21.5 21.6 21.7 21.8 21.8.1 21.9 21.9.1 22.0 22.1 22.2 22.3 22.4 22.5 22.6 22.7 22.8 22.9 23.0 23.1 23.2 23.3 23.4 23.5 23.6 23.7 23.8 23.9 24.0 24.1 24.2 24.3 24.4 24.5 24.6 24.7 24.8 24.8.1 24.9 25.0 25.1 25.2 25.3 25.3.1 25.4 25.5 25.6 25.7 25.8 25.9 26.0 26.1 26.1.1 26.2 26.3 26.4 26.5 26.6 26.7 26.8 26.9 27.0 27.1 27.1.1 27.2 27.3 27.4
wordpress-seo / admin / class-primary-term-admin.php
wordpress-seo / admin Last commit date
ajax 2 years ago capabilities 1 year ago endpoints 2 years ago exceptions 7 years ago filters 1 year ago formatter 1 year ago google_search_console 2 years ago import 2 years ago listeners 8 years ago menu 1 year ago metabox 1 year ago notifiers 3 years ago pages 1 year ago roles 2 years ago services 5 years ago statistics 2 years ago taxonomy 1 year ago tracking 1 year ago views 1 year ago watchers 2 years ago admin-settings-changed-listener.php 2 years ago ajax.php 2 years ago class-admin-asset-analysis-worker-location.php 5 years ago class-admin-asset-dev-server-location.php 2 years ago class-admin-asset-location.php 8 years ago class-admin-asset-manager.php 1 year ago class-admin-asset-seo-location.php 4 years ago class-admin-editor-specific-replace-vars.php 2 years ago class-admin-gutenberg-compatibility-notification.php 2 years ago class-admin-help-panel.php 5 years ago class-admin-init.php 1 year ago class-admin-recommended-replace-vars.php 2 years ago class-admin-user-profile.php 1 year ago class-admin-utils.php 2 years ago class-admin.php 1 year ago class-asset.php 1 year ago class-bulk-description-editor-list-table.php 5 years ago class-bulk-editor-list-table.php 2 years ago class-bulk-title-editor-list-table.php 6 years ago class-collector.php 2 years ago class-config.php 1 year ago class-database-proxy.php 2 years ago class-export.php 2 years ago class-expose-shortlinks.php 1 year ago class-gutenberg-compatibility.php 1 year ago class-meta-columns.php 1 year ago class-my-yoast-proxy.php 2 years ago class-option-tab.php 4 years ago class-option-tabs-formatter.php 2 years ago class-option-tabs.php 2 years ago class-paper-presenter.php 5 years ago class-plugin-availability.php 1 year ago class-plugin-conflict.php 2 years ago class-premium-popup.php 2 years ago class-premium-upsell-admin-block.php 1 year ago class-primary-term-admin.php 2 years ago class-product-upsell-notice.php 2 years ago class-remote-request.php 2 years ago class-schema-person-upgrade-notification.php 2 years ago class-suggested-plugins.php 2 years ago class-wincher-dashboard-widget.php 2 years ago class-yoast-columns.php 2 years ago class-yoast-dashboard-widget.php 2 years ago class-yoast-form.php 1 year ago class-yoast-input-validation.php 1 year ago class-yoast-network-admin.php 2 years ago class-yoast-network-settings-api.php 4 years ago class-yoast-notification-center.php 1 year ago class-yoast-notification.php 1 year ago class-yoast-notifications.php 2 years ago class-yoast-plugin-conflict.php 2 years ago index.php 10 years ago interface-collection.php 7 years ago interface-installable.php 8 years ago
class-primary-term-admin.php
275 lines
1 <?php
2 /**
3 * WPSEO plugin file.
4 *
5 * @package WPSEO\Admin
6 */
7
8 /**
9 * Adds the UI to change the primary term for a post.
10 */
11 class WPSEO_Primary_Term_Admin implements WPSEO_WordPress_Integration {
12
13 /**
14 * Constructor.
15 *
16 * @return void
17 */
18 public function register_hooks() {
19 add_filter( 'wpseo_content_meta_section_content', [ $this, 'add_input_fields' ] );
20
21 add_action( 'admin_footer', [ $this, 'wp_footer' ], 10 );
22
23 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
24 }
25
26 /**
27 * Gets the current post ID.
28 *
29 * @return int The post ID.
30 */
31 protected function get_current_id() {
32 // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are not processing form information, We are casting to an integer.
33 $post_id = isset( $_GET['post'] ) && is_string( $_GET['post'] ) ? (int) wp_unslash( $_GET['post'] ) : 0;
34
35 if ( $post_id === 0 && isset( $GLOBALS['post_ID'] ) ) {
36 $post_id = (int) $GLOBALS['post_ID'];
37 }
38
39 return $post_id;
40 }
41
42 /**
43 * Adds hidden fields for primary taxonomies.
44 *
45 * @param string $content The metabox content.
46 *
47 * @return string The HTML content.
48 */
49 public function add_input_fields( $content ) {
50 $taxonomies = $this->get_primary_term_taxonomies();
51
52 foreach ( $taxonomies as $taxonomy ) {
53 $content .= $this->primary_term_field( $taxonomy->name );
54 $content .= wp_nonce_field( 'save-primary-term', WPSEO_Meta::$form_prefix . 'primary_' . $taxonomy->name . '_nonce', false, false );
55 }
56 return $content;
57 }
58
59 /**
60 * Generates the HTML for a hidden field for a primary taxonomy.
61 *
62 * @param string $taxonomy_name The taxonomy's slug.
63 *
64 * @return string The HTML for a hidden primary taxonomy field.
65 */
66 protected function primary_term_field( $taxonomy_name ) {
67 return sprintf(
68 '<input class="yoast-wpseo-primary-term" type="hidden" id="%1$s" name="%2$s" value="%3$s" />',
69 esc_attr( $this->generate_field_id( $taxonomy_name ) ),
70 esc_attr( $this->generate_field_name( $taxonomy_name ) ),
71 esc_attr( $this->get_primary_term( $taxonomy_name ) )
72 );
73 }
74
75 /**
76 * Generates an id for a primary taxonomy's hidden field.
77 *
78 * @param string $taxonomy_name The taxonomy's slug.
79 *
80 * @return string The field id.
81 */
82 protected function generate_field_id( $taxonomy_name ) {
83 return 'yoast-wpseo-primary-' . $taxonomy_name;
84 }
85
86 /**
87 * Generates a name for a primary taxonomy's hidden field.
88 *
89 * @param string $taxonomy_name The taxonomy's slug.
90 *
91 * @return string The field id.
92 */
93 protected function generate_field_name( $taxonomy_name ) {
94 return WPSEO_Meta::$form_prefix . 'primary_' . $taxonomy_name . '_term';
95 }
96
97 /**
98 * Adds primary term templates.
99 *
100 * @return void
101 */
102 public function wp_footer() {
103 $taxonomies = $this->get_primary_term_taxonomies();
104
105 if ( ! empty( $taxonomies ) ) {
106 $this->include_js_templates();
107 }
108 }
109
110 /**
111 * Enqueues all the assets needed for the primary term interface.
112 *
113 * @return void
114 */
115 public function enqueue_assets() {
116 global $pagenow;
117
118 if ( ! WPSEO_Metabox::is_post_edit( $pagenow ) ) {
119 return;
120 }
121
122 $taxonomies = $this->get_primary_term_taxonomies();
123
124 // Only enqueue if there are taxonomies that need a primary term.
125 if ( empty( $taxonomies ) ) {
126 return;
127 }
128
129 $asset_manager = new WPSEO_Admin_Asset_Manager();
130 $asset_manager->enqueue_style( 'primary-category' );
131
132 $mapped_taxonomies = $this->get_mapped_taxonomies_for_js( $taxonomies );
133
134 $data = [
135 'taxonomies' => $mapped_taxonomies,
136 ];
137
138 $asset_manager->localize_script( 'post-edit', 'wpseoPrimaryCategoryL10n', $data );
139 $asset_manager->localize_script( 'post-edit-classic', 'wpseoPrimaryCategoryL10n', $data );
140 }
141
142 /**
143 * Gets the id of the primary term.
144 *
145 * @param string $taxonomy_name Taxonomy name for the term.
146 *
147 * @return int primary term id
148 */
149 protected function get_primary_term( $taxonomy_name ) {
150 $primary_term = new WPSEO_Primary_Term( $taxonomy_name, $this->get_current_id() );
151
152 return $primary_term->get_primary_term();
153 }
154
155 /**
156 * Returns all the taxonomies for which the primary term selection is enabled.
157 *
158 * @param int|null $post_id Default current post ID.
159 * @return array
160 */
161 protected function get_primary_term_taxonomies( $post_id = null ) {
162 if ( $post_id === null ) {
163 $post_id = $this->get_current_id();
164 }
165
166 $taxonomies = wp_cache_get( 'primary_term_taxonomies_' . $post_id, 'wpseo' );
167 if ( $taxonomies !== false ) {
168 return $taxonomies;
169 }
170
171 $taxonomies = $this->generate_primary_term_taxonomies( $post_id );
172
173 wp_cache_set( 'primary_term_taxonomies_' . $post_id, $taxonomies, 'wpseo' );
174
175 return $taxonomies;
176 }
177
178 /**
179 * Includes templates file.
180 *
181 * @return void
182 */
183 protected function include_js_templates() {
184 include_once WPSEO_PATH . 'admin/views/js-templates-primary-term.php';
185 }
186
187 /**
188 * Generates the primary term taxonomies.
189 *
190 * @param int $post_id ID of the post.
191 *
192 * @return array
193 */
194 protected function generate_primary_term_taxonomies( $post_id ) {
195 $post_type = get_post_type( $post_id );
196 $all_taxonomies = get_object_taxonomies( $post_type, 'objects' );
197 $all_taxonomies = array_filter( $all_taxonomies, [ $this, 'filter_hierarchical_taxonomies' ] );
198
199 /**
200 * Filters which taxonomies for which the user can choose the primary term.
201 *
202 * @param array $taxonomies An array of taxonomy objects that are primary_term enabled.
203 * @param string $post_type The post type for which to filter the taxonomies.
204 * @param array $all_taxonomies All taxonomies for this post types, even ones that don't have primary term
205 * enabled.
206 */
207 $taxonomies = (array) apply_filters( 'wpseo_primary_term_taxonomies', $all_taxonomies, $post_type, $all_taxonomies );
208
209 return $taxonomies;
210 }
211
212 /**
213 * Creates a map of taxonomies for localization.
214 *
215 * @param array $taxonomies The taxononmies that should be mapped.
216 *
217 * @return array The mapped taxonomies.
218 */
219 protected function get_mapped_taxonomies_for_js( $taxonomies ) {
220 return array_map( [ $this, 'map_taxonomies_for_js' ], $taxonomies );
221 }
222
223 /**
224 * Returns an array suitable for use in the javascript.
225 *
226 * @param stdClass $taxonomy The taxonomy to map.
227 *
228 * @return array The mapped taxonomy.
229 */
230 private function map_taxonomies_for_js( $taxonomy ) {
231 $primary_term = $this->get_primary_term( $taxonomy->name );
232
233 if ( empty( $primary_term ) ) {
234 $primary_term = '';
235 }
236
237 $terms = get_terms(
238 [
239 'taxonomy' => $taxonomy->name,
240 'update_term_meta_cache' => false,
241 'fields' => 'id=>name',
242 ]
243 );
244
245 $mapped_terms_for_js = [];
246 foreach ( $terms as $id => $name ) {
247 $mapped_terms_for_js[] = [
248 'id' => $id,
249 'name' => $name,
250 ];
251 }
252
253 return [
254 'title' => $taxonomy->labels->singular_name,
255 'name' => $taxonomy->name,
256 'primary' => $primary_term,
257 'singularLabel' => $taxonomy->labels->singular_name,
258 'fieldId' => $this->generate_field_id( $taxonomy->name ),
259 'restBase' => ( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name,
260 'terms' => $mapped_terms_for_js,
261 ];
262 }
263
264 /**
265 * Returns whether or not a taxonomy is hierarchical.
266 *
267 * @param stdClass $taxonomy Taxonomy object.
268 *
269 * @return bool
270 */
271 private function filter_hierarchical_taxonomies( $taxonomy ) {
272 return (bool) $taxonomy->hierarchical;
273 }
274 }
275