PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / trunk
VikAppointments Services Booking Calendar vtrunk
trunk 1.2.17 1.2.18 1.2.19
vikappointments / site / models / serviceslist.php
vikappointments / site / models Last commit date
allorders.php 2 years ago calendarweek.php 1 month ago cart.php 1 month ago confirmapp.php 1 month ago empaccountstat.php 2 years ago empattachser.php 2 years ago empcoupons.php 2 years ago empcustfields.php 2 years ago empeditcoupon.php 3 years ago empeditcustfield.php 3 years ago empeditlocation.php 3 years ago empeditpay.php 3 years ago empeditprofile.php 5 months ago empeditservice.php 3 years ago empeditwdays.php 3 years ago emplocations.php 2 years ago emplocwdays.php 4 years ago emplogin.php 1 month ago employeesearch.php 1 month ago employeeslist.php 1 month ago empmanres.php 2 years ago emppaylist.php 2 years ago empserviceslist.php 2 years ago empsettingsman.php 4 years ago empsubscrcart.php 4 years ago empsubscrhistory.php 2 years ago empsubscrorder.php 5 months ago empwdays.php 2 years ago index.html 4 years ago packages.php 2 years ago packagescart.php 4 years ago packagesconfirm.php 5 months ago packorders.php 2 years ago servicesearch.php 2 years ago serviceslist.php 2 years ago subscrcart.php 2 years ago subscrhistory.php 2 years ago subscrpayment.php 5 months ago
serviceslist.php
294 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
16 /**
17 * VikAppointments services list view model.
18 *
19 * @since 1.7
20 */
21 class VikAppointmentsModelServiceslist extends JModelVAP
22 {
23 /**
24 * Loads a list of services to be displayed within the
25 * services list site view.
26 *
27 * @param array $filters
28 *
29 * @return array A list of services, grouped by category.
30 */
31 public function getItems(array $filters = array())
32 {
33 $dispatcher = VAPFactory::getEventDispatcher();
34
35 $dbo = JFactory::getDbo();
36
37 $q = $dbo->getQuery(true);
38
39 $q->select('s.*');
40 $q->select(array(
41 $dbo->qn('g.id', 'group_id'),
42 $dbo->qn('g.name', 'group_name'),
43 $dbo->qn('g.description', 'group_description'),
44 ));
45 $q->select('(' . $this->getRatingQuery($dbo) . ') AS ' . $dbo->qn('ratingAVG'));
46 $q->select('(' . $this->getReviewsQuery($dbo) . ') AS ' . $dbo->qn('reviewsCount'));
47
48 $q->from($dbo->qn('#__vikappointments_service', 's'));
49 $q->leftjoin($dbo->qn('#__vikappointments_group', 'g') . ' ON ' . $dbo->qn('s.id_group') . ' = ' . $dbo->qn('g.id'));
50
51 // get only the published services
52 $q->where($dbo->qn('s.published') . ' = 1');
53
54 /**
55 * Retrieve only the services that belong to the view
56 * access level of the current user.
57 *
58 * @since 1.6
59 */
60 $levels = JFactory::getUser()->getAuthorisedViewLevels();
61
62 if ($levels)
63 {
64 $q->where($dbo->qn('s.level') . ' IN (' . implode(', ', $levels) . ')');
65 }
66
67 if (!empty($filters['id_group']))
68 {
69 // retrieve only the services that belong to the specified group
70 $q->where($dbo->qn('g.id') . ' = ' . (int) $filters['id_group']);
71 }
72
73 $now = JFactory::getDate();
74
75 // get the services with a matching end publishing date
76 $q->andWhere(array(
77 $dbo->qn('s.end_publishing') . ' IS NULL',
78 $dbo->qn('s.end_publishing') . ' = ' . $dbo->q($dbo->getNullDate()),
79 $dbo->qn('s.end_publishing') . ' > ' . $dbo->q($now->toSql()),
80 ), 'OR');
81
82 $q->order(array(
83 $dbo->qn('g.ordering') . ' ASC',
84 $dbo->qn('s.ordering') . ' ASC',
85 $dbo->qn('s.name') . ' ASC',
86 ));
87
88 /**
89 * Trigger hook to manipulate the query at runtime. Third party plugins
90 * can extend the query by applying further conditions or selecting
91 * additional data.
92 *
93 * @param mixed &$query Either a query builder or a query string.
94 * @param array $filters An array of filters.
95 *
96 * @return void
97 *
98 * @since 1.7
99 */
100 $dispatcher->trigger('onBuildServicesListQuery', array(&$q, $filters));
101
102 $dbo->setQuery($q);
103 $groups = $dbo->loadObjectList();
104
105 if ($groups)
106 {
107 $groups = $this->groupServices($groups);
108 }
109
110 // translate groups
111 $this->translate($groups);
112
113 /**
114 * Trigger hook to manipulate the query response at runtime. Third party
115 * plugins can alter the resulting list of services (and groups).
116 *
117 * @param array &$groups An array of groups and the related children.
118 * @param JModel $model The current model.
119 *
120 * @return void
121 *
122 * @since 1.7
123 */
124 $dispatcher->trigger('onBuildServicesListData', array(&$groups, $this));
125
126 return $groups;
127 }
128
129 /**
130 * Returns the inner query that should be used to calculate the
131 * average rating of the services.
132 *
133 * @param mixed $dbo The database object.
134 *
135 * @return mixed The database query.
136 */
137 protected function getRatingQuery($dbo)
138 {
139 return $dbo->getQuery(true)
140 ->select('AVG(' . $dbo->qn('re.rating') . ')')
141 ->from($dbo->qn('#__vikappointments_reviews', 're'))
142 ->where(array(
143 $dbo->qn('s.id') . ' = ' . $dbo->qn('re.id_service'),
144 $dbo->qn('re.published') . ' = 1',
145 ));
146 }
147
148 /**
149 * Returns the inner query that should be used to calculate the
150 * number of reviews of the services.
151 *
152 * @param mixed $dbo The database object.
153 *
154 * @return mixed The database query.
155 */
156 protected function getReviewsQuery($dbo)
157 {
158 return $dbo->getQuery(true)
159 ->select('COUNT(' . $dbo->qn('re.rating') . ')')
160 ->from($dbo->qn('#__vikappointments_reviews', 're'))
161 ->where(array(
162 $dbo->qn('s.id') . ' = ' . $dbo->qn('re.id_service'),
163 $dbo->qn('re.published') . ' = 1',
164 ));
165 }
166
167 /**
168 * Groups the list of services within parent blocks.
169 * The resulting list will be an array of groups, which
170 * contain the list of children services.
171 *
172 * The services with no group will be placed at the end
173 * of the list, within an empty group.
174 *
175 * @param array $services The list of services to group.
176 *
177 * @return array The grouped list.
178 */
179 protected function groupServices(array $services)
180 {
181 $groups = array();
182
183 foreach ($services as $s)
184 {
185 // if the service doesn't belong to a group,
186 // the ID will be equals to 0 (as it is casted as INT).
187 $id_group = (int) $s->id_group;
188
189 if ($id_group < 0)
190 {
191 // force to 0 for backward compatibility
192 $id_group = 0;
193 }
194
195 if (!isset($groups[$id_group]))
196 {
197 $g = new stdClass;
198 $g->id = $s->group_id;
199 $g->name = $s->group_name;
200 $g->description = $s->group_description;
201 $g->services = array();
202
203 $groups[$id_group] = $g;
204 }
205
206 // round rating to the closest .0 or .5
207 $s->rating = VikAppointments::roundHalfClosest($s->ratingAVG);
208
209 $groups[$id_group]->services[] = $s;
210 }
211
212 // check if there is the "uncategorized" group
213 if (isset($groups[0]))
214 {
215 // get the group containing the services with no group
216 $uncategorized = $groups[0];
217 // unset that group
218 unset($groups[0]);
219 // move that group at the end of the list
220 $groups[0] = $uncategorized;
221 }
222
223 // reset array keys
224 return array_values($groups);
225 }
226
227 /**
228 * Translates the groups and the services.
229 *
230 * @param array &$rows The rows to translate.
231 *
232 * @return void
233 */
234 protected function translate(&$rows)
235 {
236 /**
237 * Ignore translation in case the multilingual feature is disabled.
238 *
239 * @since 1.7.4
240 */
241 if (VAPFactory::getConfig()->getBool('ismultilang') == false)
242 {
243 return;
244 }
245
246 $langtag = JFactory::getLanguage()->getTag();
247
248 // get translator
249 $translator = VAPFactory::getTranslator();
250
251 $service_ids = array();
252 $group_ids = array();
253
254 foreach ($rows as $group)
255 {
256 $group_ids[] = $group->id;
257
258 foreach ($group->services as $service)
259 {
260 $service_ids[] = $service->id;
261 }
262 }
263
264 // pre-load services translations
265 $serLang = $translator->load('service', array_unique($service_ids), $langtag);
266 // pre-load services groups translations
267 $groupLang = $translator->load('group', array_unique($group_ids), $langtag);
268
269 foreach ($rows as $k => $group)
270 {
271 // translate group for the given language
272 $grp_tx = $groupLang->getTranslation($group->id, $langtag);
273
274 if ($grp_tx)
275 {
276 $rows[$k]->name = $grp_tx->name;
277 $rows[$k]->description = $grp_tx->description;
278 }
279
280 foreach ($group->services as $j => $service)
281 {
282 // translate service for the given language
283 $ser_tx = $serLang->getTranslation($service->id, $langtag);
284
285 if ($ser_tx)
286 {
287 $rows[$k]->services[$j]->name = $ser_tx->name;
288 $rows[$k]->services[$j]->description = $ser_tx->description;
289 }
290 }
291 }
292 }
293 }
294