PluginProbe
VikBooking Hotel Booking Engine & PMS / trunk
VikBooking Hotel Booking Engine & PMS vtrunk
1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 All 35 releases
vikbooking / admin / models / license.php

license.php in VikBooking Hotel Booking Engine & PMS trunk, at admin/models/license.php

353 lines 9.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikBooking
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2019 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 to this file
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 JLoader::import('adapter.mvc.models.form');
15
16 /**
17 * VikBooking plugin License model.
18 * @wponly
19 *
20 * @since 1.3.12
21 * @see JModelForm
22 */
23 class VikBookingModelLicense extends JModelForm
24 {
25 /**
26 * The base end-point URI.
27 *
28 * @var string
29 */
30 protected $baseUri = 'https://vikwp.com/api/';
31
32 /**
33 * Implements the request needed to validate
34 * the PRO license of the plugin.
35 *
36 * @param string $key The license key.
37 *
38 * @return mixed The response if valid, false otherwise.
39 */
40 public function validate($key)
41 {
42 // validate specified key
43 if (!preg_match("/^[a-zA-Z0-9]{16,16}$/", $key))
44 {
45 // invalid key, register error
46 $this->setError(new Exception(JText::translate('VBOEMPTYLICKEY'), 400));
47
48 return false;
49 }
50
51 // update license hash
52 VikBookingLoader::import('update.license');
53 $hash = VikBookingLicense::getHash();
54
55 // validation end-point
56 $url = $this->baseUri . '?task=licenses.validate';
57
58 // init HTTP transport
59 $http = new JHttp();
60
61 // build post data
62 $data = array(
63 'key' => $key,
64 'application' => 'vbo',
65 'version' => VIKBOOKING_SOFTWARE_VERSION,
66 'domain' => JUri::root(),
67 'ip' => $_SERVER['REMOTE_ADDR'],
68 'hash' => $hash,
69 );
70
71 // build request headers
72 $headers = array(
73 // disable the SSL peer verification
74 'sslverify' => false,
75 );
76
77 /**
78 * Apply filters to manipulate the post data and the headers at runtime.
79 * Useful to support beta/development packages.
80 *
81 * @param array $data The post data array.
82 * @param array &$headers An associative array of HTTP directives.
83 * @param string $action The name of the action to manipulate.
84 *
85 * @since 1.5.0
86 */
87 $data = apply_filters_ref_array('vikbooking_license_before_post', array($data, &$headers, 'validate'));
88
89 // make connection with VikWP server
90 $response = $http->post($url, $data, $headers);
91
92 if ($response->code != 200)
93 {
94 // register error returned by VikWP
95 $this->setError(new Exception($response->body, $response->code));
96
97 return false;
98 }
99
100 // try decoding JSON
101 $body = json_decode($response->body);
102
103 if (!$body || $body->status != 1)
104 {
105 // invalid response received, register error
106 $this->setError(new Exception(sprintf('Invalid response: %s', $response->body), 500));
107
108 return false;
109 }
110
111 // import necessary libraries
112 VikBookingLoader::import('update.changelog');
113 VikBookingLoader::import('update.license');
114
115 // register values
116 VikBookingChangelog::store((isset($body->changelog) ? $body->changelog : ''));
117 VikBookingLicense::setKey($body->key);
118 VikBookingLicense::setExpirationDate(strtotime($body->expdate));
119
120 // return response object
121 return $body;
122 }
123
124 /**
125 * Implements the request needed to download
126 * the PRO version of the plugin.
127 *
128 * @param string $key The license key.
129 *
130 * @return boolean True on success, false otherwise.
131 */
132 public function download($key)
133 {
134 // validate specified key
135 if (!preg_match("/^[a-zA-Z0-9]{16,16}$/", $key))
136 {
137 // invalid key, register error
138 $this->setError(new Exception(JText::translate('VBOEMPTYLICKEY'), 400));
139
140 return false;
141 }
142
143 // update license hash
144 VikBookingLoader::import('update.license');
145 $hash = VikBookingLicense::getHash();
146
147 JLoader::import('adapter.filesystem.folder');
148
149 // get temporary dir
150 $tmp = get_temp_dir();
151
152 // clean temporary path
153 $tmp = rtrim(JPath::clean($tmp), DIRECTORY_SEPARATOR);
154
155 // make sure the folder exists
156 if (!is_dir($tmp))
157 {
158 // missing temporary folder, register error
159 $this->setError(new Exception(sprintf('Temporary folder [%s] does not exist', $tmp), 404));
160
161 return false;
162 }
163
164 /**
165 * Make sure the temporary folder is not in conflict with the backup (uploads) folder.
166 * This could be changed from the file wp-config.php with the constant WP_TEMP_DIR.
167 *
168 * @since 1.5.9
169 */
170 $upload_dir = wp_upload_dir();
171 if (is_array($upload_dir) && !empty($upload_dir['basedir']))
172 {
173 $tmp_upload = rtrim(JPath::clean($upload_dir['basedir']), DIRECTORY_SEPARATOR);
174 if ($tmp_upload == $tmp)
175 {
176 /**
177 * This would erase all backup folders of the plugin, the temporary dir must have been overridden.
178 * Attempt to create a sub-directory to be used as a unique and safe temporary directory.
179 */
180 if (JFolder::exists($tmp . '/tmp') || JFolder::create($tmp . '/tmp'))
181 {
182 $tmp = $tmp . DIRECTORY_SEPARATOR . 'tmp';
183 }
184 else
185 {
186 // could not create the temporary and safe directory
187 $this->setError(new Exception(sprintf('Temporary folder [%s] has been rewritten to be the same value as the upload directory. This is not allowed.', $tmp), 500));
188 return false;
189 }
190 }
191 }
192
193 // make sure the temporary folder is writable
194 if (!wp_is_writable($tmp))
195 {
196 // tmp folder not writable, register error
197 $this->setError(new Exception(sprintf('Temporary folder [%s] is not writable', $tmp), 403));
198
199 return false;
200 }
201
202 // download end-point
203 $url = $this->baseUri . '?task=licenses.download';
204
205 // init HTTP transport
206 $http = new JHttp();
207
208 // build request headers
209 $headers = array(
210 // turn on stream to push body within a file
211 'stream' => true,
212 // define the filepath in which the data will be pushed
213 'filename' => $tmp . DIRECTORY_SEPARATOR . 'vikbookingpro.zip',
214 // make sure the request is non blocking
215 'blocking' => true,
216 // force timeout to 120 seconds
217 'timeout' => 120,
218 // disable the SSL peer verification
219 'sslverify' => false,
220 );
221
222 // build post data
223 $data = array(
224 'key' => $key,
225 'application' => 'vbo',
226 'version' => VIKBOOKING_SOFTWARE_VERSION,
227 'domain' => JUri::root(),
228 'ip' => $_SERVER['REMOTE_ADDR'],
229 'hash' => $hash,
230 );
231
232 /**
233 * Apply filters to manipulate the post data and the headers at runtime.
234 * Useful to support beta/development packages.
235 *
236 * @param array $data The post data array.
237 * @param array &$headers An associative array of HTTP directives.
238 * @param string $action The name of the action to manipulate.
239 *
240 * @since 1.5.0
241 */
242 $data = apply_filters_ref_array('vikbooking_license_before_post', array($data, &$headers, 'download'));
243
244 // make connection to the VikWP servers
245 $response = $http->post($url, $data, $headers);
246
247 if ($response->code != 200)
248 {
249 // register error returned by VikWP
250 $this->setError(new Exception($response->body, $response->code));
251
252 return false;
253 }
254
255 // make sure the file has been saved
256 if (!JFile::exists($headers['filename']))
257 {
258 // something went wrong while saving the archive, register error
259 $this->setError(new Exception('ZIP package could not be saved on disk', 404));
260
261 return false;
262 }
263
264 // create destination folder for extracted elements
265 $dest = $tmp . DIRECTORY_SEPARATOR . 'vikbooking';
266
267 // make sure the destination folder doesn't exist
268 if (JFolder::exists($dest))
269 {
270 // remove it before proceeding with the extraction
271 JFolder::delete($dest);
272 }
273
274 // import archive class handler
275 JLoader::import('adapter.filesystem.archive');
276
277 // the package was downloaded successfully, let's extract it (onto TMP folder)
278 $extracted = JArchive::extract($headers['filename'], $tmp);
279
280 // we no longer need the archive
281 JFile::delete($headers['filename']);
282
283 if (!$extracted)
284 {
285 // an error occurred while extracting the files, register it
286 $this->setError(new Exception(sprintf('Cannot extract files to [%s]', $tmp), 500));
287
288 return false;
289 }
290
291 // make sure the folder is intact
292 if (!JFolder::exists($dest))
293 {
294 // impossible to access the extracted elements, register error
295 $this->setError(new Exception(sprintf('Cannot access extracted elements from [%s] folder', $dest), 404));
296
297 return false;
298 }
299
300 // copy the root files
301 $root_files = JFolder::files($dest, '.', false, true);
302
303 foreach ($root_files as $file)
304 {
305 if (!JFile::copy($file, VIKBOOKING_BASE . DIRECTORY_SEPARATOR . basename($file)))
306 {
307 // delete folder before exiting
308 JFolder::delete($dest);
309
310 // we cannot afford to not be able to copy a root file, register error
311 $this->setError(new Exception(sprintf('Cannot copy root [%s] file', basename($file)), 500));
312
313 return false;
314 }
315 }
316
317 // copy the root folders
318 $root_folders = JFolder::folders($dest, '.', false, true);
319
320 foreach ($root_folders as $folder)
321 {
322 if (!JFolder::copy($folder, VIKBOOKING_BASE . DIRECTORY_SEPARATOR . basename($folder), '', true))
323 {
324 // delete folder before exiting
325 JFolder::delete($dest);
326
327 // we cannot afford to not be able to copy a root folder, register error
328 $this->setError(new Exception(sprintf('Cannot copy root [%s] folder', basename($folder)), 500));
329
330 return false;
331 }
332 }
333
334 // process complete, clean up the temporary folder before exiting
335 JFolder::delete($dest);
336
337 /**
338 * Trigger an action when the Pro version has been downloaded.
339 *
340 * @param string $key the license key validated.
341 *
342 * @since 1.6.6
343 */
344 do_action('vikbooking_license_after_complete', $key);
345
346 // restore template files that could have been overwritten by the Pro package
347 VikBookingLoader::import('update.manager');
348 VikBookingUpdateManager::restoreTemplateFiles();
349
350 return true;
351 }
352 }
353