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

Yoast / wordpress-seo / 5066322038

pending completion
5066322038

push

github

GitHub
Merge pull request #20316 from Yoast/JRF/ghactions-run-more-selectively

2550 of 29012 relevant lines covered (8.79%)

0.32 hits per line

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

0.0
/src/generators/schema/breadcrumb.php
1
<?php
2

3
namespace Yoast\WP\SEO\Generators\Schema;
4

5
use Yoast\WP\SEO\Config\Schema_IDs;
6

7
/**
8
 * Returns schema Breadcrumb data.
9
 */
10
class Breadcrumb extends Abstract_Schema_Piece {
11

12
        /**
13
         * Determine if we should add a breadcrumb attribute.
14
         *
15
         * @return bool
16
         */
17
        public function is_needed() {
18
                if ( $this->context->indexable->object_type === 'unknown' ) {
×
19
                        return false;
×
20
                }
21

22
                if ( $this->context->indexable->object_type === 'system-page' && $this->context->indexable->object_sub_type === '404' ) {
×
23
                        return false;
×
24
                }
25

26
                return true;
×
27
        }
28

29
        /**
30
         * Returns Schema breadcrumb data to allow recognition of page's position in the site hierarchy.
31
         *
32
         * @link https://developers.google.com/search/docs/data-types/breadcrumb
33
         *
34
         * @return bool|array Array on success, false on failure.
35
         */
36
        public function generate() {
37
                $breadcrumbs   = $this->context->presentation->breadcrumbs;
×
38
                $list_elements = [];
×
39

40
                // In case of pagination, replace the last breadcrumb, because it only contains "Page [number]" and has no URL.
41
                if (
42
                        (
×
43
                                $this->helpers->current_page->is_paged()
×
44
                                || $this->context->indexable->number_of_pages > 1
×
45
                        ) && (
46
                                // Do not replace the last breadcrumb on static post pages.
47
                                ! $this->helpers->current_page->is_static_posts_page()
×
48
                                // Do not remove the last breadcrumb if only one exists (bugfix for custom paginated frontpages).
×
49
                                && \count( $breadcrumbs ) > 1
×
50
                        )
51
                ) {
52
                        \array_pop( $breadcrumbs );
×
53
                }
54

55
                // Only output breadcrumbs that are not hidden.
56
                $breadcrumbs = \array_filter( $breadcrumbs, [ $this, 'not_hidden' ] );
×
57

58
                \reset( $breadcrumbs );
×
59

60
                /*
61
                 * Check whether at least one of the breadcrumbs is broken.
62
                 * If so, do not output anything.
63
                 */
64
                foreach ( $breadcrumbs as $breadcrumb ) {
×
65
                        if ( $this->is_broken( $breadcrumb ) ) {
×
66
                                return false;
×
67
                        }
68
                }
69

70
                // Create the last breadcrumb.
71
                $last_breadcrumb = \array_pop( $breadcrumbs );
×
72
                $breadcrumbs[]   = $this->format_last_breadcrumb( $last_breadcrumb );
×
73

74
                // If this is a static front page, prevent nested pages from creating a trail.
75
                if ( $this->helpers->current_page->is_home_static_page() ) {
×
76

77
                        // Check if we're dealing with a nested page.
78
                        if ( \count( $breadcrumbs ) > 1 ) {
×
79

80
                                // Store the breadcrumbs home variable before dropping the parent page from the Schema.
81
                                $breadcrumbs_home = $breadcrumbs[0]['text'];
×
82
                                $breadcrumbs      = [ \array_pop( $breadcrumbs ) ];
×
83

84
                                // Make the child page show the breadcrumbs home variable rather than its own title.
85
                                $breadcrumbs[0]['text'] = $breadcrumbs_home;
×
86
                        }
87
                }
88

89
                $breadcrumbs = \array_filter( $breadcrumbs, [ $this, 'not_empty_text' ] );
×
90
                $breadcrumbs = \array_values( $breadcrumbs );
×
91

92
                // Create intermediate breadcrumbs.
93
                foreach ( $breadcrumbs as $index => $breadcrumb ) {
×
94
                        $list_elements[] = $this->create_breadcrumb( $index, $breadcrumb );
×
95
                }
96

97
                return [
×
98
                        '@type'           => 'BreadcrumbList',
×
99
                        '@id'             => $this->context->canonical . Schema_IDs::BREADCRUMB_HASH,
×
100
                        'itemListElement' => $list_elements,
×
101
                ];
×
102
        }
103

104
        /**
105
         * Returns a breadcrumb array.
106
         *
107
         * @param int   $index      The position in the list.
108
         * @param array $breadcrumb The position in the list.
109
         *
110
         * @return array A breadcrumb listItem.
111
         */
112
        private function create_breadcrumb( $index, $breadcrumb ) {
113
                $crumb = [
×
114
                        '@type'    => 'ListItem',
×
115
                        'position' => ( $index + 1 ),
×
116
                        'name'     => $this->helpers->schema->html->smart_strip_tags( $breadcrumb['text'] ),
×
117
                ];
×
118

119
                if ( ! empty( $breadcrumb['url'] ) ) {
×
120
                        $crumb['item'] = $breadcrumb['url'];
×
121
                }
122

123
                return $crumb;
×
124
        }
125

126
        /**
127
         * Creates the last breadcrumb in the breadcrumb list, omitting the URL per Google's spec.
128
         *
129
         * @link https://developers.google.com/search/docs/data-types/breadcrumb
130
         *
131
         * @param array $breadcrumb The position in the list.
132
         *
133
         * @return array The last of the breadcrumbs.
134
         */
135
        private function format_last_breadcrumb( $breadcrumb ) {
136
                unset( $breadcrumb['url'] );
×
137

138
                return $breadcrumb;
×
139
        }
140

141
        /**
142
         * Tests if the breadcrumb is broken.
143
         * A breadcrumb is considered broken:
144
         * - when it is not an array.
145
         * - when it has no URL or text.
146
         *
147
         * @param array $breadcrumb The breadcrumb to test.
148
         *
149
         * @return bool `true` if the breadcrumb is broken.
150
         */
151
        private function is_broken( $breadcrumb ) {
152
                // A breadcrumb is broken if it is not an array.
153
                if ( ! \is_array( $breadcrumb ) ) {
×
154
                        return true;
×
155
                }
156

157
                // A breadcrumb is broken if it does not contain a URL or text.
158
                if ( ! \array_key_exists( 'url', $breadcrumb ) || ! \array_key_exists( 'text', $breadcrumb ) ) {
×
159
                        return true;
×
160
                }
161

162
                return false;
×
163
        }
164

165
        /**
166
         * Checks whether the breadcrumb is not set to be hidden.
167
         *
168
         * @param array $breadcrumb The breadcrumb array.
169
         *
170
         * @return bool If the breadcrumb should not be hidden.
171
         */
172
        private function not_hidden( $breadcrumb ) {
173
                return empty( $breadcrumb['hide_in_schema'] );
×
174
        }
175

176
        /**
177
         * Checks whether the breadcrumb has a not empty text.
178
         *
179
         * @param array $breadcrumb The breadcrumb array.
180
         *
181
         * @return bool If the breadcrumb has a not empty text.
182
         */
183
        private function not_empty_text( $breadcrumb ) {
184
                return ! empty( $breadcrumb['text'] );
×
185
        }
186
}
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