<?php

final class PhabricatorSearchDateField
  extends PhabricatorSearchField {

  protected function newControl() {
    return new AphrontFormTextControl();
  }

  protected function getValueFromRequest(AphrontRequest $request, $key) {
    return $request->getStr($key);
  }

  public function getValueForQuery($value) {
    return $this->parseDateTime($value);
  }

  protected function validateControlValue($value) {
    if (!strlen($value)) {
      return;
    }

    $epoch = $this->parseDateTime($value);
    if ($epoch) {
      return;
    }

    $this->addError(
      pht('Invalid'),
      pht('Date value for "%s" can not be parsed.', $this->getLabel()));
  }

  protected function parseDateTime($value) {
    if (!strlen($value)) {
      return null;
    }

    return PhabricatorTime::parseLocalTime($value, $this->getViewer());
  }

  protected function newConduitParameterType() {
    return new ConduitEpochParameterType();
  }

}

<?php

final class PhabricatorSearchDateField
  extends PhabricatorSearchField {

  protected function newControl() {
    return new AphrontFormTextControl();
  }

  protected function getValueFromRequest(AphrontRequest $request, $key) {
    return $request->getStr($key);
  }

  public function getValueForQuery($value) {
    return $this->parseDateTime($value);
  }

  protected function validateControlValue($value) {
    if (!strlen($value)) {
      return;
    }

    $epoch = $this->parseDateTime($value);
    if ($epoch) {
      return;
    }

    $this->addError(
      pht('Invalid'),
      pht('Date value for "%s" can not be parsed.', $this->getLabel()));
  }

  protected function parseDateTime($value) {
    if (!strlen($value)) {
      return null;
    }

    // If this appears to be an epoch timestamp, just return it unmodified.
    // This assumes values like "2016" or "20160101" are "Ymd".
    if (is_int($value) || ctype_digit($value)) {
      if ((int)$value > 30000000) {
        return (int)$value;
      }
    }

    return PhabricatorTime::parseLocalTime($value, $this->getViewer());
  }

  protected function newConduitParameterType() {
    return new ConduitEpochParameterType();
  }

}

Correct an issue with epoch timestamps in Conduit
Correct an issue with epoch timestamps in Conduit

Summary:
Fixes T11375. Some validation code was mishandling raw epoch timestamps.

For numeric values larger than 29999999 (e.g., 2999-12-25, christmas 2999), assume the value is a timestamp.

Test Plan: Used `maniphest.search` to query for `modifiedStart`, got a better result set and saw the `dateModified` constraint in the query.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T11375

Differential Revision: https://secure.phabricator.com/D16326
