PluginProbe
Boxzilla – WordPress Popup Builder / 3.4.9
Boxzilla – WordPress Popup Builder v3.4.9
3.4.11 3.4.10 3.4.9 3.4.3 3.4.4 3.4.5 3.4.6 3.4.7 3.4.8 trunk 3.0 3.0.1 3.0.2 3.0.3 3.1 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.17 3.1.18 All 72 releases
boxzilla / src / licensing / class-update-manager.php

class-update-manager.php in Boxzilla – WordPress Popup Builder 3.4.9, at src/licensing/class-update-manager.php

263 lines 7.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Boxzilla\Licensing;
4
5 use Boxzilla\Plugin;
6
7 if (! defined('ABSPATH')) {
8 exit;
9 }
10
11 class UpdateManager
12 {
13 /**
14 * @var array
15 */
16 protected $extensions = [];
17
18 /**
19 * @var API
20 */
21 protected $api;
22
23 /**
24 * @var License
25 */
26 protected $license;
27
28 /**
29 * @var array
30 */
31 protected $available_updates;
32
33 /**
34 * @param array $extensions
35 * @param API $api
36 * @param License $license
37 */
38 public function __construct(array $extensions, API $api, License $license)
39 {
40 $this->extensions = $extensions;
41 $this->license = $license;
42 $this->api = $api;
43 }
44
45 /**
46 * Add hooks
47 */
48 public function init()
49 {
50 add_filter('pre_set_site_transient_update_plugins', [ $this, 'add_updates' ]);
51 add_filter('plugins_api', [ $this, 'get_plugin_info' ], 20, 3);
52 add_filter('http_request_args', [ $this, 'add_auth_headers' ], 10, 2);
53 }
54
55 /**
56 * This adds the license key header to download package requests.
57 *
58 * @param array $args
59 * @param string $url
60 *
61 * @return mixed
62 */
63 public function add_auth_headers($args, $url)
64 {
65 // only act on download request's to the Boxzilla update API
66 if (strpos($url, $this->api->url) !== 0 || strpos($url, '/download') === false) {
67 return $args;
68 }
69
70 // only add if activation key not empty
71 if (empty($this->license->activation_key)) {
72 return $args;
73 }
74
75 if (! isset($args['headers'])) {
76 $args['headers'] = [];
77 }
78
79 $args['headers']['Authorization'] = "Bearer {$this->license->activation_key}";
80 return $args;
81 }
82
83 /**
84 * @param $result
85 * @param string $action
86 * @param object $args
87 *
88 * @return object|null
89 */
90 public function get_plugin_info($result, $action, $args)
91 {
92 // do nothing for unrelated requests
93 if ($action !== 'plugin_information' || ! isset($args->slug)) {
94 return $result;
95 }
96
97 // only act on our plugins
98 if (strpos($args->slug, 'boxzilla-') !== 0) {
99 return $result;
100 }
101
102 return $this->get_update_info($args->slug);
103 }
104
105 /**
106 * @param null|object $updates
107 * @return object
108 */
109 public function add_updates($updates)
110 {
111
112 // do nothing if no plugins registered
113 if (empty($this->extensions)) {
114 return $updates;
115 }
116
117 // failsafe WP bug
118 if (empty($updates) || ! isset($updates->response) || ! is_array($updates->response)) {
119 return $updates;
120 }
121
122 // fetch available updates
123 $available_updates = $this->fetch_updates();
124
125 // merge with other updates
126 $updates->response = array_merge($updates->response, $available_updates);
127
128 return $updates;
129 }
130
131 /**
132 * Fetch array of available updates from remote server
133 *
134 * @return array
135 */
136 protected function fetch_updates()
137 {
138 if (is_array($this->available_updates)) {
139 return $this->available_updates;
140 }
141
142 // don't try if we failed a request recently.
143 $failed_at = get_transient('boxzilla_request_failed');
144 if (! empty($failed_at) && ( ( time() - 300 ) < $failed_at )) {
145 return [];
146 }
147
148 // fetch remote info
149 try {
150 $remote_plugins = $this->api->get_plugins();
151 } catch (API_Exception $e) {
152 // set flag for 5 minutes
153 set_transient('boxzilla_request_failed', time(), 300);
154 return [];
155 }
156
157 // filter remote plugins, we only want the ones with an update available
158 $this->available_updates = $this->filter_remote_plugins($remote_plugins);
159
160 return $this->available_updates;
161 }
162
163 /**
164 * @param $remote_plugins
165 * @return array
166 */
167 protected function filter_remote_plugins($remote_plugins)
168 {
169 $available_updates = [];
170
171 // find new versions
172 foreach ($remote_plugins as $remote_plugin) {
173 // sanity check
174 if (! isset($remote_plugin->new_version)) {
175 continue;
176 }
177
178 // if plugin is activated, we can access it here
179 if (isset($this->extensions[ $remote_plugin->sid ])) {
180
181 /** @var Plugin $local_plugin */
182 $local_plugin = $this->extensions[ $remote_plugin->sid ];
183
184 // plugin found and local plugin version not same as remote version?
185 if (! $local_plugin || version_compare($local_plugin->version(), $remote_plugin->new_version, '>=')) {
186 continue;
187 }
188
189 // add some dynamic data
190 $available_updates[ $local_plugin->slug() ] = $this->format_response($local_plugin->slug(), $remote_plugin);
191 } else {
192 // if plugin is not active, use get_plugin_data for fetching version
193 $plugin_file = WP_PLUGIN_DIR . "/{$remote_plugin->slug}/{$remote_plugin->slug}.php";
194 if (! file_exists($plugin_file)) {
195 continue;
196 }
197
198 $plugin_data = get_plugin_data($plugin_file);
199
200 if (! $plugin_data || version_compare($plugin_data['Version'], $remote_plugin->new_version, '>=')) {
201 continue;
202 }
203
204 // add some dynamic data
205 $slug = plugin_basename($plugin_file);
206 $available_updates[ $slug ] = $this->format_response($slug, $remote_plugin);
207 }
208 }
209
210 return $available_updates;
211 }
212
213 /**
214 * @param string $slug
215 *
216 * @return object|null
217 */
218 public function get_update_info($slug)
219 {
220 $available_updates = $this->fetch_updates();
221
222 foreach ($available_updates as $plugin_file => $update_info) {
223 if ($slug === $update_info->slug) {
224 return $update_info;
225 }
226 }
227
228 return null;
229 }
230
231 /**
232 * @param $slug
233 * @param $response
234 *
235 * @return mixed
236 */
237 protected function format_response($slug, $response)
238 {
239 $response->slug = dirname($slug);
240 $response->plugin = $slug;
241
242 // add some notices if license is inactive
243 if (! $this->license->activated) {
244 $response->upgrade_notice = sprintf('You will need to <a href="%s">activate your license</a> to install this plugin update.', admin_url('edit.php?post_type=boxzilla-box&page=boxzilla-settings'));
245 $response->sections->changelog = '<p>' . sprintf('You will need to <a href="%s" target="_top">activate your license</a> to install this plugin update.', admin_url('edit.php?post_type=boxzilla-box&page=boxzilla-settings')) . '</p>' . $response->sections->changelog;
246 $response->package = null;
247 }
248
249 // cast subkey objects to array as that is what WP expects
250 $response->sections = get_object_vars($response->sections);
251 $response->banners = get_object_vars($response->banners);
252 $response->contributors = get_object_vars($response->contributors);
253 $response->contributors = array_map(
254 function ($v) {
255 return get_object_vars($v);
256 },
257 $response->contributors
258 );
259
260 return $response;
261 }
262 }
263