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

Yoast / wordpress-seo / dd6e866a9e6d253114633104d9e3858d807178ba

19 Jun 2024 10:03AM UTC coverage: 48.628% (-4.3%) from 52.936%
dd6e866a9e6d253114633104d9e3858d807178ba

push

github

web-flow
Merge pull request #21431 from Yoast/21429-update-copy-in-the-introduction-and-consent-modals

Updates the copy for the introduction and consent modals

7441 of 13454 branches covered (55.31%)

Branch coverage included in aggregate %.

0 of 3 new or added lines in 2 files covered. (0.0%)

3718 existing lines in 107 files now uncovered.

25100 of 53464 relevant lines covered (46.95%)

62392.47 hits per line

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

0.0
/admin/statistics/class-statistics-service.php
1
<?php
2
/**
3
 * WPSEO plugin file.
4
 *
5
 * @package WPSEO\Admin\Statistics
6
 */
7

8
/**
9
 * Class WPSEO_Statistics_Service.
10
 */
11
class WPSEO_Statistics_Service {
12

13
        /**
14
         * Cache transient id.
15
         *
16
         * @var string
17
         */
18
        public const CACHE_TRANSIENT_KEY = 'wpseo-statistics-totals';
19

20
        /**
21
         * Class that generates interesting statistics about things.
22
         *
23
         * @var WPSEO_Statistics
24
         */
25
        protected $statistics;
26

27
        /**
28
         * Statistics labels.
29
         *
30
         * @var string[]
31
         */
32
        protected $labels;
33

34
        /**
35
         * WPSEO_Statistics_Service contructor.
36
         *
37
         * @param WPSEO_Statistics $statistics The statistics class to retrieve statistics from.
38
         */
39
        public function __construct( WPSEO_Statistics $statistics ) {
×
40
                $this->statistics = $statistics;
×
41
        }
42

43
        /**
44
         * Fetches statistics by REST request.
45
         *
46
         * @return WP_REST_Response The response object.
47
         */
UNCOV
48
        public function get_statistics() {
×
49
                // Switch to the user locale with fallback to the site locale.
UNCOV
50
                switch_to_locale( get_user_locale() );
×
51

UNCOV
52
                $this->labels = $this->labels();
×
UNCOV
53
                $statistics   = $this->statistic_items();
×
54

UNCOV
55
                $data = [
×
UNCOV
56
                        'header'     => $this->get_header_from_statistics( $statistics ),
×
UNCOV
57
                        'seo_scores' => $statistics['scores'],
×
UNCOV
58
                ];
×
59

UNCOV
60
                return new WP_REST_Response( $data );
×
61
        }
62

63
        /**
64
         * Gets a header summarizing the given statistics results.
65
         *
66
         * @param array $statistics The statistics results.
67
         *
68
         * @return string The header summing up the statistics results.
69
         */
70
        private function get_header_from_statistics( array $statistics ) {
×
71
                // Personal interpretation to allow release, should be looked at later.
72
                if ( $statistics['division'] === false ) {
×
73
                        return __( 'You don\'t have any published posts, your SEO scores will appear here once you make your first post!', 'wordpress-seo' );
×
74
                }
75

76
                if ( $statistics['division']['good'] > 0.66 ) {
×
77
                        return __( 'Hey, your SEO is doing pretty well! Check out the stats:', 'wordpress-seo' );
×
78
                }
79

80
                return __( 'Below are your published posts\' SEO scores. Now is as good a time as any to start improving some of your posts!', 'wordpress-seo' );
×
81
        }
82

83
        /**
84
         * An array representing items to be added to the At a Glance dashboard widget.
85
         *
86
         * @return array The statistics for the current user.
87
         */
88
        private function statistic_items() {
×
89
                $transient = $this->get_transient();
×
90
                $user_id   = get_current_user_id();
×
91

92
                if ( isset( $transient[ $user_id ] ) ) {
×
93
                        return $transient[ $user_id ];
×
94
                }
95

96
                return $this->set_statistic_items_for_user( $transient, $user_id );
×
97
        }
98

99
        /**
100
         * Gets the statistics transient value. Returns array if transient wasn't set.
101
         *
102
         * @return array|mixed Returns the transient or an empty array if the transient doesn't exist.
103
         */
104
        private function get_transient() {
×
105
                $transient = get_transient( self::CACHE_TRANSIENT_KEY );
×
106

107
                if ( $transient === false ) {
×
108
                        return [];
×
109
                }
110

111
                return $transient;
×
112
        }
113

114
        /**
115
         * Set the statistics transient cache for a specific user.
116
         *
117
         * @param array $transient The current stored transient with the cached data.
118
         * @param int   $user      The user's ID to assign the retrieved values to.
119
         *
120
         * @return array The statistics transient for the user.
121
         */
122
        private function set_statistic_items_for_user( $transient, $user ) {
×
123
                $scores   = $this->get_seo_scores_with_post_count();
×
124
                $division = $this->get_seo_score_division( $scores );
×
125

126
                $transient[ $user ] = [
×
127
                        // Use array_values because array_filter may return non-zero indexed arrays.
128
                        'scores'   => array_values( array_filter( $scores, [ $this, 'filter_items' ] ) ),
×
129
                        'division' => $division,
×
UNCOV
130
                ];
×
131

132
                set_transient( self::CACHE_TRANSIENT_KEY, $transient, DAY_IN_SECONDS );
×
133

134
                return $transient[ $user ];
×
135
        }
136

137
        /**
138
         * Gets the division of SEO scores.
139
         *
140
         * @param array $scores The SEO scores.
141
         *
142
         * @return array|bool The division of SEO scores, false if there are no posts.
143
         */
144
        private function get_seo_score_division( array $scores ) {
×
145
                $total    = 0;
×
146
                $division = [];
×
147

148
                foreach ( $scores as $score ) {
×
149
                        $total += $score['count'];
×
150
                }
151

152
                if ( $total === 0 ) {
×
153
                        return false;
×
154
                }
155

156
                foreach ( $scores as $score ) {
×
157
                        $division[ $score['seo_rank'] ] = ( $score['count'] / $total );
×
158
                }
159

160
                return $division;
×
161
        }
162

163
        /**
164
         * Get all SEO ranks and data associated with them.
165
         *
166
         * @return array An array of SEO scores and associated data.
167
         */
168
        private function get_seo_scores_with_post_count() {
×
169
                $ranks = WPSEO_Rank::get_all_ranks();
×
170

171
                return array_map( [ $this, 'map_rank_to_widget' ], $ranks );
×
172
        }
173

174
        /**
175
         * Converts a rank to data usable in the dashboard widget.
176
         *
177
         * @param WPSEO_Rank $rank The rank to map.
178
         *
179
         * @return array The mapped rank.
180
         */
181
        private function map_rank_to_widget( WPSEO_Rank $rank ) {
×
UNCOV
182
                return [
×
183
                        'seo_rank' => $rank->get_rank(),
×
184
                        'label'    => $this->get_label_for_rank( $rank ),
×
185
                        'count'    => $this->statistics->get_post_count( $rank ),
×
186
                        'link'     => $this->get_link_for_rank( $rank ),
×
UNCOV
187
                ];
×
188
        }
189

190
        /**
191
         * Returns a dashboard widget label to use for a certain rank.
192
         *
193
         * @param WPSEO_Rank $rank The rank to return a label for.
194
         *
195
         * @return string The label for the rank.
196
         */
197
        private function get_label_for_rank( WPSEO_Rank $rank ) {
×
198
                return $this->labels[ $rank->get_rank() ];
×
199
        }
200

201
        /**
202
         * Determines the labels for the various scoring ranks that are known within Yoast SEO.
203
         *
204
         * @return array Array containing the translatable labels.
205
         */
206
        private function labels() {
×
UNCOV
207
                return [
×
208
                        WPSEO_Rank::NO_FOCUS => sprintf(
×
209
                                /* translators: %1$s expands to an opening strong tag, %2$s expands to a closing strong tag */
210
                                __( 'Posts %1$swithout%2$s a focus keyphrase', 'wordpress-seo' ),
×
211
                                '<strong>',
×
212
                                '</strong>'
×
UNCOV
213
                        ),
×
214
                        WPSEO_Rank::BAD      => sprintf(
×
215
                                /* translators: %s expands to the score */
216
                                __( 'Posts with the SEO score: %s', 'wordpress-seo' ),
×
217
                                '<strong>' . __( 'Needs improvement', 'wordpress-seo' ) . '</strong>'
×
UNCOV
218
                        ),
×
219
                        WPSEO_Rank::OK       => sprintf(
×
220
                                /* translators: %s expands to the score */
221
                                __( 'Posts with the SEO score: %s', 'wordpress-seo' ),
×
222
                                '<strong>' . __( 'OK', 'wordpress-seo' ) . '</strong>'
×
UNCOV
223
                        ),
×
224
                        WPSEO_Rank::GOOD     => sprintf(
×
225
                                /* translators: %s expands to the score */
226
                                __( 'Posts with the SEO score: %s', 'wordpress-seo' ),
×
227
                                '<strong>' . __( 'Good', 'wordpress-seo' ) . '</strong>'
×
UNCOV
228
                        ),
×
229
                        WPSEO_Rank::NO_INDEX => __( 'Posts that should not show up in search results', 'wordpress-seo' ),
×
UNCOV
230
                ];
×
231
        }
232

233
        /**
234
         * Filter items if they have a count of zero.
235
         *
236
         * @param array $item The item to potentially filter out.
237
         *
238
         * @return bool Whether or not the count is zero.
239
         */
240
        private function filter_items( $item ) {
×
241
                return $item['count'] !== 0;
×
242
        }
243

244
        /**
245
         * Returns a link for the overview of posts of a certain rank.
246
         *
247
         * @param WPSEO_Rank $rank The rank to return a link for.
248
         *
249
         * @return string The link that shows an overview of posts with that rank.
250
         */
251
        private function get_link_for_rank( WPSEO_Rank $rank ) {
×
252
                if ( current_user_can( 'edit_others_posts' ) === false ) {
×
253
                        return esc_url( admin_url( 'edit.php?post_status=publish&post_type=post&seo_filter=' . $rank->get_rank() . '&author=' . get_current_user_id() ) );
×
254
                }
255

256
                return esc_url( admin_url( 'edit.php?post_status=publish&post_type=post&seo_filter=' . $rank->get_rank() ) );
×
257
        }
258
}
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