Example #1
0
 /**
  * Pull one or more events with attributes from a remote instance.
  * Set $technique to
  * 		full - download everything
  * 		incremental - only new events
  * 		<int>	- specific id of the event to pull
  * For example to download event 10 from server 2 to /servers/pull/2/5
  * @param int $id The id of the server
  * @param unknown_type $technique
  * @throws MethodNotAllowedException
  * @throws NotFoundException
  */
 public function pull($id = null, $technique = false)
 {
     if (!$this->_isSiteAdmin() && !($this->Server->organization == $this->Auth->user('org') && $this->userRole['perm_sync'])) {
         $this->redirect(array('controller' => 'servers', 'action' => 'index'));
     }
     $this->Server->id = $id;
     if (!$this->Server->exists()) {
         throw new NotFoundException(__('Invalid server'));
     }
     App::uses('HttpSocket', 'Network/Http');
     $this->Server->read(null, $id);
     if (false == $this->Server->data['Server']['pull']) {
         $this->Session->setFlash(__('Pull setting not enabled for this server.'));
         $this->redirect(array('action' => 'index'));
     }
     $eventIds = array();
     if ("full" == $technique) {
         // get a list of the event_ids on the server
         $eventIds = $this->Event->getEventIdsFromServer($this->Server->data);
         // FIXME this is not clean at all ! needs to be refactored with try catch error handling/communication
         if ($eventIds === 403) {
             $this->Session->setFlash(__('Not authorised. This is either due to an invalid auth key, or due to the sync user not having authentication permissions enabled on the remote server.'));
             $this->redirect(array('action' => 'index'));
         } else {
             if (is_string($eventIds)) {
                 $this->Session->setFlash($eventIds);
                 $this->redirect(array('action' => 'index'));
             }
         }
         // reverse array of events, to first get the old ones, and then the new ones
         $eventIds = array_reverse($eventIds);
     } elseif ("incremental" == $technique) {
         // TODO incremental pull
         throw new NotFoundException('Sorry, this is not yet implemented');
     } elseif (true == $technique) {
         $eventIds[] = intval($technique);
     } else {
         $this->redirect(array('action' => 'index'));
     }
     // now process the $eventIds to pull each of the events sequentially
     if (!empty($eventIds)) {
         $successes = array();
         $fails = array();
         // download each event
         if (null != $eventIds) {
             App::import('Controller', 'Events');
             $HttpSocket = new HttpSocket();
             foreach ($eventIds as &$eventId) {
                 $event = $this->Event->downloadEventFromServer($eventId, $this->Server->data);
                 if (null != $event) {
                     // we have an Event array
                     // The event came from a pull, so it should be locked.
                     $event['Event']['locked'] = true;
                     if (!isset($event['Event']['distribution'])) {
                         // version 1
                         $event['Event']['distribution'] = '1';
                     }
                     // Distribution
                     switch ($event['Event']['distribution']) {
                         case 1:
                         case 'This community only':
                             // backwards compatibility
                             // if community only, downgrade to org only after pull
                             $event['Event']['distribution'] = '0';
                             break;
                         case 2:
                         case 'Connected communities':
                             // backwards compatibility
                             // if connected communities downgrade to community only
                             $event['Event']['distribution'] = '1';
                             break;
                         case 'All communities':
                             // backwards compatibility
                             $event['Event']['distribution'] = '3';
                             break;
                         case 'Your organisation only':
                             // backwards compatibility
                             $event['Event']['distribution'] = '0';
                             break;
                     }
                     // correct $event if just one Attribute
                     if (is_array($event['Event']['Attribute']) && isset($event['Event']['Attribute']['id'])) {
                         $tmp = $event['Event']['Attribute'];
                         unset($event['Event']['Attribute']);
                         $event['Event']['Attribute'][0] = $tmp;
                     }
                     if (is_array($event['Event']['Attribute'])) {
                         $size = is_array($event['Event']['Attribute']) ? count($event['Event']['Attribute']) : 0;
                         for ($i = 0; $i < $size; $i++) {
                             if (!isset($event['Event']['Attribute'][$i]['distribution'])) {
                                 // version 1
                                 $event['Event']['Attribute'][$i]['distribution'] = 1;
                             }
                             switch ($event['Event']['Attribute'][$i]['distribution']) {
                                 case 1:
                                 case 'This community only':
                                     // backwards compatibility
                                     // if community only, downgrade to org only after pull
                                     $event['Event']['Attribute'][$i]['distribution'] = '0';
                                     break;
                                 case 2:
                                 case 'Connected communities':
                                     // backwards compatibility
                                     // if connected communities downgrade to community only
                                     $event['Event']['Attribute'][$i]['distribution'] = '1';
                                     break;
                                 case 'All communities':
                                     // backwards compatibility
                                     $event['Event']['Attribute'][$i]['distribution'] = '3';
                                     break;
                                 case 'Your organisation only':
                                     // backwards compatibility
                                     $event['Event']['Attribute'][$i]['distribution'] = '0';
                                     break;
                             }
                         }
                         $event['Event']['Attribute'] = array_values($event['Event']['Attribute']);
                     } else {
                         unset($event['Event']['Attribute']);
                     }
                     // Distribution, set reporter of the event, being the admin that initiated the pull
                     $event['Event']['user_id'] = $this->Auth->user('id');
                     // check if the event already exist (using the uuid)
                     $existingEvent = null;
                     $existingEvent = $this->Event->find('first', array('conditions' => array('Event.uuid' => $event['Event']['uuid'])));
                     $eventsController = new EventsController();
                     $eventsController->constructClasses();
                     if (!$existingEvent) {
                         // add data for newly imported events
                         $passAlong = $this->Server->data['Server']['url'];
                         $result = $eventsController->_add($event, $fromXml = true, $this->Server->data['Server']['organization'], $passAlong, true);
                         if ($result) {
                             $successes[] = $eventId;
                         } else {
                             $fails[$eventId] = 'Failed (partially?) because of validation errors: ' . print_r($eventsController->Event->validationErrors, true);
                         }
                     } else {
                         $result = $eventsController->_edit($event, $existingEvent['Event']['id']);
                         if ($result === 'success') {
                             $successes[] = $eventId;
                         } else {
                             $fails[$eventId] = $result;
                         }
                     }
                 } else {
                     // error
                     $fails[$eventId] = 'failed downloading the event';
                 }
             }
             if (count($fails) > 0) {
                 // there are fails, take the lowest fail
                 $lastpulledid = min(array_keys($fails));
             } else {
                 // no fails, take the highest success
                 $lastpulledid = count($successes) > 0 ? max($successes) : 0;
             }
             // increment lastid based on the highest ID seen
             $this->Server->set('lastpulledid', $lastpulledid);
             $this->Server->save($event, array('fieldList' => array('lastpulledid', 'url')));
         }
     }
     $this->set('successes', $successes);
     $this->set('fails', $fails);
 }