PluginProbe
Plugin Check (PCP) / 0.2.1
Plugin Check (PCP) v0.2.1
2.1.0 trunk 0.1 0.2.0 0.2.1 0.2.2 0.2.3 1.0.0 1.0.1 1.0.2 1.1.0 1.2.0 1.3.0 1.3.1 1.4.0 1.5.0 1.6.0 1.7.0 1.8.0 1.9.0 2.0.0 ci-artifacts
plugin-check / inc / class-phpcs.php

class-phpcs.php in Plugin Check (PCP) 0.2.1, at inc/class-phpcs.php

262 lines 6.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace WordPressdotorg\Plugin_Check;
3 use WP_Error;
4
5 /**
6 * Class PHPCS
7 *
8 * A PHP wrapper for running the phpcs command line tool.
9 *
10 * @package WordPressdotorg\Plugin_Check
11 */
12 class PHPCS {
13 /**
14 * @var string The path to the phpcs script.
15 */
16 protected $phpcs;
17
18 /**
19 * @var PHP_CLI Instance of the PHP_CLI class.
20 */
21 protected $php;
22
23 /**
24 * @var string The name or path of the coding standard to use with phpcs.
25 */
26 protected $standard = 'WordPress';
27
28 /**
29 * @var string The state of the phpcs cache.
30 */
31 protected $cache = 'disabled';
32
33 /**
34 * @var string The path of the custom file that phpcs will use for caching.
35 */
36 protected $cache_file;
37
38 /**
39 * @var array Arguments for every phpcs call.
40 */
41 protected $common_args = array(
42 'q' => true,
43 'parallel' => 3,
44 'report-width' => 80,
45 'tab-width' => 4,
46 );
47
48 /**
49 * PHPCS constructor.
50 */
51 public function __construct() {
52 $this->phpcs = dirname( __DIR__ ) . '/vendor/squizlabs/php_codesniffer/bin/phpcs';
53 if ( is_callable( 'get_temp_dir' ) ) {
54 $this->cache_file = get_temp_dir() . 'wporg-code-analysis/phpcs-cache';
55 } else {
56 $this->cache_file = '/tmp/wporg-code-analysis/phpcs-cache';
57 }
58
59 $this->php = new PHP_CLI();
60 }
61
62 /**
63 * Set the name or path of the coding standard that will be used when running phpcs.
64 *
65 * @param string $standard The name or path of the coding standard to use.
66 *
67 * @return void
68 */
69 public function set_standard( $standard ) {
70 $this->standard = $standard;
71 }
72
73 /**
74 * Toggle the cache state to "enabled".
75 *
76 * @return void
77 */
78 public function enable_cache() {
79 $this->cache = 'enabled';
80 $this->common_args['cache'] = $this->cache_file;
81 }
82
83 /**
84 * Toggle the cache state to "disabled".
85 *
86 * @return void
87 */
88 public function disable_cache() {
89 $this->cache = 'disabled';
90 unset( $this->common_args['cache'] );
91 }
92
93 /**
94 * Delete the cache file.
95 *
96 * @return void
97 */
98 public function clear_cache() {
99 @unlink( $this->cache_file );
100 }
101
102 /**
103 * Run phpcs on a given path with a given set of arguments.
104 *
105 * The arguments array can take any of the arguments described in phpcs's Usage blurb, but there are some that
106 * should be set in other ways instead:
107 * - standard This should be set using the `set_standard` class method instead. This makes it simpler
108 * to run phpcs on several different directories in the same session.
109 * - cache and no-cache These should be set using the `enable_cache` and `disable_cache` class methods instead.
110 * As of v3.5.8 phpcs doesn't have a simple way to clear its own cache.
111 * (See https://github.com/squizlabs/PHP_CodeSniffer/issues/2993.)
112 * To get around this we set a custom cache file, which can then be deleted with the
113 * `clear_cache` class method.
114 *
115 * @param string $path The directory/file on which to to run phpcs.
116 * @param array $args Command line args as key => value pairs. Valueless keys should be set to true.
117 * See https://github.com/squizlabs/PHP_CodeSniffer/wiki/Usage.
118 * Note that the `standard` arg should be set using the `set_standard` class method.
119 *
120 * @return string|WP_Error|null
121 */
122 public function run( $path, array $args = array() ) {
123 if ( ! file_exists( $this->phpcs ) ) {
124 return new \WP_Error(
125 'missing_dependency',
126 'PHP Code Sniffer is not available. Try running <code>composer install</code> first.'
127 );
128 }
129
130 if ( ! is_readable( $path ) ) {
131 return new \WP_Error(
132 'invalid_path',
133 'The given path is not readable.'
134 );
135 }
136
137 if ( isset( $args['cache'] ) ) {
138 $this->enable_cache();
139 unset( $args['cache'] );
140 } elseif ( isset( $args['no-cache'] ) ) {
141 $this->disable_cache();
142 }
143
144 $args = array_merge(
145 array(
146 'basepath' => $path,
147 'standard' => $this->standard,
148 ),
149 $this->common_args,
150 $args
151 );
152
153 $arg_array = array();
154 foreach ( $args as $key => $value ) {
155 $prefix = '--';
156 if ( 1 === strlen( $key ) || in_array( $key, array( 'vv', 'vvv' ), true ) ) {
157 $prefix = '-';
158 }
159
160 if ( true === $value ) {
161 $arg_array[] = "{$prefix}{$key}";
162 } else {
163 $arg_array[] = "{$prefix}{$key}={$value}";
164 }
165 }
166 $arg_string = implode( ' ', $arg_array );
167
168 $command = $this->php->get_cmd( "{$this->phpcs} $arg_string $path 2>&1" );
169 $response = shell_exec( $command );
170
171 if ( strpos( $response, 'No such file or directory' ) !== false ) {
172 return new \WP_Error(
173 'plugin_check_php_binary_not_found',
174 __( 'Cannot find the PHP Binary file, please define it using the <code>`PLUGIN_CHECK_PHP_BIN`</code> constant', 'plugin-check' )
175 );
176 }
177
178 return $response;
179 }
180
181 /**
182 * Get the summary.
183 *
184 * @param string $path The directory/file on which to to run phpcs.
185 * @param array $args Command line args. See the `run` method.
186 *
187 * @return string|WP_Error|null
188 */
189 public function run_summary_report( $path, array $args = array() ) {
190 $args = array_merge(
191 $args,
192 array(
193 'report' => 'summary',
194 )
195 );
196
197 return $this->run( $path, $args );
198 }
199
200 /**
201 * Get the full report.
202 *
203 * @param string $path The directory/file on which to to run phpcs.
204 * @param array $args Command line args. See the `run` method.
205 *
206 * @return string|WP_Error|null
207 */
208 public function run_full_report( $path, array $args = array() ) {
209 $args = array_merge(
210 $args,
211 array(
212 'report' => 'full',
213 )
214 );
215
216 return $this->run( $path, $args );
217 }
218
219 /**
220 * Get the full report as JSON.
221 *
222 * @param string $path The directory/file on which to to run phpcs.
223 * @param array $args Command line args. See the `run` method.
224 * @param string $output The format of the return data. Possible values raw|object|array.
225 * "raw" means an un-decoded JSON string. Default raw.
226 *
227 * @return mixed|string|WP_Error|null
228 */
229 public function run_json_report( $path, array $args = array(), $output = 'raw' ) {
230 $args = array_merge(
231 $args,
232 array(
233 'report' => 'json',
234 )
235 );
236
237 $result = $this->run( $path, $args );
238
239 if ( is_wp_error( $result ) ) {
240 return new Error(
241 $result->get_error_code(),
242 $result->get_error_message()
243 );
244 }
245
246 if ( in_array( $output, array( 'object', 'array' ), true ) ) {
247 $assoc = 'array' === $output;
248 $result = json_decode( $result, $assoc );
249 // Does this belong here?
250 if ( $result ) {
251 array_walk_recursive( $result, function( &$value, $key ) {
252 if ( is_string( $value ) ) {
253 $value = stripcslashes( $value );
254 }
255 } );
256 }
257 }
258
259 return $result;
260 }
261 }
262