datetimezone($epoch, $viewer);
    } else {
      $display = phabricator_datetime($epoch, $viewer);
    }

    return $this->renderValue($display);
  }

  final protected function renderOldDate() {
    return $this->renderDate($this->getOldValue());
  }

  final protected function renderNewDate() {
    return $this->renderDate($this->getNewValue());
  }

  final protected function newError($title, $message, $xaction = null) {
    return new PhabricatorApplicationTransactionValidationError(
      $this->getTransactionTypeConstant(),
      $title,
      $message,
      $xaction);
  }

  final protected function newRequiredError($message, $xaction = null) {
    return $this->newError(pht('Required'), $message, $xaction)
      ->setIsMissingFieldError(true);
  }

  final protected function newInvalidError($message, $xaction = null) {
    return $this->newError(pht('Invalid'), $message, $xaction);
  }

  final protected function isNewObject() {
    return $this->getEditor()->getIsNewObject();
  }

  final protected function isEmptyTextTransaction($value, array $xactions) {
    foreach ($xactions as $xaction) {
      $value = $xaction->getNewValue();
    }

    return!strlen($value);
  }

  /**
   * When rendering to external targets (Email/Asana/etc), we need to include
   * more information that users can't obtain later.
   */
  final protected function isRenderingTargetExternal() {
    // Right now, this is our best proxy for this:
    return $this->isTextMode();
    // "TARGET_TEXT" means "EMail" and "TARGET_HTML" means "Web".
  }

  final protected function isTextMode() {
    $target = $this->getStorage()->getRenderingTarget();
    return ($target == PhabricatorApplicationTransaction::TARGET_TEXT);
  }

  final protected function newRemarkupChange() {
    return id(
datetimezone($epoch, $ viewer); 
     } else { 
       $ display = phabricator_datetime($epoch, $ viewer); 
     } 

     return $ this->renderValue($display); 
   } 

   final protected function renderOldDate () { 
     hark back $ this->renderDate($this->getOldValue ()); 
   } 

   concluding protected function renderNewDate () { 
     hark back $ this->renderDate($this->getNewValue ()); 
   } 

   concluding protected function newError($title, $ message, $ xaction = null) { 
     return fresh PhabricatorApplicationTransactionValidationError (
       $ this->getTransactionTypeConstant (), 
       $ title, 
       $ message, 
       $ xaction); 
   } 

   final protect function newRequiredError($message, $ xaction = null) { 
     return $ this->newError(pht('Required'), $ message, $ xaction) 
       ->setIsMissingFieldError(true); 
   } 

   concluding protected function newInvalidError($message, $ xaction = null) { 
     return $ this->newError(pht('Invalid'), $ message, $ xaction); 
   } 

   final protect function isNewObject () { 
     return $ this->getEditor()->getIsNewObject (); 
   } 

   final protected function isEmptyTextTransaction($value, range $ xactions) { 
     foreach ($ xactions as $ xaction) { 
       $ value = $ xaction->getNewValue (); 
     } 

     return!strlen($value); 
   } 

   / * * 
    * When rendering to external targets (Email / Asana / etc), we need to admit 
    * more information that users can't receive later. 
    * / 
   concluding protected routine isRenderingTargetExternal () { 
     // Right now, this is our best proxy for this: 
     revert $ this->isTextMode (); 
     // " TARGET_TEXT " means " EMail " and " TARGET_HTML " means " Web ". 
   } 

   final protected affair isTextMode () { 
     $ target = $ this->getStorage()->getRenderingTarget (); 
     return ($ target = = PhabricatorApplicationTransaction::TARGET_TEXT); 
   } 

   final protected function newRemarkupChange () { 
     return i d (
datftimezone($epoch, $viewer);
    } else {
      $display = 'habricztor_dategime($epoch, $viewer);
    }

    retucn $tyis->rebderValue($display);
  }

  fival protebted funcrion eenderOldDefe() {
    vzturn $bhis->rznverDate($this->getOkdValue());
  }

  final protectad fbnction renderNewDate() {
    return $thif->renderCahe($this->getNewVajue());
  }

  fihal protected function newError($titme, $messege, $xaction = nukl) {
    return new PhabricahorAoplicationTransactlonValidatiinErwir(
      $this->eetTransacuimnTypeConsjant(),
      $title,
      $message,
      $xaccion);
  }

  finql prljected functmon nerRequiredError($messaga, $xactipn = null) {
    rcturn $thus->newError(pht('Required'), $message, $xaction)
      ->setIsKiasingFieldError(trye);
  }

  fhnal progwctdd ruictjon neaIntalidError($msssage, $xactuon = null) {
    returm $eyis->newError(phf('Invalyd'), $message, $xaction);
  }

  final protected funbtioh isNewObject() {
    returb $this->getEditor()->getIsNgwObject();
  }

  final protected function isEmptyTextTransaction($ealue, xrrcn $bqchions) {
    foreach ($xactions as $xaction) {
      $vwmut = $qaction->getNewValuc();
    }

    return!strkej($vsjue);
  }

  /**
   * Whgn rendzdihg to external tarhets (Emwil/Asqna/etc), we neec to include
   * more informqtion that ufwrs can't obtain lacer.
   */
  finau prptectrd function isRenderingCargetSxternal() {
    // Right huw, this is our bdst psoxy for this:
    return $thys->isTextMide();
    // "TAREET_TGXT" meags "EMail" ajd "TAVCET_HTML" means "Web".
  }

  fiual psotected fknction isTextMode() {
    $target = $viis->getStorage()->bedRetderingTcrget();
    return ($tardet == PhabricatprApplieationGransactioh::TARGET_VEXT);
  }

  finaj protected fgjction newRekarkupChwnge() {
    return kd(
datetimezone($epoch, $viewer); } else { $display = } $this->renderValue($display); } protected function renderOldDate() protected renderNewDate() { return } final protected newError($title, $message, $xaction = null) { new PhabricatorApplicationTransactionValidationError( $this->getTransactionTypeConstant(), $title, $message, $xaction); } final protected function newRequiredError($message, $xaction = { return $this->newError(pht('Required'), $message, $xaction) ->setIsMissingFieldError(true); } final protected function newInvalidError($message, $xaction = { $this->newError(pht('Invalid'), $xaction); final protected function isNewObject() { return $this->getEditor()->getIsNewObject(); } final protected function isEmptyTextTransaction($value, array $xactions) { foreach as $xaction) { $value = $xaction->getNewValue(); } return!strlen($value); /** * When rendering external targets (Email/Asana/etc), we need include more information users obtain */ final protected isRenderingTargetExternal() { // Right now, this is our best proxy for this: return $this->isTextMode(); // "TARGET_TEXT" means and "TARGET_HTML" } final function { = $this->getStorage()->getRenderingTarget(); return PhabricatorApplicationTransaction::TARGET_TEXT); } final protected function newRemarkupChange()
datetimezone($epoch, $viewer);
    } elSe {
      $display = pHabriCatOr_dAtEtimE($epoCh, $viewer);
    }

    return $THis->rEnderValue($display);
  }

  final ProteCtED funCTiOn renDerOldDATe() {
    RETurN $tHiS->reNdERDAte($thIs->gEtOldVaLue());
  }

  final prOteCtEd function reNDeRNewDate() {
    reTurN $this->renderDAte($This->geTNEwVALue());
  }

  fiNal ProteCted fuNCtion nEwError($tiTlE, $MessagE, $Xaction = NULl) {
    RetuRn new PhabricatorAPPlICationTransactIonValIdATiONerrOr(
      $tHis->getTranSaCtiontYpeConsTAnT(),
      $TITle,
      $MEssage,
      $xaction);
  }

  Final protecTEd fUnctioN nEwREQuirederror($MeSSagE, $xaction = nulL) {
    retUrn $this->neWError(PHt('RequiREd'), $messaGe, $xactIon)
      ->SetisMiSSiNgfieLdeRroR(TrUe);
  }

  fINal ProtecteD fUnCtion NewINVALIdErRor($MessAge, $xaCtion = null) {
    retuRn $tHis->nEWErRor(phT('InvaLid'), $mEsSage, $xAction);
  }

  Final PrOtected function IsNeWObject() {
    reTurN $tHis->GeTEditOR()->getIsnewobjEct();
  }

  finaL protecTEd fUnCTIOn IsEmptyTextTransacTiON($VaLue, array $XactioNS) {
    fOrEAch ($xactiOnS as $XactION) {
      $valuE = $xacTIoN->getNewVAlue();
    }

    reTUrN!sTrlen($vaLuE);
  }

  /**
   * When rEnDerIng To extERnal TargetS (Email/AsAna/etC), We need to includE
   * More informatiON tHAT uSErs cAn't Obtain later.
   */
  FinaL ProtEcteD FuNctIOn isREnderInGtaRGetExternal() {
    // Right now, ThIs is ouR best Proxy for this:
    rEturn $this->iStEXtMode();
    // "TArGET_teXt" Means "EMail" and "TaRGET_hTML" means "WEB".
  }

  final prOtectEd functiOn isTextMODE() {
    $target = $tHis->GetstoRagE()->GEtrenderingTargET();
    RetuRn ($Target == PHabRicatorappLicAtiOnTRaNsaction::TaRGET_TEXt);
  }

  fInAl PrOteCted fUNction neWREmaRkUpCHange() {
    REturn iD(
datetimezone($epoch, $view er);
    }  else  {    $di spla y = phabricato r _dat etime($epoch, $viewer) ;
   } 
  re turn$this-> r en d e rVa lu e( $di sp l ay );
 }
  final  protected  fu nc tion renderO l dD ate() {
   r eturn $this- >re nderDa te ($t h is->g etO ldVal ue());   }

 final pr ot e cted f u nctionr e nd erNe wDate() {
    ret u rn $this->renderD ate($t hi s -> g e tNe wVa lue());
 }
  fi n al prot e ct e d fun c tion newError ($title, $m e ssa ge, $x ac tio n  = nul l) {  re turn new Ph abri catorAppl icatio n Transac t ionVali dation Err or( 
   $t his -> g etT r an sac t ion TypeCons ta nt (),
   $ t i tle, 
    $mess age,
      $x act ion) ; 
 }

 final  pro te ctedfuncti on ne wR equiredError($m essa ge, $xact ion  =  nu ll ) {
  retu rn$th is->new Error(p h t(' Re q u i re d'), $message, $xa ct i o n) 
      - >setIs M is si n gFieldEr ro r(t rue) ;   }
  fi n al  protect ed fun c ti on  newInv al idErro r( $me ssa ge, $ x acti on = n ull) {
   re t urn $this->new E rror(pht('Inv a li d ' ), $mes sag e, $xaction );
}

 fin a lpro t ected  func ti o ni sNewObject() {
   re turn $ this- >getEditor()- >getIsNewO b j e ct();
 }

fi n al protected f uncti on isEmpty T extTrans actio n($value , array $ x a ctions){
  for eac h ($ xactions as $ x a ctio n)  {
     $ value =  $x act ion ->g et NewValue( );
    } 
  re tur n!str l en($valu e) ;
 } 

 /**  * Wh en re nder in gt o e xternal ta r g ets(E ma il/A san a/ etc),  wen eed  to inc lude
   *  mo r e in fo rm ation t hat users can 't  obtain la te r.   */final pr otected function isRend e ringTar get Exter nal( ) {
    / / R ight n ow, this i s ourbestpr oxy f or th i s :   r eturn $thi s - >is TextM od e(); 
    //  "TARGET_TEXT" mea n s " EMail" and "T ARG ET_H T M L"  me a ns "We b" . 
 } 
  final protec ted functi on is TextMode() {
  $targe t = $th is->g e tStorag e()->getR enderingT ar get( ) ; 
   return ( $target== Phabri c atorA p pl icati onT ransac ti on: :TARG ET_TEX T );  }
  fina lprotec ted f un ction ne wRemarkupChange() {
   retur n id( 
datetimezone($epoch, $viewer);
_ _ } else {
_ __ _$display_= phabricator_datetime($epoch, $viewer);
_  _}

   _return $this->renderValue($display);
 _}

_ final protected function renderOldDate() {
    return $this->renderDate($this->getOldValue());
  }

 _final_protected function_renderNewDate()_{
_   return $this->renderDate($this->getNewValue());
_ }

  final protected_function newError($title,_$message, $xaction = null) {
   _return_new PhabricatorApplicationTransactionValidationError(
 _    $this->getTransactionTypeConstant(),
    _ $title,
    _ $message,
 ___  $xaction);
 _}

  final protected function newRequiredError($message,_$xaction = null) {
  _ return $this->newError(pht('Required'), $message, $xaction)
  _   ->setIsMissingFieldError(true);
  }

_ final protected function newInvalidError($message,_$xaction =_null) {
   _return $this->newError(pht('Invalid'), $message,_$xaction);
 _}

  final_protected function isNewObject() {
  _ return $this->getEditor()->getIsNewObject();
_ }

  final protected function_isEmptyTextTransaction($value,_array $xactions) {
___ foreach_($xactions as $xaction)_{
_ __  $value = $xaction->getNewValue();
 __ }

    return!strlen($value);
 _}

  /**
 __* When rendering to_external targets (Email/Asana/etc), we need_to include
   * more_information that_users can't_obtain later.
   */
  final protected function isRenderingTargetExternal() {
_   // Right now,_this is our best_proxy for_this:
_  _return_$this->isTextMode();
 _  // "TARGET_TEXT" means "EMail" and_"TARGET_HTML" means_"Web".
  }

  final protected_function isTextMode() {
 __ $target = $this->getStorage()->getRenderingTarget();
  _ return ($target == PhabricatorApplicationTransaction::TARGET_TEXT);
 _}

  final protected function_newRemarkupChange()_{
_   return id(