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

Yoast / wordpress-seo / 56db0408fe2a0dbffe1c2c6cfad9b5c2f6941e34

14 Apr 2025 12:24PM UTC coverage: 52.454% (-2.1%) from 54.594%
56db0408fe2a0dbffe1c2c6cfad9b5c2f6941e34

Pull #22077

github

enricobattocchi
Adjust carryforward in Coveralls action
Pull Request #22077: Drop compatibility with PHP 7.2 and 7.3

7827 of 13877 branches covered (56.4%)

Branch coverage included in aggregate %.

29025 of 56379 relevant lines covered (51.48%)

42277.18 hits per line

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

83.42
/src/presentations/indexable-presentation.php
1
<?php
2

3
namespace Yoast\WP\SEO\Presentations;
4

5
use Yoast\WP\SEO\Context\Meta_Tags_Context;
6
use Yoast\WP\SEO\Generators\Breadcrumbs_Generator;
7
use Yoast\WP\SEO\Generators\Open_Graph_Image_Generator;
8
use Yoast\WP\SEO\Generators\Open_Graph_Locale_Generator;
9
use Yoast\WP\SEO\Generators\Schema_Generator;
10
use Yoast\WP\SEO\Generators\Twitter_Image_Generator;
11
use Yoast\WP\SEO\Helpers\Current_Page_Helper;
12
use Yoast\WP\SEO\Helpers\Image_Helper;
13
use Yoast\WP\SEO\Helpers\Indexable_Helper;
14
use Yoast\WP\SEO\Helpers\Open_Graph\Values_Helper;
15
use Yoast\WP\SEO\Helpers\Options_Helper;
16
use Yoast\WP\SEO\Helpers\Permalink_Helper;
17
use Yoast\WP\SEO\Helpers\Url_Helper;
18
use Yoast\WP\SEO\Helpers\User_Helper;
19
use Yoast\WP\SEO\Models\Indexable;
20

21
/**
22
 * Class Indexable_Presentation.
23
 *
24
 * Presentation object for indexables.
25
 *
26
 * @property string       $title
27
 * @property string       $meta_description
28
 * @property array        $robots
29
 * @property string       $canonical
30
 * @property string       $rel_next
31
 * @property string       $rel_prev
32
 * @property string       $open_graph_type
33
 * @property string       $open_graph_title
34
 * @property string       $open_graph_description
35
 * @property array        $open_graph_images
36
 * @property int          $open_graph_image_id
37
 * @property string       $open_graph_image
38
 * @property string       $open_graph_url
39
 * @property string       $open_graph_site_name
40
 * @property string       $open_graph_article_publisher
41
 * @property string       $open_graph_article_author
42
 * @property string       $open_graph_article_published_time
43
 * @property string       $open_graph_article_modified_time
44
 * @property string       $open_graph_locale
45
 * @property string       $open_graph_fb_app_id
46
 * @property string       $permalink
47
 * @property array        $schema
48
 * @property string       $twitter_card
49
 * @property string       $twitter_title
50
 * @property string       $twitter_description
51
 * @property string       $twitter_image
52
 * @property string       $twitter_creator
53
 * @property string       $twitter_site
54
 * @property object|array $source
55
 * @property array        $breadcrumbs
56
 * @property int          $estimated_reading_time_minutes
57
 * @property array        $googlebot
58
 * @property array        $bingbot
59
 */
60
class Indexable_Presentation extends Abstract_Presentation {
61

62
        /**
63
         * The indexable.
64
         *
65
         * @var Indexable
66
         */
67
        public $model;
68

69
        /**
70
         * The meta tags context.
71
         *
72
         * @var Meta_Tags_Context
73
         */
74
        public $context;
75

76
        /**
77
         * The Schema generator.
78
         *
79
         * @var Schema_Generator
80
         */
81
        protected $schema_generator;
82

83
        /**
84
         * The Open Graph image generator.
85
         *
86
         * @var Open_Graph_Image_Generator
87
         */
88
        protected $open_graph_image_generator;
89

90
        /**
91
         * The Twitter image generator.
92
         *
93
         * @var Twitter_Image_Generator
94
         */
95
        protected $twitter_image_generator;
96

97
        /**
98
         * The Open Graph locale generator.
99
         *
100
         * @var Open_Graph_Locale_Generator
101
         */
102
        private $open_graph_locale_generator;
103

104
        /**
105
         * The breadcrumbs generator.
106
         *
107
         * @var Breadcrumbs_Generator
108
         */
109
        private $breadcrumbs_generator;
110

111
        /**
112
         * The current page helper.
113
         *
114
         * @var Current_Page_Helper
115
         */
116
        protected $current_page;
117

118
        /**
119
         * The image helper.
120
         *
121
         * @var Image_Helper
122
         */
123
        protected $image;
124

125
        /**
126
         * The options helper.
127
         *
128
         * @var Options_Helper
129
         */
130
        protected $options;
131

132
        /**
133
         * The URL helper.
134
         *
135
         * @var Url_Helper
136
         */
137
        protected $url;
138

139
        /**
140
         * The user helper.
141
         *
142
         * @var User_Helper
143
         */
144
        protected $user;
145

146
        /**
147
         * The indexable helper.
148
         *
149
         * @var Indexable_Helper
150
         */
151
        protected $indexable_helper;
152

153
        /**
154
         * The permalink helper.
155
         *
156
         * @var Permalink_Helper
157
         */
158
        protected $permalink_helper;
159

160
        /**
161
         * The values helper.
162
         *
163
         * @var Values_Helper
164
         */
165
        protected $values_helper;
166

167
        /**
168
         * Sets the generator dependencies.
169
         *
170
         * @required
171
         *
172
         * @param Schema_Generator            $schema_generator            The schema generator.
173
         * @param Open_Graph_Locale_Generator $open_graph_locale_generator The Open Graph locale generator.
174
         * @param Open_Graph_Image_Generator  $open_graph_image_generator  The Open Graph image generator.
175
         * @param Twitter_Image_Generator     $twitter_image_generator     The Twitter image generator.
176
         * @param Breadcrumbs_Generator       $breadcrumbs_generator       The breadcrumbs generator.
177
         *
178
         * @return void
179
         */
180
        public function set_generators(
×
181
                Schema_Generator $schema_generator,
182
                Open_Graph_Locale_Generator $open_graph_locale_generator,
183
                Open_Graph_Image_Generator $open_graph_image_generator,
184
                Twitter_Image_Generator $twitter_image_generator,
185
                Breadcrumbs_Generator $breadcrumbs_generator
186
        ) {
187
                $this->schema_generator            = $schema_generator;
×
188
                $this->open_graph_locale_generator = $open_graph_locale_generator;
×
189
                $this->open_graph_image_generator  = $open_graph_image_generator;
×
190
                $this->twitter_image_generator     = $twitter_image_generator;
×
191
                $this->breadcrumbs_generator       = $breadcrumbs_generator;
×
192
        }
193

194
        /**
195
         * Used by dependency injection container to inject the helpers.
196
         *
197
         * @required
198
         *
199
         * @param Image_Helper        $image        The image helper.
200
         * @param Options_Helper      $options      The options helper.
201
         * @param Current_Page_Helper $current_page The current page helper.
202
         * @param Url_Helper          $url          The URL helper.
203
         * @param User_Helper         $user         The user helper.
204
         * @param Indexable_Helper    $indexable    The indexable helper.
205
         * @param Permalink_Helper    $permalink    The permalink helper.
206
         * @param Values_Helper       $values       The values helper.
207
         *
208
         * @return void
209
         */
210
        public function set_helpers(
×
211
                Image_Helper $image,
212
                Options_Helper $options,
213
                Current_Page_Helper $current_page,
214
                Url_Helper $url,
215
                User_Helper $user,
216
                Indexable_Helper $indexable,
217
                Permalink_Helper $permalink,
218
                Values_Helper $values
219
        ) {
220
                $this->image            = $image;
×
221
                $this->options          = $options;
×
222
                $this->current_page     = $current_page;
×
223
                $this->url              = $url;
×
224
                $this->user             = $user;
×
225
                $this->indexable_helper = $indexable;
×
226
                $this->permalink_helper = $permalink;
×
227
                $this->values_helper    = $values;
×
228
        }
229

230
        /**
231
         * Gets the permalink from the indexable or generates it if dynamic permalinks are enabled.
232
         *
233
         * @return string The permalink.
234
         */
235
        public function generate_permalink() {
6✔
236
                if ( $this->indexable_helper->dynamic_permalinks_enabled() ) {
6✔
237
                        return $this->permalink_helper->get_permalink_for_indexable( $this->model );
2✔
238
                }
239

240
                if ( \is_date() ) {
4✔
241
                        return $this->current_page->get_date_archive_permalink();
×
242
                }
243

244
                if ( \is_attachment() ) {
4✔
245
                        global $wp;
×
246
                        return \trailingslashit( \home_url( $wp->request ) );
×
247
                }
248

249
                return $this->model->permalink;
4✔
250
        }
251

252
        /**
253
         * Generates the title.
254
         *
255
         * @return string The title.
256
         */
257
        public function generate_title() {
4✔
258
                if ( $this->model->title ) {
4✔
259
                        return $this->model->title;
2✔
260
                }
261

262
                return '';
2✔
263
        }
264

265
        /**
266
         * Generates the meta description.
267
         *
268
         * @return string The meta description.
269
         */
270
        public function generate_meta_description() {
4✔
271
                if ( $this->model->description ) {
4✔
272
                        return $this->model->description;
2✔
273
                }
274

275
                return '';
2✔
276
        }
277

278
        /**
279
         * Generates the robots value.
280
         *
281
         * @return array The robots value.
282
         */
283
        public function generate_robots() {
10✔
284
                $robots = $this->get_base_robots();
10✔
285

286
                return $this->filter_robots( $robots );
10✔
287
        }
288

289
        /**
290
         * Gets the base robots value.
291
         *
292
         * @return array The base robots value.
293
         */
294
        protected function get_base_robots() {
10✔
295
                return [
10✔
296
                        'index'             => ( $this->model->is_robots_noindex === true ) ? 'noindex' : 'index',
10✔
297
                        'follow'            => ( $this->model->is_robots_nofollow === true ) ? 'nofollow' : 'follow',
10✔
298
                        'max-snippet'       => 'max-snippet:-1',
10✔
299
                        'max-image-preview' => 'max-image-preview:large',
10✔
300
                        'max-video-preview' => 'max-video-preview:-1',
10✔
301
                ];
10✔
302
        }
303

304
        /**
305
         * Run the robots output content through the `wpseo_robots` filter.
306
         *
307
         * @param array $robots The meta robots values to filter.
308
         *
309
         * @return array The filtered meta robots values.
310
         */
311
        protected function filter_robots( $robots ) {
10✔
312
                // Remove values that are only listened to when indexing.
313
                if ( $robots['index'] === 'noindex' ) {
10✔
314
                        $robots['imageindex']        = null;
2✔
315
                        $robots['archive']           = null;
2✔
316
                        $robots['snippet']           = null;
2✔
317
                        $robots['max-snippet']       = null;
2✔
318
                        $robots['max-image-preview'] = null;
2✔
319
                        $robots['max-video-preview'] = null;
2✔
320
                }
321

322
                $robots_string = \implode( ', ', \array_filter( $robots ) );
10✔
323

324
                /**
325
                 * Filter: 'wpseo_robots' - Allows filtering of the meta robots output of Yoast SEO.
326
                 *
327
                 * @param string                 $robots       The meta robots directives to be echoed.
328
                 * @param Indexable_Presentation $presentation The presentation of an indexable.
329
                 */
330
                $robots_filtered = \apply_filters( 'wpseo_robots', $robots_string, $this );
10✔
331

332
                // Convert the robots string back to an array.
333
                if ( \is_string( $robots_filtered ) ) {
10✔
334
                        $robots_values = \explode( ', ', $robots_filtered );
10✔
335
                        $robots_new    = [];
10✔
336

337
                        foreach ( $robots_values as $value ) {
10✔
338
                                $key = $value;
10✔
339

340
                                // Change `noindex` to `index.
341
                                if ( \strpos( $key, 'no' ) === 0 ) {
10✔
342
                                        $key = \substr( $value, 2 );
6✔
343
                                }
344
                                // Change `max-snippet:-1` to `max-snippet`.
345
                                $colon_position = \strpos( $key, ':' );
10✔
346
                                if ( $colon_position !== false ) {
10✔
347
                                        $key = \substr( $value, 0, $colon_position );
4✔
348
                                }
349

350
                                $robots_new[ $key ] = $value;
10✔
351
                        }
352

353
                        $robots = $robots_new;
10✔
354
                }
355

356
                if ( \is_bool( $robots_filtered ) && ( $robots_filtered === false ) ) {
10✔
357
                        return [
×
358
                                'index'  => 'noindex',
×
359
                                'follow' => 'nofollow',
×
360
                        ];
×
361
                }
362

363
                if ( ! $robots_filtered ) {
10✔
364
                        return [];
×
365
                }
366

367
                /**
368
                 * Filter: 'wpseo_robots_array' - Allows filtering of the meta robots output array of Yoast SEO.
369
                 *
370
                 * @param array                  $robots       The meta robots directives to be used.
371
                 * @param Indexable_Presentation $presentation The presentation of an indexable.
372
                 */
373
                return \apply_filters( 'wpseo_robots_array', \array_filter( $robots ), $this );
10✔
374
        }
375

376
        /**
377
         * Generates the canonical.
378
         *
379
         * @return string The canonical.
380
         */
381
        public function generate_canonical() {
12✔
382
                if ( $this->model->canonical ) {
12✔
383
                        return $this->model->canonical;
2✔
384
                }
385

386
                if ( $this->permalink ) {
10✔
387
                        return $this->permalink;
8✔
388
                }
389

390
                return '';
2✔
391
        }
392

393
        /**
394
         * Generates the rel prev.
395
         *
396
         * @return string The rel prev value.
397
         */
398
        public function generate_rel_prev() {
2✔
399
                return '';
2✔
400
        }
401

402
        /**
403
         * Generates the rel next.
404
         *
405
         * @return string The rel prev next.
406
         */
407
        public function generate_rel_next() {
2✔
408
                return '';
2✔
409
        }
410

411
        /**
412
         * Generates the Open Graph type.
413
         *
414
         * @return string The Open Graph type.
415
         */
416
        public function generate_open_graph_type() {
2✔
417
                return 'website';
2✔
418
        }
419

420
        /**
421
         * Generates the open graph title.
422
         *
423
         * @return string The open graph title.
424
         */
425
        public function generate_open_graph_title() {
6✔
426
                if ( $this->model->open_graph_title ) {
6✔
427
                        $open_graph_title = $this->model->open_graph_title;
2✔
428
                }
429

430
                if ( empty( $open_graph_title ) ) {
6✔
431
                        // The helper applies a filter, but we don't have a default value at this stage so we pass an empty string.
432
                        $open_graph_title = $this->values_helper->get_open_graph_title( '', $this->model->object_type, $this->model->object_sub_type );
4✔
433
                }
434

435
                if ( empty( $open_graph_title ) ) {
6✔
436
                        $open_graph_title = $this->title;
2✔
437
                }
438

439
                return $open_graph_title;
6✔
440
        }
441

442
        /**
443
         * Generates the open graph description.
444
         *
445
         * @return string The open graph description.
446
         */
447
        public function generate_open_graph_description() {
6✔
448
                if ( $this->model->open_graph_description ) {
6✔
449
                        $open_graph_description = $this->model->open_graph_description;
2✔
450
                }
451

452
                if ( empty( $open_graph_description ) ) {
6✔
453
                        // The helper applies a filter, but we don't have a default value at this stage so we pass an empty string.
454
                        $open_graph_description = $this->values_helper->get_open_graph_description( '', $this->model->object_type, $this->model->object_sub_type );
4✔
455
                }
456

457
                if ( empty( $open_graph_description ) ) {
6✔
458
                        $open_graph_description = $this->meta_description;
2✔
459
                }
460

461
                return $open_graph_description;
6✔
462
        }
463

464
        /**
465
         * Generates the open graph images.
466
         *
467
         * @return array The open graph images.
468
         */
469
        public function generate_open_graph_images() {
4✔
470
                if ( $this->context->open_graph_enabled === false ) {
4✔
471
                        return [];
2✔
472
                }
473

474
                return $this->open_graph_image_generator->generate( $this->context );
2✔
475
        }
476

477
        /**
478
         * Generates the open graph image ID.
479
         *
480
         * @return string The open graph image ID.
481
         */
482
        public function generate_open_graph_image_id() {
×
483
                if ( $this->model->open_graph_image_id ) {
×
484
                        return $this->model->open_graph_image_id;
×
485
                }
486

487
                return $this->values_helper->get_open_graph_image_id( 0, $this->model->object_type, $this->model->object_sub_type );
×
488
        }
489

490
        /**
491
         * Generates the open graph image URL.
492
         *
493
         * @return string The open graph image URL.
494
         */
495
        public function generate_open_graph_image() {
×
496
                if ( $this->model->open_graph_image ) {
×
497
                        return $this->model->open_graph_image;
×
498
                }
499

500
                return $this->values_helper->get_open_graph_image( '', $this->model->object_type, $this->model->object_sub_type );
×
501
        }
502

503
        /**
504
         * Generates the open graph url.
505
         *
506
         * @return string The open graph url.
507
         */
508
        public function generate_open_graph_url() {
4✔
509
                if ( $this->model->canonical ) {
4✔
510
                        return $this->model->canonical;
2✔
511
                }
512

513
                return $this->permalink;
2✔
514
        }
515

516
        /**
517
         * Generates the open graph article publisher.
518
         *
519
         * @return string The open graph article publisher.
520
         */
521
        public function generate_open_graph_article_publisher() {
2✔
522
                return '';
2✔
523
        }
524

525
        /**
526
         * Generates the open graph article author.
527
         *
528
         * @return string The open graph article author.
529
         */
530
        public function generate_open_graph_article_author() {
2✔
531
                return '';
2✔
532
        }
533

534
        /**
535
         * Generates the open graph article published time.
536
         *
537
         * @return string The open graph article published time.
538
         */
539
        public function generate_open_graph_article_published_time() {
2✔
540
                return '';
2✔
541
        }
542

543
        /**
544
         * Generates the open graph article modified time.
545
         *
546
         * @return string The open graph article modified time.
547
         */
548
        public function generate_open_graph_article_modified_time() {
2✔
549
                return '';
2✔
550
        }
551

552
        /**
553
         * Generates the open graph locale.
554
         *
555
         * @return string The open graph locale.
556
         */
557
        public function generate_open_graph_locale() {
10✔
558
                return $this->open_graph_locale_generator->generate( $this->context );
10✔
559
        }
560

561
        /**
562
         * Generates the open graph site name.
563
         *
564
         * @return string The open graph site name.
565
         */
566
        public function generate_open_graph_site_name() {
4✔
567
                return $this->context->wordpress_site_name;
4✔
568
        }
569

570
        /**
571
         * Generates the Twitter card type.
572
         *
573
         * @return string The Twitter card type.
574
         */
575
        public function generate_twitter_card() {
2✔
576
                return $this->context->twitter_card;
2✔
577
        }
578

579
        /**
580
         * Generates the Twitter title.
581
         *
582
         * @return string The Twitter title.
583
         */
584
        public function generate_twitter_title() {
16✔
585
                if ( $this->model->twitter_title ) {
16✔
586
                        return $this->model->twitter_title;
2✔
587
                }
588

589
                if ( $this->context->open_graph_enabled === true ) {
14✔
590
                        $social_template_title = $this->values_helper->get_open_graph_title( '', $this->model->object_type, $this->model->object_sub_type );
12✔
591
                        $open_graph_title      = $this->open_graph_title;
12✔
592

593
                        // If the helper returns a value and it's different from the OG value in the indexable,
594
                        // output it in a twitter: tag.
595
                        if ( ! empty( $social_template_title ) && $social_template_title !== $open_graph_title ) {
12✔
596
                                return $social_template_title;
2✔
597
                        }
598

599
                        // If the OG title is set, let og: tag take care of this.
600
                        if ( ! empty( $open_graph_title ) ) {
10✔
601
                                return '';
4✔
602
                        }
603
                }
604

605
                if ( $this->title ) {
8✔
606
                        return $this->title;
6✔
607
                }
608

609
                return '';
2✔
610
        }
611

612
        /**
613
         * Generates the Twitter description.
614
         *
615
         * @return string The Twitter description.
616
         */
617
        public function generate_twitter_description() {
16✔
618
                if ( $this->model->twitter_description ) {
16✔
619
                        return $this->model->twitter_description;
2✔
620
                }
621

622
                if ( $this->context->open_graph_enabled === true ) {
14✔
623
                        $social_template_description = $this->values_helper->get_open_graph_description( '', $this->model->object_type, $this->model->object_sub_type );
12✔
624
                        $open_graph_description      = $this->open_graph_description;
12✔
625

626
                        // If the helper returns a value and it's different from the OG value in the indexable,
627
                        // output it in a twitter: tag.
628
                        if ( ! empty( $social_template_description ) && $social_template_description !== $open_graph_description ) {
12✔
629
                                return $social_template_description;
2✔
630
                        }
631

632
                        // If the OG description is set, let og: tag take care of this.
633
                        if ( ! empty( $open_graph_description ) ) {
10✔
634
                                return '';
4✔
635
                        }
636
                }
637

638
                if ( $this->meta_description ) {
8✔
639
                        return $this->meta_description;
6✔
640
                }
641

642
                return '';
2✔
643
        }
644

645
        /**
646
         * Generates the Twitter image.
647
         *
648
         * @return string The Twitter image.
649
         */
650
        public function generate_twitter_image() {
12✔
651
                $images = $this->twitter_image_generator->generate( $this->context );
12✔
652
                $image  = \reset( $images );
12✔
653

654
                // Use a user-defined Twitter image, if present.
655
                if ( $image && $this->context->indexable->twitter_image_source === 'set-by-user' ) {
12✔
656
                        return $image['url'];
2✔
657
                }
658

659
                // Let the Open Graph tags, if enabled, handle the rest of the fallback hierarchy.
660
                if ( $this->context->open_graph_enabled === true && $this->open_graph_images ) {
10✔
661
                        return '';
2✔
662
                }
663

664
                // Set a Twitter tag with the featured image, or a prominent image from the content, if present.
665
                if ( $image ) {
8✔
666
                        return $image['url'];
4✔
667
                }
668

669
                return '';
4✔
670
        }
671

672
        /**
673
         * Generates the Twitter creator.
674
         *
675
         * @return string The Twitter creator.
676
         */
677
        public function generate_twitter_creator() {
2✔
678
                return '';
2✔
679
        }
680

681
        /**
682
         * Generates the Twitter site.
683
         *
684
         * @return string The Twitter site.
685
         */
686
        public function generate_twitter_site() {
8✔
687
                switch ( $this->context->site_represents ) {
8✔
688
                        case 'person':
8✔
689
                                $twitter = $this->user->get_the_author_meta( 'twitter', (int) $this->context->site_user_id );
4✔
690
                                if ( empty( $twitter ) ) {
4✔
691
                                        $twitter = $this->options->get( 'twitter_site' );
2✔
692
                                }
693
                                break;
4✔
694
                        case 'company':
4✔
695
                        default:
696
                                $twitter = $this->options->get( 'twitter_site' );
4✔
697
                                break;
4✔
698
                }
699

700
                return $twitter;
8✔
701
        }
702

703
        /**
704
         * Generates the source.
705
         *
706
         * @return array The source.
707
         */
708
        public function generate_source() {
2✔
709
                return [];
2✔
710
        }
711

712
        /**
713
         * Generates the schema for the page.
714
         *
715
         * @codeCoverageIgnore Wrapper method.
716
         *
717
         * @return array The Schema object.
718
         */
719
        public function generate_schema() {
720
                return $this->schema_generator->generate( $this->context );
721
        }
722

723
        /**
724
         * Generates the breadcrumbs for the page.
725
         *
726
         * @codeCoverageIgnore Wrapper method.
727
         *
728
         * @return array The breadcrumbs.
729
         */
730
        public function generate_breadcrumbs() {
731
                return $this->breadcrumbs_generator->generate( $this->context );
732
        }
733

734
        /**
735
         * Generates the estimated reading time.
736
         *
737
         * @codeCoverageIgnore Wrapper method.
738
         *
739
         * @return int|null The estimated reading time.
740
         */
741
        public function generate_estimated_reading_time_minutes() {
742
                if ( $this->model->estimated_reading_time_minutes !== null ) {
743
                        return $this->model->estimated_reading_time_minutes;
744
                }
745

746
                if ( $this->context->post === null ) {
747
                        return null;
748
                }
749

750
                // 200 is the approximate estimated words per minute across languages.
751
                $words_per_minute = 200;
752
                $words            = \str_word_count( \wp_strip_all_tags( $this->context->post->post_content ) );
753
                return (int) \round( $words / $words_per_minute );
754
        }
755

756
        /**
757
         * Strips all nested dependencies from the debug info.
758
         *
759
         * @return array
760
         */
761
        public function __debugInfo() {
2✔
762
                return [
2✔
763
                        'model'   => $this->model,
2✔
764
                        'context' => $this->context,
2✔
765
                ];
2✔
766
        }
767
}
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