PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.3-beta
16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 All 507 releases
jetpack / jetpack_vendor / automattic / jetpack-my-jetpack / src / class-menu-visibility.php

class-menu-visibility.php in Jetpack – WP Security, Backup, Speed, & Growth 16.3-beta, at jetpack_vendor/automattic/jetpack-my-jetpack/src/class-menu-visibility.php

130 lines 3.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Resolves whether a Jetpack admin menu item's feature is active.
4 *
5 * @package automattic/my-jetpack
6 */
7
8 namespace Automattic\Jetpack\My_Jetpack;
9
10 use Automattic\Jetpack\Admin_UI\Admin_Menu;
11 use Automattic\Jetpack\Modules;
12
13 /**
14 * The activation half of the sidebar visibility contract.
15 *
16 * Admin_Menu owns when the question is asked and what a host may do with the answer; this
17 * class owns the answer itself, because the product classes it reads live here. A menu item
18 * declares its gate at registration and this resolves it from the same product class its
19 * My Jetpack card reads.
20 */
21 class Menu_Visibility {
22
23 /**
24 * Gates already resolved this registration pass, keyed by type and slug.
25 *
26 * @var array<string, bool|null>
27 */
28 private static $resolved = array();
29
30 /**
31 * Registers this class as Admin_Menu's visibility resolver.
32 *
33 * @return void
34 */
35 public static function init() {
36 // An older admin-ui, loaded first by another plugin, may predate the resolver; items then stay visible.
37 if ( ! method_exists( Admin_Menu::class, 'set_visibility_resolver' ) ) {
38 return;
39 }
40
41 Admin_Menu::set_visibility_resolver( array( __CLASS__, 'resolve' ) );
42
43 // Memoized answers last one registration pass, which is as long as they can stay true.
44 add_action( 'admin_menu', array( __CLASS__, 'forget_resolved_gates' ), 0 );
45 add_action( 'network_admin_menu', array( __CLASS__, 'forget_resolved_gates' ), 0 );
46 }
47
48 /**
49 * Drops the gates resolved during the previous registration pass.
50 *
51 * @return void
52 */
53 public static function forget_resolved_gates() {
54 self::$resolved = array();
55 }
56
57 /**
58 * Answers whether a menu item's declared gate is satisfied.
59 *
60 * Answers are memoized for one registration pass: resolving a product rebuilds the product
61 * class map and rescans the installed plugins, and the sidebar asks once per gated item.
62 *
63 * @param array $args The item's visibility declaration, as passed to Admin_Menu::add_menu().
64 * @return bool|null True or false, or null when the gate cannot be resolved here.
65 */
66 public static function resolve( $args ) {
67 if ( ! empty( $args['product'] ) ) {
68 $key = 'product:' . $args['product'];
69
70 if ( ! array_key_exists( $key, self::$resolved ) ) {
71 self::$resolved[ $key ] = self::is_product_activated( $args['product'] );
72 }
73
74 return self::$resolved[ $key ];
75 }
76
77 if ( ! empty( $args['module'] ) ) {
78 $key = 'module:' . $args['module'];
79
80 if ( ! array_key_exists( $key, self::$resolved ) ) {
81 self::$resolved[ $key ] = self::is_module_activated( $args['module'] );
82 }
83
84 return self::$resolved[ $key ];
85 }
86
87 return null;
88 }
89
90 /**
91 * Whether a Jetpack module gating an item is switched on.
92 *
93 * A name this site has no module for is unanswerable rather than off, so a typo in a gate
94 * fails open like an unknown product slug does instead of silently removing the item. Off
95 * the Jetpack plugin that covers any module a standalone plugin did not declare through
96 * `jetpack_get_available_standalone_modules`.
97 *
98 * @param string $module_name A Jetpack module name.
99 * @return bool|null Null when this site has no such module.
100 */
101 private static function is_module_activated( $module_name ) {
102 $modules = new Modules();
103
104 if ( ! in_array( $module_name, $modules->get_available(), true ) ) {
105 return null;
106 }
107
108 return $modules->is_active( $module_name );
109 }
110
111 /**
112 * Whether the site has switched a My Jetpack product on.
113 *
114 * Reads is_activated(), not is_active(): a lapsed plan is not "off", and resolving plans
115 * costs WordPress.com requests on every admin page load. No connection check is added.
116 *
117 * @param string $product_slug A My Jetpack product slug.
118 * @return bool|null Null when no product class is registered under that slug.
119 */
120 private static function is_product_activated( $product_slug ) {
121 $product_class = Products::get_product_class( $product_slug );
122
123 if ( ! $product_class ) {
124 return null;
125 }
126
127 return (bool) $product_class::is_activated();
128 }
129 }
130