/** * do the plugin action * */ function process(&$data, &$tableModel) { //jimport('joomla.mail.helper'); $params =& $this->getParams(); $app =& Jfactory::getApplication(); $gcal_url = $params->get('gcal_sync_gcal_url'); $matches = array(); // this matches a standard GCal URL, found under the Google "Calender Details" tab, using the XML button. // It should match any form, for public or private ... // http://www.google.com/calendar/feeds/hugh.messenger%40gmail.com/public/basic // http://www.google.com/calendar/feeds/hugh.messenger%40gmail.com/private-3081eca2b0asdfasdf8f106ea6f63343056/basic $gcal_url = str_replace('/basic', '/full', $gcal_url); $gcal_url = preg_replace('#/private-\\w+/#', '/private/', $gcal_url); if (preg_match('#feeds/(.*?)/(\\w+-\\w+|\\w+)/(\\w+)#', $gcal_url, $matches)) { // grab the bits of the URL we need for the Zend framework call $gcal_user = $matches[1]; $gcal_visibility = $matches[2]; $gcal_projection = $matches[3]; $gcal_email = urldecode($gcal_user); // grab the table model and find table name and PK $table =& $tableModel->getTable(); $table_name = $table->db_table_name; $primary_key = $table->db_primary_key; $primary_key_element_long = FabrikString::safeColNameToArrayKey($table->db_primary_key); // for now, we have to read the table ourselves. We can't rely on the $data passed to us // because it can be filtered, and we need to see all records to know if the GCal events // already exist in the table /* $mydata = array(); $db = JFactory::getDBO(); $db->setQuery("SELECT * FROM $table_name"); $mydata[0] = $db->loadObjectList(); */ $db = JFactory::getDBO(); $mydata =& $data; // grab all the field names to use $gcal_label_element_long = $params->get('gcal_sync_label_element'); $gcal_label_element = FabrikString::shortColName($gcal_label_element_long); $gcal_desc_element_long = $params->get('gcal_sync_desc_element'); $gcal_desc_element = FabrikString::shortColName($gcal_desc_element_long); $gcal_start_date_element_long = $params->get('gcal_sync_startdate_element'); $gcal_start_date_element = FabrikString::shortColName($gcal_start_date_element_long); $gcal_end_date_element_long = $params->get('gcal_sync_enddate_element'); $gcal_end_date_element = FabrikString::shortColName($gcal_end_date_element_long); $gcal_id_element_long = $params->get('gcal_sync_id_element'); $gcal_id_element = FabrikString::shortColName($gcal_id_element_long); $gcal_userid_element_long = $params->get('gcal_sync_userid_element'); $gcal_userid_element = FabrikString::shortColName($gcal_userid_element_long); // sanity check, make sure required elements have been specified if (empty($gcal_label_element_long) || empty($gcal_start_date_element_long) || empty($gcal_end_date_element_long) || empty($gcal_id_element_long)) { JError::raiseNotice(500, 'missing gcal data'); return; } // if they selected a User ID element to use, see if we can find a J! user with matching email to this feed's owner $our_userid = 0; if ($gcal_userid_element_long) { $db->setQuery("SELECT id FROM " . $db->nameQuote('#__users') . " WHERE " . $db->nameQUote('email') . " = " . $db->Quote($gcal_email)); $our_userid = $db->loadResult(); // better make sure it's not NULL, in case underlying column is NOT NULL if (empty($our_userid)) { $our_userid = 0; } } // include the Zend stuff $path = JPATH_SITE . DS . 'libraries'; set_include_path(get_include_path() . PATH_SEPARATOR . $path); $path = get_include_path(); require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata'); Zend_Loader::loadClass('Zend_Uri_Http'); // Won't need these loaded until we add sync'ing events back to Google //Zend_Loader::loadClass('Zend_Gdata_AuthSub'); //Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); Zend_Loader::loadClass('Zend_Gdata_Calendar'); // see if they want to sync to gcal, and provided a login $gcal_sync_upload = $params->get('gcal_sync_upload_events', 'from'); if ($gcal_sync_upload == 'both' || $gcal_sync_upload == 'to') { Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); $email = $params->get('gcal_sync_login', ''); $passwd = $params->get('gcal_sync_passwd', ''); try { $client = Zend_Gdata_ClientLogin::getHttpClient($email, $passwd, 'cl'); } catch (Zend_Gdata_App_CaptchaRequiredException $cre) { echo 'URL of CAPTCHA image: ' . $cre->getCaptchaUrl() . "\n"; echo 'Token ID: ' . $cre->getCaptchaToken() . "\n"; return; } catch (Zend_Gdata_App_AuthException $ae) { echo 'Problem authenticating: ' . $ae->exception() . "\n"; return; } $gdataCal = new Zend_Gdata_calendar($client); } else { $gdataCal = new Zend_Gdata_calendar(); } // set up and execute the call to grab the feed from google $query = $gdataCal->newEventQuery(); $query->setUser($gcal_user); $query->setVisibility($gcal_visibility); $query->setProjection($gcal_projection); $eventFeed = $gdataCal->getCalendarEventFeed($query); // build an array of the events from the feed, indexed by the Google ID $event_ids = array(); foreach ($eventFeed as $key => $event) { $short_id = $this->_getGcalShortId($event->id->text); $gcal_event_ids[$short_id] =& $eventFeed[$key]; } // run through our table data, and build an array of our events indexed by the Google ID // (of course not all events may have a Google ID) $our_event_ids = array(); $our_upload_ids = array(); foreach ($mydata as $gkey => $group) { if (is_array($group)) { foreach ($group as $rkey => $row) { if ($row->{$gcal_id_element_long}) { $our_event_ids[$row->{$gcal_id_element_long}] =& $mydata[$gkey][$rkey]; } else { $our_upload_ids[] =& $mydata[$gkey][$rkey]; } } } } // now go through the google events id's, and process the ones which aren't in our table. $our_event_adds = array(); foreach ($gcal_event_ids as $id => $event) { if (!array_key_exists($id, $our_event_ids)) { // we don't have the ID, so add the event to our table $row = array(); $row[$gcal_start_date_element_long] = strftime('%Y-%m-%d %H:%M:%S', strtotime($event->when[0]->startTime)); if ($gcal_end_date_element_long) { $row[$gcal_end_date_element_long] = strftime('%Y-%m-%d %H:%M:%S', strtotime($event->when[0]->endTime)); } $row[$gcal_label_element_long] = $event->title->text; if ($gcal_desc_element_long) { $row[$gcal_desc_element_long] = $event->content->text; } $row[$gcal_id_element_long] = $id; if ($gcal_userid_element_long) { $row[$gcal_userid_element_long] = $our_userid; } $tableModel->storeRow($row, 0); } $our_event_adds[$id] = $row; } $app->enqueueMessage(count($our_event_adds) . ' events added '); // if upload syncing (from us to gcal) is enabled ... if ($gcal_sync_upload == 'both' || $gcal_sync_upload == 'to') { // Grab the tzOffset. Note that gcal want +/-XX (like -06) // but J! gives us +/-X (like -6) so we sprintf it to the right format $config =& JFactory::getConfig(); $tzOffset = (int) $config->getValue('config.offset'); $tzOffset = sprintf('%+03d', $tzOffset); // loop thru the array we built earlier of events we have that aren't in gcal $uploadCount = 0; foreach ($our_upload_ids as $id => $event) { // skip if a userid element is specified, and doesn't match the owner of this gcal if ($gcal_userid_element_long) { if ($event->{$gcal_userid_element_long} != $our_userid) { continue; } } // now start building the gcal event structure $newEvent = $gdataCal->newEventEntry(); $newEvent->title = $gdataCal->newTitle($event->{$gcal_label_element_long}); if ($gcal_desc_element_long) { $newEvent->content = $gdataCal->newContent($event->{$gcal_desc_element_long}); } else { $newEvent->content = $gdataCal->newContent($event->{$gcal_label_element_long}); } $when = $gdataCal->newWhen(); // grab the start date, apply the tx offset, and format it for gcal $start_date = JFactory::getDate($event->{$gcal_start_date_element_long}); $start_date->setOffset($tzOffset); $start_fdate = $start_date->toFormat('%Y-%m-%d %H:%M:%S'); $date_array = explode(' ', $start_fdate); $when->startTime = "{$date_array[0]}T{$date_array[1]}.000{$tzOffset}:00"; // we have to provide an end date for gcal, so if we don't have one, // default it to start date + 1 hour if (empty($gcal_end_date_element_long) || empty($event->{$gcal_end_date_element_long}) || $event->{$gcal_end_date_element_long} == '0000-00-00 00:00:00') { $startstamp = strtotime($event->{$gcal_start_date_element_long}); $endstamp = $startstamp + 60 * 60; $event->{$gcal_end_date_element_long} = strftime('%Y-%m-%d %H:%M:%S', $endstamp); } // grab the end date, apply the tx offset, and format it for gcal $end_date = JFactory::getDate($event->{$gcal_end_date_element_long}); $end_date->setOffset($tzOffset); $end_fdate = $end_date->toFormat('%Y-%m-%d %H:%M:%S'); $date_array = explode(' ', $end_fdate); $when->endTime = "{$date_array[0]}T{$date_array[1]}.000{$tzOffset}:00"; $newEvent->when = array($when); // fire off the insertEvent to gcal, catch any errors try { $retEvent = $gdataCal->insertEvent($newEvent, $gcal_url); } catch (Zend_Gdata_App_HttpException $he) { $errStr = 'Problem adding event: ' . $he->getRawResponseBody() . "\n"; continue; } $uploadCount++; // insertEvent worked, so grab the gcal ID from the returned event data, // and update our event record with the short version of the ID $gcal_id = $this->_getGcalShortId($retEvent->id->text); $our_id = $event->__pk_val; $db->setQuery("\n\t\t\t\t\t\tUPDATE {$table_name}\n\t\t\t\t\t\tSET {$gcal_id_element} = " . $db->Quote($gcal_id) . "\n\t\t\t\t\t\tWHERE {$primary_key} = " . (int) $our_id); $db->query(); } $app->enqueueMessage($uploadCount . ' events uploaded to GCal'); } } else { JError::raiseNotice(500, 'Incorrect url'); } }
private function _process(&$params, &$formModel) { $app =& Jfactory::getApplication(); $gcal_url = $params->get('gcal_url', ''); $matches = array(); // this matches a standard GCal URL, found under the Google "Calender Details" tab, using the XML button. // Because we are adding events, we need the private URL, and it needs to end in /full // But the default URL Google show when you look at setting is the /basic ... // http://www.google.com/calendar/feeds/hugh.messenger%40gmail.com/private-3081eca2b0asdfasdf8f106ea6f63343056/basic // So we need to replace /basic with /full before we do anything. // Also need to remove the magic cookie, if present. $gcal_url = str_replace('/basic', '/full', $gcal_url); $gcal_url = preg_replace('#/private-\\w+/#', '/private/', $gcal_url); if (preg_match('#feeds/(.*?)/(\\w+-\\w+|\\w+)/(\\w+)#', $gcal_url, $matches)) { // grab the bits of the URL we need for the Zend framework call $gcal_user = $matches[1]; $gcal_visibility = $matches[2]; $gcal_projection = $matches[3]; $gcal_email = urldecode($gcal_user); // grab all the field names to use /* $gcal_label_element_long = $params->get('gcal_label_element'); $gcal_label_element = FabrikString::shortColName($gcal_label_element_long); $gcal_desc_element_long = $params->get('gcal_desc_element'); $gcal_desc_element = FabrikString::shortColName($gcal_desc_element_long); $gcal_start_date_element_long = $params->get('gcal_start_date_element'); $gcal_start_date_element = FabrikString::shortColName($gcal_start_date_element_long); $gcal_end_date_element_long = $params->get('gcal_end_date_element'); $gcal_end_date_element = FabrikString::shortColName($gcal_end_date_element_long); $gcal_id_element_long = $params->get('gcal_id_element'); $gcal_id_element = FabrikString::shortColName($gcal_id_element_long); $email = $params->get('gcal_login', ''); $passwd = $params->get('gcal_passwd', ''); */ $data =& $formModel->_formData; $email = $params->get('gcal_login', ''); $passwd = $params->get('gcal_passwd', ''); $gcal_label = $this->getFieldValue($params, 'gcal_label_element', $data); $gcal_desc = $this->getFieldValue($params, 'gcal_desc_element', $data); $gcal_start_date = $this->getFieldValue($params, 'gcal_start_date_element', $data); $gcal_end_date = $this->getFieldValue($params, 'gcal_end_date_element', $data); $gcal_event_id = $this->getFieldValue($params, 'gcal_id_element', $data); $gcal_id_element = FabrikString::shortColName($this->getFieldName($params, 'gcal_id_element')); // sanity check, make sure required elements have been specified if (empty($email) || empty($passwd) || empty($gcal_label) || empty($gcal_start_date) || empty($gcal_id_element)) { JError::raiseNotice(500, 'missing gcal data'); return; } // grab the table model and find table name and PK $tableModel =& $formModel->getTableModel(); $table =& $tableModel->getTable(); $table_name = $table->db_table_name; $primary_key = $tableModel->_shortKey(null, true); $db =& $tableModel->getDb(); // include the Zend stuff $path = JPATH_SITE . DS . 'libraries'; set_include_path(get_include_path() . PATH_SEPARATOR . $path); $path = get_include_path(); require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata'); Zend_Loader::loadClass('Zend_Uri_Http'); Zend_Loader::loadClass('Zend_Gdata_Calendar'); Zend_Loader::loadClass('Zend_Gdata_ClientLogin'); try { $client = Zend_Gdata_ClientLogin::getHttpClient($email, $passwd, 'cl'); } catch (Zend_Gdata_App_CaptchaRequiredException $cre) { echo 'URL of CAPTCHA image: ' . $cre->getCaptchaUrl() . "\n"; echo 'Token ID: ' . $cre->getCaptchaToken() . "\n"; return; } catch (Zend_Gdata_App_AuthException $ae) { echo 'Problem authenticating: ' . $ae->exception() . "\n"; return; } $gdataCal = new Zend_Gdata_calendar($client); // set up query $query = $gdataCal->newEventQuery(); $query->setUser($gcal_user); $query->setVisibility($gcal_visibility); $query->setProjection($gcal_projection); if (!empty($gcal_event_id)) { $query->setEvent($gcal_event_id); try { $event = $gdataCal->getCalendarEventEntry($query); } catch (Zend_Gdata_App_Exception $e) { //echo "Error: " . $e->getMessage(); JError::raiseNotice(500, 'Error retrieving GCal event: ' . $e->getMessage()); return; } } else { $event = $gdataCal->newEventEntry(); } // Grab the tzOffset. No need to offset dates from form, as they are already offset, // but need it for the gcal date string format. // Note that gcal want +/-XX (like -06) // but J! gives us +/-X (like -6) so we sprintf it to the right format $config =& JFactory::getConfig(); $tzOffset = (int) $config->getValue('config.offset'); $tzOffset = sprintf('%+03d', $tzOffset); $event->title = $gdataCal->newTitle($gcal_label); if (!empty($gcal_desc)) { $event->content = $gdataCal->newContent($gcal_desc); } else { $event->content = $gdataCal->newContent($gcal_label); } $when = $gdataCal->newWhen(); // grab the start date, apply the tx offset, and format it for gcal $start_date = JFactory::getDate($gcal_start_date); $start_date->setOffset($tzOffset); $start_fdate = $start_date->toFormat('%Y-%m-%d %H:%M:%S'); $date_array = explode(' ', $start_fdate); $when->startTime = "{$date_array[0]}T{$date_array[1]}.000{$tzOffset}:00"; // we have to provide an end date for gcal, so if we don't have one, // default it to start date + 1 hour if (empty($gcal_end_date) || $gcal_end_date == '0000-00-00 00:00:00') { $startstamp = strtotime($gcal_start_date); $endstamp = $startstamp + 60 * 60; $gcal_end_date = strftime('%Y-%m-%d %H:%M:%S', $endstamp); } // grab the end date, apply the tx offset, and format it for gcal $end_date = JFactory::getDate($gcal_end_date); $end_date->setOffset($tzOffset); $end_fdate = $end_date->toFormat('%Y-%m-%d %H:%M:%S'); $date_array = explode(' ', $end_fdate); $when->endTime = "{$date_array[0]}T{$date_array[1]}.000{$tzOffset}:00"; $event->when = array($when); if (!empty($gcal_event_id)) { try { $event->save(); } catch (Zend_Gdata_App_Exception $e) { JError::raiseNotice(500, 'Error saving GCal event: ' . $e->getMessage()); return; } } else { // fire off the insertEvent to gcal, catch any errors try { $retEvent = $gdataCal->insertEvent($event, $gcal_url); } catch (Zend_Gdata_App_HttpException $he) { JError::raiseNotice(500, 'Problem adding event: ' . $he->getRawResponseBody()); return; } // insertEvent worked, so grab the gcal ID from the returned event data, // and update our event record with the short version of the ID $gcal_event_id = $this->_getGcalShortId($retEvent->id->text); } $our_id = $formModel->_formData[$primary_key]; if (!empty($our_id)) { $db->setQuery("\n\t\t\t\t\t\t\tUPDATE {$table_name}\n\t\t\t\t\t\t\tSET {$gcal_id_element} = " . $db->Quote($gcal_event_id) . "\n\t\t\t\t\t\t\tWHERE {$primary_key} = " . $db->Quote($our_id)); $db->query(); } else { JError::raiseNotice(500, 'No rowid for GCal ID update!'); } $app->enqueueMessage('Event syncronized with GCal'); } else { JError::raiseNotice(500, 'Incorrect GCal url'); } }