Rules.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <?php
  2. /**
  3. * 数据保存规则
  4. * @author Jinhui Zhu<jinhui.zhu@live.cn> 2015-12-16
  5. */
  6. namespace Qii\Driver;
  7. use Qii\Exceptions\MethodNotFound;
  8. class Rules
  9. {
  10. const VERSION = '1.2';
  11. /**
  12. * @var $rules
  13. */
  14. private $rules;
  15. /**
  16. * @var $cacheRules
  17. */
  18. static $cacheRules;
  19. static $invalidMessage;
  20. public function __construct($rules)
  21. {
  22. $this->rules = $rules;
  23. }
  24. /**
  25. * 获取使用的数据表名
  26. *
  27. * @return mixed
  28. * @throws \Exception 未定义database的时候就抛出异常
  29. */
  30. public function getDatabase()
  31. {
  32. if (!isset($this->rules['database'])) {
  33. throw new \Exception(\Qii::i(5001, 'database'), __LINE__);
  34. }
  35. return $this->rules['database'];
  36. }
  37. /**
  38. * 获取数据表名称
  39. *
  40. * @return mixed
  41. * @throws \Exception 未定义table的时候就抛出异常
  42. * @return string
  43. */
  44. public function getTableName()
  45. {
  46. if (!isset($this->rules['tableName'])) {
  47. throw new \Exception(\Qii::i(5001, 'tableName'), __LINE__);
  48. }
  49. return $this->rules['tableName'];
  50. }
  51. /**
  52. * 获取数据表中的字段列表
  53. *
  54. * @return mixed
  55. * @throws \Exception
  56. */
  57. public function getFields()
  58. {
  59. if (!isset($this->rules['rules']['fields'])) {
  60. throw new \Exception(\Qii::i(5002, 'fields'), __LINE__);
  61. }
  62. return $this->rules['rules']['fields'];
  63. }
  64. /**
  65. * 获取验证失败的时候提示信息
  66. * 优先使用规则里表中的验证提示信息,如果未指定,再使用自动生成的规则信息
  67. * @return array 提示信息
  68. */
  69. public function getInvalidMessage()
  70. {
  71. if (isset($this->rules['rules']['invalidMessage'])) return $this->rules['rules']['invalidMessage'];
  72. if (isset(self::$invalidMessage[$this->rules['database'] . $this->rules['tableName']])) return self::$invalidMessage[$this->rules['database'] . $this->rules['tableName']];
  73. return array();
  74. }
  75. /**
  76. * 获取数据表保存\更新\的验证规则
  77. * @return array 获取验证规则
  78. */
  79. public function getOriginalRules()
  80. {
  81. if (!isset($this->rules['rules'])) {
  82. return array();
  83. }
  84. return $this->rules['rules'];
  85. }
  86. /**
  87. * 重置privateKeys使用
  88. *
  89. * @return array
  90. */
  91. public function getOperateValidFields($opt = null)
  92. {
  93. $fields = array();
  94. //检查是否存在数据使用字段
  95. if (isset($this->rules['rules']['existValid'])) {
  96. $fields['exist'] = array_keys($this->rules['rules']['existValid']);
  97. }
  98. //检查是保存使用字段
  99. if (isset($this->rules['rules']['saveValid'])) {
  100. $fields['save'] = array_keys($this->rules['rules']['saveValid']);
  101. }
  102. //更新使用字段
  103. if (isset($this->rules['rules']['updateValid'])) {
  104. $fields['update'] = array_keys($this->rules['rules']['updateValid']);
  105. }
  106. //删除使用字段
  107. if (isset($this->rules['rules']['removeValid'])) {
  108. $fields['remove'] = array_keys($this->rules['rules']['removeValid']);
  109. }
  110. if (!$opt) return $fields;
  111. return isset($fields[$opt]) ? $fields[$opt] : array();
  112. }
  113. /**
  114. * 获取唯一字段,如果不设置privatekey就是用此字段作为privatekey
  115. */
  116. public function getPrivateKey()
  117. {
  118. if (isset($this->rules['rules']['uni']) && count($this->rules['rules']['uni']) > 0) return $this->rules['rules']['uni'];
  119. }
  120. /**
  121. * 根据字段获取验证规则
  122. * @param string $field 需要验证的字段
  123. * @return array 验证规则
  124. */
  125. public function getRulesByField($field)
  126. {
  127. $rules = $this->buildRules();
  128. return isset($rules[$field]) ? $rules[$field] : array();
  129. }
  130. /**
  131. * 根据配置生成所有验证需要的规则
  132. *
  133. * @return array 生成规则
  134. */
  135. public function buildRules()
  136. {
  137. $rules = array();
  138. if (!isset($this->rules['rules']['validate']) && count($this->rules['rules']['validate']) == 0) {
  139. return $rules;
  140. }
  141. if (isset(self::$cacheRules[$this->rules['database'] . $this->rules['tableName']]['rules'])) return self::$cacheRules[$this->rules['database'] . $this->rules['tableName']]['rules'];
  142. foreach ($this->rules['rules']['validate'] AS $key => $validate) {
  143. $fieldRules = array();
  144. $fieldRules['required'] = false;
  145. foreach ($validate AS $rule) {
  146. if ($rule == 'minlength') {
  147. $fieldRules[$rule] = 1;
  148. continue;
  149. }
  150. if ($rule == 'maxlength') {
  151. $fieldRules[$rule] = $this->rules['rules']['length'][$key];
  152. continue;
  153. }
  154. if ($rule == 'sets') {
  155. if (isset($this->rules['rules']['sets'][$key])) $fieldRules[$rule] = $this->rules['rules']['sets'][$key];
  156. continue;
  157. }
  158. $fieldRules[$rule] = true;
  159. //根据验证类型自动生成规则验证错误信息
  160. $alias = isset($this->rules['rules']['alias']) && isset($this->rules['rules']['alias'][$key]) ? $this->rules['rules']['alias'][$key] : $key;
  161. self::$invalidMessage[$this->rules['database'] . $this->rules['tableName']][$key][$rule] = $rule == 'required' ? \Qii::i(5003, $alias) : \Qii::i(5004, $alias);
  162. }
  163. $rules[$key] = $fieldRules;
  164. }
  165. self::$cacheRules[$this->rules['database'] . $this->rules['tableName']]['rules'] = $rules;
  166. return $rules;
  167. }
  168. /**
  169. * 通过数据库操作类型获取对应的规则
  170. * @param string $opt 操作类型
  171. * @return array 规则
  172. */
  173. public function getRulesByOperate($opt = 'save')
  174. {
  175. $rules = array();
  176. $allowOpt = array('save', 'update', 'remove');
  177. if (!in_array($opt, $allowOpt)) {
  178. throw new \Qii\Exceptions\NotAllowed(\Qii::i(5002, $opt), __LINE__);
  179. }
  180. if (isset(self::$cacheRules[$this->rules['database'] . $this->rules['tableName']][$opt])) return self::$cacheRules[$this->rules['database'] . $this->rules['tableName']][$opt];
  181. $buildRules = $this->buildRules();
  182. //获取字段的验证类型
  183. $fieldsValidate = $this->rules['rules']['validate'];
  184. //获取操作需要验证的字段
  185. if (!isset($this->rules['rules'][$opt]) || count($this->rules['rules'][$opt]) == 0) return $rules;
  186. foreach ($this->rules['rules'][$opt] AS $key => $val) {
  187. //如果操作需要验证字段没有设定规则,就验证字段必须有值
  188. if (isset($buildRules[$key])) {
  189. $rules[$key] = $buildRules[$key];
  190. } else {
  191. $rules[$key] = array('required' => true);
  192. }
  193. }
  194. self::$cacheRules[$this->rules['database'] . $this->rules['tableName']][$opt] = $rules;
  195. return $rules;
  196. }
  197. /**
  198. * 通过 $this->$val来获取 $this->$val();的返回内容
  199. * @param string $name 属性名称
  200. */
  201. public function __get($name)
  202. {
  203. if (method_exists($this, $name)) {
  204. return call_user_func_array(array($this, $name), array());
  205. }
  206. throw new MethodNotFound(\Qii::i(1101, $name), __LINE__);
  207. }
  208. /**
  209. * 调用不存在的方法抛出方法不存在的异常
  210. * @param string $method
  211. * @param mix $args
  212. */
  213. public function __call($method, $args)
  214. {
  215. throw new MethodNotFound(\Qii::i(1101, $method), __LINE__);
  216. }
  217. }