Exemplo n.º 1
0
 public static function iCalMailGenerator($row, $params, $ics_method = "PUBLISH")
 {
     if ($ics_method == "CANCEL") {
         $status = "CANCELLED";
     }
     if (JFile::exists(JPATH_SITE . "/plugins/jevents/jevnotify/")) {
         //If using JEvents notify plugin we need to load it for the processing of data.
         JLoader::register('JEVNotifyHelper', JPATH_SITE . "/plugins/jevents/jevnotify/helper.php");
     }
     $icalEvents = array($row);
     if (ob_get_contents()) {
         ob_end_clean();
     }
     $html = "";
     $params = JComponentHelper::getParams("com_jevents");
     if ($params->get('outlook2003icalexport')) {
         $html .= "BEGIN:VCALENDAR\r\nPRODID:JEvents 3.1 for Joomla//EN\r\n";
     } else {
         $html .= "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:JEvents 3.1 for Joomla//EN\r\n";
     }
     $html .= "CALSCALE:GREGORIAN\r\nMETHOD:" . $ics_method . "\r\n";
     if (isset($status)) {
         $html .= "STATUS:" . $status . "\r\n";
     }
     if (!empty($icalEvents)) {
         ob_start();
         $tzid = self::vtimezone($icalEvents);
         $html .= ob_get_clean();
         // Build Exceptions dataset - all done in big batches to save multiple queries
         $exceptiondata = array();
         $ids = array();
         foreach ($icalEvents as $a) {
             $ids[] = $a->ev_id();
             if (count($ids) > 100) {
                 $db = JFactory::getDBO();
                 $db->setQuery("SELECT * FROM #__jevents_exception where eventid IN (" . implode(",", $ids) . ")");
                 $rows = $db->loadObjectList();
                 foreach ($rows as $row) {
                     if (!isset($exceptiondata[$row->eventid])) {
                         $exceptiondata[$row->eventid] = array();
                     }
                     $exceptiondata[$row->eventid][$row->rp_id] = $row;
                 }
                 $ids = array();
             }
         }
         // mop up the last ones
         if (count($ids) > 0) {
             $db = JFactory::getDBO();
             $db->setQuery("SELECT * FROM #__jevents_exception where eventid IN (" . implode(",", $ids) . ")");
             $rows = $db->loadObjectList();
             foreach ($rows as $row) {
                 if (!isset($exceptiondata[$row->eventid])) {
                     $exceptiondata[$row->eventid] = array();
                 }
                 $exceptiondata[$row->eventid][$row->rp_id] = $row;
             }
         }
         // make sure the array is now reindexed for the sake of the plugins!
         $icalEvents = array_values($icalEvents);
         // Call plugin on each event
         $dispatcher = JDispatcher::getInstance();
         ob_start();
         JEVHelper::onDisplayCustomFieldsMultiRow($icalEvents);
         ob_end_clean();
         foreach ($icalEvents as $a) {
             // if event has repetitions I must find the first one to confirm the dates
             if ($a->hasrepetition()) {
                 $a = $a->getOriginalFirstRepeat();
             }
             if (!$a) {
                 continue;
             }
             $html .= "BEGIN:VEVENT\r\n";
             $html .= "UID:" . $a->uid() . "\r\n";
             $html .= "CATEGORIES:" . $a->catname() . "\r\n";
             if (!empty($a->_class)) {
                 $html .= "CLASS:" . $a->_class . "\r\n";
             }
             $html .= "SUMMARY:" . $a->title() . "\r\n";
             if ($a->location() != "") {
                 if (!is_numeric($a->location())) {
                     $html .= "LOCATION:" . self::wraplines(self::replacetags($a->location())) . "\r\n";
                 } else {
                     if (isset($a->_loc_title)) {
                         $html .= "LOCATION:" . self::wraplines(self::replacetags($a->_loc_title)) . "\r\n";
                     } else {
                         $html .= "LOCATION:" . self::wraplines(self::replacetags($a->location())) . "\r\n";
                     }
                 }
             }
             // We Need to wrap this according to the specs
             /* $html .= "DESCRIPTION:".preg_replace("'<[\/\!]*?[^<>]*?>'si","",preg_replace("/\n|\r\n|\r$/","",$a->content()))."\n"; */
             $html .= self::setDescription(strip_tags($a->content())) . "\r\n";
             if ($a->hasContactInfo()) {
                 $html .= "CONTACT:" . self::replacetags($a->contact_info()) . "\r\n";
             }
             if ($a->hasExtraInfo()) {
                 $html .= "X-EXTRAINFO:" . self::wraplines(self::replacetags($a->_extra_info)) . "\r\n";
             }
             $user = JFactory::getUser($a->created_by());
             $html .= "ORGANIZER;CN=" . $user->name . ":MAILTO:" . $user->email . "\r\n";
             $alldayprefix = "";
             // No doing true timezones!
             if ($tzid == "" && is_callable("date_default_timezone_set")) {
                 // UTC!
                 $start = $a->getUnixStartTime();
                 $end = $a->getUnixEndTime();
                 // in case the first repeat has been changed
                 if (array_key_exists($a->_eventid, $exceptiondata) && array_key_exists($a->rp_id(), $exceptiondata[$a->_eventid])) {
                     $start = JevDate::strtotime($exceptiondata[$a->_eventid][$a->rp_id()]->oldstartrepeat);
                 }
                 // Change timezone to UTC
                 $current_timezone = date_default_timezone_get();
                 // If all day event then don't show the start time or end time either
                 if ($a->alldayevent()) {
                     $alldayprefix = ";VALUE=DATE";
                     $startformat = "%Y%m%d";
                     $endformat = "%Y%m%d";
                     // add 10 seconds to make sure its not midnight the previous night
                     $start += 10;
                     $end += 10;
                 } else {
                     date_default_timezone_set("UTC");
                     $startformat = "%Y%m%dT%H%M%SZ";
                     $endformat = "%Y%m%dT%H%M%SZ";
                 }
                 // Do not use JevDate version since this sets timezone to config value!
                 $start = strftime($startformat, $start);
                 $end = strftime($endformat, $end);
                 $stamptime = strftime("%Y%m%dT%H%M%SZ", time());
                 // Change back
                 date_default_timezone_set($current_timezone);
             } else {
                 $start = $a->getUnixStartTime();
                 $end = $a->getUnixEndTime();
                 // If all day event then don't show the start time or end time either
                 if ($a->alldayevent()) {
                     $alldayprefix = ";VALUE=DATE";
                     $startformat = "%Y%m%d";
                     $endformat = "%Y%m%d";
                     // add 10 seconds to make sure its not midnight the previous night
                     $start += 10;
                     $end += 10;
                 } else {
                     $startformat = "%Y%m%dT%H%M%S";
                     $endformat = "%Y%m%dT%H%M%S";
                 }
                 $start = JevDate::strftime($startformat, $start);
                 $end = JevDate::strftime($endformat, $end);
                 if (is_callable("date_default_timezone_set")) {
                     date_default_timezone_set("UTC");
                     $stamptime = JevDate::strftime("%Y%m%dT%H%M%SZ", time());
                     // Change back
                     date_default_timezone_set($current_timezone);
                 } else {
                     $stamptime = JevDate::strftime("%Y%m%dT%H%M%SZ", time());
                 }
                 // in case the first repeat is changed
                 if (array_key_exists($a->_eventid, $exceptiondata) && array_key_exists($a->rp_id(), $exceptiondata[$a->_eventid])) {
                     $start = JevDate::strftime($startformat, JevDate::strtotime($exceptiondata[$a->_eventid][$a->rp_id()]->oldstartrepeat));
                 }
             }
             $html .= "DTSTAMP:" . $stamptime . "\r\n";
             $html .= "DTSTART{$tzid}{$alldayprefix}:" . $start . "\r\n";
             // events with no end time don't give a DTEND
             if (!$a->noendtime()) {
                 $html .= "DTEND{$tzid}{$alldayprefix}:" . $end . "\r\n";
             }
             $html .= "SEQUENCE:" . $a->_sequence . "\r\n";
             if ($a->hasrepetition()) {
                 $html .= 'RRULE:';
                 // TODO MAKE SURE COMPAIBLE COMBINATIONS
                 $html .= 'FREQ=' . $a->_freq;
                 if ($a->_until != "" && $a->_until != 0) {
                     // Do not use JevDate version since this sets timezone to config value!
                     // GOOGLE HAS A PROBLEM WITH 235959!!!
                     //$html .= ';UNTIL=' . strftime("%Y%m%dT235959Z", $a->_until);
                     $html .= ';UNTIL=' . strftime("%Y%m%dT000000Z", $a->_until + 86400);
                 } else {
                     if ($a->_count != "") {
                         $html .= ';COUNT=' . $a->_count;
                     }
                 }
                 if ($a->_rinterval != "") {
                     $html .= ';INTERVAL=' . $a->_rinterval;
                 }
                 if ($a->_freq == "DAILY") {
                 } else {
                     if ($a->_freq == "WEEKLY") {
                         if ($a->_byday != "") {
                             $html .= ';BYDAY=' . $a->_byday;
                         }
                     } else {
                         if ($a->_freq == "MONTHLY") {
                             if ($a->_bymonthday != "") {
                                 $html .= ';BYMONTHDAY=' . $a->_bymonthday;
                                 if ($a->_byweekno != "") {
                                     $html .= ';BYWEEKNO=' . $a->_byweekno;
                                 }
                             } else {
                                 if ($a->_byday != "") {
                                     $html .= ';BYDAY=' . $a->_byday;
                                     if ($a->_byweekno != "") {
                                         $html .= ';BYWEEKNO=' . $a->_byweekno;
                                     }
                                 }
                             }
                         } else {
                             if ($a->_freq == "YEARLY") {
                                 if ($a->_byyearday != "") {
                                     $html .= ';BYYEARDAY=' . $a->_byyearday;
                                 }
                             }
                         }
                     }
                 }
                 $html .= "\r\n";
             }
             // Now handle Exceptions
             $exceptions = array();
             if (array_key_exists($a->ev_id(), $exceptiondata)) {
                 $exceptions = $exceptiondata[$a->ev_id()];
             }
             $deletes = array();
             $changed = array();
             $changedexceptions = array();
             if (count($exceptions) > 0) {
                 foreach ($exceptions as $exception) {
                     if ($exception->exception_type == 0) {
                         $exceptiondate = JevDate::strtotime($exception->startrepeat);
                         // No doing true timezones!
                         if ($tzid == "" && is_callable("date_default_timezone_set")) {
                             // Change timezone to UTC
                             $current_timezone = date_default_timezone_get();
                             date_default_timezone_set("UTC");
                             // Do not use JevDate version since this sets timezone to config value!
                             $deletes[] = strftime("%Y%m%dT%H%M%SZ", $exceptiondate);
                             // Change back
                             date_default_timezone_set($current_timezone);
                         } else {
                             $deletes[] = JevDate::strftime("%Y%m%dT%H%M%S", $exceptiondate);
                         }
                     } else {
                         $changed[] = $exception->rp_id;
                         $changedexceptions[$exception->rp_id] = $exception;
                     }
                 }
                 if (count($deletes) > 0) {
                     $html .= "EXDATE{$tzid}:" . self::wraplines(implode(",", $deletes)) . "\r\n";
                 }
             }
             $html .= "TRANSP:OPAQUE\r\n";
             $html .= "END:VEVENT\r\n";
             // Ok if it's a request, then it's a change. No need the include the master event for the iCal
             // Simple lets, clear her.
             if ($ics_method != "REQUEST" && $a->hasrepetition()) {
                 $html = "";
             }
             $changedrows = array();
             if (count($changed) > 0 && $changed[0] != 0) {
                 foreach ($changed as $rpid) {
                     $helper = new JEVNotifyHelper();
                     if (JPATH_SITE . "/plugins/jevents/jevnotify/") {
                         $a = $helper->getEventData($rpid, "icaldb", 0, 0, 0, $a->uid());
                     } else {
                         // No usage yet.
                         // Likely to update helper function when moving over RSVP Pro Generated iCals.
                         $a = $helper->getEventData($rpid, "icaldb", 0, 0, 0, $a->uid());
                     }
                     if ($a && isset($a["row"])) {
                         $a = $a["row"];
                         $changedrows[] = $a;
                     }
                 }
                 ob_start();
                 $dispatcher->trigger('onDisplayCustomFieldsMultiRow', array(&$changedrows));
                 ob_end_clean();
                 foreach ($changedrows as $a) {
                     $html .= "BEGIN:VEVENT\r\n";
                     $html .= "UID:" . $a->uid() . "\r\n";
                     $html .= "CATEGORIES:" . $a->catname() . "\r\n";
                     if (!empty($a->_class)) {
                         $html .= "CLASS:" . $a->_class . "\r\n";
                     }
                     $html .= "SUMMARY:" . $a->title() . "\r\n";
                     if ($a->location() != "") {
                         $html .= "LOCATION:" . self::wraplines(self::replacetags($a->location())) . "\r\n";
                     }
                     // We Need to wrap this according to the specs
                     $html .= self::setDescription(strip_tags($a->content())) . "\r\n";
                     if ($a->hasContactInfo()) {
                         $html .= "CONTACT:" . self::replacetags($a->contact_info()) . "\r\n";
                     }
                     if ($a->hasExtraInfo()) {
                         $html .= "X-EXTRAINFO:" . self::wraplines(self::replacetags($a->_extra_info));
                     }
                     $html .= "\r\n";
                     $user = JFactory::getUser($a->created_by());
                     $html .= "ORGANIZER;CN=" . $user->name . ":MAILTO:" . $user->email . "\r\n";
                     $exception = $changedexceptions[$rpid];
                     $originalstart = JevDate::strtotime($exception->oldstartrepeat);
                     $chstart = $a->getUnixStartTime();
                     $chend = $a->getUnixEndTime();
                     // No doing true timezones!
                     if ($tzid == "" && is_callable("date_default_timezone_set")) {
                         // UTC!
                         // Change timezone to UTC
                         $current_timezone = date_default_timezone_get();
                         date_default_timezone_set("UTC");
                         // Do not use JevDate version since this sets timezone to config value!
                         $chstart = strftime("%Y%m%dT%H%M%SZ", $chstart);
                         $chend = strftime("%Y%m%dT%H%M%SZ", $chend);
                         $stamptime = strftime("%Y%m%dT%H%M%SZ", time());
                         $originalstart = strftime("%Y%m%dT%H%M%SZ", $originalstart);
                         // Change back
                         date_default_timezone_set($current_timezone);
                     } else {
                         $chstart = JevDate::strftime("%Y%m%dT%H%M%S", $chstart);
                         $chend = JevDate::strftime("%Y%m%dT%H%M%S", $chend);
                         $stamptime = JevDate::strftime("%Y%m%dT%H%M%S", time());
                         $originalstart = JevDate::strftime("%Y%m%dT%H%M%S", $originalstart);
                     }
                     $html .= "DTSTAMP{$tzid}:" . $stamptime . "\r\n";
                     $html .= "DTSTART{$tzid}:" . $chstart . "\r\n";
                     $html .= "DTEND{$tzid}:" . $chend . "\r\n";
                     $html .= "RECURRENCE-ID{$tzid}:" . $originalstart . "\r\n";
                     $html .= "SEQUENCE:" . $a->_sequence . "\r\n";
                     $html .= "TRANSP:OPAQUE\r\n";
                     $html .= "END:VEVENT\r\n";
                 }
             }
         }
     }
     $html .= "END:VCALENDAR\r\n";
     return $html;
 }
Exemplo n.º 2
0
     $db = JFactory::getDBO();
     $db->setQuery("SELECT * FROM #__jevents_exception where eventid IN (" . implode(",", $ids) . ")");
     $rows = $db->loadObjectList();
     foreach ($rows as $row) {
         if (!isset($exceptiondata[$row->eventid])) {
             $exceptiondata[$row->eventid] = array();
         }
         $exceptiondata[$row->eventid][$row->rp_id] = $row;
     }
 }
 // make sure the array is now reindexed for the sake of the plugins!
 $this->icalEvents = array_values($this->icalEvents);
 // Call plugin on each event
 $dispatcher = JEventDispatcher::getInstance();
 ob_start();
 JEVHelper::onDisplayCustomFieldsMultiRow($this->icalEvents);
 ob_end_clean();
 foreach ($this->icalEvents as $a) {
     // if event has repetitions I must find the first one to confirm the dates
     if ($a->hasrepetition() && $this->withrepeats) {
         $a = $a->getOriginalFirstRepeat();
     }
     if (!$a) {
         continue;
     }
     // Fix for end time of first repeat if its an exception
     if (array_key_exists($a->ev_id(), $exceptiondata) && array_key_exists($a->rp_id(), $exceptiondata[$a->ev_id()])) {
         $exception = $exceptiondata[$a->ev_id()][$a->rp_id()];
         // if its the first repeat that has had its end time changes we have not stored this data so need to determine it again
         if ($exception->startrepeat == $exception->oldstartrepeat && $exception->exception_type == 1) {
             // look for repeats that are not exceptions
Exemplo n.º 3
0
 function listEventsByKeyword($keyword, $order, &$limit, &$limitstart, &$total, $useRegX = false)
 {
     $user = JFactory::getUser();
     $adminuser = JEVHelper::isAdminUser($user);
     $db = JFactory::getDBO();
     $keyword = $db->escape($keyword, true);
     // Use alternative data source
     $rows = array();
     $skipJEvents = false;
     $dispatcher = JDispatcher::getInstance();
     $dispatcher->trigger('fetchListEventsByKeyword', array(&$skipJEvents, &$rows, $keyword, $order, &$limit, &$limitstart, &$total, $useRegX));
     if ($skipJEvents) {
         return $rows;
     }
     $rows_per_page = $limit;
     if (empty($limitstart) || !$limitstart) {
         $limitstart = 0;
     }
     $limitstring = "";
     if ($rows_per_page > 0) {
         $limitstring = "LIMIT {$limitstart}, {$rows_per_page}";
     }
     $where = "";
     $having = "";
     if (!JRequest::getInt('showpast', 0)) {
         $datenow = JevDate::getDate("-12 hours");
         $having = " AND rpt.endrepeat>'" . $datenow->toSql() . "'";
     }
     $total = 0;
     // process the new plugins
     // get extra data and conditionality from plugins
     $extrawhere = array();
     $extrajoin = array();
     $extrafields = "";
     // must have comma prefix
     $needsgroup = false;
     $filterarray = array("published");
     // If there are extra filters from the module then apply them now
     $reg = JFactory::getConfig();
     $modparams = $reg->get("jev.modparams", false);
     if ($modparams && $modparams->get("extrafilters", false)) {
         $filterarray = array_merge($filterarray, explode(",", $modparams->get("extrafilters", false)));
     }
     $filters = jevFilterProcessing::getInstance($filterarray);
     $filters->setWhereJoin($extrawhere, $extrajoin);
     $needsgroup = $filters->needsGroupBy();
     JPluginHelper::importPlugin('jevents');
     $dispatcher = JDispatcher::getInstance();
     $dispatcher->trigger('onListIcalEvents', array(&$extrafields, &$extratables, &$extrawhere, &$extrajoin, &$needsgroup));
     $catwhere = "\n WHERE ev.catid IN(" . $this->accessibleCategoryList() . ")";
     $params = JComponentHelper::getParams("com_jevents");
     if ($params->get("multicategory", 0)) {
         $extrajoin[] = "\n #__jevents_catmap as catmap ON catmap.evid = rpt.eventid";
         $extrajoin[] = "\n #__categories AS catmapcat ON catmap.catid = catmapcat.id";
         $extrafields .= ", GROUP_CONCAT(DISTINCT catmap.catid SEPARATOR ',') as catids";
         $extrawhere[] = " catmapcat.access IN (" . JEVHelper::getAid($user) . ")";
         $extrawhere[] = " catmap.catid IN(" . $this->accessibleCategoryList() . ")";
         $needsgroup = true;
         $catwhere = "\n WHERE 1 ";
     }
     $extrajoin = count($extrajoin) ? " \n LEFT JOIN " . implode(" \n LEFT JOIN ", $extrajoin) : '';
     $extrawhere = count($extrawhere) ? ' AND ' . implode(' AND ', $extrawhere) : '';
     // NB extrajoin is a string from now on
     $extrasearchfields = array();
     $dispatcher->trigger('onSearchEvents', array(&$extrasearchfields, &$extrajoin, &$needsgroup));
     if (count($extrasearchfields) > 0) {
         $extraor = implode(" OR ", $extrasearchfields);
         $extraor = " OR " . $extraor;
         // replace the ### placeholder with the keyword
         $extraor = str_replace("###", $keyword, $extraor);
         $searchpart = $useRegX ? "(det.summary RLIKE '{$keyword}' OR det.description RLIKE '{$keyword}' OR det.location RLIKE '{$keyword}' OR det.extra_info RLIKE '{$keyword}' {$extraor})\n" : " (MATCH (det.summary, det.description, det.extra_info) AGAINST ('{$keyword}' IN BOOLEAN MODE) {$extraor})\n";
     } else {
         $searchpart = $useRegX ? "(det.summary RLIKE '{$keyword}' OR det.description RLIKE '{$keyword}'  OR det.location RLIKE '{$keyword}'  OR det.extra_info RLIKE '{$keyword}')\n" : "MATCH (det.summary, det.description, det.extra_info) AGAINST ('{$keyword}' IN BOOLEAN MODE)\n";
     }
     // Now Search Icals
     $query = "SELECT count( distinct det.evdet_id) FROM #__jevents_vevent as ev" . "\n LEFT JOIN #__jevents_icsfile as icsf ON icsf.ics_id=ev.icsid" . "\n LEFT JOIN #__jevents_repetition as rpt ON rpt.eventid = ev.ev_id" . "\n LEFT JOIN #__jevents_vevdetail as det ON det.evdet_id = rpt.eventdetail_id" . $extrajoin . $catwhere . "\n AND icsf.state=1 AND icsf.access IN (" . JEVHelper::getAid($user) . ")" . "\n AND ev.access IN (" . JEVHelper::getAid($user) . ")" . "\n AND ";
     $query .= $searchpart;
     $query .= $extrawhere;
     $query .= $having;
     $db->setQuery($query);
     //echo $db->explain();
     $total += intval($db->loadResult());
     if ($total < $limitstart) {
         $limitstart = 0;
     }
     $rows = array();
     if ($total == 0) {
         return $rows;
     }
     // Now Search Icals
     // New version
     $query = "SELECT DISTINCT det.evdet_id FROM  #__jevents_vevdetail as det" . "\n LEFT JOIN #__jevents_repetition as rpt ON rpt.eventdetail_id = det.evdet_id" . "\n LEFT JOIN #__jevents_vevent as ev ON ev.ev_id = rpt.eventid" . "\n LEFT JOIN #__jevents_icsfile as icsf ON icsf.ics_id=ev.icsid" . $extrajoin . $catwhere . "\n  AND icsf.state=1 AND icsf.access IN (" . JEVHelper::getAid($user) . ")" . "\n AND ev.access IN (" . JEVHelper::getAid($user) . ")";
     $query .= " AND ";
     $query .= $searchpart;
     $query .= $extrawhere;
     $query .= $having;
     $query .= "\n ORDER BY rpt.startrepeat ASC ";
     $query .= "\n {$limitstring}";
     $db->setQuery($query);
     if ($adminuser) {
         //echo $db->_sql;
         //echo $db->explain();
     }
     //echo $db->explain();
     $details = $db->loadColumn();
     $icalrows = array();
     foreach ($details as $detid) {
         $query2 = "SELECT ev.*, rpt.*, det.* {$extrafields}" . "\n , YEAR(rpt.startrepeat) as yup, MONTH(rpt.startrepeat ) as mup, DAYOFMONTH(rpt.startrepeat ) as dup" . "\n , YEAR(rpt.endrepeat  ) as ydn, MONTH(rpt.endrepeat   ) as mdn, DAYOFMONTH(rpt.endrepeat   ) as ddn" . "\n , HOUR(rpt.startrepeat) as hup, MINUTE(rpt.startrepeat ) as minup, SECOND(rpt.startrepeat ) as sup" . "\n , HOUR(rpt.endrepeat  ) as hdn, MINUTE(rpt.endrepeat   ) as mindn, SECOND(rpt.endrepeat   ) as sdn" . "\n FROM #__jevents_vevent as ev" . "\n LEFT JOIN #__jevents_repetition as rpt ON rpt.eventid = ev.ev_id" . "\n LEFT JOIN #__jevents_vevdetail as det ON det.evdet_id = rpt.eventdetail_id" . "\n LEFT JOIN #__jevents_icsfile as icsf ON icsf.ics_id=ev.icsid" . $extrajoin . "\n WHERE rpt.eventdetail_id = {$detid}" . $extrawhere . $having . "\n ORDER BY rpt.startrepeat ASC limit 1";
         $db->setQuery($query2);
         //echo $db->explain();
         $data = $db->loadObject();
         // belts and braces - some servers have a MYSQLK bug on the  user of DISTINCT!
         if (!$data->ev_id) {
             continue;
         }
         $icalrows[] = $data;
     }
     $num_events = count($icalrows);
     for ($i = 0; $i < $num_events; $i++) {
         // convert rows to jevents
         $icalrows[$i] = new jIcalEventRepeat($icalrows[$i]);
     }
     JEventsDBModel::translateEvents($icalrows);
     JEVHelper::onDisplayCustomFieldsMultiRow($icalrows);
     $dispatcher = JDispatcher::getInstance();
     $dispatcher->trigger('onDisplayCustomFieldsMultiRowUncached', array(&$icalrows));
     return $icalrows;
 }