/** * @param string $condition * @param string $direction * @return Closure */ public static function createSorter($condition, $direction) { list($chain, $operator) = ConditionParser::parseCondition($condition); $getter = function ($element, $chain) use(&$getter) { $key = array_shift($chain); $element = $element->{$key}; if ($element instanceof IRelationshipCollection) { throw new InvalidStateException('You can not sort by hasMany relationship.'); } if (!$chain) { return $element; } else { return $getter($element, $chain); } }; $direction = $direction === ICollection::ASC ? 1 : -1; return function ($a, $b) use($getter, $chain, $direction) { $_a = $getter($a, $chain); $_b = $getter($b, $chain); if (is_int($_a)) { return $direction * ($_a < $_b ? -1 : 1); } else { return $direction * strcmp((string) $_a, (string) $_b); } }; }
/** * Transforms orm condition to sql expression for Nette Database. * @param string $condition * @param mixed $value * @return string */ public function parse($condition, $value, NetteSqlBuilder $builder) { list($chain, $operator) = CollectionConditionParser::parseCondition($condition); if ($operator === CollectionConditionParser::OPERATOR_EQUAL) { $operator = ''; } elseif ($operator === CollectionConditionParser::OPERATOR_NOT_EQUAL) { if (is_array($value) || $value === NULL || $value instanceof Traversable) { $operator = ' NOT'; } else { $operator = ' !='; } } else { $operator = " {$operator}"; } if (count($chain) === 1) { return $builder->getTableName() . '.' . $this->mapper->getStorageReflection()->convertEntityToStorageKey($chain[0]) . $operator; } return $this->parseCondition($chain, $this->mapper) . $operator; }