/** * Relation fields can allow filters on the relations fetched. For now this is limited * to the id field because of the possible complexity of fetching and filtering * all the related data. * * For example the following queries: * 'pages', {'relationkey'=>'1'} * 'pages', {'relationkey'=>'1 || 2 || 3'}. * * Because the search is actually on the join table, we replace the * expression to filter the join side rather than on the main side. * * @param QueryInterface $query * @param ClassMetadata $metadata * * @return void */ public function query(QueryInterface $query, ClassMetadata $metadata) { $field = $this->mapping['fieldname']; foreach ($query->getFilters() as $filter) { if ($filter->getKey() == $field) { $this->rewriteQueryFilterParameters($filter, $query, $field, 'to_id'); } } }
/** * @param QueryInterface $query * @param string $order */ public function __invoke(QueryInterface $query, $order) { if (strpos($order, '-') === 0) { $direction = 'DESC'; $order = substr($order, 1); } else { $direction = null; } $query->getQueryBuilder()->orderBy($order, $direction); }
/** * Date fields perform substitution on the parameters passed in to query. * To handle this we pass every parameter through `strtotime()` to make * sure that it is a valid search. * * @param QueryInterface $query * @param ClassMetadata $metadata * * @return void */ public function query(QueryInterface $query, ClassMetadata $metadata) { $field = $this->mapping['fieldname']; $dateParams = $query->getWhereParametersFor($field); foreach ($dateParams as $key => $val) { $time = strtotime($val); if (!$time) { throw new QueryParseException('Unable to query $field = $val, not a valid date search', 1); } $replacement = date('Y-m-d H:i:s', $time); $query->setWhereParameter($key, $replacement); } }
/** * @param QueryInterface $query * @param string $order */ public function __invoke(QueryInterface $query, $order) { $separatedOrders = $this->getOrderBys($order); foreach ($separatedOrders as $order) { $order = trim($order); if (strpos($order, '-') === 0) { $direction = 'DESC'; $order = substr($order, 1); } else { $direction = null; } $query->getQueryBuilder()->addOrderBy($order, $direction); } }
/** * Relation fields can allow filters on the relations fetched. For now this is limited * to the id field because of the possible complexity of fetching and filtering * all the related data. * * For example the following queries: * 'pages', {'relationkey'=>'1'} * 'pages', {'relationkey'=>'1 || 2 || 3'}. * * Because the search is actually on the join table, we replace the * expression to filter the join side rather than on the main side. * * @param QueryInterface $query * @param ClassMetadata $metadata */ public function query(QueryInterface $query, ClassMetadata $metadata) { $field = $this->mapping['fieldname']; foreach ($query->getFilters() as $filter) { if ($filter->getKey() == $field) { // This gets the method name, one of andX() / orX() depending on type of expression $method = strtolower($filter->getExpressionObject()->getType()) . 'X'; $newExpr = $query->getQueryBuilder()->expr()->{$method}(); foreach ($filter->getParameters() as $k => $v) { $newExpr->add("{$field}.to_id = :{$k}"); } $filter->setExpression($newExpr); } } }
/** This method does an in-place modification of a generic contenttype.field query to the format actually used * in the raw sql category. For instance a simple query might say `entries.tags = 'movies'` but now we are in the * context of entries the actual SQL fragment needs to be `tags.slug = 'movies'`. We don't know this until we * drill down to the individual field types so this rewrites the SQL fragment just before the query gets sent. * * Note, reflection is used to achieve this, it is not ideal, but the CompositeExpression shipped with DBAL chooses * to keep the query parts as private and only allow access to the final computed string. * * @param Filter $filter * @param QueryInterface $query * @param $field * @param $column */ protected function rewriteQueryFilterParameters(Filter $filter, QueryInterface $query, $field, $column) { $originalExpression = $filter->getExpressionObject(); $reflected = new ReflectionProperty(CompositeExpression::class, 'parts'); $reflected->setAccessible(true); $originalParts = $reflected->getValue($originalExpression); foreach ($originalParts as &$part) { $part = str_replace($query->getContenttype() . "." . $field, $field . "." . $column, $part); } $reflected->setValue($originalExpression, $originalParts); $filter->setExpression($originalExpression); }
/** * @param QueryInterface $query * @param int $limit */ public function __invoke(QueryInterface $query, $limit) { $query->getQueryBuilder()->setMaxResults($limit); }
/** * @param QueryInterface $query */ public function __invoke(QueryInterface $query) { $query->getQueryBuilder()->setMaxResults(1); $query->setSingleFetchMode(true); }