Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/google-site-kit/includes/Core/Admin/Screens.php
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
<?php
2
+
/**
3
+
* Class Google\Site_Kit\Core\Admin\Screens
4
+
*
5
+
* @package Google\Site_Kit
6
+
* @copyright 2021 Google LLC
7
+
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
8
+
* @link https://sitekit.withgoogle.com
9
+
*/
10
+
11
+
namespace Google\Site_Kit\Core\Admin;
12
+
13
+
use Google\Site_Kit\Context;
14
+
use Google\Site_Kit\Core\Assets\Assets;
15
+
use Google\Site_Kit\Core\Authentication\Authentication;
16
+
use Google\Site_Kit\Core\Dismissals\Dismissed_Items;
17
+
use Google\Site_Kit\Core\Key_Metrics\Key_Metrics_Setup_Completed_By;
18
+
use Google\Site_Kit\Core\Modules\Modules;
19
+
use Google\Site_Kit\Core\Permissions\Permissions;
20
+
use Google\Site_Kit\Core\Storage\Options;
21
+
use Google\Site_Kit\Core\Storage\User_Options;
22
+
use Google\Site_Kit\Core\User\Initial_Setup_Settings;
23
+
use Google\Site_Kit\Core\Util\Feature_Flags;
24
+
25
+
/**
26
+
* Class managing admin screens.
27
+
*
28
+
* @since 1.0.0
29
+
* @access private
30
+
* @ignore
31
+
*/
32
+
final class Screens {
33
+
34
+
const PREFIX = 'googlesitekit-';
35
+
const PARENT_SLUG_NULL = self::PREFIX . 'null';
36
+
37
+
/**
38
+
* Plugin context.
39
+
*
40
+
* @since 1.0.0
41
+
* @var Context
42
+
*/
43
+
private $context;
44
+
45
+
/**
46
+
* Assets API instance.
47
+
*
48
+
* @since 1.0.0
49
+
* @var Assets
50
+
*/
51
+
private $assets;
52
+
53
+
/**
54
+
* Modules instance.
55
+
*
56
+
* @since 1.7.0
57
+
* @var Modules
58
+
*/
59
+
private $modules;
60
+
61
+
/**
62
+
* Authentication instance.
63
+
*
64
+
* @since 1.72.0
65
+
* @var Authentication
66
+
*/
67
+
private $authentication;
68
+
69
+
/**
70
+
* User_Options instance.
71
+
*
72
+
* @since 1.167.0
73
+
* @var User_Options
74
+
*/
75
+
private $user_options;
76
+
77
+
/**
78
+
* Associative array of $hook_suffix => $screen pairs.
79
+
*
80
+
* @since 1.0.0
81
+
* @var array
82
+
*/
83
+
private $screens = array();
84
+
85
+
/**
86
+
* Constructor.
87
+
*
88
+
* @since 1.0.0
89
+
*
90
+
* @param Context $context Plugin context.
91
+
* @param Assets $assets Optional. Assets API instance. Default is a new instance.
92
+
* @param Modules $modules Optional. Modules instance. Default is a new instance.
93
+
* @param Authentication $authentication Optional. Authentication instance. Default is a new instance.
94
+
* @param User_Options $user_options Optional. User_Options instance. Default is a new instance.
95
+
*/
96
+
public function __construct(
97
+
Context $context,
98
+
?Assets $assets = null,
99
+
?Modules $modules = null,
100
+
?Authentication $authentication = null,
101
+
?User_Options $user_options = null
102
+
) {
103
+
$this->context = $context;
104
+
$this->assets = $assets ?: new Assets( $this->context );
105
+
$this->modules = $modules ?: new Modules( $this->context );
106
+
$this->authentication = $authentication ?: new Authentication( $this->context );
107
+
$this->user_options = $user_options ?: new User_Options( $this->context );
108
+
}
109
+
110
+
/**
111
+
* Registers functionality through WordPress hooks.
112
+
*
113
+
* @since 1.0.0
114
+
*/
115
+
public function register() {
116
+
if ( $this->context->is_network_mode() ) {
117
+
add_action(
118
+
'network_admin_menu',
119
+
function () {
120
+
$this->add_screens();
121
+
}
122
+
);
123
+
}
124
+
125
+
add_action(
126
+
'admin_menu',
127
+
function () {
128
+
$this->add_screens();
129
+
}
130
+
);
131
+
132
+
add_action(
133
+
'admin_enqueue_scripts',
134
+
function ( $hook_suffix ) {
135
+
$this->enqueue_screen_assets( $hook_suffix );
136
+
}
137
+
);
138
+
139
+
add_action(
140
+
'admin_page_access_denied',
141
+
function () {
142
+
// Redirect dashboard to splash if no dashboard access (yet).
143
+
$this->no_access_redirect_dashboard_to_splash();
144
+
// Redirect splash to (shared) dashboard if splash is dismissed.
145
+
$this->no_access_redirect_splash_to_dashboard();
146
+
147
+
// Redirect module pages to dashboard.
148
+
$this->no_access_redirect_module_to_dashboard();
149
+
}
150
+
);
151
+
152
+
// Ensure the menu icon always is rendered correctly, without enqueueing a global CSS file.
153
+
add_action(
154
+
'admin_head',
155
+
function () {
156
+
?>
157
+
<style type="text/css">
158
+
#adminmenu .toplevel_page_googlesitekit-dashboard img {
159
+
width: 16px;
160
+
}
161
+
#adminmenu .toplevel_page_googlesitekit-dashboard.current img,
162
+
#adminmenu .toplevel_page_googlesitekit-dashboard.wp-has-current-submenu img {
163
+
opacity: 1;
164
+
}
165
+
</style>
166
+
<?php
167
+
}
168
+
);
169
+
170
+
$remove_notices_callback = function () {
171
+
global $hook_suffix;
172
+
173
+
if ( empty( $hook_suffix ) ) {
174
+
return;
175
+
}
176
+
177
+
if ( isset( $this->screens[ $hook_suffix ] ) ) {
178
+
remove_all_actions( current_action() );
179
+
}
180
+
};
181
+
add_action( 'admin_notices', $remove_notices_callback, -9999 );
182
+
add_action( 'network_admin_notices', $remove_notices_callback, -9999 );
183
+
add_action( 'all_admin_notices', $remove_notices_callback, -9999 );
184
+
185
+
add_filter( 'custom_menu_order', '__return_true' );
186
+
add_filter(
187
+
'menu_order',
188
+
function ( array $menu_order ) {
189
+
// Move the Site Kit dashboard menu item to be one after the index.php item if it exists.
190
+
$dashboard_index = array_search( 'index.php', $menu_order, true );
191
+
192
+
$sitekit_index = false;
193
+
foreach ( $menu_order as $key => $value ) {
194
+
if ( strpos( $value, self::PREFIX ) === 0 ) {
195
+
$sitekit_index = $key;
196
+
$sitekit_value = $value;
197
+
break;
198
+
}
199
+
}
200
+
201
+
if ( false === $dashboard_index || false === $sitekit_index ) {
202
+
return $menu_order;
203
+
}
204
+
unset( $menu_order[ $sitekit_index ] );
205
+
array_splice( $menu_order, $dashboard_index + 1, 0, $sitekit_value );
206
+
return $menu_order;
207
+
}
208
+
);
209
+
}
210
+
211
+
/**
212
+
* Gets the Screen instance for a given hook suffix.
213
+
*
214
+
* @since 1.11.0
215
+
*
216
+
* @param string $hook_suffix The hook suffix associated with the screen to retrieve.
217
+
* @return Screen|null Screen instance if available, otherwise null;
218
+
*/
219
+
public function get_screen( $hook_suffix ) {
220
+
return isset( $this->screens[ $hook_suffix ] ) ? $this->screens[ $hook_suffix ] : null;
221
+
}
222
+
223
+
/**
224
+
* Adds all screens to the admin.
225
+
*
226
+
* @since 1.0.0
227
+
*/
228
+
private function add_screens() {
229
+
$screens = $this->get_screens();
230
+
231
+
array_walk( $screens, array( $this, 'add_screen' ) );
232
+
}
233
+
234
+
/**
235
+
* Adds the given screen to the admin.
236
+
*
237
+
* @since 1.0.0
238
+
*
239
+
* @param Screen $screen Screen to add.
240
+
*/
241
+
private function add_screen( Screen $screen ) {
242
+
$hook_suffix = $screen->add( $this->context );
243
+
if ( empty( $hook_suffix ) ) {
244
+
return;
245
+
}
246
+
247
+
add_action(
248
+
"load-{$hook_suffix}",
249
+
function () use ( $screen ) {
250
+
$screen->initialize( $this->context );
251
+
}
252
+
);
253
+
254
+
$this->screens[ $hook_suffix ] = $screen;
255
+
}
256
+
257
+
/**
258
+
* Enqueues assets if a plugin screen matches the given hook suffix.
259
+
*
260
+
* @since 1.0.0
261
+
*
262
+
* @param string $hook_suffix Hook suffix for the current admin screen.
263
+
*/
264
+
private function enqueue_screen_assets( $hook_suffix ) {
265
+
if ( ! isset( $this->screens[ $hook_suffix ] ) ) {
266
+
return;
267
+
}
268
+
269
+
$this->screens[ $hook_suffix ]->enqueue_assets( $this->assets );
270
+
$this->modules->enqueue_assets();
271
+
}
272
+
273
+
/**
274
+
* Redirects from the dashboard to the splash screen if permissions to access the dashboard are currently not met.
275
+
*
276
+
* Dashboard permission access is conditional based on whether the user has successfully authenticated. When
277
+
* e.g. accessing the dashboard manually or having it open in a separate tab while disconnecting in the other tab,
278
+
* it is a better user experience to redirect to the splash screen so that the user can re-authenticate.
279
+
*
280
+
* The only time the dashboard should fail with the regular WordPress permissions error is when the current user is
281
+
* not eligible for accessing Site Kit entirely, i.e. if they are not allowed to authenticate.
282
+
*
283
+
* @since 1.12.0
284
+
*/
285
+
private function no_access_redirect_dashboard_to_splash() {
286
+
global $plugin_page;
287
+
288
+
// At this point, our preferred `$hook_suffix` is not set, and the dashboard page will not even be registered,
289
+
// so we need to rely on the `$plugin_page` global here.
290
+
if ( ! isset( $plugin_page ) || self::PREFIX . 'dashboard' !== $plugin_page ) {
291
+
return;
292
+
}
293
+
294
+
if ( current_user_can( Permissions::VIEW_SPLASH ) ) {
295
+
wp_safe_redirect(
296
+
$this->context->admin_url( 'splash' )
297
+
);
298
+
exit;
299
+
}
300
+
}
301
+
302
+
/**
303
+
* Redirects from the splash to the dashboard screen if permissions to access the splash are currently not met.
304
+
*
305
+
* Admins always have the ability to view the splash page, so this redirects non-admins who have access
306
+
* to view the shared dashboard if the splash has been dismissed.
307
+
* Currently the dismissal check is built into the capability for VIEW_SPLASH so this is implied.
308
+
*
309
+
* @since 1.77.0
310
+
*/
311
+
private function no_access_redirect_splash_to_dashboard() {
312
+
global $plugin_page;
313
+
314
+
if ( ! isset( $plugin_page ) || self::PREFIX . 'splash' !== $plugin_page ) {
315
+
return;
316
+
}
317
+
318
+
if ( current_user_can( Permissions::VIEW_DASHBOARD ) ) {
319
+
wp_safe_redirect(
320
+
$this->context->admin_url()
321
+
);
322
+
exit;
323
+
}
324
+
}
325
+
326
+
/**
327
+
* Redirects module pages to the dashboard or splash based on user capability.
328
+
*
329
+
* @since 1.69.0
330
+
*/
331
+
private function no_access_redirect_module_to_dashboard() {
332
+
global $plugin_page;
333
+
334
+
$legacy_module_pages = array(
335
+
self::PREFIX . 'module-adsense',
336
+
self::PREFIX . 'module-analytics',
337
+
self::PREFIX . 'module-search-console',
338
+
);
339
+
340
+
if ( ! in_array( $plugin_page, $legacy_module_pages, true ) ) {
341
+
return;
342
+
}
343
+
344
+
// Note: the use of add_query_arg is intentional below because it preserves
345
+
// the current query parameters in the URL.
346
+
if ( current_user_can( Permissions::VIEW_DASHBOARD ) ) {
347
+
wp_safe_redirect(
348
+
add_query_arg( 'page', self::PREFIX . 'dashboard' )
349
+
);
350
+
exit;
351
+
}
352
+
353
+
if ( current_user_can( Permissions::VIEW_SPLASH ) ) {
354
+
wp_safe_redirect(
355
+
add_query_arg( 'page', self::PREFIX . 'splash' )
356
+
);
357
+
exit;
358
+
}
359
+
}
360
+
361
+
/**
362
+
* Gets available admin screens.
363
+
*
364
+
* @since 1.0.0
365
+
*
366
+
* @return array List of Screen instances.
367
+
*/
368
+
private function get_screens() {
369
+
$show_splash_in_menu = current_user_can( Permissions::VIEW_SPLASH ) && ! current_user_can( Permissions::VIEW_DASHBOARD );
370
+
371
+
$screens = array(
372
+
new Screen(
373
+
self::PREFIX . 'dashboard',
374
+
array(
375
+
'title' => __( 'Dashboard', 'google-site-kit' ),
376
+
'capability' => Permissions::VIEW_DASHBOARD,
377
+
'enqueue_callback' => function ( Assets $assets ) {
378
+
if ( $this->context->input()->filter( INPUT_GET, 'permaLink' ) ) {
379
+
$assets->enqueue_asset( 'googlesitekit-entity-dashboard' );
380
+
} else {
381
+
$assets->enqueue_asset( 'googlesitekit-main-dashboard' );
382
+
}
383
+
},
384
+
'initialize_callback' => function ( Context $context ) {
385
+
if ( ! Feature_Flags::enabled( 'setupFlowRefresh' ) ) {
386
+
return;
387
+
}
388
+
389
+
$is_view_only = ! $this->authentication->is_authenticated();
390
+
391
+
if ( ! $is_view_only ) {
392
+
$initial_setup_settings = ( new Initial_Setup_Settings( $this->user_options ) )->get();
393
+
$is_analytics_setup_complete = $initial_setup_settings['isAnalyticsSetupComplete'];
394
+
395
+
if ( false === $is_analytics_setup_complete ) {
396
+
$is_analytics_connected = $this->modules->is_module_connected( 'analytics-4' );
397
+
398
+
if ( $is_analytics_connected ) {
399
+
wp_safe_redirect(
400
+
$context->admin_url(
401
+
'key-metrics-setup',
402
+
array(
403
+
'showProgress' => 'true',
404
+
)
405
+
)
406
+
);
407
+
408
+
exit;
409
+
} else {
410
+
$slug = $context->input()->filter( INPUT_GET, 'slug' );
411
+
$show_progress = $context->input()->filter( INPUT_GET, 'showProgress', FILTER_VALIDATE_BOOLEAN );
412
+
$re_auth = $context->input()->filter( INPUT_GET, 'reAuth', FILTER_VALIDATE_BOOLEAN );
413
+
414
+
if ( 'analytics-4' === $slug && $re_auth && $show_progress ) {
415
+
return;
416
+
}
417
+
418
+
wp_safe_redirect(
419
+
$context->admin_url(
420
+
'dashboard',
421
+
array(
422
+
'slug' => 'analytics-4',
423
+
'showProgress' => 'true',
424
+
'reAuth' => 'true',
425
+
)
426
+
)
427
+
);
428
+
429
+
exit;
430
+
}
431
+
}
432
+
}
433
+
},
434
+
'render_callback' => function ( Context $context ) {
435
+
$is_view_only = ! $this->authentication->is_authenticated();
436
+
437
+
$setup_slug = htmlspecialchars( $context->input()->filter( INPUT_GET, 'slug' ) ?: '' );
438
+
$reauth = $context->input()->filter( INPUT_GET, 'reAuth', FILTER_VALIDATE_BOOLEAN );
439
+
if ( $context->input()->filter( INPUT_GET, 'permaLink' ) ) {
440
+
?>
441
+
<div id="js-googlesitekit-entity-dashboard" data-view-only="<?php echo esc_attr( $is_view_only ); ?>" class="googlesitekit-page"></div>
442
+
<?php
443
+
} else {
444
+
$setup_module_slug = $setup_slug && $reauth ? $setup_slug : '';
445
+
446
+
if ( $setup_module_slug ) {
447
+
$active_modules = $this->modules->get_active_modules();
448
+
449
+
if ( ! array_key_exists( $setup_module_slug, $active_modules ) ) {
450
+
try {
451
+
$module_details = $this->modules->get_module( $setup_module_slug );
452
+
/* translators: %s: The module name */
453
+
$message = sprintf( __( 'The %s module cannot be set up as it has not been activated yet.', 'google-site-kit' ), $module_details->name );
454
+
} catch ( \Exception $e ) {
455
+
$message = $e->getMessage();
456
+
}
457
+
458
+
wp_die( sprintf( '<span class="googlesitekit-notice">%s</span>', esc_html( $message ) ), 403 );
459
+
}
460
+
}
461
+
?>
462
+
<div id="js-googlesitekit-main-dashboard" data-view-only="<?php echo esc_attr( $is_view_only ); ?>" data-setup-module-slug="<?php echo esc_attr( $setup_module_slug ); ?>" class="googlesitekit-page"></div>
463
+
<?php
464
+
}
465
+
},
466
+
)
467
+
),
468
+
new Screen(
469
+
self::PREFIX . 'splash',
470
+
array(
471
+
'title' => __( 'Dashboard', 'google-site-kit' ),
472
+
'capability' => Permissions::VIEW_SPLASH,
473
+
'parent_slug' => $show_splash_in_menu ? Screen::MENU_SLUG : self::PARENT_SLUG_NULL,
474
+
// This callback will redirect to the dashboard on successful authentication.
475
+
'initialize_callback' => function ( Context $context ) {
476
+
// Get the dismissed items for this user.
477
+
$user_options = new User_Options( $context );
478
+
$dismissed_items = new Dismissed_Items( $user_options );
479
+
480
+
$splash_context = $context->input()->filter( INPUT_GET, 'googlesitekit_context' );
481
+
$reset_session = $context->input()->filter( INPUT_GET, 'googlesitekit_reset_session', FILTER_VALIDATE_BOOLEAN );
482
+
483
+
// If the user is authenticated, redirect them to the disconnect URL and then send them back here.
484
+
if ( ! $reset_session && 'revoked' === $splash_context && $this->authentication->is_authenticated() ) {
485
+
$this->authentication->disconnect();
486
+
487
+
wp_safe_redirect( add_query_arg( array( 'googlesitekit_reset_session' => 1 ) ) );
488
+
exit;
489
+
}
490
+
491
+
// Don't consider redirect if the current user cannot access the dashboard (yet).
492
+
if ( ! current_user_can( Permissions::VIEW_DASHBOARD ) ) {
493
+
return;
494
+
}
495
+
496
+
// Redirect to dashboard if user is authenticated or if
497
+
// they have already accessed the shared dashboard.
498
+
if (
499
+
$this->authentication->is_authenticated() ||
500
+
(
501
+
! current_user_can( Permissions::AUTHENTICATE ) &&
502
+
$dismissed_items->is_dismissed( 'shared_dashboard_splash' ) &&
503
+
current_user_can( Permissions::VIEW_SHARED_DASHBOARD )
504
+
)
505
+
) {
506
+
wp_safe_redirect(
507
+
$context->admin_url(
508
+
'dashboard',
509
+
array(
510
+
// Pass through the notification parameter, or removes it if none.
511
+
'notification' => $context->input()->filter( INPUT_GET, 'notification' ),
512
+
)
513
+
)
514
+
);
515
+
exit;
516
+
}
517
+
},
518
+
)
519
+
),
520
+
new Screen(
521
+
self::PREFIX . 'settings',
522
+
array(
523
+
'title' => __( 'Settings', 'google-site-kit' ),
524
+
'capability' => Permissions::MANAGE_OPTIONS,
525
+
)
526
+
),
527
+
);
528
+
529
+
$screens[] = new Screen(
530
+
self::PREFIX . 'user-input',
531
+
array(
532
+
'title' => __( 'User Input', 'google-site-kit' ),
533
+
'capability' => Permissions::MANAGE_OPTIONS,
534
+
'parent_slug' => self::PARENT_SLUG_NULL,
535
+
)
536
+
);
537
+
538
+
$screens[] = new Screen(
539
+
self::PREFIX . 'ad-blocking-recovery',
540
+
array(
541
+
'title' => __( 'Ad Blocking Recovery', 'google-site-kit' ),
542
+
'capability' => Permissions::MANAGE_OPTIONS,
543
+
'parent_slug' => self::PARENT_SLUG_NULL,
544
+
)
545
+
);
546
+
547
+
$screens[] = new Screen(
548
+
self::PREFIX . 'metric-selection',
549
+
array(
550
+
'title' => __( 'Select Key Metrics', 'google-site-kit' ),
551
+
'capability' => Permissions::MANAGE_OPTIONS,
552
+
'parent_slug' => self::PARENT_SLUG_NULL,
553
+
// This callback will redirect to the dashboard if key metrics is already set up.
554
+
'initialize_callback' => function ( Context $context ) {
555
+
$options = new Options( $context );
556
+
$is_key_metrics_setup = ( new Key_Metrics_Setup_Completed_By( $options ) )->get();
557
+
558
+
if ( $is_key_metrics_setup ) {
559
+
wp_safe_redirect(
560
+
$context->admin_url( 'dashboard' )
561
+
);
562
+
563
+
exit;
564
+
}
565
+
},
566
+
)
567
+
);
568
+
569
+
$screens[] = new Screen(
570
+
self::PREFIX . 'key-metrics-setup',
571
+
array(
572
+
'title' => __( 'Key Metrics Setup', 'google-site-kit' ),
573
+
'capability' => Permissions::MANAGE_OPTIONS,
574
+
'parent_slug' => self::PARENT_SLUG_NULL,
575
+
)
576
+
);
577
+
578
+
return $screens;
579
+
}
580
+
}
581
+