Completed
Push — update/autoloader_version_sele... ( b04284...ea2528 )
by
unknown
91:47 queued 85:26
created

Plugins_Handler   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 157
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 157
rs 10
c 0
b 0
f 0
wmc 20
lcom 1
cbo 0

8 Methods

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