Location: PHPKode > projects > SolarPHP > solar-system-1.1.1/solar/source/solar/Solar/Filter/ValidateUnique.php
<?php
/**
 * 
 * Validates that a value for the current data key is unique among all
 * model records of its inheritance type; note that this validation will
 * work only when the data source is a model record.
 * 
 * @category Solar
 * 
 * @package Solar_Filter
 * 
 * @author Paul M. Jones <hide@address.com>
 * 
 * @license http://opensource.org/licenses/bsd-license.php BSD
 * 
 * @version $Id: ValidateUnique.php 4389 2010-02-14 20:10:24Z pmjones $
 * 
 */
class Solar_Filter_ValidateUnique extends Solar_Filter_Abstract
{
    /**
     * 
     * Validates that a value for the current data key is unique among all
     * model records of its inheritance type.
     * 
     * This will exclude any record having the same primary-key value as the
     * current record.
     * 
     * N.b.: If you are attempting to validate the primary column as unique,
     * you *have* to pass an additional $where condition on another unique
     * column. This is so the record being validated can recognize "itself"
     * in the database.  For example ...
     * 
     * {{code: php
     *     // validate 'foo' as unique when 'foo' is the primary column.
     *     // we need to make sure the record recognizes itself by some
     *     // other unique column value, 'bar'.  this is from inside a
     *     // Solar_Sql_Model::_setup() method.
     *     $where = array("bar != :bar AND bar IS NOT NULL")
     *     $this->_addFilter('foo', 'validateUnique', $where);
     * }}
     * 
     * ... but really, you should be using an artificial key (e.g. integer id
     * autoincremented) as your primary, not a natural key.  It makes this
     * *so* much easier.
     * 
     * @param mixed $value The value to validate.
     * 
     * @param mixed $where Additional "WHERE" conditions to exclude records
     * from the uniqueness check.
     * 
     * @return bool True if unique, false if not.
     * 
     */
    public function validateUnique($value, $where = null)
    {
        // is the data source a record?
        $record = $this->_filter->getData();
        if (! $record instanceof Solar_Sql_Model_Record) {
            throw $this->_exception('ERR_NOT_MODEL_RECORD');
        }
        
        // make sure the $where is an array
        settype($where, 'array');
        
        // get the record (data) model
        $model = $record->getModel();
        
        // the column we're validating as unique. what we do is select the
        // current value from the database, and if it's there, that means
        // the current value is not unique.  we'll add exclusion conditions
        // below.
        $col = $this->_filter->getDataKey();
        $where[] = "$col = :$col";
        
        // what is the primary-key column for the record model?
        $primary = $model->primary_col;
        
        // only add a primary key exclusion if the column being validated
        // is not itself the primary key.
        if ($col != $primary) {
            // exclude the current record by its primary key value.
            if ($record[$primary] === null) {
                $where[] = "$primary IS NOT NULL";
            } else {
                $where[] = "$primary != :$primary";
            }
        }
        
        // see if we can fetch a row, with only the primary-key column to
        // reduce resource usage.
        $result = $model->fetchValue(array(
            'where' => $where,
            'cols'  => array($primary),
            'bind'  => $record->toArray(),
        ));
        
        // if empty, no result was returned, so the value is unique.
        return empty($result);
    }
}
Return current item: SolarPHP