Completed
Push — renovate/commander-5.x ( da542f...98aca7 )
by
unknown
169:19 queued 151:48
created

Plugins_Handler   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 143
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 143
rs 10
c 0
b 0
f 0
wmc 18
lcom 1
cbo 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A get_all_active_plugins_paths() 0 14 1
A get_multisite_plugins_paths() 0 8 2
A get_active_plugins_paths() 0 5 1
A create_plugin_path() 0 3 1
A is_directory_plugin() 0 3 1
A should_autoloader_reset() 0 14 2
B get_plugins_activating_via_request() 0 32 9
A get_current_plugin_path() 0 5 1
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 the paths of all active plugins and all known activating plugins.
11
	 *
12
	 * @return array An array of plugin paths as strings or an empty array.
13
	 */
14
	public function get_all_active_plugins_paths() {
15
		global $jetpack_autoloader_activating_plugins_paths;
16
17
		$active_plugins_paths    = $this->get_active_plugins_paths();
18
		$multisite_plugins_paths = $this->get_multisite_plugins_paths();
19
		$active_plugins_paths    = array_merge( $multisite_plugins_paths, $active_plugins_paths );
20
21
		$activating_plugins_paths = $this->get_plugins_activating_via_request();
22
		$activating_plugins_paths = array_unique( array_merge( $activating_plugins_paths, $jetpack_autoloader_activating_plugins_paths ) );
23
24
		$plugins_paths = array_unique( array_merge( $active_plugins_paths, $activating_plugins_paths ) );
25
26
		return $plugins_paths;
27
	}
28
29
	/**
30
	 * Returns an array containing the paths of the active sitewide plugins in a multisite environment.
31
	 *
32
	 * @return array The paths of the active sitewide plugins or an empty array.
33
	 */
34
	protected function get_multisite_plugins_paths() {
35
		$plugin_slugs = is_multisite()
36
			? array_keys( get_site_option( 'active_sitewide_plugins', array() ) )
37
			: array();
38
39
		$plugin_slugs = array_filter( $plugin_slugs, array( $this, 'is_directory_plugin' ) );
40
		return array_map( array( $this, 'create_plugin_path' ), $plugin_slugs );
41
	}
42
43
	/**
44
	 * Returns an array containing the paths of the currently active plugins.
45
	 *
46
	 * @return array The active plugins' paths or an empty array.
47
	 */
48
	protected function get_active_plugins_paths() {
49
		$plugin_slugs = (array) get_option( 'active_plugins', array() );
50
		$plugin_slugs = array_filter( $plugin_slugs, array( $this, 'is_directory_plugin' ) );
51
		return array_map( array( $this, 'create_plugin_path' ), $plugin_slugs );
52
	}
53
54
	/**
55
	 * Adds the plugin directory from the WP_PLUGIN_DIR constant to the plugin slug.
56
	 *
57
	 * @param string $plugin_slug The plugin slug.
58
	 */
59
	private function create_plugin_path( $plugin_slug ) {
60
		return trailingslashit( WP_PLUGIN_DIR ) . substr( $plugin_slug, 0, strrpos( $plugin_slug, '/' ) );
61
	}
62
63
	/**
64
	 * Ensure the plugin has its own directory and not a single-file plugin.
65
	 *
66
	 * @param string $plugin Plugin name, may be prefixed with "/".
67
	 *
68
	 * @return bool
69
	 */
70
	public function is_directory_plugin( $plugin ) {
71
		return false !== strpos( $plugin, '/', 1 );
72
	}
73
74
	/**
75
	 * Checks whether the autoloader should be reset. The autoloader should be reset
76
	 * when a plugin is activating via a method other than a request, for example
77
	 * using WP-CLI. When this occurs, the activating plugin was not known when
78
	 * the autoloader selected the package versions for the classmap and filemap
79
	 * globals, so the autoloader must reselect the versions.
80
	 *
81
	 * If the current plugin is not already known, this method will add it to the
82
	 * $jetpack_autoloader_activating_plugins_paths global.
83
	 *
84
	 * @return boolean True if the autoloder must be reset, else false.
85
	 */
86
	public function should_autoloader_reset() {
87
		global $jetpack_autoloader_activating_plugins_paths;
88
89
		$plugins_paths       = $this->get_all_active_plugins_paths();
90
		$current_plugin_path = $this->get_current_plugin_path();
91
		$plugin_unknown      = ! in_array( $current_plugin_path, $plugins_paths, true );
92
93
		if ( $plugin_unknown ) {
94
			// If the current plugin isn't known, add it to the activating plugins list.
95
			$jetpack_autoloader_activating_plugins_paths[] = $current_plugin_path;
96
		}
97
98
		return $plugin_unknown;
99
	}
100
101
	/**
102
	 * Returns an array containing the names of plugins that are activating via a request.
103
	 *
104
	 * @return array An array of names of the activating plugins or an empty array.
105
	 */
106
	private function get_plugins_activating_via_request() {
107
108
		 // phpcs:disable WordPress.Security.NonceVerification.Recommended
109
110
		$action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : false;
111
		$plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : false;
112
		$nonce  = isset( $_REQUEST['_wpnonce'] ) ? $_REQUEST['_wpnonce'] : false;
113
114
		/**
115
		 * Note: we're not actually checking the nonce here becase it's too early
116
		 * in the execution. The pluggable functions are not yet loaded to give
117
		 * plugins a chance to plug their versions. Therefore we're doing the bare
118
		 * minimum: checking whether the nonce exists and it's in the right place.
119
		 * The request will fail later if the nonce doesn't pass the check.
120
		 */
121
122
		// In case of a single plugin activation there will be a plugin slug.
123
		if ( 'activate' === $action && ! empty( $nonce ) ) {
124
			return array( $this->create_plugin_path( wp_unslash( $plugin ) ) );
0 ignored issues
show
Bug introduced by
It seems like wp_unslash($plugin) targeting wp_unslash() can also be of type array<integer,string>; however, Plugins_Handler::create_plugin_path() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
125
		}
126
127
		$plugins = isset( $_REQUEST['checked'] ) ? $_REQUEST['checked'] : array();
128
129
		// In case of bulk activation there will be an array of plugins.
130
		if ( 'activate-selected' === $action && ! empty( $nonce ) ) {
131
			$plugin_slugs = array_map( 'wp_unslash', $plugins );
132
			return array_map( array( $this, 'create_plugin_path' ), $plugin_slugs );
133
		}
134
135
		// phpcs:enable WordPress.Security.NonceVerification.Recommended
136
		return array();
137
	}
138
139
	/**
140
	 * Returns the path of the current plugin.
141
	 *
142
	 * @return string The path of the current plugin.
143
	 */
144
	public function get_current_plugin_path() {
145
		$vendor_path = dirname( __FILE__ );
146
		// Path to the plugin's folder (the parent of the vendor folder).
147
		return substr( $vendor_path, 0, strrpos( $vendor_path, '/' ) );
148
	}
149
}
150