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 | libraries/update/manager.php +865 -0 1.6.3 → 1.8.16 View file →
@@ -1,0 +1,865 @@
1 +<?php
2 +/**
3 + * @package VikBooking - Libraries
4 + * @subpackage update
5 + * @author E4J s.r.l.
6 + * @copyright Copyright (C) 2018 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 +JLoader::import('adapter.database.helper');
15 +VikBookingLoader::import('update.changelog');
16 +VikBookingLoader::import('update.license');
17 +
18 +/**
19 + * Class used to handle the upgrade of the plugin.
20 + *
21 + * @since 1.0
22 + */
23 +class VikBookingUpdateManager
24 +{
25 +
26 + /**
27 + * For bc with PHP < 5.6, the private static var is now
28 + * returned by this private method, because class properties
29 + * do not support concatenation, and so we can't build the array.
30 + *
31 + * @return array the list of template files used as Options to temporary store modifications.
32 + *
33 + * @since 1.0.9
34 + */
35 + private static function getTemplateFiles()
36 + {
37 + return array(
38 + VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'email_tmpl.php',
39 + VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'error_form.php',
40 + VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'invoices' . DIRECTORY_SEPARATOR . 'invoice_tmpl.php',
41 + VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'invoices' . DIRECTORY_SEPARATOR . 'custom_invoice_tmpl.php',
42 + VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'checkins' . DIRECTORY_SEPARATOR . 'checkin_tmpl.php',
43 + VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'vikbooking_custom.css',
44 + VBO_ADMIN_PATH . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'vikbooking_backendcustom.css'
45 + );
46 + }
47 +
48 + /**
49 + * Checks if the current version should be updated.
50 + *
51 + * @param string $version The version to check.
52 + *
53 + * @return boolean True if should be updated, otherwise false.
54 + */
55 + public static function shouldUpdate($version)
56 + {
57 + if (is_null($version))
58 + {
59 + return false;
60 + }
61 +
62 + return version_compare($version, VIKBOOKING_SOFTWARE_VERSION, '<');
63 + }
64 +
65 + /**
66 + * Executes the SQL file for the installation of the plugin.
67 + *
68 + * @return void
69 + *
70 + * @uses execSqlFile()
71 + * @uses installAcl()
72 + * @uses installProSettings()
73 + * @uses installUploadBackup()
74 + */
75 + public static function install()
76 + {
77 + self::execSqlFile(VIKBOOKING_BASE . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR . 'install.mysql.utf8.sql');
78 +
79 + $dbo = JFactory::getDbo();
80 +
81 + // create the configuration record with the email address of the current user
82 + $q = "INSERT INTO `#__vikbooking_config` (`param`,`setting`) VALUES ('adminemail', " . $dbo->q(JFactory::getUser()->email) . ");";
83 + $dbo->setQuery($q);
84 + $dbo->execute();
85 +
86 + // footer must be disabled by default
87 + $q = "UPDATE `#__vikbooking_config` SET `setting`='0' WHERE `param`='showfooter';";
88 + $dbo->setQuery($q);
89 + $dbo->execute();
90 +
91 + // closing main text must not mention the name of the software
92 + $q = "UPDATE `#__vikbooking_texts` SET `setting`='' WHERE `param`='closingmain';";
93 + $dbo->setQuery($q);
94 + $dbo->execute();
95 +
96 + // truncate the payment gateways table
97 + $dbo->setQuery("TRUNCATE TABLE `#__vikbooking_gpayments`");
98 + $dbo->execute();
99 +
100 + self::installAcl();
101 + self::installProSettings();
102 + self::installUploadBackup();
103 + }
104 +
105 + /**
106 + * Executes the SQL file for the uninstallation of the plugin.
107 + *
108 + * @param boolean $drop True to drop the tables of VikBooking from the database.
109 + *
110 + * @return void
111 + *
112 + * @uses execSqlFile()
113 + * @uses uninstallAcl()
114 + * @uses uninstallProSettings()
115 + * @uses uninstallTemplateContents()
116 + * @uses uninstallUploadBackup()
117 + */
118 + public static function uninstall($drop = true)
119 + {
120 + if ($drop)
121 + {
122 + self::execSqlFile(VIKBOOKING_BASE . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR . 'uninstall.mysql.utf8.sql');
123 + }
124 +
125 + self::uninstallAcl();
126 + self::uninstallProSettings();
127 + self::uninstallTemplateContents();
128 + self::uninstallUploadBackup();
129 + }
130 +
131 + /**
132 + * Launches the process to finalise the update.
133 + *
134 + * @param string $version The current version.
135 + *
136 + * @uses getFixer()
137 + * @uses installSql()
138 + * @uses installAcl()
139 + * @uses restoreTemplateFiles()
140 + * @uses restoreUploadBackup()
141 + */
142 + public static function update($version)
143 + {
144 + $fixer = self::getFixer($version);
145 +
146 + // trigger before installation routine
147 +
148 + $res = $fixer->beforeInstallation();
149 +
150 + if ($res === false)
151 + {
152 + return false;
153 + }
154 +
155 + // install SQL statements
156 +
157 + $res = self::installSql($version);
158 +
159 + if ($res === false)
160 + {
161 + return false;
162 + }
163 +
164 + // install ACL
165 +
166 + $res = self::installAcl();
167 +
168 + if ($res === false)
169 + {
170 + return false;
171 + }
172 +
173 + // move template files
174 + self::restoreTemplateFiles();
175 +
176 + // restore files uploaded
177 + self::restoreUploadBackup();
178 +
179 + // trigger after installation routine
180 +
181 + $res = $fixer->afterInstallation();
182 +
183 + return ($res === false ? false : true);
184 + }
185 +
186 + /**
187 + * Reads from the Options if the content of a template file
188 + * was previously modified. In this case, it restores the
189 + * modifications onto the template file which is always
190 + * overwritten during updates and upgrades.
191 + *
192 + * @return void
193 + *
194 + * @since 1.0.3
195 + */
196 + public static function restoreTemplateFiles()
197 + {
198 + jimport('joomla.filesystem.file');
199 +
200 + foreach (self::getTemplateFiles() as $file)
201 + {
202 + // the file base name as used in the Options
203 + $base_file = basename($file);
204 + $base_file = substr($base_file, 0, strrpos($base_file, '.'));
205 +
206 + // get override value from Options
207 + $tmp_val = get_option('vikbooking_tmp_'.$base_file, null);
208 + if (!is_null($tmp_val))
209 + {
210 + JFile::write($file, $tmp_val);
211 + }
212 + }
213 + }
214 +
215 + /**
216 + * Updates an Option with the content of the modified
217 + * template file for later use after updates/upgrades.
218 + *
219 + * @param string $path the template file full path or just its name
220 + * @param string $content the raw content to put in the Option
221 + *
222 + * @return boolean
223 + *
224 + * @since 1.0.3
225 + */
226 + public static function storeTemplateContent($path, $content)
227 + {
228 + $base_path = basename($path);
229 +
230 + foreach (self::getTemplateFiles() as $file)
231 + {
232 + // template file names are unique no matter of the directory
233 + $base_file = basename($file);
234 + if ($base_path == $base_file) {
235 + // template file found
236 + $base_file = substr($base_file, 0, strrpos($base_file, '.'));
237 + // update the Option and return
238 + update_option('vikbooking_tmp_'.$base_file, $content);
239 +
240 + return true;
241 + }
242 + }
243 +
244 + return false;
245 + }
246 +
247 + /**
248 + * Removes some Options that were used to hold
249 + * modifications made to the template files.
250 + *
251 + * @return void
252 + */
253 + public static function uninstallTemplateContents()
254 + {
255 + foreach (self::getTemplateFiles() as $file)
256 + {
257 + // the file base name as used in the Options
258 + $base_file = basename($file);
259 + $base_file = substr($base_file, 0, strrpos($base_file, '.'));
260 +
261 + // remove entry from Options
262 + delete_option('vikbooking_tmp_'.$base_file);
263 + }
264 + }
265 +
266 + /**
267 + * Returns a pair of key-values for each directory used
268 + * for handling the backup of the uploaded files.
269 + * All paths are missing the trailing directory separator.
270 + * Gets the backup upload dir paths by default, or the
271 + * real plugin dir paths if $real_path is true.
272 + * Used during the installation, uninstallation and backup (post-update).
273 + *
274 + * @param boolean [$real_paths] If True, the real paths used by the plugin will be returned.
275 + * The path of the backup folders will be returned otherwise.
276 + *
277 + * @return array An array of strings with the path of each dir
278 + */
279 + protected static function getUploadBackupDirs($real_paths = false)
280 + {
281 + if ($real_paths) {
282 + // return the real upload dir paths used by the plugin
283 + return array(
284 + // main upload path for the images of the rooms, options, characteristics and such...
285 + 'front' => VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'uploads',
286 + // upload dir path for the customers check-in documents
287 + 'checkins' => VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'checkins' . DIRECTORY_SEPARATOR . 'generated',
288 + // upload dir path for the invoices in PDF format
289 + 'invoices' => VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'invoices' . DIRECTORY_SEPARATOR . 'generated',
290 + // upload dir path for the scans of the ID/Documents of the customers
291 + 'idscans' => VBO_ADMIN_PATH . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'idscans',
292 + // dir path for the PMS reports data
293 + 'pmsdata' => VBO_ADMIN_PATH . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'pmsdata',
294 + // dir path to extend the reports
295 + 'report' => VBO_ADMIN_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'report',
296 + // dir path to extend the SMS APIs
297 + 'smsapi' => VBO_ADMIN_PATH . DIRECTORY_SEPARATOR . 'smsapi',
298 + // dir path to custom language files
299 + 'languages' => VIKBOOKING_BASE . DIRECTORY_SEPARATOR . 'languages',
300 + // upload dir path for the admin section, for custom logos and such... (we keep the smaller admin path at the end of the array)
301 + 'admin' => VBO_ADMIN_PATH . DIRECTORY_SEPARATOR . 'resources',
302 + );
303 + }
304 +
305 + // get the array information of the upload dir
306 + $upload_dir = wp_upload_dir();
307 + if (!is_array($upload_dir) || empty($upload_dir['basedir'])) {
308 + return false;
309 + }
310 +
311 + // keep the keys of this array, as they are used as a map with other methods
312 + return array(
313 + // base directory that will contain the sub-directories divided by category
314 + 'base' => $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'vikbooking',
315 + // main upload path for the images of the rooms, options, characteristics and such...
316 + 'front' => $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'vikbooking' . DIRECTORY_SEPARATOR . 'front',
317 + // upload dir path for the the customers check-in documents
318 + 'checkins' => $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'vikbooking' . DIRECTORY_SEPARATOR . 'checkins',
319 + // upload dir path for the invoices in PDF format
320 + 'invoices' => $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'vikbooking' . DIRECTORY_SEPARATOR . 'invoices',
321 + // upload dir path for the scans of the ID/Documents of the customers
322 + 'idscans' => $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'vikbooking' . DIRECTORY_SEPARATOR . 'idscans',
323 + // dir path for the PMS reports data
324 + 'pmsdata' => $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'vikbooking' . DIRECTORY_SEPARATOR . 'pmsdata',
325 + // dir path to extend the reports
326 + 'report' => $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'vikbooking' . DIRECTORY_SEPARATOR . 'report',
327 + // dir path to extend the SMS APIs
328 + 'smsapi' => $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'vikbooking' . DIRECTORY_SEPARATOR . 'smsapi',
329 + // dir path to custom language files
330 + 'languages' => $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'vikbooking' . DIRECTORY_SEPARATOR . 'languages',
331 + // upload dir path for the admin section, for custom logos and such...
332 + 'admin' => $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'vikbooking' . DIRECTORY_SEPARATOR . 'admin',
333 + // views overrides dir path: this dir should NOT be backed up, so this key should ONLY be in this array
334 + 'overrides' => $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'vikbooking' . DIRECTORY_SEPARATOR . 'overrides',
335 + // media dir path: this dir should NOT be backed up, so this key should ONLY be in this array
336 + 'media' => VBO_MEDIA_PATH,
337 + // customer docs dir path: this dir should NOT be backed up, so this key should ONLY be in this array
338 + 'customerdocs' => VBO_CUSTOMERS_PATH,
339 + );
340 + }
341 +
342 + /**
343 + * Returns a list of keys for the upload back up directories
344 + * only containing the keys for those dirs where the extendable
345 + * PHP Classes are located by default in the plugin.
346 + * Used during the installation, uninstallation and backup (post-update).
347 + *
348 + * @return array An array of strings with the keys of the paths of each dir supported
349 + */
350 + protected static function getExtendableDirsKeys()
351 + {
352 + // return the real upload dir paths used by the plugin
353 + return array(
354 + // dir path to extend the reports
355 + 'report',
356 + // dir path to extend the SMS APIs
357 + 'smsapi',
358 + );
359 + }
360 +
361 + /**
362 + * Creates a directory called 'vikbooking' onto the defined upload
363 + * directory for the website, for later use during the upload of files.
364 + * All dirs are created by reading the instructions from getUploadBackupDirs().
365 + * By default in /wp-content/uploads/vikbooking
366 + *
367 + * @return boolean True on success.
368 + *
369 + * @uses getUploadBackupDirs()
370 + *
371 + * @since 1.0.4
372 + * @since 1.5.0 the visibility of this method has been changed to public for the Fixer class.
373 + */
374 + public static function installUploadBackup()
375 + {
376 + // import the Folder and File classes
377 + JLoader::import('adapter.filesystem.folder');
378 + JLoader::import('adapter.filesystem.file');
379 +
380 + // create all necessary folders (if they don't exist)
381 + $result = true;
382 + foreach (self::getUploadBackupDirs() as $type => $path) {
383 + $result = $result && JFolder::create($path);
384 + if ($result) {
385 + // create an empty HTML file to secure the directory from browsing
386 + JFile::write($path . DIRECTORY_SEPARATOR . 'index.html', '<html></html>');
387 + }
388 + }
389 +
390 + return $result;
391 + }
392 +
393 + /**
394 + * Removes the directory 'vikbooking' used for the file upload.
395 + * The dirs to be removed are read from the array in getUploadBackupDirs().
396 + * This should happen only upon uninstallation of the Plugin.
397 + *
398 + * @return boolean True on success.
399 + *
400 + * @uses getUploadBackupDirs()
401 + *
402 + * @since 1.0.4
403 + */
404 + protected static function uninstallUploadBackup()
405 + {
406 + // import the Folder class
407 + JLoader::import('adapter.filesystem.folder');
408 +
409 + // delete all folders no longer needed (if they exist)
410 + $result = true;
411 + foreach (self::getUploadBackupDirs() as $type => $path) {
412 + $result = JFolder::delete($path) && $result;
413 + }
414 +
415 + return $result;
416 + }
417 +
418 + /**
419 + * Restores all the uploaded files from the directory 'vikbooking'
420 + * and its sub-dirs, onto the original dirs of the Plugin.
421 + *
422 + * @return boolean True on success.
423 + *
424 + * @uses getUploadBackupDirs()
425 + *
426 + * @since 1.0.4
427 + */
428 + protected static function restoreUploadBackup()
429 + {
430 + // get the list of the backup directories
431 + $backup_dirs = self::getUploadBackupDirs();
432 +
433 + // get the list of the real upload directories
434 + $real_dirs = self::getUploadBackupDirs(true);
435 +
436 + // import the Folder and File classes
437 + JLoader::import('adapter.filesystem.folder');
438 + JLoader::import('adapter.filesystem.file');
439 +
440 + $result = true;
441 +
442 + foreach ($backup_dirs as $type => $path) {
443 + // scan all files in this backup dir
444 + $files = JFolder::files($path);
445 + if (!isset($real_dirs[$type]) || !is_array($files) || !count($files)) {
446 + continue;
447 + }
448 +
449 + // restore all backed-up files onto its real dir
450 + foreach ($files as $file) {
451 + $fname = basename($file);
452 + // skip placeholder HTML file
453 + if ($fname == 'index.html') {
454 + continue;
455 + }
456 + // restore original file
457 + $result = JFile::copy($path . DIRECTORY_SEPARATOR . $file, $real_dirs[$type] . DIRECTORY_SEPARATOR . $fname) && $result;
458 + }
459 + }
460 +
461 + return $result;
462 + }
463 +
464 + /**
465 + * Trigger called whenever a file has been uploaded.
466 + * Checks if the destination path is recognized, and
467 + * copies the uploaded/created file onto its backup folder.
468 + * This is to have a mirror-file to be restored upon update.
469 + *
470 + * @param string $dest the path to the just uploaded file.
471 + *
472 + * @return boolean True on success.
473 + *
474 + * @uses getUploadBackupDirs()
475 + * @uses installUploadBackup()
476 + *
477 + * @since 1.0.4
478 + */
479 + public static function triggerUploadBackup($dest)
480 + {
481 + // seek the key of the uploaded dir
482 + $dir_key = false;
483 + foreach (self::getUploadBackupDirs(true) as $key => $path) {
484 + if (strpos($dest, $path) !== false) {
485 + $dir_key = $key;
486 + break;
487 + }
488 + }
489 + if (!$dir_key) {
490 + // could not recognize upload dir path from destination file
491 + return false;
492 + }
493 +
494 + // always make sure the upload backup dirs are set for bc with those that installed a previous version of the plugin
495 + if (!self::installUploadBackup()) {
496 + // cannot proceed because backup folders are not set
497 + return false;
498 + }
499 +
500 + // import the File class
501 + JLoader::import('adapter.filesystem.file');
502 +
503 + // get the backup upload dir path for this type of file
504 + $backup_dirs = self::getUploadBackupDirs();
505 + if (!isset($backup_dirs[$dir_key])) {
506 + // the arrays returned by getUploadBackupDirs do not match (should NEVER happen)
507 + return false;
508 + }
509 +
510 + // copy the file onto its backup dir
511 + return JFile::copy($dest, $backup_dirs[$dir_key] . DIRECTORY_SEPARATOR . basename($dest));
512 + }
513 +
514 + /**
515 + * Trigger called whenever a mirroring file has been deleted.
516 + * Checks if the destination path is recognized, and attempts to
517 + * delete the previously backed up file in order to never restore it.
518 + *
519 + * @param string $dest The path to the file just deleted.
520 + *
521 + * @return boolean True on success.
522 + *
523 + * @since 1.8.12
524 + */
525 + public static function triggerDeletionBackup($dest)
526 + {
527 + // seek the key of the uploaded dir
528 + $dir_key = false;
529 + foreach (self::getUploadBackupDirs(true) as $key => $path) {
530 + if (strpos($dest, $path) !== false) {
531 + $dir_key = $key;
532 + break;
533 + }
534 + }
535 + if (!$dir_key) {
536 + // could not recognize upload dir path from destination file
537 + return false;
538 + }
539 +
540 + // always make sure the upload backup dirs are set for bc with those that installed a previous version of the plugin
541 + if (!self::installUploadBackup()) {
542 + // cannot proceed because backup folders are not set
543 + return false;
544 + }
545 +
546 + // import the File class
547 + JLoader::import('adapter.filesystem.file');
548 +
549 + // get the backup upload dir path for this type of file
550 + $backup_dirs = self::getUploadBackupDirs();
551 + if (!isset($backup_dirs[$dir_key])) {
552 + // do not proceed
553 + return false;
554 + }
555 +
556 + // build the full file path on the mirroring directory
557 + $mirroredFilePath = $backup_dirs[$dir_key] . DIRECTORY_SEPARATOR . basename($dest);
558 +
559 + if (!is_file($mirroredFilePath)) {
560 + // do not proceed
561 + return false;
562 + }
563 +
564 + // delete the file from its backup dir
565 + return JFile::delete($mirroredFilePath);
566 + }
567 +
568 + /**
569 + * This method should be called after importing a full backup
570 + * copy from another Vik Booking installation. It recursively
571 + * parses all the upload backup directories to mirror. This
572 + * way, installing a future update will be safe.
573 + *
574 + * @return boolean true on success, false otherwise.
575 + *
576 + * @since 1.5.0
577 + */
578 + public static function triggerUploadFullMirroring()
579 + {
580 + // make sure all needed directories are available
581 + if (!self::installUploadBackup()) {
582 + // cannot proceed because backup folders are not set
583 + return false;
584 + }
585 +
586 + // get all the backup upload directory paths
587 + $backup_dirs = self::getUploadBackupDirs();
588 +
589 + // copy result
590 + $result = false;
591 +
592 + // loop through all the real upload directories used by the plugin
593 + foreach (self::getUploadBackupDirs(true) as $key => $path) {
594 + if (!isset($backup_dirs[$key])) {
595 + continue;
596 + }
597 + // copy all files onto their backup directory
598 + foreach (JFolder::files($path) as $fname) {
599 + $result = JFile::copy($path . DIRECTORY_SEPARATOR . $fname, $backup_dirs[$key] . DIRECTORY_SEPARATOR . $fname) || $result;
600 + }
601 + }
602 +
603 + return $result;
604 + }
605 +
606 + /**
607 + * Trigger called to back up all the files inside the path with the key
608 + * passed. Useful to back up custom PHP files manually uploaded to extend
609 + * the default Reports, Cron Jobs, SMS APIs to save a clone copy of these
610 + * files onto a directory that will be later used for restoring the files.
611 + * This method should be called every time a back-end View with a list of
612 + * specific extendable classes is visited, to always update the back ups.
613 + *
614 + * @param string $key The key of the extendable class.
615 + * @param string $filter An optional regex to apply on the file name to skip.
616 + *
617 + * @return boolean True on success.
618 + *
619 + * @uses getUploadBackupDirs()
620 + * @uses installUploadBackup()
621 + *
622 + * @since 1.0.14
623 + */
624 + public static function triggerExtendableClassesBackup($key, $filter = '')
625 + {
626 + // get the list of the original directories
627 + $orig_dirs = self::getUploadBackupDirs(true);
628 +
629 + // get the list of the backup directories
630 + $backup_dirs = self::getUploadBackupDirs();
631 +
632 + // make sure the key exists in the dirs arrays
633 + if (empty($key) || !isset($orig_dirs[$key]) || !isset($backup_dirs[$key])) {
634 + return false;
635 + }
636 +
637 + // always make sure the backup dirs are set for bc with those that installed a previous version of the plugin
638 + if (!self::installUploadBackup()) {
639 + // cannot proceed because backup folders are not set
640 + return false;
641 + }
642 +
643 + // import the Folder and File classes
644 + JLoader::import('adapter.filesystem.folder');
645 + JLoader::import('adapter.filesystem.file');
646 +
647 + // scan all files in the original dir
648 + $files = JFolder::files($orig_dirs[$key]);
649 + if (!is_array($files) || !count($files)) {
650 + return false;
651 + }
652 +
653 + $result = true;
654 +
655 + // back-up all files of this dir onto its real dir
656 + foreach ($files as $file) {
657 + $fname = basename($file);
658 + // skip placeholder HTML file
659 + if ($fname == 'index.html') {
660 + continue;
661 + }
662 + if (!empty($filter) && !preg_match($filter, $file)) {
663 + // we skip this file as the filter matched its name
664 + continue;
665 + }
666 + // clone original file
667 + $result = JFile::copy($orig_dirs[$key] . DIRECTORY_SEPARATOR . $file, $backup_dirs[$key] . DIRECTORY_SEPARATOR . $fname) && $result;
668 + }
669 +
670 + return $result;
671 + }
672 +
673 + /**
674 + * Get the script class to run the installation methods.
675 + *
676 + * @param string $version The current version.
677 + *
678 + * @return VikBookingUpdateFixer
679 + */
680 + protected static function getFixer($version)
681 + {
682 + VikBookingLoader::import('update.fixer');
683 +
684 + return new VikBookingUpdateFixer($version);
685 + }
686 +
687 + /**
688 + * Provides the installation of the ACL routines.
689 + *
690 + * @return boolean True on success, otherwise false.
691 + */
692 + protected static function installAcl()
693 + {
694 + JLoader::import('adapter.acl.access');
695 + $actions = JAccess::getActions('vikbooking');
696 +
697 + // No actions found!
698 + // Probably, the main folder is not called "vikbooking".
699 + if (!$actions)
700 + {
701 + return false;
702 + }
703 +
704 + $roles = array(
705 + get_role('administrator'),
706 + );
707 +
708 + foreach ($roles as $role)
709 + {
710 + if ($role)
711 + {
712 + foreach ($actions as $action)
713 + {
714 + $cap = JAccess::adjustCapability($action->name, 'com_vikbooking');
715 + $role->add_cap($cap, true);
716 + }
717 + }
718 + }
719 +
720 + return true;
721 + }
722 +
723 + /**
724 + * Sets up the options for using the Pro version.
725 + *
726 + * @return void
727 + */
728 + protected static function installProSettings()
729 + {
730 + VikBookingChangelog::install();
731 + VikBookingLicense::install();
732 + }
733 +
734 + /**
735 + * Sets up the options for using the Pro version.
736 + *
737 + * @return void
738 + */
739 + protected static function uninstallProSettings()
740 + {
741 + VikBookingChangelog::uninstall();
742 + VikBookingLicense::uninstall();
743 + }
744 +
745 + /**
746 + * Provides the uninstallation of the ACL routines.
747 + *
748 + * @return boolean True on success, otherwise false.
749 + */
750 + protected static function uninstallAcl()
751 + {
752 + JLoader::import('adapter.acl.access');
753 + $actions = JAccess::getActions('vikbooking');
754 +
755 + // No actions found!
756 + // Probably, something went wrong while installing the plugin.
757 + if (!$actions)
758 + {
759 + return false;
760 + }
761 +
762 + $roles = array(
763 + get_role('administrator'),
764 + );
765 +
766 + foreach ($roles as $role)
767 + {
768 + if ($role)
769 + {
770 + foreach ($actions as $action)
771 + {
772 + $cap = JAccess::adjustCapability($action->name, 'com_vikbooking');
773 + $role->remove_cap($cap);
774 + }
775 + }
776 + }
777 +
778 + return true;
779 + }
780 +
781 + /**
782 + * Run all the proper SQL files.
783 + *
784 + * @param string $version The current version.
785 + *
786 + * @return boolean True on success, otherwise false.
787 + *
788 + * @uses execSqlFile()
789 + */
790 + protected static function installSql($version)
791 + {
792 + $dbo = JFactory::getDbo();
793 +
794 + $ok = true;
795 +
796 + $sql_base = VIKBOOKING_BASE . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR . 'update' . DIRECTORY_SEPARATOR . 'mysql' . DIRECTORY_SEPARATOR;
797 + $sqlFiles = glob($sql_base . '*.sql');
798 +
799 + /**
800 + * Make sure the SQL files are properly executed per ascending version rather than alphabetically.
801 + *
802 + * @since 1.8.3
803 + */
804 + usort($sqlFiles, function($a, $b) {
805 + return version_compare(basename($a, '.sql'), basename($b, '.sql'));
806 + });
807 +
808 + try
809 + {
810 + foreach ($sqlFiles as $file)
811 + {
812 + $sql_v = basename($file, '.sql');
813 +
814 + if (version_compare($sql_v, $version, '>'))
815 + {
816 + // in case the SQL version is newer, execute the queries listed in the file
817 + self::execSqlFile($file, $dbo);
818 + }
819 + }
820 + }
821 + catch (Exception $e)
822 + {
823 + $ok = false;
824 + }
825 +
826 + return $ok;
827 + }
828 +
829 + /**
830 + * Executes all the queries contained in the specified file.
831 + *
832 + * @param string $file The SQL file to launch.
833 + * @param JDatabase $dbo The database driver handler.
834 + *
835 + * @return void
836 + */
837 + protected static function execSqlFile($file, $dbo = null)
838 + {
839 + if (!is_file($file))
840 + {
841 + return;
842 + }
843 +
844 + if ($dbo === null)
845 + {
846 + $dbo = JFactory::getDbo();
847 + }
848 +
849 + $handle = fopen($file, 'r');
850 +
851 + $bytes = '';
852 + while (!feof($handle))
853 + {
854 + $bytes .= fread($handle, 8192);
855 + }
856 +
857 + fclose($handle);
858 +
859 + foreach (JDatabaseHelper::splitSql($bytes) as $q)
860 + {
861 + $dbo->setQuery($q);
862 + $dbo->execute();
863 + }
864 + }
865 +}