PluginProbe
SureCookie – GDPR Cookie Consent Banner, Cookie Scanner & Script Blocking / 1.4.0
SureCookie – GDPR Cookie Consent Banner, Cookie Scanner & Script Blocking v1.4.0
1.5.0 1.4.0 1.3.0 1.3.1 trunk 0.0.0-alpha.1 0.0.0-alpha.2 0.0.0-alpha.3 0.0.1-beta.1 0.0.1-beta.2 0.0.1-beta.3 0.0.1-beta.4 1.0.0 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4
surecookie / admin / menu.php

menu.php in SureCookie – GDPR Cookie Consent Banner, Cookie Scanner & Script Blocking 1.4.0, at admin/menu.php

581 lines 19.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Menu handler for SureCookie plugin.
4 *
5 * @package SureCookie
6 * @subpackage SureCookie\Admin
7 * @since 0.0.1
8 */
9
10 namespace SureCookie\Admin;
11
12 use SureCookie\Inc\Database\ConsentLog;
13 use SureCookie\Inc\Functions\Get;
14 use SureCookie\Inc\Functions\Helper;
15 use SureCookie\Inc\Functions\Sanitize;
16 use SureCookie\Inc\Functions\Settings;
17 use SureCookie\Inc\Traits\GetInstance;
18 use SureCookie\Inc\Utils\LocalizeData;
19
20 defined( 'ABSPATH' ) || exit;
21
22 /**
23 * Menu handler for SureCookie plugin.
24 *
25 * This class handles the registration and rendering of the admin menu.
26 *
27 * @since 0.0.1
28 */
29 class Menu {
30 use GetInstance;
31
32 /**
33 * Admin page hooks that render the SureCookie app.
34 *
35 * @since 1.4.0
36 */
37 private const PLUGIN_SCREEN_HOOKS = [
38 'toplevel_page_surecookie',
39 'settings_page_surecookie',
40 'surecookie_page_surecookie-banner',
41 'surecookie_page_surecookie-settings',
42 'surecookie_page_surecookie-advanced',
43 ];
44
45 /**
46 * Constructor.
47 *
48 * @since 0.0.1
49 */
50 public function __construct() {
51 add_action( 'admin_menu', [ $this, 'register_admin_menu' ] );
52 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_assets' ] );
53 // Late, so it wins over plugins that enqueue on the default priority.
54 add_action( 'admin_enqueue_scripts', [ $this, 'dequeue_conflicting_styles' ], 999 );
55 add_filter( 'plugin_action_links_' . SURECOOKIE_BASE, [ $this, 'plugin_action_links' ] );
56
57 if ( ! Helper::is_pro_active() && Settings::get( 'top_level_menu_enabled' ) ) {
58 add_action( 'admin_footer', [ $this, 'print_upgrade_submenu_assets' ] );
59 }
60 }
61
62 /**
63 * Register the admin menu.
64 *
65 * @since 0.0.1
66 * @return void
67 */
68 public function register_admin_menu(): void {
69 $show_top_level = Settings::get( 'top_level_menu_enabled' );
70
71 if ( $show_top_level ) {
72 // Resolve the unread-logs count once so the top-level attention dot
73 // and the Logs submenu badge stay in sync from a single lookup.
74 $unread_logs = $this->get_unread_logs_count();
75
76 add_menu_page(
77 'SureCookie',
78 $this->get_top_level_menu_title( $unread_logs ),
79 SURECOOKIE_CAPABILITY,
80 SURECOOKIE_PREFIX,
81 [ $this, 'render_admin_page' ],
82 'none',
83 58
84 );
85
86 $submenus = [
87 [
88 'id' => SURECOOKIE_PREFIX,
89 'page_title' => __( 'Dashboard', 'surecookie' ),
90 ],
91 [
92 'id' => SURECOOKIE_PREFIX . '#/cookie-manager/scan',
93 'page_title' => __( 'Tracking Manager', 'surecookie' ),
94 ],
95 [
96 'id' => SURECOOKIE_PREFIX . '#/analytics',
97 'page_title' => __( 'Consent Logs', 'surecookie' ),
98 'menu_title' => $this->get_logs_submenu_title( $unread_logs ),
99 ],
100 [
101 'id' => SURECOOKIE_PREFIX . '#/data-requests',
102 'page_title' => __( 'Data Requests', 'surecookie' ),
103 'menu_title' => $this->get_data_requests_submenu_title( $this->get_open_data_requests_count() ),
104 ],
105 [
106 'id' => SURECOOKIE_PREFIX . '#/banner/content',
107 'page_title' => __( 'Settings', 'surecookie' ),
108 ],
109 [
110 'id' => SURECOOKIE_PREFIX . '#/learn',
111 'page_title' => __( 'Learn', 'surecookie' ),
112 ],
113 ];
114
115 foreach ( $submenus as $submenu ) {
116 add_submenu_page(
117 SURECOOKIE_PREFIX,
118 $submenu['page_title'],
119 $submenu['menu_title'] ?? $submenu['page_title'],
120 SURECOOKIE_CAPABILITY,
121 $submenu['id'],
122 [ $this, 'render_admin_page' ]
123 );
124 }
125
126 if ( ! Helper::is_pro_active() ) {
127 $this->register_upgrade_submenu();
128 }
129
130 return;
131 }
132
133 add_options_page(
134 'SureCookie',
135 'SureCookie',
136 SURECOOKIE_CAPABILITY,
137 SURECOOKIE_PREFIX,
138 [ $this, 'render_admin_page' ]
139 );
140 }
141
142 /**
143 * Render the admin page.
144 *
145 * @since 0.0.1
146 * @return void
147 */
148 public function render_admin_page(): void {
149 if ( ! current_user_can( SURECOOKIE_CAPABILITY ) ) {
150 wp_die( esc_html__( 'You don\'t have access to this page.', 'surecookie' ) );
151 }
152
153 echo '<div class="wrap">';
154 echo '<div id="surecookie-admin-root"></div>';
155 echo '</div>';
156 }
157
158 /**
159 * Enqueue admin assets.
160 *
161 * @since 0.0.1
162 * @param string $hook The current admin page.
163 * @return void
164 */
165 public function enqueue_admin_assets( $hook ): void {
166 $this->enqueue_admin_menu_icon_style();
167
168 if ( ! in_array( $hook, self::PLUGIN_SCREEN_HOOKS, true ) ) {
169 return;
170 }
171
172 $asset_file = SURECOOKIE_DIR . 'build/admin.asset.php';
173
174 if ( ! file_exists( $asset_file ) ) {
175 return;
176 }
177
178 $assets = require $asset_file;
179 $extra_dependencies = [ 'updates' ];
180
181 // Enqueue WordPress media uploader.
182 wp_enqueue_media();
183
184 // Enqueue CodeMirror for CSS editor.
185 wp_enqueue_code_editor( [ 'type' => 'text/css' ] );
186
187 wp_enqueue_script(
188 'surecookie-admin',
189 SURECOOKIE_URL . 'build/admin.js',
190 array_merge( $assets['dependencies'] ?? [], $extra_dependencies ),
191 $assets['version'] ?? SURECOOKIE_VERSION,
192 true
193 );
194 wp_set_script_translations( 'surecookie-admin', 'surecookie', SURECOOKIE_DIR . 'languages' );
195
196 wp_enqueue_style(
197 'surecookie-admin',
198 SURECOOKIE_URL . 'build/' . Get::admin_style_css(),
199 [],
200 SURECOOKIE_VERSION
201 );
202
203 wp_enqueue_style(
204 'surecookie-jodit-library',
205 SURECOOKIE_URL . 'assets/css/' . Get::jodit_style_css(),
206 [],
207 SURECOOKIE_VERSION . '-jodit-4.12.18'
208 );
209
210 wp_enqueue_style(
211 'surecookie-admin-styles',
212 SURECOOKIE_URL . 'assets/css/' . Get::shared_style_css(),
213 [ 'surecookie-admin' ],
214 SURECOOKIE_VERSION
215 );
216
217 // Add palette CSS variables from stored option.
218 $palette_css = Sanitize::stylesheet( Get::palette_root_css() );
219 if ( ! empty( $palette_css ) ) {
220 wp_add_inline_style( 'surecookie-admin', wp_strip_all_tags( $palette_css ) );
221 }
222
223 do_action( 'surecookie_admin_enqueue_scripts_after', $hook );
224
225 // Localize admin data using utility.
226 LocalizeData::localize_admin_script( 'surecookie-admin' );
227 }
228
229 /**
230 * Drop other plugins' unscoped stylesheets from SureCookie's own screens.
231 *
232 * MemberPress Courses enqueues simplegrid.css on EVERY admin page; its
233 * generic selectors (`.grid`, `[class*='col-']`) restyle Tailwind's grid
234 * and col-span utilities and mangle this app's layout (ticket 1507247).
235 * `mpcs-admin-shared` lists simplegrid as a dependency, so it has to go
236 * too or WordPress prints simplegrid right back.
237 *
238 * @since 1.4.0
239 * @param string $hook The current admin page.
240 * @return void
241 */
242 public function dequeue_conflicting_styles( $hook ): void {
243 if ( ! in_array( $hook, self::PLUGIN_SCREEN_HOOKS, true ) ) {
244 return;
245 }
246
247 foreach ( [ 'mpcs-admin-shared', 'mpcs-simplegrid', 'mepr-simplegrid' ] as $handle ) {
248 wp_dequeue_style( $handle );
249 }
250 }
251
252 /**
253 * Print styles and a click handler that open the Upgrade submenu in a new tab.
254 *
255 * Runs on every admin page because the submenu appears in the sidebar site-wide.
256 * The CSS/JS selectors are scoped to `#toplevel_page_surecookie` so there is no
257 * side effect on other admin screens.
258 *
259 * @since 1.0.0
260 * @return void
261 */
262 public function print_upgrade_submenu_assets(): void {
263 ?>
264 <style>
265 #adminmenu #toplevel_page_surecookie .wp-submenu a[href*="surecookie.com/pricing"] {
266 background-color: #377A00 !important;
267 color: #ffffff !important;
268 font-weight: 500;
269 font-size: 13px;
270 line-height: 20px;
271 padding-right: 12px !important;
272 padding-left: 12px !important;
273 }
274 #adminmenu #toplevel_page_surecookie .wp-submenu a[href*="surecookie.com/pricing"]:hover,
275 #adminmenu #toplevel_page_surecookie .wp-submenu a[href*="surecookie.com/pricing"]:focus {
276 background-color: #2F6A00 !important;
277 color: #ffffff !important;
278 }
279 </style>
280 <script type="text/javascript">
281 document.addEventListener( 'DOMContentLoaded', function () {
282 var link = document.querySelector( '#adminmenu #toplevel_page_surecookie .wp-submenu a[href*="surecookie.com/pricing"]' );
283 if ( ! link ) {
284 return;
285 }
286 link.addEventListener( 'click', function ( e ) {
287 e.preventDefault();
288 window.open( link.href, '_blank', 'noopener,noreferrer' );
289 } );
290 } );
291 </script>
292 <?php
293 }
294
295 /**
296 * Add action links to the plugin list page.
297 *
298 * @since 0.0.1
299 * @param array<string, string> $links Existing action links.
300 * @return array<string, string> Modified action links.
301 */
302 public function plugin_action_links( $links ): array {
303 $admin_url = admin_url( 'admin.php' );
304
305 $new_links = [
306 'settings' => sprintf(
307 '<a href="%s">%s</a>',
308 esc_url( add_query_arg( 'page', SURECOOKIE_PREFIX, $admin_url ) . '#/banner/content' ),
309 esc_html__( 'Settings', 'surecookie' )
310 ),
311 ];
312
313 return array_merge( $new_links, $links );
314 }
315
316 /**
317 * Register the "Upgrade" submenu under SureCookie.
318 *
319 * Uses a stable internal slug so that WordPress-generated hook names
320 * (`load-{$slug}`, `admin_page_{$slug}`, etc.) stay clean. The external
321 * pricing URL is then swapped into the `$submenu` global so WordPress
322 * renders the item as an external link. The JS click handler printed in
323 * `print_upgrade_submenu_assets()` intercepts the click and opens it in a
324 * new tab, so the page is never actually navigated to - `'__return_null'`
325 * is therefore a safe no-op callback.
326 *
327 * @since 1.0.0
328 * @return void
329 */
330 private function register_upgrade_submenu(): void {
331 $upgrade_slug = SURECOOKIE_PREFIX . '_upgrade';
332
333 add_submenu_page(
334 SURECOOKIE_PREFIX,
335 __( 'Upgrade', 'surecookie' ),
336 __( 'Upgrade', 'surecookie' ),
337 SURECOOKIE_CAPABILITY,
338 $upgrade_slug,
339 '__return_null'
340 );
341
342 $upgrade_url = Helper::get_marketing_link(
343 'pricing/',
344 'pricing_submenu_link_upgrade'
345 );
346
347 // Swap the internal slug with the external pricing URL. Writing to the
348 // $submenu global is the canonical WP pattern for linking a submenu item
349 // to an external URL without polluting hook names with query strings.
350 global $submenu;
351
352 if ( ! isset( $submenu[ SURECOOKIE_PREFIX ] ) || ! is_array( $submenu[ SURECOOKIE_PREFIX ] ) ) {
353 return;
354 }
355
356 foreach ( $submenu[ SURECOOKIE_PREFIX ] as $key => $item ) {
357 if ( isset( $item[2] ) && $upgrade_slug === $item[2] ) {
358 // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Intentional: swap internal slug for external upgrade URL.
359 $submenu[ SURECOOKIE_PREFIX ][ $key ][2] = $upgrade_url;
360 break;
361 }
362 }
363 }
364
365 /**
366 * Enqueue the inline style used for the top-level admin menu icon.
367 *
368 * @since 0.0.1
369 * @return void
370 */
371 private function enqueue_admin_menu_icon_style(): void {
372 if ( ! is_admin() || ! current_user_can( SURECOOKIE_CAPABILITY ) ) {
373 return;
374 }
375
376 if ( ! Settings::get( 'top_level_menu_enabled' ) ) {
377 return;
378 }
379
380 wp_register_style( 'surecookie-admin-menu-icon', false, [], SURECOOKIE_VERSION );
381 wp_enqueue_style( 'surecookie-admin-menu-icon' );
382 wp_add_inline_style( 'surecookie-admin-menu-icon', $this->get_admin_menu_icon_css() );
383 wp_add_inline_style( 'surecookie-admin-menu-icon', $this->get_admin_menu_separator_css() );
384 wp_add_inline_style( 'surecookie-admin-menu-icon', $this->get_admin_menu_dot_css() );
385 }
386
387 /**
388 * Count the current user's unread consent logs.
389 *
390 * Centralizes the capability check and count lookup so the top-level menu
391 * attention dot and the Logs submenu badge are driven by a single query.
392 *
393 * @since 1.2.3
394 * @return int
395 */
396 private function get_unread_logs_count(): int {
397 if ( ! current_user_can( SURECOOKIE_CAPABILITY ) ) {
398 return 0;
399 }
400
401 return ConsentLog::count_unread_logs_for_user( get_current_user_id() );
402 }
403
404 /**
405 * Build the top-level menu title, appending an attention dot for unread logs.
406 *
407 * The dot mirrors the pattern used across BSF plugins (e.g. SureForms) to
408 * flag unseen activity on the parent menu item. It is removed client-side
409 * once the Logs page is viewed (see AdminApp.jsx) and stops rendering on the
410 * next load once the logs are marked as viewed server-side.
411 *
412 * @since 1.2.3
413 * @param int $unread_count Number of unread consent logs.
414 * @return string
415 */
416 private function get_top_level_menu_title( int $unread_count ): string {
417 $label = 'SureCookie';
418
419 if ( $unread_count <= 0 ) {
420 return $label;
421 }
422
423 return $label . ' <span class="surecookie-update-dot" data-surecookie-logs-dot="true" aria-hidden="true"></span>';
424 }
425
426 /**
427 * Count the data requests still awaiting action.
428 *
429 * Free ships no data-request storage, so the number comes from Pro through
430 * the filter; without Pro it stays 0 and the submenu shows the "New" badge.
431 *
432 * @since 1.4.0
433 * @return int
434 */
435 private function get_open_data_requests_count(): int {
436 if ( ! current_user_can( SURECOOKIE_CAPABILITY ) ) {
437 return 0;
438 }
439
440 return max( 0, (int) apply_filters( 'surecookie_open_data_requests_count', 0 ) );
441 }
442
443 /**
444 * Build the Data Requests submenu title.
445 *
446 * Mirrors the Consent Logs badge: an attention count when requests are
447 * waiting, and a "New" pill in its place while there are none, so the
448 * feature is still discoverable on a site that has never received one.
449 *
450 * @since 1.4.0
451 * @param int $open_count Number of data requests awaiting action.
452 * @return string
453 */
454 private function get_data_requests_submenu_title( int $open_count ): string {
455 $label = __( 'Data Requests', 'surecookie' );
456
457 if ( $open_count <= 0 ) {
458 return sprintf(
459 '%1$s <span class="surecookie-new-badge">%2$s</span>',
460 $label,
461 esc_html__( 'NEW', 'surecookie' )
462 );
463 }
464
465 return sprintf(
466 '%1$s <span class="update-plugins count-%2$d" data-surecookie-data-requests-badge="true"><span class="plugin-count">%3$s</span></span>',
467 $label,
468 $open_count,
469 esc_html( number_format_i18n( $open_count ) )
470 );
471 }
472
473 /**
474 * Build the Logs submenu title with an unread-count badge when needed.
475 *
476 * @since 1.2.0
477 * @since 1.2.3 Accepts the pre-computed unread count instead of querying it.
478 * @param int $unread_count Number of unread consent logs.
479 * @return string
480 */
481 private function get_logs_submenu_title( int $unread_count ): string {
482 $label = __( 'Consent Logs', 'surecookie' );
483
484 if ( $unread_count <= 0 ) {
485 return $label;
486 }
487
488 return sprintf(
489 '%1$s <span class="update-plugins count-%2$d" data-surecookie-logs-badge="true"><span class="plugin-count">%3$s</span></span>',
490 $label,
491 $unread_count,
492 esc_html( number_format_i18n( $unread_count ) )
493 );
494 }
495
496 /**
497 * Build the submenu group-separator stylesheet.
498 *
499 * @since 1.1.0
500 * @return string
501 */
502 private function get_admin_menu_separator_css(): string {
503 return '#toplevel_page_surecookie li {
504 clear: both;
505 }
506 #toplevel_page_surecookie li:not(:last-child) a[href^="admin.php?page=surecookie"]:after {
507 border-bottom: 1px solid hsla(0,0%,100%,.2);
508 display: block;
509 float: left;
510 margin: 13px -15px 8px;
511 content: "";
512 width: calc(100% + 26px);
513 }
514 #toplevel_page_surecookie li:not(:last-child) a[href="admin.php?page=surecookie"]:after,
515 #toplevel_page_surecookie li:not(:last-child) a[href^="admin.php?page=surecookie#/analytics"]:after,
516 #toplevel_page_surecookie li:not(:last-child) a[href^="admin.php?page=surecookie#/learn"]:after,
517 #toplevel_page_surecookie li:not(:last-child) a[href^="admin.php?page=surecookie#/banner/content"]:after {
518 content: none;
519 }';
520 }
521
522 /**
523 * Build the unread-logs attention dot stylesheet for the top-level menu.
524 *
525 * @since 1.2.3
526 * @return string
527 */
528 private function get_admin_menu_dot_css(): string {
529 return '#toplevel_page_surecookie .wp-menu-name .surecookie-update-dot {
530 display: inline-block;
531 width: 8px;
532 height: 8px;
533 margin-left: 6px;
534 border-radius: 50%;
535 background: #d63638;
536 vertical-align: middle;
537 }
538 #toplevel_page_surecookie .wp-submenu .surecookie-new-badge {
539 background-color: #377a00;
540 font-size: 9px;
541 color: #fff;
542 padding: 2px 4px;
543 margin-left: 4px;
544 border-radius: 4px;
545 font-weight: 600;
546 }';
547 }
548
549 /**
550 * Build the admin menu icon stylesheet.
551 *
552 * @since 0.0.1
553 * @return string
554 */
555 private function get_admin_menu_icon_css(): string {
556 $icon_svg = 'data:image/svg+xml;base64,' . base64_encode( '<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 256 256" fill="none"><path d="M97.0156 9.74499C120.404 0.0570803 146.141 -2.47884 170.971 2.45983C195.8 7.39873 218.609 19.59 236.51 37.4911L200.307 73.6942C189.566 62.9535 175.88 55.64 160.982 52.6766C146.085 49.7134 130.643 51.233 116.609 57.0458C102.576 62.8586 90.5814 72.7032 82.1426 85.3329C73.7038 97.9625 69.1992 112.811 69.1992 128.001C69.1992 140.594 72.2983 152.952 78.166 164.007C78.2596 164.006 78.3534 164.001 78.4473 164.001C89.4146 164.001 98.5033 172.026 100.17 182.524C105.185 179.335 111.141 177.497 117.525 177.518C133.572 177.572 146.835 189.36 149.221 204.729C153.155 204.564 157.087 204.1 160.982 203.325C175.88 200.362 189.566 193.046 200.307 182.306L236.51 218.511C218.609 236.412 195.8 248.603 170.971 253.542C146.141 258.48 120.404 255.945 97.0156 246.257C73.6273 236.569 53.6369 220.163 39.5723 199.114C25.5075 178.065 18 153.317 18 128.001C18 102.685 25.5074 77.9371 39.5723 56.8876C53.6369 35.8385 73.6272 19.433 97.0156 9.74499Z" fill="#A0A5AA"/><path d="M164 140.001C170.627 140.001 176 145.373 176 152.001C176 158.628 170.627 164.001 164 164.001C157.373 164.001 152 158.628 152 152.001C152 145.373 157.373 140.001 164 140.001Z" fill="#A0A5AA"/><path d="M108 108.001C114.627 108.001 120 113.373 120 120.001C120 126.628 114.627 132.001 108 132.001C101.373 132.001 96.0004 126.628 96 120.001C96 113.373 101.373 108.001 108 108.001Z" fill="#A0A5AA"/><path d="M152 76.0008C158.627 76.0008 164 81.3734 164 88.0008C164 94.6279 158.627 100.001 152 100.001C145.373 100.001 140 94.6279 140 88.0008C140 81.3734 145.373 76.0008 152 76.0008Z" fill="#A0A5AA"/></svg>' );
557 $active_icon_svg = 'data:image/svg+xml;base64,' . base64_encode( '<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 256 256" fill="none"><path d="M97.0156 9.74499C120.404 0.0570803 146.141 -2.47884 170.971 2.45983C195.8 7.39873 218.609 19.59 236.51 37.4911L200.307 73.6942C189.566 62.9535 175.88 55.64 160.982 52.6766C146.085 49.7134 130.643 51.233 116.609 57.0458C102.576 62.8586 90.5814 72.7032 82.1426 85.3329C73.7038 97.9625 69.1992 112.811 69.1992 128.001C69.1992 140.594 72.2983 152.952 78.166 164.007C78.2596 164.006 78.3534 164.001 78.4473 164.001C89.4146 164.001 98.5033 172.026 100.17 182.524C105.185 179.335 111.141 177.497 117.525 177.518C133.572 177.572 146.835 189.36 149.221 204.729C153.155 204.564 157.087 204.1 160.982 203.325C175.88 200.362 189.566 193.046 200.307 182.306L236.51 218.511C218.609 236.412 195.8 248.603 170.971 253.542C146.141 258.48 120.404 255.945 97.0156 246.257C73.6273 236.569 53.6369 220.163 39.5723 199.114C25.5075 178.065 18 153.317 18 128.001C18 102.685 25.5074 77.9371 39.5723 56.8876C53.6369 35.8385 73.6272 19.433 97.0156 9.74499Z" fill="#FFFFFF"/><path d="M164 140.001C170.627 140.001 176 145.373 176 152.001C176 158.628 170.627 164.001 164 164.001C157.373 164.001 152 158.628 152 152.001C152 145.373 157.373 140.001 164 140.001Z" fill="#FFFFFF"/><path d="M108 108.001C114.627 108.001 120 113.373 120 120.001C120 126.628 114.627 132.001 108 132.001C101.373 132.001 96.0004 126.628 96 120.001C96 113.373 101.373 108.001 108 108.001Z" fill="#FFFFFF"/><path d="M152 76.0008C158.627 76.0008 164 81.3734 164 88.0008C164 94.6279 158.627 100.001 152 100.001C145.373 100.001 140 94.6279 140 88.0008C140 81.3734 145.373 76.0008 152 76.0008Z" fill="#FFFFFF"/></svg>' );
558
559 return implode(
560 "\n",
561 [
562 '#toplevel_page_surecookie .wp-menu-image:before {',
563 "\tcontent: '';",
564 "\tmask-image: url(" . wp_json_encode( $icon_svg ) . ');',
565 "\tmask-size: contain;",
566 "\tmask-repeat: no-repeat;",
567 "\tmask-position: center;",
568 "\tbackground-color: currentColor;",
569 '}',
570 '#toplevel_page_surecookie .wp-menu-image {',
571 "\talign-content: center;",
572 '}',
573 '#toplevel_page_surecookie.current .wp-menu-image:before,',
574 '#toplevel_page_surecookie.wp-has-current-submenu .wp-menu-image:before {',
575 "\tmask-image: url(" . wp_json_encode( $active_icon_svg ) . ');',
576 '}',
577 ]
578 );
579 }
580 }
581