/library/Bvb/Grid/Source/Doctrine.php
PHP | 1090 lines | 543 code | 147 blank | 400 comment | 65 complexity | 4d602ffbba825766b1ddeb725356ee49 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-3-Clause, LGPL-2.0, CC-BY-SA-3.0, MIT
- <?php
- class Bvb_Grid_Source_Doctrine implements Bvb_Grid_Source_Interface
- {
- /**
- * Stores the supplied Doctrine_Query
- *
- * @var Doctrine_Query
- */
- protected $_query;
-
- /**
- * Stores the parsed out DQL
- *
- * @var array
- */
- protected $_queryParts = array(
- 'select' => array(),
- 'from' => array(),
- 'join' => array()
- );
-
- /**
- * Intialize the Doctrine_Query. We will parse out
- * all the provided DQL or start a Doctrine_Query
- * if an instance of Doctrine_Record is provided
- *
- * @param mixed $q
- */
- public function __construct($q)
- {
- if ($q instanceof Doctrine_Record) {
- $q = get_class($q);
- }
-
- if (is_string($q)) {
- $q = Doctrine_Query::create()->from($q);
- }
-
- if (!$q instanceof Doctrine_Query) {
- require_once 'Bvb/Grid/Source/Doctrine/Exception.php';
- throw new Bvb_Grid_Source_Doctrine_Exception(
- "Please provide only an instance of Doctrine_Query "
- . "or a valid Doctrine_Record instance"
- );
- }
-
- $this->_query = $q;
- $this->_setFromParts();
- $this->_setSelectParts();
- }
-
- /**
- * Simple method for the Grid to determine if this
- * Source can handle CRUD
- *
- * @return boolean
- */
- public function hasCrud()
- {
- return true;
- }
-
- /**
- * Returns the "main" table
- * the one after select * FROM {MAIN_TABLE}
- *
- * @return array
- */
- public function getMainTable()
- {
- $table = Doctrine::getTable($this->_queryParts['from']['tableModel']);
- return array('table' => $table->getTableName());
- }
-
- /**
- * builds a key=>value array
- *
- * they must have two options
- * title and field
- * field is used to perform queries.
- * Must have table name or table alias as a prefix
- * ex: user.id | country.population
- *
- * The key for this array is the output field
- * If raw sql is somehting like
- *
- * select name as alias, country from users
- *
- * the return array must be like this:
- *
- * array('alias'=>array('title'=>'alias','field'=>'users.name'));
- *
- * its not bad idea to apply this to fields titles
- * $title = ucwords(str_replace('_',' ',$title));
- *
- * @return array
- */
- public function buildFields()
- {
- $this->_setSelectParts();
- return $this->_queryParts['select'];
- }
-
- /**
- * Use the supplied Doctrine_Query to find its primary ID
- *
- * TODO : Implement usage of $table param
- */
- public function getPrimaryKey($table = null)
- {
- $return = array();
- $table = Doctrine::getTable($this->_queryParts['from']['tableModel']);
- $alias = $this->_queryParts['from']['alias'];
-
- //Get the Primary Key(s) for provided table
- $ids = $table->getIdentifierColumnNames();
-
- //Append the alias to each Primary key field
- foreach ($ids as $id) {
- $return[] = (!empty($alias)) ? $alias . '.' . $id : $id;
- }
-
- return $return;
- }
-
- /**
- * Gets a unique record as a associative array
- *
- * @param $table
- * @param $condition
- * @return array
- */
- public function getRecord($table, array $condition)
- {
- $tableModel = $this->_getModelFromTable($table);
-
- $query = Doctrine_Query::create()->from($tableModel);
-
- foreach ($condition as $field => $value) {
- $query->addWhere($field . ' = ?', $value);
- }
-
- $results = $query->fetchArray(array(), Doctrine::HYDRATE_SCALAR);
-
- $newResults = $this->_cleanQueryResults($results);
-
- if (count($newResults) == 1) {
- return $newResults[0];
- }
-
- return $newResults;
- }
- /**
- * Should return the database server name or source name
- *
- * Ex: mysql, pgsql, array, xml
- *
- * @return string
- */
- public function getSourceName()
- {
- return strtolower($this->_query->getConnection()->getDriverName());
- }
- /**
- * Runs the query and returns the result as a associative array
- *
- * @return array
- */
- public function execute()
- {
- $newQuery = clone $this->_query;
- $results = $newQuery->execute(array(), Doctrine::HYDRATE_SCALAR);
-
- $newArray = $this->_cleanQueryResults($results);
-
- return $newArray;
- }
- /**
- * Get a record detail based the current query
- *
- * <code>
- * $where = array(
- * array('columnName' => 'searchValue')
- * )
- * </code>
- *
- * @param array $where
- * @return array
- */
- public function fetchDetail(array $where)
- {
- /**
- * Remove these since we are trying to retrieve
- * a specific row
- */
- $this->_query->removeDqlQueryPart('limit')
- ->removeDqlQueryPart('offset');
- foreach ($where as $column => $value) {
- $this->_query->addWhere($column . ' = ?', $value);
- }
-
- return $this->execute();
- }
- /**
- * Return the total of records
- *
- * @return integer
- */
- public function getTotalRecords()
- {
- return (int) $this->_query->count();
- }
- /**
- * Ex: array('c'=>array('tableName'=>'Country'));
- * where c is the table alias. If the table as no alias,
- * c should be the table name
- *
- * @return array
- */
- function getTableList ()
- {
- die('getTableList');
- }
- /**
- * Return possible filters values based on field definion
- * This is mostly used for enum fields where the possibile
- * values are extracted
- *
- * Ex: enum('Yes','No','Empty');
- *
- * should return
- *
- * array('Yes'=>'Yes','No'=>'No','Empty'=>'Empty');
- *
- * @param $field
- * @return string
- */
- public function getFilterValuesBasedOnFieldDefinition($field)
- {
- $table = $this->_getModelFromColumn($field);
-
- $tableClass = Doctrine::getTable($table);
-
- if (strpos($field, '.') !== false) {
- list($alias, $column) = explode('.', $field);
- } else {
- $column = $field;
- }
-
- $definition = $tableClass->getDefinitionOf($column);
-
- if ($definition['type'] == 'enum') {
- foreach ($definition['values'] as $val) {
- $return[$val] = $val;
- }
-
- return $return;
- }
-
- return 'text';
- }
- /**
- * Return te field type
- * char, varchar, int
- *
- * Note: If the field is enum or set,
- * the value returned must be set or enum,
- * and not the full definition
- *
- * @param string $field
- * @return string|null
- */
- public function getFieldType($field)
- {
- $tableModel = $this->_getModelFromColumn($field);
-
- if (isset($this->_queryParts['select'][$field]['field'])) {
- if (strpos($this->_queryParts['select'][$field]['field'], '.') !== false) {
- list($alias, $fieldName) = explode('.', $this->_queryParts['select'][$field]['field']);
- } else {
- $fieldName = $field;
- }
- } else {
- return null;
- }
-
- $fieldType = Doctrine::getTable($tableModel)->getTypeOfColumn($fieldName);
-
- return $fieldType;
- }
- /**
- *
- * Build the order part from the query.
- *
- * The first arg is the field to be ordered and the $order
- * arg is the correspondent order (ASC|DESC)
- *
- * If the $reset is set to true, all previous order should be removed
- *
- * @param string $field
- * @param string $order
- * @param bool $reset
- * @return Bvb_Grid_Source_Doctrine
- */
- public function buildQueryOrder($field, $order, $reset = false)
- {
- if ($reset) {
- $this->_query->removeDqlQueryPart('orderby');
- }
-
- $this->_query->addOrderBy($field . ' ' . $order);
-
- return $this;
- }
- /**
- * Build the query limit clause
- *
- * @param $start
- * @param $offset
- * @return Bvb_Grid_Source_Doctrine
- */
- public function buildQueryLimit($start, $offset)
- {
- $this->_query->limit($start)->offset($offset);
-
- return $this;
- }
- /**
- * Returns the select object
- */
- function getSelectObject ()
- {
- die('getSelectObject');
- }
- /**
- * Returns the selected order
- * that was defined by the user in the query entered
- * and not the one generated by the system
- *
- * If empty an empty array must be returned.
- *
- * Else the array must be like this:
- *
- * <code>
- * $return = array(
- * 0 => field
- * 1 => (ASC|DESC)
- * );
- * </code>
- *
- * @return array
- */
- public function getSelectOrder()
- {
- $newOrderBys = array();
- $orderBy = $this->_query->getDqlPart('orderby');
-
- if (!empty($orderBy)) {
- foreach ($orderBy as $anOrderby) {
- $orderBys = explode(',', $anOrderby);
-
- foreach ($orderBys as $order) {
- $parts = explode(' ', trim($order));
- if (strtolower($parts[1]) != 'desc' && strtolower($parts[1]) != 'asc') {
- $parts[1] = '';
- }
- $newOrderBys[] = $parts;
- }
- }
- }
-
- return $newOrderBys;
- }
- /**
- * Should preform a query based on the provided by the user
- * select the two fields and return an array $field=>$value
- * as result
- *
- * ex: SELECT $field, $value FROM *
- * array('1'=>'Something','2'=>'Number','3'=>'history')....;
- *
- * @param string $field
- * @param string $value
- * @return array
- */
- public function getDistinctValuesForFilters($field, $value)
- {
- $return = array();
-
- $newQuery = clone $this->_query;
-
- $distinct = new Doctrine_Expression("DISTINCT($field)");
-
- $newQuery->removeDqlQueryPart('select')
- ->removeDqlQueryPart('orderby')
- ->removeDqlQueryPart('limit')
- ->removeDqlQueryPart('offset')
- ->select("$distinct AS field, $value AS value")
- ->orderBy('value ASC');
-
- $results = $newQuery->fetchArray();
-
- foreach ($results as $value ) {
- $return[$value['field']] = $value['value'];
- }
-
- return $return;
- }
- /**
- * Perform a sqlexp
- *
- * $value = array ('functions' => array ('AVG'), 'value' => 'Population' );
- *
- * Should be converted to
- * SELECT AVG(Population) FROM *
- *
- * $value = array ('functions' => array ('SUM','AVG'), 'value' => 'Population' );
- *
- * Should be converted to
- * SELECT SUM(AVG(Population)) FROM *
- *
- * @param array $value
- */
- public function getSqlExp(array $value)
- {
- $return = array();
-
- $newQuery = clone $this->_query;
-
- foreach (array_reverse($value['functions']) as $key => $func) {
- if ($key == 0) {
- $exp = $func . '(' . $value['value'] . ')';
- } else {
- $exp = $func . '(' . $exp . ')';
- }
- }
-
- $exp = new Doctrine_Expression($exp);
-
- $newQuery->removeDqlQueryPart('select')
- ->removeDqlQueryPart('orderby')
- ->removeDqlQueryPart('limit')
- ->removeDqlQueryPart('offset')
- ->select("$exp AS total");
-
- $result = $newQuery->fetchOne(array(), Doctrine::HYDRATE_ARRAY);
-
- return $result['total'];
- }
- /**
- * Adds a fulltext search instead of a addcondition method
- *
- * $field has an index search
- * $field['search'] = array('extra'=>'boolean|queryExpansion','indexes'=>'string|array');
- *
- * if no indexes provided, use the field name
- *
- * boolean => IN BOOLEAN MODE
- * queryExpansion => WITH QUERY EXPANSION
- *
- * @param $filter
- * @param $field
- */
- function addFullTextSearch ($filter, $field)
- {
- die('addFullTextSearch');
- }
- /**
- * Adds a new condition to the current query
- * $filter is the value to be filtered
- * $op is the opreand to be used: =,>=, like, llike,REGEX,
- * $completeField. use the index $completField['field'] to
- * specify the field, to avoid ambiguous
- *
- * @param $filter
- * @param $op
- * @param $completeField
- * @return Bvb_Grid_Source_Doctrine
- */
- public function addCondition($filter, $op, $completeField)
- {
- $field = $completeField['field'];
-
- switch (strtolower($op)) {
- case 'equal':
- case '=':
- $this->_query->addWhere($field . ' = ?', $filter);
- break;
- case 'regex':
- $this->_query->addWhere($field . " REGEXP ?", $filter);
- break;
- case 'rlike':
- $this->_query->addWhere($field . " LIKE ?", $filter . "%");
- break;
- case 'llike':
- $this->_query->addWhere($field . " LIKE ?", "%" . $filter);
- break;
- case '>=':
- $this->_query->addWhere($field . " >= ?", $filter);
- break;
- case '>':
- $this->_query->addWhere($field . " > ?", $filter);
- break;
- case '<>':
- case '!=':
- $this->_query->addWhere($field . " <> ?", $filter);
- break;
- case '<=':
- $this->_query->addWhere($field . " <= ?", $filter);
- break;
- case '<':
- $this->_query->addWhere($field . " < ?", $filter);
- break;
- case 'in':
- $filter = explode(',', $filter);
- $this->_query->whereIn($field, $filter);
- break;
- case 'range':
- $start = substr($filter, 0, strpos($filter, '<>'));
- $end = substr($filter, strpos($filter, '<>') + 2);
- $this->_query->addWhere($field . " between ? and ?", array($start, $end));
- break;
- case 'like':
- default:
- $this->_query->addWhere($field . " LIKE ?", "%" . $filter . "%");
- break;
- }
-
- return $this;
- }
- /**
- * Insert an array of key=>values in the specified table
- *
- * @param string $table
- * @param array $post
- * @return boolean
- */
- public function insert($table, array $post)
- {
- $tableModel = $this->_getModelFromTable($table);
- $id = Doctrine::getTable($tableModel)->getIdentifier();
-
- /**
- * @var Doctrine_Record
- */
- $model = new $tableModel;
- $model->fromArray($post);
-
- return $model->trySave();
- }
- /**
- * Update values in a table using the $condition clause
- *
- * The condition clause is a $field=>$value array
- * that should be escaped by YOU (if your class doesn't do that for you)
- * and usinf the AND operand
- *
- * Ex: array('user_id'=>'1','id_site'=>'12');
- *
- * Raw SQL: * WHERE user_id='1' AND id_site='12'
- *
- * @param string $table
- * @param array $post
- * @param array $condition
- * @return integer Of Affected rows
- */
- public function update($table, array $post, array $condition)
- {
- $tableModel = $this->_getModelFromTable($table);
-
- $query = Doctrine_Query::create()->update($tableModel);
-
- foreach ($post as $field => $value) {
- $query->set($field, '?', $value);
- }
-
- foreach ($condition as $field => $value) {
- $query->addWhere($field . ' = ?', $value);
- }
-
- return $query->execute();
- }
- /**
- * Delete a record from a table
- *
- * The condition clause is a $field=>$value array
- * that should be escaped by YOU (if your class doesn't do that for you)
- * and usinf the AND operand
- *
- * Ex: array('user_id'=>'1','id_site'=>'12');
- * Raw SQL: * WHERE user_id='1' AND id_site='12'
- *
- * @param string $table
- * @param array $condition
- * @return integer Of Affected rows
- */
- public function delete($table, array $condition)
- {
- $tableModel = $this->_getModelFromTable($table);
-
- $query = Doctrine_Query::create()->delete($tableModel);
-
- foreach ($condition as $field => $value) {
- $query->addWhere($field . ' = ?', $value);
- }
-
- return $query->execute();
- }
- /**
- * Removes any order in query
- *
- * @return Bvb_Grid_Source_Doctrine
- */
- public function resetOrder()
- {
- $this->_query->removeDqlQueryPart('orderby');
- return $this;
- }
- /**
- * Cache handler.
- *
- * TODO: Research what 'cache' does, might just need to look at the
- * bool and see if we need to set Doctrine Cache or not
- */
- function setCache($cache)
- {
- //die(Zend_Debug::dump($cache));
- //die('setCache');
- }
- /**
- * Build the form based on a Model or query
- *
- * @return array
- */
- public function buildForm()
- {
- $table = $this->_queryParts['from']['tableModel'];
- $columns = Doctrine::getTable($table)->getColumns();
-
- return $this->buildFormElements($columns);
- }
-
- /**
- * Will build out an array of form elements,
- * based on the column type and return the array
- * to be used when loading the Bvb_Grid_Form
- *
- * @param array $cols
- * @param array $info
- * @return array
- */
- public function buildFormElements(array $cols, $info = array())
- {
- $form = array();
-
- foreach ($cols as $column => $detail) {
-
- if (isset($detail['primary']) && $detail['primary']) {
- continue;
- }
-
- $label = ucwords(str_replace('_', ' ', $column));
-
- switch ($detail['type']) {
- case 'enum':
- $form['elements'][$column] = array('select', array('multiOptions' => $detail['values'], 'required' => ($detail['notnull'] == 1) ? false : true, 'label' => $label));
- break;
-
- case 'string':
- case 'varchar':
- case 'char':
- $length = $detail['length'];
- $form['elements'][$column] = array('text', array('validators' => array(array('stringLength', false, array(0, $length))), 'size' => 40, 'label' => $label, 'required' => ($detail['notnull'] == 1) ? false : true, 'value' => (! empty($detail['default']) ? $detail['default'] : "")));
- break;
- case 'date':
- $form['elements'][$column] = array('text', array('validators' => array(array('Date')), 'size' => 10, 'label' => $label, 'required' => ($detail['notnull'] == 1) ? false : true, 'value' => (! empty($detail['default']) ? $detail['default'] : "")));
- break;
- case 'datetime':
- case 'timestamp':
- $form['elements'][$column] = array('text', array('validators' => array(array(new Zend_Validate_Date('Y-m-d H:i:s'))), 'size' => 19, 'label' => $label, 'required' => ($detail['notnull'] == 1) ? false : true, 'value' => (! empty($detail['default']) ? $detail['default'] : "")));
- break;
-
- case 'text':
- case 'mediumtext':
- case 'longtext':
- case 'smalltext':
- $form['elements'][$column] = array('textarea', array('label' => $label, 'required' => ($detail['notnull'] == 1) ? false : true, 'filters' => array('StripTags')));
- break;
-
- case 'integer':
- case 'int':
- case 'bigint':
- case 'mediumint':
- case 'smallint':
- case 'tinyint':
- $isZero = (! empty($detail['default']) && $detail['default'] == "0") ? true : false;
- $form['elements'][$column] = array('text', array('validators' => array('Digits'), 'label' => $label, 'size' => 10, 'required' => ($isZero == false && $detail['notnull'] == 1) ? false : true, 'value' => (! empty($detail['default']) ? $detail['default'] : "")));
- break;
- case 'float':
- case 'decimal':
- case 'double':
- $form['elements'][$column] = array('text', array('validators' => array('Float'), 'size' => 10, 'label' => $label, 'required' => ($detail['notnull'] == 1) ? false : true, 'value' => (! empty($detail['default']) ? $detail['default'] : "")));
- break;
- default:
- break;
- }
- }
-
- return $form;
- }
-
- /**
- * Used within this class to clean the hydrated result
- * to be something more Grid friendly
- *
- * @param array $results
- * @return array Cleaned results
- */
- protected function _cleanQueryResults($results)
- {
- $newArray = array();
-
- if (empty($this->_queryParts['from']['alias'])) {
- foreach ($results as $rows) {
- $temp = array();
- foreach ($rows as $col => $val) {
- $name = str_replace($this->_queryParts['from']['tableModel'] . '_', '', $col);
- $temp[$name] = $val;
- }
-
- $newArray[] = $temp;
- }
- } else {
- foreach ($results as $rows) {
- $temp = array();
-
- foreach ($rows as $col => $val) {
- $parts = explode('_', $col, 2);
-
- foreach ($this->_queryParts['select'] as $alias => $select) {
- if (implode('.', $parts) == $select['field'] || $parts[1] == $alias) {
- $temp[$alias] = $val;
- }
- }
- }
-
- $newArray[] = $temp;
- }
- }
-
- return $newArray;
- }
-
- /**
- * Used to parse out the SELECT pieces of the DQL
- * and place it in the $_queryParts array for use
- * in many other places
- *
- * @return Bvb_Grid_Source_Doctrine
- */
- protected function _setSelectParts()
- {
- $return = array();
-
- $selects = $this->_query->getDqlPart('select');
-
- if (empty($selects)) {
- $this->_findAndSetSelect();
- $selects = $this->_query->getDqlPart('select');
- }
-
- //Remove all 'as' instances
- $selects = $this->_removeAs($selects);
-
- foreach ($selects as $select) {
- $fields = explode(',', $select);
- $fields = array_map('trim', $fields);
-
- foreach ($fields as $field) {
- $fieldName = trim($field);
- $fieldAlias = null;
-
- if (count(explode(' ', trim($field))) > 1) {
- list($fieldName, $fieldAlias) = explode(' ', trim($field));
- }
-
- if (empty($fieldAlias)) {
- $pos = strpos($fieldName, '.');
- $fieldAlias = substr($fieldName, ++$pos);
- }
-
- $return[$fieldAlias] = array(
- 'title' => ucwords(str_replace('_', ' ', $fieldAlias)),
- 'field' => $fieldName
- );
- }
- }
-
- $this->_queryParts['select'] = $return;
- return $this;
- }
-
- /**
- * Used to parse out the FROM and JOIN pieces of the DQL
- * and place it in the $_queryParts array for use
- * in many other places
- *
- * @return Bvb_Grid_Source_Doctrine
- */
- protected function _setFromParts()
- {
- $return = array();
-
- //Remove all 'as' instances
- $froms = $this->_removeAs($this->_query->getDqlPart('from'));
-
- foreach ($froms as $from) {
- $fields = explode(',', $from);
- $fields = array_map('trim', $fields);
-
- foreach ($fields as $field) {
- if (strpos(strtoupper($field), 'JOIN') === false) {
- $this->_queryParts = array_merge($this->_queryParts, $this->_explodeFrom($field));
- } else {
- $join = explode('JOIN', $field);
- $join = array_map('trim', $join);
-
- $joinType = strtolower($join[0]);
-
- $this->_queryParts = array_merge($this->_queryParts, $this->_explodeJoin($join[1], $joinType));
- }
- }
-
- }
-
- return $this;
- }
-
- /**
- * Used to set SELECT values to the DQL when
- * no SELECT is provided. We will just add
- * ALL columns for all tables given.
- *
- * NOTE: Since no SELECT was provided, to access these
- * from within the Bvb_Grid_Data class, you will need to
- * use the table alias + "_" + column name
- *
- * <code>
- * $grid->setGridColumns(array('co_code', 'co_name', 'co_continent', 'ci_name'));
- * </code>
- *
- * @return void
- */
- protected function _findAndSetSelect()
- {
- $return = array();
-
- //Make sure we have the FROM set
- $this->_setFromParts();
-
- $fromTableModel = $this->_queryParts['from']['tableModel'];
- $fromClass = Doctrine::getTable($fromTableModel);
- $fromColumns = array_keys($fromClass->getColumns());
- $fromAlias = $this->_queryParts['from']['alias'];
-
- foreach ($fromColumns as $fromColumn) {
- /**
- * Do this check here because a DQL with no JOIN,
- * does not need a table alias
- *
- * @var string
- */
- $addColumn = (!empty($fromAlias)) ? $fromAlias . '.' . $fromColumn : $fromColumn;
- $this->_query->addSelect($addColumn);
- }
-
- $joins = $this->_queryParts['join'];
-
- if (!empty($joins)) {
- foreach ($joins as $joinType) {
- foreach ($joinType as $join) {
- $joinClass = Doctrine::getTable($join['tableModel']);
- $joinColumns = array_keys($joinClass->getColumns());
-
- foreach ($joinColumns as $joinColumn) {
- $this->_query->addSelect($join['alias'] . '.' . $joinColumn);
- }
- }
- }
- }
- }
-
- /**
- * Take a DQL SELECT string and parse it into
- * a usable array
- *
- * <code>
- * $return = array(
- * 'from' => array(
- * 'alias' => 'c',
- * 'table' => 'country'
- * )
- * )
- * </code>
- *
- * @param string $from A DQL SELECT statement
- * @return array
- */
- private function _explodeFrom($from)
- {
- if (!is_string($from)) {
- require_once 'Bvb/Grid/Source/Doctrine/Exception.php';
- throw new Bvb_Grid_Source_Doctrine_Exception('Provided param needs to be a string only');
- }
-
- $return = array();
- $table = $from;
- $alias = null;
-
- if (count(explode(' ', $from)) > 1) {
- list($table, $alias) = explode(' ', $from);
- }
-
- if (strpos($table, '.') !== false) {
- $return = $this->_explodeJoin($from, 'left');
- } else {
- $return['from'] = array(
- 'alias' => $alias,
- 'tableModel' => $table,
- 'tableName' => Doctrine::getTable($table)->getTableName()
- );
- }
-
- return $return;
- }
-
- /**
- * Take a DQL JOIN string and parse it into
- * a usable array
- *
- * <code>
- * $return = array(
- * 'join' => array(
- * 'left' => array(
- * array(
- * 'alias' => 'ci'
- * 'table' => 'Model_City' //Doctrine Table name
- * 'tableAlias' => 'City' //What is used in the JOIN statement
- * 'joinOn' => 'c'
- * )
- * )
- * )
- * )
- * </code>
- *
- * @param string $join
- * @param string $joinType The type of join - LEFT, RIGHT, etc
- */
- private function _explodeJoin($join, $joinType)
- {
- $return = array();
-
- list($table, $alias) = explode(' ', $join);
- list($joinOn, $tableAlias) = explode('.', $table);
- $mainTable = $this->_getModelFromAlias($joinOn);
-
- $tableModel = Doctrine::getTable($mainTable)->getRelation($tableAlias)->getClass();
-
- $return['join'][strtolower($joinType)][] = array(
- 'alias' => $alias,
- 'tableModel' => $tableModel,
- 'tableAlias' => $tableAlias,
- 'joinOn' => $joinOn
- );
-
- return $return;
- }
-
- /**
- * Simple utility for removing "as" from the DQL
- *
- * @param string $subject
- * @return string No-As DQL expression
- */
- private function _removeAs($subject)
- {
- return str_replace(array(' AS', ' As', ' aS', ' as'), array('', '', '', ''), $subject);
- }
-
- /**
- * Find the table for which a column belongs
- *
- * @param string $column
- * @return string Name of the table used
- */
- private function _getModelFromColumn($column)
- {
- if (!is_string($column)) {
- $type = gettype($column);
- require_once 'Bvb/Grid/Source/Doctrine/Exception.php';
- throw new Bvb_Grid_Source_Doctrine_Exception('The $column param needs to be a string, ' . $type . ' provided');
- }
-
- if (empty($this->_queryParts['from']['alias'])) {
- return $this->_queryParts['from']['tableModel'];
- }
-
- list($alias, $field) = explode('.', $column);
-
- return $this->_getModelFromAlias($alias);
- }
-
- /**
- * Find the table/model based on the table alias provided
- *
- * @param string $alias
- * @return string
- */
- private function _getModelFromAlias($alias)
- {
- if (!is_string($alias)) {
- $type = gettype($alias);
- require_once 'Bvb/Grid/Source/Doctrine/Exception.php';
- throw new Bvb_Grid_Source_Doctrine_Exception('The $alias param needs to be a string, ' . $type . ' provided');
- }
-
- if ($this->_queryParts['from']['alias'] == $alias) {
- return $this->_queryParts['from']['tableModel'];
- }
-
- foreach ($this->_queryParts['join'] as $joins) {
- foreach ($joins as $join) {
- if ($join['alias'] == $alias) {
- return $join['tableModel'];
- }
- }
- }
- }
-
- /**
- * Find the table/model based on the table alias provided
- *
- * @param string $table Name of table to find model from
- * @return string Name of the model associated with the provided table
- */
- private function _getModelFromTable($table)
- {
- if (!is_string($table)) {
- $type = gettype($table);
- require_once 'Bvb/Grid/Source/Doctrine/Exception.php';
- throw new Bvb_Grid_Source_Doctrine_Exception('The $table param needs to be a string, ' . $type . ' provided');
- }
-
- if ($this->_queryParts['from']['tableName'] == $table) {
- return $this->_queryParts['from']['tableModel'];
- }
-
- foreach ($this->_queryParts['join'] as $joins) {
- foreach ($joins as $join) {
- if ($join['tableAlias'] == $table) {
- return $join['tableModel'];
- }
- }
- }
- }
- }