field.class.inc.php 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. <?php
  2. // Copyright (C) 2010-2017 Combodo SARL
  3. //
  4. // This file is part of iTop.
  5. //
  6. // iTop is free software; you can redistribute it and/or modify
  7. // it under the terms of the GNU Affero General Public License as published by
  8. // the Free Software Foundation, either version 3 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // iTop is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU Affero General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU Affero General Public License
  17. // along with iTop. If not, see <http://www.gnu.org/licenses/>
  18. namespace Combodo\iTop\Form\Field;
  19. use \Closure;
  20. use \Combodo\iTop\Form\Validator\Validator;
  21. use \Combodo\iTop\Form\Validator\MandatoryValidator;
  22. /**
  23. * Description of Field
  24. *
  25. * @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
  26. */
  27. abstract class Field
  28. {
  29. const ENUM_DISPLAY_MODE_COSY = 'cosy'; // Label above value
  30. const ENUM_DISPLAY_MODE_COMPACT = 'compact'; // Label and value side by side
  31. const ENUM_DISPLAY_MODE_DENSE = 'dense'; // Label and value side by side, closely
  32. const DEFAULT_LABEL = '';
  33. const DEFAULT_HIDDEN = false;
  34. const DEFAULT_READ_ONLY = false;
  35. const DEFAULT_MANDATORY = false;
  36. const DEFAULT_DISPLAY_MODE = self::ENUM_DISPLAY_MODE_COSY;
  37. const DEFAULT_VALID = true;
  38. protected $sId;
  39. protected $sGlobalId;
  40. protected $sFormPath;
  41. protected $sLabel;
  42. protected $bHidden;
  43. protected $bReadOnly;
  44. protected $bMandatory;
  45. protected $sDisplayMode;
  46. protected $aValidators;
  47. protected $bValid;
  48. protected $aErrorMessages;
  49. protected $currentValue;
  50. protected $onFinalizeCallback;
  51. /**
  52. * Default constructor
  53. *
  54. * @param string $sId
  55. * @param Closure $onFinalizeCallback (Used in the $oForm->AddField($sId, ..., function() use ($oManager, $oForm, '...') { ... } ); )
  56. */
  57. public function __construct($sId, Closure $onFinalizeCallback = null)
  58. {
  59. $this->sId = $sId;
  60. // No space in such an id, that could be used as a DOM node id
  61. $this->sGlobalId = 'field_' . str_replace(' ', '_', $sId) . '_' . uniqid();
  62. $this->sLabel = static::DEFAULT_LABEL;
  63. $this->bHidden = static::DEFAULT_HIDDEN;
  64. $this->bReadOnly = static::DEFAULT_READ_ONLY;
  65. $this->bMandatory = static::DEFAULT_MANDATORY;
  66. $this->sDisplayMode = static::DEFAULT_DISPLAY_MODE;
  67. $this->aValidators = array();
  68. $this->bValid = static::DEFAULT_VALID;
  69. $this->aErrorMessages = array();
  70. $this->onFinalizeCallback = $onFinalizeCallback;
  71. }
  72. /**
  73. * Returns the field id within its container form
  74. *
  75. * @return string
  76. */
  77. public function GetId()
  78. {
  79. return $this->sId;
  80. }
  81. /**
  82. * Returns a unique field id within the top level form
  83. *
  84. * @return string
  85. */
  86. public function GetGlobalId()
  87. {
  88. return $this->sGlobalId;
  89. }
  90. /**
  91. * Returns the id of the container form
  92. *
  93. * @return string
  94. */
  95. public function GetFormPath()
  96. {
  97. return $this->sFormPath;
  98. }
  99. /**
  100. *
  101. * @return string
  102. */
  103. public function GetLabel()
  104. {
  105. return $this->sLabel;
  106. }
  107. /**
  108. *
  109. * @return boolean
  110. */
  111. public function GetHidden()
  112. {
  113. return $this->bHidden;
  114. }
  115. /**
  116. *
  117. * @return boolean
  118. */
  119. public function GetReadOnly()
  120. {
  121. return $this->bReadOnly;
  122. }
  123. /**
  124. *
  125. * @return boolean
  126. */
  127. public function GetMandatory()
  128. {
  129. return $this->bMandatory;
  130. }
  131. /**
  132. *
  133. * @return string
  134. */
  135. public function GetDisplayMode()
  136. {
  137. return $this->sDisplayMode;
  138. }
  139. /**
  140. *
  141. * @return array
  142. */
  143. public function GetValidators()
  144. {
  145. return $this->aValidators;
  146. }
  147. /**
  148. * Returns the current validation state of the field (true|false).
  149. * It DOESN'T make the validation, see Validate() instead.
  150. *
  151. * @return boolean
  152. */
  153. public function GetValid()
  154. {
  155. return $this->bValid;
  156. }
  157. /**
  158. *
  159. * @return array
  160. */
  161. public function GetErrorMessages()
  162. {
  163. return $this->aErrorMessages;
  164. }
  165. /**
  166. *
  167. * @return array
  168. */
  169. public function GetCurrentValue()
  170. {
  171. return $this->currentValue;
  172. }
  173. public function GetDisplayValue()
  174. {
  175. return $this->currentValue;
  176. }
  177. /**
  178. * Sets the field formpath
  179. * Usually Called by the form when adding the field
  180. *
  181. * @param string $sFormPath
  182. * @return \Combodo\iTop\Form\Field\Field
  183. */
  184. public function SetFormPath($sFormPath)
  185. {
  186. $this->sFormPath = $sFormPath;
  187. return $this;
  188. }
  189. /**
  190. *
  191. * @param type $sLabel
  192. * @return \Combodo\iTop\Form\Field\Field
  193. */
  194. public function SetLabel($sLabel)
  195. {
  196. $this->sLabel = $sLabel;
  197. return $this;
  198. }
  199. /**
  200. *
  201. * @param boolean $bHidden
  202. * @return \Combodo\iTop\Form\Field\Field
  203. */
  204. public function SetHidden($bHidden)
  205. {
  206. $this->bHidden = $bHidden;
  207. return $this;
  208. }
  209. /**
  210. *
  211. * @param boolean $bReadOnly
  212. * @return \Combodo\iTop\Form\Field\Field
  213. */
  214. public function SetReadOnly($bReadOnly)
  215. {
  216. $this->bReadOnly = $bReadOnly;
  217. return $this;
  218. }
  219. /**
  220. * Sets if the field is mandatory or not.
  221. * Setting the value will automatically add/remove a MandatoryValidator to the Field
  222. *
  223. * @param boolean $bMandatory
  224. * @return \Combodo\iTop\Form\Field\Field
  225. */
  226. public function SetMandatory($bMandatory)
  227. {
  228. // Before changing the property, we check if it was already mandatory. If not, we had the mandatory validator
  229. if ($bMandatory && !$this->bMandatory)
  230. {
  231. $this->AddValidator(new MandatoryValidator());
  232. }
  233. if (!$bMandatory)
  234. {
  235. foreach ($this->aValidators as $iKey => $oValue)
  236. {
  237. if ($oValue::Getname() === MandatoryValidator::GetName())
  238. {
  239. unset($this->aValidators[$iKey]);
  240. }
  241. }
  242. }
  243. $this->bMandatory = $bMandatory;
  244. return $this;
  245. }
  246. /**
  247. *
  248. * @param $sDisplayMode
  249. * @return $this
  250. */
  251. public function SetDisplayMode($sDisplayMode)
  252. {
  253. $this->sDisplayMode = $sDisplayMode;
  254. return $this;
  255. }
  256. /**
  257. *
  258. * @param array $aValidators
  259. * @return \Combodo\iTop\Form\Field\Field
  260. */
  261. public function SetValidators($aValidators)
  262. {
  263. $this->aValidators = $aValidators;
  264. return $this;
  265. }
  266. /**
  267. * Note : Function is protected as bValid should not be set from outside
  268. *
  269. * @param boolean $bValid
  270. * @return \Combodo\iTop\Form\Field\Field
  271. */
  272. protected function SetValid($bValid)
  273. {
  274. $this->bValid = $bValid;
  275. return $this;
  276. }
  277. /**
  278. * Note : Function is protected as aErrorMessages should not be set from outside
  279. *
  280. * @param array $aErrorMessages
  281. * @return \Combodo\iTop\Form\Field\Field
  282. */
  283. protected function SetErrorMessages($aErrorMessages)
  284. {
  285. $this->aErrorMessages = $aErrorMessages;
  286. return $this;
  287. }
  288. /**
  289. *
  290. * @param mixed $currentValue
  291. * @return \Combodo\iTop\Form\Field\Field
  292. */
  293. public function SetCurrentValue($currentValue)
  294. {
  295. $this->currentValue = $currentValue;
  296. return $this;
  297. }
  298. /**
  299. *
  300. * @param Closure $onFinalizeCallback
  301. * @return \Combodo\iTop\Form\Field\Field
  302. */
  303. public function SetOnFinalizeCallback(Closure $onFinalizeCallback)
  304. {
  305. $this->onFinalizeCallback = $onFinalizeCallback;
  306. return $this;
  307. }
  308. /**
  309. *
  310. * @param Validator $oValidator
  311. * @return \Combodo\iTop\Form\Field\Field
  312. */
  313. public function AddValidator(Validator $oValidator)
  314. {
  315. $this->aValidators[] = $oValidator;
  316. return $this;
  317. }
  318. /**
  319. *
  320. * @param Validator $oValidator
  321. * @return \Combodo\iTop\Form\Field\Field
  322. */
  323. public function RemoveValidator(Validator $oValidator)
  324. {
  325. foreach ($this->aValidators as $iKey => $oValue)
  326. {
  327. if ($oValue === $oValidator)
  328. {
  329. unset($this->aValidators[$iKey]);
  330. }
  331. }
  332. return $this;
  333. }
  334. /**
  335. * Note : Function is protected as aErrorMessages should not be add from outside
  336. *
  337. * @param string $sErrorMessage
  338. * @return \Combodo\iTop\Form\Field\Field
  339. */
  340. protected function AddErrorMessage($sErrorMessage)
  341. {
  342. $this->aErrorMessages[] = $sErrorMessage;
  343. return $this;
  344. }
  345. /**
  346. * Note : Function is protected as aErrorMessages should not be set from outside
  347. *
  348. * @return \Combodo\iTop\Form\Field\Field
  349. */
  350. protected function EmptyErrorMessages()
  351. {
  352. $this->aErrorMessages = array();
  353. return $this;
  354. }
  355. /**
  356. * Returns if the field is editable. Meaning that it is not editable nor hidden.
  357. *
  358. * @return boolean
  359. */
  360. public function IsEditable()
  361. {
  362. return (!$this->bReadOnly && !$this->bHidden);
  363. }
  364. public function OnCancel()
  365. {
  366. // Overload when needed
  367. }
  368. public function OnFinalize()
  369. {
  370. if ($this->onFinalizeCallback !== null)
  371. {
  372. // Note : We MUST have a temp variable to call the Closure. otherwise it won't work when the Closure is a class member
  373. $callback = $this->onFinalizeCallback;
  374. $callback($this);
  375. }
  376. }
  377. /**
  378. * Checks the validators to see if the field's current value is valid.
  379. * Then sets $bValid and $aErrorMessages.
  380. *
  381. * @return boolean
  382. */
  383. public function Validate()
  384. {
  385. $this->SetValid(true);
  386. $this->EmptyErrorMessages();
  387. $bEmpty = ( ($this->GetCurrentValue() === null) || ($this->GetCurrentValue() === '') );
  388. if (!$bEmpty || $this->GetMandatory())
  389. {
  390. foreach ($this->GetValidators() as $oValidator)
  391. {
  392. if (!preg_match($oValidator->GetRegExp(true), $this->GetCurrentValue()))
  393. {
  394. $this->SetValid(false);
  395. $this->AddErrorMessage($oValidator->GetErrorMessage());
  396. }
  397. }
  398. }
  399. return $this->GetValid();
  400. }
  401. }