Version Description
- March 5, 2020
- update WP Dependency Installer to 3.0.0
Download this release
Release Info
Developer | senlin |
Plugin | Classic Editor Addon |
Version | 2.6.1 |
Comparing to | |
See all releases |
Code changes from version 2.6.0 to 2.6.1
classic-editor-addon.php
CHANGED
@@ -4,10 +4,10 @@
|
|
4 |
* Description: This free "Classic Editor Addon" plugin makes sure that the new block editor cannot be accidentally activated and blocks the calls to additional styles from the `<head>` (frontend). See README for details.
|
5 |
|
6 |
* Author: <a href="https://so-wp.com">Pieter Bos</a>, <a href="https://gschoppe.com">Greg Schoppe</a>
|
7 |
-
* Version: 2.6.
|
8 |
|
9 |
* Requires at least: 4.9
|
10 |
-
* Tested up to: 5.3
|
11 |
|
12 |
* License: GPL-3.0+
|
13 |
* License URI: http://www.gnu.org/licenses/gpl-3.0.txt
|
4 |
* Description: This free "Classic Editor Addon" plugin makes sure that the new block editor cannot be accidentally activated and blocks the calls to additional styles from the `<head>` (frontend). See README for details.
|
5 |
|
6 |
* Author: <a href="https://so-wp.com">Pieter Bos</a>, <a href="https://gschoppe.com">Greg Schoppe</a>
|
7 |
+
* Version: 2.6.1
|
8 |
|
9 |
* Requires at least: 4.9
|
10 |
+
* Tested up to: 5.3.2
|
11 |
|
12 |
* License: GPL-3.0+
|
13 |
* License URI: http://www.gnu.org/licenses/gpl-3.0.txt
|
readme.txt
CHANGED
@@ -3,8 +3,8 @@ Contributors: senlin, gschoppe
|
|
3 |
Tags: gutenberg, block editor, classic editor, addon, wordpress 5.0, woocommerce
|
4 |
Requires at least: 4.9
|
5 |
Requires PHP: 5.6
|
6 |
-
Tested up to: 5.
|
7 |
-
Stable tag: 2.6.
|
8 |
License: GPL-3.0+
|
9 |
License URI: http://www.gnu.org/licenses/gpl-3.0.txt
|
10 |
|
@@ -17,7 +17,7 @@ This free "Classic Editor Addon" plugin makes sure that the new block editor can
|
|
17 |
The free Classic Editor Addon plugin is targeted at everyone who is not yet ready for the new editing experience that has been introduced in WordPress 5.0. Install it now on sites and the UX remains the same as you are used to!
|
18 |
|
19 |
<strong>What's New:</strong>
|
20 |
-
|
21 |
|
22 |
Please pay attention that the minimum PHP version to use our plugin is <strong>5.6</strong>.
|
23 |
|
@@ -27,7 +27,7 @@ Since version 0.0.4 of the "Classic Editor" plugin, it finally set the default s
|
|
27 |
|
28 |
Also, if we look at developers protecting the sites of their clients with the Classic Editor, they certainly don't want their clients to accidentally turn off the Classic Editor as the new block editor adds a lot of undesirable comments, tags and what not to the content.
|
29 |
|
30 |
-
Sites running WooCommerce get another style added to the
|
31 |
|
32 |
Therefore we highly recommend installing this "Classic Editor Addon" plugin, which will automatically install the “Classic Editor” plugin and remove its settings.
|
33 |
|
@@ -63,6 +63,11 @@ Please open an issue on [Github](https://github.com/senlin/classic-editor-addon/
|
|
63 |
|
64 |
== Changelog ==
|
65 |
|
|
|
|
|
|
|
|
|
|
|
66 |
= 2.6.0 =
|
67 |
|
68 |
* November 14, 2019
|
3 |
Tags: gutenberg, block editor, classic editor, addon, wordpress 5.0, woocommerce
|
4 |
Requires at least: 4.9
|
5 |
Requires PHP: 5.6
|
6 |
+
Tested up to: 5.4
|
7 |
+
Stable tag: 2.6.1
|
8 |
License: GPL-3.0+
|
9 |
License URI: http://www.gnu.org/licenses/gpl-3.0.txt
|
10 |
|
17 |
The free Classic Editor Addon plugin is targeted at everyone who is not yet ready for the new editing experience that has been introduced in WordPress 5.0. Install it now on sites and the UX remains the same as you are used to!
|
18 |
|
19 |
<strong>What's New:</strong>
|
20 |
+
Update WP Dependency Installer
|
21 |
|
22 |
Please pay attention that the minimum PHP version to use our plugin is <strong>5.6</strong>.
|
23 |
|
27 |
|
28 |
Also, if we look at developers protecting the sites of their clients with the Classic Editor, they certainly don't want their clients to accidentally turn off the Classic Editor as the new block editor adds a lot of undesirable comments, tags and what not to the content.
|
29 |
|
30 |
+
Sites running WooCommerce get another style added to the <code><head></code> section of the site. With the Classic Editor Addon installed that call is obviously redundant. With version 2.5.0 we introduce a condition that checks for WooCommerce and if active it removes that call. Win!
|
31 |
|
32 |
Therefore we highly recommend installing this "Classic Editor Addon" plugin, which will automatically install the “Classic Editor” plugin and remove its settings.
|
33 |
|
63 |
|
64 |
== Changelog ==
|
65 |
|
66 |
+
= 2.6.1 =
|
67 |
+
|
68 |
+
* March 5, 2020
|
69 |
+
* update WP Dependency Installer to 3.0.0
|
70 |
+
|
71 |
= 2.6.0 =
|
72 |
|
73 |
* November 14, 2019
|
vendor/afragen/wp-dependency-installer/wp-dependency-installer.php
CHANGED
@@ -1,5 +1,4 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
/**
|
4 |
* WP Dependency Installer
|
5 |
*
|
@@ -8,7 +7,7 @@
|
|
8 |
* It can install a plugin from w.org, GitHub, Bitbucket, GitLab, Gitea or direct URL.
|
9 |
*
|
10 |
* @package WP_Dependency_Installer
|
11 |
-
* @author Andy Fragen, Matt Gibbs
|
12 |
* @license MIT
|
13 |
* @link https://github.com/afragen/wp-dependency-installer
|
14 |
*/
|
@@ -21,124 +20,175 @@ if ( ! defined( 'WPINC' ) ) {
|
|
21 |
}
|
22 |
|
23 |
if ( ! class_exists( 'WP_Dependency_Installer' ) ) {
|
24 |
-
|
25 |
/**
|
26 |
* Class WP_Dependency_Installer
|
27 |
*/
|
28 |
class WP_Dependency_Installer {
|
29 |
-
|
30 |
/**
|
31 |
* Holds the JSON file contents.
|
32 |
*
|
33 |
* @var array $config
|
34 |
*/
|
35 |
-
|
36 |
|
37 |
/**
|
38 |
* Holds the current dependency's slug.
|
39 |
*
|
40 |
* @var string $current_slug
|
41 |
*/
|
42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
|
44 |
/**
|
45 |
* Holds the calling plugin/theme slug.
|
46 |
*
|
47 |
* @var string $source
|
48 |
*/
|
49 |
-
|
50 |
|
51 |
/**
|
52 |
* Holds names of installed dependencies for admin notices.
|
53 |
*
|
54 |
* @var array $notices
|
55 |
*/
|
56 |
-
|
57 |
|
58 |
/**
|
59 |
-
*
|
|
|
|
|
60 |
*/
|
61 |
-
public static function instance() {
|
62 |
static $instance = null;
|
63 |
if ( null === $instance ) {
|
64 |
$instance = new self();
|
65 |
}
|
|
|
|
|
66 |
|
67 |
return $instance;
|
68 |
}
|
69 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
/**
|
71 |
* Load hooks.
|
72 |
*
|
73 |
* @return void
|
74 |
*/
|
75 |
public function load_hooks() {
|
76 |
-
add_action( 'admin_init',
|
77 |
-
add_action( 'admin_footer',
|
78 |
-
add_action( 'admin_notices',
|
79 |
-
add_action( 'network_admin_notices',
|
80 |
-
add_action( 'wp_ajax_dependency_installer',
|
|
|
81 |
|
82 |
// Initialize Persist admin Notices Dismissal dependency.
|
83 |
-
add_action( 'admin_init',
|
84 |
}
|
85 |
|
86 |
/**
|
87 |
-
*
|
|
|
|
|
|
|
|
|
88 |
*
|
89 |
-
* @
|
90 |
*/
|
91 |
-
public function run( $
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
}
|
99 |
-
$this->source = basename( $plugin_path );
|
100 |
$this->load_hooks();
|
101 |
-
$this->register( $config );
|
102 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
}
|
104 |
|
105 |
/**
|
106 |
* Register dependencies (supports multiple instances).
|
107 |
*
|
108 |
-
* @param array
|
|
|
|
|
|
|
109 |
*/
|
110 |
-
public function register( $config ) {
|
|
|
111 |
foreach ( $config as $dependency ) {
|
112 |
-
|
113 |
-
$
|
114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
$this->config[ $slug ] = $dependency;
|
116 |
}
|
117 |
}
|
|
|
|
|
118 |
}
|
119 |
|
120 |
/**
|
121 |
* Process the registered dependencies.
|
122 |
*/
|
123 |
-
|
124 |
foreach ( $this->config as $dependency ) {
|
125 |
$download_link = null;
|
126 |
$base = null;
|
127 |
$uri = $dependency['uri'];
|
128 |
$slug = $dependency['slug'];
|
129 |
-
$
|
130 |
-
$
|
131 |
-
$
|
132 |
-
$
|
|
|
|
|
|
|
133 |
$owner_repo = str_replace( '.git', '', trim( $path, '/' ) );
|
134 |
|
135 |
switch ( $dependency['host'] ) {
|
136 |
case 'github':
|
137 |
$base = null === $api || 'github.com' === $api ? 'api.github.com' : $api;
|
138 |
$download_link = "{$scheme}{$base}/repos/{$owner_repo}/zipball/{$dependency['branch']}";
|
139 |
-
if ( ! empty( $dependency['token'] ) ) {
|
140 |
-
$download_link = add_query_arg( 'access_token', $dependency['token'], $download_link );
|
141 |
-
}
|
142 |
break;
|
143 |
case 'bitbucket':
|
144 |
$base = null === $api || 'bitbucket.org' === $api ? 'bitbucket.org' : $api;
|
@@ -149,15 +199,9 @@ if ( ! class_exists( 'WP_Dependency_Installer' ) ) {
|
|
149 |
$project_id = rawurlencode( $owner_repo );
|
150 |
$download_link = "{$scheme}{$base}/api/v4/projects/{$project_id}/repository/archive.zip";
|
151 |
$download_link = add_query_arg( 'sha', $dependency['branch'], $download_link );
|
152 |
-
if ( ! empty( $dependency['token'] ) ) {
|
153 |
-
$download_link = add_query_arg( 'private_token', $dependency['token'], $download_link );
|
154 |
-
}
|
155 |
break;
|
156 |
case 'gitea':
|
157 |
-
$download_link = "{$scheme}{$api}/repos/{$owner_repo}/archive/{$dependency['branch']}.zip";
|
158 |
-
if ( ! empty( $dependency['token'] ) ) {
|
159 |
-
$download_link = add_query_arg( 'access_token', $dependency['token'], $download_link );
|
160 |
-
}
|
161 |
break;
|
162 |
case 'wordpress': // phpcs:ignore WordPress.WP.CapitalPDangit.Misspelled
|
163 |
$download_link = $this->get_dot_org_latest_download( basename( $owner_repo ) );
|
@@ -175,16 +219,23 @@ if ( ! class_exists( 'WP_Dependency_Installer' ) ) {
|
|
175 |
* @param string $download_link Download link.
|
176 |
* @param array $dependency Dependency configuration.
|
177 |
*/
|
178 |
-
$download_link = apply_filters( 'wp_dependency_download_link', $download_link, $dependency );
|
179 |
|
180 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
}
|
182 |
}
|
183 |
|
184 |
/**
|
185 |
* Get lastest download link from WordPress API.
|
186 |
*
|
187 |
-
* @param
|
188 |
* @return string $download_link
|
189 |
*/
|
190 |
private function get_dot_org_latest_download( $slug ) {
|
@@ -193,10 +244,10 @@ if ( ! class_exists( 'WP_Dependency_Installer' ) ) {
|
|
193 |
if ( ! $download_link ) {
|
194 |
$url = 'https://api.wordpress.org/plugins/info/1.1/';
|
195 |
$url = add_query_arg(
|
196 |
-
|
197 |
'action' => 'plugin_information',
|
198 |
rawurlencode( 'request[slug]' ) => $slug,
|
199 |
-
|
200 |
$url
|
201 |
);
|
202 |
$response = wp_remote_get( $url );
|
@@ -220,40 +271,37 @@ if ( ! class_exists( 'WP_Dependency_Installer' ) ) {
|
|
220 |
|
221 |
// Generate admin notices.
|
222 |
foreach ( $this->config as $slug => $dependency ) {
|
223 |
-
$
|
224 |
|
225 |
-
if (
|
226 |
-
$this->
|
227 |
}
|
228 |
|
229 |
-
if (
|
230 |
-
|
231 |
-
}
|
232 |
-
|
233 |
-
if ( $this->is_installed( $slug ) ) {
|
234 |
-
if ( $is_optional ) {
|
235 |
-
$this->notices[] = array(
|
236 |
-
'action' => 'activate',
|
237 |
-
'slug' => $slug,
|
238 |
-
/* translators: %s: Plugin name */
|
239 |
-
'text' => sprintf( esc_html__( 'Please activate the %s plugin.' ), $dependency['name'] ),
|
240 |
-
'source' => $dependency['source'],
|
241 |
-
);
|
242 |
-
|
243 |
-
} else {
|
244 |
$this->notices[] = $this->activate( $slug );
|
|
|
|
|
245 |
}
|
246 |
-
} elseif ( $is_optional ) {
|
247 |
-
$this->notices[] = array(
|
248 |
-
'action' => 'install',
|
249 |
-
'slug' => $slug,
|
250 |
-
/* translators: %s: Plugin name */
|
251 |
-
'text' => sprintf( esc_html__( 'The %s plugin is required.' ), $dependency['name'] ),
|
252 |
-
'source' => $dependency['source'],
|
253 |
-
);
|
254 |
} else {
|
255 |
-
|
|
|
|
|
|
|
|
|
256 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
257 |
}
|
258 |
}
|
259 |
|
@@ -297,7 +345,7 @@ if ( ! class_exists( 'WP_Dependency_Installer' ) ) {
|
|
297 |
public function ajax_router() {
|
298 |
$method = isset( $_POST['method'] ) ? $_POST['method'] : '';
|
299 |
$slug = isset( $_POST['slug'] ) ? $_POST['slug'] : '';
|
300 |
-
$whitelist =
|
301 |
|
302 |
if ( in_array( $method, $whitelist, true ) ) {
|
303 |
$response = $this->$method( $slug );
|
@@ -306,6 +354,32 @@ if ( ! class_exists( 'WP_Dependency_Installer' ) ) {
|
|
306 |
wp_die();
|
307 |
}
|
308 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
309 |
/**
|
310 |
* Is dependency installed?
|
311 |
*
|
@@ -319,6 +393,17 @@ if ( ! class_exists( 'WP_Dependency_Installer' ) ) {
|
|
319 |
return isset( $plugins[ $slug ] );
|
320 |
}
|
321 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
322 |
/**
|
323 |
* Install and activate dependency.
|
324 |
*
|
@@ -332,54 +417,73 @@ if ( ! class_exists( 'WP_Dependency_Installer' ) ) {
|
|
332 |
}
|
333 |
|
334 |
$this->current_slug = $slug;
|
335 |
-
add_filter( 'upgrader_source_selection',
|
336 |
|
337 |
$skin = new WPDI_Plugin_Installer_Skin(
|
338 |
-
|
339 |
'type' => 'plugin',
|
340 |
'nonce' => wp_nonce_url( $this->config[ $slug ]['download_link'] ),
|
341 |
-
|
342 |
);
|
343 |
$upgrader = new Plugin_Upgrader( $skin );
|
344 |
$result = $upgrader->install( $this->config[ $slug ]['download_link'] );
|
345 |
|
346 |
if ( is_wp_error( $result ) ) {
|
347 |
-
return
|
348 |
'status' => 'error',
|
349 |
'message' => $result->get_error_message(),
|
350 |
-
|
351 |
}
|
352 |
|
353 |
if ( null === $result ) {
|
354 |
-
return
|
355 |
'status' => 'error',
|
356 |
'message' => esc_html__( 'Plugin download failed' ),
|
357 |
-
|
358 |
}
|
359 |
|
360 |
wp_cache_flush();
|
361 |
-
if (
|
362 |
$this->activate( $slug );
|
363 |
|
364 |
-
return
|
365 |
'status' => 'updated',
|
366 |
'slug' => $slug,
|
367 |
/* translators: %s: Plugin name */
|
368 |
'message' => sprintf( esc_html__( '%s has been installed and activated.' ), $this->config[ $slug ]['name'] ),
|
369 |
'source' => $this->config[ $slug ]['source'],
|
370 |
-
|
371 |
-
|
372 |
}
|
373 |
-
|
|
|
374 |
return $result;
|
375 |
}
|
376 |
|
377 |
-
return
|
378 |
'status' => 'updated',
|
379 |
/* translators: %s: Plugin name */
|
380 |
'message' => sprintf( esc_html__( '%s has been installed.' ), $this->config[ $slug ]['name'] ),
|
381 |
'source' => $this->config[ $slug ]['source'],
|
382 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
383 |
}
|
384 |
|
385 |
/**
|
@@ -390,23 +494,41 @@ if ( ! class_exists( 'WP_Dependency_Installer' ) ) {
|
|
390 |
* @return array Message.
|
391 |
*/
|
392 |
public function activate( $slug ) {
|
393 |
-
|
394 |
// network activate only if on network admin pages.
|
395 |
$result = is_network_admin() ? activate_plugin( $slug, null, true ) : activate_plugin( $slug );
|
396 |
|
397 |
if ( is_wp_error( $result ) ) {
|
398 |
-
return
|
399 |
'status' => 'error',
|
400 |
'message' => $result->get_error_message(),
|
401 |
-
|
402 |
}
|
403 |
|
404 |
-
return
|
405 |
'status' => 'updated',
|
406 |
/* translators: %s: Plugin name */
|
407 |
'message' => sprintf( esc_html__( '%s has been activated.' ), $this->config[ $slug ]['name'] ),
|
408 |
'source' => $this->config[ $slug ]['source'],
|
409 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
410 |
}
|
411 |
|
412 |
/**
|
@@ -415,28 +537,62 @@ if ( ! class_exists( 'WP_Dependency_Installer' ) ) {
|
|
415 |
* @return array Empty Message.
|
416 |
*/
|
417 |
public function dismiss() {
|
418 |
-
return
|
419 |
'status' => 'updated',
|
420 |
'message' => '',
|
421 |
-
|
422 |
}
|
423 |
|
424 |
/**
|
425 |
* Correctly rename dependency for activation.
|
426 |
*
|
427 |
-
* @param string $source
|
428 |
-
* @param string $remote_source
|
429 |
*
|
430 |
* @return string $new_source
|
431 |
*/
|
432 |
public function upgrader_source_selection( $source, $remote_source ) {
|
433 |
-
global $wp_filesystem;
|
434 |
$new_source = trailingslashit( $remote_source ) . dirname( $this->current_slug );
|
435 |
-
$
|
436 |
|
437 |
return trailingslashit( $new_source );
|
438 |
}
|
439 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
440 |
/**
|
441 |
* Display admin notices / action links.
|
442 |
*
|
@@ -446,82 +602,161 @@ if ( ! class_exists( 'WP_Dependency_Installer' ) ) {
|
|
446 |
if ( ! current_user_can( 'update_plugins' ) ) {
|
447 |
return false;
|
448 |
}
|
449 |
-
$message = null;
|
450 |
foreach ( $this->notices as $notice ) {
|
451 |
-
$status
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
|
|
459 |
$message = esc_html( $notice['message'] );
|
460 |
}
|
461 |
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
477 |
}
|
478 |
-
?>
|
479 |
-
<div data-dismissible="<?php echo $dismissible; ?>" class="<?php echo $status; ?> notice is-dismissible dependency-installer">
|
480 |
-
<p><?php echo '<strong>[' . esc_html__( 'Dependency' ) . ']</strong> ' . $message; ?></p>
|
481 |
-
</div>
|
482 |
-
<?php
|
483 |
}
|
484 |
}
|
485 |
|
486 |
/**
|
487 |
-
*
|
488 |
*
|
489 |
-
* @param $plugin_file
|
490 |
*/
|
491 |
-
|
492 |
-
add_filter( 'network_admin_plugin_action_links_' . $plugin_file,
|
493 |
-
add_filter( 'plugin_action_links_' . $plugin_file,
|
494 |
-
add_action(
|
495 |
-
'after_plugin_row_' . $plugin_file,
|
496 |
-
function( $plugin_file ) {
|
497 |
-
print( '<script>jQuery(".inactive[data-plugin=\'' . $plugin_file . '\']").attr("class", "active");</script>' );
|
498 |
-
print( '<script>jQuery(".active[data-plugin=\'' . $plugin_file . '\'] .check-column input").remove();</script>' );
|
499 |
-
}
|
500 |
-
);
|
501 |
}
|
502 |
|
503 |
/**
|
504 |
-
* Unset plugin action links so
|
505 |
*
|
506 |
-
* @param $actions
|
|
|
507 |
*
|
508 |
* @return mixed
|
509 |
*/
|
510 |
-
public function unset_action_links( $actions ) {
|
511 |
-
|
512 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
513 |
}
|
514 |
-
|
515 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
516 |
}
|
517 |
-
|
518 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
519 |
}
|
|
|
|
|
|
|
|
|
520 |
|
521 |
-
|
522 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
523 |
|
524 |
-
return $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
525 |
}
|
526 |
|
527 |
/**
|
@@ -529,10 +764,59 @@ if ( ! class_exists( 'WP_Dependency_Installer' ) ) {
|
|
529 |
*
|
530 |
* @since 1.4.11
|
531 |
*
|
532 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
533 |
*/
|
534 |
-
public function
|
535 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
536 |
}
|
537 |
}
|
538 |
|
@@ -542,10 +826,16 @@ if ( ! class_exists( 'WP_Dependency_Installer' ) ) {
|
|
542 |
* Class WPDI_Plugin_Installer_Skin
|
543 |
*/
|
544 |
class WPDI_Plugin_Installer_Skin extends Plugin_Installer_Skin {
|
545 |
-
public function header() {
|
546 |
-
|
547 |
-
|
548 |
-
public function
|
549 |
-
|
|
|
|
|
|
|
550 |
|
|
|
|
|
|
|
551 |
}
|
1 |
<?php
|
|
|
2 |
/**
|
3 |
* WP Dependency Installer
|
4 |
*
|
7 |
* It can install a plugin from w.org, GitHub, Bitbucket, GitLab, Gitea or direct URL.
|
8 |
*
|
9 |
* @package WP_Dependency_Installer
|
10 |
+
* @author Andy Fragen, Matt Gibbs, Raruto
|
11 |
* @license MIT
|
12 |
* @link https://github.com/afragen/wp-dependency-installer
|
13 |
*/
|
20 |
}
|
21 |
|
22 |
if ( ! class_exists( 'WP_Dependency_Installer' ) ) {
|
|
|
23 |
/**
|
24 |
* Class WP_Dependency_Installer
|
25 |
*/
|
26 |
class WP_Dependency_Installer {
|
|
|
27 |
/**
|
28 |
* Holds the JSON file contents.
|
29 |
*
|
30 |
* @var array $config
|
31 |
*/
|
32 |
+
private $config;
|
33 |
|
34 |
/**
|
35 |
* Holds the current dependency's slug.
|
36 |
*
|
37 |
* @var string $current_slug
|
38 |
*/
|
39 |
+
private $current_slug;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Holds the calling plugin/theme file path.
|
43 |
+
*
|
44 |
+
* @var string $source
|
45 |
+
*/
|
46 |
+
private static $caller;
|
47 |
|
48 |
/**
|
49 |
* Holds the calling plugin/theme slug.
|
50 |
*
|
51 |
* @var string $source
|
52 |
*/
|
53 |
+
private static $source;
|
54 |
|
55 |
/**
|
56 |
* Holds names of installed dependencies for admin notices.
|
57 |
*
|
58 |
* @var array $notices
|
59 |
*/
|
60 |
+
private $notices;
|
61 |
|
62 |
/**
|
63 |
+
* Factory.
|
64 |
+
*
|
65 |
+
* @param string $caller File path to calling plugin/theme.
|
66 |
*/
|
67 |
+
public static function instance( $caller = false ) {
|
68 |
static $instance = null;
|
69 |
if ( null === $instance ) {
|
70 |
$instance = new self();
|
71 |
}
|
72 |
+
self::$caller = $caller;
|
73 |
+
self::$source = ! $caller ? false : basename( $caller );
|
74 |
|
75 |
return $instance;
|
76 |
}
|
77 |
|
78 |
+
/**
|
79 |
+
* Private constructor.
|
80 |
+
*/
|
81 |
+
private function __construct() {
|
82 |
+
$this->config = [];
|
83 |
+
$this->notices = [];
|
84 |
+
}
|
85 |
+
|
86 |
/**
|
87 |
* Load hooks.
|
88 |
*
|
89 |
* @return void
|
90 |
*/
|
91 |
public function load_hooks() {
|
92 |
+
add_action( 'admin_init', [ $this, 'admin_init' ] );
|
93 |
+
add_action( 'admin_footer', [ $this, 'admin_footer' ] );
|
94 |
+
add_action( 'admin_notices', [ $this, 'admin_notices' ] );
|
95 |
+
add_action( 'network_admin_notices', [ $this, 'admin_notices' ] );
|
96 |
+
add_action( 'wp_ajax_dependency_installer', [ $this, 'ajax_router' ] );
|
97 |
+
add_filter( 'http_request_args', [ $this, 'add_basic_auth_headers' ], 15, 2 );
|
98 |
|
99 |
// Initialize Persist admin Notices Dismissal dependency.
|
100 |
+
add_action( 'admin_init', [ 'PAnD', 'init' ] );
|
101 |
}
|
102 |
|
103 |
/**
|
104 |
+
* Let's get going.
|
105 |
+
* First load data from wp-dependencies.json if present.
|
106 |
+
* Then load hooks needed to run.
|
107 |
+
*
|
108 |
+
* @param string $caller Path to plugin or theme calling the framework.
|
109 |
*
|
110 |
+
* @return self
|
111 |
*/
|
112 |
+
public function run( $caller = false ) {
|
113 |
+
$caller = ! $caller ? self::$caller : $caller;
|
114 |
+
$config = $this->json_file_decode( $caller . '/wp-dependencies.json' );
|
115 |
+
if ( ! empty( $config ) ) {
|
116 |
+
$this->register( $config, $caller );
|
117 |
+
}
|
118 |
+
if ( ! empty( $this->config ) ) {
|
|
|
|
|
119 |
$this->load_hooks();
|
|
|
120 |
}
|
121 |
+
|
122 |
+
return $this;
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Decode JSON config data from a file.
|
127 |
+
*
|
128 |
+
* @param string $json_path File path to JSON config file.
|
129 |
+
*
|
130 |
+
* @return bool|array $config
|
131 |
+
*/
|
132 |
+
public function json_file_decode( $json_path ) {
|
133 |
+
$config = [];
|
134 |
+
if ( file_exists( $json_path ) ) {
|
135 |
+
$config = file_get_contents( $json_path );
|
136 |
+
$config = json_decode( $config, true );
|
137 |
+
}
|
138 |
+
|
139 |
+
return $config;
|
140 |
}
|
141 |
|
142 |
/**
|
143 |
* Register dependencies (supports multiple instances).
|
144 |
*
|
145 |
+
* @param array $config JSON config as array.
|
146 |
+
* @param string $caller Path to plugin or theme calling the framework.
|
147 |
+
*
|
148 |
+
* @return self
|
149 |
*/
|
150 |
+
public function register( $config, $caller = false ) {
|
151 |
+
$source = ! self::$source ? basename( $caller ) : self::$source;
|
152 |
foreach ( $config as $dependency ) {
|
153 |
+
// Save a reference of current dependent plugin.
|
154 |
+
$dependency['source'] = $source;
|
155 |
+
$dependency['sources'][] = $source;
|
156 |
+
$slug = $dependency['slug'];
|
157 |
+
// Keep a reference of all dependent plugins.
|
158 |
+
if ( isset( $this->config[ $slug ] ) ) {
|
159 |
+
$dependency['sources'] = array_merge( $this->config[ $slug ]['sources'], $dependency['sources'] );
|
160 |
+
}
|
161 |
+
// Update config.
|
162 |
+
if ( ! isset( $this->config[ $slug ] ) || $this->is_required( $dependency ) ) {
|
163 |
$this->config[ $slug ] = $dependency;
|
164 |
}
|
165 |
}
|
166 |
+
|
167 |
+
return $this;
|
168 |
}
|
169 |
|
170 |
/**
|
171 |
* Process the registered dependencies.
|
172 |
*/
|
173 |
+
private function apply_config() {
|
174 |
foreach ( $this->config as $dependency ) {
|
175 |
$download_link = null;
|
176 |
$base = null;
|
177 |
$uri = $dependency['uri'];
|
178 |
$slug = $dependency['slug'];
|
179 |
+
$uri_args = parse_url( $uri ); // phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url
|
180 |
+
$port = isset( $uri_args['port'] ) ? $uri_args['port'] : null;
|
181 |
+
$api = isset( $uri_args['host'] ) ? $uri_args['host'] : null;
|
182 |
+
$api = ! $port ? $api : "$api:$port";
|
183 |
+
$scheme = isset( $uri_args['scheme'] ) ? $uri_args['scheme'] : null;
|
184 |
+
$scheme = null !== $scheme ? $scheme . '://' : 'https://';
|
185 |
+
$path = isset( $uri_args['path'] ) ? $uri_args['path'] : null;
|
186 |
$owner_repo = str_replace( '.git', '', trim( $path, '/' ) );
|
187 |
|
188 |
switch ( $dependency['host'] ) {
|
189 |
case 'github':
|
190 |
$base = null === $api || 'github.com' === $api ? 'api.github.com' : $api;
|
191 |
$download_link = "{$scheme}{$base}/repos/{$owner_repo}/zipball/{$dependency['branch']}";
|
|
|
|
|
|
|
192 |
break;
|
193 |
case 'bitbucket':
|
194 |
$base = null === $api || 'bitbucket.org' === $api ? 'bitbucket.org' : $api;
|
199 |
$project_id = rawurlencode( $owner_repo );
|
200 |
$download_link = "{$scheme}{$base}/api/v4/projects/{$project_id}/repository/archive.zip";
|
201 |
$download_link = add_query_arg( 'sha', $dependency['branch'], $download_link );
|
|
|
|
|
|
|
202 |
break;
|
203 |
case 'gitea':
|
204 |
+
$download_link = "{$scheme}{$api}/api/v1/repos/{$owner_repo}/archive/{$dependency['branch']}.zip";
|
|
|
|
|
|
|
205 |
break;
|
206 |
case 'wordpress': // phpcs:ignore WordPress.WP.CapitalPDangit.Misspelled
|
207 |
$download_link = $this->get_dot_org_latest_download( basename( $owner_repo ) );
|
219 |
* @param string $download_link Download link.
|
220 |
* @param array $dependency Dependency configuration.
|
221 |
*/
|
222 |
+
$dependency['download_link'] = apply_filters( 'wp_dependency_download_link', $download_link, $dependency );
|
223 |
|
224 |
+
/**
|
225 |
+
* Allow filtering of individual dependency config.
|
226 |
+
*
|
227 |
+
* @since 3.0.0
|
228 |
+
*
|
229 |
+
* @param array $dependency Dependency configuration.
|
230 |
+
*/
|
231 |
+
$this->config[ $slug ] = apply_filters( 'wp_dependency_config', $dependency );
|
232 |
}
|
233 |
}
|
234 |
|
235 |
/**
|
236 |
* Get lastest download link from WordPress API.
|
237 |
*
|
238 |
+
* @param string $slug Plugin slug.
|
239 |
* @return string $download_link
|
240 |
*/
|
241 |
private function get_dot_org_latest_download( $slug ) {
|
244 |
if ( ! $download_link ) {
|
245 |
$url = 'https://api.wordpress.org/plugins/info/1.1/';
|
246 |
$url = add_query_arg(
|
247 |
+
[
|
248 |
'action' => 'plugin_information',
|
249 |
rawurlencode( 'request[slug]' ) => $slug,
|
250 |
+
],
|
251 |
$url
|
252 |
);
|
253 |
$response = wp_remote_get( $url );
|
271 |
|
272 |
// Generate admin notices.
|
273 |
foreach ( $this->config as $slug => $dependency ) {
|
274 |
+
$is_required = $this->is_required( $dependency );
|
275 |
|
276 |
+
if ( $is_required ) {
|
277 |
+
$this->modify_plugin_row( $slug );
|
278 |
}
|
279 |
|
280 |
+
if ( $this->is_active( $slug ) ) {
|
281 |
+
// Do nothing.
|
282 |
+
} elseif ( $this->is_installed( $slug ) ) {
|
283 |
+
if ( $is_required ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
284 |
$this->notices[] = $this->activate( $slug );
|
285 |
+
} else {
|
286 |
+
$this->notices[] = $this->activate_notice( $slug );
|
287 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
} else {
|
289 |
+
if ( $is_required ) {
|
290 |
+
$this->notices[] = $this->install( $slug );
|
291 |
+
} else {
|
292 |
+
$this->notices[] = $this->install_notice( $slug );
|
293 |
+
}
|
294 |
}
|
295 |
+
|
296 |
+
/**
|
297 |
+
* Allow filtering of admin notices.
|
298 |
+
*
|
299 |
+
* @since 3.0.0
|
300 |
+
*
|
301 |
+
* @param array $notices admin notices.
|
302 |
+
* @param string $slug plugin slug.
|
303 |
+
*/
|
304 |
+
$this->notices = apply_filters( 'wp_dependency_notices', $this->notices, $slug );
|
305 |
}
|
306 |
}
|
307 |
|
345 |
public function ajax_router() {
|
346 |
$method = isset( $_POST['method'] ) ? $_POST['method'] : '';
|
347 |
$slug = isset( $_POST['slug'] ) ? $_POST['slug'] : '';
|
348 |
+
$whitelist = [ 'install', 'activate', 'dismiss' ];
|
349 |
|
350 |
if ( in_array( $method, $whitelist, true ) ) {
|
351 |
$response = $this->$method( $slug );
|
354 |
wp_die();
|
355 |
}
|
356 |
|
357 |
+
/**
|
358 |
+
* Check if a dependency is currently required.
|
359 |
+
*
|
360 |
+
* @param string|array $plugin Plugin dependency slug or config.
|
361 |
+
*
|
362 |
+
* @return boolean True if required. Default: False
|
363 |
+
*/
|
364 |
+
public function is_required( &$plugin ) {
|
365 |
+
if ( empty( $this->config ) ) {
|
366 |
+
return false;
|
367 |
+
}
|
368 |
+
if ( is_string( $plugin ) && isset( $this->config[ $plugin ] ) ) {
|
369 |
+
$dependency = &$this->config[ $plugin ];
|
370 |
+
} else {
|
371 |
+
$dependency = &$plugin;
|
372 |
+
}
|
373 |
+
if ( isset( $dependency['required'] ) ) {
|
374 |
+
return true === $dependency['required'] || 'true' === $dependency['required'];
|
375 |
+
}
|
376 |
+
if ( isset( $dependency['optional'] ) ) {
|
377 |
+
return false === $dependency['optional'] || 'false' === $dependency['optional'];
|
378 |
+
}
|
379 |
+
|
380 |
+
return false;
|
381 |
+
}
|
382 |
+
|
383 |
/**
|
384 |
* Is dependency installed?
|
385 |
*
|
393 |
return isset( $plugins[ $slug ] );
|
394 |
}
|
395 |
|
396 |
+
/**
|
397 |
+
* Is dependency active?
|
398 |
+
*
|
399 |
+
* @param string $slug Plugin slug.
|
400 |
+
*
|
401 |
+
* @return boolean
|
402 |
+
*/
|
403 |
+
public function is_active( $slug ) {
|
404 |
+
return is_plugin_active( $slug );
|
405 |
+
}
|
406 |
+
|
407 |
/**
|
408 |
* Install and activate dependency.
|
409 |
*
|
417 |
}
|
418 |
|
419 |
$this->current_slug = $slug;
|
420 |
+
add_filter( 'upgrader_source_selection', [ $this, 'upgrader_source_selection' ], 10, 2 );
|
421 |
|
422 |
$skin = new WPDI_Plugin_Installer_Skin(
|
423 |
+
[
|
424 |
'type' => 'plugin',
|
425 |
'nonce' => wp_nonce_url( $this->config[ $slug ]['download_link'] ),
|
426 |
+
]
|
427 |
);
|
428 |
$upgrader = new Plugin_Upgrader( $skin );
|
429 |
$result = $upgrader->install( $this->config[ $slug ]['download_link'] );
|
430 |
|
431 |
if ( is_wp_error( $result ) ) {
|
432 |
+
return [
|
433 |
'status' => 'error',
|
434 |
'message' => $result->get_error_message(),
|
435 |
+
];
|
436 |
}
|
437 |
|
438 |
if ( null === $result ) {
|
439 |
+
return [
|
440 |
'status' => 'error',
|
441 |
'message' => esc_html__( 'Plugin download failed' ),
|
442 |
+
];
|
443 |
}
|
444 |
|
445 |
wp_cache_flush();
|
446 |
+
if ( $this->is_required( $slug ) ) {
|
447 |
$this->activate( $slug );
|
448 |
|
449 |
+
return [
|
450 |
'status' => 'updated',
|
451 |
'slug' => $slug,
|
452 |
/* translators: %s: Plugin name */
|
453 |
'message' => sprintf( esc_html__( '%s has been installed and activated.' ), $this->config[ $slug ]['name'] ),
|
454 |
'source' => $this->config[ $slug ]['source'],
|
455 |
+
];
|
|
|
456 |
}
|
457 |
+
|
458 |
+
if ( true !== $result && 'error' === $result['status'] ) {
|
459 |
return $result;
|
460 |
}
|
461 |
|
462 |
+
return [
|
463 |
'status' => 'updated',
|
464 |
/* translators: %s: Plugin name */
|
465 |
'message' => sprintf( esc_html__( '%s has been installed.' ), $this->config[ $slug ]['name'] ),
|
466 |
'source' => $this->config[ $slug ]['source'],
|
467 |
+
];
|
468 |
+
}
|
469 |
+
|
470 |
+
/**
|
471 |
+
* Get install plugin notice.
|
472 |
+
*
|
473 |
+
* @param string $slug Plugin slug.
|
474 |
+
*
|
475 |
+
* @return array Admin notice.
|
476 |
+
*/
|
477 |
+
public function install_notice( $slug ) {
|
478 |
+
$dependency = $this->config[ $slug ];
|
479 |
+
|
480 |
+
return [
|
481 |
+
'action' => 'install',
|
482 |
+
'slug' => $slug,
|
483 |
+
/* translators: %s: Plugin name */
|
484 |
+
'message' => sprintf( esc_html__( 'The %s plugin is recommended.' ), $dependency['name'] ),
|
485 |
+
'source' => $dependency['source'],
|
486 |
+
];
|
487 |
}
|
488 |
|
489 |
/**
|
494 |
* @return array Message.
|
495 |
*/
|
496 |
public function activate( $slug ) {
|
|
|
497 |
// network activate only if on network admin pages.
|
498 |
$result = is_network_admin() ? activate_plugin( $slug, null, true ) : activate_plugin( $slug );
|
499 |
|
500 |
if ( is_wp_error( $result ) ) {
|
501 |
+
return [
|
502 |
'status' => 'error',
|
503 |
'message' => $result->get_error_message(),
|
504 |
+
];
|
505 |
}
|
506 |
|
507 |
+
return [
|
508 |
'status' => 'updated',
|
509 |
/* translators: %s: Plugin name */
|
510 |
'message' => sprintf( esc_html__( '%s has been activated.' ), $this->config[ $slug ]['name'] ),
|
511 |
'source' => $this->config[ $slug ]['source'],
|
512 |
+
];
|
513 |
+
}
|
514 |
+
|
515 |
+
/**
|
516 |
+
* Get activate plugin notice.
|
517 |
+
*
|
518 |
+
* @param string $slug Plugin slug.
|
519 |
+
*
|
520 |
+
* @return array Admin notice.
|
521 |
+
*/
|
522 |
+
public function activate_notice( $slug ) {
|
523 |
+
$dependency = $this->config[ $slug ];
|
524 |
+
|
525 |
+
return [
|
526 |
+
'action' => 'activate',
|
527 |
+
'slug' => $slug,
|
528 |
+
/* translators: %s: Plugin name */
|
529 |
+
'message' => sprintf( esc_html__( 'Please activate the %s plugin.' ), $dependency['name'] ),
|
530 |
+
'source' => $dependency['source'],
|
531 |
+
];
|
532 |
}
|
533 |
|
534 |
/**
|
537 |
* @return array Empty Message.
|
538 |
*/
|
539 |
public function dismiss() {
|
540 |
+
return [
|
541 |
'status' => 'updated',
|
542 |
'message' => '',
|
543 |
+
];
|
544 |
}
|
545 |
|
546 |
/**
|
547 |
* Correctly rename dependency for activation.
|
548 |
*
|
549 |
+
* @param string $source Path fo $source.
|
550 |
+
* @param string $remote_source Path of $remote_source.
|
551 |
*
|
552 |
* @return string $new_source
|
553 |
*/
|
554 |
public function upgrader_source_selection( $source, $remote_source ) {
|
|
|
555 |
$new_source = trailingslashit( $remote_source ) . dirname( $this->current_slug );
|
556 |
+
$this->move( $source, $new_source );
|
557 |
|
558 |
return trailingslashit( $new_source );
|
559 |
}
|
560 |
|
561 |
+
/**
|
562 |
+
* Rename or recursive file copy and delete.
|
563 |
+
*
|
564 |
+
* This is more versatile than `$wp_filesystem->move()`.
|
565 |
+
* It moves/renames directories as well as files.
|
566 |
+
* Fix for https://github.com/afragen/github-updater/issues/826,
|
567 |
+
* strange failure of `rename()`.
|
568 |
+
*
|
569 |
+
* @param string $source File path of source.
|
570 |
+
* @param string $destination File path of destination.
|
571 |
+
*
|
572 |
+
* @return bool|void
|
573 |
+
*/
|
574 |
+
private function move( $source, $destination ) {
|
575 |
+
if ( @rename( $source, $destination ) ) {
|
576 |
+
return true;
|
577 |
+
}
|
578 |
+
$dir = opendir( $source );
|
579 |
+
mkdir( $destination );
|
580 |
+
$source = untrailingslashit( $source );
|
581 |
+
// phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
|
582 |
+
while ( false !== ( $file = readdir( $dir ) ) ) {
|
583 |
+
if ( ( '.' !== $file ) && ( '..' !== $file ) && "$source/$file" !== $destination ) {
|
584 |
+
if ( is_dir( "$source/$file" ) ) {
|
585 |
+
$this->move( "$source/$file", "$destination/$file" );
|
586 |
+
} else {
|
587 |
+
copy( "$source/$file", "$destination/$file" );
|
588 |
+
unlink( "$source/$file" );
|
589 |
+
}
|
590 |
+
}
|
591 |
+
}
|
592 |
+
@rmdir( $source );
|
593 |
+
closedir( $dir );
|
594 |
+
}
|
595 |
+
|
596 |
/**
|
597 |
* Display admin notices / action links.
|
598 |
*
|
602 |
if ( ! current_user_can( 'update_plugins' ) ) {
|
603 |
return false;
|
604 |
}
|
|
|
605 |
foreach ( $this->notices as $notice ) {
|
606 |
+
$status = isset( $notice['status'] ) ? $notice['status'] : 'updated';
|
607 |
+
$source = isset( $notice['source'] ) ? $notice['source'] : __( 'Dependency' );
|
608 |
+
$class = esc_attr( $status ) . ' notice is-dismissible dependency-installer';
|
609 |
+
$label = esc_html( $this->get_dismiss_label( $source ) );
|
610 |
+
$message = '';
|
611 |
+
$action = '';
|
612 |
+
$dismissible = '';
|
613 |
+
|
614 |
+
if ( isset( $notice['message'] ) ) {
|
615 |
$message = esc_html( $notice['message'] );
|
616 |
}
|
617 |
|
618 |
+
if ( isset( $notice['action'] ) ) {
|
619 |
+
$action = sprintf(
|
620 |
+
' <a href="javascript:;" class="wpdi-button" data-action="%1$s" data-slug="%2$s">%3$s Now »</a> ',
|
621 |
+
esc_attr( $notice['action'] ),
|
622 |
+
esc_attr( $notice['slug'] ),
|
623 |
+
esc_html( ucfirst( $notice['action'] ) )
|
624 |
+
);
|
625 |
+
}
|
626 |
+
if ( isset( $notice['slug'] ) ) {
|
627 |
+
/**
|
628 |
+
* Filters the dismissal timeout.
|
629 |
+
*
|
630 |
+
* @since 1.4.1
|
631 |
+
*
|
632 |
+
* @param string|int '7' Default dismissal in days.
|
633 |
+
* @param string $notice['source'] Plugin slug of calling plugin.
|
634 |
+
* @return string|int Dismissal timeout in days.
|
635 |
+
*/
|
636 |
+
$timeout = apply_filters( 'wp_dependency_timeout', '7', $source );
|
637 |
+
$dependency = dirname( $notice['slug'] );
|
638 |
+
$dismissible = empty( $timeout ) ? '' : sprintf( 'dependency-installer-%1$s-%2$s', esc_attr( $dependency ), esc_attr( $timeout ) );
|
639 |
+
}
|
640 |
+
if ( class_exists( '\PAnD' ) && \PAnD::is_admin_notice_active( $dismissible ) ) {
|
641 |
+
printf( '<div class="%1$s" data-dismissible="%2$s"><p><strong>[%3$s]</strong> %4$s%5$s</p></div>', $class, $dismissible, $label, $message, $action );
|
642 |
}
|
|
|
|
|
|
|
|
|
|
|
643 |
}
|
644 |
}
|
645 |
|
646 |
/**
|
647 |
+
* Make modifications to plugin row.
|
648 |
*
|
649 |
+
* @param string $plugin_file Plugin file.
|
650 |
*/
|
651 |
+
private function modify_plugin_row( $plugin_file ) {
|
652 |
+
add_filter( 'network_admin_plugin_action_links_' . $plugin_file, [ $this, 'unset_action_links' ], 10, 2 );
|
653 |
+
add_filter( 'plugin_action_links_' . $plugin_file, [ $this, 'unset_action_links' ], 10, 2 );
|
654 |
+
add_action( 'after_plugin_row_' . $plugin_file, [ $this, 'modify_plugin_row_elements' ] );
|
|
|
|
|
|
|
|
|
|
|
|
|
655 |
}
|
656 |
|
657 |
/**
|
658 |
+
* Unset plugin action links so required plugins can't be removed or deactivated.
|
659 |
*
|
660 |
+
* @param array $actions Action links.
|
661 |
+
* @param string $plugin_file Plugin file.
|
662 |
*
|
663 |
* @return mixed
|
664 |
*/
|
665 |
+
public function unset_action_links( $actions, $plugin_file ) {
|
666 |
+
/**
|
667 |
+
* Allow to remove required plugin action links.
|
668 |
+
*
|
669 |
+
* @since 3.0.0
|
670 |
+
*
|
671 |
+
* @param bool $unset remove default action links.
|
672 |
+
*/
|
673 |
+
if ( apply_filters( 'wp_dependency_unset_action_links', true ) ) {
|
674 |
+
if ( isset( $actions['delete'] ) ) {
|
675 |
+
unset( $actions['delete'] );
|
676 |
+
}
|
677 |
+
|
678 |
+
if ( isset( $actions['deactivate'] ) ) {
|
679 |
+
unset( $actions['deactivate'] );
|
680 |
+
}
|
681 |
}
|
682 |
+
|
683 |
+
/**
|
684 |
+
* Allow to display of requied plugin label.
|
685 |
+
*
|
686 |
+
* @since 3.0.0
|
687 |
+
*
|
688 |
+
* @param bool $display show required plugin label.
|
689 |
+
*/
|
690 |
+
if ( apply_filters( 'wp_dependency_required_label', true ) ) {
|
691 |
+
/* translators: %s: opening and closing span tags */
|
692 |
+
$actions = array_merge( [ 'required-plugin' => sprintf( esc_html__( '%1$sRequired Plugin%2$s' ), '<span class="network_active" style="font-variant-caps: small-caps;">', '</span>' ) ], $actions );
|
693 |
}
|
694 |
+
|
695 |
+
return $actions;
|
696 |
+
}
|
697 |
+
|
698 |
+
/**
|
699 |
+
* Modify the plugin row elements.
|
700 |
+
*
|
701 |
+
* @param string $plugin_file Plugin file.
|
702 |
+
*
|
703 |
+
* @return void
|
704 |
+
*/
|
705 |
+
public function modify_plugin_row_elements( $plugin_file ) {
|
706 |
+
print '<script>';
|
707 |
+
/**
|
708 |
+
* Allow to display additional row meta info of required plugin.
|
709 |
+
*
|
710 |
+
* @since 3.0.0
|
711 |
+
*
|
712 |
+
* @param bool $display show plugin row meta.
|
713 |
+
*/
|
714 |
+
if ( apply_filters( 'wp_dependency_required_row_meta', true ) ) {
|
715 |
+
print 'jQuery("tr[data-plugin=\'' . $plugin_file . '\'] .plugin-version-author-uri").append("<br><br><strong>' . esc_html__( 'Required by:' ) . '</strong> ' . $this->get_dependency_sources( $plugin_file ) . '");';
|
716 |
}
|
717 |
+
print 'jQuery(".inactive[data-plugin=\'' . $plugin_file . '\']").attr("class", "active");';
|
718 |
+
print 'jQuery(".active[data-plugin=\'' . $plugin_file . '\'] .check-column input").remove();';
|
719 |
+
print '</script>';
|
720 |
+
}
|
721 |
|
722 |
+
/**
|
723 |
+
* Get formatted string of dependent plugins.
|
724 |
+
*
|
725 |
+
* @param string $plugin_file Plugin file.
|
726 |
+
*
|
727 |
+
* @return string $dependents
|
728 |
+
*/
|
729 |
+
private function get_dependency_sources( $plugin_file ) {
|
730 |
+
// Remove empty values from $sources.
|
731 |
+
$sources = array_filter( $this->config[ $plugin_file ]['sources'] );
|
732 |
+
$sources = array_map( [ $this, 'get_dismiss_label' ], $sources );
|
733 |
+
$sources = implode( ', ', $sources );
|
734 |
|
735 |
+
return $sources;
|
736 |
+
}
|
737 |
+
|
738 |
+
/**
|
739 |
+
* Get formatted source string for text usage.
|
740 |
+
*
|
741 |
+
* @param string $source plugin source.
|
742 |
+
*
|
743 |
+
* @return string friendly plugin name.
|
744 |
+
*/
|
745 |
+
private function get_dismiss_label( $source ) {
|
746 |
+
$label = str_replace( '-', ' ', $source );
|
747 |
+
$label = ucwords( $label );
|
748 |
+
$label = str_ireplace( 'wp ', 'WP ', $label );
|
749 |
+
|
750 |
+
/**
|
751 |
+
* Filters the dismissal notice label
|
752 |
+
*
|
753 |
+
* @since 3.0.0
|
754 |
+
*
|
755 |
+
* @param string $label Default dismissal notice string.
|
756 |
+
* @param string $source Plugin slug of calling plugin.
|
757 |
+
* @return string Dismissal notice string.
|
758 |
+
*/
|
759 |
+
return apply_filters( 'wp_dependency_dismiss_label', $label, $source );
|
760 |
}
|
761 |
|
762 |
/**
|
764 |
*
|
765 |
* @since 1.4.11
|
766 |
*
|
767 |
+
* @param string $slug Plugin slug.
|
768 |
+
* @param string $key Dependency key.
|
769 |
+
*
|
770 |
+
* @return mixed|array The configuration.
|
771 |
+
*/
|
772 |
+
public function get_config( $slug = '', $key = '' ) {
|
773 |
+
if ( empty( $slug ) && empty( $key ) ) {
|
774 |
+
return $this->config;
|
775 |
+
} elseif ( empty( $key ) ) {
|
776 |
+
return isset( $this->config[ $slug ] ) ? $this->config[ $slug ] : null;
|
777 |
+
} else {
|
778 |
+
return isset( $this->config[ $slug ][ $key ] ) ? $this->config[ $slug ][ $key ] : null;
|
779 |
+
}
|
780 |
+
}
|
781 |
+
|
782 |
+
/**
|
783 |
+
* Add Basic Auth headers for authentication.
|
784 |
+
*
|
785 |
+
* @param array $args HTTP header args.
|
786 |
+
* @param string $url URL.
|
787 |
+
*
|
788 |
+
* @return array $args
|
789 |
*/
|
790 |
+
public function add_basic_auth_headers( $args, $url ) {
|
791 |
+
if ( null === $this->current_slug ) {
|
792 |
+
return $args;
|
793 |
+
}
|
794 |
+
$package = $this->config[ $this->current_slug ];
|
795 |
+
$host = $package['host'];
|
796 |
+
$token = empty( $package['token'] ) ? false : $package['token'];
|
797 |
+
|
798 |
+
if ( $token && $url === $package['download_link'] ) {
|
799 |
+
if ( 'bitbucket' === $host ) {
|
800 |
+
// Bitbucket token must be in the form of 'username:password'.
|
801 |
+
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
|
802 |
+
$args['headers']['Authorization'] = 'Basic ' . base64_encode( $token );
|
803 |
+
}
|
804 |
+
if ( 'github' === $host || 'gitea' === $host ) {
|
805 |
+
$args['headers']['Authorization'] = 'token ' . $token;
|
806 |
+
}
|
807 |
+
if ( 'gitlab' === $host ) {
|
808 |
+
$args['headers']['Authorization'] = 'Bearer ' . $token;
|
809 |
+
}
|
810 |
+
}
|
811 |
+
|
812 |
+
// dot org should not have auth header.
|
813 |
+
// phpcs:ignore WordPress.WP.CapitalPDangit.Misspelled
|
814 |
+
if ( 'wordpress' === $host ) {
|
815 |
+
unset( $args['headers']['Authorization'] );
|
816 |
+
}
|
817 |
+
remove_filter( 'http_request_args', [ $this, 'add_basic_auth_headers' ] );
|
818 |
+
|
819 |
+
return $args;
|
820 |
}
|
821 |
}
|
822 |
|
826 |
* Class WPDI_Plugin_Installer_Skin
|
827 |
*/
|
828 |
class WPDI_Plugin_Installer_Skin extends Plugin_Installer_Skin {
|
829 |
+
public function header() {
|
830 |
+
}
|
831 |
+
|
832 |
+
public function footer() {
|
833 |
+
}
|
834 |
+
|
835 |
+
public function error( $errors ) {
|
836 |
+
}
|
837 |
|
838 |
+
public function feedback( $string, ...$args ) {
|
839 |
+
}
|
840 |
+
}
|
841 |
}
|