PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / trunk
VikAppointments Services Booking Calendar vtrunk
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / libraries / adapter / plugin / installer / installer.php
vikappointments / libraries / adapter / plugin / installer Last commit date
adapter.php 2 years ago installer.php 2 years ago interface.php 2 years ago
installer.php
169 lines
1 <?php
2 /**
3 * @package VikUpdater
4 * @subpackage plugin
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2023 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 require_once ABSPATH . 'wp-includes/pluggable.php';
15 require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
16 require_once ABSPATH . 'wp-admin/includes/file.php';
17 require_once ABSPATH . 'wp-admin/includes/misc.php';
18 require_once ABSPATH . 'wp-admin/includes/plugin.php';
19 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
20
21 JLoader::import('adapter.plugin.installer.interface');
22
23 /**
24 * Generic class used to install remote plugins without
25 * the confirmation of the user.
26 *
27 * @since 10.1.57
28 */
29 abstract class JPluginInstaller implements JPluginInstallerInterface
30 {
31 /**
32 * @inheritDoc
33 */
34 final public function isInstalled()
35 {
36 // get the plugin slug
37 $slug = $this->getSlug();
38
39 // construct plugin url
40 $pluginPath = JPath::clean(WP_PLUGIN_DIR . '/' . $slug . '.php');
41
42 // validate the presence of the file
43 return JFile::exists($pluginPath);
44 }
45
46 /**
47 * @inheritDoc
48 */
49 final public function isActive()
50 {
51 return is_plugin_active($this->getSlug() . '.php');
52 }
53
54 /**
55 * @inheritDoc
56 */
57 final public function install()
58 {
59 /**
60 * Create a custom skin to support a sort of silent installation.
61 *
62 * @see WP_Upgrader_Skin
63 */
64 $skin = new class extends WP_Upgrader_Skin
65 {
66 /** @var string[] */
67 private $trace = [];
68
69 /**
70 * @inheritDoc
71 */
72 public function header()
73 {
74 // suppress unexpected output
75 }
76
77 /**
78 * @inheritDoc
79 */
80 public function footer()
81 {
82 // suppress unexpected output
83 }
84
85 /**
86 * @inheritDoc
87 */
88 public function feedback($feedback, ...$args)
89 {
90 // suppress any errors
91 $this->trace[] = $feedback;
92 }
93
94 /**
95 * Returns the feedback trace.
96 *
97 * @return string[]
98 */
99 public function getTrace(): array
100 {
101 return $this->trace;
102 }
103 };
104
105 // create installer handler
106 $upgrader = new Plugin_Upgrader($skin);
107
108 // check whether the plugin is already installed
109 if ($this->isInstalled())
110 {
111 // plugin already installed, delete the folder first
112 JFolder::delete(dirname(WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $this->getSlug() . '.php'));
113 }
114
115 // download the plugin from the provided link and install it
116 $result = $upgrader->install($this->getUrl());
117
118 if ($result !== true)
119 {
120 if ($result instanceof WP_Error)
121 {
122 // propagate the error registered by the WP installer
123 $code = $result->get_error_code();
124 throw new RuntimeException($result->get_error_message(), is_numeric($code) ? (int) $code : 500);
125 }
126 else
127 {
128 // extract the error from our skin
129 $trace = $skin->getTrace();
130 throw new RuntimeException(end($trace) ?: 'Installation error.', 500);
131 }
132 }
133
134 // make sure the plugin actually exists
135 if (!$this->isInstalled())
136 {
137 // the plugin hasn't been properly downloaded
138 throw new RuntimeException('Plugin [' . $this->getSlug() . '] not found', 404);
139 }
140
141 if (!$this->isActive())
142 {
143 // try to activate the plugin
144 $result = activate_plugin($this->getSlug() . '.php');
145
146 if ($result instanceof WP_Error)
147 {
148 // propagate the error registered during the activation
149 $code = $result->get_error_code();
150 throw new RuntimeException($result->get_error_message(), is_numeric($code) ? (int) $code : 500);
151 }
152 }
153 }
154
155 /**
156 * Returns the plugin slug for the activation.
157 *
158 * @return string
159 */
160 abstract protected function getSlug();
161
162 /**
163 * Returns the remote URL that will be used to download the plugin.
164 *
165 * @return string
166 */
167 abstract protected function getUrl();
168 }
169