PluginProbe
Extendify / 1.9.3
Extendify v1.9.3
3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 0.7.0 All 126 releases
extendify / app / Library / Plugin.php

Plugin.php in Extendify 1.9.3, at app/Library/Plugin.php

319 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // phpcs:ignoreFile
3 // This class was copied from JetPack (mostly)
4 // so will be a bit of work to refactor
5 /**
6 * Manage plugin dependencies
7 */
8
9 namespace Extendify\Library;
10
11 class Plugin
12 {
13 /**
14 * Install and activate a plugin.
15 *
16 * @since 5.8.0
17 *
18 * @param string $slug Plugin slug.
19 *
20 * @return bool|WP_Error True if installation succeeded, error object otherwise.
21 */
22 public static function install_and_activate_plugin($slug)
23 {
24 $plugin_id = self::get_plugin_id_by_slug($slug);
25 if (! $plugin_id) {
26 $installed = self::install_plugin($slug);
27 if (is_wp_error($installed)) {
28 return $installed;
29 }
30 $plugin_id = self::get_plugin_id_by_slug($slug);
31 } elseif (is_plugin_active($plugin_id)) {
32 return true; // Already installed and active.
33 }
34
35 if (! current_user_can('activate_plugins')) {
36 return new \WP_Error('not_allowed', __('You are not allowed to activate plugins on this site.', 'jetpack'));
37 }
38 $activated = activate_plugin($plugin_id);
39 if (is_wp_error($activated)) {
40 return $activated;
41 }
42
43 return true;
44 }
45
46 /**
47 * Install a plugin.
48 *
49 * @since 5.8.0
50 *
51 * @param string $slug Plugin slug.
52 *
53 * @return bool|WP_Error True if installation succeeded, error object otherwise.
54 */
55 public static function install_plugin($slug)
56 {
57 if (is_multisite() && ! current_user_can('manage_network')) {
58 return new \WP_Error('not_allowed', __('You are not allowed to install plugins on this site.', 'jetpack'));
59 }
60
61 $skin = new PluginUpgraderSkin();
62 $upgrader = new \Plugin_Upgrader($skin);
63 $zip_url = self::generate_wordpress_org_plugin_download_link($slug);
64
65 $result = $upgrader->install($zip_url);
66
67 if (is_wp_error($result)) {
68 return $result;
69 }
70
71 $plugin = self::get_plugin_id_by_slug($slug);
72 $error_code = 'install_error';
73 if (! $plugin) {
74 $error = __('There was an error installing your plugin', 'jetpack');
75 }
76
77 if (! $result) {
78 $error_code = $upgrader->skin->get_main_error_code();
79 $message = $upgrader->skin->get_main_error_message();
80 $error = $message ? $message : __('An unknown error occurred during installation', 'jetpack');
81 }
82
83 if (! empty($error)) {
84 if ('download_failed' === $error_code) {
85 // For backwards compatibility: versions prior to 3.9 would return no_package instead of download_failed.
86 $error_code = 'no_package';
87 }
88
89 return new \WP_Error($error_code, $error, 400);
90 }
91
92 return (array) $upgrader->skin->get_upgrade_messages();
93 }
94
95 /**
96 * Get WordPress.org zip download link from a plugin slug
97 *
98 * @param string $plugin_slug Plugin slug.
99 */
100 protected static function generate_wordpress_org_plugin_download_link($plugin_slug)
101 {
102 return "https://downloads.wordpress.org/plugin/$plugin_slug.latest-stable.zip";
103 }
104
105 /**
106 * Get the plugin ID (composed of the plugin slug and the name of the main plugin file) from a plugin slug.
107 *
108 * @param string $slug Plugin slug.
109 */
110 public static function get_plugin_id_by_slug($slug)
111 {
112 // Check if get_plugins() function exists. This is required on the front end of the
113 // site, since it is in a file that is normally only loaded in the admin.
114 if (! function_exists('get_plugins')) {
115 require_once ABSPATH . 'wp-admin/includes/plugin.php';
116 }
117
118 /** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */
119 $plugins = apply_filters('all_plugins', get_plugins());
120 if (! is_array($plugins)) {
121 return false;
122 }
123
124 foreach ($plugins as $plugin_file => $plugin_data) {
125 if (self::get_slug_from_file_path($plugin_file) === $slug) {
126 return $plugin_file;
127 }
128 }
129
130 return false;
131 }
132
133 /**
134 * Get the plugin slug from the plugin ID (composed of the plugin slug and the name of the main plugin file)
135 *
136 * @param string $plugin_file Plugin file (ID -- e.g. hello-dolly/hello.php).
137 */
138 protected static function get_slug_from_file_path($plugin_file)
139 {
140 // Similar to get_plugin_slug() method.
141 $slug = dirname($plugin_file);
142 if ('.' === $slug) {
143 $slug = preg_replace('/(.+)\.php$/', '$1', $plugin_file);
144 }
145
146 return $slug;
147 }
148
149 /**
150 * Get the activation status for a plugin.
151 *
152 * @since 8.9.0
153 *
154 * @param string $plugin_file The plugin file to check.
155 * @return string Either 'network-active', 'active' or 'inactive'.
156 */
157 public static function get_plugin_status($plugin_file)
158 {
159 if (is_plugin_active_for_network($plugin_file)) {
160 return 'network-active';
161 }
162
163 if (is_plugin_active($plugin_file)) {
164 return 'active';
165 }
166
167 return 'inactive';
168 }
169
170 /**
171 * Returns a list of all plugins in the site.
172 *
173 * @since 8.9.0
174 * @uses get_plugins()
175 *
176 * @return array
177 */
178 public static function get_plugins()
179 {
180 if (! function_exists('get_plugins')) {
181 require_once ABSPATH . 'wp-admin/includes/plugin.php';
182 }
183 /** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */
184 $plugins = apply_filters('all_plugins', get_plugins());
185
186 if (is_array($plugins) && ! empty($plugins)) {
187 foreach ($plugins as $plugin_slug => $plugin_data) {
188 $plugins[ $plugin_slug ]['active'] = in_array(
189 self::get_plugin_status($plugin_slug),
190 array( 'active', 'network-active' ),
191 true
192 );
193 }
194 return $plugins;
195 }
196
197 return array();
198 }
199 }
200
201 include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
202 include_once ABSPATH . 'wp-admin/includes/file.php';
203 include_once ABSPATH . 'wp-includes/pluggable.php';
204 /**
205 * Allows us to capture that the site doesn't have proper file system access.
206 * In order to update the plugin.
207 */
208 class PluginUpgraderSkin extends \Automatic_Upgrader_Skin
209 {
210 /**
211 * Stores the last error key;
212 **/
213 protected $main_error_code = 'install_error';
214
215 /**
216 * Stores the last error message.
217 **/
218 protected $main_error_message = 'An unknown error occurred during installation';
219
220 /**
221 * Overwrites the set_upgrader to be able to tell if we e ven have the ability to write to the files.
222 *
223 * @param WP_Upgrader $upgrader
224 *
225 */
226 public function set_upgrader(&$upgrader)
227 {
228 parent::set_upgrader($upgrader);
229
230 // Check if we even have permission to.
231 $result = $upgrader->fs_connect(array( WP_CONTENT_DIR, WP_PLUGIN_DIR ));
232 if (! $result) {
233 // set the string here since they are not available just yet
234 $upgrader->generic_strings();
235 $this->feedback('fs_unavailable');
236 }
237 }
238
239 /**
240 * Overwrites the error function
241 */
242 public function error($error)
243 {
244 if (is_wp_error($error)) {
245 $this->feedback($error);
246 }
247 }
248
249 private function set_main_error_code($code)
250 {
251 // Don't set the process_failed as code since it is not that helpful unless we don't have one already set.
252 $this->main_error_code = ($code === 'process_failed' && $this->main_error_code ? $this->main_error_code : $code);
253 }
254
255 private function set_main_error_message($message, $code)
256 {
257 // Don't set the process_failed as message since it is not that helpful unless we don't have one already set.
258 $this->main_error_message = ($code === 'process_failed' && $this->main_error_code ? $this->main_error_code : $message);
259 }
260
261 public function get_main_error_code()
262 {
263 return $this->main_error_code;
264 }
265
266 public function get_main_error_message()
267 {
268 return $this->main_error_message;
269 }
270
271 /**
272 * Overwrites the feedback function
273 *
274 * @param string|array|WP_Error $data Data.
275 * @param mixed ...$args Optional text replacements.
276 */
277 public function feedback($data, ...$args)
278 {
279 $current_error = null;
280 if (is_wp_error($data)) {
281 $this->set_main_error_code($data->get_error_code());
282 $string = $data->get_error_message();
283 } elseif (is_array($data)) {
284 return;
285 } else {
286 $string = $data;
287 }
288
289 if (! empty($this->upgrader->strings[$string])) {
290 $this->set_main_error_code($string);
291
292 $current_error = $string;
293 $string = $this->upgrader->strings[$string];
294 }
295
296 if (strpos($string, '%') !== false) {
297 if (! empty($args)) {
298 $string = vsprintf($string, $args);
299 }
300 }
301
302 $string = trim($string);
303 $string = wp_kses(
304 $string,
305 array(
306 'a' => array(
307 'href' => true
308 ),
309 'br' => true,
310 'em' => true,
311 'strong' => true,
312 )
313 );
314
315 $this->set_main_error_message($string, $current_error);
316 $this->messages[] = $string;
317 }
318 }
319