/** * Outputs the html for a DateGallery tile. * * @param Ansel_Gallery_Decorator_Date $dgallery The Ansel_Gallery_Date we are * displaying. * @param Ansel_Style $style A style object. * @param boolean $mini Force the use of a mini thumbail? * @param array $params An array containing additional parameters. * Currently, gallery_view_url and image_view_url * are used to override the respective urls. * %g and %i are replaced with image id and * gallery id, respectively. * * @return string The HTML for the tile. */ public function getTile(Ansel_Gallery_Decorator_Date $dgallery, Ansel_Style $style = null, $mini = false, array $params = array()) { $view = $GLOBALS['injector']->createInstance('Horde_View'); $view->addTemplatePath(ANSEL_TEMPLATES . '/tile'); // User's preferred date format $date_format = $GLOBALS['prefs']->getValue('date_format'); $date_array = $dgallery->getDate(); if (empty($date_array['month'])) { $date_array['month'] = 1; } if (empty($date_array['day'])) { $date_array['day'] = 1; } $full_date = new Horde_Date($date_array); // Need the unaltered date part array $date_array = $dgallery->getDate(); // Figure out the needed link for the next drill down level. We *must* // have at least a year since we are in a date tile. if (empty($date_array['month'])) { // unit == year $view->caption = $full_date->strftime('%Y'); $next_date = array('year' => (int) $view->caption); } elseif (empty($date_array['day'])) { // unit == month $view->caption = $full_date->strftime('%B %Y'); $next_date = array('year' => date('Y', $full_date->timestamp()), 'month' => date('n', $full_date->timestamp())); } else { // unit == day $view->caption = $full_date->strftime($date_format); $next_date = array('year' => date('Y', $full_date->timestamp()), 'month' => date('n', $full_date->timestamp()), 'day' => date('j', $full_date->timestamp())); } // Check permissions on the gallery and get appropriate tile image if ($dgallery->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::READ)) { if (is_null($style)) { $style = $dgallery->getStyle(); } $thumbstyle = $mini ? 'mini' : 'thumb'; $view->gallery_image = Ansel::getImageUrl($dgallery->getKeyImage(), $thumbstyle, true, $style); } else { $view->gallery_image = Horde_Themes::img('thumb-error.png'); } /* Check for being called via the api and generate correct view links */ if (!isset($params['gallery_view_url'])) { if (empty($params['style'])) { $gstyle = $dgallery->getStyle(); } else { $gstyle = $params['style']; } $params = array('gallery' => $dgallery->id, 'view' => 'Gallery', 'slug' => $dgallery->get('slug')); $view->view_link = Ansel::getUrlFor('view', array_merge($params, $next_date)); } else { $view->view_link = new Horde_Url(str_replace(array('%g', '%s'), array($dgallery->id, $dgallery->get('slug')), urldecode($params['gallery_view_url']))); $view->view_link->add($next_date); } $view->gallery_count = $dgallery->countImages(true); return $view->render('dategallery'); }
/** * Returns a relative, natural language representation of a timestamp * * @todo Wider range of values ... maybe future time as well? * @todo Support minimum resolution parameter. * * @param mixed $time The time. Any format accepted by Horde_Date. * @param string $date_format Format to display date if timestamp is * more then 1 day old. * @param string $time_format Format to display time if timestamp is 1 * day old. * * @return string The relative time (i.e. 2 minutes ago) */ public static function relativeDateTime($time, $date_format = '%x', $time_format = '%X') { $date = new Horde_Date($time); $delta = time() - $date->timestamp(); if ($delta < 60) { return sprintf(Horde_Date_Translation::ngettext("%d second ago", "%d seconds ago", $delta), $delta); } $delta = round($delta / 60); if ($delta < 60) { return sprintf(Horde_Date_Translation::ngettext("%d minute ago", "%d minutes ago", $delta), $delta); } $delta = round($delta / 60); if ($delta < 24) { return sprintf(Horde_Date_Translation::ngettext("%d hour ago", "%d hours ago", $delta), $delta); } if ($delta > 24 && $delta < 48) { $date = new Horde_Date($time); return sprintf(Horde_Date_Translation::t("yesterday at %s"), $date->strftime($time_format)); } $delta = round($delta / 24); if ($delta < 7) { return sprintf(Horde_Date_Translation::t("%d days ago"), $delta); } if (round($delta / 7) < 5) { $delta = round($delta / 7); return sprintf(Horde_Date_Translation::ngettext("%d week ago", "%d weeks ago", $delta), $delta); } // Default to the user specified date format. return $date->strftime($date_format); }
public function testMethodListeventsHasResultArrayTheEventsInTheGivenTimeSpan() { $rec_start = new Horde_Date('2009-12-12 10:00:00'); $rec_end = new Horde_Date('2009-12-12 14:00:00'); $objects = array(array('uid' => 1, 'sensitivity' => 'public', 'start-date' => $rec_start->timestamp(), 'end-date' => $rec_end->timestamp(), 'recurrence' => array('interval' => 1, 'cycle' => 'daily', 'range-type' => 'none'))); $resource = $this->_getData($objects); $start = new Horde_Date('2009-12-13 0:00:00'); $end = new Horde_Date('2009-12-14 0:00:00'); $result = $resource->listEvents($start, $end); $this->assertInstanceOf('Horde_Kolab_FreeBusy_Object_Event', $result[0]); }
public function getInfo(&$vars, &$var, &$info) { $due_type = $vars->get('due_type'); $due = $vars->get('due'); if (is_array($due)) { $due_date = !empty($due['date']) ? $due['date'] : null; $due_time = !empty($due['time']) ? $due['time'] : null; $due_array = Nag::parseDate("{$due_date} {$due_time}"); $due_dt = new Horde_Date($due_array); $due = $due_dt->timestamp(); } $info = strcasecmp($due_type, 'none') ? $due : 0; }
public function getInfo(&$vars, &$var, &$info) { $start_type = $vars->get('start_date'); $start = $vars->get('start'); if (is_array($start)) { if (empty($start['date'])) { $start = null; } else { $start_array = Nag::parseDate($start['date'], false); $start_dt = new Horde_Date($start_array); $start = $start_dt->timestamp(); } } $info = strcasecmp($start_type, 'none') ? $start : 0; }
/** * Returns a list of events or tasks. * * @param integer $folder A folder ID. If empty, returns objects of all * visible resources. * @param Horde_Date $start Start date, defaults to epoch. * @param Horde_Date $end End date, defaults to maximum date possible. * * @return array List of object hashes. * @throws Horde_OpenXchange_Exception. */ protected function _listObjects($folder = null, $start = null, $end = null) { $this->_login(); $data = array('session' => $this->_session, 'columns' => implode(',', array_keys($this->_columns)), 'start' => $start ? $start->timestamp() * 1000 : 0, 'end' => $end ? $end->timestamp() * 1000 : PHP_INT_MAX, 'recurrence_master' => true); if ($folder) { $data['folder'] = $folder; } $response = $this->_request('GET', $this->_folderType, array('action' => 'all'), $data); $events = array(); foreach ($response['data'] as $event) { $map = array(); foreach (array_values($this->_columns) as $key => $column) { $map[$column] = $event[$key]; } $events[] = $map; } return $events; }
/** * Retrieve the busy times from this event within the given timeframe. This * is trivial for non-recurring events but recurring events need to be * expanded. * * @param Horde_Date $startDate The start point. * @param Horde_Date $endDate The end point. * * @return array The list of busy times (only the start times of the event). */ public function getBusyTimes(Horde_Date $startDate, Horde_Date $endDate) { if (!$this->recurs()) { if ($startDate->compareDateTime($this->_start) > 0 || $endDate->compareDateTime($this->_start) < 0) { return array(); } return array($this->_start->timestamp()); } else { $result = array(); $next = $this->_recurrence->nextRecurrence($startDate); while ($next) { if ($endDate->compareDateTime($next) < 0) { break; } if (!$this->_recurrence->hasException($next->year, $next->month, $next->mday)) { $result[] = $next->timestamp(); } $next->mday++; $next = $this->_recurrence->nextRecurrence($next); } return $result; } }
/** * Lists users with birthdays/goout dates as time objects. * * @param array $categories The time categories (from listTimeObjectCategories) to list. * @param Horde_Date $start The start date of the period. * @param Horde_Date $end The end date of the period. */ public function listTimeObjects($categories, $start, $end) { require_once __DIR__ . '/base.php'; require_once FOLKS_BASE . '/lib/Friends.php'; $friends_driver = Folks_Friends::singleton('sql'); $friends = $friends_driver->getFriends(); if ($friends instanceof PEAR_Error) { return array(); } $objects = array(); foreach ($friends as $friend) { $user = $GLOBALS['folks_driver']->getProfile($friend); if ($user instanceof PEAR_Error) { continue; } $user['user_birthday'] = date('Y') . substr($user['user_birthday'], 4); $born = strtotime($user['user_birthday']); if ($born === false || $born < $start->timestamp() || $born > $end->timestamp()) { continue; } $age = Folks::calcAge($user['user_birthday']); $desc = $age['age'] . ' (' . $age['sign'] . ')'; $objects[$friend] = array('title' => $friend, 'description' => $desc, 'id' => $friend, 'start' => date('Y-m-d\\TH:i:s', $born), 'end' => date('Y-m-d\\TH:i:s', $born + 1), 'params' => array('user' => $friend), 'link' => Folks::getUrlFor('user', $friend, true)); } return $objects; }
/** * Lists active tasks as time objects. * * @param array $categories The time categories (from * listTimeObjectCategories) to list. * @param mixed $start The start date of the period. * @param mixed $end The end date of the period. */ public function listTimeObjects($categories, $start, $end) { $allowed_tasklists = Nag::listTasklists(false, Horde_Perms::READ); foreach ($categories as $tasklist) { if (!isset($allowed_tasklists[$tasklist])) { throw new Horde_Exception_PermissionDenied(); } } $timeobjects = array(); $start = new Horde_Date($start); $start_ts = $start->timestamp(); $end = new Horde_Date($end); $end_ts = $end->timestamp(); // List incomplete tasks. $tasks = Nag::listTasks(array('tasklists' => $categories, 'completed' => Nag::VIEW_INCOMPLETE, 'include_history' => false)); $tasks->reset(); while ($task = $tasks->each()) { // If there's no due date, it's not a time object. if (!$task->due || $task->due > $end_ts || !$task->recurs() && $task->due + 1 < $start_ts || $task->recurs() && $task->recurrence->getRecurEnd() && $task->recurrence->getRecurEnd()->timestamp() + 1 < $start_ts) { continue; } $due_date = date('Y-m-d\\TH:i:s', $task->due); $recurrence = null; if ($task->recurs()) { $recurrence = array('type' => $task->recurrence->getRecurType(), 'interval' => $task->recurrence->getRecurInterval(), 'end' => $task->recurrence->getRecurEnd(), 'count' => $task->recurrence->getRecurCount(), 'days' => $task->recurrence->getRecurOnDays(), 'exceptions' => $task->recurrence->getExceptions(), 'completions' => $task->recurrence->getCompletions()); } $timeobjects[$task->id] = array('id' => $task->id, 'title' => $task->name, 'description' => $task->desc, 'start' => $due_date, 'end' => $due_date, 'recurrence' => $recurrence, 'color' => $allowed_tasklists[$task->tasklist]->get('color'), 'owner' => $allowed_tasklists[$task->tasklist]->get('owner'), 'permissions' => $GLOBALS['nag_shares']->getPermissions($task->tasklist, $GLOBALS['registry']->getAuth()), 'variable_length' => false, 'params' => array('task' => $task->id, 'tasklist' => $task->tasklist), 'link' => Horde::url('view.php', true)->add(array('tasklist' => $task->tasklist, 'task' => $task->id)), 'edit_link' => Horde::url('task.php', true)->add(array('tasklist' => $task->tasklist, 'task' => $task->id, 'actionID' => 'modify_task')), 'delete_link' => Horde::url('task.php', true)->add(array('tasklist' => $task->tasklist, 'task' => $task->id, 'actionID' => 'delete_task')), 'ajax_link' => 'task:' . $task->tasklist . ':' . $task->id); } return $timeobjects; }
$form = new Ansel_Form_ImageDate($vars, _("Edit Dates")); /* Are we doing the edit now? */ if ($actionID == 'edit_dates') { $count = 0; foreach (array_keys($images) as $image_id) { try { $image = $GLOBALS['injector']->getInstance('Ansel_Storage')->getImage($image_id); if (empty($gallery_id)) { // Images might be from different galleries $gallery = $GLOBALS['injector']->getInstance('Ansel_Storage')->getGallery($image->gallery); if (!$gallery->hasPermission($registry->getAuth(), Horde_Perms::EDIT)) { continue; } } $newDate = new Horde_Date($vars->get('image_originalDate')); $image->originalDate = (int) $newDate->timestamp(); $image->save(); ++$count; } catch (Ansel_Exception $e) { $notification->push(sprintf(_("There was an error editing the dates: %s"), $e->getMessage()), 'horde.error'); echo Horde::wrapInlineScript(array('window.opener.location.href = window.opener.location.href;', 'window.close();')); exit; } } $notification->push(sprintf(_("Successfully modified the date on %d photos."), $count), 'horde.success'); echo Horde::wrapInlineScript(array('window.opener.location.href = window.opener.location.href;', 'window.close();')); exit; } $keys = array_keys($images); $html = ''; foreach ($keys as $key) {
private function _getMinimalInvitation() { $start = new Horde_Date('20080926T110000'); $end = new Horde_Date('20080926T120000'); $vCal = new Horde_Icalendar(); $vCal->setAttribute('METHOD', 'REQUEST'); $inv = Horde_Icalendar::newComponent('VEVENT', $vCal); $inv->setAttribute('UID', '1001'); $inv->setAttribute('ORGANIZER', 'mailto:orga@example.org', array('cn' => 'Mr. Orga')); $inv->setAttribute('DTSTART', $start->timestamp()); $inv->setAttribute('DTEND', $end->timestamp()); return $inv; }
} $task = new Nag_Task($nag_storage); $task->fromiCalendar($row); $row = $task->toHash(); foreach (array_keys($app_fields) as $field) { if (!isset($row[$field])) { $row[$field] = ''; } } } $row['owner'] = $GLOBALS['registry']->getAuth(); foreach (array('start', 'due', 'completed_date') as $field) { if (!empty($row[$field])) { try { $date = new Horde_Date($row[$field]); $row[$field] = $date->timestamp(); } catch (Horde_Date_Exception $e) { unset($row[$field]); } } else { $row[$field] = 0; } } try { $nag_storage->add($row); } catch (Nag_Exception $e) { $haveError = true; $notification->push(sprintf(_("There was an error importing the data: %s"), $e->getMessage()), 'horde.error'); break; } $num_tasks++;
/** * Update a set of billing information. * * @param array $entries The billing information to enter. Each array row * must contain the following entries: * 'id' The id of this time entry. * 'date' The day the hours were worked (ISO format) * 'client' The id of the client the work was done for. * 'type' The type of work done. * 'hours' The number of hours worked * 'rate' The hourly rate the work was done at. * 'billable' Whether or not the work is billable hours. * 'description' A short description of the work. * 'employee' The employee * * If any rows contain a 'delete' entry, those rows * will be deleted instead of updated. * * @return integer The number of successful updates. * @throws Horde_Exception_PermissionDenied * @throws Hermes_Exception */ public function updateTime($entries) { foreach ($entries as $info) { if (!Hermes::canEditTimeslice($info['id'])) { throw new Horde_Exception_PermissionDenied(_("Access denied; user cannot modify this timeslice.")); } if (!empty($info['delete'])) { try { return $this->_db->delete('DELETE FROM hermes_timeslices WHERE timeslice_id = ?', array((int) $info['id'])); } catch (Horde_Db_Exception $e) { throw new Hermes_Exception($e); } } else { if (isset($info['employee'])) { $employee_cl = ' ,employee_id = ?'; } else { $employee_cl = ''; } $dt = new Horde_Date($info['date']); $sql = 'UPDATE hermes_timeslices SET' . ' clientjob_id = ?, jobtype_id = ?,' . ' timeslice_hours = ?, timeslice_isbillable = ?,' . ' timeslice_date = ?, timeslice_description = ?,' . ' timeslice_note = ?, costobject_id = ?' . $employee_cl . ' WHERE timeslice_id = ?'; $values = array($info['client'], $info['type'], $info['hours'], isset($info['billable']) ? (int) $info['billable'] : 0, $dt->timestamp(), $this->_convertToDriver($info['description']), $this->_convertToDriver($info['note']), empty($info['costobject']) ? null : $info['costobject']); if (!empty($employee_cl)) { $values[] = $info['employee']; } $values[] = (int) $info['id']; try { return $this->_db->update($sql, $values); } catch (Horde_Db_Exception $e) { throw new Hermes_Exception($e); } } } }
/** * Reads the search form submitted and return the search criteria * */ protected function _readSearchForm() { $perms = $GLOBALS['injector']->getInstance('Horde_Perms'); $vars = $this->vars; $criteria = array(); if ($GLOBALS['registry']->isAdmin(array('permission' => 'hermes:review'))) { if (!empty($vars->employees[0])) { $auth = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Auth')->create(); if (!$auth->hasCapability('list')) { $criteria['employee'] = explode(',', $vars->employees[0]); if (empty($criteria['employee'])) { unset($criteria['employee']); } } else { $criteria['employee'] = $vars->employees; } } } else { $criteria['employee'] = $GLOBALS['registry']->getAuth(); } if (!empty($vars->client)) { $criteria['client'] = $vars->client; } if (!empty($vars->type)) { $criteria['jobtype'] = $vars->type; } if (!empty($vars->costobject)) { $criteria['costobject'] = $vars->costobject; } if (!empty($vars->after_date)) { $dt = new Horde_Date($vars->after_date); $criteria['start'] = $dt->timestamp(); } if (!empty($vars->before_date)) { $dt = new Horde_Date($vars->before_date); $criteria['end'] = $dt->add(86400)->timestamp(); } if ($vars->billable !== '') { $criteria['billable'] = $vars->billable; } if ($vars->submitted !== '') { $criteria['submitted'] = $vars->submitted; } if ($vars->exported !== '') { $criteria['exported'] = $vars->exported; } return $criteria; }
public function testRecurringTasks() { $due = time() - 1; $recurrence = new Horde_Date_Recurrence($due); $recurrence->setRecurType(Horde_Date_Recurrence::RECUR_DAILY); $id = $this->_add(array('name' => 'TEST', 'desc' => 'Some test task.', 'due' => $due, 'recurrence' => $recurrence)); $due = new Horde_Date($due); $result = self::$driver->get($id[0]); $next = $result->getNextDue(); $this->assertInstanceOf('Horde_Date', $next); $this->assertEquals($due->timestamp(), $next->timestamp()); $result->toggleComplete(); $result->save(); $result2 = self::$driver->get($id[0]); $due->mday++; $next = $result2->getNextDue(); $this->assertInstanceOf('Horde_Date', $next); $this->assertEquals($due->timestamp(), $next->timestamp()); $result2->toggleComplete(); $result2->save(); $result3 = self::$driver->get($id[0]); $due->mday++; $next = $result3->getNextDue(); $this->assertInstanceOf('Horde_Date', $next); $this->assertEquals($due->timestamp(), $next->timestamp()); $this->assertFalse($result3->recurrence->hasCompletion($due->year, $due->month, $due->mday)); $due->mday--; $this->assertTrue($result3->recurrence->hasCompletion($due->year, $due->month, $due->mday)); $due->mday--; $this->assertTrue($result3->recurrence->hasCompletion($due->year, $due->month, $due->mday)); }
public function getSearchCriteria($vars) { if (!$this->isValid() || !$this->isSubmitted()) { return null; } $this->getInfo($vars, $info); $criteria = array(); if ($GLOBALS['registry']->isAdmin(array('permission' => 'hermes:review'))) { if (!empty($info['employees'])) { $auth = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Auth')->create(); if (!$auth->hasCapability('list')) { $criteria['employee'] = explode(',', $info['employees']); } else { $criteria['employee'] = $info['employees']; } } } else { $criteria['employee'] = $GLOBALS['registry']->getAuth(); } if (!empty($info['clients'])) { $criteria['client'] = $info['clients']; } if (!empty($info['jobtypes'])) { $criteria['jobtype'] = $info['jobtypes']; } if (!empty($info['costobjects'])) { $criteria['costobject'] = $info['costobjects']; } if (!empty($info['start'])) { $dt = new Horde_Date($info['start']); $criteria['start'] = $dt->timestamp(); } if (!empty($info['end'])) { $dt = new Horde_Date($info['end']); $criteria['end'] = $dt->add(86400)->timestamp(); } if (isset($info['submitted']) && $info['submitted'] != '') { $criteria['submitted'] = $info['submitted']; } if (isset($info['exported']) && $info['exported'] != '') { $criteria['exported'] = $info['exported']; } if (isset($info['billable']) && $info['billable'] != '') { $criteria['billable'] = $info['billable']; } return $criteria; }
/** * Get the children of this gallery. * * @param integer $perm The permissions to limit to. * @param integer $from The child to start at. * @param integer $to The child to end with. * @param boolean $noauto Whether or not to automatically drill down to the * first grouping with more then one group. * * @return array A mixed array of Ansel_Gallery_Decorator_Date and * Ansel_Image objects. */ public function getGalleryChildren($perm = Horde_Perms::SHOW, $from = 0, $to = 0, $noauto = false) { // Cache the results static $children = array(); $fullkey = md5($noauto . $perm . $this->_gallery->id . serialize($this->_date) . 0 . 0); $cache_key = md5($noauto . $perm . $this->_gallery->id . serialize($this->_date) . $from . $to); if (!empty($children[$cache_key])) { return $children[$cache_key]; } elseif (!empty($children[$fullkey])) { return $this->_getArraySlice($children[$fullkey], $from, $to, true); } $ansel_storage = $GLOBALS['injector']->getInstance('Ansel_Storage'); // Get a list of all the subgalleries $this->_loadSubGalleries(); $params = array('fields' => array('image_id', 'image_original_date')); if (count($this->_subGalleries)) { $params['gallery_id'] = array_merge($this->_subGalleries, array($this->_gallery->id)); } else { $params['gallery_id'] = $this->_gallery->id; } $sorted_dates = array(); // See how specific the date is if (!count($this->_date) || empty($this->_date['year'])) { // All available images - grouped by year $images = $ansel_storage->listImages($params); $dates = array(); foreach ($images as $key => $image) { $dates[date('Y', $image['image_original_date'])][] = $key; } $keys = array_keys($dates); // Drill down further if we only have a single group if (!$noauto && count($keys) == 1) { $this->_date['year'] = array_pop($keys); return $this->getGalleryChildren($perm, $from, $to, $noauto); } sort($keys, SORT_NUMERIC); foreach ($keys as $key) { $sorted_dates[$key] = $dates[$key]; } $display_unit = 'year'; } elseif (empty($this->_date['month'])) { // Specific year - grouped by month $start = new Horde_Date(array('year' => $this->_date['year'], 'month' => 1, 'day' => 1)); // Last second of the year $end = new Horde_Date($start); $end->mday = 31; $end->month = 12; $end->hour = 23; $end->min = 59; $end->sec = 59; // Get the image ids and dates $params['filter'] = array(array('property' => 'originalDate', 'op' => '<=', 'value' => (int) $end->timestamp()), array('property' => 'originalDate', 'op' => '>=', 'value' => (int) $start->timestamp())); $images = $ansel_storage->listImages($params); $dates = array(); foreach ($images as $key => $image) { $dates[date('n', $image['image_original_date'])][] = $key; } $keys = array_keys($dates); // Only 1 date grouping here, automatically drill down if (!$noauto && count($keys) == 1) { $this->_date['month'] = array_pop($keys); return $this->getGalleryChildren($perm, $from, $to, $noauto); } sort($keys, SORT_NUMERIC); foreach ($keys as $key) { $sorted_dates[$key] = $dates[$key]; } $display_unit = 'month'; } elseif (empty($this->_date['day'])) { // A single month - group by day $start = new Horde_Date(array('year' => $this->_date['year'], 'month' => $this->_date['month'], 'day' => 1)); // Last second of the month $end = new Horde_Date($start); $end->mday = Horde_Date_Utils::daysInMonth($end->month, $end->year); $end->hour = 23; $end->min = 59; $end->sec = 59; $params['filter'] = array(array('property' => 'originalDate', 'op' => '<=', 'value' => (int) $end->timestamp()), array('property' => 'originalDate', 'op' => '>=', 'value' => (int) $start->timestamp())); $images = $ansel_storage->listImages($params); $dates = array(); foreach ($images as $key => $image) { $dates[date('d', $image['image_original_date'])][] = $key; } $keys = array_keys($dates); // Only a single grouping, go deeper if (!$noauto && count($keys) == 1) { $this->_date['day'] = array_pop($keys); return $this->getGalleryChildren($perm, $from, $to, $noauto); } sort($keys, SORT_NUMERIC); foreach ($keys as $key) { $sorted_dates[$key] = $dates[$key]; } $dates = $sorted_dates; $display_unit = 'day'; } else { // We are down to a specific day $start = new Horde_Date($this->_date); // Last second of this day $end = new Horde_Date($start->timestamp()); $end->hour = 23; $end->min = 59; $end->sec = 59; // Filter for this day $params['filter'] = array(array('property' => 'originalDate', 'op' => '<=', 'value' => (int) $end->timestamp()), array('property' => 'originalDate', 'op' => '>=', 'value' => (int) $start->timestamp())); // Only get what we need $params['offset'] = $from; $params['limit'] = $to; // Default to asking for just image_ids unset($params['fields']); // Get the image list $images = $ansel_storage->listImages($params); if ($images) { $results = $ansel_storage->getImages(array('ids' => $images, 'preserve' => true)); } else { $results = array(); } if ($this->_gallery->get('has_subgalleries')) { $images = array(); foreach ($results as $id => $image) { $image->gallery = $this->_gallery->id; $images[$id] = $image; } $children[$cache_key] = $images; } else { $children[$cache_key] = $results; } return $children[$cache_key]; } $results = array(); foreach ($sorted_dates as $key => $images) { /* Get the new date parameter */ switch ($display_unit) { case 'year': $date = array('year' => $key); break; case 'month': $date = array('year' => $this->_date['year'], 'month' => (int) $key); break; case 'day': $date = array('year' => (int) $this->_date['year'], 'month' => (int) $this->_date['month'], 'day' => (int) $key); } $obj = new Ansel_Gallery_Decorator_Date($this->_gallery, $images); $obj->setDate($date); $results[$key] = $obj; } $children[$cache_key] = $results; if ($from > 0 || $to > 0) { return $this->_getArraySlice($results, $from, $to, true); } return $results; }
/** * Build a EAS style FB string. Essentially, each digit represents 1/2 hour. * The values are as follows: * 0 - Free * 1 - Tentative * 2 - Busy * 3 - OOF * 4 - No data available. * * Though currently we only provide a Free/Busy/Unknown differentiation. * * @param stdClass $fb The fb information. An object containing: * - s: The start of the period covered. * - e: The end of the period covered. * - b: An array of busy periods. * * @param Horde_Date $start The start of the period requested by the client. * @param Horde_Date $end The end of the period requested by the client. * * @return string The EAS freebusy string. * @since 2.4.0 */ public static function buildFbString($fb, Horde_Date $start, Horde_Date $end) { if (empty($fb)) { return false; } // Convert all to UTC $start->setTimezone('UTC'); $end->setTimezone('UTC'); // Calculate total time span (end timestamp in non-inclusive). $end_ts = $end->timestamp() - 1; $start_ts = $start->timestamp(); $sec = $end_ts - $start_ts; $fb_start = new Horde_Date($fb->s); $fb_end = new Horde_Date($fb->e); $fb_start->setTimezone('UTC'); $fb_end->setTimezone('UTC'); // Number of 30 minute periods. $period_cnt = ceil($sec / 1800); // Requested range is completely out of the available range. if ($start_ts >= $fb_end->timestamp() || $end_ts < $fb_start->timestamp()) { return str_repeat('4', $period_cnt); } // We already know we don't have any busy periods. if (empty($fb->b) && $fb_end->timestamp() <= $end_ts) { return str_repeat('0', $period_cnt); } $eas_fb = ''; // Move $start to the start of the available data. while ($start_ts < $fb_start->timestamp() && $start_ts <= $end_ts) { $eas_fb .= '4'; $start_ts += 1800; // 30 minutes } // The rest is assumed free up to $fb->e while ($start_ts <= $fb_end->timestamp() && $start_ts <= $end_ts) { $eas_fb .= '0'; $start_ts += 1800; } // The remainder is also unavailable while ($start_ts <= $end_ts) { $eas_fb .= '4'; $start_ts += 1800; } // Now put in the busy blocks. Need to convert to UTC here too since // all fb data is returned as local tz. while (list($b_start, $b_end) = each($fb->b)) { $b_start = new Horde_Date($b_start); $b_start->setTimezone('UTC'); $b_end = new Horde_Date($b_end); $b_end->setTimezone('UTC'); if ($b_start->timestamp() > $end->timestamp()) { continue; } $offset = $b_start->timestamp() - $start->timestamp(); $duration = ceil(($b_end->timestamp() - $b_start->timestamp()) / 1800); if ($offset > 0) { $eas_fb = substr_replace($eas_fb, str_repeat('2', $duration), floor($offset / 1800), $duration); } } return $eas_fb; }
/** * Generate the HTML for a vEvent. */ protected function _vEventException($vevent, $id, $method = 'PUBLISH') { global $prefs, $registry; $attendees = null; $options = array(); try { if (($attendees = $vevent->getAttribute('ATTENDEE')) && !is_array($attendees)) { $attendees = array($attendees); } } catch (Horde_Icalendar_Exception $e) { } $view = $this->_getViewOb(); try { $start = $vevent->getAttribute('DTSTART'); $view->start = is_array($start) ? strftime($prefs->getValue('date_format'), mktime(0, 0, 0, $start['month'], $start['mday'], $start['year'])) : strftime($prefs->getValue('date_format'), $start) . ' ' . date($prefs->getValue('twentyFour') ? ' G:i' : ' g:i a', $start); } catch (Horde_Icalendar_Exception $e) { $start = null; } try { $end = $vevent->getAttribute('DTEND'); // Check for exceptions that are over and done with. $d = new Horde_Date($end); if ($d->timestamp() < time()) { return false; } $view->end = is_array($end) ? strftime($prefs->getValue('date_format'), mktime(0, 0, 0, $end['month'], $end['mday'], $end['year'])) : strftime($prefs->getValue('date_format'), $end) . ' ' . date($prefs->getValue('twentyFour') ? ' G:i' : ' g:i a', $end); } catch (Horde_Icalendar_Exception $e) { $end = null; } try { $summary = $vevent->getAttribute('SUMMARY'); $view->summary = $summary; } catch (Horde_Icalendar_Exception $e) { $summary = _("Unknown Meeting"); $view->summary_error = _("None"); } try { $view->desc2 = $vevent->getAttribute('DESCRIPTION'); } catch (Horde_Icalendar_Exception $e) { } try { $view->loc = $vevent->getAttribute('LOCATION'); } catch (Horde_Icalendar_Exception $e) { } if (!empty($attendees)) { $view->attendees = $this->_parseAttendees($vevent, $attendees); } if (!is_null($start) && !is_null($end) && in_array($method, array('PUBLISH', 'REQUEST', 'ADD')) && $registry->hasMethod('calendar/getFbCalendars') && $registry->hasMethod('calendar/listEvents')) { try { $calendars = $registry->call('calendar/getFbCalendars'); $vevent_start = new Horde_Date($start); $vevent_end = new Horde_Date($end); // Check if it's an all-day event. if (is_array($start)) { $vevent_allDay = true; $vevent_end = $vevent_end->sub(1); } else { $vevent_allDay = false; $time_span_start = $vevent_start->sub($prefs->getValue('conflict_interval') * 60); $time_span_end = $vevent_end->add($prefs->getValue('conflict_interval') * 60); } $events = $registry->call('calendar/listEvents', array($start, $vevent_end, $calendars, false)); // TODO: Check if there are too many events to show. $conflicts = array(); foreach ($events as $calendar) { foreach ($calendar as $event) { // TODO: WTF? Why are we using Kronolith constants // here? if (in_array($event->status, array(Kronolith::STATUS_CANCELLED, Kronolith::STATUS_FREE))) { continue; } if ($vevent_allDay || $event->isAllDay()) { $type = 'collision'; } elseif ($event->end->compareDateTime($time_span_start) <= -1 || $event->start->compareDateTime($time_span_end) >= 1) { continue; } elseif ($event->end->compareDateTime($vevent_start) <= -1 || $event->start->compareDateTime($vevent_end) >= 1) { $type = 'nearcollision'; } else { $type = 'collision'; } $conflicts[] = array('collision' => $type == 'collision', 'range' => $event->getTimeRange(), 'title' => $event->getTitle()); } } if (!empty($conflicts)) { $view->conflicts = $conflicts; } } catch (Horde_Exception $e) { } } if (!empty($options)) { reset($options); $view->options = $options; $view->options_id = $id; } return $view->render('action'); }
protected function _testGetRecentObjects() { $recent = self::$tagger->getRecentObjects(); $this->assertEquals(4, count($recent)); $this->assertEquals(4, $recent[0]['object_id']); $date = new Horde_Date($recent[0]['created'], 'UTC'); $this->assertEquals(1230764760, $date->timestamp()); }
public function saveTask() { $results = new stdClass(); $task = array('name' => $this->vars->task_title, 'desc' => $this->vars->task_desc, 'assignee' => $this->vars->task_assignee, 'priority' => $this->vars->task_priority, 'owner' => $GLOBALS['registry']->getAuth()); if ($this->vars->task_private) { $task['private'] = true; } if ($this->vars->task_start) { $date = new Horde_Date($this->vars->task_start); $task['start'] = $date->timestamp(); } if ($this->vars->task_due) { $date = new Horde_Date($this->vars->task_due); $task['due'] = $date->timestamp(); } if ($this->vars->task_estimate) { $task['estimate'] = $this->vars->task_estimate; } if ($this->vars->task_completed) { $task['completed'] = $this->vars->task_completed == 'on' ? true : false; } if ($this->vars->tasklist) { $tasklist = $this->vars->tasklist; } else { $tasklist = $GLOBALS['prefs']->getValue('default_tasklist'); } try { $storage = $GLOBALS['injector']->getInstance('Nag_Factory_Driver')->create($tasklist); } catch (Nag_Exception $e) { $GLOBALS['notification']->push($e); return $results; } if ($this->vars->task_id) { // Existing task try { $existing_task = $storage->get($this->vars->task_id); $existing_task->merge($task); $existing_task->save(); $results->task = $existing_task->toJson(true); } catch (Nag_Exception $e) { $GLOBALS['notification']->push($e); return $results; } catch (Horde_Exception_NotFound $e) { $GLOBALS['notification']->push($e); return $results; } } else { try { $ids = $storage->add($task); $results->task = $storage->get($ids[0])->toJson(true); } catch (Nag_Exception $e) { $GLOBALS['notification']->push($e); return $results; } } $GLOBALS['notification']->push(sprintf(_("Saved %s"), $task['name']), 'horde.success'); return $results; }
/** * Returns the width of this span in seconds. */ public function width() { return abs($this->end->timestamp() - $this->begin->timestamp()); }
/** * Generates the free/busy text for $calendars. * * @param string|array $calendars The calendar to view free/busy slots for. * @param integer $startstamp The start of the time period to retrieve. * @param integer $endstamp The end of the time period to retrieve. * @param boolean $returnObj Default false. Return a vFreebusy object * instead of text. * @param string $user Set organizer to this user. * * @return string The free/busy text. * @throws Horde_Exception, Kronolith_Exception */ public static function generate($calendars, $startstamp = null, $endstamp = null, $returnObj = false, $user = null) { if (!is_array($calendars)) { $calendars = array($calendars); } if (!$user) { $kronolith_shares = $GLOBALS['injector']->getInstance('Kronolith_Shares'); /* Find a share and retrieve owner. */ foreach ($calendars as $calendar) { if (strpos($calendar, 'internal_') !== 0) { continue; } $calendar = substr($calendar, 9); try { $share = $kronolith_shares->getShare($calendar); $user = $share->get('owner'); break; } catch (Horde_Exception $e) { } } } /* Default the start date to today. */ if (is_null($startstamp)) { $startstamp = mktime(0, 0, 0); } /* Default the end date to the start date + freebusy_days. */ if (is_null($endstamp) || $endstamp < $startstamp) { $enddate = new Horde_Date($startstamp); $enddate->mday += $GLOBALS['prefs']->getValue('freebusy_days'); $endstamp = $enddate->timestamp(); } else { $enddate = new Horde_Date($endstamp); } /* Get the Identity for the owner of the share. */ $identity = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create($user); $email = $identity->getValue('from_addr'); $cn = $identity->getValue('fullname'); if (empty($email) && empty($cn)) { $cn = $user; } /* Fetch events. */ $busy = array(); foreach ($calendars as $calendar) { if (strpos($calendar, '_')) { @(list($type, $calendar) = explode('_', $calendar, 2)); } else { $type = 'internal'; } try { $GLOBALS['injector']->getInstance('Kronolith_Shares')->getShare($calendar); } catch (Horde_Exception $e) { throw new Kronolith_Exception('Share not found.'); } try { $driver = Kronolith::getDriver($type, $calendar); $events = $driver->listEvents(new Horde_Date($startstamp), $enddate, array('show_recurrence' => true)); Kronolith::mergeEvents($busy, $events); } catch (Exception $e) { } } /* Create the new iCalendar. */ $vCal = new Horde_Icalendar(); $vCal->setAttribute('PRODID', '-//The Horde Project//Kronolith ' . $GLOBALS['registry']->getVersion() . '//EN'); $vCal->setAttribute('METHOD', 'PUBLISH'); /* Create new vFreebusy. */ $vFb = Horde_Icalendar::newComponent('vfreebusy', $vCal); $params = array(); if (!empty($cn)) { $params['CN'] = $cn; } if (!empty($email)) { $vFb->setAttribute('ORGANIZER', 'mailto:' . $email, $params); } else { $vFb->setAttribute('ORGANIZER', '', $params); } $vFb->setAttribute('DTSTAMP', $_SERVER['REQUEST_TIME']); $vFb->setAttribute('DTSTART', $startstamp); $vFb->setAttribute('DTEND', $endstamp); $vFb->setAttribute('URL', Horde::url('fb.php?u=' . $user, true, -1)); /* Add all the busy periods. */ foreach ($busy as $events) { foreach ($events as $event) { if ($event->status == Kronolith::STATUS_FREE) { continue; } if ($event->status == Kronolith::STATUS_CANCELLED) { continue; } /* Horde_Icalendar_Vfreebusy only supports timestamps at the * moment. */ $vFb->addBusyPeriod('BUSY', $event->start->timestamp(), null, $event->end->timestamp() - $event->start->timestamp()); } } /* Remove the overlaps. */ $vFb->simplify(); $vCal->addComponent($vFb); /* Return the vFreebusy object if requested. */ if ($returnObj) { return $vFb; } /* Generate the vCal file. */ return $vCal->exportvCalendar(); }
/** * Create a nag Task object from an activesync message * * @param Horde_ActiveSync_Message_Task $message The task object */ public function fromASTask(Horde_ActiveSync_Message_Task $message) { /* Owner is always current user. */ $this->owner = $GLOBALS['registry']->getAuth(); /* Must set _tags so we don't lazy load tags from the backend in the * case that this is an edit. For edits, all current tags will be passed * from the client. */ $this->_tags = array(); /* Notes and Title */ if ($message->getProtocolVersion() >= Horde_ActiveSync::VERSION_TWELVE) { if ($message->airsyncbasebody->type == Horde_ActiveSync::BODYPREF_TYPE_HTML) { $this->desc = Horde_Text_Filter::filter($message->airsyncbasebody->data, 'Html2text'); } else { $this->desc = $message->airsyncbasebody->data; } } else { $this->desc = $message->body; } $this->name = $message->subject; $tz = date_default_timezone_get(); /* Completion */ if ($this->completed = $message->complete) { if ($message->datecompleted) { $message->datecompleted->setTimezone($tz); $this->completed_date = $message->datecompleted->timestamp(); } else { $this->completed_date = null; } } /* Due Date */ if ($due = $message->utcduedate) { $due->setTimezone($tz); $this->due = $due->timestamp(); } elseif ($due = $message->duedate) { // "Local" date, sent as a UTC datetime string, // but must be interpreted as a local time. Since // we have no timezone information we have to assume it's the // same as $tz. $due = new Horde_Date(array('year' => $due->year, 'month' => $due->month, 'mday' => $due->mday, 'hour' => $due->hour, 'min' => $due->min), $tz); $this->due = $due->timestamp(); } /* Start Date */ if ($start = $message->utcstartdate) { $start->setTimezone($tz); $this->start = $start->timestamp(); } elseif ($start = $message->startdate) { // See note above regarding utc vs local times. $start = new Horde_Date(array('year' => $start->year, 'month' => $start->month, 'mday' => $start->mday, 'hour' => $start->hour, 'min' => $start->min), $tz); $this->start = $start->timestamp(); } /* Priority */ switch ($message->getImportance()) { case Horde_ActiveSync_Message_Task::IMPORTANCE_LOW: $this->priority = 5; break; case Horde_ActiveSync_Message_Task::IMPORTANCE_NORMAL: $this->priority = 3; break; case Horde_ActiveSync_Message_Task::IMPORTANCE_HIGH: $this->priority = 1; break; default: $this->priority = 3; } if (($alarm = $message->getReminder()) && $this->due) { $alarm->setTimezone($tz); $this->alarm = ($this->due - $alarm->timestamp()) / 60; } if ($rrule = $message->getRecurrence()) { $this->recurrence = $rrule; } $this->tasklist = $GLOBALS['prefs']->getValue('default_tasklist'); /* Categories */ if (is_array($message->categories) && count($message->categories)) { $this->tags = implode(',', $message->categories); } }
/** * Check for, and handle, image editing actions. * * @param string $actionID The action identifier. * * @return boolean True if an action was handled, otherwise false. * @throws Ansel_Exception */ public static function editActions($actionID) { global $notification, $page_output, $registry; $ansel_storage = $GLOBALS['injector']->getInstance('Ansel_Storage'); $gallery_id = Horde_Util::getFormData('gallery'); $image_id = Horde_Util::getFormData('image'); $date = Ansel::getDateParameter(); $page = Horde_Util::getFormData('page', 0); $watermark_font = Horde_Util::getFormData('font'); $watermark_halign = Horde_Util::getFormData('whalign'); $watermark_valign = Horde_Util::getFormData('wvalign'); $watermark = Horde_Util::getFormData('watermark', $GLOBALS['prefs']->getValue('watermark_text')); // Get the gallery object and style information. try { $gallery = $ansel_storage->getGallery($gallery_id); } catch (Ansel_Exception $e) { $notification->push(sprintf(_("Gallery %s not found."), $gallery_id), 'horde.error'); Ansel::getUrlFor('view', array('view' => 'List'), true)->redirect(); exit; } switch ($actionID) { case 'modify': try { $image = $ansel_storage->getImage($image_id); $ret = Horde_Util::getFormData('ret', 'gallery'); } catch (Ansel_Exception $e) { $notification->push(_("Photo not found."), 'horde.error'); Ansel::getUrlFor('view', array('view' => 'List'), true)->redirect(); exit; } $title = sprintf(_("Edit properties :: %s"), $image->filename); // Set up the form object. $vars = Horde_Variables::getDefaultVariables(); if ($ret == 'gallery') { $vars->set('actionID', 'saveclose'); } else { $vars->set('actionID', 'savecloseimage'); } $form = new Ansel_Form_Image($vars, $title); $renderer = new Horde_Form_Renderer(); // Set up the gallery attributes. $vars->set('image_default', $image->id == $gallery->get('default')); $vars->set('image_desc', $image->caption); $vars->set('image_tags', implode(', ', $image->getTags())); $vars->set('image_originalDate', $image->originalDate); $vars->set('image_uploaded', $image->uploaded); $page_output->header(array('title' => $title)); $form->renderActive($renderer, $vars, Horde::url('image.php'), 'post', 'multipart/form-data'); $page_output->footer(); exit; case 'savecloseimage': case 'saveclose': case 'save': $title = _("Save Photo"); if (!$gallery->hasPermission($registry->getAuth(), Horde_Perms::EDIT)) { $notification->push(_("Access denied saving photo to this gallery."), 'horde.error'); Ansel::getUrlFor('view', array_merge(array('gallery' => $gallery_id, 'slug' => $gallery->get('slug'), 'view' => 'Gallery', 'page' => $page), $date), true)->redirect(); exit; } // Validate the form object. $vars = Horde_Variables::getDefaultVariables(); $vars->set('actionID', 'save'); $renderer = new Horde_Form_Renderer(); $form = new Ansel_Form_Image($vars, _("Edit a photo")); // Update existing image. if ($form->validate($vars)) { $form->getInfo($vars, $info); // Replacing photo if (!empty($info['file0']['file'])) { try { $GLOBALS['browser']->wasFileUploaded('file0'); if (filesize($info['file0']['file'])) { $data = file_get_contents($info['file0']['file']); if (getimagesize($info['file0']['file']) === false) { $notification->push(_("The file you uploaded does not appear to be a valid photo."), 'horde.error'); unset($data); } } } catch (Horde_Browser_Exception $e) { } } $image = $ansel_storage->getImage($image_id); $image->caption = $vars->get('image_desc'); $image->setTags(explode(',', $vars->get('image_tags'))); $newDate = new Horde_Date($vars->get('image_originalDate')); $image->originalDate = (int) $newDate->timestamp(); if (!empty($data)) { try { $image->replace($data); } catch (Ansel_Exception $e) { $notification->push(_("There was an error replacing the photo."), 'horde.error'); } } $image->save(); if ($vars->get('image_default')) { if ($gallery->get('default') != $image_id) { // Changing default - force refresh of stack // If we have a default-pretty already, make sure we delete it $ids = unserialize($gallery->get('default_prettythumb')); if (is_array($ids)) { foreach ($ids as $imageId) { $gallery->removeImage($imageId, true); } } $gallery->set('default_prettythumb', ''); } $gallery->set('default', $image_id); $gallery->set('default_type', 'manual'); } elseif ($gallery->get('default') == $image_id) { // Currently set as default, but we no longer wish it. $gallery->set('default', 0); $gallery->set('default_type', 'auto'); // If we have a default-pretty already, make sure we delete it $ids = unserialize($gallery->get('default_prettythumb')); if (is_array($ids)) { foreach ($ids as $imageId) { $gallery->removeImage($imageId); } } $gallery->set('default_prettythumb', ''); } $gallery->save(); $imageurl = Ansel::getUrlFor('view', array_merge(array('gallery' => $gallery_id, 'image' => $image_id, 'view' => 'Image', 'page' => $page), $date), true); if ($actionID == 'save') { $imageurl->redirect(); } elseif ($actionID == 'saveclose') { $page_output->addInlineScript(array('window.opener.location.href = window.opener.location.href;', 'window.close();')); $page_output->outputInlineScript(); } else { $page_output->addInlineScript(array('window.opener.location.href = "' . $imageurl . '";', 'window.close();')); $page_output->outputInlineScript(); } exit; } break; case 'editimage': case 'cropedit': case 'resizeedit': $imageGenerator_url = Ansel::getUrlFor('view', array_merge(array('gallery' => $gallery_id, 'image' => $image_id, 'view' => 'Image', 'page' => $page), $date), true); $imageurl = Horde::url('image.php')->add(array_merge(array('gallery' => $gallery_id, 'slug' => $gallery->get('slug'), 'image' => $image_id, 'page' => $page), $date)); $galleryurl = Ansel::getUrlFor('view', array_merge(array('gallery' => $gallery_id, 'page' => $page, 'view' => 'Gallery', 'slug' => $gallery->get('slug')), $date)); if (!$gallery->hasPermission($registry->getAuth(), Horde_Perms::EDIT)) { $notification->push(_("Access denied editing the photo."), 'horde.error'); // Return to the image view. $imageGenerator_url->redirect(); exit; } // Retrieve image details. $image = $ansel_storage->getImage($image_id); $title = sprintf(_("Edit %s :: %s"), $gallery->get('name'), $image->filename); if ($actionID == 'cropedit') { $geometry = $image->getDimensions('full'); $x1 = 0; $y1 = 0; $x2 = $geometry['width']; $y2 = $geometry['height']; // js and css files $page_output->addScriptFile('scriptaculous/builder.js', 'horde'); $page_output->addScriptFile('scriptaculous/effects.js', 'horde'); $page_output->addScriptFile('scriptaculous/controls.js', 'horde'); $page_output->addScriptFile('scriptaculous/dragdrop.js', 'horde'); $page_output->addScriptFile('cropper.js'); $page_output->addInlineScript('imageCropper.init();', true); $page_output->addThemeStylesheet('cropper.css'); } elseif ($actionID == 'resizeedit') { // js and css files $geometry = $image->getDimensions('full'); $page_output->addScriptFile('scriptaculous/builder.js', 'horde'); $page_output->addScriptFile('scriptaculous/effects.js', 'horde'); $page_output->addScriptFile('scriptaculous/controls.js', 'horde'); $page_output->addScriptFile('scriptaculous/dragdrop.js', 'horde'); $page_output->addScriptFile('scriptaculous/slider.js', 'horde'); $page_output->addScriptFile('resizeimage.js'); $js = array('window.Ansel = window.Ansel || {}', 'Ansel.image_geometry = ' . Horde_Serialize::serialize($geometry, Horde_Serialize::JSON), "Ansel.slider = new Control.Slider(\n 'handle1',\n 'slider-track',\n {\n minimum: 1,\n maximum: Ansel.image_geometry['width'],\n sliderValue: Ansel.image_geometry['width'],\n handleImage: 'ansel_slider_img',\n axis: 'horizontal',\n onChange: function(e) { resizeImage(e * Ansel.image_geometry['width']); },\n onSlide: function(e) { resizeImage(e * Ansel.image_geometry['width']); }\n }\n );"); $page_output->addInlineScript($js, true); } $page_output->header(array('title' => $title)); $notification->notify(array('listeners' => 'status')); if ($actionID == 'cropedit') { require ANSEL_TEMPLATES . '/image/crop_image.inc'; } elseif ($actionID == 'resizeedit') { require ANSEL_TEMPLATES . '/image/resize_image.inc'; } else { require ANSEL_TEMPLATES . '/image/edit_image.inc'; } $page_output->footer(); exit; case 'watermark': if ($watermark) { $identity = $injector->getInstance('Horde_Core_Factory_Identity')->create(); $name = $identity->getValue('fullname'); if (empty($name)) { $name = $registry->getAuth(); } // Set up array of possible substitutions. $watermark_array = array('%N' => $name, '%L' => $registry->getAuth()); $watermark = str_replace(array_keys($watermark_array), array_values($watermark_array), $watermark); $watermark = strftime($watermark); } if (!$gallery->hasPermission($registry->getAuth(), Horde_Perms::EDIT)) { $notification->push(_("Access denied saving photo to this gallery."), 'horde.error'); // Return to the image view Ansel::getUrlFor('view', array_merge(array('gallery' => $gallery_id, 'image' => $image_id, 'view' => 'Image', 'page' => $page, 'slug' => $gallery->get('slug')), $date), true)->redirect(); exit; } else { $image = $ansel_storage->getImage($image_id); $image->watermark('screen', $watermark, $watermark_halign, $watermark_valign, $watermark_font); $image->updateData($image->raw('screen'), 'screen'); Horde::url('image.php', true)->add(array_merge(array('gallery' => $gallery_id, 'image' => $image_id, 'actionID' => 'editimage', 'page' => $page), $date))->redirect(); exit; } case 'rotate90': case 'rotate180': case 'rotate270': case 'flip': case 'mirror': case 'grayscale': case 'crop': case 'resize': if (!$gallery->hasPermission($registry->getAuth(), Horde_Perms::EDIT)) { $notification->push(_("Access denied saving photo to this gallery."), 'horde.error'); } else { try { $image = $ansel_storage->getImage($image_id); } catch (Ansel_Exception $e) { $notification->push($e->getMessage(), 'horde.error'); Ansel::getUrlFor('view', array('view' => 'List'), true)->redirect(); exit; } switch ($actionID) { case 'rotate90': case 'rotate180': case 'rotate270': $angle = intval(substr($actionID, 6)); try { $image->rotate('full', $angle); } catch (Ansel_Exception $e) { Horde::log($e->getMessage(), 'ERR'); $notification->push($e->getMessage(), 'horde.error'); $error = true; } break; case 'flip': try { $image->flip('full'); } catch (Ansel_Exception $e) { Horde::log($e->getMessage(), 'ERR'); $notification->push($e->getMessage(), 'horde.error'); $error = true; } break; case 'mirror': try { $image->mirror('full'); } catch (Ansel_Exception $e) { Horde::log($e->getMessage(), 'ERR'); $notification->push($e->getMessage(), 'horde.error'); $error = true; } break; case 'grayscale': try { $image->grayscale('full'); } catch (Ansel_Exception $e) { Horde::log($e->getMessage(), 'ERR'); $notification->push($e->getMessage(), 'horde.error'); $error = true; } break; case 'crop': $image->load('full'); $params = Horde_Util::getFormData('params'); list($x1, $y1, $x2, $y2) = explode('.', $params); try { $image->crop($x1, $y1, $x2, $y2); } catch (Ansel_Exception $e) { Horde::log($e->getMessage(), 'ERR'); $notification->push($e->getMessage(), 'horde.error'); $error = true; } break; case 'resize': $image->load('full'); $width = Horde_Util::getFormData('width'); $height = Horde_Util::getFormData('height'); try { $image->resize($width, $height, true); } catch (Ansel_Exception $e) { Horde::log($e->getMessage(), 'ERR'); $notification->push($e->getMessage(), 'horde.error'); $error = true; } break; } if (empty($error)) { $image->updateData($image->raw()); } } Horde::url('image.php', true)->add(array_merge(array('gallery' => $gallery_id, 'image' => $image_id, 'actionID' => 'editimage', 'page' => $page), $date))->redirect(); exit; case 'setwatermark': $title = _("Watermark"); try { $image = $ansel_storage->getImage($image_id); } catch (Ansel_Exception $e) { $notification->push($image->getMessage(), 'horde.error'); Ansel::getUrlFor('view', array('view' => 'List'), true)->redirect(); exit; } $vars = Horde_Variables::getDefaultVariables(); $vars->set('actionID', 'previewcustomwatermark'); $form = new Ansel_Form_Watermark($vars, _("Watermark")); $renderer = new Horde_Form_Renderer(); $page_output->header(array('title' => $title)); $form->renderActive($renderer, $vars, Horde::url('image.php'), 'post'); $page_output->footer(); exit; case 'previewcustomwatermark': $imageurl = Horde::url('image.php', true)->add(array_merge(array('gallery' => $gallery_id, 'image' => $image_id, 'page' => $page, 'watermark' => $watermark, 'font' => $watermark_font, 'whalign' => $watermark_halign, 'wvalign' => $watermark_valign, 'actionID' => 'previewwatermark'), $date)); $page_output->addInlineScript(array('window.opener.location.href = "' . $imageurl . '";', 'window.close();')); $page_output->outputInlineScript(); exit; case 'previewgrayscale': case 'previewwatermark': case 'previewflip': case 'previewmirror': case 'previewrotate90': case 'previewrotate180': case 'previewrotate270': $title = _("Edit Photo"); $action = substr($actionID, 7); $image = $ansel_storage->getImage($image_id); $title = sprintf(_("Preview changes for %s :: %s"), $gallery->get('name'), $image->filename); $page_output->header(array('title' => $title)); require ANSEL_TEMPLATES . '/image/preview_image.inc'; $page_output->footer(); exit; case 'imagerotate90': case 'imagerotate180': case 'imagerotate270': $view = Horde_Util::getFormData('view'); $angle = intval(substr($actionID, 11)); $image = $ansel_storage->getImage($image_id); $image->rotate($view, $angle); $image->display($view); exit; case 'imageflip': $view = Horde_Util::getFormData('view'); $image = $ansel_storage->getImage($image_id); $image->flip($view); $image->display($view); exit; case 'imagemirror': $view = Horde_Util::getFormData('view'); $image = $ansel_storage->getImage($image_id); $image->mirror($view); $image->display($view); exit; case 'imagegrayscale': $view = Horde_Util::getFormData('view'); $image = $ansel_storage->getImage($image_id); $image->grayscale($view); $image->display($view); exit; case 'imagewatermark': $view = Horde_Util::getFormData('view'); $image = $ansel_storage->getImage($image_id); $image->watermark($view, $watermark, $watermark_halign, $watermark_valign, $watermark_font); $image->display($view); exit; case 'previewcrop': if (!$gallery->hasPermission($registry->getAuth(), Horde_Perms::EDIT)) { $notification->push(_("Access denied editing the photo."), 'horde.error'); Ansel::getUrlFor('view', array('gallery' => $gallery_id, 'image' => $image_id, 'view' => 'Image', 'page' => $page))->redirect(); } else { $x1 = (int) Horde_Util::getFormData('x1'); $y1 = (int) Horde_Util::getFormData('y1'); $x2 = (int) Horde_Util::getFormData('x2'); $y2 = (int) Horde_Util::getFormData('y2'); $title = _("Crop"); $action = substr($actionID, 7); $image = $ansel_storage->getImage($image_id); $title = sprintf(_("Preview changes for %s :: %s"), $gallery->get('name'), $image->filename); $params = $x1 . '.' . $y1 . '.' . $x2 . '.' . $y2; $page_output->header(array('title' => $title)); require ANSEL_TEMPLATES . '/image/preview_cropimage.inc'; $page_output->footer(); } exit; case 'imagecrop': if ($gallery->hasPermission($registry->getAuth(), Horde_Perms::EDIT)) { $params = Horde_Util::getFormData('params'); list($x1, $y1, $x2, $y2) = explode('.', $params); $image = $ansel_storage->getImage($image_id); $image->load('full'); $image->crop($x1, $y1, $x2, $y2); $image->display(); } exit; } return false; }
/** * Lists tickets with due dates as time objects. * * @param array $categories The time categories (from listTimeObjectCategories) to list. * @param mixed $start The start date of the period. * @param mixed $end The end date of the period. */ public function listTimeObjects($categories, $start, $end) { global $whups_driver; $start = new Horde_Date($start); $start_ts = $start->timestamp(); $end = new Horde_Date($end); $end_ts = $end->timestamp(); $criteria['owner'] = Whups::getOwnerCriteria($GLOBALS['registry']->getAuth()); /* @TODO Use $categories */ $category = 'due'; switch ($category) { case 'assigned': $label = _("Assigned"); $criteria['ass'] = true; break; case 'created': $label = _("Created"); break; case 'due': $label = _("Due"); $criteria['nores'] = true; break; case 'resolved': $label = _("Resolved"); $criteria['res'] = true; break; } try { $tickets = $whups_driver->getTicketsByProperties($criteria); } catch (Whups_Exception $e) { return array(); } $objects = array(); foreach ($tickets as $ticket) { switch ($category) { case 'assigned': $t_start = $ticket['date_assigned']; break; case 'created': $t_start = $ticket['timestamp']; break; case 'due': if (empty($ticket['due'])) { continue 2; } $t_start = $ticket['due']; break; case 'resolved': $t_start = $ticket['date_resolved']; break; } if ($t_start + 1 < $start_ts || $t_start > $end_ts) { continue; } $t = new Whups_Ticket($ticket['id'], $ticket); $objects[$ticket['id']] = array('title' => sprintf('%s: [#%s] %s', $label, $ticket['id'], $ticket['summary']), 'description' => $t->toString(), 'id' => $ticket['id'], 'start' => date('Y-m-d\\TH:i:s', $t_start), 'end' => date('Y-m-d\\TH:i:s', $t_start + 1), 'params' => array('id' => $ticket['id']), 'link' => Whups::urlFor('ticket', $ticket['id'], true)); } return $objects; }
/** * Imports the values for this event from an array of values. * * @param array $hash Array containing all the values. * * @throws Kronolith_Exception */ public function fromHash($hash) { // See if it's a new event. if ($this->id === null) { $this->creator = $GLOBALS['registry']->getAuth(); } if (!empty($hash['title'])) { $this->title = $hash['title']; } else { throw new Kronolith_Exception(_("Events must have a title.")); } $this->start = null; if (!empty($hash['start_date'])) { $date = array_map('intval', explode('-', $hash['start_date'])); if (empty($hash['start_time'])) { $time = array(0, 0, 0); } else { $time = array_map('intval', explode(':', $hash['start_time'])); if (count($time) == 2) { $time[2] = 0; } } if (count($time) == 3 && count($date) == 3 && !empty($date[1]) && !empty($date[2])) { $this->start = new Horde_Date(array('year' => $date[0], 'month' => $date[1], 'mday' => $date[2], 'hour' => $time[0], 'min' => $time[1], 'sec' => $time[2]), isset($hash['timezone']) ? $hash['timezone'] : null); } } if (!isset($this->start)) { throw new Kronolith_Exception(_("Events must have a start date.")); } if (empty($hash['duration'])) { if (empty($hash['end_date'])) { $hash['end_date'] = $hash['start_date']; } if (empty($hash['end_time'])) { $hash['end_time'] = $hash['start_time']; } } else { $weeks = str_replace('W', '', $hash['duration'][1]); $days = str_replace('D', '', $hash['duration'][2]); $hours = str_replace('H', '', $hash['duration'][4]); $minutes = isset($hash['duration'][5]) ? str_replace('M', '', $hash['duration'][5]) : 0; $seconds = isset($hash['duration'][6]) ? str_replace('S', '', $hash['duration'][6]) : 0; $hash['duration'] = $weeks * 60 * 60 * 24 * 7 + $days * 60 * 60 * 24 + $hours * 60 * 60 + $minutes * 60 + $seconds; $this->end = new Horde_Date($this->start); $this->end->sec += $hash['duration']; } if (!empty($hash['end_date'])) { $date = array_map('intval', explode('-', $hash['end_date'])); if (empty($hash['end_time'])) { $time = array(0, 0, 0); } else { $time = array_map('intval', explode(':', $hash['end_time'])); if (count($time) == 2) { $time[2] = 0; } } if (count($time) == 3 && count($date) == 3 && !empty($date[1]) && !empty($date[2])) { $this->end = new Horde_Date(array('year' => $date[0], 'month' => $date[1], 'mday' => $date[2], 'hour' => $time[0], 'min' => $time[1], 'sec' => $time[2]), isset($hash['timezone']) ? $hash['timezone'] : null); } } if (!empty($hash['alarm'])) { $this->alarm = (int) $hash['alarm']; } elseif (!empty($hash['alarm_date']) && !empty($hash['alarm_time'])) { $date = array_map('intval', explode('-', $hash['alarm_date'])); $time = array_map('intval', explode(':', $hash['alarm_time'])); if (count($time) == 2) { $time[2] = 0; } if (count($time) == 3 && count($date) == 3 && !empty($date[1]) && !empty($date[2])) { $alarm = new Horde_Date(array('year' => $date[0], 'month' => $date[1], 'mday' => $date[2], 'hour' => $time[0], 'min' => $time[1], 'sec' => $time[2]), isset($hash['timezone']) ? $hash['timezone'] : null); $this->alarm = ($this->start->timestamp() - $alarm->timestamp()) / 60; } } $this->allday = !empty($hash['allday']); if (!empty($hash['description'])) { $this->description = $hash['description']; } if (!empty($hash['location'])) { $this->location = $hash['location']; } // Import once we support organizers. /* if (!empty($hash['organizer'])) { $this->organizer = $hash['organizer']; } */ if (!empty($hash['private'])) { $this->private = true; } if (!empty($hash['recur_type'])) { $this->recurrence = new Horde_Date_Recurrence($this->start); $this->recurrence->setRecurType($hash['recur_type']); if (!empty($hash['recur_count'])) { $this->recurrence->setRecurCount($hash['recur_count']); } elseif (!empty($hash['recur_end_date'])) { $date = array_map('intval', explode('-', $hash['recur_end_date'])); if (count($date) == 3 && !empty($date[1]) && !empty($date[2])) { $this->recurrence->setRecurEnd(new Horde_Date(array('year' => $date[0], 'month' => $date[1], 'mday' => $date[2]))); } } if (!empty($hash['recur_interval'])) { $this->recurrence->setRecurInterval($hash['recur_interval']); } if (!empty($hash['recur_data'])) { $this->recurrence->setRecurOnDay($hash['recur_data']); } if (!empty($hash['recur_exceptions'])) { foreach ($hash['recur_exceptions'] as $exception) { $parts = explode('-', $exception); if (count($parts) == 3) { $this->recurrence->addException($parts[0], $parts[1], $parts[2]); } } } } if (isset($hash['sequence'])) { $this->sequence = $hash['sequence']; } if (!empty($hash['tags'])) { $this->tags = $hash['tags']; } if (!empty($hash['timezone'])) { $this->timezone = $hash['timezone']; } if (!empty($hash['uid'])) { $this->uid = $hash['uid']; } $this->initialized = true; }
/** * Lists vacation rules as timeobject. * * @param array $time_categories The time categories (from * listTimeObjectCategories) to list. * @param mixed $start The start date of the period. * @param mixed $end The end date of the period. * * @return array An array of timeObject results. * @throws Turba_Exception */ public function listTimeObjects(array $time_categories, $start, $end) { global $injector; if (!in_array('vacation', $time_categories)) { return array(); } $vacation = $injector->getInstance('Ingo_Factory_Storage')->create()->getSystemRule('Ingo_Rule_System_Vacation'); // Don't return any inactive rules. if ($vacation->disable) { return array(); } // Ensure these are Horde_Dates $start = new Horde_Date($start); $end = new Horde_Date($end); // Use the vacation dates if possible otherwise use the full range // asked for. $vac_start = $vacation->start ? $vacation->start : $start->timestamp(); $vac_end = $vacation->end ? $vacation->end : $end->timestamp(); if ($vac_start <= $end->timestamp() && $vac_end >= $start->timestamp()) { return array($vacation->uid => array('id' => $vacation->uid, 'title' => $vacation->subject, 'start' => $vacation->start, 'end' => $vacation->end, 'link' => Ingo_Basic_Vacation::url())); } return array(); }
public function testStrftimeUnsupported() { setlocale(LC_TIME, 'en_US.UTF-8'); $date = new Horde_Date('2001-02-03 16:05:06'); $this->assertEquals(strftime('%a', $date->timestamp()), $date->strftime('%a')); }
/** * Lists all events in the given time range. * * @param Horde_Date $startDate Start of range date object. * @param Horde_Date $endDate End of range data object. * * @return array Events in the given time range. * * @throws Horde_Kolab_FreeBusy_Exception If retrieving the events failed. */ public function listEvents(Horde_Date $startDate, Horde_Date $endDate) { try { $objects = $this->getData()->getObjects(); } catch (Horde_Kolab_Storage_Exception $e) { //todo: prior exception throw new Horde_Kolab_FreeBusy_Exception($e); } $startts = $startDate->timestamp(); $endts = $endDate->timestamp(); $result = array(); /** * PERFORMANCE START * * The following section has been performance optimized using * xdebug and kcachegrind. * * If there are many events it takes a lot of time and memory to create * new objects from the array and use those for time comparison. So the * code tries to use the original data array as long as possible and * only converts it to an object if really required (e.g. the event * actually lies in the time span or it recurs in which case the * calculations are more complex). */ foreach ($objects as $object) { /* check if event period intersects with given period */ if (!($object['start-date'] > $endts || $object['end-date'] < $startts)) { $result[] = new Horde_Kolab_FreeBusy_Object_Event($object); continue; } /* do recurrence expansion if not keeping anyway */ if (isset($object['recurrence'])) { $event = new Horde_Kolab_FreeBusy_Object_Event($object); if ($event->recursIn($startDate, $endDate)) { $result[] = $event; } } } /** PERFORMANCE END */ return $result; }