PluginProbe
Boxzilla – WordPress Popup Builder / 3.4.7
Boxzilla – WordPress Popup Builder v3.4.7
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.7, at src/licensing/class-update-manager.php

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