public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     if ($this->id) {
         $page_title = pht('Edit Countdown');
         $countdown = id(new PhabricatorCountdownQuery())->setViewer($user)->withIDs(array($this->id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
         if (!$countdown) {
             return new Aphront404Response();
         }
         $date_value = AphrontFormDateControlValue::newFromEpoch($user, $countdown->getEpoch());
     } else {
         $page_title = pht('Create Countdown');
         $countdown = PhabricatorCountdown::initializeNewCountdown($user);
         $date_value = AphrontFormDateControlValue::newFromEpoch($user, time());
     }
     $errors = array();
     $e_text = true;
     $e_epoch = null;
     $v_text = $countdown->getTitle();
     $v_space = $countdown->getSpacePHID();
     if ($request->isFormPost()) {
         $v_text = $request->getStr('title');
         $v_space = $request->getStr('spacePHID');
         $date_value = AphrontFormDateControlValue::newFromRequest($request, 'epoch');
         $view_policy = $request->getStr('viewPolicy');
         $e_text = null;
         if (!strlen($v_text)) {
             $e_text = pht('Required');
             $errors[] = pht('You must give the countdown a name.');
         }
         if (!$date_value->isValid()) {
             $e_epoch = pht('Invalid');
             $errors[] = pht('You must give the countdown a valid end date.');
         }
         if (!count($errors)) {
             $countdown->setTitle($v_text);
             $countdown->setEpoch($date_value->getEpoch());
             $countdown->setViewPolicy($view_policy);
             $countdown->setSpacePHID($v_space);
             $countdown->save();
             return id(new AphrontRedirectResponse())->setURI('/countdown/' . $countdown->getID() . '/');
         }
     }
     $crumbs = $this->buildApplicationCrumbs();
     $cancel_uri = '/countdown/';
     if ($countdown->getID()) {
         $cancel_uri = '/countdown/' . $countdown->getID() . '/';
         $crumbs->addTextCrumb('C' . $countdown->getID(), $cancel_uri);
         $crumbs->addTextCrumb(pht('Edit'));
         $submit_label = pht('Save Changes');
     } else {
         $crumbs->addTextCrumb(pht('Create Countdown'));
         $submit_label = pht('Create Countdown');
     }
     $policies = id(new PhabricatorPolicyQuery())->setViewer($user)->setObject($countdown)->execute();
     $form = id(new AphrontFormView())->setUser($user)->setAction($request->getRequestURI()->getPath())->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Title'))->setValue($v_text)->setName('title')->setError($e_text))->appendChild(id(new AphrontFormDateControl())->setUser($user)->setName('epoch')->setLabel(pht('End Date'))->setError($e_epoch)->setValue($date_value))->appendChild(id(new AphrontFormPolicyControl())->setUser($user)->setName('viewPolicy')->setPolicyObject($countdown)->setPolicies($policies)->setSpacePHID($v_space)->setCapability(PhabricatorPolicyCapability::CAN_VIEW))->appendChild(id(new AphrontFormSubmitControl())->addCancelButton($cancel_uri)->setValue($submit_label));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText($page_title)->setFormErrors($errors)->setForm($form);
     return $this->buildApplicationPage(array($crumbs, $form_box), array('title' => $page_title));
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $event = id(new PhabricatorCalendarEventQuery())->setViewer($viewer)->withIDs(array($request->getURIData('id')))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
     if (!$event) {
         return new Aphront404Response();
     }
     if (!$request->validateCSRF()) {
         return new Aphront400Response();
     }
     if ($event->getIsAllDay()) {
         return new Aphront400Response();
     }
     $xactions = array();
     $duration = $event->getDuration();
     $start = $request->getInt('start');
     $start_value = id(AphrontFormDateControlValue::newFromEpoch($viewer, $start));
     $end = $start + $duration;
     $end_value = id(AphrontFormDateControlValue::newFromEpoch($viewer, $end));
     $xactions[] = id(new PhabricatorCalendarEventTransaction())->setTransactionType(PhabricatorCalendarEventStartDateTransaction::TRANSACTIONTYPE)->setNewValue($start_value);
     $xactions[] = id(new PhabricatorCalendarEventTransaction())->setTransactionType(PhabricatorCalendarEventEndDateTransaction::TRANSACTIONTYPE)->setNewValue($end_value);
     $editor = id(new PhabricatorCalendarEventEditor())->setActor($viewer)->setContinueOnMissingFields(true)->setContentSourceFromRequest($request)->setContinueOnNoEffect(true);
     $xactions = $editor->applyTransactions($event, $xactions);
     return id(new AphrontReloadResponse());
 }
 protected function getParameterValue(AphrontRequest $request, $key)
 {
     $value = AphrontFormDateControlValue::newFromRequest($request, $key);
     if ($this->getAllowNull()) {
         $value->setOptional(true);
     }
     return $value;
 }
 protected function didReadValueFromSavedQuery($value)
 {
     if (!$value) {
         return null;
     }
     if ($value instanceof AphrontFormDateControlValue && $value->getEpoch()) {
         return $value->setOptional(true);
     }
     $value = AphrontFormDateControlValue::newFromWild($this->getViewer(), $value);
     return $value->setOptional(true);
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $this->getViewer();
     $username = $request->getURIData('username');
     $user = id(new PhabricatorPeopleQuery())->setViewer($viewer)->withUsernames(array($username))->needProfileImage(true)->executeOne();
     if (!$user) {
         return new Aphront404Response();
     }
     $this->setUser($user);
     $picture = $user->getProfileImageURI();
     $now = time();
     $request = $this->getRequest();
     $year_d = phabricator_format_local_time($now, $user, 'Y');
     $year = $request->getInt('year', $year_d);
     $month_d = phabricator_format_local_time($now, $user, 'm');
     $month = $request->getInt('month', $month_d);
     $day = phabricator_format_local_time($now, $user, 'j');
     $start_epoch = strtotime("{$year}-{$month}-01");
     $end_epoch = strtotime("{$year}-{$month}-01 next month");
     $statuses = id(new PhabricatorCalendarEventQuery())->setViewer($user)->withInvitedPHIDs(array($user->getPHID()))->withDateRange($start_epoch, $end_epoch)->execute();
     $start_range_value = AphrontFormDateControlValue::newFromEpoch($user, $start_epoch);
     $end_range_value = AphrontFormDateControlValue::newFromEpoch($user, $end_epoch);
     if ($month == $month_d && $year == $year_d) {
         $month_view = new PHUICalendarMonthView($start_range_value, $end_range_value, $month, $year, $day);
     } else {
         $month_view = new PHUICalendarMonthView($start_range_value, $end_range_value, $month, $year);
     }
     $month_view->setBrowseURI($request->getRequestURI());
     $month_view->setUser($user);
     $month_view->setImage($picture);
     $phids = mpull($statuses, 'getUserPHID');
     $handles = $this->loadViewerHandles($phids);
     foreach ($statuses as $status) {
         $event = new AphrontCalendarEventView();
         $event->setEpochRange($status->getDateFrom(), $status->getDateTo());
         $event->setUserPHID($status->getUserPHID());
         $event->setName($status->getName());
         $event->setDescription($status->getDescription());
         $event->setEventID($status->getID());
         $month_view->addEvent($event);
     }
     $nav = $this->getProfileMenu();
     $nav->selectFilter('calendar');
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('Calendar'));
     return $this->newPage()->setTitle(pht('Calendar'))->setNavigation($nav)->setCrumbs($crumbs)->appendChild($month_view);
 }
 private function getEventTooltip(AphrontCalendarEventView $event)
 {
     $time_pref = $this->getUser()->getPreference(PhabricatorUserPreferences::PREFERENCE_TIME_FORMAT);
     Javelin::initBehavior('phabricator-tooltips');
     $start = id(AphrontFormDateControlValue::newFromEpoch($this->getUser(), $event->getEpochStart()));
     $end = id(AphrontFormDateControlValue::newFromEpoch($this->getUser(), $event->getEpochEnd()));
     $start_date = $start->getDateTime()->format('m d Y');
     $end_date = $end->getDateTime()->format('m d Y');
     if ($event->getIsAllDay()) {
         if ($start_date == $end_date) {
             $tip = pht('All day');
         } else {
             $tip = pht('All day, %s - %s', $start->getValueAsFormat('M j, Y'), $end->getValueAsFormat('M j, Y'));
         }
     } else {
         if ($start->getValueDate() == $end->getValueDate()) {
             $tip = pht('%s - %s', $start->getValueAsFormat($time_pref), $end->getValueAsFormat($time_pref));
         } else {
             $tip = pht('%s - %s', $start->getValueAsFormat('M j, Y, ' . $time_pref), $end->getValueAsFormat('M j, Y, ' . $time_pref));
         }
     }
     return $tip;
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $phid = $this->phid;
     $handle = id(new PhabricatorHandleQuery())->setViewer($viewer)->withPHIDs(array($phid))->executeOne();
     $done_uri = $handle->getURI();
     $current_timer = null;
     switch ($this->verb) {
         case 'start':
             $button_text = pht('Start Tracking');
             $title_text = pht('Start Tracking Time');
             $inner_text = pht('What time did you start working?');
             $action_text = pht('Start Timer');
             $label_text = pht('Start Time');
             break;
         case 'stop':
             $button_text = pht('Stop Tracking');
             $title_text = pht('Stop Tracking Time');
             $inner_text = pht('What time did you stop working?');
             $action_text = pht('Stop Timer');
             $label_text = pht('Stop Time');
             $current_timer = id(new PhrequentUserTimeQuery())->setViewer($viewer)->withUserPHIDs(array($viewer->getPHID()))->withObjectPHIDs(array($phid))->withEnded(PhrequentUserTimeQuery::ENDED_NO)->executeOne();
             if (!$current_timer) {
                 return $this->newDialog()->setTitle(pht('Not Tracking Time'))->appendParagraph(pht('You are not currently tracking time on this object.'))->addCancelButton($done_uri);
             }
             break;
         default:
             return new Aphront404Response();
     }
     $errors = array();
     $v_note = null;
     $e_date = null;
     $timestamp = AphrontFormDateControlValue::newFromEpoch($viewer, time());
     if ($request->isDialogFormPost()) {
         $v_note = $request->getStr('note');
         $timestamp = AphrontFormDateControlValue::newFromRequest($request, 'epoch');
         if (!$timestamp->isValid()) {
             $errors[] = pht('Please choose a valid date.');
             $e_date = pht('Invalid');
         } else {
             $max_time = PhabricatorTime::getNow();
             if ($timestamp->getEpoch() > $max_time) {
                 if ($this->isStoppingTracking()) {
                     $errors[] = pht('You can not stop tracking time at a future time. Enter the ' . 'current time, or a time in the past.');
                 } else {
                     $errors[] = pht('You can not start tracking time at a future time. Enter the ' . 'current time, or a time in the past.');
                 }
                 $e_date = pht('Invalid');
             }
             if ($this->isStoppingTracking()) {
                 $min_time = $current_timer->getDateStarted();
                 if ($min_time > $timestamp->getEpoch()) {
                     $errors[] = pht('Stop time must be after start time.');
                     $e_date = pht('Invalid');
                 }
             }
         }
         if (!$errors) {
             $editor = new PhrequentTrackingEditor();
             if ($this->isStartingTracking()) {
                 $editor->startTracking($viewer, $this->phid, $timestamp->getEpoch());
             } else {
                 if ($this->isStoppingTracking()) {
                     $editor->stopTracking($viewer, $this->phid, $timestamp->getEpoch(), $v_note);
                 }
             }
             return id(new AphrontRedirectResponse())->setURI($done_uri);
         }
     }
     $dialog = $this->newDialog()->setTitle($title_text)->setWidth(AphrontDialogView::WIDTH_FORM)->setErrors($errors)->appendParagraph($inner_text);
     $form = new PHUIFormLayoutView();
     if ($this->isStoppingTracking()) {
         $start_time = $current_timer->getDateStarted();
         $start_string = pht('%s (%s ago)', phabricator_datetime($start_time, $viewer), phutil_format_relative_time(PhabricatorTime::getNow() - $start_time));
         $form->appendChild(id(new AphrontFormStaticControl())->setLabel(pht('Started At'))->setValue($start_string));
     }
     $form->appendChild(id(new AphrontFormDateControl())->setUser($viewer)->setName('epoch')->setLabel($action_text)->setError($e_date)->setValue($timestamp));
     if ($this->isStoppingTracking()) {
         $form->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Note'))->setName('note')->setValue($v_note));
     }
     $dialog->appendChild($form);
     $dialog->addCancelButton($done_uri);
     $dialog->addSubmitButton($action_text);
     return $dialog;
 }
 private function getSafeDate($value)
 {
     $viewer = $this->requireViewer();
     if ($value) {
         // ideally this would be consistent and always pass in the same type
         if ($value instanceof AphrontFormDateControlValue) {
             return $value;
         } else {
             $value = AphrontFormDateControlValue::newFromWild($viewer, $value);
         }
     } else {
         $value = AphrontFormDateControlValue::newFromEpoch($viewer, PhabricatorTime::getTodayMidnightDateTime($viewer)->format('U'));
         $value->setEnabled(false);
     }
     $value->setOptional(true);
     return $value;
 }
 protected function readDateFromRequest(AphrontRequest $request, $key)
 {
     $value = AphrontFormDateControlValue::newFromRequest($request, $key);
     if ($value->isEmpty()) {
         return null;
     }
     return $value->getDictionary();
 }
 public static function newFromDictionary(PhabricatorUser $viewer, array $dictionary)
 {
     $value = new AphrontFormDateControlValue();
     $value->viewer = $viewer;
     $value->valueDate = idx($dictionary, 'd');
     $value->valueTime = idx($dictionary, 't');
     $formatted = $value->getFormattedDateFromDate($value->valueDate, $value->valueTime);
     if ($formatted) {
         list($value->valueDate, $value->valueTime) = $formatted;
     }
     $value->valueEnabled = idx($dictionary, 'e');
     return $value;
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $id = $request->getURIData('id');
     if ($id) {
         $page_title = pht('Edit Countdown');
         $countdown = id(new PhabricatorCountdownQuery())->setViewer($viewer)->withIDs(array($id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
         if (!$countdown) {
             return new Aphront404Response();
         }
         $date_value = AphrontFormDateControlValue::newFromEpoch($viewer, $countdown->getEpoch());
         $v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs($countdown->getPHID(), PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
         $v_projects = array_reverse($v_projects);
     } else {
         $page_title = pht('Create Countdown');
         $countdown = PhabricatorCountdown::initializeNewCountdown($viewer);
         $date_value = AphrontFormDateControlValue::newFromEpoch($viewer, PhabricatorTime::getNow());
         $v_projects = array();
     }
     $errors = array();
     $e_text = true;
     $e_epoch = null;
     $v_text = $countdown->getTitle();
     $v_desc = $countdown->getDescription();
     $v_space = $countdown->getSpacePHID();
     $v_view = $countdown->getViewPolicy();
     $v_edit = $countdown->getEditPolicy();
     if ($request->isFormPost()) {
         $v_text = $request->getStr('title');
         $v_desc = $request->getStr('description');
         $v_space = $request->getStr('spacePHID');
         $date_value = AphrontFormDateControlValue::newFromRequest($request, 'epoch');
         $v_view = $request->getStr('viewPolicy');
         $v_edit = $request->getStr('editPolicy');
         $v_projects = $request->getArr('projects');
         $type_title = PhabricatorCountdownTransaction::TYPE_TITLE;
         $type_epoch = PhabricatorCountdownTransaction::TYPE_EPOCH;
         $type_description = PhabricatorCountdownTransaction::TYPE_DESCRIPTION;
         $type_space = PhabricatorTransactions::TYPE_SPACE;
         $type_view = PhabricatorTransactions::TYPE_VIEW_POLICY;
         $type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY;
         $xactions = array();
         $xactions[] = id(new PhabricatorCountdownTransaction())->setTransactionType($type_title)->setNewValue($v_text);
         $xactions[] = id(new PhabricatorCountdownTransaction())->setTransactionType($type_epoch)->setNewValue($date_value);
         $xactions[] = id(new PhabricatorCountdownTransaction())->setTransactionType($type_description)->setNewValue($v_desc);
         $xactions[] = id(new PhabricatorCountdownTransaction())->setTransactionType($type_space)->setNewValue($v_space);
         $xactions[] = id(new PhabricatorCountdownTransaction())->setTransactionType($type_view)->setNewValue($v_view);
         $xactions[] = id(new PhabricatorCountdownTransaction())->setTransactionType($type_edit)->setNewValue($v_edit);
         $proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
         $xactions[] = id(new PhabricatorCountdownTransaction())->setTransactionType(PhabricatorTransactions::TYPE_EDGE)->setMetadataValue('edge:type', $proj_edge_type)->setNewValue(array('=' => array_fuse($v_projects)));
         $editor = id(new PhabricatorCountdownEditor())->setActor($viewer)->setContentSourceFromRequest($request)->setContinueOnNoEffect(true);
         try {
             $editor->applyTransactions($countdown, $xactions);
             return id(new AphrontRedirectResponse())->setURI('/' . $countdown->getMonogram());
         } catch (PhabricatorApplicationTransactionValidationException $ex) {
             $validation_exception = $ex;
             $e_title = $ex->getShortMessage($type_title);
             $e_epoch = $ex->getShortMessage($type_epoch);
         }
     }
     $crumbs = $this->buildApplicationCrumbs();
     $cancel_uri = '/countdown/';
     if ($countdown->getID()) {
         $cancel_uri = '/countdown/' . $countdown->getID() . '/';
         $crumbs->addTextCrumb('C' . $countdown->getID(), $cancel_uri);
         $crumbs->addTextCrumb(pht('Edit'));
         $submit_label = pht('Save Changes');
     } else {
         $crumbs->addTextCrumb(pht('Create Countdown'));
         $submit_label = pht('Create Countdown');
     }
     $policies = id(new PhabricatorPolicyQuery())->setViewer($viewer)->setObject($countdown)->execute();
     $form = id(new AphrontFormView())->setUser($viewer)->setAction($request->getRequestURI()->getPath())->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Title'))->setValue($v_text)->setName('title')->setError($e_text))->appendControl(id(new AphrontFormDateControl())->setName('epoch')->setLabel(pht('End Date'))->setError($e_epoch)->setValue($date_value))->appendControl(id(new PhabricatorRemarkupControl())->setName('description')->setLabel(pht('Description'))->setValue($v_desc))->appendControl(id(new AphrontFormPolicyControl())->setName('viewPolicy')->setPolicyObject($countdown)->setPolicies($policies)->setSpacePHID($v_space)->setValue($v_view)->setCapability(PhabricatorPolicyCapability::CAN_VIEW))->appendControl(id(new AphrontFormPolicyControl())->setName('editPolicy')->setPolicyObject($countdown)->setPolicies($policies)->setValue($v_edit)->setCapability(PhabricatorPolicyCapability::CAN_EDIT))->appendControl(id(new AphrontFormTokenizerControl())->setLabel(pht('Projects'))->setName('projects')->setValue($v_projects)->setDatasource(new PhabricatorProjectDatasource()))->appendChild(id(new AphrontFormSubmitControl())->addCancelButton($cancel_uri)->setValue($submit_label));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText($page_title)->setFormErrors($errors)->setForm($form);
     return $this->newPage()->setTitle($page_title)->setCrumbs($crumbs)->appendChild(array($form_box));
 }
 private function getDefaultTimeValues($viewer)
 {
     $start = new DateTime('@' . time());
     $start->setTimeZone($viewer->getTimeZone());
     $start->setTime($start->format('H'), 0, 0);
     $start->modify('+1 hour');
     $end = id(clone $start)->modify('+1 hour');
     $start_value = AphrontFormDateControlValue::newFromEpoch($viewer, $start->format('U'));
     $end_value = AphrontFormDateControlValue::newFromEpoch($viewer, $end->format('U'));
     return array($start_value, $end_value);
 }
 protected function validateTransaction(PhabricatorLiskDAO $object, $type, array $xactions)
 {
     $errors = parent::validateTransaction($object, $type, $xactions);
     switch ($type) {
         case PhabricatorCountdownTransaction::TYPE_TITLE:
             $missing = $this->validateIsEmptyTextField($object->getTitle(), $xactions);
             if ($missing) {
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Required'), pht('You must give the countdown a name.'), nonempty(last($xactions), null));
                 $error->setIsMissingFieldError(true);
                 $errors[] = $error;
             }
             break;
         case PhabricatorCountdownTransaction::TYPE_EPOCH:
             $date_value = AphrontFormDateControlValue::newFromEpoch($this->requireActor(), $object->getEpoch());
             if (!$date_value->isValid()) {
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Invalid'), pht('You must give the countdown a valid end date.'), nonempty(last($xactions), null));
                 $error->setIsMissingFieldError(true);
                 $errors[] = $error;
             }
             break;
     }
     return $errors;
 }
 private function getEventTooltip(AphrontCalendarEventView $event)
 {
     $viewer = $this->getViewer();
     $time_key = PhabricatorTimeFormatSetting::SETTINGKEY;
     $time_pref = $viewer->getUserSetting($time_key);
     Javelin::initBehavior('phabricator-tooltips');
     $start = id(AphrontFormDateControlValue::newFromEpoch($viewer, $event->getEpochStart()));
     $end = id(AphrontFormDateControlValue::newFromEpoch($viewer, $event->getEpochEnd()));
     $start_date = $start->getDateTime()->format('m d Y');
     $end_date = $end->getDateTime()->format('m d Y');
     if ($event->getIsAllDay()) {
         if ($start_date == $end_date) {
             $tip = pht('All day');
         } else {
             $tip = pht('All day, %s - %s', $start->getValueAsFormat('M j, Y'), $end->getValueAsFormat('M j, Y'));
         }
     } else {
         if ($start->getValueDate() == $end->getValueDate()) {
             $tip = pht('%s - %s', $start->getValueAsFormat($time_pref), $end->getValueAsFormat($time_pref));
         } else {
             $tip = pht('%s - %s', $start->getValueAsFormat('M j, Y, ' . $time_pref), $end->getValueAsFormat('M j, Y, ' . $time_pref));
         }
     }
     return $tip;
 }
 protected function getParameterValue(AphrontRequest $request, $key)
 {
     return AphrontFormDateControlValue::newFromRequest($request, $key);
 }