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

Yoast / wordpress-seo / 6987097851

25 Nov 2023 04:49AM UTC coverage: 49.206% (-0.1%) from 49.302%
6987097851

push

github

web-flow
Merge pull request #20878 from Yoast/JRF/ghactions-minor-tweak

GH Actions: update a few links in inline comments

15305 of 31104 relevant lines covered (49.21%)

4.03 hits per line

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

69.52
/src/integrations/third-party/woocommerce.php
1
<?php
2

3
namespace Yoast\WP\SEO\Integrations\Third_Party;
4

5
use WPSEO_Replace_Vars;
6
use Yoast\WP\SEO\Conditionals\Front_End_Conditional;
7
use Yoast\WP\SEO\Conditionals\WooCommerce_Conditional;
8
use Yoast\WP\SEO\Helpers\Options_Helper;
9
use Yoast\WP\SEO\Helpers\Pagination_Helper;
10
use Yoast\WP\SEO\Helpers\Woocommerce_Helper;
11
use Yoast\WP\SEO\Integrations\Integration_Interface;
12
use Yoast\WP\SEO\Memoizers\Meta_Tags_Context_Memoizer;
13
use Yoast\WP\SEO\Models\Indexable;
14
use Yoast\WP\SEO\Presentations\Indexable_Presentation;
15
use Yoast\WP\SEO\Repositories\Indexable_Repository;
16

17
/**
18
 * WooCommerce integration.
19
 */
20
class WooCommerce implements Integration_Interface {
21

22
        /**
23
         * The options helper.
24
         *
25
         * @var Options_Helper
26
         */
27
        private $options;
28

29
        /**
30
         * The WPSEO Replace Vars object.
31
         *
32
         * @var WPSEO_Replace_Vars
33
         */
34
        private $replace_vars;
35

36
        /**
37
         * The memoizer for the meta tags context.
38
         *
39
         * @var Meta_Tags_Context_Memoizer
40
         */
41
        protected $context_memoizer;
42

43
        /**
44
         * The indexable repository.
45
         *
46
         * @var Indexable_Repository
47
         */
48
        private $repository;
49

50
        /**
51
         * The pagination helper.
52
         *
53
         * @var Pagination_Helper
54
         */
55
        protected $pagination_helper;
56

57
        /**
58
         * The WooCommerce helper.
59
         *
60
         * @var Woocommerce_Helper
61
         */
62
        private $woocommerce_helper;
63

64
        /**
65
         * Returns the conditionals based in which this loadable should be active.
66
         *
67
         * @return array
68
         */
69
        public static function get_conditionals() {
2✔
70
                return [ WooCommerce_Conditional::class, Front_End_Conditional::class ];
2✔
71
        }
72

73
        /**
74
         * WooCommerce constructor.
75
         *
76
         * @param Options_Helper             $options            The options helper.
77
         * @param WPSEO_Replace_Vars         $replace_vars       The replace vars helper.
78
         * @param Meta_Tags_Context_Memoizer $context_memoizer   The meta tags context memoizer.
79
         * @param Indexable_Repository       $repository         The indexable repository.
80
         * @param Pagination_Helper          $pagination_helper  The paginataion helper.
81
         * @param Woocommerce_Helper         $woocommerce_helper The WooCommerce helper.
82
         */
83
        public function __construct(
2✔
84
                Options_Helper $options,
85
                WPSEO_Replace_Vars $replace_vars,
86
                Meta_Tags_Context_Memoizer $context_memoizer,
87
                Indexable_Repository $repository,
88
                Pagination_Helper $pagination_helper,
89
                Woocommerce_Helper $woocommerce_helper
90
        ) {
1✔
91
                $this->options            = $options;
2✔
92
                $this->replace_vars       = $replace_vars;
2✔
93
                $this->context_memoizer   = $context_memoizer;
2✔
94
                $this->repository         = $repository;
2✔
95
                $this->pagination_helper  = $pagination_helper;
2✔
96
                $this->woocommerce_helper = $woocommerce_helper;
2✔
97
        }
1✔
98

99
        /**
100
         * Initializes the integration.
101
         *
102
         * This is the place to register hooks and filters.
103
         *
104
         * @return void
105
         */
106
        public function register_hooks() {
2✔
107
                \add_filter( 'wpseo_frontend_page_type_simple_page_id', [ $this, 'get_page_id' ] );
2✔
108
                \add_filter( 'wpseo_breadcrumb_indexables', [ $this, 'add_shop_to_breadcrumbs' ] );
2✔
109

110
                \add_filter( 'wpseo_title', [ $this, 'title' ], 10, 2 );
2✔
111
                \add_filter( 'wpseo_metadesc', [ $this, 'description' ], 10, 2 );
2✔
112
                \add_filter( 'wpseo_canonical', [ $this, 'canonical' ], 10, 2 );
2✔
113
                \add_filter( 'wpseo_adjacent_rel_url', [ $this, 'adjacent_rel_url' ], 10, 3 );
2✔
114
        }
1✔
115

116
        /**
117
         * Returns the correct canonical when WooCommerce is enabled.
118
         *
119
         * @param string                      $canonical    The current canonical.
120
         * @param Indexable_Presentation|null $presentation The indexable presentation.
121
         *
122
         * @return string The correct canonical.
123
         */
124
        public function canonical( $canonical, $presentation = null ) {
8✔
125
                if ( ! $this->woocommerce_helper->is_shop_page() ) {
8✔
126
                        return $canonical;
2✔
127
                }
128

129
                $url = $this->get_shop_paginated_link( 'curr', $presentation );
6✔
130

131
                if ( $url ) {
6✔
132
                        return $url;
4✔
133
                }
134

135
                return $canonical;
2✔
136
        }
137

138
        /**
139
         * Returns correct adjacent pages when WooCommerce is enabled.
140
         *
141
         * @param string                      $link         The current link.
142
         * @param string                      $rel          Link relationship, prev or next.
143
         * @param Indexable_Presentation|null $presentation The indexable presentation.
144
         *
145
         * @return string The correct link.
146
         */
147
        public function adjacent_rel_url( $link, $rel, $presentation = null ) {
×
148
                if ( ! $this->woocommerce_helper->is_shop_page() ) {
×
149
                        return $link;
×
150
                }
151

152
                if ( $rel !== 'next' && $rel !== 'prev' ) {
×
153
                        return $link;
×
154
                }
155

156
                $url = $this->get_shop_paginated_link( $rel, $presentation );
×
157

158
                if ( $url ) {
×
159
                        return $url;
×
160
                }
161

162
                return $link;
×
163
        }
164

165
        /**
166
         * Adds a breadcrumb for the shop page.
167
         *
168
         * @param Indexable[] $indexables The array with indexables.
169
         *
170
         * @return Indexable[] The indexables to be shown in the breadcrumbs, with the shop page added.
171
         */
172
        public function add_shop_to_breadcrumbs( $indexables ) {
4✔
173
                $shop_page_id = $this->woocommerce_helper->get_shop_page_id();
4✔
174

175
                if ( ! \is_int( $shop_page_id ) || $shop_page_id < 1 ) {
4✔
176
                        return $indexables;
×
177
                }
178

179
                foreach ( $indexables as $index => $indexable ) {
4✔
180
                        if ( $indexable->object_type === 'post-type-archive' && $indexable->object_sub_type === 'product' ) {
4✔
181
                                $shop_page_indexable = $this->repository->find_by_id_and_type( $shop_page_id, 'post' );
4✔
182
                                if ( \is_a( $shop_page_indexable, Indexable::class ) ) {
4✔
183
                                        $indexables[ $index ] = $shop_page_indexable;
2✔
184
                                }
185
                        }
186
                }
187

188
                return $indexables;
4✔
189
        }
190

191
        /**
192
         * Returns the ID of the WooCommerce shop page when the currently opened page is the shop page.
193
         *
194
         * @param int $page_id The page id.
195
         *
196
         * @return int The Page ID of the shop.
197
         */
198
        public function get_page_id( $page_id ) {
6✔
199
                if ( ! $this->woocommerce_helper->is_shop_page() ) {
6✔
200
                        return $page_id;
2✔
201
                }
202

203
                return $this->woocommerce_helper->get_shop_page_id();
4✔
204
        }
205

206
        /**
207
         * Handles the title.
208
         *
209
         * @param string                      $title        The title.
210
         * @param Indexable_Presentation|null $presentation The indexable presentation.
211
         *
212
         * @return string The title to use.
213
         */
214
        public function title( $title, $presentation = null ) {
14✔
215
                $presentation = $this->ensure_presentation( $presentation );
14✔
216

217
                if ( $presentation->model->title ) {
14✔
218
                        return $title;
2✔
219
                }
220

221
                if ( ! $this->woocommerce_helper->is_shop_page() ) {
12✔
222
                        return $title;
2✔
223
                }
224

225
                if ( ! \is_archive() ) {
10✔
226
                        return $title;
2✔
227
                }
228

229
                $shop_page_id = $this->woocommerce_helper->get_shop_page_id();
8✔
230
                if ( $shop_page_id < 1 ) {
8✔
231
                        return $title;
2✔
232
                }
233

234
                $product_template_title = $this->get_product_template( 'title-product', $shop_page_id );
6✔
235
                if ( $product_template_title ) {
6✔
236
                        return $product_template_title;
4✔
237
                }
238

239
                return $title;
2✔
240
        }
241

242
        /**
243
         * Handles the meta description.
244
         *
245
         * @param string                      $description  The title.
246
         * @param Indexable_Presentation|null $presentation The indexable presentation.
247
         *
248
         * @return string The description to use.
249
         */
250
        public function description( $description, $presentation = null ) {
14✔
251
                $presentation = $this->ensure_presentation( $presentation );
14✔
252

253
                if ( $presentation->model->description ) {
14✔
254
                        return $description;
2✔
255
                }
256

257
                if ( ! $this->woocommerce_helper->is_shop_page() ) {
12✔
258
                        return $description;
2✔
259
                }
260

261
                if ( ! \is_archive() ) {
10✔
262
                        return $description;
2✔
263
                }
264

265
                $shop_page_id = $this->woocommerce_helper->get_shop_page_id();
8✔
266
                if ( $shop_page_id < 1 ) {
8✔
267
                        return $description;
2✔
268
                }
269

270
                $product_template_description = $this->get_product_template( 'metadesc-product', $shop_page_id );
6✔
271
                if ( $product_template_description ) {
6✔
272
                        return $product_template_description;
4✔
273
                }
274

275
                return $description;
2✔
276
        }
277

278
        /**
279
         * Uses template for the given option name and replace the replacement variables on it.
280
         *
281
         * @param string $option_name  The option name to get the template for.
282
         * @param string $shop_page_id The page id to retrieve template for.
283
         *
284
         * @return string The rendered value.
285
         */
286
        protected function get_product_template( $option_name, $shop_page_id ) {
4✔
287
                $template = $this->options->get( $option_name );
4✔
288
                $page     = \get_post( $shop_page_id );
4✔
289

290
                return $this->replace_vars->replace( $template, $page );
4✔
291
        }
292

293
        /**
294
         * Get paginated link for shop page.
295
         *
296
         * @param string                      $rel          Link relationship, prev or next or curr.
297
         * @param Indexable_Presentation|null $presentation The indexable presentation.
298
         *
299
         * @return string|null The link.
300
         */
301
        protected function get_shop_paginated_link( $rel, $presentation = null ) {
×
302
                $presentation = $this->ensure_presentation( $presentation );
×
303

304
                $permalink = $presentation->permalink;
×
305
                if ( ! $permalink ) {
×
306
                        return null;
×
307
                }
308

309
                $current_page = \max( 1, $this->pagination_helper->get_current_archive_page_number() );
×
310

311
                if ( $rel === 'curr' && $current_page === 1 ) {
×
312
                        return $permalink;
×
313
                }
314

315
                if ( $rel === 'curr' && $current_page > 1 ) {
×
316
                        return $this->pagination_helper->get_paginated_url( $permalink, $current_page );
×
317
                }
318

319
                if ( $rel === 'prev' && $current_page === 2 ) {
×
320
                        return $permalink;
×
321
                }
322

323
                if ( $rel === 'prev' && $current_page > 2 ) {
×
324
                        return $this->pagination_helper->get_paginated_url( $permalink, ( $current_page - 1 ) );
×
325
                }
326

327
                if ( $rel === 'next' && $current_page < $this->pagination_helper->get_number_of_archive_pages() ) {
×
328
                        return $this->pagination_helper->get_paginated_url( $permalink, ( $current_page + 1 ) );
×
329
                }
330

331
                return null;
×
332
        }
333

334
        /**
335
         * Ensures a presentation is available.
336
         *
337
         * @param Indexable_Presentation $presentation The indexable presentation.
338
         *
339
         * @return Indexable_Presentation The presentation, taken from the current page if the input was invalid.
340
         */
341
        protected function ensure_presentation( $presentation ) {
×
342
                if ( \is_a( $presentation, Indexable_Presentation::class ) ) {
×
343
                        return $presentation;
×
344
                }
345

346
                $context = $this->context_memoizer->for_current_page();
×
347

348
                return $context->presentation;
×
349
        }
350
}
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