3 final class PhabricatorStandardCustomFieldDate
4 extends PhabricatorStandardCustomField
{
6 public function getFieldType() {
10 public function buildFieldIndexes() {
13 $value = $this->getFieldValue();
15 $indexes[] = $this->newNumericIndex((int)$value);
21 public function buildOrderIndex() {
22 return $this->newNumericIndex(0);
25 public function getValueForStorage() {
26 $value = $this->getFieldValue();
34 public function setValueFromStorage($value) {
40 return $this->setFieldValue($value);
43 public function renderEditControl(array $handles) {
44 return $this->newDateControl();
47 public function readValueFromRequest(AphrontRequest
$request) {
48 $control = $this->newDateControl();
49 $control->setUser($request->getUser());
50 $value = $control->readValueFromRequest($request);
52 $this->setFieldValue($value);
55 public function renderPropertyViewValue(array $handles) {
56 $value = $this->getFieldValue();
61 return phabricator_datetime($value, $this->getViewer());
64 private function newDateControl() {
65 $control = id(new AphrontFormDateControl())
66 ->setLabel($this->getFieldName())
67 ->setName($this->getFieldKey())
68 ->setUser($this->getViewer())
69 ->setCaption($this->getCaption())
70 ->setAllowNull(!$this->getRequired());
72 // If the value is already numeric, treat it as an epoch timestamp and set
73 // it directly. Otherwise, it's likely a field default, which we let users
74 // specify as a string. Parse the string into an epoch.
76 $value = $this->getFieldValue();
77 if (!ctype_digit($value)) {
78 $value = PhabricatorTime
::parseLocalTime($value, $this->getViewer());
81 // If we don't have anything valid, make sure we pass `null`, since the
82 // control special-cases that.
83 $control->setValue(nonempty($value, null));
88 public function readApplicationSearchValueFromRequest(
89 PhabricatorApplicationSearchEngine
$engine,
90 AphrontRequest
$request) {
92 $key = $this->getFieldKey();
95 'min' => $request->getStr($key.'.min'),
96 'max' => $request->getStr($key.'.max'),
100 public function applyApplicationSearchConstraintToQuery(
101 PhabricatorApplicationSearchEngine
$engine,
102 PhabricatorCursorPagedPolicyAwareQuery
$query,
105 $viewer = $this->getViewer();
107 if (!is_array($value)) {
111 $min_str = idx($value, 'min', '');
112 if (strlen($min_str)) {
113 $min = PhabricatorTime
::parseLocalTime($min_str, $viewer);
118 $max_str = idx($value, 'max', '');
119 if (strlen($max_str)) {
120 $max = PhabricatorTime
::parseLocalTime($max_str, $viewer);
125 if (($min !== null) ||
($max !== null)) {
126 $query->withApplicationSearchRangeConstraint(
127 $this->newNumericIndex(null),
133 public function appendToApplicationSearchForm(
134 PhabricatorApplicationSearchEngine
$engine,
135 AphrontFormView
$form,
138 if (!is_array($value)) {
144 id(new AphrontFormTextControl())
145 ->setLabel(pht('%s After', $this->getFieldName()))
146 ->setName($this->getFieldKey().'.min')
147 ->setValue(idx($value, 'min', '')))
149 id(new AphrontFormTextControl())
150 ->setLabel(pht('%s Before', $this->getFieldName()))
151 ->setName($this->getFieldKey().'.max')
152 ->setValue(idx($value, 'max', '')));
155 public function getApplicationTransactionTitle(
156 PhabricatorApplicationTransaction
$xaction) {
157 $author_phid = $xaction->getAuthorPHID();
158 $old = $xaction->getOldValue();
159 $new = $xaction->getNewValue();
161 $viewer = $this->getViewer();
165 $old_date = phabricator_datetime($old, $viewer);
170 $new_date = phabricator_datetime($new, $viewer);
176 $xaction->renderHandleLink($author_phid),
177 $this->getFieldName(),
182 $xaction->renderHandleLink($author_phid),
183 $this->getFieldName());
186 '%s changed %s from %s to %s.',
187 $xaction->renderHandleLink($author_phid),
188 $this->getFieldName(),
194 public function getApplicationTransactionTitleForFeed(
195 PhabricatorApplicationTransaction
$xaction) {
197 $viewer = $this->getViewer();
199 $author_phid = $xaction->getAuthorPHID();
200 $object_phid = $xaction->getObjectPHID();
202 $old = $xaction->getOldValue();
203 $new = $xaction->getNewValue();
207 '%s set %s to %s on %s.',
208 $xaction->renderHandleLink($author_phid),
209 $this->getFieldName(),
210 phabricator_datetime($new, $viewer),
211 $xaction->renderHandleLink($object_phid));
214 '%s removed %s on %s.',
215 $xaction->renderHandleLink($author_phid),
216 $this->getFieldName(),
217 $xaction->renderHandleLink($object_phid));
220 '%s changed %s from %s to %s on %s.',
221 $xaction->renderHandleLink($author_phid),
222 $this->getFieldName(),
223 phabricator_datetime($old, $viewer),
224 phabricator_datetime($new, $viewer),
225 $xaction->renderHandleLink($object_phid));
229 protected function newConduitSearchParameterType() {
230 // TODO: Build a new "pair<epoch|null, epoch|null>" type or similar.
234 protected function newConduitEditParameterType() {
235 return id(new ConduitEpochParameterType())
236 ->setAllowNull(!$this->getRequired());
239 protected function newExportFieldType() {
240 return new PhabricatorEpochExportField();