Completed
Push — feature/update_autoloader ( ffb56e...0d7a0f )
by
unknown
06:32
created

get_plugins_activating_via_request()   B

Complexity

Conditions 9
Paths 40

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
nc 40
nop 0
dl 0
loc 32
rs 8.0555
c 0
b 0
f 0
1
<?php
2
/* HEADER */ // phpcs:ignore
3
4
/**
5
 * This class provides information about the current plugin and the site's active plugins.
6
 */
7
class Plugins_Handler {
8
9
	/**
10
	 * Returns an array containing all active plugins and all known activating
11
	 * plugins.
12
	 *
13
	 * @param bool $skip_single_file_plugins If true, plugins with no dedicated directories will be skipped.
14
	 *
15
	 * @return Array An array of plugin names as strings.
16
	 */
17
	public function get_all_active_plugins( $skip_single_file_plugins = true ) {
18
		$active_plugins = array_merge( $this->get_multisite_plugins(), $this->get_active_plugins() );
19
20
		$plugins = array_unique( array_merge( $active_plugins, $this->get_all_activating_plugins() ) );
21
22
		if ( $skip_single_file_plugins ) {
23
			$plugins = array_filter( $plugins, array( $this, 'is_directory_plugin' ) );
24
		}
25
26
		return $plugins;
27
	}
28
29
	/**
30
	 * Get the active sitewide plugins in a multisite environment.
31
	 *
32
	 * @return Array The active sitewide plugins.
33
	 */
34
	protected function get_multisite_plugins() {
35
		return is_multisite()
36
			? array_keys( get_site_option( 'active_sitewide_plugins', array() ) )
37
			: array();
38
	}
39
40
	/**
41
	 * Get the currently active plugins.
42
	 *
43
	 * @return Array The active plugins.
44
	 */
45
	protected function get_active_plugins() {
46
		return (array) get_option( 'active_plugins', array() );
47
	}
48
49
	/**
50
	 * Ensure the plugin has its own directory and not a single-file plugin.
51
	 *
52
	 * @param string $plugin Plugin name, may be prefixed with "/".
53
	 *
54
	 * @return bool
55
	 */
56
	public function is_directory_plugin( $plugin ) {
57
		return false !== strpos( $plugin, '/', 1 );
58
	}
59
60
	/**
61
	 * Checks whether the autoloader should be reset. The autoloader should be reset
62
	 * when a plugin is activating via a method other than a request, for example
63
	 * using WP-CLI. When this occurs, the activating plugin was not known when
64
	 * the autoloader selected the package versions for the classmap and filemap
65
	 * globals, so the autoloader must reselect the versions.
66
	 *
67
	 * If the current plugin is not already known, this method will add it to the
68
	 * $jetpack_autoloader_activating_plugins global.
69
	 *
70
	 * @return Boolean True if the autoloder must be reset, else false.
71
	 */
72
	public function should_autoloader_reset() {
73
		global $jetpack_autoloader_activating_plugins;
74
75
		$plugins        = $this->get_all_active_plugins();
76
		$current_plugin = $this->get_current_plugin();
77
		$plugin_unknown = ! in_array( $current_plugin, $plugins, true );
78
79
		if ( $plugin_unknown ) {
80
			// If the current plugin isn't known, add it to the activating plugins list.
81
			$jetpack_autoloader_activating_plugins[] = $current_plugin;
82
		}
83
84
		return $plugin_unknown;
85
	}
86
87
	/**
88
	 * Returns the names of activating plugins if the plugins are activating via a request.
89
	 *
90
	 * @return Array The array of the activating plugins or empty array.
91
	 */
92
	private function get_plugins_activating_via_request() {
93
94
		 // phpcs:disable WordPress.Security.NonceVerification.Recommended
95
96
		$action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : false;
97
		$plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : false;
98
		$nonce  = isset( $_REQUEST['_wpnonce'] ) ? $_REQUEST['_wpnonce'] : false;
99
100
		/**
101
		 * Note: we're not actually checking the nonce here becase it's too early
102
		 * in the execution. The pluggable functions are not yet loaded to give
103
		 * plugins a chance to plug their versions. Therefore we're doing the bare
104
		 * minimum: checking whether the nonce exists and it's in the right place.
105
		 * The request will fail later if the nonce doesn't pass the check.
106
		 */
107
108
		// In case of a single plugin activation there will be a plugin slug.
109
		if ( 'activate' === $action && ! empty( $nonce ) ) {
110
			return array( wp_unslash( $plugin ) );
111
		}
112
113
		$plugins = isset( $_REQUEST['checked'] ) ? $_REQUEST['checked'] : array();
114
115
		// In case of bulk activation there will be an array of plugins.
116
		if ( 'activate-selected' === $action && ! empty( $nonce ) ) {
117
			return array_map( 'wp_unslash', $plugins );
118
		}
119
120
		// phpcs:enable WordPress.Security.NonceVerification.Recommended
121
122
		return array();
123
	}
124
125
	/**
126
	 * Returns an array of the names of all known activating plugins. This includes
127
	 * plugins activating via a request and plugins that are activating via other
128
	 * methods.
129
	 *
130
	 * @return Array The array of all activating plugins or empty array.
131
	 */
132
	private function get_all_activating_plugins() {
133
		global $jetpack_autoloader_activating_plugins;
134
135
		$activating_plugins = $this->get_plugins_activating_via_request();
136
		return array_unique( array_merge( $activating_plugins, $jetpack_autoloader_activating_plugins ) );
137
	}
138
139
	/**
140
	 * Returns the name of the current plugin.
141
	 *
142
	 * @return String The name of the current plugin.
143
	 */
144
	public function get_current_plugin() {
145
		if ( ! function_exists( 'get_plugins' ) ) {
146
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
147
		}
148
149
		$dir  = explode( '/', plugin_basename( __FILE__ ) )[0];
150
		$file = array_keys( get_plugins( "/$dir" ) )[0];
151
		return "$dir/$file";
152
	}
153
}
154