| 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 |
} |
| 866 |
|