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/fixer.php +318 -0 1.6.2 → 1.8.16 View file →
@@ -1,0 +1,318 @@
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 +/**
15 + * Implements the abstract methods to fix an update.
16 + *
17 + * Never use exit() and die() functions to stop the flow.
18 + * Return false instead to break process safely.
19 + */
20 +class VikBookingUpdateFixer
21 +{
22 + /**
23 + * The current version.
24 + *
25 + * @var string
26 + */
27 + protected $version;
28 +
29 + /**
30 + * Class constructor.
31 + */
32 + public function __construct($version)
33 + {
34 + $this->version = $version;
35 + }
36 +
37 + /**
38 + * This method is called before the SQL installation.
39 + *
40 + * @return boolean True to proceed with the update, otherwise false to stop.
41 + */
42 + public function beforeInstallation()
43 + {
44 + /**
45 + * Make sure all the necessary (and new) directories have been created.
46 + *
47 + * @since 1.5.0
48 + */
49 + VikBookingUpdateManager::installUploadBackup();
50 +
51 + if (version_compare($this->version, '1.5.0', '<')) {
52 + /**
53 + * For those upgrading to VBO 1.5.0 we need to move the customer upload
54 + * document directories to the new location. Basically, they have been
55 + * moved to the new dir /customerdocs inside the plugin's upload dir of WP.
56 + *
57 + * @since 1.5.0
58 + */
59 + $dbo = JFactory::getDbo();
60 +
61 + $old_custdocs_path = str_replace(DIRECTORY_SEPARATOR . 'customerdocs', '', VBO_CUSTOMERS_PATH);
62 + $new_custdocs_path = VBO_CUSTOMERS_PATH;
63 +
64 + $q = "SELECT `docsfolder` FROM `#__vikbooking_customers` WHERE `docsfolder` IS NOT NULL";
65 + $dbo->setQuery($q);
66 + $dbo->execute();
67 + if ($dbo->getNumRows()) {
68 + $doc_folders = $dbo->loadObjectList();
69 + foreach ($doc_folders as $doc_folder) {
70 + if (empty($doc_folder->docsfolder)) {
71 + continue;
72 + }
73 + // move directory to new path
74 + $from_dir = $old_custdocs_path . DIRECTORY_SEPARATOR . $doc_folder->docsfolder;
75 + $to_dir = $new_custdocs_path . DIRECTORY_SEPARATOR . $doc_folder->docsfolder;
76 + if (JFolder::copy($from_dir, $to_dir, $path = '', $force = true)) {
77 + JFolder::delete($from_dir);
78 + }
79 + }
80 + }
81 + }
82 +
83 + if (version_compare($this->version, '1.5.11', '<') && !VikBookingLiteManager::guessPro())
84 + {
85 + $dbo = JFactory::getDbo();
86 + // truncate the payment gateways table
87 + $dbo->setQuery("TRUNCATE TABLE `#__vikbooking_gpayments`");
88 + $dbo->execute();
89 + }
90 +
91 + if (version_compare($this->version, '1.6.0', '<'))
92 + {
93 + if (!class_exists('VikBooking')) {
94 + require_once VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'lib.vikbooking.php';
95 + }
96 +
97 + // normalize translation records table name
98 + VikBooking::getTranslator()->normalizeTnTableNames();
99 + }
100 +
101 + return true;
102 + }
103 +
104 + /**
105 + * This method is called after the SQL installation.
106 + *
107 + * @return boolean True to proceed with the update, otherwise false to stop.
108 + */
109 + public function afterInstallation()
110 + {
111 + $dbo = JFactory::getDbo();
112 +
113 + /**
114 + * Unpublish overrides and obtain tracking list.
115 + *
116 + * @since 1.6.5
117 + */
118 + $track = $this->deactivateBreakingOverrides();
119 +
120 + // register breaking changes, if any
121 + VikBookingInstaller::registerBreakingChanges($track);
122 +
123 + if (version_compare($this->version, '1.6.1', '<'))
124 + {
125 + // resolve conflicting update checks for older VCM versions (1.8.4)
126 + if (defined('VIKCHANNELMANAGER_SOFTWARE_VERSION') && version_compare(VIKCHANNELMANAGER_SOFTWARE_VERSION, '1.8.5', '<'))
127 + {
128 + $old_vcm_data = file_get_contents(VCM_ADMIN_PATH . DIRECTORY_SEPARATOR . 'controller.php');
129 + $old_vcm_data = str_replace("'forcecheck'", "'force_check'", $old_vcm_data);
130 + file_put_contents(VCM_ADMIN_PATH . DIRECTORY_SEPARATOR . 'controller.php', $old_vcm_data);
131 + }
132 + }
133 +
134 + if (version_compare($this->version, '1.7.0', '<'))
135 + {
136 + /**
137 + * Install the new "tinyurl" Shortcode.
138 + */
139 + $model = JModel::getInstance('vikbooking', 'shortcode', 'admin');
140 +
141 + $shortcode = new stdClass;
142 + $shortcode->createdby = JFactory::getUser()->id;
143 + $shortcode->createdon = JFactory::getDate()->toSql();
144 + $shortcode->title = 'COM_VIKBOOKING_TINYURL_VIEW_DEFAULT_TITLE';
145 + $shortcode->name = 'Tiny URL';
146 + $shortcode->type = 'tinyurl';
147 + $shortcode->shortcode = '[vikbooking view="tinyurl" lang="*"]';
148 +
149 + try {
150 + $sh_id = $model->save($shortcode);
151 +
152 + if ($sh_id) {
153 + // assign the shortcode to a new page
154 + $model->addPage($sh_id);
155 + }
156 + } catch (Throwable $e) {
157 + // do nothing, but prevent fatal errors
158 + }
159 +
160 + /**
161 + * Normalize invoice and check-in document names for OTA bookings.
162 + *
163 + * @since 1.7.0
164 + */
165 + $fixing_invoices = JFolder::files(implode(DIRECTORY_SEPARATOR, [VBO_SITE_PATH, 'helpers', 'invoices', 'generated']), '[0-9]+_\.pdf$', $recursive = false, $fullpath = true);
166 + $fixing_checkdocs = JFolder::files(implode(DIRECTORY_SEPARATOR, [VBO_SITE_PATH, 'helpers', 'checkins', 'generated']), '[0-9]+_\.pdf$', $recursive = false, $fullpath = true);
167 + foreach (array_merge($fixing_invoices, $fixing_checkdocs) as $fix_doc) {
168 + $doc_bid = (int) preg_replace('/[^0-9]/', '', basename($fix_doc));
169 + if (!$doc_bid) {
170 + continue;
171 + }
172 + // whether it's an invoice or a check-in document
173 + $is_invoice = strpos($fix_doc, 'invoices') !== false;
174 + // get the OTA booking ID
175 + $dbo->setQuery(
176 + $dbo->getQuery(true)
177 + ->select($dbo->qn('idorderota'))
178 + ->from($dbo->qn('#__vikbooking_orders'))
179 + ->where($dbo->qn('id') . ' = ' . $doc_bid)
180 + , 0, 1);
181 + $idorderota = $dbo->loadResult();
182 + if (!$idorderota) {
183 + // delete file for security reason if the booking does not exist
184 + JFile::delete($fix_doc);
185 + continue;
186 + }
187 + // build new safe document name
188 + $safe_fname = $doc_bid . '_' . $idorderota . '.pdf';
189 + $safe_fpath = str_replace(basename($fix_doc), $safe_fname, $fix_doc);
190 + // rename document file
191 + rename($fix_doc, $safe_fpath);
192 + // update db reference
193 + if ($is_invoice) {
194 + // invoice
195 + $q = $dbo->getQuery(true)
196 + ->update($dbo->qn('#__vikbooking_invoices'))
197 + ->set($dbo->qn('file_name') . ' = ' . $dbo->q($safe_fname))
198 + ->where($dbo->qn('idorder') . ' = ' . $doc_bid)
199 + ->where($dbo->qn('file_name') . ' = ' . $dbo->q(basename($fix_doc)));
200 + } else {
201 + // check-in document
202 + $q = $dbo->getQuery(true)
203 + ->update($dbo->qn('#__vikbooking_customers_orders'))
204 + ->set($dbo->qn('checkindoc') . ' = ' . $dbo->q($safe_fname))
205 + ->where($dbo->qn('idorder') . ' = ' . $doc_bid)
206 + ->where($dbo->qn('checkindoc') . ' = ' . $dbo->q(basename($fix_doc)));
207 + }
208 + $dbo->setQuery($q);
209 + $dbo->execute();
210 + if (VBOPlatformDetection::isWordPress()) {
211 + // trigger files mirroring
212 + VikBookingUpdateManager::triggerUploadBackup($safe_fpath);
213 + }
214 + }
215 + }
216 +
217 + return true;
218 + }
219 +
220 + /**
221 + * Returns a list of possible overrides that may
222 + * break the site for backward compatibility errors.
223 + *
224 + * @return array The list of overrides, grouped by client.
225 + *
226 + * @since 1.6.5
227 + */
228 + protected function getBreakingOverrides()
229 + {
230 + // define initial overrides lookup
231 + $lookup = [
232 + 'admin' => [],
233 + 'site' => [],
234 + 'layouts' => [],
235 + 'widgets' => [],
236 + ];
237 +
238 + // check whether the current version (before the update)
239 + // was prior than 1.6.5 version
240 + if (version_compare($this->version, '1.6.5', '<'))
241 + {
242 + // multitasking layout must be updated to support the Service Worker
243 + $lookup['layouts'][] = VBO_ADMIN_PATH . '/layouts/sidepanel/multitasking.php';
244 + }
245 +
246 + /**
247 + * NOTE: it is possible to use the code below to automatically deactivate all the existing overrides:
248 + * `$lookup = JModel::getInstance('vikbooking', 'overrides', 'admin')->getAllOverrides();`
249 + */
250 +
251 + return $lookup;
252 + }
253 +
254 + /**
255 + * Helper function used to deactivate any overrides that
256 + * may corrupt the system because of breaking changes.
257 + *
258 + * @return array The list of unpublished overrides.
259 + *
260 + * @since 1.6.5
261 + */
262 + protected function deactivateBreakingOverrides()
263 + {
264 + // load list of breaking overrides
265 + $lookup = $this->getBreakingOverrides();
266 +
267 + $track = [];
268 +
269 + // get models to manage the overrides
270 + $listModel = JModel::getInstance('vikbooking', 'overrides', 'admin');
271 + $itemModel = JModel::getInstance('vikbooking', 'override', 'admin');
272 +
273 + foreach ($lookup as $client => $files)
274 + {
275 + // do not need to load the whole tree in case
276 + // the client doesn't report any files
277 + if ($files)
278 + {
279 + $tree = $listModel->getTree($client);
280 +
281 + foreach ($files as $file)
282 + {
283 + // clean file path
284 + $file = JPath::clean($file);
285 +
286 + // check whether the specified file is supported
287 + if ($node = $listModel->isSupported($tree, $file))
288 + {
289 + // skip in case the path has been already unpublished
290 + if (in_array($node['override'], isset($track[$client]) ? $track[$client] : []))
291 + {
292 + continue;
293 + }
294 +
295 + // override found, check whether we have an existing
296 + // and published override
297 + if ($node['has'] && $node['published'])
298 + {
299 + // deactivate the override
300 + if ($itemModel->publish($node['override'], 0))
301 + {
302 + if (!isset($track[$client]))
303 + {
304 + $track[$client] = [];
305 + }
306 +
307 + // track the unpublished file for later use
308 + $track[$client][] = $node['override'];
309 + }
310 + }
311 + }
312 + }
313 + }
314 + }
315 +
316 + return $track;
317 + }
318 +}