Browse Source

Extract validator logic into a trait.

Having these methods in a trait will let us not copy + paste code into
the elastic search plugin. It could also be useful for other datasource
plugins that need validation features.
Mark Story 11 years ago
parent
commit
a6a2eb38cf
2 changed files with 110 additions and 79 deletions
  1. 2 79
      src/ORM/Table.php
  2. 108 0
      src/Validation/ValidatorAwareTrait.php

+ 2 - 79
src/ORM/Table.php

@@ -37,7 +37,7 @@ use Cake\ORM\Marshaller;
 use Cake\ORM\RulesChecker;
 use Cake\ORM\Rule\IsUnique;
 use Cake\Utility\Inflector;
-use Cake\Validation\Validator;
+use Cake\Validation\ValidatorAwareTrait;
 use InvalidArgumentException;
 use RuntimeException;
 
@@ -121,6 +121,7 @@ class Table implements RepositoryInterface, EventListenerInterface
 {
 
     use EventManagerTrait;
+    use ValidatorAwareTrait;
 
     /**
      * Name of default validation set.
@@ -201,13 +202,6 @@ class Table implements RepositoryInterface, EventListenerInterface
     protected $_registryAlias;
 
     /**
-     * A list of validation objects indexed by name
-     *
-     * @var array
-     */
-    protected $_validators = [];
-
-    /**
      * The domain rules to be applied to entities saved by this table
      *
      * @var \Cake\ORM\RulesChecker
@@ -1162,77 +1156,6 @@ class Table implements RepositoryInterface, EventListenerInterface
     }
 
     /**
-     * Returns the validation rules tagged with $name. It is possible to have
-     * multiple different named validation sets, this is useful when you need
-     * to use varying rules when saving from different routines in your system.
-     *
-     * There are two different ways of creating and naming validation sets: by
-     * creating a new method inside your own Table subclass, or by building
-     * the validator object yourself and storing it using this method.
-     *
-     * For example, if you wish to create a validation set called 'forSubscription',
-     * you will need to create a method in your Table subclass as follows:
-     *
-     * ```
-     * public function validationForSubscription($validator)
-     * {
-     *  return $validator
-     *  ->add('email', 'valid-email', ['rule' => 'email'])
-     *  ->add('password', 'valid', ['rule' => 'notEmpty'])
-     *  ->requirePresence('username');
-     * }
-     * ```
-     *
-     * Otherwise, you can build the object by yourself and store it in the Table object:
-     *
-     * ```
-     * $validator = new \Cake\Validation\Validator($table);
-     * $validator
-     *  ->add('email', 'valid-email', ['rule' => 'email'])
-     *  ->add('password', 'valid', ['rule' => 'notEmpty'])
-     *  ->allowEmpty('bio');
-     * $table->validator('forSubscription', $validator);
-     * ```
-     *
-     * You can implement the method in `validationDefault` in your Table subclass
-     * should you wish to have a validation set that applies in cases where no other
-     * set is specified.
-     *
-     * @param string $name the name of the validation set to return
-     * @param \Cake\Validation\Validator|null $validator The validator instance to store,
-     *   use null to get a validator.
-     * @return \Cake\Validation\Validator
-     */
-    public function validator($name = self::DEFAULT_VALIDATOR, Validator $validator = null)
-    {
-        if ($validator === null && isset($this->_validators[$name])) {
-            return $this->_validators[$name];
-        }
-
-        if ($validator === null) {
-            $validator = new Validator();
-            $validator = $this->{'validation' . ucfirst($name)}($validator);
-            $this->dispatchEvent('Model.buildValidator', compact('validator', 'name'));
-        }
-
-        $validator->provider('table', $this);
-        return $this->_validators[$name] = $validator;
-    }
-
-    /**
-     * Returns the default validator object. Subclasses can override this function
-     * to add a default validation set to the validator object.
-     *
-     * @param \Cake\Validation\Validator $validator The validator that can be modified to
-     * add some rules to it.
-     * @return \Cake\Validation\Validator
-     */
-    public function validationDefault(Validator $validator)
-    {
-        return $validator;
-    }
-
-    /**
      * {@inheritDoc}
      */
     public function deleteAll($conditions)

+ 108 - 0
src/Validation/ValidatorAwareTrait.php

@@ -0,0 +1,108 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.3
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Validation;
+
+use Cake\Validation\Validator;
+
+/**
+ * A trait that provides methods for building and
+ * interacting with Validators.
+ *
+ * This trait is useful when building ORM like features where
+ * the implementing class wants to build and customize a variety
+ * of validator instances.
+ */
+trait ValidatorAwareTrait
+{
+    /**
+     * A list of validation objects indexed by name
+     *
+     * @var array
+     */
+    protected $_validators = [];
+
+    /**
+     * Returns the validation rules tagged with $name. It is possible to have
+     * multiple different named validation sets, this is useful when you need
+     * to use varying rules when saving from different routines in your system.
+     *
+     * There are two different ways of creating and naming validation sets: by
+     * creating a new method inside your own Table subclass, or by building
+     * the validator object yourself and storing it using this method.
+     *
+     * For example, if you wish to create a validation set called 'forSubscription',
+     * you will need to create a method in your Table subclass as follows:
+     *
+     * ```
+     * public function validationForSubscription($validator)
+     * {
+     *  return $validator
+     *  ->add('email', 'valid-email', ['rule' => 'email'])
+     *  ->add('password', 'valid', ['rule' => 'notEmpty'])
+     *  ->requirePresence('username');
+     * }
+     * ```
+     *
+     * Otherwise, you can build the object by yourself and store it in the Table object:
+     *
+     * ```
+     * $validator = new \Cake\Validation\Validator($table);
+     * $validator
+     *  ->add('email', 'valid-email', ['rule' => 'email'])
+     *  ->add('password', 'valid', ['rule' => 'notEmpty'])
+     *  ->allowEmpty('bio');
+     * $table->validator('forSubscription', $validator);
+     * ```
+     *
+     * You can implement the method in `validationDefault` in your Table subclass
+     * should you wish to have a validation set that applies in cases where no other
+     * set is specified.
+     *
+     * @param string $name the name of the validation set to return
+     * @param \Cake\Validation\Validator|null $validator The validator instance to store,
+     *   use null to get a validator.
+     * @return \Cake\Validation\Validator
+     */
+    public function validator($name = self::DEFAULT_VALIDATOR, Validator $validator = null)
+    {
+        if ($validator === null && isset($this->_validators[$name])) {
+            return $this->_validators[$name];
+        }
+
+        if ($validator === null) {
+            $validator = new Validator();
+            $validator = $this->{'validation' . ucfirst($name)}($validator);
+            if (method_exists($this, 'dispatchEvent')) {
+                $this->dispatchEvent('Model.buildValidator', compact('validator', 'name'));
+            }
+        }
+
+        $validator->provider('table', $this);
+        return $this->_validators[$name] = $validator;
+    }
+
+    /**
+     * Returns the default validator object. Subclasses can override this function
+     * to add a default validation set to the validator object.
+     *
+     * @param \Cake\Validation\Validator $validator The validator that can be modified to
+     * add some rules to it.
+     * @return \Cake\Validation\Validator
+     */
+    public function validationDefault(Validator $validator)
+    {
+        return $validator;
+    }
+}