/ fixed a bug in my when querying attended events
[eventlist:eventlist.git] / component / models / my.php
1 <?php
2 /**
3  * @version 1.1 $Id$
4  * @package Joomla
5  * @subpackage EventList
6  * @copyright (C) 2005 - 2009 Christoph Lukes
7  * @license GNU/GPL, see LICENSE.php
8  * EventList is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License 2
10  * as published by the Free Software Foundation.
11  * EventList is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  * You should have received a copy of the GNU General Public License
16  * along with EventList; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19
20 // no direct access
21 defined('_JEXEC') or die ('Restricted access');
22
23 jimport('joomla.application.component.model');
24 jimport('joomla.html.pagination');
25
26 /**
27  * EventList Component EventList Model
28  *
29  * @package Joomla
30  * @subpackage EventList
31  * @since               1.0
32  */
33 class EventListModelMy extends JModel
34 {
35     /**
36      * Events data array
37      *
38      * @var array
39      */
40     var $_events = null;
41
42     /**
43      * Events total
44      *
45      * @var integer
46      */
47     var $_total_events = null;
48
49     var $_venues = null;
50
51     var $_total_venues = null;
52
53     var $_attending = null;
54
55     var $_total_attending = null;
56
57     /**
58      * Pagination object
59      *
60      * @var object
61      */
62     var $_pagination_events = null;
63
64     /**
65      * Pagination object
66      *
67      * @var object
68      */
69     var $_pagination_venues = null;
70
71     /**
72      * Constructor
73      *
74      * @since 1.0
75      */
76     function __construct()
77     {
78         parent::__construct();
79
80         $app = & JFactory::getApplication();
81
82         // Get the paramaters of the active menu item
83         $params = & $app->getParams('com_eventlist');
84
85         //get the number of events from database
86         $limit = $app->getUserStateFromRequest('com_eventlist.my.limit', 'limit', $params->def('display_num', 0), 'int');
87         $limitstart_events = JRequest::getVar('limitstart_events', 0, '', 'int');
88         $limitstart_venues = JRequest::getVar('limitstart_venues', 0, '', 'int');
89         $limitstart_attending = JRequest::getVar('limitstart_attending', 0, '', 'int');
90
91         $this->setState('limit', $limit);
92         $this->setState('limitstart_events', $limitstart_events);
93         $this->setState('limitstart_venues', $limitstart_venues);
94         $this->setState('limitstart_attending', $limitstart_attending);
95
96         // Get the filter request variables
97         $this->setState('filter_order', JRequest::getCmd('filter_order', 'a.dates'));
98         $this->setState('filter_order_dir', JRequest::getCmd('filter_order_Dir', 'ASC'));
99     }
100
101     /**
102      * Method to get the Events
103      *
104      * @access public
105      * @return array
106      */
107     function & getEvents()
108     {
109         $pop = JRequest::getBool('pop');
110
111         // Lets load the content if it doesn't already exist
112         if ( empty($this->_events))
113         {
114             $query = $this->_buildQueryEvents();
115             $pagination = $this->getEventsPagination();
116
117             if ($pop)
118             {
119                 $this->_events = $this->_getList($query);
120             } else
121             {
122                 $this->_events = $this->_getList($query, $pagination->limitstart, $pagination->limit);
123             }
124                         
125                         $k = 0;
126                         $count = count($this->_events);
127                         for($i = 0; $i < $count; $i++)
128                         {
129                                 $item =& $this->_events[$i];
130                                 $item->categories = $this->getCategories($item->eventid);
131                                 
132                                 //remove events without categories (users have no access to them)
133                                 if (empty($item->categories)) {
134                                         unset($this->_events[$i]);
135                                 } 
136                                 
137                                 $k = 1 - $k;
138                         }
139         }
140
141         return $this->_events;
142     }
143
144     /**
145      * Method to get the Events user is attending
146      *
147      * @access public
148      * @return array
149      */
150     function & getAttending()
151     {
152         $pop = JRequest::getBool('pop');
153
154         // Lets load the content if it doesn't already exist
155         if ( empty($this->_attending))
156         {
157             $query = $this->_buildQueryAttending();
158             $pagination = $this->getAttendingPagination();
159
160             if ($pop)
161             {
162                 $this->_attending = $this->_getList($query);
163             } else
164             {
165                 $this->_attending = $this->_getList($query, $pagination->limitstart, $pagination->limit);
166             }
167                         
168                         $k = 0;
169                         $count = count($this->_attending);
170                         for($i = 0; $i < $count; $i++)
171                         {
172                                 $item =& $this->_attending[$i];
173                                 $item->categories = $this->getCategories($item->eventid);
174                                 
175                                 //remove events without categories (users have no access to them)
176                                 if (empty($item->categories)) {
177                                         unset($this->_attending[$i]);
178                                 } 
179                                 
180                                 $k = 1 - $k;
181                         }
182         }
183
184         return $this->_attending;
185     }
186
187     /**
188      * Method to get the Venues
189      *
190      * @access public
191      * @return array
192      */
193     function & getVenues()
194     {
195         $pop = JRequest::getBool('pop');
196
197         // Lets load the content if it doesn't already exist
198         if ( empty($this->_venues))
199         {
200             $query = $this->_buildQueryVenues();
201             $pagination = $this->getVenuesPagination();
202
203             if ($pop)
204             {
205                 $this->_venues = $this->_getList($query);
206             } else
207             {
208                 $this->_venues = $this->_getList($query, $pagination->limitstart, $pagination->limit);
209             }
210         }
211
212         return $this->_venues;
213     }
214
215     /**
216      * Total nr of events
217      *
218      * @access public
219      * @return integer
220      */
221     function getTotalEvents()
222     {
223         // Lets load the total nr if it doesn't already exist
224         if ( empty($this->_total_events))
225         {
226             $query = $this->_buildQueryEvents();
227             $this->_total_events = $this->_getListCount($query);
228         }
229
230         return $this->_total_events;
231     }
232
233     /**
234      * Total nr of events
235      *
236      * @access public
237      * @return integer
238      */
239     function getTotalAttending()
240     {
241         // Lets load the total nr if it doesn't already exist
242         if ( empty($this->_total_attending))
243         {
244             $query = $this->_buildQueryAttending();
245             $this->_total_attending = $this->_getListCount($query);
246         }
247
248         return $this->_total_attending;
249     }
250
251     /**
252      * Total nr of events
253      *
254      * @access public
255      * @return integer
256      */
257     function getTotalVenues()
258     {
259         // Lets load the total nr if it doesn't already exist
260         if ( empty($this->_total_venues))
261         {
262             $query = $this->_buildQueryVenues();
263             $this->_total_venues = $this->_getListCount($query);
264         }
265
266         return $this->_total_venues;
267     }
268
269     /**
270      * Method to get a pagination object for the events
271      *
272      * @access public
273      * @return integer
274      */
275     function getEventsPagination()
276     {
277         // Lets load the content if it doesn't already exist
278         if ( empty($this->_pagination_events))
279         {
280             jimport('joomla.html.pagination');
281             $this->_pagination_events = new MyEventsPagination($this->getTotalEvents(), $this->getState('limitstart_events'), $this->getState('limit'));
282         }
283
284         return $this->_pagination_events;
285     }
286
287     /**
288      * Method to get a pagination object for the venues
289      *
290      * @access public
291      * @return integer
292      */
293     function getVenuesPagination()
294     {
295         // Lets load the content if it doesn't already exist
296         if ( empty($this->_pagination_venues))
297         {
298             jimport('joomla.html.pagination');
299             $this->_pagination_venues = new MyVenuesPagination($this->getTotalVenues(), $this->getState('limitstart_venues'), $this->getState('limit'));
300         }
301
302         return $this->_pagination_venues;
303     }
304
305     /**
306      * Method to get a pagination object for the attending events
307      *
308      * @access public
309      * @return integer
310      */
311     function getAttendingPagination()
312     {
313         // Lets load the content if it doesn't already exist
314         if ( empty($this->_pagination_attending))
315         {
316             jimport('joomla.html.pagination');
317             $this->_pagination_attending = new MyAttendingPagination($this->getTotalAttending(), $this->getState('limitstart_attending'), $this->getState('limit'));
318         }
319
320         return $this->_pagination_attending;
321     }
322
323     /**
324      * Build the query
325      *
326      * @access private
327      * @return string
328      */
329     function _buildQueryEvents()
330     {
331         // Get the WHERE and ORDER BY clauses for the query
332         $where = $this->_buildEventListWhere();
333         $orderby = $this->_buildEventListOrderBy();
334
335         //Get Events from Database
336                 $query = 'SELECT DISTINCT a.id as eventid, a.dates, a.enddates, a.times, a.endtimes, a.title, a.created, a.locid, a.datdescription,'
337                                 . ' l.venue, l.city, l.state, l.url,'
338                                 . ' CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(\':\', a.id, a.alias) ELSE a.id END as slug,'
339                                 . ' CASE WHEN CHAR_LENGTH(l.alias) THEN CONCAT_WS(\':\', a.locid, l.alias) ELSE a.locid END as venueslug'
340                                 . ' FROM #__eventlist_events AS a'
341                                 . ' LEFT JOIN #__eventlist_venues AS l ON l.id = a.locid'
342                                 . $where
343                                 . $orderby
344                                 ;
345
346         return $query;
347     }
348
349     /**
350      * Build the query
351      *
352      * @access private
353      * @return string
354      */
355     function _buildQueryAttending()
356     {
357         // Get the WHERE and ORDER BY clauses for the query
358         $where = $this->_buildEventListAttendingWhere();
359         $orderby = $this->_buildEventListOrderBy();
360
361         //Get Events from Database
362         $query = 'SELECT a.id AS eventid, a.dates, a.enddates, a.times, a.endtimes, a.title, a.created, a.locid, a.datdescription, a.published, '
363         .' l.id, l.venue, l.city, l.state, l.url,'
364         .' CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(\':\', a.id, a.alias) ELSE a.id END as slug,'
365         .' CASE WHEN CHAR_LENGTH(l.alias) THEN CONCAT_WS(\':\', a.locid, l.alias) ELSE a.locid END as venueslug'
366         .' FROM #__eventlist_events AS a'
367         .' INNER JOIN #__eventlist_register AS r ON r.event = a.id'
368         .' LEFT JOIN #__eventlist_venues AS l ON l.id = a.locid'
369         .$where
370         .$orderby
371         ;
372
373         return $query;
374     }
375
376     /**
377      * Build the query
378      *
379      * @access private
380      * @return string
381      */
382     function _buildQueryVenues()
383     {
384         $user = & JFactory::getUser();
385         //Get Events from Database
386         $query = 'SELECT l.id, l.venue, l.city, l.state, l.url, l.published, '
387         .' CASE WHEN CHAR_LENGTH(l.alias) THEN CONCAT_WS(\':\', l.id, l.alias) ELSE l.id END as venueslug'
388         .' FROM #__eventlist_venues AS l '
389         .' WHERE l.created_by = '.$this->_db->Quote($user->id)
390         .' ORDER BY l.venue ASC '
391         ;
392
393         return $query;
394     }
395
396     /**
397      * Build the order clause
398      *
399      * @access private
400      * @return string
401      */
402     function _buildEventListOrderBy()
403     {
404         $filter_order = $this->getState('filter_order');
405         $filter_order_dir = $this->getState('filter_order_dir');
406
407         $orderby = ' ORDER BY '.$filter_order.' '.$filter_order_dir.', a.dates, a.times';
408
409         return $orderby;
410     }
411
412     /**
413      * Build the where clause
414      *
415      * @access private
416      * @return string
417      */
418     function _buildEventListWhere()
419     {
420         $app = & JFactory::getApplication();
421
422         $user = & JFactory::getUser();
423         $gid = (int)$user->get('aid');
424
425         // Get the paramaters of the active menu item
426         $params = & $app->getParams();
427
428         $task = JRequest::getWord('task');
429
430         // First thing we need to do is to select only needed events
431         if ($task == 'archive')
432         {
433             $where = ' WHERE a.published = -1';
434         } else
435         {
436             $where = ' WHERE a.published = 1';
437         }
438
439         // then if the user is the owner of the event
440         $where .= ' AND a.created_by = '.$this->_db->Quote($user->id);
441
442         // Second is to only select events assigned to category the user has access to
443       //  $where .= ' AND c.access <= '.$gid;
444
445         /*
446          * If we have a filter, and this is enabled... lets tack the AND clause
447          * for the filter onto the WHERE clause of the item query.
448          */
449         if ($params->get('filter'))
450         {
451             $filter = JRequest::getString('filter', '', 'request');
452             $filter_type = JRequest::getWord('filter_type', '', 'request');
453
454             if ($filter)
455             {
456                 // clean filter variables
457                 $filter = JString::strtolower($filter);
458                 $filter = $this->_db->Quote('%'.$this->_db->getEscaped($filter, true).'%', false);
459                 $filter_type = JString::strtolower($filter_type);
460
461                 switch($filter_type)
462                 {
463                     case 'title':
464                         $where .= ' AND LOWER( a.title ) LIKE '.$filter;
465                         break;
466
467                     case 'venue':
468                         $where .= ' AND LOWER( l.venue ) LIKE '.$filter;
469                         break;
470
471                     case 'city':
472                         $where .= ' AND LOWER( l.city ) LIKE '.$filter;
473                         break;
474 /*
475                     case 'type':
476                         $where .= ' AND LOWER( c.catname ) LIKE '.$filter;
477                         break;
478 */
479                 }
480             }
481         }
482         return $where;
483     }
484
485     /**
486      * Build the where clause
487      *
488      * @access private
489      * @return string
490      */
491     function _buildEventListAttendingWhere()
492     {
493         $app = & JFactory::getApplication();
494
495         $user = & JFactory::getUser();
496                 $nulldate = '0000-00-00';
497
498         // Get the paramaters of the active menu item
499         $params = & $app->getParams();
500
501         $task = JRequest::getWord('task');
502
503         // First thing we need to do is to select only needed events
504         if ($task == 'archive')
505         {
506             $where = ' WHERE a.published = -1';
507         } else
508         {
509             $where = ' WHERE a.published = 1';
510         }
511                 
512                 //limit output so only future events the user attends will be shown
513                 if ($params->get('filtermyregs')) {
514                         $where .= ' AND DATE_SUB(NOW(), INTERVAL '.(int)$params->get('myregspast').' DAY) < (IF (a.enddates <> '.$nulldate.', a.enddates, a.dates))';
515                 }
516                 
517         // then if the user is attending the event
518         $where .= ' AND r.uid = '.$this->_db->Quote($user->id);
519
520         return $where;
521     }
522         
523         function getCategories($id)
524         {
525                 $user           = & JFactory::getUser();
526                 $gid            = (int) $user->get('aid');
527                 
528                 $query = 'SELECT DISTINCT c.id, c.catname, c.access, c.checked_out AS cchecked_out,'
529                                 . ' CASE WHEN CHAR_LENGTH(c.alias) THEN CONCAT_WS(\':\', c.id, c.alias) ELSE c.id END as catslug'
530                                 . ' FROM #__eventlist_categories AS c'
531                                 . ' LEFT JOIN #__eventlist_cats_event_relations AS rel ON rel.catid = c.id'
532                                 . ' WHERE rel.itemid = '.(int)$id
533                                 . ' AND c.published = 1'
534                                 . ' AND c.access  <= '.$gid;
535                                 ;
536         
537                 $this->_db->setQuery( $query );
538
539                 $this->_cats = $this->_db->loadObjectList();
540
541                 return $this->_cats;
542         }
543 }
544
545 class MyEventsPagination extends JPagination
546 {
547     /**
548      * Create and return the pagination data object
549      *
550      * @access  public
551      * @return  object  Pagination data object
552      * @since 1.5
553      */
554     function _buildDataObject()
555     {
556         // Initialize variables
557         $data = new stdClass ();
558
559         $data->all = new JPaginationObject(JText::_('View All'));
560         if (!$this->_viewall)
561         {
562             $data->all->base = '0';
563             $data->all->link = JRoute::_("&limitstart_events=");
564         }
565
566         // Set the start and previous data objects
567         $data->start = new JPaginationObject(JText::_('Start'));
568         $data->previous = new JPaginationObject(JText::_('Prev'));
569
570         if ($this->get('pages.current') > 1)
571         {
572             $page = ($this->get('pages.current')-2)*$this->limit;
573
574             $page = $page == 0?'':$page; //set the empty for removal from route
575
576             $data->start->base = '0';
577             $data->start->link = JRoute::_("&limitstart_events=");
578             $data->previous->base = $page;
579             $data->previous->link = JRoute::_("&limitstart_events=".$page);
580         }
581
582         // Set the next and end data objects
583         $data->next = new JPaginationObject(JText::_('Next'));
584         $data->end = new JPaginationObject(JText::_('End'));
585
586         if ($this->get('pages.current') < $this->get('pages.total'))
587         {
588             $next = $this->get('pages.current')*$this->limit;
589             $end = ($this->get('pages.total')-1)*$this->limit;
590
591             $data->next->base = $next;
592             $data->next->link = JRoute::_("&limitstart_events=".$next);
593             $data->end->base = $end;
594             $data->end->link = JRoute::_("&limitstart_events=".$end);
595         }
596
597         $data->pages = array ();
598         $stop = $this->get('pages.stop');
599         for ($i = $this->get('pages.start'); $i <= $stop; $i++)
600         {
601             $offset = ($i-1)*$this->limit;
602
603             $offset = $offset == 0?'':$offset; //set the empty for removal from route
604
605             $data->pages[$i] = new JPaginationObject($i);
606             if ($i != $this->get('pages.current') || $this->_viewall)
607             {
608                 $data->pages[$i]->base = $offset;
609                 $data->pages[$i]->link = JRoute::_("&limitstart_events=".$offset);
610             }
611         }
612         return $data;
613     }
614
615     function _list_footer($list)
616     {
617         // Initialize variables
618         $html = "<div class=\"list-footer\">\n";
619
620         $html .= "\n<div class=\"limit\">".JText::_('Display Num').$list['limitfield']."</div>";
621         $html .= $list['pageslinks'];
622         $html .= "\n<div class=\"counter\">".$list['pagescounter']."</div>";
623
624         $html .= "\n<input type=\"hidden\" name=\"limitstart_events\" value=\"".$list['limitstart']."\" />";
625         $html .= "\n</div>";
626
627         return $html;
628     }
629
630 }
631
632
633 class MyAttendingPagination extends JPagination
634 {
635     /**
636      * Create and return the pagination data object
637      *
638      * @access  public
639      * @return  object  Pagination data object
640      * @since 1.5
641      */
642     function _buildDataObject()
643     {
644         // Initialize variables
645         $data = new stdClass ();
646
647         $data->all = new JPaginationObject(JText::_('View All'));
648         if (!$this->_viewall)
649         {
650             $data->all->base = '0';
651             $data->all->link = JRoute::_("&limitstart_attending=");
652         }
653
654         // Set the start and previous data objects
655         $data->start = new JPaginationObject(JText::_('Start'));
656         $data->previous = new JPaginationObject(JText::_('Prev'));
657
658         if ($this->get('pages.current') > 1)
659         {
660             $page = ($this->get('pages.current')-2)*$this->limit;
661
662             $page = $page == 0?'':$page; //set the empty for removal from route
663
664             $data->start->base = '0';
665             $data->start->link = JRoute::_("&limitstart_attending=");
666             $data->previous->base = $page;
667             $data->previous->link = JRoute::_("&limitstart_attending=".$page);
668         }
669
670         // Set the next and end data objects
671         $data->next = new JPaginationObject(JText::_('Next'));
672         $data->end = new JPaginationObject(JText::_('End'));
673
674         if ($this->get('pages.current') < $this->get('pages.total'))
675         {
676             $next = $this->get('pages.current')*$this->limit;
677             $end = ($this->get('pages.total')-1)*$this->limit;
678
679             $data->next->base = $next;
680             $data->next->link = JRoute::_("&limitstart_attending=".$next);
681             $data->end->base = $end;
682             $data->end->link = JRoute::_("&limitstart_attending=".$end);
683         }
684
685         $data->pages = array ();
686         $stop = $this->get('pages.stop');
687         for ($i = $this->get('pages.start'); $i <= $stop; $i++)
688         {
689             $offset = ($i-1)*$this->limit;
690
691             $offset = $offset == 0?'':$offset; //set the empty for removal from route
692
693             $data->pages[$i] = new JPaginationObject($i);
694             if ($i != $this->get('pages.current') || $this->_viewall)
695             {
696                 $data->pages[$i]->base = $offset;
697                 $data->pages[$i]->link = JRoute::_("&limitstart_attending=".$offset);
698             }
699         }
700         return $data;
701     }
702
703     function _list_footer($list)
704     {
705         // Initialize variables
706         $html = "<div class=\"list-footer\">\n";
707
708         $html .= "\n<div class=\"limit\">".JText::_('Display Num').$list['limitfield']."</div>";
709         $html .= $list['pageslinks'];
710         $html .= "\n<div class=\"counter\">".$list['pagescounter']."</div>";
711
712         $html .= "\n<input type=\"hidden\" name=\"limitstart_attending\" value=\"".$list['limitstart']."\" />";
713         $html .= "\n</div>";
714
715         return $html;
716     }
717
718 }
719
720 class MyVenuesPagination extends JPagination
721 {
722     /**
723      * Create and return the pagination data object
724      *
725      * @access  public
726      * @return  object  Pagination data object
727      * @since 1.5
728      */
729     function _buildDataObject()
730     {
731         // Initialize variables
732         $data = new stdClass ();
733
734         $data->all = new JPaginationObject(JText::_('View All'));
735         if (!$this->_viewall)
736         {
737             $data->all->base = '0';
738             $data->all->link = JRoute::_("&limitstart_venues=");
739         }
740
741         // Set the start and previous data objects
742         $data->start = new JPaginationObject(JText::_('Start'));
743         $data->previous = new JPaginationObject(JText::_('Prev'));
744
745         if ($this->get('pages.current') > 1)
746         {
747             $page = ($this->get('pages.current')-2)*$this->limit;
748
749             $page = $page == 0?'':$page; //set the empty for removal from route
750
751             $data->start->base = '0';
752             $data->start->link = JRoute::_("&limitstart_venues=");
753             $data->previous->base = $page;
754             $data->previous->link = JRoute::_("&limitstart_venues=".$page);
755         }
756
757         // Set the next and end data objects
758         $data->next = new JPaginationObject(JText::_('Next'));
759         $data->end = new JPaginationObject(JText::_('End'));
760
761         if ($this->get('pages.current') < $this->get('pages.total'))
762         {
763             $next = $this->get('pages.current')*$this->limit;
764             $end = ($this->get('pages.total')-1)*$this->limit;
765
766             $data->next->base = $next;
767             $data->next->link = JRoute::_("&limitstart_venues=".$next);
768             $data->end->base = $end;
769             $data->end->link = JRoute::_("&limitstart_venues=".$end);
770         }
771
772         $data->pages = array ();
773         $stop = $this->get('pages.stop');
774         for ($i = $this->get('pages.start'); $i <= $stop; $i++)
775         {
776             $offset = ($i-1)*$this->limit;
777
778             $offset = $offset == 0?'':$offset; //set the empty for removal from route
779
780             $data->pages[$i] = new JPaginationObject($i);
781             if ($i != $this->get('pages.current') || $this->_viewall)
782             {
783                 $data->pages[$i]->base = $offset;
784                 $data->pages[$i]->link = JRoute::_("&limitstart_venues=".$offset);
785             }
786         }
787         return $data;
788     }
789
790     function _list_footer($list)
791     {
792         // Initialize variables
793         $html = "<div class=\"list-footer\">\n";
794
795         $html .= "\n<div class=\"limit\">".JText::_('Display Num').$list['limitfield']."</div>";
796         $html .= $list['pageslinks'];
797         $html .= "\n<div class=\"counter\">".$list['pagescounter']."</div>";
798
799         $html .= "\n<input type=\"hidden\" name=\"limitstart_venues\" value=\"".$list['limitstart']."\" />";
800         $html .= "\n</div>";
801
802         return $html;
803     }
804 }
805 ?>