PluginProbe
Plugin Check (PCP) / 1.5.0
Plugin Check (PCP) v1.5.0
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 / includes / Plugin_Context.php

Plugin_Context.php in Plugin Check (PCP) 1.5.0, at includes/Plugin_Context.php

245 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class WordPress\Plugin_Check\Plugin_Context
4 *
5 * @package plugin-check
6 */
7
8 namespace WordPress\Plugin_Check;
9
10 use Exception;
11 use WordPress\Plugin_Check\Traits\Find_Readme;
12 use WordPressdotorg\Plugin_Directory\Readme\Parser;
13 use function WP_CLI\Utils\normalize_path;
14
15 /**
16 * Class representing the context in which the plugin is running.
17 *
18 * @since 1.0.0
19 */
20 class Plugin_Context {
21
22 use Find_Readme;
23
24 /**
25 * Absolute path of the plugin main file.
26 *
27 * @since 1.0.0
28 * @var string
29 */
30 protected $main_file;
31
32 /**
33 * Plugin slug.
34 *
35 * @since 1.2.0
36 * @var string
37 */
38 protected $slug;
39
40 /**
41 * The minimum supported WordPress version of the plugin.
42 *
43 * @since 1.0.0
44 * @var string
45 */
46 protected $minimum_supported_wp;
47
48 /**
49 * Constructor.
50 *
51 * @since 1.0.0
52 * @since 1.2.0 Second argument $slug was introduced.
53 *
54 * @param string $main_file The absolute path to the plugin main file.
55 * @param string $slug The plugin slug.
56 *
57 * @throws Exception Throws exception if not called via regular WP-CLI or WordPress bootstrap order.
58 */
59 public function __construct( $main_file, $slug = '' ) {
60 if ( function_exists( 'wp_normalize_path' ) ) {
61 $this->main_file = wp_normalize_path( $main_file );
62 } elseif ( function_exists( '\WP_CLI\Utils\normalize_path' ) ) {
63 $this->main_file = normalize_path( $main_file );
64 } else {
65 throw new Exception(
66 __( 'Unknown environment, normalize_path function not found', 'plugin-check' )
67 );
68 }
69
70 if ( false === strpos( $this->main_file, '.php' ) ) {
71 $files = glob( $this->main_file . '/*.php' );
72 foreach ( $files as $file ) {
73 $plugin_data = get_plugin_data( $file );
74 if ( ! empty( $plugin_data['Name'] ) ) {
75 $this->main_file = $file;
76 break;
77 }
78 }
79 }
80
81 if ( ! empty( $slug ) ) {
82 $this->slug = $slug;
83 } else {
84 $this->slug = basename( dirname( $this->main_file ) );
85 }
86 }
87
88 /**
89 * Returns the plugin basename.
90 *
91 * @since 1.0.0
92 *
93 * @return string Plugin basename.
94 */
95 public function basename() {
96 return plugin_basename( $this->main_file );
97 }
98
99 /**
100 * Returns the plugin main file.
101 *
102 * @since 1.0.2
103 *
104 * @return string Plugin main file.
105 */
106 public function main_file() {
107 return $this->main_file;
108 }
109
110 /**
111 * Returns the plugin slug.
112 *
113 * @since 1.2.0
114 *
115 * @return string Plugin slug.
116 */
117 public function slug() {
118 return $this->slug;
119 }
120
121 /**
122 * Returns the absolute path for a relative path to the plugin directory.
123 *
124 * @since 1.0.0
125 *
126 * @param string $relative_path Optional. Relative path. Default '/'.
127 * @return string Absolute path.
128 */
129 public function path( $relative_path = '/' ) {
130 if ( is_dir( $this->main_file ) ) {
131 return trailingslashit( $this->main_file ) . ltrim( $relative_path, '/' );
132 } else {
133 return plugin_dir_path( $this->main_file ) . ltrim( $relative_path, '/' );
134 }
135 }
136
137 /**
138 * Returns the full URL for a path relative to the plugin directory.
139 *
140 * @since 1.0.0
141 *
142 * @param string $relative_path Optional. Relative path. Default '/'.
143 * @return string Full URL.
144 */
145 public function url( $relative_path = '/' ) {
146 return plugin_dir_url( $this->main_file ) . ltrim( $relative_path, '/' );
147 }
148
149 /**
150 * Returns the plugin location.
151 *
152 * @since 1.0.0
153 *
154 * @return string The plugin file if single file plugin. Or the plugin folder.
155 */
156 public function location() {
157 $path = $this->path();
158
159 // Return the plugin path and basename if the path matches the plugin directory.
160 if ( WP_PLUGIN_DIR . '/' === $path ) {
161 return $path . $this->basename();
162 }
163
164 return $path;
165 }
166
167 /**
168 * Checks if the plugin is a single file plugin without a dedicated directory.
169 *
170 * This is the case when the single file is directly placed within `wp-content/plugins`.
171 *
172 * @since 1.0.0
173 *
174 * @return bool true if the single file plugin, otherwise false.
175 */
176 public function is_single_file_plugin() {
177 return $this->path() !== $this->location();
178 }
179
180 /**
181 * Determine the minimum supported WordPress version of the plugin.
182 *
183 * @since 1.0.0
184 *
185 * @return string The minimum version supported, or empty string if unknown.
186 */
187 public function minimum_supported_wp() {
188 if ( ! is_null( $this->minimum_supported_wp ) ) {
189 return $this->minimum_supported_wp;
190 }
191
192 $this->minimum_supported_wp = '';
193
194 $headers = get_plugin_data( $this->main_file );
195 if ( ! empty( $headers['RequiresWP'] ) ) {
196 $this->minimum_supported_wp = $headers['RequiresWP'];
197 } elseif ( ! $this->is_single_file_plugin() ) {
198 // Look for the readme.
199 $readme_files = glob( $this->path() . '*' );
200 $readme_files = $this->filter_files_for_readme( $readme_files, $this->path() );
201 $readme_file = reset( $readme_files );
202 if ( $readme_file ) {
203 $parser = new Parser( $readme_file );
204
205 if ( ! empty( $parser->requires ) ) {
206 $this->minimum_supported_wp = $parser->requires;
207 }
208 }
209 }
210
211 return $this->minimum_supported_wp;
212 }
213
214 /**
215 * Checks if the file is editable.
216 *
217 * @since 1.1.0
218 *
219 * @param string $file Filename.
220 * @return bool true if the file is editable, otherwise false.
221 */
222 public function is_file_editable( $file ) {
223 $editable = false;
224
225 $editable_extensions = wp_get_plugin_file_editable_extensions( $this->basename() );
226
227 $info = pathinfo( $file );
228
229 $filename = $info['filename'];
230 $dirname = $info['dirname'];
231 $extension = isset( $info['extension'] ) ? strtolower( $info['extension'] ) : '';
232
233 if (
234 in_array( $extension, $editable_extensions, true )
235 && file_exists( dirname( $this->main_file() ) . '/' . $file )
236 && ( ! empty( $filename ) && ( '.' !== $filename[0] ) )
237 && ! ( '.' === $dirname[0] && strlen( $dirname ) > 1 )
238 ) {
239 $editable = true;
240 }
241
242 return $editable;
243 }
244 }
245