Completed
Push — renovate/slack-web-api-6.x ( 1d54b7...bfe495 )
by
unknown
193:23 queued 183:13
created

Plugin_Locator   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 139
rs 10
c 0
b 0
f 0
wmc 22
lcom 1
cbo 1

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A find_current_plugin() 0 12 2
A find_using_option() 0 8 3
B find_using_request_action() 0 43 10
B convert_plugins_to_paths() 0 23 6
1
<?php
2
/* HEADER */ // phpcs:ignore
3
4
/**
5
 * This class scans the WordPress installation to find active plugins.
6
 */
7
class Plugin_Locator {
8
9
	/**
10
	 * The path processor for finding plugin paths.
11
	 *
12
	 * @var Path_Processor
13
	 */
14
	private $path_processor;
15
16
	/**
17
	 * The constructor.
18
	 *
19
	 * @param Path_Processor $path_processor The Path_Processor instance.
20
	 */
21
	public function __construct( $path_processor ) {
22
		$this->path_processor = $path_processor;
23
	}
24
25
	/**
26
	 * Finds the path to the current plugin.
27
	 *
28
	 * @return string $path The path to the current plugin.
29
	 *
30
	 * @throws \RuntimeException If the current plugin does not have an autoloader.
31
	 */
32
	public function find_current_plugin() {
33
		// Escape from `vendor/__DIR__` to root plugin directory.
34
		$plugin_directory = dirname( dirname( __DIR__ ) );
35
36
		// Use the path processor to ensure that this is an autoloader we're referencing.
37
		$path = $this->path_processor->find_directory_with_autoloader( $plugin_directory, array() );
38
		if ( false === $path ) {
39
			throw new \RuntimeException( 'Failed to locate plugin ' . $plugin_directory );
40
		}
41
42
		return $path;
43
	}
44
45
	/**
46
	 * Checks a given option for plugin paths.
47
	 *
48
	 * @param string $option_name  The option that we want to check for plugin information.
49
	 * @param bool   $site_option  Indicates whether or not we want to check the site option.
50
	 *
51
	 * @return array $plugin_paths The list of absolute paths we've found.
52
	 */
53
	public function find_using_option( $option_name, $site_option = false ) {
54
		$raw = $site_option ? get_site_option( $option_name ) : get_option( $option_name );
55
		if ( false === $raw ) {
56
			return array();
57
		}
58
59
		return $this->convert_plugins_to_paths( $raw );
60
	}
61
62
	/**
63
	 * Checks for plugins in the `action` request parameter.
64
	 *
65
	 * @param string[] $allowed_actions The actions that we're allowed to return plugins for.
66
	 *
67
	 * @return array $plugin_paths The list of absolute paths we've found.
68
	 */
69
	public function find_using_request_action( $allowed_actions ) {
70
		// phpcs:disable WordPress.Security.NonceVerification.Recommended
71
72
		/**
73
		 * Note: we're not actually checking the nonce here because it's too early
74
		 * in the execution. The pluggable functions are not yet loaded to give
75
		 * plugins a chance to plug their versions. Therefore we're doing the bare
76
		 * minimum: checking whether the nonce exists and it's in the right place.
77
		 * The request will fail later if the nonce doesn't pass the check.
78
		 */
79
		if ( empty( $_REQUEST['_wpnonce'] ) ) {
80
			return array();
81
		}
82
83
		$action = isset( $_REQUEST['action'] ) ? wp_unslash( $_REQUEST['action'] ) : false;
84
		if ( ! in_array( $action, $allowed_actions, true ) ) {
85
			return array();
86
		}
87
88
		$plugin_slugs = array();
89
		switch ( $action ) {
90
			case 'activate':
91
			case 'deactivate':
92
				if ( empty( $_REQUEST['plugin'] ) ) {
93
					break;
94
				}
95
96
				$plugin_slugs[] = wp_unslash( $_REQUEST['plugin'] );
97
				break;
98
99
			case 'activate-selected':
100
			case 'deactivate-selected':
101
				if ( empty( $_REQUEST['checked'] ) ) {
102
					break;
103
				}
104
105
				$plugin_slugs = wp_unslash( $_REQUEST['checked'] );
106
				break;
107
		}
108
109
		// phpcs:enable WordPress.Security.NonceVerification.Recommended
110
		return $this->convert_plugins_to_paths( $plugin_slugs );
0 ignored issues
show
Documentation introduced by
$plugin_slugs is of type string|array, but the function expects a array<integer,string>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
111
	}
112
113
	/**
114
	 * Given an array of plugin slugs or paths, this will convert them to absolute paths and filter
115
	 * out the plugins that are not directory plugins. Note that array keys will also be included
116
	 * if they are plugin paths!
117
	 *
118
	 * @param string[] $plugins Plugin paths or slugs to filter.
119
	 *
120
	 * @return string[]
121
	 */
122
	private function convert_plugins_to_paths( $plugins ) {
123
		if ( ! is_array( $plugins ) || empty( $plugins ) ) {
124
			return array();
125
		}
126
127
		// We're going to look for plugins in the standard directories.
128
		$path_constants = array( WP_PLUGIN_DIR, WPMU_PLUGIN_DIR );
129
130
		$plugin_paths = array();
131
		foreach ( $plugins as $key => $value ) {
132
			$path = $this->path_processor->find_directory_with_autoloader( $key, $path_constants );
133
			if ( $path ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $path of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
134
				$plugin_paths[] = $path;
135
			}
136
137
			$path = $this->path_processor->find_directory_with_autoloader( $value, $path_constants );
138
			if ( $path ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $path of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
139
				$plugin_paths[] = $path;
140
			}
141
		}
142
143
		return $plugin_paths;
144
	}
145
}
146