PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/class.atknodevalidator.inc

https://github.com/ibuildingsnl/ATK
PHP | 274 lines | 154 code | 30 blank | 90 comment | 41 complexity | 7188063b5046146d7c774d66940c4582 MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception, LGPL-3.0
  1. <?php
  2. /**
  3. * This file is part of the Achievo ATK distribution.
  4. * Detailed copyright and licensing information can be found
  5. * in the doc/COPYRIGHT and doc/LICENSE files which should be
  6. * included in the distribution.
  7. *
  8. * @package atk
  9. *
  10. * @copyright (c)2000-2004 Ibuildings.nl BV
  11. * @license http://www.achievo.org/atk/licensing ATK Open Source License
  12. *
  13. * @version $Revision$
  14. * $Id$
  15. */
  16. /**
  17. * Validator for records, based on node definition.
  18. *
  19. * The class takes a node, and based on the attribute definitions,
  20. * validation can be performed on records.
  21. *
  22. * @author Kees van Dieren <kees@ibuildings.nl>
  23. * @package atk
  24. *
  25. */
  26. class atkNodeValidator
  27. {
  28. /**
  29. * @var atkNode The node which needs to get validated
  30. * @access private
  31. */
  32. var $m_nodeObj = null;
  33. /**
  34. * @var array the record of the node which will get validated
  35. * @access private
  36. */
  37. var $m_record = array();
  38. /**
  39. * @var String the mode in which the validate will get runned
  40. * @access private
  41. */
  42. var $m_mode = "";
  43. /**
  44. * constructor
  45. *
  46. */
  47. function atkNodeValidator()
  48. {
  49. }
  50. /**
  51. * set the list of fields which will get ignored
  52. * @param array $fieldArr List of fields to ignore during validation
  53. */
  54. function setIgnoreList($fieldArr)
  55. {
  56. $this->m_ignoreList = $fieldArr;
  57. }
  58. /**
  59. * set the mode in which to validate
  60. * @param String $mode The mode ("edit"/"add")
  61. */
  62. function setMode($mode)
  63. {
  64. $this->m_mode = $mode;
  65. }
  66. /**
  67. * Set the Node which should be validated
  68. *
  69. * @param atkNode $nodeObj The node for validation
  70. */
  71. function setNode(&$nodeObj)
  72. {
  73. $this->m_nodeObj = &$nodeObj;
  74. }
  75. /**
  76. * set the record which should get validated.
  77. * @param array $record The record to validate. The record is passed by
  78. * reference, because errors that are found are
  79. * stored in the record.
  80. */
  81. function setRecord(&$record)
  82. {
  83. $this->m_record = &$record;
  84. }
  85. /**
  86. * Validate a record
  87. *
  88. * @param string $mode Override the mode
  89. * @param array $ignoreList Override the ignoreList
  90. */
  91. function validate($mode="", $ignoreList=array())
  92. {
  93. // check overrides
  94. if(count($ignoreList))
  95. $this->setIgnoreList($ignoreList);
  96. if($mode != "")
  97. $this->setMode($mode);
  98. atkdebug("validate() with mode ".$this->m_mode." for node ".$this->m_nodeObj->atkNodeType());
  99. // set the record
  100. $record = &$this->m_record;
  101. // Check flags and values
  102. $db = &$this->m_nodeObj->getDb();
  103. foreach ($this->m_nodeObj->m_attribIndexList as $attribdata)
  104. {
  105. $attribname = $attribdata['name'];
  106. if (!atk_in_array($attribname, $this->m_ignoreList))
  107. {
  108. $p_attrib = &$this->m_nodeObj->m_attribList[$attribname];
  109. $this->validateAttributeValue($p_attrib, $record);
  110. if ($p_attrib->hasFlag(AF_PRIMARY) && !$p_attrib->hasFlag(AF_AUTO_INCREMENT))
  111. {
  112. $atkorgkey = $record["atkprimkey"];
  113. if(($atkorgkey == '' // no orgkey, so adding this record
  114. || $atkorgkey != $this->m_nodeObj->primaryKey($record)) // key has changed, so check is necessary
  115. && $this->m_nodeObj->countDb($this->m_nodeObj->primaryKey($record))>0
  116. )
  117. {
  118. atkTriggerError($record, $p_attrib, 'error_primarykey_exists');
  119. }
  120. }
  121. // if no root elements may be added to the tree, then every record needs to have a parent!
  122. if ($p_attrib->hasFlag(AF_PARENT) && $this->m_nodeObj->hasFlag(NF_TREE_NO_ROOT_ADD) && $this->m_nodeObj->m_action == "save")
  123. $p_attrib->m_flags |= AF_OBLIGATORY;
  124. // validate obligatory fields (but not the auto_increment ones, because they don't have a value yet)
  125. if ($p_attrib->hasFlag(AF_OBLIGATORY) && !$p_attrib->hasFlag(AF_AUTO_INCREMENT) && $p_attrib->isEmpty($record))
  126. {
  127. atkTriggerError($record, $p_attrib, 'error_obligatoryfield');
  128. }
  129. // if flag is primary
  130. else if ($p_attrib->hasFlag(AF_UNIQUE) && !$p_attrib->hasFlag(AF_PRIMARY) && !$p_attrib->isEmpty($record)
  131. && $this->m_nodeObj->countDb($this->m_nodeObj->getTable().".{$attribname}='".$db->escapeSQL($p_attrib->value2db($record))."'".($this->m_mode != 'add' ? " AND NOT (".$this->m_nodeObj->primaryKey($record).")" : ""))>0
  132. )
  133. {
  134. atkTriggerError($record, $p_attrib, 'error_uniquefield');
  135. }
  136. }
  137. }
  138. if(isset($record['atkerror'])&&count($record['atkerror']) > 0)
  139. {
  140. for ($i = 0, $_i = count($record["atkerror"]); $i < $_i; $i++)
  141. $record["atkerror"][$i]["node"] = $this->m_nodeObj->m_type;
  142. }
  143. $this->validateUniqueFieldSets($record);
  144. if (isset($record['atkerror']))
  145. {
  146. for ($i = 0, $_i = count($record["atkerror"]); $i < $_i; $i++)
  147. $record["atkerror"][$i]["node"] = $this->m_nodeObj->m_type;
  148. return false;
  149. }
  150. return true;
  151. }
  152. /**
  153. * Validate attribute value.
  154. *
  155. * @param atkAttribute $p_attrib pointer to the attribute
  156. * @param array $record record
  157. */
  158. function validateAttributeValue(&$p_attrib, &$record)
  159. {
  160. if (!$p_attrib->isEmpty($record))
  161. {
  162. $funcname = $p_attrib->m_name."_validate";
  163. if (method_exists($this->m_nodeObj, $funcname))
  164. {
  165. $this->m_nodeObj->$funcname($record, $this->m_mode);
  166. }
  167. else
  168. {
  169. $p_attrib->validate($record, $this->m_mode);
  170. }
  171. }
  172. }
  173. /**
  174. * @deprecated
  175. *
  176. * @param array $record
  177. */
  178. function validateAttributes(&$record)
  179. {
  180. foreach (array_keys($this->m_nodeObj->m_attribList) as $attribname)
  181. {
  182. if (!atk_in_array($attribname, $this->m_ignoreList))
  183. {
  184. $p_attrib = &$this->m_nodeObj->m_attribList[$attribname];
  185. $this->validateAttributeValue($p_attrib, $record);
  186. }
  187. }
  188. }
  189. /**
  190. * Check unique field combinations.
  191. * The function is called by the validate() method automatically. It is
  192. * not necessary to call this manually in a validation process.
  193. * Errors that are found are stored in the $record parameter
  194. *
  195. * @param array $record The record to validate
  196. */
  197. function validateUniqueFieldSets(&$record)
  198. {
  199. $db = &$this->m_nodeObj->getDb();
  200. atkimport('atk.db.atkquery');
  201. foreach($this->m_nodeObj->m_uniqueFieldSets as $uniqueFieldSet)
  202. {
  203. $query = &$db->createQuery();
  204. $query->addField('*');
  205. $query->addTable($this->m_nodeObj->m_table);
  206. $attribs = array();
  207. foreach($uniqueFieldSet as $field)
  208. {
  209. $attrib = &$this->m_nodeObj->m_attribList[$field];
  210. if ($attrib)
  211. {
  212. $attribs[] = &$attrib;
  213. if (is_a($attrib, 'atkmanytoonerelation') && count($attrib->m_refKey) > 1)
  214. {
  215. $attrib->createDestination();
  216. foreach ($attrib->m_refKey as $refkey)
  217. {
  218. $query->addCondition($query->quoteField($refkey)." = '".$db->escapeSQL($record[$attrib->fieldName()][$refkey])."'");
  219. }
  220. }
  221. else if (!$attrib->isNotNullInDb() && $attrib->isEmpty($record))
  222. {
  223. $query->addCondition($query->quoteField($field)." IS NULL");
  224. }
  225. else
  226. {
  227. $query->addCondition($query->quoteField($field)." = '".$attrib->value2db($record)."'");
  228. }
  229. }
  230. else
  231. atkerror("Field $field is mentioned in uniquefieldset but does not exist in ".$this->m_nodeObj->atknodetype());
  232. }
  233. if ($this->m_mode != 'add')
  234. {
  235. $query->addCondition("NOT (".$this->m_nodeObj->primaryKey($record).")");
  236. }
  237. if (count($db->getRows($query->buildSelect()))> 0)
  238. {
  239. atkTriggerError($record, $attribs, 'error_uniquefieldset');
  240. }
  241. }
  242. }
  243. }
  244. ?>