PluginProbe
VikBooking Hotel Booking Engine & PMS / trunk
VikBooking Hotel Booking Engine & PMS vtrunk
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 1.7.3 All 36 releases
vikbooking / admin / helpers / src / report / loader.php

loader.php in VikBooking Hotel Booking Engine & PMS trunk, at admin/helpers/src/report/loader.php

261 lines 7.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikBooking
4 * @subpackage core
5 * @author Alessio Gaggii - E4J s.r.l.
6 * @copyright Copyright (C) 2023 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 * Class handler for loading PMS Reports.
16 *
17 * @since 1.16.1 (J) - 1.6.1 (WP)
18 */
19 final class VBOReportLoader
20 {
21 /**
22 * The singleton instance of the class.
23 *
24 * @var VBOReportLoader
25 */
26 private static $instance = null;
27
28 /**
29 * @var array
30 */
31 private $global_reports = [];
32
33 /**
34 * @var array
35 */
36 private $country_reports = [];
37
38 /**
39 * @var array
40 */
41 private $countries = [];
42
43 /**
44 * Proxy to construct the object.
45 *
46 * @return self
47 */
48 public static function getInstance()
49 {
50 if (is_null(static::$instance)) {
51 static::$instance = new static();
52 }
53
54 return static::$instance;
55 }
56
57 /**
58 * Class constructor will require the necessary dependencies.
59 */
60 public function __construct()
61 {
62 // require the report abstract class
63 $report_base = $this->getReportBasePath();
64 require_once $report_base . 'report.php';
65 }
66
67 /**
68 * Gets the instance of a specific report class.
69 *
70 * @param string $report the name of the report to load.
71 *
72 * @return mixed false or report object instance.
73 */
74 public function getDriver($report)
75 {
76 return VikBooking::getReportInstance($report);
77 }
78
79 /**
80 * Loads and returns the list of available PMS Report objects.
81 *
82 * @return array list of "global" and "country" reports.
83 */
84 public function getDrivers($type = '')
85 {
86 if ($this->global_reports || $this->country_reports) {
87 // drivers loaded already
88 return [$this->global_reports, $this->country_reports];
89 }
90
91 // read all driver files
92 $report_files = glob($this->getReportBasePath() . '*.php');
93
94 /**
95 * Trigger event to let other plugins register additional driver full paths.
96 *
97 * @since 1.16.0 (J) - 1.6.0 (WP)
98 */
99 $list = VBOFactory::getPlatform()->getDispatcher()->filter('onLoadPmsReports');
100 foreach ($list as $chunk) {
101 // merge default driver files with the returned ones
102 $report_files = array_merge($report_files, (array)$chunk);
103 }
104
105 // parse and invoke all drivers
106 foreach ($report_files as $k => $report_path) {
107 // driver file name
108 $report_file = basename($report_path, '.php');
109
110 if ($report_file == 'report') {
111 // exclude protected abstract report class
112 unset($report_files[$k]);
113 continue;
114 }
115
116 // load report file
117 require_once $report_path;
118
119 // build report class name
120 $classname = 'VikBookingReport' . str_replace(' ', '', ucwords(str_replace('_', ' ', $report_file)));
121 if (!class_exists($classname)) {
122 // invalid class name declared
123 unset($report_files[$k]);
124 continue;
125 }
126
127 // instantiate the report object
128 $reportInstance = new $classname;
129
130 // ensure the report is compatible with the current environment
131 if ($reportInstance->preflight() === false) {
132 // exclude non-compatible report
133 unset($report_files[$k]);
134 continue;
135 }
136
137 if ($report_file == 'revenue' && $this->global_reports) {
138 // make the "revenue" the first element of the list
139 array_unshift($this->global_reports, $reportInstance);
140 } elseif (strpos($report_file, 'istat') !== false || strpos($report_file, 'polizia') !== false) {
141 // this is a country (italy) specific report so we push it to a separate array
142 $country_key = 'IT';
143 if (!isset($this->country_reports[$country_key])) {
144 $this->country_reports[$country_key] = [];
145 }
146 $this->country_reports[$country_key][] = $reportInstance;
147 } elseif (substr($report_file, 2, 1) == '_') {
148 // this is probably a country specific report so we push it to a separate array (two-letter country code + underscore in file name)
149 $country_key = strtoupper(substr($report_file, 0, 2));
150 if (!isset($this->country_reports[$country_key])) {
151 $this->country_reports[$country_key] = [];
152 }
153 $this->country_reports[$country_key][] = $reportInstance;
154 } else {
155 // push this object as a global report
156 $this->global_reports[] = $reportInstance;
157 }
158 }
159
160 // get countries information for the reports
161 $countries = $this->getInvolvedCountries();
162
163 // check whether some country specific reports truly belong to a country
164 foreach ($this->country_reports as $ckey => $cvalue) {
165 if (!isset($countries[$ckey])) {
166 // this country does not exist, so maybe the report file was given a short beginning name. Push it to the global reports array
167 unset($this->country_reports[$ckey]);
168 $this->global_reports = array_merge($this->global_reports, $cvalue);
169 }
170 }
171
172 /**
173 * Apply sorting based on most advanced PMS reports supporting electronic transmission.
174 *
175 * @since 1.17.2 (J) - 1.7.2 (WP)
176 */
177 foreach ($this->country_reports as $ckey => &$creports) {
178 // apply sorting by priority and then by name
179 usort($creports, function($a, $b) use ($ckey) {
180 // calculate the priority based on electronic transmission functions
181 $a_reflection = new ReflectionMethod($a, 'getScopedActions');
182 $a_priority = (int) ($a_reflection->getDeclaringClass()->getName() === get_class($a));
183 $b_reflection = new ReflectionMethod($b, 'getScopedActions');
184 $b_priority = (int) ($b_reflection->getDeclaringClass()->getName() === get_class($b));
185
186 // technical priority
187 $tech_priority = $b_priority - $a_priority;
188
189 if ($tech_priority !== 0) {
190 // the higher the priority is, the higher the position will be
191 return $tech_priority;
192 }
193
194 // get report names
195 $a_name = $a->getName();
196 $b_name = $b->getName();
197
198 if ($ckey === 'IT') {
199 // static priority to Police related reports
200 $police_priority = (int) stripos($b_name, 'poli') - (int) stripos($a_name, 'poli');
201 if ($police_priority !== 0) {
202 // sort by authority
203 return $police_priority;
204 }
205 }
206
207 // sort by report name
208 return strcasecmp($a_name, $b_name);
209 });
210 }
211 // unset last reference
212 unset($creports);
213
214 // return the list of drivers
215 return [$this->global_reports, $this->country_reports];
216 }
217
218 /**
219 * Returns the associative list of the involved countries for the reports.
220 *
221 * @return array
222 */
223 public function getInvolvedCountries()
224 {
225 if ($this->countries || !$this->country_reports) {
226 return $this->countries;
227 }
228
229 $dbo = JFactory::getDbo();
230
231 // get countries information for the reports
232 $country_keys = array_keys($this->country_reports);
233 $country_keys = array_map(array($dbo, 'quote'), $country_keys);
234
235 $q = $dbo->getQuery(true);
236
237 $q->select($dbo->qn(['country_name', 'country_2_code']));
238 $q->from($dbo->qn('#__vikbooking_countries'));
239 $q->where($dbo->qn('country_2_code') . ' IN (' . implode(', ', $country_keys) . ')');
240
241 $dbo->setQuery($q);
242 $cdata = $dbo->loadAssocList();
243
244 foreach ($cdata as $cd) {
245 $this->countries[$cd['country_2_code']] = $cd['country_name'];
246 }
247
248 return $this->countries;
249 }
250
251 /**
252 * Returns the report base path.
253 *
254 * @return string the base path for the reports.
255 */
256 private function getReportBasePath()
257 {
258 return VBO_ADMIN_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'report' . DIRECTORY_SEPARATOR;
259 }
260 }
261