Location: PHPKode > projects > Maintainable PHP Framework > vendor/Mad/Model/Association/HasOne.php
<?php
/**
 * @category   Mad
 * @package    Mad_Model
 * @subpackage Association
 * @copyright  (c) 2007-2009 Maintainable Software, LLC
 * @license    http://opensource.org/licenses/bsd-license.php BSD
 */

/**
 * An association between model objects
 * 
 * @category   Mad
 * @package    Mad_Model
 * @subpackage Association
 * @copyright  (c) 2007-2009 Maintainable Software, LLC
 * @license    http://opensource.org/licenses/bsd-license.php BSD
 */
class Mad_Model_Association_HasOne extends Mad_Model_Association_Proxy
{
    /*##########################################################################
    # Construct/Destruct
    ##########################################################################*/

    /**
     * Construct association object
     * 
     * @param   string  $assocName
     * @param   array   $options
     * @param   object  $model
     */
    public function __construct($assocName, $options, Mad_Model_Base $model)
    {
        $valid = array('className', 'foreignKey', 'primaryKey', 'include',  
                       'order', 'dependent' => 'nullify');
        $this->_options = Mad_Support_Base::assertValidKeys($options, $valid);
        $this->_assocName = $assocName;
        $this->_model     = $model;
        $this->_conn      = $model->connection();

        // get inflections
        $toMethod = Mad_Support_Inflector::camelize($this->_assocName, 'lower');
        $toMethod = str_replace('/', '_', $toMethod);
        $toClass  = ucfirst($toMethod);

        $this->_methods = array(
            $toMethod         => 'getObject',   // folder
            $toMethod.'='     => 'setObject',   // folder=
            'build'.$toClass  => 'buildObject', // buildFolder
            'create'.$toClass => 'createObject' // createFolder
        );
    }


    /*##########################################################################
    # Instance Methods
    ##########################################################################*/

    /**
     * Save changes to association. This will only save the object's changes if it
     * has been loaded up from the database and was changed
     */
    public function save()
    {
        if ($this->isLoaded()) {
            if ($this->_deleteModel) { $this->destroyDependent(); }

            $baseModel  = $this->getModel();
            $assocModel = $this->getObject();
            $fkName     = $this->getFkName();
            $pkName     = $this->getPkName();

            // set foreign key on associated model before saving
            $assocModel->writeAttribute($fkName, $baseModel->$pkName);
            $assocModel->save();
        }
    }

    /**
     * Destroy all objects that are dependent on the base object based on their
     * dependency options. This only applies to hasOne/hasMany/HABTM associations.
     */
    public function destroyDependent()
    {
        // no need to destroy dependent if base model is new
        if ($this->getModel()->isNewRecord()) return;

        $fkName = $this->getFkName();
        $value  = $this->getPkValue();
        // we assign a model for deletion when assigning a new object
        if (!empty($this->_deleteModel)) {
            $assocModel = $this->_deleteModel;
        } else {
            $assocModel = $this->getObject();
        }
        if (!$assocModel) return;

        // delete associated records
        if ($this->_options['dependent'] == 'destroy') {
            $assocModel->destroy();

        // (default) nullify associated records 
        } elseif ($this->_options['dependent'] == 'nullify') {
            $assocModel->updateAll("$fkName = NULL", "$fkName = :val", 
                                   array(':val' => $value));
        // invalid dependency
        } else {
            $assoc = $this->getClass().' hasOne '.$this->getAssocClass();
            $msg = 'Invalid setting for $assoc association "dependent" option';
            throw new Mad_Model_Association_Exception($msg);
        }
    }

    /**
     * return associated object
     *
     * @param   array   $args
     * @return  object
     */
    public function getObject($args=array())
    {
        if (!isset($this->_loaded['getObject'])) {
            $table   = $this->getAssocTable();
            $pkValue = $this->getPkValue();
            $fkName  = $this->getFkName();
            
            $order = $this->_constructOrder();

            // query for associated object
            $options = array('conditions' => "$table.$fkName = :value", 
                             'order'      => $order);
            if (!empty($this->_options['include'])) {
              $options['include'] = $this->_options['include'];
            }
            $bind = array(':value' => $pkValue);

            // load associated object
            if (!empty($pkValue)) {
                $object = $this->getAssocModel()->find('first', $options, $bind);
                $this->_loaded['getObject'] = $object;
            } else {
                $this->_loaded['getObject'] = null;
            }
        }
        return $this->_loaded['getObject'];
    }

    /**
     * @param   string  $order
     */
    protected function _constructOrder($order=null)
    {
        $orderStr =  null;
        if (isset($this->_options['order']) && empty($order)) {
            $orderStr = $this->_options['order'];

        } elseif ($order) {
            $orderStr = $order;
        }
        return $orderStr;
    }
}
Return current item: Maintainable PHP Framework