PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / trunk
VikAppointments Services Booking Calendar vtrunk
trunk 1.2.17 1.2.18 1.2.19
vikappointments / admin / models / backup.php
vikappointments / admin / models Last commit date
apiban.php 4 years ago apilog.php 2 years ago apiplugin.php 4 years ago apiuser.php 2 years ago apiuseroptions.php 2 years ago backup.php 4 months ago caldays.php 1 month ago calendar.php 1 month ago city.php 4 years ago closure.php 1 month ago configapp.php 4 years ago configcldays.php 4 years ago configcron.php 4 years ago configemp.php 4 years ago configsmsapi.php 4 years ago configuration.php 4 months ago conversion.php 4 years ago country.php 2 years ago coupon.php 2 years ago couponemployee.php 4 years ago coupongroup.php 2 years ago couponservice.php 4 years ago cronjob.php 2 years ago cronjoblog.php 4 years ago customer.php 4 months ago customf.php 2 years ago customfservice.php 4 years ago customizer.php 4 years ago empgroup.php 2 years ago employee.php 2 years ago empsettings.php 4 years ago file.php 4 years ago findreservation.php 1 month ago group.php 2 years ago import.php 4 years ago index.html 4 years ago invoice.php 1 month ago langcustomf.php 4 years ago langempgroup.php 4 years ago langemployee.php 4 years ago langgroup.php 4 years ago langmedia.php 4 years ago langoption.php 2 years ago langoptiongroup.php 4 years ago langoptionvar.php 4 years ago langpackage.php 4 years ago langpackgroup.php 4 years ago langpayment.php 4 years ago langservice.php 4 years ago langstatuscode.php 4 years ago langsubscr.php 4 years ago langtax.php 2 years ago langtaxrule.php 4 years ago location.php 2 years ago mailtext.php 2 years ago makerecurrence.php 1 month ago media.php 2 years ago multiorder.php 1 month ago option.php 1 year ago optiongroup.php 2 years ago optionvar.php 1 year ago orderstatus.php 2 years ago package.php 2 years ago packageservice.php 4 years ago packgroup.php 2 years ago packorder.php 2 years ago packorderitem.php 1 month ago payment.php 2 years ago rate.php 2 years ago reportsemp.php 4 months ago reportsser.php 4 months ago reservation.php 1 month ago resoptassoc.php 2 years ago restriction.php 2 years ago review.php 3 years ago serempassoc.php 1 year ago seroptassoc.php 4 years ago serrateassoc.php 4 years ago serrestrassoc.php 4 years ago service.php 2 years ago state.php 2 years ago statswidget.php 2 years ago statuscode.php 2 years ago subscription.php 1 month ago subscrorder.php 1 month ago tag.php 4 years ago tax.php 2 years ago taxrule.php 2 years ago updateprogram.php 4 years ago usernote.php 2 years ago waitinglist.php 1 month ago webhook.php 1 year ago worktime.php 1 month ago
backup.php
365 lines
1 <?php
2 /**
3 * @package VikAppointments
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 VAPLoader::import('libraries.mvc.model');
15 VAPLoader::import('libraries.backup.manager');
16
17 /**
18 * VikAppointments backup model.
19 *
20 * @since 1.7.1
21 */
22 class VikAppointmentsModelBackup extends JModelVAP
23 {
24 /**
25 * Basic item loading implementation.
26 *
27 * @param mixed $pk An optional primary key value to load the row by, or an array of fields to match.
28 * If not set the instance property value is used.
29 *
30 * @return mixed The record object on success, null otherwise.
31 */
32 public function getItem($pk, $new = false)
33 {
34 // check if we have a file path or a name
35 if (!JFile::exists($pk))
36 {
37 // fetch folder in which the backup are stored
38 $folder = VAPFactory::getConfig()->get('backupfolder');
39
40 if (!$folder)
41 {
42 // folder not specified, use the temporary folder
43 $folder = JFactory::getApplication()->get('tmp_path');
44 }
45
46 // build file path
47 $pk = rtrim($folder, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $pk;
48
49 if (!JFile::exists($pk))
50 {
51 // backup not found
52 return null;
53 }
54 }
55
56 $vik = VAPApplication::getInstance();
57
58 $backup = new stdClass;
59
60 $backup->name = basename($pk);
61 $backup->path = $pk;
62 $backup->url = $vik->getUrlFromPath($pk);
63 $backup->timestamp = filemtime($pk);
64 $backup->date = JFactory::getDate($backup->timestamp)->format('Y-m-d H:i:s');
65 $backup->size = filesize($pk);
66
67 if (!$backup->url)
68 {
69 // use the administrator task for a direct download
70 $url = $vik->addUrlCSRF('index.php?option=com_vikappointments&task=backup.download&cid[]=' . $backup->name);
71 $backup->url = $vik->adminUrl($url, false);
72 }
73
74 $backup->type = new stdClass;
75
76 if (preg_match("/backup_/i", $backup->name))
77 {
78 // try to fetch the backup type from the name
79 $chunks = preg_split("/backup_/i", $backup->name);
80 $chunks = preg_split("/_/", array_pop($chunks));
81 // remove date from chunks
82 array_pop($chunks);
83
84 $backup->type->id = implode('_', $chunks);
85
86 // try to fetch the matching export type
87 $type = $this->getExportTypes($backup->type->id);
88
89 if ($backup->type->id && $type)
90 {
91 $backup->type->name = $type->getName();
92 }
93 else
94 {
95 $backup->type->name = $backup->type->id;
96 }
97 }
98 else
99 {
100 // we are not dealing with a backup file
101 $backup->type->id = 'custom';
102 $backup->type->name = 'custom';
103 }
104
105 return $backup;
106 }
107
108 /**
109 * Entirely rewrite save method because the backup files
110 * do not use database tables.
111 *
112 * @param mixed $data Either an array or an object of data to save.
113 *
114 * @return mixed The ID of the record on success, false otherwise.
115 */
116 public function save($data)
117 {
118 // wrap in a registry for a better ease of use
119 $data = new JRegistry($data);
120
121 $config = VAPFactory::getConfig();
122
123 if ($data->get('action', 'create') === 'create')
124 {
125 // get requested type
126 $type = $data->get('type');
127
128 if (!$type)
129 {
130 // type not specified, use the default one
131 $type = $config->get('backuptype', 'full');
132 }
133
134 $options = [];
135
136 // get requested folder
137 $options['folder'] = $data->get('folder');
138
139 if (!$options['folder'])
140 {
141 // folder not specified, use the default one
142 $options['folder'] = $config->get('backupfolder', null);
143 }
144
145 if ($filename = $data->get('filename'))
146 {
147 // use the given filename
148 $options['filename'] = $filename;
149 }
150
151 if ($prefix = $data->get('prefix'))
152 {
153 // use the given price
154 $options['prefix'] = $prefix;
155 }
156
157 try
158 {
159 // create a new backup
160 $archive = VAPBackupManager::create($type, $options);
161 }
162 catch (Exception $e)
163 {
164 // register error and abort the saving process
165 $this->setError($e);
166 return false;
167 }
168 }
169 else
170 {
171 $file = $data->get('file');
172
173 // get requested folder
174 $dest = $data->get('folder');
175
176 if (!$dest)
177 {
178 // folder not specified, use the default one
179 $dest = $config->get('backupfolder', null);
180 }
181
182 if (!$dest)
183 {
184 // use temporary folder if not specified
185 $dest = JFactory::getApplication()->get('tmp_path');
186 }
187
188 // upload archive
189 $resp = VikAppointments::uploadFile($file, $dest, 'zip', $overwrite = false);
190
191 if (!$resp->status)
192 {
193 // unable to upload the image, abort
194 if ($resp->errno == 1)
195 {
196 $this->setError(JText::sprintf('VAPCONFIGFILETYPEERRORWHO', $resp->mimeType));
197 }
198 else
199 {
200 $this->setError(JText::translate('VAPCONFIGUPLOADERROR'));
201 }
202
203 return false;
204 }
205
206 // extract file type from path
207 $filetype = pathinfo($resp->path, PATHINFO_EXTENSION);
208
209 // build safe name
210 $safeName = 'backup_uploaded_' . JFactory::getDate()->format('Y-m-d H-i-s') . '.' . $filetype;
211
212 // rename the file so that the system will be able to load it
213 if (!rename($resp->path, dirname($resp->path) . DIRECTORY_SEPARATOR . $safeName))
214 {
215 // it was not possible to rename the file
216 JFile::delete($resp->path);
217 $this->setError(sprintf('Cannot rename [%s] into [%s]', $resp->name, $safeName));
218 return false;
219 }
220
221 // register archive name
222 $archive = $safeName;
223 }
224
225 return $archive;
226 }
227
228 /**
229 * Restores an existing backup.
230 *
231 * @param string $path Either the name of the path of the archive.
232 *
233 * @return boolean True on success, false otherwise.
234 */
235 public function restore($path)
236 {
237 // make sure the archive exists
238 $archive = $this->getItem($path);
239
240 if (!$archive)
241 {
242 // the specified backup doesn't exist
243 $this->setError(sprintf('Backup [%s] not found', $path));
244 return false;
245 }
246
247 try
248 {
249 // restore the system with the backup data
250 VAPBackupManager::restore($archive->path);
251 }
252 catch (Exception $e)
253 {
254 // an error occurred
255 $this->setError($e);
256 return false;
257 }
258
259 return true;
260 }
261
262 /**
263 * Extend delete implementation to delete any related records
264 * stored within a separated table.
265 *
266 * @param mixed $ids Either the record ID or a list of records.
267 *
268 * @return boolean True on success, false otherwise.
269 */
270 public function delete($ids)
271 {
272 $ids = (array) $ids;
273
274 $result = false;
275
276 foreach ($ids as $id)
277 {
278 // fetch backup details
279 $item = $this->getItem($id);
280
281 if ($item)
282 {
283 // delete the backup file
284 $result = JFile::delete($item->path) || $result;
285 }
286 }
287
288 return $result;
289 }
290
291 /**
292 * Moves the existing backup archives into the new specified folder.
293 *
294 * @param string $path The new folder used to host the archives.
295 *
296 * @return boolean True on success, false otherwise.
297 */
298 public function moveArchives($path)
299 {
300 // get currently set folder
301 $current = VAPFactory::getConfig()->get('backupfolder');
302
303 if (!$current)
304 {
305 // folder not specified, use the default one
306 $current = JFactory::getApplication()->get('tmp_path');
307 }
308
309 // load all backup archives
310 $files = JFolder::files($current, 'backup_', $recurse = false, $fullpath = true);
311
312 $path = rtrim($path, DIRECTORY_SEPARATOR);
313
314 if (!JFolder::exists($path))
315 {
316 // attempt to create the folder if missing
317 JFolder::create($path);
318 }
319
320 $status = true;
321
322 foreach ($files as $file)
323 {
324 // create new path
325 $newFile = $path . DIRECTORY_SEPARATOR . basename($file);
326 // try to rename the archive
327 if (!rename($file, $newFile))
328 {
329 $this->setError(sprintf('Unable to move [%s] into [%s]', $file, $newFile));
330 $status = false;
331 }
332 }
333
334 return $status;
335 }
336
337 /**
338 * Returns a list of supported export types.
339 *
340 * @param string|null $id When provided, only the matching type will be returned.
341 *
342 * @return array|object|null
343 */
344 public function getExportTypes($id = null)
345 {
346 // the export types will be fetched only once
347 $types = VAPBackupManager::getExportTypes();
348
349 if (!$id)
350 {
351 // return all the types
352 return $types;
353 }
354
355 if ($id && isset($types[$id]))
356 {
357 // return the searched type
358 return $types[$id];
359 }
360
361 // type not found
362 return null;
363 }
364 }
365