/** * Return the entityset query. If $clone is passed it will return a clone instance of the entityset * query is returned * * @param boolean $clone If set to true then it will return a new clone instance of entityset * @param boolean $disable_chain Disable the chain * * @return AnDomainQuery */ public function getQuery($clone = false, $disable_chain = false) { if (!isset($this->_set_query) || $clone) { if ($this->_query instanceof AnDomainQuery) { $query = clone $this->_query; } else { $query = $this->_repository->getQuery(); AnDomainQueryHelper::applyFilters($query, $this->_query); } //if clone is set, then return the qury object if ($clone) { if ($disable_chain) { $query->disableChain(); } return $query; } //if not then set the entity query object $this->_set_query = $query; } return $this->_set_query; }
/** * Return the column name of a property. If property not exists just return $name * * @param $query * @param $columns * @return array */ public static function parseColumns($query, $columns) { if ($columns instanceof AnDomainResourceColumn) { return array($columns); } settype($columns, 'array'); $array = array(); foreach ($columns as $key => $column) { $result = strpos($column, ' ') !== false ? null : AnDomainQueryHelper::parseColumn($query, $column); $cols = $result['columns']; if (!isset($result['property'])) { $array[$key] = $column; } elseif (!is_array($cols)) { $array[$key] = $cols; } else { $key = 10000; foreach ($cols as $col) { $array[$key++] = $col; } } } return $array; }
/** * Builds a query into a final query statement. * * @param AnDomainQuery $query Query object * @param string $string A String object * * @return string */ public function parseMethods($query, $string) { //replaces any @col(\w+) pattern with the correct column name if (strpos($string, '@col(')) { $matches = array(); if (preg_match_all('/@col\\((.*?)\\)/', $string, $matches)) { $description = $query->getRepository()->getDescription(); $replaces = array(); foreach ($matches[1] as $match) { $result = AnDomainQueryHelper::parseColumn($query, $match); if (empty($result['columns'])) { $replaces[] = $match; } else { $replaces[] = (string) $result['columns']; } } $string = str_replace($matches[0], $replaces, $string); } } if (strpos($string, '@quote(')) { $matches = array(); $replaces = array(); if (preg_match_all('/@quote\\((.*?)\\)/', $string, $matches)) { foreach ($matches[1] as $match) { $replaces[] = $this->_store->quoteValue($match); } $string = str_replace($matches[0], $replaces, $string); } } if (strpos($string, '@instanceof(')) { $matches = array(); $replaces = array(); if (preg_match_all('/\\!?@instanceof\\((.*?)\\)/', $string, $matches)) { foreach ($matches[1] as $i => $match) { $operand = ''; if ($matches[0][$i][0] == '!') { $operand = 'NOT '; } $type_col = $query->getRepository()->getDescription()->getInheritanceColumn(); $classes = explode(',', $match); $statements = array(); foreach ($classes as $class) { $class = $this->_store->quoteValue($class); $statements[] = $operand . "FIND_IN_SET({$class},{$type_col})"; } if ($operand == 'NOT ') { $operand = ' AND '; } else { $operand = ' OR '; } if (count($statements) == 1) { $statements = implode($operand, $statements); } else { $statements = '(' . implode($operand, $statements) . ')'; } $replaces[] = $statements; } $string = str_replace($matches[0], $replaces, $string); } } if (strpos($string, '@remove_from_set(')) { $matches = array(); $replaces = array(); if (preg_match_all('/@remove_from_set\\((.*?)\\)/', $string, $matches)) { foreach ($matches[1] as $i => $match) { list($set, $item) = explode(',', $match); $set = trim($set); $item = trim($item); $replaces[] = "TRIM(BOTH ',' FROM REPLACE(concat(',',{$set},','),CONCAT(',',{$item},','),','))"; } $string = str_replace($matches[0], $replaces, $string); } } if (strpos($string, '@set_length(')) { $matches = array(); $replaces = array(); if (preg_match_all('/@set_length\\((.*?)\\)/', $string, $matches)) { foreach ($matches[1] as $i => $match) { $replaces[] = "LENGTH({$match}) - LENGTH(REPLACE({$match}, ',', '')) + 1"; } $string = str_replace($matches[0], $replaces, $string); } } return $string; }
/** * Links a query to anotehr query by joining the main query resoruce. * * @param mixed $query Query object * @param string|array $condition Array condition * @param array $options Options * * @return AnDomainQuery */ public function link($query, $condition = array(), $options = array()) { if (is_string($query)) { if (strpos($query, '.') === false) { $name = $query; if ($property = $this->getRepository()->getDescription()->getProperty($name)) { $name = $property->getName(); } AnDomainQueryHelper::addRelationship($this, $name); $link = $this->getLink($name); $config = new KConfig($condition); $config->append(array('type' => $link->type, 'bind_type' => $link->bind_type, 'conditions' => array())); $link->offsetSet('type', $config->type)->offsetSet('bind_type', $config->bind_type); foreach ($config->conditions as $key => $value) { if (is_string($value)) { $value = AnDomainQueryBuilder::getInstance()->parseMethods($this, $value); } elseif ($value instanceof AnDomainResourceColumn) { $value = clone $value; } $link->conditions[$key] = $value; } return $this; } else { $query = AnDomain::getRepository($query)->getQuery(); } } elseif ($query instanceof AnDomainRepositoryAbstract) { $query = $query->getQuery(); } settype($condition, 'array'); $options = new KConfig($options); $options->append(array('type' => 'strong', 'resource' => $query->getRepository()->getResources()->main(), 'as' => $query->getRepository()->getDescription()->getEntityIdentifier()->name)); if (!isset($this->link[$options->as])) { $options->resource->setAlias(KInflector::underscore($options->as)); $destination = $query->getRepository()->getDescription()->getInheritanceColumn(); $link = array('query' => $query, 'resource' => $options->resource, 'resource_name' => $options->resource->getAlias(), 'type' => $options->type, 'conditions' => array(), 'bind_type' => $destination ? clone $destination : null); foreach ($condition as $key => $value) { $link['conditions'][$key] = $value instanceof AnDomainResourceColumn ? clone $value : $value; } $this->link[$options->as] = new KConfig($link); $this->distinct = true; } return $this; }
/** * Get the proxied entity. Since there could many entities proxied. The getObject method will try to * load all the proxied entities of the same type in order to reduce the number of calls * to the storage later on. * * @return AnDomainEntityAbstract */ public function getObject() { //security check if (!isset($this->_object)) { $condition = array($this->_property => $this->_value); $repository = AnDomain::getRepository($this->getIdentifier()); //check if an entity exiting in the repository with $condition if ($data = $repository->find($condition, false)) { $this->_object = $data; return $this->_object; } //now time to fetch the object from the database //but lets grab all the similar entities all together $handle = $this->getIdentifier() . $this->_property; $values = isset(self::$_values[$handle]) ? self::$_values[$handle] : array(); if (empty($values)) { return; } $values = AnHelperArray::unique($values); $query = $repository->getQuery(); AnDomainQueryHelper::applyFilters($query, $this->_relationship->getQueryFilters()); $query->where(array($this->_property => $values)); $entities = $repository->fetchSet($query); //the object must have been fetched with the set //in the previous line //if the object is still not fetched, then the object //doesn't exists in the databse $this->_object = $repository->find($condition, false); if (!$this->_object) { //lets cache the null result to prevent re-fetching //the same result $query = $repository->getQuery()->where($condition)->limit(1); if ($repository->hasBehavior('cachable')) { $repository->emptyCache($query); } $this->_object = false; //if it's a required one-to-one relationship //then instantaite a new entity if the entity doesn't exists if ($this->_relationship->isOneToOne()) { if ($this->_relationship->isRequired()) { $this->_object = $repository->getEntity(array('data' => array($this->_property => $this->_value))); } } } unset(self::$_values[$handle]); } return $this->_object; }