/** * override store function to return id to pass to iCalEvent and store the events too! * * @param int $catid - forced category for the underlying events */ function store($catid = false, $cleanup = true, $flush = true) { @ini_set("memory_limit", "256M"); @ini_set("max_execution_time", "300"); // clean out the cache $cache = JFactory::getCache('com_jevents'); $cache->clean(JEV_COM_COMPONENT); static $categories; if (is_null($categories)) { $sql = "SELECT * FROM #__categories WHERE extension='com_jevents'"; $db = JFactory::getDBO(); $db->setQuery($sql); $categories = $db->loadObjectList('title'); } if (!$catid) { $catid = $this->catid; } if ($id = $this->isDuplicate()) { $this->ics_id = $id; // TODO return warning about duplicate file name VERY IMPORTANT TO DECIDE WHAT TO DO // UIDs for the vcalendar itself are not compulsory } // There is a better way to find // duplicate key info trap repeated insertions - I should if (!parent::store()) { echo "failed to store icsFile<br/>"; } else { if ($this->isdefault == 1 && $this->icaltype == 2) { // set all the others to 0 $db = JFactory::getDBO(); $sql = "UPDATE #__jevents_icsfile SET isdefault=0 WHERE icaltype=2 AND ics_id<>" . $this->ics_id; $db->setQuery($sql); $db->execute(); } } // find the full set of ids currently in the calendar so taht we can remove cancelled ones $db = JFactory::getDBO(); $sql = "SELECT ev_id, uid, lockevent FROM #__jevents_vevent WHERE icsid=" . $this->ics_id; //. " AND catid=".$catid; $db->setQuery($sql); $existingevents = $db->loadObjectList('ev_id'); // insert the data - this will need to deal with multiple rrule values foreach ($this->_icalInfo->vevents as &$vevent) { if (!$vevent->isCancelled() && !$vevent->isRecurrence()) { // if existing category then use it if (!$this->ignoreembedcat && JString::strlen($vevent->_detail->categories) > 0) { $evcat = explode(",", $vevent->_detail->categories); if (count($evcat) > 0) { include_once JEV_ADMINLIBS . "categoryClass.php"; foreach ($evcat as $ct) { // if no such category then create it/them if (!array_key_exists(trim($ct), $categories)) { $cat = new JEventsCategory($db); $cat->bind(array("title" => trim($ct))); $cat->published = 1; $cat->check(); if (!$cat->store()) { var_dump($cat->getErrors()); die("failed to auto create category {$ct}"); } } } // must reset the list of categories now $sql = "SELECT * FROM #__categories WHERE extension='com_jevents'"; $db->setQuery($sql); $categories = $db->loadObjectList('title'); $params = JComponentHelper::getParams(JEV_COM_COMPONENT); if ($params->get("multicategory", 0)) { $vevent->catid = array(); foreach ($evcat as $ct) { $vevent->catid[] = $categories[trim($ct)]->id; } } else { $vevent->catid = $categories[trim($evcat[0])]->id; } } } else { $params = JComponentHelper::getParams(JEV_COM_COMPONENT); if ($params->get("multicategory", 0)) { $vevent->catid = array($catid); } else { $vevent->catid = $catid; } } // These now gets picked up in the event //$vevent->access = $this->access; //$vevent->state = $this->state; $vevent->icsid = $this->ics_id; // The refreshed field is used to track dropped events on reload $vevent->refreshed = $this->refreshed; // make sure I don't add the same events more than once if ($matchingEvent = $vevent->matchingEventDetails()) { $vevent->ev_id = $matchingEvent->ev_id; $vevent->_detail->evdet_id = $matchingEvent->evdet_id; unset($existingevents[$vevent->ev_id]); } // if the event is locked then skip this row if ($matchingEvent && $matchingEvent->lockevent) { $vevent->lockevent = 1; continue; } else { $vevent->lockevent = 0; } // handle events running over midnight $params = JComponentHelper::getParams(JEV_COM_COMPONENT); $icalmultiday = $params->get("icalmultiday", 0); $icalmultiday24h = $params->get("icalmultiday24h", 0); // These booleans are the wrong way around. $vevent->_detail->multiday = $icalmultiday ? 0 : 1; if ($vevent->_detail->dtend - $vevent->_detail->dtstart < 86400) { $vevent->_detail->multiday = $icalmultiday24h ? 0 : 1; } // force creator if appropriate if ($this->created_by > 0) { $vevent->created_by = $this->created_by; // force override of creator $vevent->store(false, true); } else { $vevent->store(); } // trigger post save plugins e.g. AutoTweet $dispatcher = JEventDispatcher::getInstance(); JPluginHelper::importPlugin("jevents"); if ($matchingEvent) { JRequest::setVar("evid", $vevent->ev_id); } else { JRequest::setVar("evid", 0); } $repetitions = $vevent->getRepetitions(true); $vevent->storeRepetitions(); if (isset($vevent->state) && !isset($vevent->published)) { $vevent->published = $vevent->state; } // not a dry run of course! $res = $dispatcher->trigger('onAfterSaveEvent', array(&$vevent, false)); // Save memory by clearing out the repetitions we no longer need $repetitions = null; $vevent->_repetitions = null; //$vevent=null; //echo "Event Data read in<br/>"; //echo "memory = ".memory_get_usage()." ".memory_get_usage(true)."<br/>"; if ($flush) { ob_flush(); flush(); } } } unset($vevent); // Having stored all the repetitions - remove the cancelled instances // this should be done as a batch but for now I'll do them one at a time foreach ($this->_icalInfo->vevents as $vevent) { // if the event is locked then skip this row if (!is_null($vevent) && $vevent->lockevent) { continue; } if (!is_null($vevent) && ($vevent->isCancelled() || $vevent->isRecurrence())) { // if existing category then use it if (JString::strlen($vevent->_detail->categories) > 0) { if (count($evcat) > 0) { include_once JEV_ADMINLIBS . "categoryClass.php"; foreach ($evcat as $ct) { // if no such category then create it/them if (!array_key_exists($ct, $categories)) { $cat = new JEventsCategory($db); $cat->bind(array("title" => $ct)); $cat->published = 1; $cat->check(); $cat->store(); } } // must reset the list of categories now $sql = "SELECT * FROM #__categories WHERE extension='com_jevents'"; $db->setQuery($sql); $categories = $db->loadObjectList('title'); $params = JComponentHelper::getParams(JEV_COM_COMPONENT); if ($params->get("multicategory", 0) && count($evcat) > 1) { $vevent->catid = array(); foreach ($evcat as $ct) { $vevent->catid[] = $categories[$ct]->id; } } else { $vevent->catid = $categories[$evcat[0]]->id; } } } else { $params = JComponentHelper::getParams(JEV_COM_COMPONENT); if ($params->get("multicategory", 0)) { $vevent->catid = array($catid); } else { $vevent->catid = $catid; } } $vevent->access = $this->access; $vevent->state = $this->state; $vevent->icsid = $this->ics_id; // make sure I don't add the same events more than once if ($matchingEvent = $vevent->matchingEventDetails()) { $vevent->ev_id = $matchingEvent->ev_id; } if ($vevent->isCancelled()) { $vevent->cancelRepetition(); } else { // replace event that is only 'adjusted' with the correct settings $vevent->adjustRepetition($matchingEvent); } } } // Now remove existing events that have been deleted if ($cleanup) { if (count($existingevents) > 0) { $todelete = array(); foreach ($existingevents as $event) { $todelete[] = $event->ev_id; } $veventidstring = implode(",", $todelete); $query = "SELECT DISTINCT (eventdetail_id) FROM #__jevents_repetition WHERE eventid IN ({$veventidstring})"; $db->setQuery($query); $detailids = $db->loadColumn(); $detailidstring = implode(",", $detailids); $query = "DELETE FROM #__jevents_rrule WHERE eventid IN ({$veventidstring})"; $db->setQuery($query); $db->execute(); $query = "DELETE FROM #__jevents_repetition WHERE eventid IN ({$veventidstring})"; $db->setQuery($query); $db->execute(); $query = "DELETE FROM #__jevents_exception WHERE eventid IN ({$veventidstring})"; $db->setQuery($query); $db->execute(); if (JString::strlen($detailidstring) > 0) { $query = "DELETE FROM #__jevents_vevdetail WHERE evdet_id IN ({$detailidstring})"; $db->setQuery($query); $db->execute(); } $query = "DELETE FROM #__jevents_vevent WHERE ev_id IN ({$veventidstring})"; $db->setQuery($query); $db->execute(); JFactory::getApplication()->enqueueMessage(count($existingevents) . ' deleted iCal events removed'); } } $count = count($this->_icalInfo->vevents); unset($this->_icalInfo->vevents); JFactory::getApplication()->enqueueMessage($count . ' iCal events processed'); }