/** * It is used for both editing and adding */ public function executeAdd(sfWebRequest $request) { $description = $request->getParameter('content'); $listId = $request->getParameter('listId'); $taskId = $request->getParameter('taskId'); // the contexts coming from the client have a trailing slash $contexts = $request->getParameter('contexts'); $isHeader = $request->getParameter('isHeader') == 1 ? 1 : 0; $note = $request->getParameter('note'); $dueDate = $request->getParameter('dueDate'); $dueTime = $request->getParameter('dueTime'); $isStarred = $request->getParameter('isStarred') == 1 ? 1 : 0; $repetitionId = $request->getParameter('repetitionId'); $repetitionParam = $request->getParameter('repetitionParam'); $taskAboveId = (int) $request->getParameter('taskAboveId'); $task = PcTaskPeer::createOrEdit($description, $listId, $taskId, $contexts, $isHeader, $note, $dueDate, $dueTime, $isStarred, $repetitionId, $repetitionParam, $taskAboveId, 'ajax', 'Y-m-d'); if ($request->isXmlHttpRequest()) { return $this->renderJson($task->toArray()); } }
/** * Updates the corresponding Plancake task. * If there is not a corresponding Plancake task, * we create a new one. * * @param -Google Calendar Event- $event */ private function updatePlancakeTask($event) { $eventId = $this->getEventId($event); // retrieving the Plancake task: we use this method, rather than the EVENT_EXTENDED_PROPERTY_TASK_ID // extended property, because it should be more reliable $task = PcTaskPeer::getTaskByGoogleCalendarEventId($eventId); // {{{ PATCH: we have this problem something Google was trying to send us back some events that // had been either completed or deleted on the Plancake side. // This is the reason why we have decided to use an extended property to keep a record of the link // CalendarEvent<-->PlancakeTask $taskIdFromExtendedProperty = $this->getExtendedProperty($event, self::EVENT_EXTENDED_PROPERTY_TASK_ID); if ($taskIdFromExtendedProperty) { $taskFromExtendedProperty = PcTaskPeer::retrieveByPK($taskIdFromExtendedProperty); if ($taskFromExtendedProperty && $taskFromExtendedProperty->isCompleted()) { $taskFromExtendedProperty->removeGoogleCalendarEventId(); return; } if (PcTrashbinTaskPeer::retrieveByPK($taskIdFromExtendedProperty)) { return; } } // }}} // end PATCH // {{{ checking whether the event has been deleted if ($this->hasEventBeenDeleted($event)) { // event has been deleted if (is_object($task)) { if (SfConfig::get('app_gcal_debug')) { error_log('Deleting Plancake task ' . $task->getId() . ' ' . $task->getDescription()); } $task->removeGoogleCalendarEventId(); // In order to avoid potential disasters, we disable the possibility // for GCal to delete tasks // $task->delete(); return; } } // }}} $eventDescription = $event->title->text; $eventNote = $event->content->text; $eventDueDate = ''; $eventDueTime = ''; $eventRepetitionId = 0; $eventRepetitionParam = 0; $eventIsRecurrent = true; foreach ($event->when as $when) { $startTime = $when->startTime; $eventIsRecurrent = false; if (strlen($startTime) == 10) { $eventDueDate = $startTime; $eventDueTime = ''; } else { preg_match('!([^T]+)T([0-9]{2}):([0-9]{2}):.*!', $startTime, $matches); $eventDueDate = $matches[1]; $eventDueTime = $matches[2] . $matches[3]; $eventDueTime = (int) $eventDueTime; } break; // getting just the first due date } if ($eventIsRecurrent) { $recurrentData = $event->recurrence->text; // $recurrentData is something like: // DTSTART;VALUE=DATE:20110215 DTEND;VALUE=DATE:20110216 RRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=TU // DTSTART:20110228T110000Z DTEND:20110228T120000Z RRULE:FREQ=WEEKLY;BYDAY=MO list($eventDueDate, $eventDueTime, $eventRepetitionId, $eventRepetitionParam) = DateFormat::fromICalRecurrentStringToInternalParams($recurrentData); } foreach ($event->when as $when) { break; // we only consider the first 'when' parameter } list($eventLocalDueDate, $eventLocalDueTime) = DateFormat::fromGmtDateAndTime2LocalDateAndTime($eventDueDate, $eventDueTime); if (is_object($task)) { $task->edit($eventDescription, null, null, null, $eventNote, $eventLocalDueDate, $eventLocalDueTime, null, $eventRepetitionId, $eventRepetitionParam, 'gcal'); if (SfConfig::get('app_gcal_debug')) { error_log('Updated Plancake task ' . $task->getId() . ' ' . $task->getDescription()); } } else { $dbEntry = PcGoogleCalendarPeer::retrieveByUser($this->user); if (!is_object($dbEntry)) { throw new Exception("You need a session token in order to create a new task."); } // we have to create a new Plancake task $task = PcTaskPeer::createOrEdit($eventDescription, null, 0, '', false, $eventNote, $eventLocalDueDate, $eventLocalDueTime, 0, $eventRepetitionId, $eventRepetitionParam, 0, 'gcal', 'Y-m-d'); if (SfConfig::get('app_gcal_debug')) { error_log('Created Plancake task ' . $task->getId() . ' ' . $task->getDescription()); } } $task->setGoogleCalendarEventId($eventId); }
/** * @see sfTask */ protected function executeTask($env, $arguments = array(), $options = array()) { /** * Getting the directory where the emails are stored */ $inboxUser = sfConfig::get('app_emailToInbox_inboxUser'); $emailDomain = sfConfig::get('app_emailToInbox_mailServerDomain'); $newEmailPath = $arguments['emailFileAbsolutePath']; // there are some regular Plancake inbox email address that are // use just for spam $spamAccounts = array(); $spamAccounts[] = 'niki_5436'; // this will be interpreted as inbox_niki_5436@plancakebox.com $spamAccounts[] = 'niki.jones_15c522'; $this->log(''); $this->log(''); $this->log("parsing the email at " . $newEmailPath); $mailParser = new PlancakeEmailParser(file_get_contents($newEmailPath)); $plancakeSubjectOK = false; $plancakeRecipientOK = false; $emailTo = array(); $emailSubject = ''; $emailCc = $mailParser->getCc(); try { $emailTo = $mailParser->getTo(); } catch (Exception $e) { $this->handleFault("couldn't retrieve the 'to' header of the email", $newEmailPath); return; } try { $emailSubject = $mailParser->getSubject(); $plancakeSubjectOK = true; $this->log("got the subject of the email: " . $emailSubject); } catch (Exception $e) { $this->handleFault("couldn't retrieve the subject of the email", $newEmailPath); return; } $emailRecipients = array_merge($emailTo, $emailCc); $emailRecipients = implode(', ', $emailRecipients); $deliveredToHeader = $mailParser->getHeader('Delivered-To'); $emailRecipients = $deliveredToHeader . ', ' . $emailRecipients; $this->log("all recipients of the email: " . $emailRecipients); $internalEmail = false; // to flag an email sent to the catchall address $spamEmail = false; if (preg_match('/' . $inboxUser . "@{$emailDomain}/", $emailRecipients, $matches)) { $internalEmail = true; $this->log("discarding the email as it is an internal one"); if (is_file($newEmailPath)) { unlink($newEmailPath); } return; } if (preg_match("/inbox_([^@]+)@{$emailDomain}/i", $emailRecipients, $matches)) { // found Plancake Inbox address! $plancakeInbox = $matches[1]; if (in_array($plancakeInbox, $spamAccounts)) { $spamEmail = true; $this->handleFault("discarding the email because it is from a spammer", $newEmailPath); return; } else { $emailRecipient = 'inbox_' . $plancakeInbox . "@{$emailDomain}"; $plancakeRecipientOK = true; $this->log("got the Plancake recipient of the email: " . $emailRecipient); } } else { $this->handleFault("couldn't find a Plancake recipient for the email", $newEmailPath); return; } /** * Sorting the email into the database */ if ($plancakeRecipientOK && $plancakeSubjectOK) { $this->log('well done. For this email we got both the recipient and the subject. I can now create the task for the user.'); $emailRecipientWithoutDomain = str_replace("@{$emailDomain}", '', $emailRecipient); $c = new Criteria(); $c->add(PcPlancakeEmailAddressPeer::EMAIL, $emailRecipientWithoutDomain, Criteria::EQUAL); $plancakeEmail = PcPlancakeEmailAddressPeer::doSelectOne($c); if (is_object($plancakeEmail)) { // everything's OK $userId = $plancakeEmail->getUserId(); $user = PcUserPeer::retrieveByPk($userId); PcUserPeer::setLoggedInUser($user); // check whether there is a note for the task $note = $this->extractNote($mailParser->getPlainBody()); if (strlen($note)) { $this->log("note: {$note}"); } if (!strlen($emailSubject)) { $emailSubject = 'Something went wrong with a task you sent via email. Please contact us.'; } PcTaskPeer::createOrEdit($emailSubject, $user->getInbox()->getId(), 0, '', false, $note); $this->log('the email has successfully become a task for the user.'); } else { // something wrong $this->handleFault('no email user', $newEmailPath); $this->log('couldn\'t create a task from the email - the Plancake address is not in the system :-(.'); } } else { if ((!$plancakeRecipientOK || !$plancakeSubjectOK) && !$internalEmail && !$spamEmail) { // something wrong $this->handleFault('email parsing', $newEmailPath); $this->log("counldn't find both the recipient and the subject of the email. Nothing to do."); } } $this->log("deleting the email from the hard disk."); if (is_file($newEmailPath)) { unlink($newEmailPath); } $this->log(''); $this->log(''); }
public function import($xml) { $originalMaxExecutionTime = ini_get('max_execution_time'); ini_set('max_execution_time', 120); proc_nice(1); $tagLocalIds = array(); $listLocalIds = array(); $newTagIds = array(); $newListIds = array(); $newTaskIds = array(); $newNoteIds = array(); $tags = $xml->plancake_tasks->tags->tag; foreach ($tags as $tag) { $isNewTag = false; $tagId = (int) $tag->id > 0 ? $tag->id : null; $tagLocalId = (int) $tag->localId; $tagName = (string) $tag->name; $tagSortOrder = (int) $tag->sortOrder; $tagObj = null; if ($tagId && !in_array($tagId, $newTagIds)) { $tagObj = PcUsersContextsPeer::retrieveByPK($tagId); } if ($tagObj) { if ($tagObj->getUserId() != $this->user->getId()) { die("Hacking attempt."); } } else { // tags are unique by name, thus // we check whether the tag is already in the instance // we are importing the dump to. $c = new Criteria(); $c->add(PcUsersContextsPeer::CONTEXT, $tagName); $tagObj = PcUsersContextsPeer::doSelectOne($c); if (!is_object($tagObj)) { $tagObj = new PcUsersContexts(); $isNewTag = true; } } $tagObj->setUserId($this->user->getId())->setContext($tagName)->setSortOrder($tagSortOrder)->save(); $tagLocalIds[$tagLocalId] = $tagObj->getId(); if ($isNewTag) { $newTagIds[] = $tagObj->getId(); } } $lists = $xml->plancake_tasks->lists->list; foreach ($lists as $list) { $isNewList = false; $listId = (int) $list->id > 0 ? $list->id : null; $listLocalId = (int) $list->localId; $listName = (string) $list->name; $listSortOrder = (int) $list->sortOrder; $listIsInbox = (int) $list->isInbox == 1 ? true : false; $listIsTodo = (int) $list->isTodo == 1 ? true : false; $listIsHeader = (int) $list->isHeader == 1 ? true : false; $listObj = null; if ($listId && !in_array($listId, $newListIds)) { $listObj = PcListPeer::retrieveByPK($listId); } if ($listObj) { if ($listObj->getCreatorId() != $this->user->getId()) { die("Hacking attempt."); } } else { if ($listIsInbox) { $listObj = $this->user->getInbox(); } else { if ($listIsTodo) { $listObj = $this->user->getTodo(); } else { $listObj = new PcList(); $isNewList = true; } } } $listObj->setCreatorId($this->user->getId())->setTitle($listName)->setSortOrder($listSortOrder)->setIsInbox($listIsInbox)->setIsTodo($listIsTodo)->setIsHeader($listIsHeader)->save(); $listLocalIds[$listLocalId] = $listObj->getId(); if ($isNewList) { $newListIds[] = $listObj->getId(); } } $tasks = $xml->plancake_tasks->tasks->task; foreach ($tasks as $task) { $isNewTask = false; $taskId = (int) $task->id > 0 ? $task->id : 0; $taskListLocalId = (int) $task->listLocalId; $taskDescription = (string) $task->description; $taskSortOrder = (int) $task->sortOrder; $taskDueDate = (string) $task->dueDate; $taskDueTime = strlen($task->dueTime) > 0 ? (int) $task->dueTime : ''; $taskRepetitionId = (int) $task->repetitionId; $taskRepetitionParam = (int) $task->repetitionParam; $taskIsStarred = (int) $task->isStarred == 1 ? true : false; $taskIsCompleted = (int) $task->isCompleted == 1 ? true : false; $taskIsHeader = (int) $task->isHeader == 1 ? true : false; $taskIsFromSystem = (int) $task->isFromSystem == 1 ? true : false; $taskTagLocalIds = (string) $task->tagLocalIds; $taskNote = (string) $task->note; $taskListId = $listLocalIds[$taskListLocalId]; $taskTagIdsArray = array(); $taskTagLocalIdsArray = PcUtils::explodeWithEmptyInputDetection(',', $taskTagLocalIds); foreach ($taskTagLocalIdsArray as $id) { $taskTagIdsArray[] = $tagLocalIds[$id]; } $taskTagIds = ''; if (count($taskTagIdsArray)) { $taskTagIds = implode(',', $taskTagIdsArray); } $taskFromDb = null; if ($taskId && !in_array($taskId, $newTaskIds)) { $taskFromDb = PcTaskPeer::retrieveByPK($taskId); } if (!is_object($taskFromDb)) { // if the task doesn't exist (even if the dump contains a taskId) // we want to add it. $taskId = 0; $isNewTask = true; } $newTask = PcTaskPeer::createOrEdit($taskDescription, $taskListId, $taskId, $taskTagIds, $taskIsHeader, $taskNote, $taskDueDate, $taskDueTime, $taskIsStarred, $taskRepetitionId, $taskRepetitionParam, 0, '', 'd-m-Y', false); if ($taskIsCompleted) { $newTask->setIsCompleted(1); $newTask->setCompletedAt($task->completedAt); $newTask->save(); } if ($isNewTask) { $newTaskIds[] = $newTask->getId(); } if (!$taskId) { $newTask->deleteDirtyEntry(); } } $notes = $xml->plancake_notes->notes->note; foreach ($notes as $note) { $isNewNote = false; $noteId = (int) $note->id > 0 ? $note->id : null; $noteTitle = (string) $note->title; $noteContent = (string) $note->content; $noteObj = null; if ($noteId && !in_array($noteId, $newNoteIds)) { $noteObj = PcNotePeer::retrieveByPK($noteId); } if ($noteObj) { if ($noteObj->getCreatorId() != $this->user->getId()) { die("Hacking attempt."); } } else { $noteObj = new PcNote(); $isNewNote = true; } $noteObj->setCreatorId($this->user->getId())->setTitle($noteTitle)->setContent($noteContent)->save(); if ($isNewNote) { $newNoteIds[] = $noteObj->getId(); } } ini_set('max_execution_time', $originalMaxExecutionTime); }
/** * Edit anything in a task * Only the input parameters that are not null will be changed. * * @param string $description (=null) * @param integer $listId (=null) * @param string $contexts (=null) (comma separated list) * @param boolean $isHeader * @param string $note (=null) * @param string $dueDate in the PHP date() format 'Y-m-d' * @param string $dueTime - formatted as an integer, ie: 0753 * @param integer $repetitionId * @param integer $repetitionParam * @param integer $taskAboveId * @param string $callerContext - can be either 'ajax' or 'email' * @return PcTask - the object that has been created */ public function edit($description = null, $listId = null, $contexts = null, $isHeader = null, $note = null, $dueDate = null, $dueTime = null, $isStarred = null, $repetitionId = null, $repetitionParam = null, $callerContext = '') { $description = $description === null ? $this->getDescription() : $description; $listId = $listId === null ? $this->getListId() : $listId; $contexts = $contexts === null ? $this->getContexts() : $contexts; $note = $note === null ? $this->getNote() : $note; $isHeader = $isHeader === null ? $this->isHeader() : $isHeader; $dueDate = $dueDate === null ? $this->getDueDate('Y-m-d') : $dueDate; $dueTime = $dueTime === null ? $this->getDueTime() : $dueTime; $isStarred = $isStarred === null ? $this->isStarred() : $isStarred; $repetitionId = $repetitionId === null ? $this->getRepetitionId() : $repetitionId; $repetitionParam = $repetitionParam === null ? $this->getRepetitionParam() : $repetitionParam; $taskId = $this->getId(); PcTaskPeer::createOrEdit($description, $listId, $taskId, $contexts, $isHeader, $note, $dueDate, $dueTime, $isStarred, $repetitionId, $repetitionParam, 0, $callerContext, 'Y-m-d'); }