File indexing completed on 2025-01-19 05:21:38

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Validate
0017  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0018  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0019  * @version    $Id$
0020  */
0021 
0022 /**
0023  * @see Zend_Validate_Abstract
0024  */
0025 // require_once 'Zend/Validate/Abstract.php';
0026 
0027 /**
0028  * Class for Database record validation
0029  *
0030  * @category   Zend
0031  * @package    Zend_Validate
0032  * @uses       Zend_Validate_Abstract
0033  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0034  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0035  */
0036 abstract class Zend_Validate_Db_Abstract extends Zend_Validate_Abstract
0037 {
0038     /**
0039      * Error constants
0040      */
0041     const ERROR_NO_RECORD_FOUND = 'noRecordFound';
0042     const ERROR_RECORD_FOUND    = 'recordFound';
0043 
0044     /**
0045      * @var array Message templates
0046      */
0047     protected $_messageTemplates = array(
0048         self::ERROR_NO_RECORD_FOUND => "No record matching '%value%' was found",
0049         self::ERROR_RECORD_FOUND    => "A record matching '%value%' was found",
0050     );
0051 
0052     /**
0053      * @var string
0054      */
0055     protected $_schema = null;
0056 
0057     /**
0058      * @var string
0059      */
0060     protected $_table = '';
0061 
0062     /**
0063      * @var string
0064      */
0065     protected $_field = '';
0066 
0067     /**
0068      * @var mixed
0069      */
0070     protected $_exclude = null;
0071 
0072     /**
0073      * Database adapter to use. If null isValid() will use Zend_Db::getInstance instead
0074      *
0075      * @var unknown_type
0076      */
0077     protected $_adapter = null;
0078 
0079     /**
0080      * Select object to use. can be set, or will be auto-generated
0081      * @var Zend_Db_Select
0082      */
0083     protected $_select;
0084 
0085     /**
0086      * Provides basic configuration for use with Zend_Validate_Db Validators
0087      * Setting $exclude allows a single record to be excluded from matching.
0088      * Exclude can either be a String containing a where clause, or an array with `field` and `value` keys
0089      * to define the where clause added to the sql.
0090      * A database adapter may optionally be supplied to avoid using the registered default adapter.
0091      *
0092      * The following option keys are supported:
0093      * 'table'   => The database table to validate against
0094      * 'schema'  => The schema keys
0095      * 'field'   => The field to check for a match
0096      * 'exclude' => An optional where clause or field/value pair to exclude from the query
0097      * 'adapter' => An optional database adapter to use
0098      *
0099      * @param array|Zend_Config $options Options to use for this validator
0100      * @throws Zend_Validate_Exception
0101      */
0102     public function __construct($options)
0103     {
0104         if ($options instanceof Zend_Db_Select) {
0105             $this->setSelect($options);
0106             return;
0107         }
0108         if ($options instanceof Zend_Config) {
0109             $options = $options->toArray();
0110         } else if (func_num_args() > 1) {
0111             $options       = func_get_args();
0112             $temp['table'] = array_shift($options);
0113             $temp['field'] = array_shift($options);
0114             if (!empty($options)) {
0115                 $temp['exclude'] = array_shift($options);
0116             }
0117 
0118             if (!empty($options)) {
0119                 $temp['adapter'] = array_shift($options);
0120             }
0121 
0122             $options = $temp;
0123         }
0124 
0125         if (!array_key_exists('table', $options) && !array_key_exists('schema', $options)) {
0126             // require_once 'Zend/Validate/Exception.php';
0127             throw new Zend_Validate_Exception('Table or Schema option missing!');
0128         }
0129 
0130         if (!array_key_exists('field', $options)) {
0131             // require_once 'Zend/Validate/Exception.php';
0132             throw new Zend_Validate_Exception('Field option missing!');
0133         }
0134 
0135         if (array_key_exists('adapter', $options)) {
0136             $this->setAdapter($options['adapter']);
0137         }
0138 
0139         if (array_key_exists('exclude', $options)) {
0140             $this->setExclude($options['exclude']);
0141         }
0142 
0143         $this->setField($options['field']);
0144         if (array_key_exists('table', $options)) {
0145             $this->setTable($options['table']);
0146         }
0147 
0148         if (array_key_exists('schema', $options)) {
0149             $this->setSchema($options['schema']);
0150         }
0151     }
0152 
0153     /**
0154      * Returns the set adapter
0155      *
0156      * @throws Zend_Validate_Exception
0157      * @return Zend_Db_Adapter
0158      */
0159     public function getAdapter()
0160     {
0161         /**
0162          * Check for an adapter being defined. if not, fetch the default adapter.
0163          */
0164         if ($this->_adapter === null) {
0165             $this->_adapter = Zend_Db_Table_Abstract::getDefaultAdapter();
0166             if (null === $this->_adapter) {
0167                 // require_once 'Zend/Validate/Exception.php';
0168                 throw new Zend_Validate_Exception('No database adapter present');
0169             }
0170         }
0171         return $this->_adapter;
0172     }
0173 
0174     /**
0175      * Sets a new database adapter
0176      *
0177      * @param  Zend_Db_Adapter_Abstract $adapter
0178      * @throws Zend_Validate_Exception
0179      * @return Zend_Validate_Db_Abstract
0180      */
0181     public function setAdapter($adapter)
0182     {
0183         if (!($adapter instanceof Zend_Db_Adapter_Abstract)) {
0184             // require_once 'Zend/Validate/Exception.php';
0185             throw new Zend_Validate_Exception('Adapter option must be a database adapter!');
0186         }
0187 
0188         $this->_adapter = $adapter;
0189         return $this;
0190     }
0191 
0192     /**
0193      * Returns the set exclude clause
0194      *
0195      * @return string|array
0196      */
0197     public function getExclude()
0198     {
0199         return $this->_exclude;
0200     }
0201 
0202     /**
0203      * Sets a new exclude clause
0204      *
0205      * @param string|array $exclude
0206      * @return Zend_Validate_Db_Abstract
0207      */
0208     public function setExclude($exclude)
0209     {
0210         $this->_exclude = $exclude;
0211         return $this;
0212     }
0213 
0214     /**
0215      * Returns the set field
0216      *
0217      * @return string|array
0218      */
0219     public function getField()
0220     {
0221         return $this->_field;
0222     }
0223 
0224     /**
0225      * Sets a new field
0226      *
0227      * @param string $field
0228      * @return Zend_Validate_Db_Abstract
0229      */
0230     public function setField($field)
0231     {
0232         $this->_field = (string) $field;
0233         return $this;
0234     }
0235 
0236     /**
0237      * Returns the set table
0238      *
0239      * @return string
0240      */
0241     public function getTable()
0242     {
0243         return $this->_table;
0244     }
0245 
0246     /**
0247      * Sets a new table
0248      *
0249      * @param string $table
0250      * @return Zend_Validate_Db_Abstract
0251      */
0252     public function setTable($table)
0253     {
0254         $this->_table = (string) $table;
0255         return $this;
0256     }
0257 
0258     /**
0259      * Returns the set schema
0260      *
0261      * @return string
0262      */
0263     public function getSchema()
0264     {
0265         return $this->_schema;
0266     }
0267 
0268     /**
0269      * Sets a new schema
0270      *
0271      * @param string $schema
0272      * @return Zend_Validate_Db_Abstract
0273      */
0274     public function setSchema($schema)
0275     {
0276         $this->_schema = $schema;
0277         return $this;
0278     }
0279 
0280     /**
0281      * Sets the select object to be used by the validator
0282      *
0283      * @param Zend_Db_Select $select
0284      * @throws Zend_Validate_Exception
0285      * @return Zend_Validate_Db_Abstract
0286      */
0287     public function setSelect($select)
0288     {
0289         if (!$select instanceof Zend_Db_Select) {
0290             throw new Zend_Validate_Exception('Select option must be a valid ' .
0291                                               'Zend_Db_Select object');
0292         }
0293         $this->_select = $select;
0294         return $this;
0295     }
0296 
0297     /**
0298      * Gets the select object to be used by the validator.
0299      * If no select object was supplied to the constructor,
0300      * then it will auto-generate one from the given table,
0301      * schema, field, and adapter options.
0302      *
0303      * @return Zend_Db_Select The Select object which will be used
0304      */
0305     public function getSelect()
0306     {
0307         if (null === $this->_select) {
0308             $db = $this->getAdapter();
0309             /**
0310              * Build select object
0311              */
0312             $select = new Zend_Db_Select($db);
0313             $select->from($this->_table, array($this->_field), $this->_schema);
0314             if ($db->supportsParameters('named')) {
0315                 $select->where($db->quoteIdentifier($this->_field, true).' = :value'); // named
0316             } else {
0317                 $select->where($db->quoteIdentifier($this->_field, true).' = ?'); // positional
0318             }
0319             if ($this->_exclude !== null) {
0320                 if (is_array($this->_exclude)) {
0321                     $select->where(
0322                           $db->quoteIdentifier($this->_exclude['field'], true) .
0323                             ' != ?', $this->_exclude['value']
0324                     );
0325                 } else {
0326                     $select->where($this->_exclude);
0327                 }
0328             }
0329             $select->limit(1);
0330             $this->_select = $select;
0331         }
0332         return $this->_select;
0333     }
0334 
0335     /**
0336      * Run query and returns matches, or null if no matches are found.
0337      *
0338      * @param  String $value
0339      * @return Array when matches are found.
0340      */
0341     protected function _query($value)
0342     {
0343         $select = $this->getSelect();
0344         /**
0345          * Run query
0346          */
0347         $result = $select->getAdapter()->fetchRow(
0348             $select,
0349             array('value' => $value), // this should work whether db supports positional or named params
0350             Zend_Db::FETCH_ASSOC
0351             );
0352 
0353         return $result;
0354     }
0355 }