PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.3
16.3 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 All 508 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-a.3, at jetpack_vendor/automattic/jetpack-my-jetpack/src/class-menu-visibility.php

125 lines 3.7 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 Admin_Menu::set_visibility_resolver( array( __CLASS__, 'resolve' ) );
37
38 // Memoized answers last one registration pass, which is as long as they can stay true.
39 add_action( 'admin_menu', array( __CLASS__, 'forget_resolved_gates' ), 0 );
40 add_action( 'network_admin_menu', array( __CLASS__, 'forget_resolved_gates' ), 0 );
41 }
42
43 /**
44 * Drops the gates resolved during the previous registration pass.
45 *
46 * @return void
47 */
48 public static function forget_resolved_gates() {
49 self::$resolved = array();
50 }
51
52 /**
53 * Answers whether a menu item's declared gate is satisfied.
54 *
55 * Answers are memoized for one registration pass: resolving a product rebuilds the product
56 * class map and rescans the installed plugins, and the sidebar asks once per gated item.
57 *
58 * @param array $args The item's visibility declaration, as passed to Admin_Menu::add_menu().
59 * @return bool|null True or false, or null when the gate cannot be resolved here.
60 */
61 public static function resolve( $args ) {
62 if ( ! empty( $args['product'] ) ) {
63 $key = 'product:' . $args['product'];
64
65 if ( ! array_key_exists( $key, self::$resolved ) ) {
66 self::$resolved[ $key ] = self::is_product_activated( $args['product'] );
67 }
68
69 return self::$resolved[ $key ];
70 }
71
72 if ( ! empty( $args['module'] ) ) {
73 $key = 'module:' . $args['module'];
74
75 if ( ! array_key_exists( $key, self::$resolved ) ) {
76 self::$resolved[ $key ] = self::is_module_activated( $args['module'] );
77 }
78
79 return self::$resolved[ $key ];
80 }
81
82 return null;
83 }
84
85 /**
86 * Whether a Jetpack module gating an item is switched on.
87 *
88 * A name this site has no module for is unanswerable rather than off, so a typo in a gate
89 * fails open like an unknown product slug does instead of silently removing the item. Off
90 * the Jetpack plugin that covers any module a standalone plugin did not declare through
91 * `jetpack_get_available_standalone_modules`.
92 *
93 * @param string $module_name A Jetpack module name.
94 * @return bool|null Null when this site has no such module.
95 */
96 private static function is_module_activated( $module_name ) {
97 $modules = new Modules();
98
99 if ( ! in_array( $module_name, $modules->get_available(), true ) ) {
100 return null;
101 }
102
103 return $modules->is_active( $module_name );
104 }
105
106 /**
107 * Whether the site has switched a My Jetpack product on.
108 *
109 * Reads is_activated(), not is_active(): a lapsed plan is not "off", and resolving plans
110 * costs WordPress.com requests on every admin page load. No connection check is added.
111 *
112 * @param string $product_slug A My Jetpack product slug.
113 * @return bool|null Null when no product class is registered under that slug.
114 */
115 private static function is_product_activated( $product_slug ) {
116 $product_class = Products::get_product_class( $product_slug );
117
118 if ( ! $product_class ) {
119 return null;
120 }
121
122 return (bool) $product_class::is_activated();
123 }
124 }
125