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/report/loader.php +260 -0 1.6.2 → 1.8.16 View file →
@@ -1,0 +1,260 @@
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 +}