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

/**
 * @category   Mad
 * @package    Mad_Model
 * @subpackage Join
 * @copyright  (c) 2007-2009 Maintainable Software, LLC
 * @license    http://opensource.org/licenses/bsd-license.php BSD
 */
class Mad_Model_Join_Association extends Mad_Model_Join_Base
{
    protected $_reflection           = null;
    protected $_parent               = null;
    protected $_aliasedTableName     = null;
    protected $_aliasPrefix          = null;
    protected $_aliasedJoinTableName = null;
    protected $_parentTableName      = null;


    /*##########################################################################
    # Construct/Destruct
    ##########################################################################*/

    /**
     * Construct new Join Association.
     *
     * @param   object  $reflection
     * @param   object  $joinDependency
     * @param   object  $parent
     */
    public function __construct(Mad_Model_Association_Base $reflection, 
                                Mad_Model_Join_Dependency $joinDependency,
                                Mad_Model_Join_Base $parent)
    {
        parent::__construct($reflection->getAssocModel());

        $this->_parent           = $parent;
        $this->_reflection       = $reflection;
        $this->_aliasedPrefix    = 'T'.sizeof($joinDependency->joins());
        $this->_aliasedTableName = $this->tableName(); // start with table name
        $this->_parentTableName  = $parent->model()->tableName();

        // if the table name has been used, then use an alias
        $alias = $this->_aliasedTableName;
        if ($joinDependency->tableAlias($this->_aliasedTableName)) {
            $alias = $reflection->getAssocTable()."_$this->_parentTableName";
            $this->_aliasedTableName = $this->_model->connection->tableAliasFor($alias);

            // make sure to get a unique name. careful of name restrictions
            $alias = $this->_aliasedTableName;
            $i = $joinDependency->tableAlias($alias);
            if ($i > 0) {
                $maxLen = $this->_model->connection->tableAliasLength() - 3;
                $this->_aliasedTableName = substr($this->_aliasedTableName, 0, $maxLen)."_".($i+1);
            }

        }
        $joinDependency->addTableAlias($alias);

        // create alias for join table (only should be executed for hasAndBelongsToMany|belongsTo
        if ($this->_aliasedJoinTableName = $this->_reflection->getJoinTable()) {
            if ($joinDependency->tableAlias($this->_aliasedJoinTableName)) {
                $alias = $reflection->getAssocTable().'_'.$this->_parentTableName.'_join';
                $this->_aliasedJoinTableName = $this->_model->connection->tableAliasFor($alias);

                // make sure to get a unique name. careful of oracle name restrictions
                $i = $joinDependency->tableAlias($this->_aliasedJoinTableName);
                if ($i > 0) {
                    $maxLen = $this->_model->connection->tableAliasLength() - 3;
                    $this->_aliasedJoinTableName = substr($this->_aliasedJoinTableName, 0, $maxLen)."_".($i+1);
                }
            }
            $joinDependency->addTableAlias($this->_aliasedJoinTableName);
        }
    }

    /**
     * Stringified version of the object
     * @return  string
     */
    public function __toString()
    {
        return get_class($this->_reflection->getModel()).' : '.
               get_class($this->_reflection).' : '.
               get_class($this->_model).' '.
               $this->aliasedPrefix();
    }


    /*##########################################################################
    # Public
    ##########################################################################*/

    /**
     * @return  Mad_Model_Association_Base
     */
    public function reflection()
    {
        return $this->_reflection;
    }

    /**
     * @return  Mad_Model_Join_Base
     */
    public function parent()
    {
        return $this->_parent;
    }

    /**
     * @return  string
     */
    public function aliasedTableName()
    {
        return $this->_aliasedTableName;
    }

    /**
     * @return  string
     */
    public function aliasedPrefix()
    {
        return $this->_aliasedPrefix;
    }

    /**
     * @return  string
     */
    public function aliasedJoinTableName()
    {
        return $this->_aliasedJoinTableName;
    }

    /**
     * @return  string
     */
    public function parentTableName()
    {
        return $this->_parentTableName;
    }


    /**
     * Get the association join
     */
    public function associationJoin()
    {
        $macro = $this->reflection()->getMacro();

        // HABTM
        if ($macro == 'hasAndBelongsToMany' || $macro == 'hasManyThrough') {
            // eg. Binders hasAndBelongsToMany Documents
            // JOIN binders_documents ON binders_documents.binder_id = binders.id
            // JOIN documents ON documents.id = binders_documents.document_id
            $join =
            sprintf(" LEFT OUTER JOIN %s ON %s.%s = %s.%s ",
                $this->_tableAliasFor($this->_reflection->getJoinTable(), $this->aliasedJoinTableName()),
                $this->aliasedJoinTableName(),
                $this->reflection()->getFkName(),
                $this->reflection()->tableName(),
                $this->reflection()->getPkName()).
            sprintf(" LEFT OUTER JOIN %s ON %s.%s = %s.%s ",
                $this->_tableNameAndAlias(),
                $this->aliasedTableName(),
                $this->reflection()->getAssocPkName(),
                $this->aliasedJoinTableName(),
                $this->reflection()->getAssocFkName());

        // hasMany/hasOne
        } elseif ($macro == 'hasMany' || $macro == 'hasOne') {
            // eg. Folders hasMany Documents
            // JOIN documents ON documents.folder_id = folders.id
            $join = sprintf(" LEFT OUTER JOIN %s ON %s.%s = %s.%s ",
                $this->_tableNameAndAlias(),
                $this->aliasedTableName(),
                $this->reflection()->getFkName(),
                $this->parent()->aliasedTableName(),
                $this->reflection()->getPkName());

        // belongsTo
        } elseif ($macro == 'belongsTo') {
            // use join table.
            if ($this->reflection()->getJoinTable()) {
                // eg. BinderCollection belongsTo VisibilityGroup
                // JOIN visibility_collections
                //  ON visibility_collections.collectionid = briefcase_collections.collectionid
                // JOIN user_visibility_groups
                //  ON user_visibility_groups.visibility_groupid = visibility_collections.visibility_groupid
                $join =
                sprintf(" LEFT OUTER JOIN %s ON %s.%s = %s.%s ",
                    $this->_tableAliasFor($this->_reflection->getJoinTable(), $this->aliasedJoinTableName()),
                    $this->aliasedJoinTableName(),
                    $this->reflection()->getFkName(),
                    $this->reflection()->tableName(),
                    $this->reflection()->getPkName()).
                sprintf(" LEFT OUTER JOIN %s ON %s.%s = %s.%s ",
                    $this->_tableNameAndAlias(),
                    $this->aliasedTableName(),
                    $this->reflection()->getAssocPkName(),
                    $this->aliasedJoinTableName(),
                    $this->reflection()->getAssocFkName());


            // no join table
            } else {
                // eg. Document belongsTo Folder
                // JOIN folders ON folders.id = documents.folder_id
                $join = sprintf(" LEFT OUTER JOIN %s ON %s.%s = %s.%s ",
                    $this->_tableNameAndAlias(),
                    $this->aliasedTableName(),
                    $this->reflection()->getPkName(),
                    $this->parent()->aliasedTableName(),
                    $this->reflection()->getFkName());
            }
        }

        return isset($join) ? $join : null;
    }

    /*##########################################################################
    # Private
    ##########################################################################*/

    /**
     * Concatenate table name/alias if needed
     * @param   string  $tableName
     * @param   string  $tableAlias
     * @return  string
     */
    private function _tableAliasFor($tableName, $tableAlias)
    {
        return $tableName . ($tableName != $tableAlias ? " $tableAlias" : null);
    }

    /**
     * Generate a string with tablename/tableAlias
     * @return  string
     */
    private function _tableNameAndAlias()
    {
        return $this->_tableAliasFor($this->tableName(), $this->_aliasedTableName);
    }
}
Return current item: Maintainable PHP Framework