@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
at upstream/main 174 lines 4.9 kB view raw
1<?php 2 3final class PhrequentTrackController 4 extends PhrequentController { 5 6 private $verb; 7 private $phid; 8 9 public function willProcessRequest(array $data) { 10 $this->phid = $data['phid']; 11 $this->verb = $data['verb']; 12 } 13 14 public function processRequest() { 15 $request = $this->getRequest(); 16 $viewer = $request->getUser(); 17 18 $phid = $this->phid; 19 $handle = id(new PhabricatorHandleQuery()) 20 ->setViewer($viewer) 21 ->withPHIDs(array($phid)) 22 ->executeOne(); 23 $done_uri = $handle->getURI(); 24 25 $current_timer = null; 26 switch ($this->verb) { 27 case 'start': 28 $button_text = pht('Start Tracking'); 29 $title_text = pht('Start Tracking Time'); 30 $inner_text = pht('What time did you start working?'); 31 $action_text = pht('Start Timer'); 32 $label_text = pht('Start Time'); 33 break; 34 case 'stop': 35 $button_text = pht('Stop Tracking'); 36 $title_text = pht('Stop Tracking Time'); 37 $inner_text = pht('What time did you stop working?'); 38 $action_text = pht('Stop Timer'); 39 $label_text = pht('Stop Time'); 40 41 42 $current_timer = id(new PhrequentUserTimeQuery()) 43 ->setViewer($viewer) 44 ->withUserPHIDs(array($viewer->getPHID())) 45 ->withObjectPHIDs(array($phid)) 46 ->withEnded(PhrequentUserTimeQuery::ENDED_NO) 47 ->executeOne(); 48 if (!$current_timer) { 49 return $this->newDialog() 50 ->setTitle(pht('Not Tracking Time')) 51 ->appendParagraph( 52 pht('You are not currently tracking time on this object.')) 53 ->addCancelButton($done_uri); 54 } 55 break; 56 default: 57 return new Aphront404Response(); 58 } 59 60 $errors = array(); 61 $v_note = null; 62 $e_date = null; 63 64 $timestamp = AphrontFormDateControlValue::newFromEpoch( 65 $viewer, 66 time()); 67 68 if ($request->isDialogFormPost()) { 69 $v_note = $request->getStr('note'); 70 $timestamp = AphrontFormDateControlValue::newFromRequest( 71 $request, 72 'epoch'); 73 74 if (!$timestamp->isValid()) { 75 $errors[] = pht('Please choose a valid date.'); 76 $e_date = pht('Invalid'); 77 } else { 78 $max_time = PhabricatorTime::getNow(); 79 if ($timestamp->getEpoch() > $max_time) { 80 if ($this->isStoppingTracking()) { 81 $errors[] = pht( 82 'You can not stop tracking time at a future time. Enter the '. 83 'current time, or a time in the past.'); 84 } else { 85 $errors[] = pht( 86 'You can not start tracking time at a future time. Enter the '. 87 'current time, or a time in the past.'); 88 } 89 $e_date = pht('Invalid'); 90 } 91 92 if ($this->isStoppingTracking()) { 93 $min_time = $current_timer->getDateStarted(); 94 if ($min_time > $timestamp->getEpoch()) { 95 $errors[] = pht('Stop time must be after start time.'); 96 $e_date = pht('Invalid'); 97 } 98 } 99 } 100 101 if (!$errors) { 102 $editor = new PhrequentTrackingEditor(); 103 if ($this->isStartingTracking()) { 104 $editor->startTracking( 105 $viewer, 106 $this->phid, 107 $timestamp->getEpoch()); 108 } else if ($this->isStoppingTracking()) { 109 $editor->stopTracking( 110 $viewer, 111 $this->phid, 112 $timestamp->getEpoch(), 113 $v_note); 114 } 115 116 return id(new AphrontRedirectResponse())->setURI($done_uri); 117 } 118 119 } 120 121 $dialog = $this->newDialog() 122 ->setTitle($title_text) 123 ->setWidth(AphrontDialogView::WIDTH_FORM) 124 ->setErrors($errors) 125 ->appendParagraph($inner_text); 126 127 $form = new PHUIFormLayoutView(); 128 129 if ($this->isStoppingTracking()) { 130 $start_time = $current_timer->getDateStarted(); 131 $start_string = pht( 132 '%s (%s ago)', 133 phabricator_datetime($start_time, $viewer), 134 phutil_format_relative_time(PhabricatorTime::getNow() - $start_time)); 135 136 $form->appendChild( 137 id(new AphrontFormStaticControl()) 138 ->setLabel(pht('Started At')) 139 ->setValue($start_string)); 140 } 141 142 $form->appendChild( 143 id(new AphrontFormDateControl()) 144 ->setUser($viewer) 145 ->setName('epoch') 146 ->setLabel($action_text) 147 ->setError($e_date) 148 ->setValue($timestamp)); 149 150 if ($this->isStoppingTracking()) { 151 $form->appendChild( 152 id(new AphrontFormTextControl()) 153 ->setLabel(pht('Note')) 154 ->setName('note') 155 ->setValue($v_note)); 156 } 157 158 $dialog->appendChild($form); 159 160 $dialog->addCancelButton($done_uri); 161 162 $dialog->addSubmitButton($action_text); 163 164 return $dialog; 165 } 166 167 private function isStartingTracking() { 168 return $this->verb === 'start'; 169 } 170 171 private function isStoppingTracking() { 172 return $this->verb === 'stop'; 173 } 174}