PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.21
VikAppointments Services Booking Calendar v1.2.21
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / site / helpers / libraries / worktime / import / manager.php
vikappointments / site / helpers / libraries / worktime / import Last commit date
layout 3 days ago type 3 days ago index.html 3 days ago layout.php 3 days ago manager.php 3 days ago type.php 3 days ago
manager.php
270 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.worktime.import.layout');
15 VAPLoader::import('libraries.worktime.import.type');
16
17 /**
18 * Working days import manager.
19 *
20 * @since 1.7.1
21 */
22 abstract class VAPWorktimeImportManager
23 {
24 /**
25 * An array of include paths.
26 *
27 * @var array
28 */
29 protected static $includePaths = null;
30
31 /**
32 * An array of types.
33 *
34 * @var VAPWorktimeImportType[]
35 */
36 protected static $types = null;
37
38 /**
39 * Processes the given file and try to import the working days according
40 * to the mime type of the file.
41 *
42 * @param string $file The path of the file to import.
43 * @param array $options An array of options.
44 *
45 * @return array An array containing all the fetched working times.
46 *
47 * @throws Exception
48 */
49 public static function process($file, array $options = [])
50 {
51 // access the list of supported import types
52 $types = static::getSupportedTypes();
53
54 $auto_delete = false;
55
56 // check whether the file exists
57 if (!JFile::exists($file))
58 {
59 $app = JFactory::getApplication();
60
61 // file missing, try to upload it from the request
62 $fileData = $app->input->files->get($file, null, 'raw');
63
64 if (!$fileData)
65 {
66 // file not found in request
67 throw new Exception(sprintf('Import file [%s] not found', $file), 404);
68 }
69
70 // build the filter with the allowed file types
71 $filters = implode(',', array_keys($types));
72
73 // try to upload the file
74 $result = VikAppointments::uploadFile($fileData, $app->get('tmp_path'), $filters);
75
76 if (!$result->status)
77 {
78 // unable to upload the image, abort
79 if ($result->errno == 1)
80 {
81 // invalid file type
82 $error = new Exception(JText::sprintf('VAPCONFIGFILETYPEERRORWHO', $result->mimeType), 405);
83 }
84 else
85 {
86 // unable to upload the file
87 $error = new Exception(JText::translate('VAPCONFIGUPLOADERROR'), 500);
88 }
89
90 throw $error;
91 }
92
93 // file uploaded, register the path
94 $file = $result->path;
95
96 // auto-delete the uploaded file at the end of the process
97 $auto_delete = true;
98 }
99
100 // extract file type from path
101 $type = pathinfo($file, PATHINFO_EXTENSION);
102
103 $error = null;
104
105 $list = [];
106
107 try
108 {
109 // make sure the file type is supported
110 if (!isset($types[$type]))
111 {
112 // cannot handle the given type
113 throw new Exception(sprintf('Import type [%s] not supported', $type), 405);
114 }
115
116 $buffer = '';
117
118 // open file in reading mode
119 $fp = fopen($file, 'r');
120
121 while (!feof($fp))
122 {
123 // read buffer from file
124 $buffer .= fread($fp, 8192);
125 }
126
127 fclose($fp);
128
129 // process import through the requested type
130 $list = $types[$type]->process($buffer);
131 }
132 catch (Exception $e)
133 {
134 $error = $e;
135 }
136
137 if ($auto_delete)
138 {
139 // auto-delete the uploaded file
140 JFile::delete($file);
141 }
142
143 if ($error)
144 {
145 // propagate the error after cleaning the temporary file
146 throw $error;
147 }
148
149 if (!isset($options['layout']))
150 {
151 // layout not found, use the default one
152 $options['layout'] = 'raw';
153 }
154
155 if (!$options['layout'] instanceof VAPWorktimeImportLayout)
156 {
157 // try to load the layout from the default directory
158 VAPLoader::import('libraries.worktime.import.layout.' . $options['layout']);
159 // build layout class name
160 $layoutClassName = 'VAPWorktimeImportLayout' . ucfirst($options['layout']);
161
162 if (!class_exists($layoutClassName))
163 {
164 // import layout handler missing
165 throw new Exception(sprintf('Import layout [%s] not found', $options['layout']), 404);
166 }
167
168 // create layout handler
169 $options['layout'] = new $layoutClassName();
170
171 if (!$options['layout'] instanceof VAPWorktimeImportLayout)
172 {
173 // invalid instance
174 throw new Exception(sprintf('Import layout [%s] is not a valid instance', $layoutClassName), 500);
175 }
176 }
177
178 // adjust the returned times to the requested layout
179 return $options['layout']->build($list);
180 }
181
182 /**
183 * Returns a list of supported types.
184 *
185 * @return array An associative array of instances.
186 */
187 public static function getSupportedTypes()
188 {
189 if (!is_null(static::$types))
190 {
191 return static::$types;
192 }
193
194 static::$types = [];
195
196 // get list of registered paths
197 $paths = static::addIncludePath();
198
199 // scan all the folders
200 foreach ($paths as $path)
201 {
202 // scan all the PHP files
203 foreach (JFolder::files($path, '\.php') as $file)
204 {
205 // include the file
206 include_once JPath::clean($path . '/' . $file);
207
208 // extract type from file name
209 $type = explode('.', $file);
210 $type = strtolower($type[0]);
211
212 // build class name
213 $classname = 'VAPWorktimeImportType' . ucfirst($type);
214
215 if (!class_exists($classname))
216 {
217 // class not found
218 continue;
219 }
220
221 // create import instance
222 $driver = new $classname();
223
224 if (!$driver instanceof VAPWorktimeImportType)
225 {
226 // invalid class
227 continue;
228 }
229
230 // register import type
231 static::$types[$type] = $driver;
232 }
233 }
234
235 return static::$types;
236 }
237
238 /**
239 * Registers a new include path in which to search for the supported import types.
240 *
241 * @param mixed $paths Either an array or the path to include.
242 *
243 * @return array A list of supported include paths.
244 */
245 public static function addIncludePath($paths = null)
246 {
247 if (!static::$includePaths)
248 {
249 // init with the default include path
250 static::$includePaths = [
251 dirname(__FILE__) . DIRECTORY_SEPARATOR . 'type',
252 ];
253 }
254
255 $paths = (array) $paths;
256
257 // iterate paths
258 foreach ($paths as $path)
259 {
260 // make sure the paths hasn't been registered yet
261 if (!in_array($path, static::$includePaths))
262 {
263 static::$includePaths[] = $path;
264 }
265 }
266
267 return static::$includePaths;
268 }
269 }
270