/** * Called by the Event Queue processor to process a reminder * on a task. * @access public * @param string $module Module name (not used) * @param string $type Type of event (not used) * @param integer $id ID of task being reminded * @param integer $owner Originator of event * @param mixed $args event-specific arguments. * @return mixed true, dequeue event, false, event stays in queue. * -1, event is destroyed. */ public function remind($module, $type, $id, $owner, &$args) { global $locale_char_set, $AppUI; $q = new w2p_Database_Query(); // At this stage we won't have an object yet if (!$this->load($id)) { return -1; // No point it trying again later. } $this->htmlDecode(); // Only remind on working days. $today = new w2p_Utilities_Date(); if (!$today->isWorkingDay()) { return true; } // Check if the task is completed if ($this->task_percent_complete == 100) { return -1; } $contacts = $this->getAssigned(); // Now we also check the owner of the task, as we will need // to notify them as well. $owner_is_not_assignee = false; $q->addTable('users', 'u'); $q->addJoin('contacts', 'c', 'c.contact_id = u.user_contact', 'inner'); $q->addQuery('c.contact_id, contact_first_name, contact_last_name, contact_email'); $q->addWhere('u.user_id = ' . (int) $this->task_owner); if ($q->exec(ADODB_FETCH_NUM)) { list($owner_contact, $owner_first_name, $owner_last_name, $owner_email) = $q->fetchRow(); if (!isset($contacts[$owner_contact])) { $owner_is_not_assignee = true; $contacts[$owner_contact] = array('contact_id' => $owner_contact, 'contact_first_name' => $owner_first_name, 'contact_last_name' => $owner_last_name, 'contact_email' => $owner_email); } } $q->clear(); // build the subject line, based on how soon the // task will be overdue. $starts = new w2p_Utilities_Date($this->task_start_date); $expires = new w2p_Utilities_Date($this->task_end_date); $now = new w2p_Utilities_Date(); $diff = $expires->dateDiff($now); $diff *= w2p_Utilities_Date::compare($expires, $now); $prefix = $AppUI->_('Task Due', UI_OUTPUT_RAW); if ($diff == 0) { $msg = $AppUI->_('TODAY', UI_OUTPUT_RAW); } elseif ($diff == 1) { $msg = $AppUI->_('TOMORROW', UI_OUTPUT_RAW); } elseif ($diff < 0) { $msg = $AppUI->_(array('OVERDUE', abs($diff), 'DAYS')); $prefix = $AppUI->_('Task', UI_OUTPUT_RAW); } else { $msg = $AppUI->_(array($diff, 'DAYS')); } $project = new CProject(); $project_name = $project->load($this->task_project)->project_name; // Check to see that the project is both active and not a template if (!$project->project_active || $project->project_status == w2PgetConfig('template_projects_status_id', 0)) { return -1; } $subject = $prefix . ' ' . $msg . ' ' . $this->task_name . '::' . $project_name; $body = $AppUI->_('Task Due', UI_OUTPUT_RAW) . ': ' . $msg . "\n" . $AppUI->_('Project', UI_OUTPUT_RAW) . ': ' . $project_name . "\n" . $AppUI->_('Task', UI_OUTPUT_RAW) . ': ' . $this->task_name . "\n" . $AppUI->_('Start Date', UI_OUTPUT_RAW) . ': START-TIME' . "\n" . $AppUI->_('Finish Date', UI_OUTPUT_RAW) . ': END-TIME' . "\n" . $AppUI->_('URL', UI_OUTPUT_RAW) . ': ' . W2P_BASE_URL . '/index.php?m=tasks&a=view&task_id=' . $this->task_id . '&reminded=1' . "\n\n" . $AppUI->_('Resources', UI_OUTPUT_RAW) . ":\n"; foreach ($contacts as $contact) { if (!$owner_is_not_assignee || $owner_is_not_assignee && $contact['contact_id'] != $owner_contact) { $body .= $contact['contact_first_name'] . ' ' . $contact['contact_last_name'] . ' <' . $contact['contact_email'] . ">\n"; } } $body .= "\n" . $AppUI->_('Description', UI_OUTPUT_RAW) . ":\n" . $this->task_description . "\n"; $mail = new w2p_Utilities_Mail(); $mail->Subject($subject, $locale_char_set); foreach ($contacts as $contact) { $user_id = CUser::getUserIdByContactID($contact['contact_id']); $AppUI->loadPrefs($user_id); $df = $AppUI->getPref('DISPLAYFORMAT'); $tz = $AppUI->getPref('TIMEZONE'); $body = str_replace('START-TIME', $starts->convertTZ($tz)->format($df), $body); $body = str_replace('END-TIME', $expires->convertTZ($tz)->format($df), $body); $mail->Body($body, $locale_char_set); if ($mail->ValidEmail($contact['contact_email'])) { $mail->To($contact['contact_email'], true); $mail->Send(); } } return true; }
/** Import tasks from another project * * @param int Project ID of the tasks come from. * @return bool **/ public function importTasks($from_project_id) { global $AppUI; $errors = array(); // Load the original $origProject = new CProject(); $origProject->load($from_project_id); $q = $this->_query; $q->addTable('tasks'); $q->addQuery('task_id'); $q->addWhere('task_project =' . (int) $from_project_id); $tasks = array_flip($q->loadColumn()); $q->clear(); $origDate = new w2p_Utilities_Date($origProject->project_start_date); $destDate = new w2p_Utilities_Date($this->project_start_date); $timeOffset = $origDate->dateDiff($destDate); if ($origDate->compare($origDate, $destDate) > 0) { $timeOffset = -1 * $timeOffset; } // Dependencies array $deps = array(); // Copy each task into this project and get their deps foreach ($tasks as $orig => $void) { $objTask = new CTask(); $objTask->load($orig); $destTask = $objTask->copy($this->project_id); $tasks[$orig] = $destTask; $deps[$orig] = $objTask->getDependencies(); } // Fix record integrity foreach ($tasks as $old_id => $newTask) { // Fix parent Task // This task had a parent task, adjust it to new parent task_id if ($newTask->task_id != $newTask->task_parent) { $newTask->task_parent = $tasks[$newTask->task_parent]->task_id; } // Fix task start date from project start date offset $origDate->setDate($newTask->task_start_date); $origDate->addDays($timeOffset); $destDate = $origDate; $newTask->task_start_date = $destDate->format(FMT_DATETIME_MYSQL); // Fix task end date from start date + work duration if (!empty($newTask->task_end_date) && $newTask->task_end_date != '0000-00-00 00:00:00') { $origDate->setDate($newTask->task_end_date); $origDate->addDays($timeOffset); $destDate = $origDate; $newTask->task_end_date = $destDate->format(FMT_DATETIME_MYSQL); } // Dependencies if (!empty($deps[$old_id])) { $oldDeps = explode(',', $deps[$old_id]); // New dependencies array $newDeps = array(); foreach ($oldDeps as $dep) { $newDeps[] = $tasks[$dep]->task_id; } // Update the new task dependencies $csList = implode(',', $newDeps); $newTask->updateDependencies($csList); } // end of update dependencies $result = $newTask->store($AppUI); $newTask->addReminder(); $importedTasks[] = $newTask->task_id; if (is_array($result) && count($result)) { foreach ($result as $key => $error_msg) { $errors[] = $newTask->task_name . ': ' . $error_msg; } } } // end Fix record integrity // We have errors, so rollback everything we've done so far if (count($errors)) { foreach ($importedTasks as $badTask) { $delTask = new CTask(); $delTask->task_id = $badTask; $delTask->delete($AppUI); } } return $errors; }
$AppUI->redirect('m=tasks&a=view&task_id=' . $task_id); } } $result = $obj->store(); if ($result) { if (isset($hassign)) { $obj->updateAssigned($hassign, $hperc_assign_ar); } // This call has to be here to make sure that old dependencies are // cleared on save, even if there's no new dependencies $obj->updateDependencies($hdependencies, $obj->task_id); if (isset($hdependencies) && '' != $hdependencies) { // there are dependencies set! $nsd = new w2p_Utilities_Date($obj->get_deps_max_end_date($obj)); if (isset($start_date)) { $shift = $nsd->compare($start_date, $nsd); if ($shift < 1) { //$obj->task_start_date = $nsd->format(FMT_DATETIME_MYSQL); $osd = new w2p_Utilities_Date($obj->task_start_date); $ned = new w2p_Utilities_Date($obj->task_end_date); $dur = -$ned->calcDuration($osd); $ned->copy($nsd); $ned->addDuration($dur, 1); $new_start_date = $nsd->format(FMT_DATETIME_MYSQL); $obj->task_start_date = $AppUI->formatTZAwareTime($new_start_date, '%Y-%m-%d %T'); $new_end_date = $ned->format(FMT_DATETIME_MYSQL); $obj->task_end_date = $AppUI->formatTZAwareTime($new_end_date, '%Y-%m-%d %T'); $obj->store(); } } }
/** * Called by the Event Queue processor to process a reminder * on a task. * @access public * @param string $notUsed Module name (not used) * @param string $notUsed2 Type of event (not used) * @param integer $id ID of task being reminded * @param integer $owner Originator of event * @param mixed $notUsed event-specific arguments. * * @return mixed true, dequeue event, false, event stays in queue. * -1, event is destroyed. */ public function remind($notUsed = null, $notUsed2 = null, $id, $owner, $notUsed3 = null) { // At this stage we won't have an object yet if (!$this->load($id)) { return -1; // No point it trying again later. } $this->htmlDecode(); // Only remind on working days. $today = new w2p_Utilities_Date(); if (!$today->isWorkingDay()) { return true; } // Check if the task is completed if ($this->task_percent_complete == 100) { return -1; } $contacts = $this->assignees($this->task_id); $contact = new CContact(); $owner = $contact->findContactByUserId($this->task_owner); $contacts[$owner->contact_id] = array('user_id' => $this->task_owner, 'contact_id' => $owner->contact_id, 'contact_name' => $owner->contact_display_name, 'contact_email' => $owner->contact_email); // build the subject line, based on how soon the // task will be overdue. $starts = new w2p_Utilities_Date($this->task_start_date); $expires = new w2p_Utilities_Date($this->task_end_date); $now = new w2p_Utilities_Date(); $diff = $expires->dateDiff($now); $diff *= $expires->compare($expires, $now); $prefix = $this->_AppUI->_('Task Due', UI_OUTPUT_RAW); if ($diff == 0) { $msg = $this->_AppUI->_('TODAY', UI_OUTPUT_RAW); } elseif ($diff == 1) { $msg = $this->_AppUI->_('TOMORROW', UI_OUTPUT_RAW); } elseif ($diff < 0) { $msg = $this->_AppUI->_(array('OVERDUE', abs($diff), 'DAYS')); $prefix = $this->_AppUI->_('Task', UI_OUTPUT_RAW); } else { $msg = $this->_AppUI->_(array($diff, 'DAYS')); } $project = new CProject(); $project->overrideDatabase($this->_query); $project_name = $project->load($this->task_project)->project_name; // Check to see that the project is both active and not a template if (!$project->project_active || $project->project_status == w2PgetConfig('template_projects_status_id', 0)) { return -1; } $subject = $prefix . ' ' . $msg . ' ' . $this->task_name . '::' . $project_name; $emailManager = new w2p_Output_EmailManager($this->_AppUI); $body = $emailManager->getTaskRemind($this, $msg, $project_name, $contacts); $mail = new w2p_Utilities_Mail(); $mail->Subject($subject); foreach ($contacts as $contact) { $user_id = $contact['user_id']; $this->_AppUI->loadPrefs($user_id); $df = $this->_AppUI->getPref('SHDATEFORMAT'); $tz = $this->_AppUI->getPref('TIMEZONE'); $body = str_replace('START-TIME', $starts->convertTZ($tz)->format($df), $body); $body = str_replace('END-TIME', $expires->convertTZ($tz)->format($df), $body); $mail->Body($body, $this->_locale_char_set); $mail->To($contact['contact_email'], true); $mail->Send(); } return true; }
/** * Tests compare function when both dates are equal, convert timezones */ public function testCompareEqualConvertTz() { $date1 = new w2p_Utilities_Date('2010-08-07 00:00:00', 'America/Halifax'); $date2 = new w2p_Utilities_Date('2010-08-06 22:00:00', 'America/Chicago'); $this->assertEquals(0, $date1->compare($date1, $date2, true)); }
if (($show_uid = w2PgetParam($_REQUEST, 'show_user_events', 0)) != 0) { $user_id = $show_uid; $no_modify = true; $AppUI->setState('event_user_id', $user_id); } } // assemble the links for the events $events = CEvent::getEventsForPeriod($first_time, $last_time, $event_filter, $user_id); $events2 = array(); $start_hour = w2PgetConfig('cal_day_start'); $end_hour = w2PgetConfig('cal_day_end'); foreach ($events as $row) { $start = new w2p_Utilities_Date($row['event_start_date']); $end = new w2p_Utilities_Date($row['event_end_date']); $key = $start->format('%H%M%S'); if (-1 == $start->compare($start, $this_day)) { $myhour = $start_hour < 10 ? '0' . $start_hour : $start_hour; $key = $myhour . '0000'; } $events2[$key][] = $row; if ($start_hour > $start->format('%H')) { $start_hour = $start->format('%H'); } if ($end_hour < $end->format('%H')) { $end_hour = $end->format('%H'); } } $tf = $AppUI->getPref('TIMEFORMAT'); $dayStamp = $this_day->format(FMT_TIMESTAMP_DATE); $start = $start_hour; $end = $end_hour;