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/helpers/src/model/backup.php +363 -0 1.6.0 → 1.8.16 View file →
@@ -1,0 +1,363 @@
1 +<?php
2 +/**
3 + * @package VikBooking
4 + * @subpackage core
5 + * @author E4J s.r.l.
6 + * @copyright Copyright (C) 2021 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 + * VikBooking backup model.
16 + *
17 + * @since 1.5
18 + */
19 +class VBOModelBackup extends JObject
20 +{
21 + /**
22 + * Basic item loading implementation.
23 + *
24 + * @param mixed $pk An optional primary key value to load the row by, or an array of fields to match.
25 + * If not set the instance property value is used.
26 + *
27 + * @return mixed The record object on success, null otherwise.
28 + */
29 + public function getItem($pk)
30 + {
31 + // check if we have a file path or a name
32 + if (!JFile::exists($pk))
33 + {
34 + // fetch folder in which the backup are stored
35 + $folder = VBOFactory::getConfig()->get('backupfolder');
36 +
37 + if (!$folder)
38 + {
39 + // folder not specified, use the temporary folder
40 + $folder = JFactory::getApplication()->get('tmp_path');
41 + }
42 +
43 + // build file path
44 + $pk = rtrim($folder, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $pk;
45 +
46 + if (!JFile::exists($pk))
47 + {
48 + // backup not found
49 + return null;
50 + }
51 + }
52 +
53 + // get running platform
54 + $platform = VBOFactory::getPlatform();
55 +
56 + $backup = new stdClass;
57 +
58 + $backup->name = basename($pk);
59 + $backup->path = $pk;
60 + $backup->url = $platform->getUri()->getUrlFromPath($pk);
61 + $backup->timestamp = filemtime($pk);
62 + $backup->date = JFactory::getDate($backup->timestamp)->format('Y-m-d H:i:s');
63 + $backup->size = filesize($pk);
64 +
65 + if (!$backup->url)
66 + {
67 + // use the administrator task for a direct download
68 + $url = $platform->getUri()->addCSRF('index.php?option=com_vikbooking&task=backup.download&cid[]=' . $backup->name);
69 + $backup->url = $platform->getUri()->admin($url, false);
70 + }
71 +
72 + $backup->type = new stdClass;
73 +
74 + if (preg_match("/backup_/i", $backup->name))
75 + {
76 + // try to fetch the backup type from the name
77 + $chunks = preg_split("/backup_/i", $backup->name);
78 + $chunks = preg_split("/_/", array_pop($chunks));
79 + // remove date from chunks
80 + array_pop($chunks);
81 +
82 + $backup->type->id = implode('_', $chunks);
83 +
84 + if (empty($backup->type->id))
85 + {
86 + // unexpected file format
87 + return null;
88 + }
89 +
90 + // try to fetch the matching export type
91 + $type = $this->getExportTypes($backup->type->id);
92 +
93 + if ($type)
94 + {
95 + $backup->type->name = $type->getName();
96 + }
97 + else
98 + {
99 + $backup->type->name = $backup->type->id;
100 + }
101 + }
102 + else
103 + {
104 + // we are not dealing with a backup file
105 + $backup->type->id = 'custom';
106 + $backup->type->name = 'custom';
107 + }
108 +
109 + return $backup;
110 + }
111 +
112 + /**
113 + * Entirely rewrite save method because the backup files
114 + * do not use database tables.
115 + *
116 + * @param mixed $data Either an array or an object of data to save.
117 + *
118 + * @return mixed The ID of the record on success, false otherwise.
119 + */
120 + public function save($data)
121 + {
122 + // wrap in a registry for a better ease of use
123 + $data = new JRegistry($data);
124 +
125 + $config = VBOFactory::getConfig();
126 +
127 + if ($data->get('action', 'create') === 'create')
128 + {
129 + // get requested type
130 + $type = $data->get('type');
131 +
132 + if (!$type)
133 + {
134 + // type not specified, use the default one
135 + $type = $config->get('backuptype', 'full');
136 + }
137 +
138 + $options = [];
139 +
140 + // get requested folder
141 + $options['folder'] = $data->get('folder');
142 +
143 + if (!$options['folder'])
144 + {
145 + // folder not specified, use the default one
146 + $options['folder'] = $config->get('backupfolder', null);
147 + }
148 +
149 + if ($filename = $data->get('filename'))
150 + {
151 + // use the given filename
152 + $options['filename'] = $filename;
153 + }
154 +
155 + if ($prefix = $data->get('prefix'))
156 + {
157 + // use the given price
158 + $options['prefix'] = $prefix;
159 + }
160 +
161 + try
162 + {
163 + // create a new backup
164 + $archive = VBOBackupManager::create($type, $options);
165 + }
166 + catch (Exception $e)
167 + {
168 + // register error and abort the saving process
169 + $this->setError($e);
170 + return false;
171 + }
172 + }
173 + else
174 + {
175 + $file = $data->get('file');
176 +
177 + // get requested folder
178 + $dest = $data->get('folder');
179 +
180 + if (!$dest)
181 + {
182 + // folder not specified, use the default one
183 + $dest = $config->get('backupfolder', null);
184 + }
185 +
186 + if (!$dest)
187 + {
188 + // use temporary folder if not specified
189 + $dest = JFactory::getApplication()->get('tmp_path');
190 + }
191 +
192 + try
193 + {
194 + // upload archive
195 + $resp = VikBooking::uploadFileFromRequest((array)$file, $dest, 'zip');
196 + }
197 + catch (Exception $e)
198 + {
199 + // catch error and register it within the model
200 + $this->setError($e);
201 +
202 + return false;
203 + }
204 +
205 + // extract file type from path
206 + $filetype = pathinfo($resp->path, PATHINFO_EXTENSION);
207 +
208 + // build safe name
209 + $safeName = 'backup_uploaded_' . JFactory::getDate()->format('Y-m-d H:i:s') . '.' . $filetype;
210 +
211 + // rename the file so that the system will be able to load it
212 + if (!rename($resp->path, dirname($resp->path) . DIRECTORY_SEPARATOR . $safeName))
213 + {
214 + // it was not possible to rename the file
215 + JFile::delete($resp->path);
216 + $this->setError(sprintf('Cannot rename [%s] into [%s]', $resp->name, $safeName));
217 + return false;
218 + }
219 +
220 + // register archive name
221 + $archive = $safeName;
222 + }
223 +
224 + return $archive;
225 + }
226 +
227 + /**
228 + * Restores an existing backup.
229 + *
230 + * @param string $path Either the name of the path of the archive.
231 + *
232 + * @return boolean True on success, false otherwise.
233 + */
234 + public function restore($path)
235 + {
236 + // make sure the archive exists
237 + $archive = $this->getItem($path);
238 +
239 + if (!$archive)
240 + {
241 + // the specified backup doesn't exist
242 + $this->setError(sprintf('Backup [%s] not found', $path));
243 + return false;
244 + }
245 +
246 + try
247 + {
248 + // restore the system with the backup data
249 + VBOBackupManager::restore($archive->path);
250 + }
251 + catch (Exception $e)
252 + {
253 + // an error occurred
254 + $this->setError($e);
255 + return false;
256 + }
257 +
258 + return true;
259 + }
260 +
261 + /**
262 + * Extend delete implementation to delete any related records
263 + * stored within a separated table.
264 + *
265 + * @param mixed $ids Either the record ID or a list of records.
266 + *
267 + * @return boolean True on success, false otherwise.
268 + */
269 + public function delete($ids)
270 + {
271 + $ids = (array) $ids;
272 +
273 + $result = false;
274 +
275 + foreach ($ids as $id)
276 + {
277 + // fetch backup details
278 + $item = $this->getItem($id);
279 +
280 + if ($item)
281 + {
282 + // delete the backup file
283 + $result = JFile::delete($item->path) || $result;
284 + }
285 + }
286 +
287 + return $result;
288 + }
289 +
290 + /**
291 + * Moves the existing backup archives into the new specified folder.
292 + *
293 + * @param string $path The new folder used to host the archives.
294 + *
295 + * @return boolean True on success, false otherwise.
296 + */
297 + public function moveArchives($path)
298 + {
299 + // get currently set folder
300 + $current = VBOFactory::getConfig()->get('backupfolder');
301 +
302 + if (!$current)
303 + {
304 + // folder not specified, use the default one
305 + $current = JFactory::getApplication()->get('tmp_path');
306 + }
307 +
308 + // load all backup archives
309 + $files = JFolder::files($current, 'backup_', $recurse = false, $fullpath = true);
310 +
311 + $path = rtrim($path, DIRECTORY_SEPARATOR);
312 +
313 + if (!JFolder::exists($path))
314 + {
315 + // attempt to create the folder if missing
316 + JFolder::create($path);
317 + }
318 +
319 + $status = true;
320 +
321 + foreach ($files as $file)
322 + {
323 + // create new path
324 + $newFile = $path . DIRECTORY_SEPARATOR . basename($file);
325 + // try to rename the archive
326 + if (!rename($file, $newFile))
327 + {
328 + $this->setError(sprintf('Unable to move [%s] into [%s]', $file, $newFile));
329 + $status = false;
330 + }
331 + }
332 +
333 + return $status;
334 + }
335 +
336 + /**
337 + * Returns a list of supported export types.
338 + *
339 + * @param string|null $id When provided, only the matching type will be returned.
340 + *
341 + * @return array|object|null
342 + */
343 + public function getExportTypes($id = null)
344 + {
345 + // the export types will be fetched only once
346 + $types = VBOBackupManager::getExportTypes();
347 +
348 + if (!$id)
349 + {
350 + // return all the types
351 + return $types;
352 + }
353 +
354 + if ($id && isset($types[$id]))
355 + {
356 + // return the searched type
357 + return $types[$id];
358 + }
359 +
360 + // type not found
361 + return null;
362 + }
363 +}