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

Yoast / wordpress-seo / ff7fbe548e11c03015095d039b28d1168b751857

16 Feb 2026 01:09AM UTC coverage: 52.986%. Remained the same
ff7fbe548e11c03015095d039b28d1168b751857

push

github

web-flow
Merge pull request #22987 from Yoast/JRF/modernize-use-trailing-commas-in-function-calls

Modernize: use trailing comma in multi-line function call

8482 of 15955 branches covered (53.16%)

Branch coverage included in aggregate %.

396 of 875 new or added lines in 311 files covered. (45.26%)

21 existing lines in 12 files now uncovered.

32462 of 61318 relevant lines covered (52.94%)

48791.32 hits per line

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

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

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

13
        /**
14
         * Holds the admin page's ID.
15
         *
16
         * @var string
17
         */
18
        public const ADMIN_PAGE = 'wpseo_dashboard';
19

20
        /**
21
         * Total notifications count.
22
         *
23
         * @var int
24
         */
25
        private static $notification_count = 0;
26

27
        /**
28
         * All error notifications.
29
         *
30
         * @var array
31
         */
32
        private static $errors = [];
33

34
        /**
35
         * Active errors.
36
         *
37
         * @var array
38
         */
39
        private static $active_errors = [];
40

41
        /**
42
         * Dismissed errors.
43
         *
44
         * @var array
45
         */
46
        private static $dismissed_errors = [];
47

48
        /**
49
         * All warning notifications.
50
         *
51
         * @var array
52
         */
53
        private static $warnings = [];
54

55
        /**
56
         * Active warnings.
57
         *
58
         * @var array
59
         */
60
        private static $active_warnings = [];
61

62
        /**
63
         * Dismissed warnings.
64
         *
65
         * @var array
66
         */
67
        private static $dismissed_warnings = [];
68

69
        /**
70
         * Yoast_Notifications constructor.
71
         */
72
        public function __construct() {
×
73

74
                $this->add_hooks();
×
75
        }
76

77
        /**
78
         * Add hooks
79
         *
80
         * @return void
81
         */
82
        private function add_hooks() {
×
83
                // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
84
                if ( isset( $_GET['page'] ) && is_string( $_GET['page'] ) ) {
×
85
                        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
86
                        $page = sanitize_text_field( wp_unslash( $_GET['page'] ) );
×
87
                        if ( $page === self::ADMIN_PAGE ) {
×
88
                                add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
×
89
                        }
90
                }
91

92
                // Needed for adminbar and Notifications page.
93
                add_action( 'admin_init', [ self::class, 'collect_notifications' ], 99 );
×
94

95
                // Add AJAX hooks.
96
                add_action( 'wp_ajax_yoast_dismiss_notification', [ $this, 'ajax_dismiss_notification' ] );
×
97
                add_action( 'wp_ajax_yoast_restore_notification', [ $this, 'ajax_restore_notification' ] );
×
98
        }
99

100
        /**
101
         * Enqueue assets.
102
         *
103
         * @return void
104
         */
105
        public function enqueue_assets() {
×
106
                $asset_manager = new WPSEO_Admin_Asset_Manager();
×
107

108
                $asset_manager->enqueue_style( 'notifications' );
×
109
        }
110

111
        /**
112
         * Handle ajax request to dismiss a notification.
113
         *
114
         * @return void
115
         */
116
        public function ajax_dismiss_notification() {
×
117

118
                $notification = $this->get_notification_from_ajax_request();
×
119
                if ( $notification ) {
×
120
                        $notification_center = Yoast_Notification_Center::get();
×
121
                        $notification_center->maybe_dismiss_notification( $notification );
×
122

123
                        $this->output_ajax_response( $notification->get_type() );
×
124
                }
125

126
                wp_die();
×
127
        }
128

129
        /**
130
         * Handle ajax request to restore a notification.
131
         *
132
         * @return void
133
         */
134
        public function ajax_restore_notification() {
×
135

136
                $notification = $this->get_notification_from_ajax_request();
×
137
                if ( $notification ) {
×
138
                        $notification_center = Yoast_Notification_Center::get();
×
139
                        $notification_center->restore_notification( $notification );
×
140

141
                        $this->output_ajax_response( $notification->get_type() );
×
142
                }
143

144
                wp_die();
×
145
        }
146

147
        /**
148
         * Create AJAX response data.
149
         *
150
         * @param string $type Notification type.
151
         *
152
         * @return void
153
         */
154
        private function output_ajax_response( $type ) {
×
155

156
                $html = $this->get_view_html( $type );
×
157
                // phpcs:disable WordPress.Security.EscapeOutput -- Reason: WPSEO_Utils::format_json_encode is safe.
158
                echo WPSEO_Utils::format_json_encode(
×
159
                        [
×
160
                                'html'  => $html,
×
161
                                'total' => self::get_active_notification_count(),
×
NEW
162
                        ],
×
163
                );
×
164
                // phpcs:enable -- Reason: WPSEO_Utils::format_json_encode is safe.
165
        }
166

167
        /**
168
         * Get the HTML to return in the AJAX request.
169
         *
170
         * @param string $type Notification type.
171
         *
172
         * @return bool|string
173
         */
174
        private function get_view_html( $type ) {
×
175

176
                switch ( $type ) {
177
                        case 'error':
×
178
                                $view = 'errors';
×
179
                                break;
×
180

181
                        case 'warning':
×
182
                        default:
183
                                $view = 'warnings';
×
184
                                break;
×
185
                }
186

187
                // Re-collect notifications.
188
                self::collect_notifications();
×
189

190
                /**
191
                 * Stops PHPStorm from nagging about this variable being unused. The variable is used in the view.
192
                 *
193
                 * @noinspection PhpUnusedLocalVariableInspection
194
                 */
195
                $notifications_data = self::get_template_variables();
×
196

197
                ob_start();
×
198
                include WPSEO_PATH . 'admin/views/partial-notifications-' . $view . '.php';
×
199
                $html = ob_get_clean();
×
200

201
                return $html;
×
202
        }
203

204
        /**
205
         * Extract the Yoast Notification from the AJAX request.
206
         *
207
         * This function does not handle nonce verification.
208
         *
209
         * @return Yoast_Notification|null A Yoast_Notification on success, null on failure.
210
         */
211
        private function get_notification_from_ajax_request() {
×
212
                // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reason: This function does not handle nonce verification.
213
                if ( ! isset( $_POST['notification'] ) || ! is_string( $_POST['notification'] ) ) {
×
214
                        return null;
×
215
                }
216
                // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reason: This function does not handle nonce verification.
217
                $notification_id = sanitize_text_field( wp_unslash( $_POST['notification'] ) );
×
218

219
                if ( empty( $notification_id ) ) {
×
220
                        return null;
×
221
                }
222
                $notification_center = Yoast_Notification_Center::get();
×
223
                return $notification_center->get_notification_by_id( $notification_id );
×
224
        }
225

226
        /**
227
         * Collect the notifications and group them together.
228
         *
229
         * @return void
230
         */
231
        public static function collect_notifications() {
×
232

233
                $notification_center = Yoast_Notification_Center::get();
×
234

235
                $notifications            = $notification_center->get_sorted_notifications();
×
236
                self::$notification_count = count( $notifications );
×
237

238
                self::$errors           = array_filter( $notifications, [ self::class, 'filter_error_notifications' ] );
×
239
                self::$dismissed_errors = array_filter( self::$errors, [ self::class, 'filter_dismissed_notifications' ] );
×
240
                self::$active_errors    = array_diff( self::$errors, self::$dismissed_errors );
×
241

242
                self::$warnings           = array_filter( $notifications, [ self::class, 'filter_warning_notifications' ] );
×
243
                self::$dismissed_warnings = array_filter( self::$warnings, [ self::class, 'filter_dismissed_notifications' ] );
×
244
                self::$active_warnings    = array_diff( self::$warnings, self::$dismissed_warnings );
×
245
        }
246

247
        /**
248
         * Get the variables needed in the views.
249
         *
250
         * @return array
251
         */
252
        public static function get_template_variables() {
×
253

254
                return [
×
255
                        'metrics'  => [
×
256
                                'total'    => self::$notification_count,
×
257
                                'active'   => self::get_active_notification_count(),
×
258
                                'errors'   => count( self::$errors ),
×
259
                                'warnings' => count( self::$warnings ),
×
260
                        ],
×
261
                        'errors'   => [
×
262
                                'dismissed' => self::$dismissed_errors,
×
263
                                'active'    => self::$active_errors,
×
264
                        ],
×
265
                        'warnings' => [
×
266
                                'dismissed' => self::$dismissed_warnings,
×
267
                                'active'    => self::$active_warnings,
×
268
                        ],
×
269
                ];
×
270
        }
271

272
        /**
273
         * Get the number of active notifications.
274
         *
275
         * @return int
276
         */
277
        public static function get_active_notification_count() {
×
278

279
                return ( count( self::$active_errors ) + count( self::$active_warnings ) );
×
280
        }
281

282
        /**
283
         * Filter out any non-errors.
284
         *
285
         * @param Yoast_Notification $notification Notification to test.
286
         *
287
         * @return bool
288
         */
289
        private static function filter_error_notifications( Yoast_Notification $notification ) {
×
290

291
                return $notification->get_type() === 'error';
×
292
        }
293

294
        /**
295
         * Filter out any non-warnings.
296
         *
297
         * @param Yoast_Notification $notification Notification to test.
298
         *
299
         * @return bool
300
         */
301
        private static function filter_warning_notifications( Yoast_Notification $notification ) {
×
302

303
                return $notification->get_type() !== 'error';
×
304
        }
305

306
        /**
307
         * Filter out any dismissed notifications.
308
         *
309
         * @param Yoast_Notification $notification Notification to test.
310
         *
311
         * @return bool
312
         */
313
        private static function filter_dismissed_notifications( Yoast_Notification $notification ) {
×
314

315
                return Yoast_Notification_Center::is_notification_dismissed( $notification );
×
316
        }
317
}
318

319
class_alias( Yoast_Notifications::class, 'Yoast_Alerts' );
×
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