/** * Test convertMinutesToHours */ public function testConvertMinutesToHours() { $converter = new Phprojekt_Converter_Time(); $this->assertEquals('00:20', $converter->convertMinutesToHours(20)); $this->assertEquals('01:20', $converter->convertMinutesToHours(80)); $this->assertEquals('10:05', $converter->convertMinutesToHours(605)); }
/** * Sets a fields definitions for each field. * * @return void */ public function setFields() { // username $this->fillField('username', 'Username', 'text', 1, 1, array('required' => true, 'length' => 255)); // password $this->fillField('password', 'Password', 'password', 0, 2, array('length' => 50)); // firstname $this->fillField('firstname', 'First name', 'text', 2, 3, array('required' => true, 'length' => 255)); // lastname $this->fillField('lastname', 'Last name', 'text', 3, 4, array('required' => true, 'length' => 255)); // email $this->fillField('email', 'Email', 'text', 0, 5, array('length' => 255)); // language $range = array(); $languageRange = Phprojekt_LanguageAdapter::getLanguageList(); foreach ($languageRange as $key => $value) { $range[] = $this->getRangeValues($key, $value); } $this->fillField('language', 'Language', 'selectbox', 0, 6, array('range' => $range, 'required' => true, 'default' => 'en')); // timeZone $range = array(); $timeZoneRange = Phprojekt_Converter_Time::getTimeZones(); foreach ($timeZoneRange as $key => $value) { $range[] = $this->getRangeValues($key, $value); } $this->fillField('timeZone', 'Time zone', 'selectbox', 0, 7, array('range' => $range, 'required' => true, 'default' => '000')); // status $this->fillField('status', 'Status', 'selectbox', 4, 8, array('range' => array($this->getFullRangeValues('A', 'Active'), $this->getFullRangeValues('I', 'Inactive')), 'default' => 'A')); // admin $this->fillField('admin', 'Admin', 'selectbox', 5, 9, array('range' => array($this->getFullRangeValues(0, 'No'), $this->getFullRangeValues(1, 'Yes')), 'integer' => true, 'default' => 0)); }
/** * Returns the statistics data. * * Also return the Total per rows. * * OPTIONAL request parameters: * <pre> * - date <b>startDate</b> ISO start date for filter. * - date <b>endDate</b> ISO end date for filter. * - integer <b>nodeId</b> List all the projects under nodeId. * </pre> * * The return is in CSV format. * * @return void */ public function csvListAction() { $startDate = Cleaner::sanitize('date', $this->getRequest()->getParam('startDate', date("Y-m-d"))); $endDate = Cleaner::sanitize('date', $this->getRequest()->getParam('endDate', date("Y-m-d"))); $projectId = (int) $this->getRequest()->getParam('nodeId', null); $this->setCurrentProjectId(); $data = $this->getModelObject()->getStatistics($startDate, $endDate, $projectId); $data = $data['data']; $rows = array(); $sumPerUser = array(); $index = 0; $rows[$index][] = 'Project'; foreach ($data['users'] as $name) { $rows[$index][] = $name; } $rows[$index][] = 'Total'; $index++; $converter = new Phprojekt_Converter_Time(); foreach ($data['projects'] as $projectId => $title) { $sumPerProject = 0; $rows[$index][] = $title; foreach (array_keys($data['users']) as $userId) { if (!isset($data['rows'][$projectId][$userId])) { $rows[$index][] = $converter->convertMinutesToHours(0); } else { $rows[$index][] = $converter->convertMinutesToHours($data['rows'][$projectId][$userId]); $sumPerProject = $sumPerProject + $data['rows'][$projectId][$userId]; if (!isset($sumPerUser[$userId])) { $sumPerUser[$userId] = 0; } $sumPerUser[$userId] = $sumPerUser[$userId] + $data['rows'][$projectId][$userId]; } } $rows[$index][] = $converter->convertMinutesToHours($sumPerProject); $index++; } $rows[$index][] = 'Total'; $total = 0; foreach (array_keys($data['users']) as $userId) { if (!isset($sumPerUser[$userId])) { $rows[$index][] = $converter->convertMinutesToHours(0); } else { $rows[$index][] = $converter->convertMinutesToHours($sumPerUser[$userId]); $total = $total + $sumPerUser[$userId]; } } $rows[$index][] = $converter->convertMinutesToHours($total); Phprojekt_Converter_Csv::echoConvert($rows); }
/** * Returns not the IDs of the item, module, user, etc. but real values. * * @param integer $userId The ID of the user who calls this method. * * @return array Array with 'user', 'module', 'process', 'description', 'itemId', * 'item', 'projectId', 'details', 'time' and 'project'. */ public function getMessage($userId) { $messageData = $this->getMessageData($userId); $data = array(); $this->_deleteOutdatedMessages(); if (true === empty($messageData)) { return false; } $userObject = new Phprojekt_User_User(); $user = $userObject->find($messageData[0]->actorId); $data['user'] = $userObject->displayName; $data['module'] = ucfirst(Phprojekt_Module::getModuleName($messageData[0]->moduleId)); $data['process'] = $messageData[0]->process; $data['description'] = Phprojekt::getInstance()->translate($messageData[0]->description); $data['itemId'] = $messageData[0]->itemId; $data['item'] = $messageData[0]->itemName; $data['projectId'] = $messageData[0]->projectId; $data['details'] = $messageData[0]->details; // Convert time to user timezone if ($messageData[0]->process == Phprojekt_Notification::LAST_ACTION_REMIND) { $addTime = Phprojekt::getInstance()->getConfig()->remindBefore * 60; } else { $addTime = 0; } $data['time'] = date("H:i", Phprojekt_Converter_Time::utcToUser($messageData[0]->validFrom) + $addTime); // Convert project name $project = new Project_Models_Project(); $data['project'] = $project->find($data['projectId'])->title; return $data; }
/** * Return a value for get, using some validations from the table data. * * @param string $type Type of field. * @param mixed $value Value to transform. * * @return mixed Value of the var. */ public static function get($type, $value) { switch ($type) { case 'float': $value = Zend_Locale_Format::toFloat($value, array('precision' => 2)); break; case 'time': if (!empty($value)) { $value = date("H:i:s", Phprojekt_Converter_Time::utcToUser($value)); } break; case 'datetime': case 'timestamp': if (!empty($value)) { $value = date("Y-m-d H:i:s", Phprojekt_Converter_Time::utcToUser($value)); } break; case 'text': // Get html only if the text contain some html code if (preg_match("/([\\<])([^\\>]{1,})*([\\>])/i", $value)) { $value = stripslashes($value); } break; } return $value; }
/** * Apply the timezone to one datetime for use it in the database. * * @param string $dateTime The datetime to transform. * * @return string Datetime string. */ public function applyTimeZone($dateTime) { return date("Y-m-d H:i:s", Phprojekt_Converter_Time::userToUtc($dateTime)); }
/** * Defines the datetime from which the generated frontend message is valid. * * @return string Datetime string. */ public function getCalendarValidFrom() { $date = Phprojekt_Converter_Time::userToUtc($this->_model->startDatetime); $configMin = Phprojekt::getInstance()->getConfig()->remindBefore; $configMinInSec = $configMin * 60; return date("Y-m-d H:i:s", $date - $configMinInSec); }
/** * Excludes the given date from this series. * Do not call save() after this, or you might reset the rrule to the old value. * * @param Datetime $date The date to remove * * @return void */ protected function _excludeDate(Datetime $date) { // This function distinguishes three cases. // 1. This is the first event in the series. // 2. This is the last event in the series. // 3. Somewhere in between. if (empty($this->id)) { throw new Exception('Can only exclude dates from saved events'); } $series = clone $this; $series->find($this->id); $helper = $series->getRruleHelper(); if (!$helper->containsDate($date)) { throw new Exception('Trying to exclude date that is not part of this series'); } $start = new Datetime('@' . Phprojekt_Converter_Time::userToUtc($series->start)); $end = new Datetime('@' . Phprojekt_Converter_Time::userToUtc($series->end)); if ($start == $date) { // If it's the first in it's series, adjust the start date, // remove excluded dates that we skipped while doing that and // finally, check if we still need a rrule at all. $duration = $start->diff($end); $newStart = $helper->firstOccurrenceAfter($start); if (is_null($newStart)) { throw new Exception('$newStart should not be null'); } $newEnd = clone $newStart; $newEnd->add($duration); $series->start = Phprojekt_Converter_Time::utcToUser($newStart->format('Y-m-d H:i:s')); $series->end = Phprojekt_Converter_Time::utcToUser($newEnd->format('Y-m-d H:i:s')); // Delete all obsolete excludes $db = $this->getAdapter(); $where = $db->quoteInto('calendar2_id = ?', $this->id); $where .= $db->quoteInto('AND date < ?', $newStart->format('Y-m-d H:i:s')); $db->delete('calendar2_excluded_dates', $where); // Check if this is still a recurring event if ($helper->islastOccurrence($newStart)) { $series->rrule = null; } $series->save(); } elseif ($helper->isLastOccurrence($date)) { // If it's the last in it's series, adjust the Rrule and delete // now obsolete excludes. $newLast = $helper->lastOccurrenceBefore($date); // Check if this is still a recurring event if ($helper->isFirstOccurrence($newLast)) { $series->rrule = null; } else { // Adjust the rrule $series->rrule = preg_replace('/UNTIL=[^;]*/', "UNTIL={$newLast->format('Ymd\\THis\\Z')}", $series->rrule); } $series->save(); // Delete all obsolete excludes $db = $this->getAdapter(); $where = $db->quoteInto('calendar2_id = ?', $this->id); $where .= $db->quoteInto('AND date > ?', $newLast->format('Y-m-d H:i:s')); $db->delete('calendar2_excluded_dates', $where); } else { // If it's somewhere in between, just add it to the list of // excluded dates. $this->getAdapter()->insert('calendar2_excluded_dates', array('calendar2_id' => $this->id, 'date' => $date->format('Y-m-d H:i:s'))); } }
/** * Constructor. * * @return void */ public function __construct() { $this->_languageRange = Phprojekt_LanguageAdapter::getLanguageList(); $this->_timeZoneRange = Phprojekt_Converter_Time::getTimeZones(); }
/** * Converts a timecard join project join module row to a vobject string. * * @param array $entry * * @return string */ private function _getDataForEntry(array $entry) { $v = new Sabre_VObject_Component('vevent'); if (1 == $entry['project_id']) { $v->add('summary', Phprojekt::getInstance()->translate('Unassigned')); } else { $v->add('summary', $entry['title'] . ' [' . $entry['project_id'] . ']'); } $notes = trim($entry['notes']); if (!is_null($entry['module_id'])) { if ($notes) { $notes .= "\n"; } $notes .= Phprojekt::getInstance()->translate('There is an attachment of type ') . Phprojekt::getInstance()->translate($entry['label']); } if ($notes) { $v->add('description', $notes); } $start = new DateTime('@' . Phprojekt_Converter_Time::userToUtc($entry['start_datetime'])); $end = substr($entry['start_datetime'], 0, 11) . $entry['end_time']; $end = new DateTime('@' . Phprojekt_Converter_Time::userToUtc($end)); $v->add('dtstart', $start->format('Ymd\\THis\\Z')); $v->add('dtend', $end->format('Ymd\\THis\\Z')); $v->add('uid', 'phprojekt-timecard-entry' . $entry['uid']); $calendarData = new Sabre_VObject_Component('vcalendar'); $calendarData->add('version', '2.0'); $calendarData->add('prodid', 'Phprojekt ' . Phprojekt::getVersion()); $calendarData->add($v); return $calendarData->serialize(); }
private function applyICalendarTimes($start, $end, $timezoneID = null) { $utc = new DateTimezone('UTC'); $timezone = null; $userTimeZone = Phprojekt_User_User::getUserDateTimeZone(); if ('Z' === substr($start, -1)) { $timezone = $utc; } else { if (!is_null($timezoneID)) { $timezone = new DateTimeZone($timezoneID); } else { $timezone = $userTimeZone; } } // We can't use ->setTimezone with the timezones returned by getUserDateTimeZone, as these are non-standard // timezones. Unless we start storing correct timezones, we can't directly set the user timezone, so we go to // UTC and convert to usertime from there. Because utcToUser returns a unix timestamp, but ActiveRecords expects // a "Y-m-d H:i:s" timestamp, we have to go through Datetime again. $start = new Datetime($start, $timezone); $start->setTimezone($utc); $startTs = Phprojekt_Converter_Time::utcToUser($start->format('Y-m-d H:i:s')); $start = new Datetime('@' . $startTs); $end = new Datetime($end, $timezone); $end->setTimezone($utc); $endTs = Phprojekt_Converter_Time::utcToUser($end->format('Y-m-d H:i:s')); $end = new Datetime('@' . $endTs); if ($start->diff($end)->invert) { throw new Sabre_DAV_Exception_BadRequest('Start must be before End'); } $this->_timecard->startDatetime = $start->format('Y-m-d H:i:s'); if ($start->format('z') == $end->format('z')) { // Same day $this->_timecard->endTime = $end->format('H:i:s'); } else { $this->_timecard->endTime = '23:59:00'; } }
/** * Convert the rule and value into a real where clause. * * @param string $field Field for filter. * @param string $identifier Converted field for filter. * @param string $rule Rule for apply the filter. * @param string $keyword Value used for filter. * * @return string Where clause. */ private function _convertRule($field, $identifier, $rule, $keyword) { // Sanitize values if ($this->_info['metadata'][$identifier]['DATA_TYPE'] == 'time') { // Moving the value to UTC $identifier = $this->_record->getTableName() . '.' . $identifier; $identifier = Phprojekt::getInstance()->getDb()->quoteIdentifier($identifier); $value = Cleaner::sanitize('time', $keyword); $k = date("H:i:s", Phprojekt_Converter_Time::userToUtc($value)); //$identifier = 'TIME(' . $identifier . ')'; } else { if ($this->_info['metadata'][$identifier]['DATA_TYPE'] == 'datetime') { $identifier = $this->_record->getTableName() . '.' . $identifier; $identifier = Phprojekt::getInstance()->getDb()->quoteIdentifier($identifier); if (strstr($keyword, '-')) { // Use it as date $k = Cleaner::sanitize('date', $keyword); $identifier = 'DATE(' . $identifier . ')'; } else { if (strstr($keyword, ':')) { // Use it as time $value = Cleaner::sanitize('time', $keyword); $k = date("H:i:s", Phprojekt_Converter_Time::userToUtc($value)); $identifier = 'TIME(' . $identifier . ')'; } else { // Use it as datetime $value = Cleaner::sanitize('timestamp', $keyword); $k = date("Y-m-d H:i:s", Phprojekt_Converter_Time::userToUtc($value)); } } } else { $keyword = mb_strtolower($keyword, 'UTF-8'); $k = $keyword; $identifier = $this->_record->getTableName() . '.' . $identifier; $identifier = Phprojekt::getInstance()->getDb()->quoteIdentifier($identifier); } } switch ($rule) { case 'equal': $w = $identifier . ' = ? '; break; case 'notEqual': $w = $identifier . ' != ? '; break; case 'major': $w = $identifier . ' > ? '; break; case 'majorEqual': $w = $identifier . ' >= ? '; break; case 'minor': $w = $identifier . ' < ? '; break; case 'minorEqual': $w = $identifier . ' <= ? '; break; case 'begins': $w = $identifier . ' LIKE ? '; $k = $keyword . '%'; break; case 'ends': $w = $identifier . ' LIKE ? '; $k = '%' . $keyword; break; case 'notLike': $w = $identifier . ' NOT LIKE ? '; $k = '%' . $keyword . '%'; break; case 'like': default: $w = $identifier . ' LIKE ? '; $k = '%' . $keyword . '%'; } return Phprojekt::getInstance()->getDb()->quoteInto($w, $k); }
private static function _ldapIntegration($userId, $username, $password, $loginServer = null) { $userId = intval($userId); $conf = Phprojekt::getInstance()->getConfig(); $ldapOptions = $conf->authentication->ldap->toArray(); // Zend library does not allow determining from which server the user was found from // That's why we need to request the server from the user during login. $account = null; if ($loginServer !== null && array_key_exists($loginServer, $ldapOptions)) { $searchOpts = $ldapOptions[$loginServer]; try { $ldap = new Zend_Ldap($searchOpts); $ldap->connect(); $ldap->bind($username, $password); $filter = sprintf("(\n &(\n |(objectclass=posixAccount)\n (objectclass=Person)\n )\n (\n |(uid=%s)\n (samAccountName=%s)\n )\n )", $username, $username); $result = $ldap->search($filter, $searchOpts['baseDn']); $account = $result->getFirst(); $ldap->disconnect(); } catch (Exception $e) { throw new Phprojekt_Auth_Exception('Failed to establish a search connection to the LDAP server:' . ' ' . $server . ' ' . 'Please check your configuration for that server.', 8); } } else { throw new Phprojekt_Auth_Exception('Server not specified during login! " . "Please check that your login screen contains the login domain selection.', 9); } if ($account !== null) { // User found $integration = isset($conf->authentication->integration) ? $conf->authentication->integration->toArray() : array(); $firstname = ""; $lastname = ""; $email = ""; if (isset($account['givenname'])) { $firstname = $account['givenname'][0]; } if (isset($account['sn'])) { $lastname = $account['sn'][0]; } if (isset($account['mail'])) { $email = $account['mail'][0]; } // Set user params $params = array(); $params['id'] = intval($userId); // New user has id = 0 $params['username'] = $username; $params['password'] = $password; $admins = array(); if (isset($integration['systemAdmins'])) { $admins = split(",", $integration['systemAdmins']); foreach ($admins as $key => $admin) { $admins[$key] = trim($admin); } } $params['admin'] = in_array($username, $admins) ? 1 : 0; // Default to non-admin (0) if ($userId > 0) { $user = self::_getUser($userId); $params['admin'] = intval($user->admin); } // Integrate with parameters found from LDAP server $params['firstname'] = $firstname; $params['lastname'] = $lastname; $params['email'] = $email; if ($userId > 0) { // Update user parameters with those found from LDAP server $user->find($userId); $params['id'] = $userId; if (!self::_saveUser($params)) { throw new Phprojekt_Auth_Exception('User update failed for LDAP parameters', 10); } } else { // Add new user to PHProjekt // TODO: Default conf could be defined in configuration // Lists needed for checks ? // Set default parameters for users $params['status'] = "A"; // Active user $params['language'] = isset($conf->language) ? $conf->language : "en"; // Conf language / English $params['timeZone'] = "0000"; // (GMT) Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London // Default integration vals from config if (isset($integration['admin']) && $params['admin'] == 0) { $val = intval($integration['admin']); if ($val == 1 || $val == 0) { $params['admin'] = $val; } } if (isset($integration['status'])) { $val = trim(strtoupper($integration['status'])); if (in_array($val, array("A", "I"))) { $params['status'] = $val; } } if (isset($integration['language'])) { $val = trim(strtolower($integration['language'])); $languages = Phprojekt_LanguageAdapter::getLanguageList(); if (array_key_exists($val, $languages)) { $params['language'] = $val; } else { if (($val = array_search('(' . $val . ')', $languages)) !== false) { $params['language'] = $val; } } } if (isset($integration['timeZone'])) { $val = trim(strtolower($integration['timeZone'])); $timezones = Phprojekt_Converter_Time::getTimeZones(); if (array_key_exists($val, $timezones)) { $params['timeZone'] = $val; } else { if (($val = array_search($val, $timezones)) !== false) { $params['timeZone'] = $val; } } } if (!self::_saveUser($params)) { throw new Phprojekt_Auth_Exception('User creation failed after LDAP authentication', 10); } } } else { throw new Phprojekt_Auth_Exception('Failed to find the LDAP user with the given username', 11); } }