PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.8.16
VikBooking Hotel Booking Engine & PMS v1.8.16
1.8.16 1.8.15 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 All 37 releases
← All changes | admin/models/license.php +352 -0 1.6.3 → 1.8.16 View file →
@@ -1,0 +1,352 @@
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 +}