3 namespace Rapsys\AirBundle\Repository
;
5 use Symfony\Component\Translation\TranslatorInterface
;
6 use Doctrine\ORM\Query\ResultSetMapping
;
11 class SessionRepository
extends \Doctrine\ORM\EntityRepository
{
13 * Find session by location, slot and date
15 * @param $location The location
16 * @param $slot The slot
17 * @param $date The datetime
19 public function findOneByLocationSlotDate($location, $slot, $date) {
21 $ret = $this->getEntityManager()
22 ->createQuery('SELECT s FROM RapsysAirBundle:Session s WHERE (s.location = :location AND s.slot = :slot AND s.date = :date)')
23 ->setParameter('location', $location)
24 ->setParameter('slot', $slot)
25 ->setParameter('date', $date)
33 * Find sessions by date period
35 * @param $period The date period
37 public function findAllByDatePeriod($period) {
39 $ret = $this->getEntityManager()
40 ->createQuery('SELECT s FROM RapsysAirBundle:Session s WHERE s.date BETWEEN :begin AND :end')
41 ->setParameter('begin', $period->getStartDate())
42 ->setParameter('end', $period->getEndDate())
50 * Find sessions by location and date period
52 * @param $location The location
53 * @param $period The date period
55 public function findAllByLocationDatePeriod($location, $period) {
57 $ret = $this->getEntityManager()
58 ->createQuery('SELECT s FROM RapsysAirBundle:Session s WHERE (s.location = :location AND s.date BETWEEN :begin AND :end)')
59 ->setParameter('location', $location)
60 ->setParameter('begin', $period->getStartDate())
61 ->setParameter('end', $period->getEndDate())
69 * Fetch sessions calendar with translated location by date period
71 * @param $translator The TranslatorInterface instance
72 * @param $period The date period
73 * @param $locationId The location id
74 * @param $sessionId The session id
75 * @param $granted The session is granted
77 public function fetchCalendarByDatePeriod(TranslatorInterface
$translator, $period, $locationId = null, $sessionId = null, $granted = false) {
79 $em = $this->getEntityManager();
82 $qs = $em->getConfiguration()->getQuoteStrategy();
83 $dp = $em->getConnection()->getDatabasePlatform();
85 //Get quoted table names
86 //XXX: this allow to make this code table name independent
88 'RapsysAirBundle:GroupUser' => $qs->getJoinTableName($em->getClassMetadata('RapsysAirBundle:User')->getAssociationMapping('groups'), $em->getClassMetadata('RapsysAirBundle:User'), $dp),
89 'RapsysAirBundle:Session' => $qs->getTableName($em->getClassMetadata('RapsysAirBundle:Session'), $dp),
90 'RapsysAirBundle:Application' => $qs->getTableName($em->getClassMetadata('RapsysAirBundle:Application'), $dp),
91 'RapsysAirBundle:Group' => $qs->getTableName($em->getClassMetadata('RapsysAirBundle:Group'), $dp),
92 'RapsysAirBundle:Location' => $qs->getTableName($em->getClassMetadata('RapsysAirBundle:Location'), $dp),
93 'RapsysAirBundle:Slot' => $qs->getTableName($em->getClassMetadata('RapsysAirBundle:Slot'), $dp),
94 'RapsysAirBundle:User' => $qs->getTableName($em->getClassMetadata('RapsysAirBundle:User'), $dp)
98 $req = 'SELECT s.id, s.date, s.location_id AS l_id, l.title AS l_title, s.slot_id AS t_id, t.title AS t_title, s.application_id AS a_id, a.user_id AS a_u_id, au.pseudonym AS a_u_pseudonym, GROUP_CONCAT(sa.user_id ORDER BY sa.user_id SEPARATOR "\n") AS as_u_id, GROUP_CONCAT(sau.pseudonym ORDER BY sa.user_id SEPARATOR "\n") AS as_u_pseudonym
99 FROM RapsysAirBundle:Session AS s
100 JOIN RapsysAirBundle:Location AS l ON (l.id = s.location_id)
101 JOIN RapsysAirBundle:Slot AS t ON (t.id = s.slot_id)
102 '.($granted?'':'LEFT ').'JOIN RapsysAirBundle:Application AS a ON (a.id = s.application_id)
103 '.($granted?'':'LEFT ').'JOIN RapsysAirBundle:User AS au ON (au.id = a.user_id)
104 LEFT JOIN RapsysAirBundle:Application AS sa ON (sa.session_id = s.id)
105 LEFT JOIN RapsysAirBundle:User AS sau ON (sau.id = sa.user_id)
106 WHERE s.date BETWEEN :begin AND :end
107 '.($locationId?'AND s.location_id = :lid':'').'
111 //Replace bundle entity name by table name
112 $req = str_replace(array_keys($tables), array_values($tables), $req);
114 //Get result set mapping instance
115 //XXX: DEBUG: see ../blog.orig/src/Rapsys/BlogBundle/Repository/ArticleRepository.php
116 $rsm = new ResultSetMapping();
119 //XXX: see vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php
120 //addScalarResult($sqlColName, $resColName, $type = 'string');
121 $rsm->addScalarResult('id', 'id', 'integer')
122 ->addScalarResult('date', 'date', 'date')
123 ->addScalarResult('t_id', 't_id', 'integer')
124 ->addScalarResult('t_title', 't_title', 'string')
125 ->addScalarResult('l_id', 'l_id', 'integer')
126 ->addScalarResult('l_title', 'l_title', 'string')
127 ->addScalarResult('a_id', 'a_id', 'integer')
128 ->addScalarResult('a_u_id', 'a_u_id', 'integer')
129 ->addScalarResult('a_u_pseudonym', 'a_u_pseudonym', 'string')
130 //XXX: is a string because of \n separator
131 ->addScalarResult('as_u_id', 'as_u_id', 'string')
132 //XXX: is a string because of \n separator
133 ->addScalarResult('as_u_pseudonym', 'as_u_pseudonym', 'string')
134 ->addIndexByScalar('id');
138 ->createNativeQuery($req, $rsm)
139 ->setParameter('begin', $period->getStartDate())
140 ->setParameter('end', $period->getEndDate())
141 ->setParameter('lid', $locationId)
150 //Iterate on each day
151 foreach($period as $date) {
152 //Init day in calendar
153 $calendar[$Ymd = $date->format('Ymd')] = [
154 'title' => $date->format('d'),
159 //Append month for first day of month
160 if ($month != $date->format('m')) {
161 $month = $date->format('m');
162 $calendar[$Ymd]['title'] .= '/'.$month;
165 if ($date->format('U') == ($today = strtotime('today'))) {
166 $calendar[$Ymd]['title'] .= '/'.$month;
167 $calendar[$Ymd]['current'] = true;
168 $calendar[$Ymd]['class'][] = 'current';
170 //Disable passed days
171 if ($date->format('U') < $today) {
172 $calendar[$Ymd]['disabled'] = true;
173 $calendar[$Ymd]['class'][] = 'disabled';
175 //Set next month days
176 if ($date->format('m') > date('m')) {
177 $calendar[$Ymd]['next'] = true;
178 $calendar[$Ymd]['class'][] = 'next';
181 //Iterate on each session to find the one of the day
182 foreach($res as $session) {
183 if (($sessionYmd = $session['date']->format('Ymd')) == $Ymd) {
184 //Count number of application
185 $count = count(explode("\n", $session['as_u_id']));
189 if (!empty($session['a_id'])) {
190 $applications = [ $session['a_u_id'] => $session['a_u_pseudonym'] ];
191 $class[] = 'granted';
192 } elseif ($count == 0) {
193 $class[] = 'orphaned';
194 } elseif ($count > 1) {
195 $class[] = 'disputed';
197 $class[] = 'pending';
200 if ($sessionId == $session['id']) {
201 $class[] = 'highlight';
204 //Check that session is not granted
205 if (empty($session['a_id'])) {
206 //Fetch pseudonyms from session applications
207 $applications = array_combine(explode("\n", $session['as_u_id']), explode("\n", $session['as_u_pseudonym']));
211 //XXX: see if we shouldn't prepend with 0 the slot and location to avoid collision ???
212 $calendar[$Ymd]['sessions'][$session['t_id'].$session['l_id']] = [
213 'id' => $session['id'],
214 'title' => $translator->trans($session['l_title']).' ('.$translator->trans($session['t_title']).')',
216 'applications' => [ 0 => $translator->trans($session['t_title']).' '.$translator->trans('at '.$session['l_title']).($count > 1?' ['.$count.']':'') ]+
$applications
222 ksort($calendar[$Ymd]['sessions']);
230 * Fetch sessions calendar with translated location by date period and user
232 * @param $translator The TranslatorInterface instance
233 * @param $period The date period
234 * @param $userId The user id
235 * @param $sessionId The session id
237 public function fetchUserCalendarByDatePeriod(TranslatorInterface
$translator, $period, $userId = null, $sessionId = null) {
239 $em = $this->getEntityManager();
242 $qs = $em->getConfiguration()->getQuoteStrategy();
243 $dp = $em->getConnection()->getDatabasePlatform();
245 //Get quoted table names
246 //XXX: this allow to make this code table name independent
248 'RapsysAirBundle:GroupUser' => $qs->getJoinTableName($em->getClassMetadata('RapsysAirBundle:User')->getAssociationMapping('groups'), $em->getClassMetadata('RapsysAirBundle:User'), $dp),
249 'RapsysAirBundle:Session' => $qs->getTableName($em->getClassMetadata('RapsysAirBundle:Session'), $dp),
250 'RapsysAirBundle:Application' => $qs->getTableName($em->getClassMetadata('RapsysAirBundle:Application'), $dp),
251 'RapsysAirBundle:Group' => $qs->getTableName($em->getClassMetadata('RapsysAirBundle:Group'), $dp),
252 'RapsysAirBundle:Location' => $qs->getTableName($em->getClassMetadata('RapsysAirBundle:Location'), $dp),
253 'RapsysAirBundle:Slot' => $qs->getTableName($em->getClassMetadata('RapsysAirBundle:Slot'), $dp),
254 'RapsysAirBundle:User' => $qs->getTableName($em->getClassMetadata('RapsysAirBundle:User'), $dp)
258 $req = 'SELECT s.id, s.date, s.location_id AS l_id, l.title AS l_title, s.slot_id AS t_id, t.title AS t_title, s.application_id AS a_id, a.user_id AS a_u_id, au.pseudonym AS a_u_pseudonym, GROUP_CONCAT(sa.user_id ORDER BY sa.user_id SEPARATOR "\n") AS as_u_id, GROUP_CONCAT(sau.pseudonym ORDER BY sa.user_id SEPARATOR "\n") AS as_u_pseudonym
259 FROM RapsysAirBundle:Session AS s
260 JOIN RapsysAirBundle:Location AS l ON (l.id = s.location_id)
261 JOIN RapsysAirBundle:Slot AS t ON (t.id = s.slot_id)
262 LEFT JOIN RapsysAirBundle:Application AS a ON (a.id = s.application_id)
263 LEFT JOIN RapsysAirBundle:User AS au ON (au.id = a.user_id)
264 LEFT JOIN RapsysAirBundle:Application AS sa ON (sa.session_id = s.id)
265 LEFT JOIN RapsysAirBundle:User AS sau ON (sau.id = sa.user_id)
266 WHERE s.date BETWEEN :begin AND :end
267 '.($userId?' AND sa.user_id = :uid':'').'
271 //Replace bundle entity name by table name
272 $req = str_replace(array_keys($tables), array_values($tables), $req);
274 //Get result set mapping instance
275 //XXX: DEBUG: see ../blog.orig/src/Rapsys/BlogBundle/Repository/ArticleRepository.php
276 $rsm = new ResultSetMapping();
279 //XXX: see vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php
280 //addScalarResult($sqlColName, $resColName, $type = 'string');
281 $rsm->addScalarResult('id', 'id', 'integer')
282 ->addScalarResult('date', 'date', 'date')
283 ->addScalarResult('t_id', 't_id', 'integer')
284 ->addScalarResult('t_title', 't_title', 'string')
285 ->addScalarResult('l_id', 'l_id', 'integer')
286 ->addScalarResult('l_title', 'l_title', 'string')
287 ->addScalarResult('a_id', 'a_id', 'integer')
288 ->addScalarResult('a_u_id', 'a_u_id', 'integer')
289 ->addScalarResult('a_u_pseudonym', 'a_u_pseudonym', 'string')
290 //XXX: is a string because of \n separator
291 ->addScalarResult('as_u_id', 'as_u_id', 'string')
292 //XXX: is a string because of \n separator
293 ->addScalarResult('as_u_pseudonym', 'as_u_pseudonym', 'string')
294 ->addIndexByScalar('id');
298 ->createNativeQuery($req, $rsm)
299 ->setParameter('begin', $period->getStartDate())
300 ->setParameter('end', $period->getEndDate())
301 ->setParameter('uid', $userId)
310 //Iterate on each day
311 foreach($period as $date) {
312 //Init day in calendar
313 $calendar[$Ymd = $date->format('Ymd')] = [
314 'title' => $date->format('d'),
319 //Append month for first day of month
320 if ($month != $date->format('m')) {
321 $month = $date->format('m');
322 $calendar[$Ymd]['title'] .= '/'.$month;
325 if ($date->format('U') == ($today = strtotime('today'))) {
326 $calendar[$Ymd]['title'] .= '/'.$month;
327 $calendar[$Ymd]['current'] = true;
328 $calendar[$Ymd]['class'][] = 'current';
330 //Disable passed days
331 if ($date->format('U') < $today) {
332 $calendar[$Ymd]['disabled'] = true;
333 $calendar[$Ymd]['class'][] = 'disabled';
335 //Set next month days
336 if ($date->format('m') > date('m')) {
337 $calendar[$Ymd]['next'] = true;
338 $calendar[$Ymd]['class'][] = 'next';
341 //Iterate on each session to find the one of the day
342 foreach($res as $session) {
343 if (($sessionYmd = $session['date']->format('Ymd')) == $Ymd) {
344 //Count number of application
345 $count = count(explode("\n", $session['as_u_id']));
349 if (!empty($session['a_id'])) {
350 $applications = [ $session['a_u_id'] => $session['a_u_pseudonym'] ];
351 if ($session['a_u_id'] == $userId) {
352 $class[] = 'granted';
354 $class[] = 'disputed';
356 } elseif ($count == 0) {
357 $class[] = 'orphaned';
358 } elseif ($count > 1) {
359 $class[] = 'disputed';
361 $class[] = 'pending';
364 if ($sessionId == $session['id']) {
365 $class[] = 'highlight';
368 //Check that session is not granted
369 if (empty($session['a_id'])) {
370 //Fetch pseudonyms from session applications
371 $applications = array_combine(explode("\n", $session['as_u_id']), explode("\n", $session['as_u_pseudonym']));
375 //XXX: see if we shouldn't prepend with 0 the slot and location to avoid collision ???
376 $calendar[$Ymd]['sessions'][$session['t_id'].$session['l_id']] = [
377 'id' => $session['id'],
378 'title' => $translator->trans($session['l_title']).' ('.$translator->trans($session['t_title']).')',
380 'applications' => [ 0 => $translator->trans($session['t_title']).' '.$translator->trans('at '.$session['l_title']).($count > 1?' ['.$count.']':'') ]+
$applications
386 ksort($calendar[$Ymd]['sessions']);