Completed
Push — update/anchor-fm-add-podcast-p... ( 52f496...e64a3b )
by
unknown
251:07 queued 242:18
created

Plugin_Locator::find_using_request_action()   B

Complexity

Conditions 10
Paths 21

Size

Total Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
nc 21
nop 1
dl 0
loc 43
rs 7.6666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
	 * @throws \RuntimeException If the current plugin does not have an autoloader.
30
	 */
31
	public function find_current_plugin() {
32
		// Escape from `vendor/__DIR__` to root plugin directory.
33
		$plugin_directory = dirname( dirname( __DIR__ ) );
34
35
		// Use the path processor to ensure that this is an autoloader we're referencing.
36
		$path = $this->path_processor->find_directory_with_autoloader( $plugin_directory, array() );
37
		if ( false === $path ) {
38
			throw new \RuntimeException( 'Failed to locate plugin ' . $plugin_directory );
39
		}
40
41
		return $path;
42
	}
43
44
	/**
45
	 * Checks a given option for plugin paths.
46
	 *
47
	 * @param string $option_name  The option that we want to check for plugin information.
48
	 * @param bool   $site_option  Indicates whether or not we want to check the site option.
49
	 *
50
	 * @return array $plugin_paths The list of absolute paths we've found.
51
	 */
52
	public function find_using_option( $option_name, $site_option = false ) {
53
		$raw = $site_option ? get_site_option( $option_name, array() ) : get_option( $option_name, array() );
54
		if ( empty( $raw ) ) {
55
			return array();
56
		}
57
58
		return $this->convert_plugins_to_paths( $raw );
59
	}
60
61
	/**
62
	 * Checks for plugins in the `action` request parameter.
63
	 *
64
	 * @param string[] $allowed_actions The actions that we're allowed to return plugins for.
65
	 * @return array $plugin_paths The list of absolute paths we've found.
66
	 */
67
	public function find_using_request_action( $allowed_actions ) {
68
		// phpcs:disable WordPress.Security.NonceVerification.Recommended
69
70
		/**
71
		 * Note: we're not actually checking the nonce here because it's too early
72
		 * in the execution. The pluggable functions are not yet loaded to give
73
		 * plugins a chance to plug their versions. Therefore we're doing the bare
74
		 * minimum: checking whether the nonce exists and it's in the right place.
75
		 * The request will fail later if the nonce doesn't pass the check.
76
		 */
77
		if ( empty( $_REQUEST['_wpnonce'] ) ) {
78
			return array();
79
		}
80
81
		$action = isset( $_REQUEST['action'] ) ? wp_unslash( $_REQUEST['action'] ) : false;
82
		if ( ! in_array( $action, $allowed_actions, true ) ) {
83
			return array();
84
		}
85
86
		$plugin_slugs = array();
87
		switch ( $action ) {
88
			case 'activate':
89
			case 'deactivate':
90
				if ( empty( $_REQUEST['plugin'] ) ) {
91
					break;
92
				}
93
94
				$plugin_slugs[] = wp_unslash( $_REQUEST['plugin'] );
95
				break;
96
97
			case 'activate-selected':
98
			case 'deactivate-selected':
99
				if ( empty( $_REQUEST['checked'] ) ) {
100
					break;
101
				}
102
103
				$plugin_slugs = wp_unslash( $_REQUEST['checked'] );
104
				break;
105
		}
106
107
		// phpcs:enable WordPress.Security.NonceVerification.Recommended
108
		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...
109
	}
110
111
	/**
112
	 * Given an array of plugin slugs or paths, this will convert them to absolute paths and filter
113
	 * out the plugins that are not directory plugins. Note that array keys will also be included
114
	 * if they are plugin paths!
115
	 *
116
	 * @param string[] $plugins Plugin paths or slugs to filter.
117
	 *
118
	 * @return string[]
119
	 */
120
	private function convert_plugins_to_paths( $plugins ) {
121
		// We're going to look for plugins in the standard directories.
122
		$path_constants = array( WP_PLUGIN_DIR, WPMU_PLUGIN_DIR );
123
124
		$plugin_paths = array();
125
		foreach ( $plugins as $key => $value ) {
126
			$path = $this->path_processor->find_directory_with_autoloader( $key, $path_constants );
127
			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...
128
				$plugin_paths[] = $path;
129
			}
130
131
			$path = $this->path_processor->find_directory_with_autoloader( $value, $path_constants );
132
			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...
133
				$plugin_paths[] = $path;
134
			}
135
		}
136
137
		return $plugin_paths;
138
	}
139
}
140