PluginProbe ʕ •ᴥ•ʔ
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 27.5
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v27.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 3 months ago filters 3 months ago formatter 1 year ago google_search_console 3 months ago import 3 months ago listeners 8 years ago menu 3 months ago metabox 3 months ago notifiers 3 months ago pages 3 months ago roles 3 months ago services 3 months ago statistics 3 months ago taxonomy 3 months ago tracking 3 months ago views 3 months ago watchers 3 months ago admin-settings-changed-listener.php 2 years ago ajax.php 3 months ago class-admin-asset-analysis-worker-location.php 3 months ago class-admin-asset-dev-server-location.php 3 months ago class-admin-asset-location.php 8 years ago class-admin-asset-manager.php 3 months ago class-admin-asset-seo-location.php 4 years ago class-admin-editor-specific-replace-vars.php 3 months ago class-admin-gutenberg-compatibility-notification.php 3 months ago class-admin-help-panel.php 3 months ago class-admin-init.php 3 months ago class-admin-recommended-replace-vars.php 2 years ago class-admin-user-profile.php 7 months ago class-admin-utils.php 3 months ago class-admin.php 3 months ago class-asset.php 1 year ago class-bulk-description-editor-list-table.php 3 months ago class-bulk-editor-list-table.php 3 months ago class-bulk-title-editor-list-table.php 3 months ago class-collector.php 1 year ago class-config.php 3 months ago class-database-proxy.php 3 months ago class-export.php 3 months ago class-expose-shortlinks.php 7 months ago class-gutenberg-compatibility.php 1 month ago class-meta-columns.php 3 months ago class-my-yoast-proxy.php 3 months ago class-option-tab.php 4 years ago class-option-tabs-formatter.php 3 months ago class-option-tabs.php 2 years ago class-paper-presenter.php 5 years ago class-plugin-availability.php 3 months ago class-plugin-conflict.php 2 years ago class-premium-popup.php 1 year ago class-premium-upsell-admin-block.php 3 months ago class-primary-term-admin.php 3 months ago class-product-upsell-notice.php 3 months ago class-remote-request.php 2 years ago class-schema-person-upgrade-notification.php 3 months ago class-suggested-plugins.php 3 months ago class-wincher-dashboard-widget.php 3 months ago class-yoast-columns.php 3 months ago class-yoast-dashboard-widget.php 3 months ago class-yoast-form.php 3 months ago class-yoast-input-validation.php 3 months ago class-yoast-network-admin.php 3 months ago class-yoast-network-settings-api.php 3 months ago class-yoast-notification-center.php 3 months ago class-yoast-notification.php 3 months ago class-yoast-notifications.php 3 months ago class-yoast-plugin-conflict.php 3 months ago index.php 10 years ago interface-collection.php 7 years ago interface-installable.php 8 years ago
class-primary-term-admin.php
273 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 $post_id ??= $this->get_current_id();
163
164 $taxonomies = wp_cache_get( 'primary_term_taxonomies_' . $post_id, 'wpseo' );
165 if ( $taxonomies !== false ) {
166 return $taxonomies;
167 }
168
169 $taxonomies = $this->generate_primary_term_taxonomies( $post_id );
170
171 wp_cache_set( 'primary_term_taxonomies_' . $post_id, $taxonomies, 'wpseo' );
172
173 return $taxonomies;
174 }
175
176 /**
177 * Includes templates file.
178 *
179 * @return void
180 */
181 protected function include_js_templates() {
182 include_once WPSEO_PATH . 'admin/views/js-templates-primary-term.php';
183 }
184
185 /**
186 * Generates the primary term taxonomies.
187 *
188 * @param int $post_id ID of the post.
189 *
190 * @return array
191 */
192 protected function generate_primary_term_taxonomies( $post_id ) {
193 $post_type = get_post_type( $post_id );
194 $all_taxonomies = get_object_taxonomies( $post_type, 'objects' );
195 $all_taxonomies = array_filter( $all_taxonomies, [ $this, 'filter_hierarchical_taxonomies' ] );
196
197 /**
198 * Filters which taxonomies for which the user can choose the primary term.
199 *
200 * @param array $taxonomies An array of taxonomy objects that are primary_term enabled.
201 * @param string $post_type The post type for which to filter the taxonomies.
202 * @param array $all_taxonomies All taxonomies for this post types, even ones that don't have primary term
203 * enabled.
204 */
205 $taxonomies = (array) apply_filters( 'wpseo_primary_term_taxonomies', $all_taxonomies, $post_type, $all_taxonomies );
206
207 return $taxonomies;
208 }
209
210 /**
211 * Creates a map of taxonomies for localization.
212 *
213 * @param array $taxonomies The taxononmies that should be mapped.
214 *
215 * @return array The mapped taxonomies.
216 */
217 protected function get_mapped_taxonomies_for_js( $taxonomies ) {
218 return array_map( [ $this, 'map_taxonomies_for_js' ], $taxonomies );
219 }
220
221 /**
222 * Returns an array suitable for use in the javascript.
223 *
224 * @param stdClass $taxonomy The taxonomy to map.
225 *
226 * @return array The mapped taxonomy.
227 */
228 private function map_taxonomies_for_js( $taxonomy ) {
229 $primary_term = $this->get_primary_term( $taxonomy->name );
230
231 if ( empty( $primary_term ) ) {
232 $primary_term = '';
233 }
234
235 $terms = get_terms(
236 [
237 'taxonomy' => $taxonomy->name,
238 'update_term_meta_cache' => false,
239 'fields' => 'id=>name',
240 ],
241 );
242
243 $mapped_terms_for_js = [];
244 foreach ( $terms as $id => $name ) {
245 $mapped_terms_for_js[] = [
246 'id' => $id,
247 'name' => $name,
248 ];
249 }
250
251 return [
252 'title' => $taxonomy->labels->singular_name,
253 'name' => $taxonomy->name,
254 'primary' => $primary_term,
255 'singularLabel' => $taxonomy->labels->singular_name,
256 'fieldId' => $this->generate_field_id( $taxonomy->name ),
257 'restBase' => ( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name,
258 'terms' => $mapped_terms_for_js,
259 ];
260 }
261
262 /**
263 * Returns whether or not a taxonomy is hierarchical.
264 *
265 * @param stdClass $taxonomy Taxonomy object.
266 *
267 * @return bool
268 */
269 private function filter_hierarchical_taxonomies( $taxonomy ) {
270 return (bool) $taxonomy->hierarchical;
271 }
272 }
273