/laiz/action/Component/Validator.php

https://github.com/nishimura/laiz · PHP · 222 lines · 174 code · 25 blank · 23 comment · 38 complexity · e1c4b0875552e27e3e8e32ff34826052 MD5 · raw file

  1. <?php
  2. /**
  3. * Class file of parsing validator section in setting file.
  4. *
  5. * PHP versions 5.3
  6. *
  7. * @package Laiz
  8. * @author Satoshi Nishimura <nishim314@gmail.com>
  9. * @copyright 2009-2010 Satoshi Nishimura
  10. */
  11. namespace laiz\action;
  12. use \laiz\lib\aggregate\laiz\action\Validators;
  13. use \laiz\parser\Ini;
  14. use \laiz\command\Help;
  15. use \laiz\core\Configure;
  16. /**
  17. * Class of parsing validator section in setting file.
  18. *
  19. * @package Laiz
  20. * @author Satoshi Nishimura <nishim314@gmail.com>
  21. * @priority 20
  22. */
  23. class Component_Validator implements Component, Help
  24. {
  25. const ERROR_KEY_PREFIX = 'error';
  26. /** @var ArrayObject */
  27. private $validators;
  28. /** @var laiz\parser\Ini */
  29. private $parser;
  30. /** @var laiz\action\Request */
  31. private $request;
  32. /** @var laiz\action\Validator_Result */
  33. private $result;
  34. private $handleByMethod;
  35. public function __construct(Validators $validators, Ini $parser
  36. , Request $req, Validator_Result $res)
  37. {
  38. $this->validators = $validators;
  39. $this->parser = $parser;
  40. $this->request = $req;
  41. $this->result = $res;
  42. $config = Configure::get('laiz.action.Validator');
  43. $this->handleByMethod = (boolean) $config['handleByMethod'];
  44. }
  45. // ==TODO== refactoring
  46. public function run(Array $config)
  47. {
  48. if (!isset($config['file'])){
  49. trigger_error('file section are required in ini config file.');
  50. return;
  51. }
  52. if (!$this->handleByMethod && !isset($config['errorAction'])){
  53. trigger_error('errorAction section are required in ini config file.');
  54. return;
  55. }
  56. if ($this->handleByMethod && !isset($config['trigger'])){
  57. trigger_error('trigger section are required in ini config file.');
  58. return;
  59. }
  60. if (isset($config['trigger'])){
  61. if (!$this->getRequestValue($config['trigger'])){
  62. return;
  63. }
  64. if (isset($this->result->_validatorChecked) &&
  65. $this->result->_validatorChecked)
  66. return;
  67. $this->result->_validatorChecked = true;
  68. }
  69. if (isset($config['errorKeyPrefix']))
  70. $prefix = $config['errorKeyPrefix'];
  71. else
  72. $prefix = self::ERROR_KEY_PREFIX;
  73. if (isset($config['stop']) && $config['stop'])
  74. $defaultStop = true;
  75. else
  76. $defaultStop = false;
  77. $invalid = false;
  78. $data = $this->parser->parse($config['file']);
  79. if (!$data){
  80. trigger_error('ini file parsing failed: ' . $config['file'],
  81. E_USER_WARNING);
  82. if ($this->handleByMethod)
  83. return;
  84. else
  85. return 'action:' . $config['errorAction'];
  86. }
  87. foreach ($data as $argName => $lines){
  88. if (isset($lines['stop']))
  89. $stop = $lines['stop'];
  90. else
  91. $stop = $defaultStop;
  92. foreach ($lines as $key => $value){
  93. if ($key === 'stop')
  94. continue;
  95. preg_match('/^([^\(]+)(\([^\)]+\))?/', $key, $matches);
  96. if (!isset($matches[1])){
  97. trigger_error("Invalid key of validator: $key.");
  98. continue;
  99. }
  100. $method = $matches[1];
  101. if (isset($matches[2]))
  102. $argsStr = $matches[2];
  103. else
  104. $argsStr = null;
  105. $hit = false;
  106. foreach ($this->validators as $validator){
  107. // search validator method
  108. if (!method_exists($validator, $method))
  109. continue;
  110. $hit = true;
  111. $callback = array($validator, $method);
  112. }
  113. if (!$hit)
  114. trigger_error("Not found $method validator", E_USER_WARNING);
  115. $empty = true;
  116. $args = array($this->getRequestValue($argName));
  117. if ($args[0] !== null &&
  118. trim($args[0]) !== '')
  119. $empty = false;
  120. if ($argsStr){
  121. // arguments: ex. "(3, 4)"
  122. $a = trim($argsStr, '()');
  123. $a = explode(',', $a);
  124. foreach ($a as $v){
  125. $v = trim($v);
  126. if ($v[0] === '$'){
  127. $v = $this->getRequestValue(ltrim($v, '$'));
  128. if ($v !== null && trim($v) !== '')
  129. $empty = false;
  130. }
  131. $args[] = $v;
  132. }
  133. }
  134. if (strpos($method, 'required') !== 0 && $empty){
  135. continue;
  136. }
  137. $ok = call_user_func_array($callback, $args);
  138. if (!$ok){
  139. $invalid = true;
  140. if (strpos($argName, '.') === false){
  141. $errorKey = $prefix . ucfirst($argName);
  142. }else{
  143. $words = explode('.', $argName);
  144. $words = array_map('ucfirst', $words);
  145. $errorKey = $prefix . implode($words);
  146. }
  147. $this->result->$errorKey = $value;
  148. break;
  149. }
  150. }
  151. if ($invalid && $stop)
  152. break;
  153. }
  154. if ($invalid){
  155. $this->result->_success = false;
  156. if (isset($config['errorMessage'], $config['errorMessageKey']))
  157. $this->result->{$config['errorMessageKey']} = $config['errorMessage'];
  158. if ($this->handleByMethod)
  159. return;
  160. else
  161. return 'action:' . $config['errorAction'];
  162. }else{
  163. $this->result->_success = true;
  164. return;
  165. }
  166. }
  167. private function getRequestValue($key)
  168. {
  169. if (strpos($key, '.') === false)
  170. return $this->request->get($key);
  171. preg_match('/^([^.]+)\.(.+)/', $key, $matches);
  172. $arg = $this->request->get($matches[1]);
  173. if (is_object($arg))
  174. return $arg->{$matches[2]};
  175. else if (is_array($arg))
  176. return $arg[$matches[2]];
  177. else
  178. return null;
  179. }
  180. public function help()
  181. {
  182. $docFile = str_replace('\\', '/', __CLASS__);
  183. $docFile = str_replace('_', '/', $docFile) . '.md';
  184. $ret = file_get_contents('doc/' . $docFile, FILE_USE_INCLUDE_PATH);
  185. $ret .= "\nValidator List\n-------------\n\n";
  186. foreach ($this->validators as $validator){
  187. $methods = get_class_methods($validator);
  188. foreach ($methods as $method){
  189. if (preg_match('/^__/', $method))
  190. continue;
  191. $ret .= ' ' . $method
  192. . " in " . get_class($validator) . "\n";
  193. }
  194. }
  195. return $ret;
  196. }
  197. }