• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Yoast / wordpress-seo / 04df54d03c4cae059a7cff413a64420a715f62b4

28 May 2024 07:52AM UTC coverage: 52.776% (+0.006%) from 52.77%
04df54d03c4cae059a7cff413a64420a715f62b4

Pull #21361

github

web-flow
Merge c2a553580 into 1ed281fdb
Pull Request #21361: Decouple primary term second round

7363 of 13366 branches covered (55.09%)

Branch coverage included in aggregate %.

44 of 80 new or added lines in 5 files covered. (55.0%)

594 existing lines in 3 files now uncovered.

28354 of 54310 relevant lines covered (52.21%)

41359.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

24.1
/admin/class-primary-term-admin.php
1
<?php
2
/**
3
 * WPSEO plugin file.
4
 *
5
 * @package WPSEO\Admin
6
 */
7

8
use Yoast\WP\SEO\Helpers\Primary_Term_Helper;
9

10
/**
11
 * Adds the UI to change the primary term for a post.
12
 */
13
class WPSEO_Primary_Term_Admin implements WPSEO_WordPress_Integration {
14

15
        /**
16
         * Primary term helper
17
         *
18
         * @var Primary_Term_Helper
19
         */
20
        private $primary_term_helper;
21

22
        /**
23
         * Constructor.
24
         *
25
         * @param Primary_Term_Helper $primary_term_helper Primary term helper.
26
         */
NEW
27
        public function __construct( Primary_Term_Helper $primary_term_helper ) {
×
NEW
28
                $this->primary_term_helper = $primary_term_helper;
×
29
        }
30

31
        /**
32
         * Register hooks.
33
         *
34
         * @return void
35
         */
36
        public function register_hooks() {
×
37
                add_filter( 'wpseo_content_meta_section_content', [ $this, 'add_input_fields' ] );
×
38

39
                add_action( 'admin_footer', [ $this, 'wp_footer' ], 10 );
×
40

41
                add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
×
42
        }
43

44
        /**
45
         * Gets the current post ID.
46
         *
47
         * @return int The post ID.
48
         */
49
        protected function get_current_id() {
×
50
                // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are not processing form information, We are casting to an integer.
51
                $post_id = isset( $_GET['post'] ) && is_string( $_GET['post'] ) ? (int) wp_unslash( $_GET['post'] ) : 0;
×
52

53
                if ( $post_id === 0 && isset( $GLOBALS['post_ID'] ) ) {
×
54
                        $post_id = (int) $GLOBALS['post_ID'];
×
55
                }
56

57
                return $post_id;
×
58
        }
59

60
        /**
61
         * Adds hidden fields for primary taxonomies.
62
         *
63
         * @param string $content The metabox content.
64
         *
65
         * @return string The HTML content.
66
         */
67
        public function add_input_fields( $content ) {
×
68
                $taxonomies = $this->get_primary_term_taxonomies();
×
69

70
                foreach ( $taxonomies as $taxonomy ) {
×
71
                        $content .= $this->primary_term_field( $taxonomy->name );
×
72
                        $content .= wp_nonce_field( 'save-primary-term', WPSEO_Meta::$form_prefix . 'primary_' . $taxonomy->name . '_nonce', false, false );
×
73
                }
74
                return $content;
×
75
        }
76

77
        /**
78
         * Generates the HTML for a hidden field for a primary taxonomy.
79
         *
80
         * @param string $taxonomy_name The taxonomy's slug.
81
         *
82
         * @return string The HTML for a hidden primary taxonomy field.
83
         */
84
        protected function primary_term_field( $taxonomy_name ) {
×
85
                return sprintf(
×
86
                        '<input class="yoast-wpseo-primary-term" type="hidden" id="%1$s" name="%2$s" value="%3$s" />',
×
87
                        esc_attr( $this->generate_field_id( $taxonomy_name ) ),
×
88
                        esc_attr( $this->generate_field_name( $taxonomy_name ) ),
×
89
                        esc_attr( $this->get_primary_term( $taxonomy_name ) )
×
90
                );
91
        }
92

93
        /**
94
         * Generates an id for a primary taxonomy's hidden field.
95
         *
96
         * @param string $taxonomy_name The taxonomy's slug.
97
         *
98
         * @return string The field id.
99
         */
100
        protected function generate_field_id( $taxonomy_name ) {
×
101
                return WPSEO_Meta::$form_prefix . 'primary_' . $taxonomy_name;
×
102
        }
103

104
        /**
105
         * Generates a name for a primary taxonomy's hidden field.
106
         *
107
         * @param string $taxonomy_name The taxonomy's slug.
108
         *
109
         * @return string The field id.
110
         */
111
        protected function generate_field_name( $taxonomy_name ) {
×
112
                return WPSEO_Meta::$form_prefix . 'primary_' . $taxonomy_name . '_term';
×
113
        }
114

115
        /**
116
         * Adds primary term templates.
117
         *
118
         * @return void
119
         */
120
        public function wp_footer() {
8✔
121
                $taxonomies = $this->get_primary_term_taxonomies();
8✔
122

123
                if ( ! empty( $taxonomies ) ) {
8✔
124
                        $this->include_js_templates();
4✔
125
                }
126
        }
4✔
127

128
        /**
129
         * Enqueues all the assets needed for the primary term interface.
130
         *
131
         * @return void
132
         */
133
        public function enqueue_assets() {
12✔
134
                global $pagenow;
12✔
135

136
                if ( ! WPSEO_Metabox::is_post_edit( $pagenow ) ) {
12✔
137
                        return;
8✔
138
                }
139

140
                $taxonomies = $this->get_primary_term_taxonomies();
4✔
141

142
                // Only enqueue if there are taxonomies that need a primary term.
143
                if ( empty( $taxonomies ) ) {
4✔
144
                        return;
×
145
                }
146

147
                $asset_manager = new WPSEO_Admin_Asset_Manager();
4✔
148
                $asset_manager->enqueue_style( 'primary-category' );
4✔
149

150
                $mapped_taxonomies = $this->get_mapped_taxonomies_for_js( $taxonomies );
4✔
151

152
                $data = [
2✔
153
                        'taxonomies' => $mapped_taxonomies,
4✔
154
                ];
2✔
155

156
                $asset_manager->localize_script( 'post-edit', 'wpseoPrimaryCategoryL10n', $data );
4✔
157
                $asset_manager->localize_script( 'post-edit-classic', 'wpseoPrimaryCategoryL10n', $data );
4✔
158
        }
2✔
159

160
        /**
161
         * Gets the id of the primary term.
162
         *
163
         * @param string $taxonomy_name Taxonomy name for the term.
164
         *
165
         * @return int primary term id
166
         */
167
        protected function get_primary_term( $taxonomy_name ) {
×
168
                $primary_term = new WPSEO_Primary_Term( $taxonomy_name, $this->get_current_id() );
×
169

170
                return $primary_term->get_primary_term();
×
171
        }
172

173
        /**
174
         * Returns all the taxonomies for which the primary term selection is enabled.
175
         *
176
         * @param int|null $post_id Default current post ID.
177
         * @return array<WP_Taxonomy> The primary term taxonomies.
178
         */
179
        protected function get_primary_term_taxonomies( $post_id = null ) {
×
180
                if ( $post_id === null ) {
×
181
                        $post_id = $this->get_current_id();
×
182
                }
183

184
                $taxonomies = wp_cache_get( 'primary_term_taxonomies_' . $post_id, 'wpseo' );
×
185
                if ( $taxonomies !== false ) {
×
186
                        return $taxonomies;
×
187
                }
188

NEW
189
                $taxonomies = $this->primary_term_helper->get_primary_term_taxonomies( $post_id );
×
190

191
                wp_cache_set( 'primary_term_taxonomies_' . $post_id, $taxonomies, 'wpseo' );
×
192

193
                return $taxonomies;
×
194
        }
195

196
        /**
197
         * Includes templates file.
198
         *
199
         * @return void
200
         */
201
        protected function include_js_templates() {
×
202
                include_once WPSEO_PATH . 'admin/views/js-templates-primary-term.php';
×
203
        }
204

205
        /**
206
         * Creates a map of taxonomies for localization.
207
         *
208
         * @param array<WP_Taxonomy> $taxonomies The taxonomies that should be mapped.
209
         *
210
         * @return array<string,array<string|int|array<int|string>>> The mapped taxonomies.
211
         */
212
        protected function get_mapped_taxonomies_for_js( $taxonomies ) {
×
213
                return array_map( [ $this, 'map_taxonomies_for_js' ], $taxonomies );
×
214
        }
215

216
        /**
217
         * Returns an array suitable for use in the javascript.
218
         *
219
         * @param stdClass $taxonomy The taxonomy to map.
220
         *
221
         * @return array<string|int|array<int|string>> The mapped taxonomy.
222
         */
223
        private function map_taxonomies_for_js( $taxonomy ) {
×
224
                $primary_term = $this->get_primary_term( $taxonomy->name );
×
225

226
                if ( empty( $primary_term ) ) {
×
227
                        $primary_term = '';
×
228
                }
229

230
                $terms = get_terms(
×
231
                        [
232
                                'taxonomy'               => $taxonomy->name,
×
233
                                'update_term_meta_cache' => false,
234
                                'fields'                 => 'id=>name',
×
235
                        ]
236
                );
237

238
                $mapped_terms_for_js = [];
×
239
                foreach ( $terms as $id => $name ) {
×
240
                        $mapped_terms_for_js[] = [
×
241
                                'id'   => $id,
×
242
                                'name' => $name,
×
243
                        ];
244
                }
245

246
                return [
247
                        'title'         => $taxonomy->labels->singular_name,
×
248
                        'name'          => $taxonomy->name,
×
249
                        'primary'       => $primary_term,
×
250
                        'singularLabel' => $taxonomy->labels->singular_name,
×
NEW
251
                        'fieldId'       => WPSEO_Meta::$form_prefix . 'primary_' . $taxonomy->name,
×
252
                        'restBase'      => ( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name,
×
253
                        'terms'         => $mapped_terms_for_js,
×
254
                ];
255
        }
256
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc