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

Yoast / wordpress-seo / ba2921a57c1827483483ec1d9ad26f7563cb93d4

20 Aug 2024 07:34AM UTC coverage: 48.697% (-5.4%) from 54.072%
ba2921a57c1827483483ec1d9ad26f7563cb93d4

push

github

YoastBot
Bump version to 23.3

7460 of 13482 branches covered (55.33%)

Branch coverage included in aggregate %.

25255 of 53699 relevant lines covered (47.03%)

42524.45 hits per line

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

43.75
/src/models/indexable.php
1
<?php
2

3
namespace Yoast\WP\SEO\Models;
4

5
use Yoast\WP\Lib\Model;
6

7
/**
8
 * Indexable table definition.
9
 *
10
 * @property int    $id
11
 * @property int    $object_id
12
 * @property string $object_type
13
 * @property string $object_sub_type
14
 *
15
 * @property int    $author_id
16
 * @property int    $post_parent
17
 *
18
 * @property string $created_at
19
 * @property string $updated_at
20
 *
21
 * @property string $permalink
22
 * @property string $permalink_hash
23
 * @property string $canonical
24
 *
25
 * @property bool   $is_robots_noindex
26
 * @property bool   $is_robots_nofollow
27
 * @property bool   $is_robots_noarchive
28
 * @property bool   $is_robots_noimageindex
29
 * @property bool   $is_robots_nosnippet
30
 *
31
 * @property string $title
32
 * @property string $description
33
 * @property string $breadcrumb_title
34
 *
35
 * @property bool   $is_cornerstone
36
 *
37
 * @property string $primary_focus_keyword
38
 * @property int    $primary_focus_keyword_score
39
 *
40
 * @property int    $readability_score
41
 *
42
 * @property int    $inclusive_language_score
43
 *
44
 * @property int    $link_count
45
 * @property int    $incoming_link_count
46
 * @property int    $number_of_pages
47
 *
48
 * @property string $open_graph_title
49
 * @property string $open_graph_description
50
 * @property string $open_graph_image
51
 * @property string $open_graph_image_id
52
 * @property string $open_graph_image_source
53
 * @property string $open_graph_image_meta
54
 *
55
 * @property string $twitter_title
56
 * @property string $twitter_description
57
 * @property string $twitter_image
58
 * @property string $twitter_image_id
59
 * @property string $twitter_image_source
60
 * @property string $twitter_card
61
 *
62
 * @property int    $prominent_words_version
63
 *
64
 * @property bool   $is_public
65
 * @property bool   $is_protected
66
 * @property string $post_status
67
 * @property bool   $has_public_posts
68
 *
69
 * @property int    $blog_id
70
 *
71
 * @property string $language
72
 * @property string $region
73
 *
74
 * @property string $schema_page_type
75
 * @property string $schema_article_type
76
 *
77
 * @property bool   $has_ancestors
78
 *
79
 * @property int    $estimated_reading_time_minutes
80
 *
81
 * @property string $object_last_modified
82
 * @property string $object_published_at
83
 *
84
 * @property int    $version
85
 */
86
class Indexable extends Model {
87

88
        /**
89
         * Holds the ancestors.
90
         *
91
         * @var Indexable[]
92
         */
93
        public $ancestors = [];
94

95
        /**
96
         * Whether nor this model uses timestamps.
97
         *
98
         * @var bool
99
         */
100
        protected $uses_timestamps = true;
101

102
        /**
103
         * Which columns contain boolean values.
104
         *
105
         * @var array
106
         */
107
        protected $boolean_columns = [
108
                'is_robots_noindex',
109
                'is_robots_nofollow',
110
                'is_robots_noarchive',
111
                'is_robots_noimageindex',
112
                'is_robots_nosnippet',
113
                'is_cornerstone',
114
                'is_public',
115
                'is_protected',
116
                'has_public_posts',
117
                'has_ancestors',
118
        ];
119

120
        /**
121
         * Which columns contain int values.
122
         *
123
         * @var array
124
         */
125
        protected $int_columns = [
126
                'id',
127
                'object_id',
128
                'author_id',
129
                'post_parent',
130
                'primary_focus_keyword_score',
131
                'readability_score',
132
                'inclusive_language_score',
133
                'link_count',
134
                'incoming_link_count',
135
                'number_of_pages',
136
                'prominent_words_version',
137
                'blog_id',
138
                'estimated_reading_time_minutes',
139
                'version',
140
        ];
141

142
        /**
143
         * The loaded indexable extensions.
144
         *
145
         * @var Indexable_Extension[]
146
         */
147
        protected $loaded_extensions = [];
148

149
        /**
150
         * Returns an Indexable_Extension by its name.
151
         *
152
         * @param string $class_name The class name of the extension to load.
153
         *
154
         * @return Indexable_Extension|bool The extension.
155
         */
156
        public function get_extension( $class_name ) {
4✔
157
                if ( ! $this->loaded_extensions[ $class_name ] ) {
4✔
158
                        $this->loaded_extensions[ $class_name ] = $this->has_one( $class_name, 'indexable_id', 'id' )->find_one();
2✔
159
                }
160

161
                return $this->loaded_extensions[ $class_name ];
4✔
162
        }
163

164
        /**
165
         * Enhances the save method.
166
         *
167
         * @return bool True on success.
168
         */
169
        public function save() {
10✔
170
                if ( $this->permalink ) {
10✔
171
                        $this->sanitize_permalink();
6✔
172
                        $this->permalink_hash = \strlen( $this->permalink ) . ':' . \md5( $this->permalink );
6✔
173
                }
174
                if ( \is_string( $this->primary_focus_keyword ) && \mb_strlen( $this->primary_focus_keyword ) > 191 ) {
10✔
175
                        $this->primary_focus_keyword = \mb_substr( $this->primary_focus_keyword, 0, 191, 'UTF-8' );
2✔
176
                }
177

178
                return parent::save();
10✔
179
        }
180

181
        /**
182
         * Sanitizes the permalink.
183
         *
184
         * @return void
185
         */
186
        protected function sanitize_permalink() {
2✔
187
                if ( $this->permalink === 'unindexed' ) {
2✔
188
                        return;
2✔
189
                }
190

191
                $permalink_structure = \get_option( 'permalink_structure' );
×
192
                $permalink_parts     = \wp_parse_url( $this->permalink );
×
193

194
                if ( ! isset( $permalink_parts['path'] ) ) {
×
195
                        $permalink_parts['path'] = '/';
×
196
                }
197
                if ( \substr( $permalink_structure, -1, 1 ) === '/' && \strpos( \substr( $permalink_parts['path'], -5 ), '.' ) === false ) {
×
198
                        $permalink_parts['path'] = \trailingslashit( $permalink_parts['path'] );
×
199
                }
200

201
                $permalink = '';
×
202
                if ( isset( $permalink_parts['scheme'] ) ) {
×
203
                        $permalink .= $permalink_parts['scheme'] . '://';
×
204
                }
205
                if ( isset( $permalink_parts['host'] ) ) {
×
206
                        $permalink .= $permalink_parts['host'];
×
207
                }
208
                if ( isset( $permalink_parts['port'] ) ) {
×
209
                        $permalink .= ':' . $permalink_parts['port'];
×
210
                }
211
                if ( isset( $permalink_parts['path'] ) ) {
×
212
                        $permalink .= $permalink_parts['path'];
×
213
                }
214
                if ( isset( $permalink_parts['query'] ) ) {
×
215
                        $permalink .= '?' . $permalink_parts['query'];
×
216
                }
217
                // We never set the fragment as the fragment is intended to be client-only.
218
                $this->permalink = $permalink;
×
219
        }
220
}
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

© 2025 Coveralls, Inc