<?php

/**
 * This file is part of the Propel package.
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @license    MIT License
 */

require_once dirname(__FILE__) . '/OMBuilder.php';

/**
 * Generates a PHP5 base Query class for user object model (OM).
 *
 * This class produces the base query class (e.g. BaseBookQuery) which contains all
 * the custom-built query methods.
 *
 * @author     Francois Zaninotto
 * @package    propel.generator.builder.om
 */
class QueryBuilder extends OMBuilder
{

    /**
     * Gets the package for the [base] object classes.
     *
     * @return string
     */
    public function getPackage()
    {
        return parent::getPackage() . ".om";
    }

    public function getNamespace()
    {
        if ($namespace = parent::getNamespace()) {
            if ($this->getGeneratorConfig() && $omns = $this->getGeneratorConfig()->getBuildProperty('namespaceOm')) {
                return $namespace . '\\' . $omns;
            } else {
                return $namespace;
            }
        }
    }

    /**
     * Returns the name of the current class being built.
     *
     * @return string
     */
    public function getUnprefixedClassname()
    {
        return $this->getBuildProperty('basePrefix') . $this->getStubQueryBuilder()->getUnprefixedClassname();
    }

    /**
     * Adds the include() statements for files that this class depends on or utilizes.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addIncludes(&$script)
    {
    }

    /**
     * Adds class phpdoc comment and opening of class.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addClassOpen(&$script)
    {
        $table = $this->getTable();
        $tableName = $table->getName();
        $tableDesc = $table->getDescription();
        $queryClass = $this->getStubQueryBuilder()->getClassname();
        $modelClass = $this->getStubObjectBuilder()->getClassname();
        $parentClass = $this->getBehaviorContent('parentClass');
        $parentClass = null === $parentClass ? 'ModelCriteria' : $parentClass;

        if ($this->getBuildProperty('addClassLevelComment')) {
            $script .= "
/**
 * Base class that represents a query for the '$tableName' table.
 *
 * $tableDesc
 *";
            if ($this->getBuildProperty('addTimeStamp')) {
                $now = strftime('%c');
                $script .= "
 * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
 *
 * $now
 *";
            }
        } else {
            $script .= "
/**";
        }

        // magic orderBy() methods, for IDE completion
        foreach ($this->getTable()->getColumns() as $column) {
            $script .= "
 * @method $queryClass orderBy" . $column->getPhpName() . "(\$order = Criteria::ASC) Order by the " . $column->getName() . " column";
        }
        $script .= "
 *";

        // magic groupBy() methods, for IDE completion
        foreach ($this->getTable()->getColumns() as $column) {
            $script .= "
 * @method $queryClass groupBy" . $column->getPhpName() . "() Group by the " . $column->getName() . " column";
        }

        // override the signature of ModelCriteria::left-, right- and innerJoin to specify the class of the returned object, for IDE completion
        $script .= "
 *
 * @method $queryClass leftJoin(\$relation) Adds a LEFT JOIN clause to the query
 * @method $queryClass rightJoin(\$relation) Adds a RIGHT JOIN clause to the query
 * @method $queryClass innerJoin(\$relation) Adds a INNER JOIN clause to the query
 *";

        // magic XXXjoinYYY() methods, for IDE completion
        foreach ($this->getTable()->getForeignKeys() as $fk) {
            $relationName = $this->getFKPhpNameAffix($fk);

            $script .= "
 * @method $queryClass leftJoin" . $relationName . "(\$relationAlias = null) Adds a LEFT JOIN clause to the query using the " . $relationName . " relation
 * @method $queryClass rightJoin" . $relationName . "(\$relationAlias = null) Adds a RIGHT JOIN clause to the query using the " . $relationName . " relation
 * @method $queryClass innerJoin" . $relationName . "(\$relationAlias = null) Adds a INNER JOIN clause to the query using the " . $relationName . " relation
 *";
        }
        foreach ($this->getTable()->getReferrers() as $refFK) {
            $relationName = $this->getRefFKPhpNameAffix($refFK);

            $script .= "
 * @method $queryClass leftJoin" . $relationName . "(\$relationAlias = null) Adds a LEFT JOIN clause to the query using the " . $relationName . " relation
 * @method $queryClass rightJoin" . $relationName . "(\$relationAlias = null) Adds a RIGHT JOIN clause to the query using the " . $relationName . " relation
 * @method $queryClass innerJoin" . $relationName . "(\$relationAlias = null) Adds a INNER JOIN clause to the query using the " . $relationName . " relation
 *";
        }

        // override the signature of ModelCriteria::findOne() to specify the class of the returned object, for IDE completion
        $script .= "
 * @method $modelClass findOne(PropelPDO \$con = null) Return the first $modelClass matching the query
 * @method $modelClass findOneOrCreate(PropelPDO \$con = null) Return the first $modelClass matching the query, or a new $modelClass object populated from the query conditions when no match is found
 *";

        // magic findBy() methods, for IDE completion
        foreach ($this->getTable()->getColumns() as $column) {
            // skip "findPk" alias method
            if (!$this->getTable()->hasCompositePrimaryKey() && $column->isPrimaryKey()) {
                continue;
            }

            $script .= "
 * @method $modelClass findOneBy" . $column->getPhpName() . "(" . $column->getPhpType() . " \$" . $column->getName() . ") Return the first $modelClass filtered by the " . $column->getName() . " column";
        }
        $script .= "
 *";
        foreach ($this->getTable()->getColumns() as $column) {
            $script .= "
 * @method array findBy" . $column->getPhpName() . "(" . $column->getPhpType() . " \$" . $column->getName() . ") Return $modelClass objects filtered by the " . $column->getName() . " column";
        }

        if ($this->getBuildProperty('addClassLevelComment')) {
            $script .= "
 *
 * @package    propel.generator." . $this->getPackage();
        }

        $script .= "
 */
abstract class " . $this->getClassname() . " extends " . $parentClass . "
{";
    }

    /**
     * Specifies the methods that are added as part of the stub object class.
     *
     * By default there are no methods for the empty stub classes; override this method
     * if you want to change that behavior.
     *
     * @see        ObjectBuilder::addClassBody()
     */
    protected function addClassBody(&$script)
    {
        // namespaces
        $this->declareClasses('ModelCriteria', 'Criteria', 'ModelJoin', 'Exception');
        $this->declareClassFromBuilder($this->getStubQueryBuilder());
        $this->declareClassFromBuilder($this->getStubPeerBuilder());

        // apply behaviors
        $this->applyBehaviorModifier('queryAttributes', $script, "	");
        $this->addConstructor($script);
        $this->addFactory($script);
        $this->addFindPk($script);
        $this->addFindOneByPk($script);
        $this->addFindPkSimple($script);
        $this->addFindPkComplex($script);
        $this->addFindPks($script);
        $this->addFilterByPrimaryKey($script);
        $this->addFilterByPrimaryKeys($script);
        foreach ($this->getTable()->getColumns() as $col) {
            $this->addFilterByCol($script, $col);
            if ($col->getType() === PropelTypes::PHP_ARRAY && $col->isNamePlural()) {
                $this->addFilterByArrayCol($script, $col);
            }
        }
        foreach ($this->getTable()->getForeignKeys() as $fk) {
            $this->addFilterByFK($script, $fk);
            $this->addJoinFk($script, $fk);
            $this->addUseFKQuery($script, $fk);
        }
        foreach ($this->getTable()->getReferrers() as $refFK) {
            $this->addFilterByRefFK($script, $refFK);
            $this->addJoinRefFk($script, $refFK);
            $this->addUseRefFKQuery($script, $refFK);
        }
        foreach ($this->getTable()->getCrossFks() as $fkList) {
            list($refFK, $crossFK) = $fkList;
            $this->addFilterByCrossFK($script, $refFK, $crossFK);
        }
        $this->addPrune($script);
        $this->addBasePreSelect($script);
        $this->addBasePreDelete($script);
        $this->addBasePostDelete($script);
        $this->addBasePreUpdate($script);
        $this->addBasePostUpdate($script);
        // apply behaviors
        $this->applyBehaviorModifier('queryMethods', $script, "	");
    }

    /**
     * Closes class.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addClassClose(&$script)
    {
        $script .= "
}
";
        $this->applyBehaviorModifier('queryFilter', $script, "");
    }

    /**
     * Adds the constructor for this object.
     *
     * @param string &$script The script will be modified in this method.
     *
     * @see        addConstructor()
     */
    protected function addConstructor(&$script)
    {
        $this->addConstructorComment($script);
        $this->addConstructorOpen($script);
        $this->addConstructorBody($script);
        $this->addConstructorClose($script);
    }

    /**
     * Adds the comment for the constructor
     *
     * @param string &$script The script will be modified in this method.
     **/
    protected function addConstructorComment(&$script)
    {
        $script .= "
    /**
     * Initializes internal state of " . $this->getClassname() . " object.
     *
     * @param     string \$dbName The dabase name
     * @param     string \$modelName The phpName of a model, e.g. 'Book'
     * @param     string \$modelAlias The alias for the model in this query, e.g. 'b'
     */";
    }

    /**
     * Adds the function declaration for the constructor
     *
     * @param string &$script The script will be modified in this method.
     **/
    protected function addConstructorOpen(&$script)
    {
        $script .= "
    public function __construct(\$dbName = null, \$modelName = null, \$modelAlias = null)
    {";
    }

    /**
     * Adds the function body for the constructor
     *
     * @param string &$script The script will be modified in this method.
     **/
    protected function addConstructorBody(&$script)
    {
        $table = $this->getTable();
        $script .= "
        if (null === \$dbName) {
            \$dbName = '" . $table->getDatabase()->getName() . "';
        }
        if (null === \$modelName) {
            \$modelName = '" . addslashes($this->getNewStubObjectBuilder($table)->getFullyQualifiedClassname()) . "';
        }
        parent::__construct(\$dbName, \$modelName, \$modelAlias);";
    }

    /**
     * Adds the function close for the constructor
     *
     * @param string &$script The script will be modified in this method.
     **/
    protected function addConstructorClose(&$script)
    {
        $script .= "
    }
";
    }

    /**
     * Adds the factory for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addFactory(&$script)
    {
        $this->addFactoryComment($script);
        $this->addFactoryOpen($script);
        $this->addFactoryBody($script);
        $this->addFactoryClose($script);
    }

    /**
     * Adds the comment for the factory
     *
     * @param string &$script The script will be modified in this method.
     **/
    protected function addFactoryComment(&$script)
    {
        $classname = $this->getNewStubQueryBuilder($this->getTable())->getClassname();
        $script .= "
    /**
     * Returns a new " . $classname . " object.
     *
     * @param     string \$modelAlias The alias of a model in the query
     * @param   $classname|Criteria \$criteria Optional Criteria to build the query from
     *
     * @return " . $classname . "
     */";
    }

    /**
     * Adds the function declaration for the factory
     *
     * @param string &$script The script will be modified in this method.
     **/
    protected function addFactoryOpen(&$script)
    {
        $script .= "
    public static function create(\$modelAlias = null, \$criteria = null)
    {";
    }

    /**
     * Adds the function body for the factory
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addFactoryBody(&$script)
    {
        $classname = $this->getNewStubQueryBuilder($this->getTable())->getClassname();
        $script .= "
        if (\$criteria instanceof " . $classname . ") {
            return \$criteria;
        }
        \$query = new " . $classname . "(null, null, \$modelAlias);

        if (\$criteria instanceof Criteria) {
            \$query->mergeWith(\$criteria);
        }

        return \$query;";
    }

    /**
     * Adds the function close for the factory
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addFactoryClose(&$script)
    {
        $script .= "
    }
";
    }

    protected function addFindPk(&$script)
    {
        $pkDescription = '';
        $class = $this->getObjectClassname();
        $peerClassname = $this->getPeerClassname();
        $table = $this->getTable();
        $script .= "
    /**
     * Find object by primary key.
     * Propel uses the instance pool to skip the database if the object exists.
     * Go fast if the query is untouched.
     *";
        if ($table->hasCompositePrimaryKey()) {
            $pks = $table->getPrimaryKey();
            $examplePk = array_slice(array(12, 34, 56, 78, 91), 0, count($pks));
            $colNames = array();
            foreach ($pks as $col) {
                $colNames[] = '$' . $col->getName();
            }
            $pkType = 'array';
            $pkDescription = "
                         A Primary key composition: " . '[' . join($colNames, ', ') . ']';
            $script .= "
     * <code>
     * \$obj = \$c->findPk(array(" . join($examplePk, ', ') . "), \$con);";
        } else {
            $pkType = 'mixed';
            $script .= "
     * <code>
     * \$obj  = \$c->findPk(12, \$con);";
        }
        $script .= "
     * </code>
     *
     * @param " . $pkType . " \$key Primary key to use for the query $pkDescription
     * @param     PropelPDO \$con an optional connection object
     *
     * @return   $class|{$class}[]|mixed the result, formatted by the current formatter
     */
    public function findPk(\$key, \$con = null)
    {
        if (\$key === null) {
            return null;
        }";
        if ($table->hasCompositePrimaryKey()) {
            $pks = array();
            foreach ($table->getPrimaryKey() as $index => $column) {
                $pks [] = "\$key[$index]";
            }
        } else {
            $pks = '$key';
        }
        $pkHash = $this->getPeerBuilder()->getInstancePoolKeySnippet($pks);
        $script .= "
        if ((null !== (\$obj = {$peerClassname}::getInstanceFromPool({$pkHash}))) && !\$this->formatter) {
            // the object is already in the instance pool
            return \$obj;
        }
        if (\$con === null) {
            \$con = Propel::getConnection({$peerClassname}::DATABASE_NAME, Propel::CONNECTION_READ);
        }
        \$this->basePreSelect(\$con);
        if (\$this->formatter || \$this->modelAlias || \$this->with || \$this->select
         || \$this->selectColumns || \$this->asColumns || \$this->selectModifiers
         || \$this->map || \$this->having || \$this->joins) {
            return \$this->findPkComplex(\$key, \$con);
        } else {
            return \$this->findPkSimple(\$key, \$con);
        }
    }
";
    }

    protected function addFindOneByPk(&$script)
    {
        $table = $this->getTable();
        if ($table->hasCompositePrimaryKey()) {
            return;
        }

        $pk = $table->getPrimaryKey();
        $column = $pk[0]->getPhpName();
        $ARClassname = $this->getObjectClassname();

        $script .= "
    /**
     * Alias of findPk to use instance pooling
     *
     * @param     mixed \$key Primary key to use for the query
     * @param     PropelPDO \$con A connection object
     *
     * @return                 $ARClassname A model object, or null if the key is not found
     * @throws PropelException
     */
     public function findOneBy{$column}(\$key, \$con = null)
     {
        return \$this->findPk(\$key, \$con);
     }
";
    }

    protected function addFindPkSimple(&$script)
    {
        $table = $this->getTable();
        $platform = $this->getPlatform();
        $peerClassname = $this->getPeerClassname();
        $ARClassname = $this->getObjectClassname();
        $this->declareClassFromBuilder($this->getStubObjectBuilder());
        $this->declareClasses('PDO', 'PropelException', 'PropelObjectCollection');
        $selectColumns = array();
        foreach ($table->getColumns() as $column) {
            if (!$column->isLazyLoad()) {
                $selectColumns [] = $platform->quoteIdentifier($column->getName());
            }
        }
        $conditions = array();
        foreach ($table->getPrimaryKey() as $index => $column) {
            $conditions [] = sprintf('%s = :p%d', $platform->quoteIdentifier($column->getName()), $index);
        }
        $query = sprintf('SELECT %s FROM %s WHERE %s', implode(', ', $selectColumns), $platform->quoteIdentifier($table->getName()), implode(' AND ', $conditions));
        $pks = array();
        if ($table->hasCompositePrimaryKey()) {
            foreach ($table->getPrimaryKey() as $index => $column) {
                $pks [] = "\$key[$index]";
            }
        } else {
            $pks [] = "\$key";
        }
        $pkHashFromRow = $this->getPeerBuilder()->getInstancePoolKeySnippet($pks);
        $script .= "
    /**
     * Find object by primary key using raw SQL to go fast.
     * Bypass doSelect() and the object formatter by using generated code.
     *
     * @param     mixed \$key Primary key to use for the query
     * @param     PropelPDO \$con A connection object
     *
     * @return                 $ARClassname A model object, or null if the key is not found
     * @throws PropelException
     */
    protected function findPkSimple(\$key, \$con)
    {
        \$sql = '$query';
        try {
            \$stmt = \$con->prepare(\$sql);";
        if ($table->hasCompositePrimaryKey()) {
            foreach ($table->getPrimaryKey() as $index => $column) {
                $script .= $platform->getColumnBindingPHP($column, "':p$index'", "\$key[$index]", '			');
            }
        } else {
            $pk = $table->getPrimaryKey();
            $column = $pk[0];
            $script .= $platform->getColumnBindingPHP($column, "':p0'", "\$key", '			');
        }
        $script .= "
            \$stmt->execute();
        } catch (Exception \$e) {
            Propel::log(\$e->getMessage(), Propel::LOG_ERR);
            throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', \$sql), \$e);
        }
        \$obj = null;
        if (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {";

        if ($col = $table->getChildrenColumn()) {
            $script .= "
            \$cls = {$peerClassname}::getOMClass(\$row, 0);
            \$obj = new \$cls();";
        } else {
            $script .= "
            \$obj = new $ARClassname();";
        }
        $script .= "
            \$obj->hydrate(\$row);
            {$peerClassname}::addInstanceToPool(\$obj, $pkHashFromRow);
        }
        \$stmt->closeCursor();

        return \$obj;
    }
";
    }

    /**
     * Adds the findPk method for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addFindPkComplex(&$script)
    {
        $table = $this->getTable();
        $pks = $table->getPrimaryKey();
        $class = $this->getStubObjectBuilder()->getClassname();
        $this->declareClasses('PropelPDO');
        $script .= "
    /**
     * Find object by primary key.
     *
     * @param     mixed \$key Primary key to use for the query
     * @param     PropelPDO \$con A connection object
     *
     * @return " . $class . "|{$class}[]|mixed the result, formatted by the current formatter
     */
    protected function findPkComplex(\$key, \$con)
    {
        // As the query uses a PK condition, no limit(1) is necessary.
        \$criteria = \$this->isKeepQuery() ? clone \$this : \$this;
        \$stmt = \$criteria
            ->filterByPrimaryKey(\$key)
            ->doSelect(\$con);

        return \$criteria->getFormatter()->init(\$criteria)->formatOne(\$stmt);
    }
";
    }

    /**
     * Adds the findPks method for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addFindPks(&$script)
    {
        $this->declareClasses('PropelPDO', 'Propel');
        $table = $this->getTable();
        $pks = $table->getPrimaryKey();
        $count = count($pks);
        $class = $this->getStubObjectBuilder()->getClassname();
        $script .= "
    /**
     * Find objects by primary key
     * <code>";
        if ($count === 1) {
            $script .= "
     * \$objs = \$c->findPks(array(12, 56, 832), \$con);";
        } else {
            $script .= "
     * \$objs = \$c->findPks(array(array(12, 56), array(832, 123), array(123, 456)), \$con);";
        }
        $script .= "
     * </code>
     * @param     array \$keys Primary keys to use for the query
     * @param     PropelPDO \$con an optional connection object
     *
     * @return PropelObjectCollection|{$class}[]|mixed the list of results, formatted by the current formatter
     */
    public function findPks(\$keys, \$con = null)
    {
        if (\$con === null) {
            \$con = Propel::getConnection(\$this->getDbName(), Propel::CONNECTION_READ);
        }
        \$this->basePreSelect(\$con);
        \$criteria = \$this->isKeepQuery() ? clone \$this : \$this;
        \$stmt = \$criteria
            ->filterByPrimaryKeys(\$keys)
            ->doSelect(\$con);

        return \$criteria->getFormatter()->init(\$criteria)->format(\$stmt);
    }
";
    }

    /**
     * Adds the filterByPrimaryKey method for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addFilterByPrimaryKey(&$script)
    {
        $script .= "
    /**
     * Filter the query by primary key
     *
     * @param     mixed \$key Primary key to use for the query
     *
     * @return " . $this->getStubQueryBuilder()->getClassname() . " The current query, for fluid interface
     */
    public function filterByPrimaryKey(\$key)
    {";
        $table = $this->getTable();
        $pks = $table->getPrimaryKey();
        if (count($pks) === 1) {
            // simple primary key
            $col = $pks[0];
            $const = $this->getColumnConstant($col);
            $script .= "

        return \$this->addUsingAlias($const, \$key, Criteria::EQUAL);";
        } else {
            // composite primary key
            $i = 0;
            foreach ($pks as $col) {
                $const = $this->getColumnConstant($col);
                $script .= "
        \$this->addUsingAlias($const, \$key[$i], Criteria::EQUAL);";
                $i++;
            }
            $script .= "

        return \$this;";
        }
        $script .= "
    }
";
    }

    /**
     * Adds the filterByPrimaryKey method for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addFilterByPrimaryKeys(&$script)
    {
        $script .= "
    /**
     * Filter the query by a list of primary keys
     *
     * @param     array \$keys The list of primary key to use for the query
     *
     * @return " . $this->getStubQueryBuilder()->getClassname() . " The current query, for fluid interface
     */
    public function filterByPrimaryKeys(\$keys)
    {";
        $table = $this->getTable();
        $pks = $table->getPrimaryKey();
        if (count($pks) === 1) {
            // simple primary key
            $col = $pks[0];
            $const = $this->getColumnConstant($col);
            $script .= "

        return \$this->addUsingAlias($const, \$keys, Criteria::IN);";
        } else {
            // composite primary key
            $script .= "
        if (empty(\$keys)) {
            return \$this->add(null, '1<>1', Criteria::CUSTOM);
        }
        foreach (\$keys as \$key) {";
            $i = 0;
            foreach ($pks as $col) {
                $const = $this->getColumnConstant($col);
                $script .= "
            \$cton$i = \$this->getNewCriterion($const, \$key[$i], Criteria::EQUAL);";
                if ($i > 0) {
                    $script .= "
            \$cton0->addAnd(\$cton$i);";
                }
                $i++;
            }
            $script .= "
            \$this->addOr(\$cton0);
        }";
            $script .= "

        return \$this;";
        }
        $script .= "
    }
";
    }

    /**
     * Adds the filterByCol method for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addFilterByCol(&$script, $col)
    {
        $colPhpName = $col->getPhpName();
        $colName = $col->getName();
        $variableName = $col->getStudlyPhpName();
        $qualifiedName = $this->getColumnConstant($col);
        $script .= "
    /**
     * Filter the query on the $colName column
     *";
        if ($col->isNumericType()) {
            $script .= "
     * Example usage:
     * <code>
     * \$query->filterBy$colPhpName(1234); // WHERE $colName = 1234
     * \$query->filterBy$colPhpName(array(12, 34)); // WHERE $colName IN (12, 34)
     * \$query->filterBy$colPhpName(array('min' => 12)); // WHERE $colName >= 12
     * \$query->filterBy$colPhpName(array('max' => 12)); // WHERE $colName <= 12
     * </code>";
            if ($col->isForeignKey()) {
                foreach ($col->getForeignKeys() as $fk) {
                    $script .= "
     *
     * @see       filterBy" . $this->getFKPhpNameAffix($fk) . "()";
                }
            }
            $script .= "
     *
     * @param     mixed \$$variableName The value to use as filter.
     *              Use scalar values for equality.
     *              Use array values for in_array() equivalent.
     *              Use associative array('min' => \$minValue, 'max' => \$maxValue) for intervals.";
        } elseif ($col->isTemporalType()) {
            $script .= "
     * Example usage:
     * <code>
     * \$query->filterBy$colPhpName('2011-03-14'); // WHERE $colName = '2011-03-14'
     * \$query->filterBy$colPhpName('now'); // WHERE $colName = '2011-03-14'
     * \$query->filterBy$colPhpName(array('max' => 'yesterday')); // WHERE $colName < '2011-03-13'
     * </code>
     *
     * @param     mixed \$$variableName The value to use as filter.
     *              Values can be integers (unix timestamps), DateTime objects, or strings.
     *              Empty strings are treated as NULL.
     *              Use scalar values for equality.
     *              Use array values for in_array() equivalent.
     *              Use associative array('min' => \$minValue, 'max' => \$maxValue) for intervals.";
        } elseif ($col->getType() == PropelTypes::PHP_ARRAY) {
            $script .= "
     * @param     array \$$variableName The values to use as filter.";
        } elseif ($col->isTextType()) {
            $script .= "
     * Example usage:
     * <code>
     * \$query->filterBy$colPhpName('fooValue');   // WHERE $colName = 'fooValue'
     * \$query->filterBy$colPhpName('%fooValue%'); // WHERE $colName LIKE '%fooValue%'
     * </code>
     *
     * @param     string \$$variableName The value to use as filter.
     *              Accepts wildcards (* and % trigger a LIKE)";
        } elseif ($col->isBooleanType()) {
            $script .= "
     * Example usage:
     * <code>
     * \$query->filterBy$colPhpName(true); // WHERE $colName = true
     * \$query->filterBy$colPhpName('yes'); // WHERE $colName = true
     * </code>
     *
     * @param     boolean|string \$$variableName The value to use as filter.
     *              Non-boolean arguments are converted using the following rules:
     *                * 1, '1', 'true',  'on',  and 'yes' are converted to boolean true
     *                * 0, '0', 'false', 'off', and 'no'  are converted to boolean false
     *              Check on string values is case insensitive (so 'FaLsE' is seen as 'false').";
        } else {
            $script .= "
     * @param     mixed \$$variableName The value to use as filter";
        }
        $script .= "
     * @param     string \$comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
     *
     * @return " . $this->getStubQueryBuilder()->getClassname() . " The current query, for fluid interface";

        if ($col->getType() == PropelTypes::ENUM) {
            $script .= "
     * @throws PropelException - if the value is not accepted by the enum.";
        }

        $script .= "
     */
    public function filterBy$colPhpName(\$$variableName = null, \$comparison = null)
    {";
        if ($col->isNumericType() || $col->isTemporalType()) {
            $script .= "
        if (is_array(\$$variableName)) {
            \$useMinMax = false;
            if (isset(\${$variableName}['min'])) {
                \$this->addUsingAlias($qualifiedName, \${$variableName}['min'], Criteria::GREATER_EQUAL);
                \$useMinMax = true;
            }
            if (isset(\${$variableName}['max'])) {
                \$this->addUsingAlias($qualifiedName, \${$variableName}['max'], Criteria::LESS_EQUAL);
                \$useMinMax = true;
            }
            if (\$useMinMax) {
                return \$this;
            }
            if (null === \$comparison) {
                \$comparison = Criteria::IN;
            }
        }";
        } elseif ($col->getType() == PropelTypes::OBJECT) {
            $script .= "
        if (is_object(\$$variableName)) {
            \$$variableName = serialize(\$$variableName);
        }";
        } elseif ($col->getType() == PropelTypes::PHP_ARRAY) {
            $script .= "
        \$key = \$this->getAliasedColName($qualifiedName);
        if (null === \$comparison || \$comparison == Criteria::CONTAINS_ALL) {
            foreach (\$$variableName as \$value) {
                \$value = '%| ' . \$value . ' |%';
                if (\$this->containsKey(\$key)) {
                    \$this->addAnd(\$key, \$value, Criteria::LIKE);
                } else {
                    \$this->add(\$key, \$value, Criteria::LIKE);
                }
            }

            return \$this;
        } elseif (\$comparison == Criteria::CONTAINS_SOME) {
            foreach (\$$variableName as \$value) {
                \$value = '%| ' . \$value . ' |%';
                if (\$this->containsKey(\$key)) {
                    \$this->addOr(\$key, \$value, Criteria::LIKE);
                } else {
                    \$this->add(\$key, \$value, Criteria::LIKE);
                }
            }

            return \$this;
        } elseif (\$comparison == Criteria::CONTAINS_NONE) {
            foreach (\$$variableName as \$value) {
                \$value = '%| ' . \$value . ' |%';
                if (\$this->containsKey(\$key)) {
                    \$this->addAnd(\$key, \$value, Criteria::NOT_LIKE);
                } else {
                    \$this->add(\$key, \$value, Criteria::NOT_LIKE);
                }
            }
            \$this->addOr(\$key, null, Criteria::ISNULL);

            return \$this;
        }";
        } elseif ($col->getType() == PropelTypes::ENUM) {
            $script .= "
        if (is_scalar(\$$variableName)) {
            \$$variableName = {$this->getPeerClassname()}::getSqlValueForEnum({$this->getColumnConstant($col)}, \$$variableName);
        } elseif (is_array(\$$variableName)) {
            \$convertedValues = array();
            foreach (\$$variableName as \$value) {
                \$convertedValues[] = {$this->getPeerClassname()}::getSqlValueForEnum({$this->getColumnConstant($col)}, \$value);
            }
            \$$variableName = \$convertedValues;
            if (null === \$comparison) {
                \$comparison = Criteria::IN;
            }
        }";
        } elseif ($col->isTextType()) {
            $script .= "
        if (null === \$comparison) {
            if (is_array(\$$variableName)) {
                \$comparison = Criteria::IN;
            } elseif (preg_match('/[\%\*]/', \$$variableName)) {
                \$$variableName = str_replace('*', '%', \$$variableName);
                \$comparison = Criteria::LIKE;
            }
        }";
        } elseif ($col->isBooleanType()) {
            $script .= "
        if (is_string(\$$variableName)) {
            \$$variableName = in_array(strtolower(\$$variableName), array('false', 'off', '-', 'no', 'n', '0', '')) ? false : true;
        }";
        }
        $script .= "

        return \$this->addUsingAlias($qualifiedName, \$$variableName, \$comparison);
    }
";
    }

    /**
     * Adds the singular filterByCol method for an Array column.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addFilterByArrayCol(&$script, $col)
    {
        $colPhpName = $col->getPhpName();
        $singularPhpName = rtrim($colPhpName, 's');
        $colName = $col->getName();
        $variableName = $col->getStudlyPhpName();
        $qualifiedName = $this->getColumnConstant($col);
        $script .= "
    /**
     * Filter the query on the $colName column
     * @param     mixed \$$variableName The value to use as filter
     * @param     string \$comparison Operator to use for the column comparison, defaults to Criteria::CONTAINS_ALL
     *
     * @return " . $this->getStubQueryBuilder()->getClassname() . " The current query, for fluid interface
     */
    public function filterBy$singularPhpName(\$$variableName = null, \$comparison = null)
    {
        if (null === \$comparison || \$comparison == Criteria::CONTAINS_ALL) {
            if (is_scalar(\$$variableName)) {
                \$$variableName = '%| ' . \$$variableName . ' |%';
                \$comparison = Criteria::LIKE;
            }
        } elseif (\$comparison == Criteria::CONTAINS_NONE) {
            \$$variableName = '%| ' . \$$variableName . ' |%';
            \$comparison = Criteria::NOT_LIKE;
            \$key = \$this->getAliasedColName($qualifiedName);
            if (\$this->containsKey(\$key)) {
                \$this->addAnd(\$key, \$$variableName, \$comparison);
            } else {
                \$this->addAnd(\$key, \$$variableName, \$comparison);
            }
            \$this->addOr(\$key, null, Criteria::ISNULL);

            return \$this;
        }

        return \$this->addUsingAlias($qualifiedName, \$$variableName, \$comparison);
    }
";
    }

    /**
     * Adds the filterByFk method for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addFilterByFk(&$script, $fk)
    {
        $this->declareClasses('PropelObjectCollection', 'PropelCollection', 'PropelException');
        $table = $this->getTable();
        $queryClass = $this->getStubQueryBuilder()->getClassname();
        $fkTable = $this->getForeignTable($fk);
        $fkStubObjectBuilder = $this->getNewStubObjectBuilder($fkTable);
        $this->declareClassFromBuilder($fkStubObjectBuilder);
        $fkPhpName = $fkStubObjectBuilder->getClassname();
        $relationName = $this->getFKPhpNameAffix($fk);
        $objectName = '$' . $fkTable->getStudlyPhpName();
        $script .= "
    /**
     * Filter the query by a related $fkPhpName object
     *";
        if ($fk->isComposite()) {
            $script .= "
     * @param   $fkPhpName $objectName The related object to use as filter";
        } else {
            $script .= "
     * @param   $fkPhpName|PropelObjectCollection $objectName The related object(s) to use as filter";
        }
        $script .= "
     * @param     string \$comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
     *
     * @return                 $queryClass The current query, for fluid interface
     * @throws PropelException - if the provided filter is invalid.
     */
    public function filterBy$relationName($objectName, \$comparison = null)
    {
        if ($objectName instanceof $fkPhpName) {
            return \$this";
        foreach ($fk->getLocalForeignMapping() as $localColumn => $foreignColumn) {
            $localColumnObject = $table->getColumn($localColumn);
            $foreignColumnObject = $fkTable->getColumn($foreignColumn);
            $script .= "
                ->addUsingAlias(" . $this->getColumnConstant($localColumnObject) . ", " . $objectName . "->get" . $foreignColumnObject->getPhpName() . "(), \$comparison)";
        }
        $script .= ";";
        if (!$fk->isComposite()) {
            $localColumnConstant = $this->getColumnConstant($fk->getLocalColumn());
            $foreignColumnName = $fk->getForeignColumn()->getPhpName();
            $keyColumn = $fk->getForeignTable()->hasCompositePrimaryKey() ? $foreignColumnName : 'PrimaryKey';
            $script .= "
        } elseif ($objectName instanceof PropelObjectCollection) {
            if (null === \$comparison) {
                \$comparison = Criteria::IN;
            }

            return \$this
                ->addUsingAlias($localColumnConstant, {$objectName}->toKeyValue('$keyColumn', '$foreignColumnName'), \$comparison);";
        }
        $script .= "
        } else {";
        if ($fk->isComposite()) {
            $script .= "
            throw new PropelException('filterBy$relationName() only accepts arguments of type $fkPhpName');";
        } else {
            $script .= "
            throw new PropelException('filterBy$relationName() only accepts arguments of type $fkPhpName or PropelCollection');";
        }
        $script .= "
        }
    }
";
    }

    /**
     * Adds the filterByRefFk method for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addFilterByRefFk(&$script, $fk)
    {
        $this->declareClasses('PropelObjectCollection', 'PropelCollection', 'PropelException');
        $table = $this->getTable();
        $queryClass = $this->getStubQueryBuilder()->getClassname();
        $fkTable = $this->getTable()->getDatabase()->getTable($fk->getTableName());
        $fkStubObjectBuilder = $this->getNewStubObjectBuilder($fkTable);
        $this->declareClassFromBuilder($fkStubObjectBuilder);
        $fkPhpName = $fkStubObjectBuilder->getClassname();
        $relationName = $this->getRefFKPhpNameAffix($fk);
        $objectName = '$' . $fkTable->getStudlyPhpName();
        $script .= "
    /**
     * Filter the query by a related $fkPhpName object
     *
     * @param   $fkPhpName|PropelObjectCollection $objectName  the related object to use as filter
     * @param     string \$comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
     *
     * @return                 $queryClass The current query, for fluid interface
     * @throws PropelException - if the provided filter is invalid.
     */
    public function filterBy$relationName($objectName, \$comparison = null)
    {
        if ($objectName instanceof $fkPhpName) {
            return \$this";
        foreach ($fk->getForeignLocalMapping() as $localColumn => $foreignColumn) {
            $localColumnObject = $table->getColumn($localColumn);
            $foreignColumnObject = $fkTable->getColumn($foreignColumn);
            $script .= "
                ->addUsingAlias(" . $this->getColumnConstant($localColumnObject) . ", " . $objectName . "->get" . $foreignColumnObject->getPhpName() . "(), \$comparison)";
        }
        $script .= ";";
        if (!$fk->isComposite()) {
            $script .= "
        } elseif ($objectName instanceof PropelObjectCollection) {
            return \$this
                ->use{$relationName}Query()
                ->filterByPrimaryKeys({$objectName}->getPrimaryKeys())
                ->endUse();";
        }
        $script .= "
        } else {";
        if ($fk->isComposite()) {
            $script .= "
            throw new PropelException('filterBy$relationName() only accepts arguments of type $fkPhpName');";
        } else {
            $script .= "
            throw new PropelException('filterBy$relationName() only accepts arguments of type $fkPhpName or PropelCollection');";
        }
        $script .= "
        }
    }
";
    }

    /**
     * Adds the joinFk method for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addJoinFk(&$script, $fk)
    {
        $table = $this->getTable();
        $queryClass = $this->getStubQueryBuilder()->getClassname();
        $fkTable = $this->getForeignTable($fk);
        $relationName = $this->getFKPhpNameAffix($fk);
        $joinType = $this->getJoinType($fk);
        $this->addJoinRelated($script, $fkTable, $queryClass, $relationName, $joinType);
    }

    /**
     * Adds the joinRefFk method for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addJoinRefFk(&$script, $fk)
    {
        $table = $this->getTable();
        $queryClass = $this->getStubQueryBuilder()->getClassname();
        $fkTable = $this->getTable()->getDatabase()->getTable($fk->getTableName());
        $relationName = $this->getRefFKPhpNameAffix($fk);
        $joinType = $this->getJoinType($fk);
        $this->addJoinRelated($script, $fkTable, $queryClass, $relationName, $joinType);
    }

    /**
     * Adds a joinRelated method for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addJoinRelated(&$script, $fkTable, $queryClass, $relationName, $joinType)
    {
        $script .= "
    /**
     * Adds a JOIN clause to the query using the " . $relationName . " relation
     *
     * @param     string \$relationAlias optional alias for the relation
     * @param     string \$joinType Accepted values are null, 'left join', 'right join', 'inner join'
     *
     * @return " . $queryClass . " The current query, for fluid interface
     */
    public function join" . $relationName . "(\$relationAlias = null, \$joinType = " . $joinType . ")
    {
        \$tableMap = \$this->getTableMap();
        \$relationMap = \$tableMap->getRelation('" . $relationName . "');

        // create a ModelJoin object for this join
        \$join = new ModelJoin();
        \$join->setJoinType(\$joinType);
        \$join->setRelationMap(\$relationMap, \$this->useAliasInSQL ? \$this->getModelAlias() : null, \$relationAlias);
        if (\$previousJoin = \$this->getPreviousJoin()) {
            \$join->setPreviousJoin(\$previousJoin);
        }

        // add the ModelJoin to the current object
        if (\$relationAlias) {
            \$this->addAlias(\$relationAlias, \$relationMap->getRightTable()->getName());
            \$this->addJoinObject(\$join, \$relationAlias);
        } else {
            \$this->addJoinObject(\$join, '" . $relationName . "');
        }

        return \$this;
    }
";
    }

    /**
     * Adds the useFkQuery method for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addUseFkQuery(&$script, $fk)
    {
        $table = $this->getTable();
        $fkTable = $this->getForeignTable($fk);
        $fkQueryBuilder = $this->getNewStubQueryBuilder($fkTable);
        $queryClass = $fkQueryBuilder->getClassname();
        if ($namespace = $fkQueryBuilder->getNamespace()) {
            $queryClass = '\\' . $namespace . '\\' . $queryClass;
        }
        $relationName = $this->getFKPhpNameAffix($fk);
        $joinType = $this->getJoinType($fk);
        $this->addUseRelatedQuery($script, $fkTable, $queryClass, $relationName, $joinType);
    }

    /**
     * Adds the useFkQuery method for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addUseRefFkQuery(&$script, $fk)
    {
        $table = $this->getTable();
        $fkTable = $this->getTable()->getDatabase()->getTable($fk->getTableName());
        $fkQueryBuilder = $this->getNewStubQueryBuilder($fkTable);
        $queryClass = $fkQueryBuilder->getClassname();
        if ($namespace = $fkQueryBuilder->getNamespace()) {
            $queryClass = '\\' . $namespace . '\\' . $queryClass;
        }
        $relationName = $this->getRefFKPhpNameAffix($fk);
        $joinType = $this->getJoinType($fk);
        $this->addUseRelatedQuery($script, $fkTable, $queryClass, $relationName, $joinType);
    }

    /**
     * Adds a useRelatedQuery method for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addUseRelatedQuery(&$script, $fkTable, $queryClass, $relationName, $joinType)
    {
        $script .= "
    /**
     * Use the $relationName relation " . $fkTable->getPhpName() . " object
     *
     * @see       useQuery()
     *
     * @param     string \$relationAlias optional alias for the relation,
     *                                   to be used as main alias in the secondary query
     * @param     string \$joinType Accepted values are null, 'left join', 'right join', 'inner join'
     *
     * @return   $queryClass A secondary query class using the current class as primary query
     */
    public function use" . $relationName . "Query(\$relationAlias = null, \$joinType = " . $joinType . ")
    {
        return \$this
            ->join" . $relationName . "(\$relationAlias, \$joinType)
            ->useQuery(\$relationAlias ? \$relationAlias : '$relationName', '$queryClass');
    }
";
    }

    protected function addFilterByCrossFK(&$script, $refFK, $crossFK)
    {
        $queryClass = $this->getStubQueryBuilder()->getClassname();
        $crossRefTable = $crossFK->getTable();
        $foreignTable = $crossFK->getForeignTable();
        $fkPhpName = $foreignTable->getPhpName();
        $crossTableName = $crossRefTable->getName();
        $this->declareClassFromBuilder($this->getNewStubObjectBuilder($foreignTable));
        $relName = $this->getFKPhpNameAffix($crossFK, $plural = false);
        $objectName = '$' . $foreignTable->getStudlyPhpName();
        $relationName = $this->getRefFKPhpNameAffix($refFK, $plural = false);
        $script .= "
    /**
     * Filter the query by a related $fkPhpName object
     * using the $crossTableName table as cross reference
     *
     * @param   $fkPhpName $objectName the related object to use as filter
     * @param     string \$comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
     *
     * @return   $queryClass The current query, for fluid interface
     */
    public function filterBy{$relName}($objectName, \$comparison = Criteria::EQUAL)
    {
        return \$this
            ->use{$relationName}Query()
            ->filterBy{$relName}($objectName, \$comparison)
            ->endUse();
    }
";
    }

    /**
     * Adds the prune method for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addPrune(&$script)
    {
        $table = $this->getTable();
        $class = $this->getStubObjectBuilder()->getClassname();
        $objectName = '$' . $table->getStudlyPhpName();
        $script .= "
    /**
     * Exclude object from result
     *
     * @param   $class $objectName Object to remove from the list of results
     *
     * @return " . $this->getStubQueryBuilder()->getClassname() . " The current query, for fluid interface
     */
    public function prune($objectName = null)
    {
        if ($objectName) {";
        $pks = $table->getPrimaryKey();
        if (count($pks) > 1) {
            $i = 0;
            $conditions = array();
            foreach ($pks as $col) {
                $const = $this->getColumnConstant($col);
                $condName = "'pruneCond" . $i . "'";
                $conditions[] = $condName;
                $script .= "
            \$this->addCond(" . $condName . ", \$this->getAliasedColName($const), " . $objectName . "->get" . $col->getPhpName() . "(), Criteria::NOT_EQUAL);";
                $i++;
            }
            $conditionsString = implode(', ', $conditions);
            $script .= "
            \$this->combine(array(" . $conditionsString . "), Criteria::LOGICAL_OR);";
        } else {
            $col = $pks[0];
            $const = $this->getColumnConstant($col);
            $script .= "
            \$this->addUsingAlias($const, " . $objectName . "->get" . $col->getPhpName() . "(), Criteria::NOT_EQUAL);";
        }
        $script .= "
        }

        return \$this;
    }
";
    }

    /**
     * Adds the basePreSelect hook for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addBasePreSelect(&$script)
    {
        $behaviorCode = '';
        $this->applyBehaviorModifier('preSelectQuery', $behaviorCode, "		");
        if (!$behaviorCode) {
            return;
        }
        $script .= "
    /**
     * Code to execute before every SELECT statement
     *
     * @param     PropelPDO \$con The connection object used by the query
     */
    protected function basePreSelect(PropelPDO \$con)
    {" . $behaviorCode . "

        return \$this->preSelect(\$con);
    }
";
    }

    /**
     * Adds the basePreDelete hook for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addBasePreDelete(&$script)
    {
        $behaviorCode = '';
        $this->applyBehaviorModifier('preDeleteQuery', $behaviorCode, "		");
        if (!$behaviorCode) {
            return;
        }
        $script .= "
    /**
     * Code to execute before every DELETE statement
     *
     * @param     PropelPDO \$con The connection object used by the query
     */
    protected function basePreDelete(PropelPDO \$con)
    {" . $behaviorCode . "

        return \$this->preDelete(\$con);
    }
";
    }

    /**
     * Adds the basePostDelete hook for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addBasePostDelete(&$script)
    {
        $behaviorCode = '';
        $this->applyBehaviorModifier('postDeleteQuery', $behaviorCode, "		");
        if (!$behaviorCode) {
            return;
        }
        $script .= "
    /**
     * Code to execute after every DELETE statement
     *
     * @param     int \$affectedRows the number of deleted rows
     * @param     PropelPDO \$con The connection object used by the query
     */
    protected function basePostDelete(\$affectedRows, PropelPDO \$con)
    {" . $behaviorCode . "

        return \$this->postDelete(\$affectedRows, \$con);
    }
";
    }

    /**
     * Adds the basePreUpdate hook for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addBasePreUpdate(&$script)
    {
        $behaviorCode = '';
        $this->applyBehaviorModifier('preUpdateQuery', $behaviorCode, "		");
        if (!$behaviorCode) {
            return;
        }
        $script .= "
    /**
     * Code to execute before every UPDATE statement
     *
     * @param     array \$values The associative array of columns and values for the update
     * @param     PropelPDO \$con The connection object used by the query
     * @param     boolean \$forceIndividualSaves If false (default), the resulting call is a BasePeer::doUpdate(), otherwise it is a series of save() calls on all the found objects
     */
    protected function basePreUpdate(&\$values, PropelPDO \$con, \$forceIndividualSaves = false)
    {" . $behaviorCode . "

        return \$this->preUpdate(\$values, \$con, \$forceIndividualSaves);
    }
";
    }

    /**
     * Adds the basePostUpdate hook for this object.
     *
     * @param string &$script The script will be modified in this method.
     */
    protected function addBasePostUpdate(&$script)
    {
        $behaviorCode = '';
        $this->applyBehaviorModifier('postUpdateQuery', $behaviorCode, "		");
        if (!$behaviorCode) {
            return;
        }
        $script .= "
    /**
     * Code to execute after every UPDATE statement
     *
     * @param     int \$affectedRows the number of updated rows
     * @param     PropelPDO \$con The connection object used by the query
     */
    protected function basePostUpdate(\$affectedRows, PropelPDO \$con)
    {" . $behaviorCode . "

        return \$this->postUpdate(\$affectedRows, \$con);
    }
";
    }

    /**
     * Checks whether any registered behavior on that table has a modifier for a hook
     *
     * @param string $hookName The name of the hook as called from one of this class methods, e.g. "preSave"
     *
     * @return boolean
     */
    public function hasBehaviorModifier($hookName, $modifier = null)
    {
        return parent::hasBehaviorModifier($hookName, 'QueryBuilderModifier');
    }

    /**
     * Checks whether any registered behavior on that table has a modifier for a hook
     *
     * @param string $hookName The name of the hook as called from one of this class methods, e.g. "preSave"
     * @param string &$script  The script will be modified in this method.
     */
    public function applyBehaviorModifier($hookName, &$script, $tab = "		")
    {
        return $this->applyBehaviorModifierBase($hookName, 'QueryBuilderModifier', $script, $tab);
    }

    /**
     * Checks whether any registered behavior content creator on that table exists a contentName
     *
     * @param string $contentName The name of the content as called from one of this class methods, e.g. "parentClassname"
     */
    public function getBehaviorContent($contentName)
    {
        return $this->getBehaviorContentBase($contentName, 'QueryBuilderModifier');
    }
}
