- Documentation >
- Guide >
- Content rendering >
- Queries and controllers >
- Create custom Query type
Create a custom Query type
If you need to perform a more complex query than the built-in Query types allow,
you can create a custom Query type.
The following example shows how to create a custom Query type
that renders the latest Content items of selected Types.
First, add the following LatestContentQueryType.php
file to src/QueryType
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 | <?php declare(strict_types=1);
namespace App\QueryType;
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
use eZ\Publish\API\Repository\Values\Content\Query;
use eZ\Publish\Core\QueryType\QueryType;
class LatestContentQueryType implements QueryType
{
public static function getName()
{
return 'LatestContent';
}
public function getQuery(array $parameters = [])
{
$criteria[] = new Query\Criterion\Visibility(Query\Criterion\Visibility::VISIBLE);
if (isset($parameters['contentType'])) {
$criteria[] = new Query\Criterion\ContentTypeIdentifier($parameters['contentType']);
}
return new LocationQuery([
'filter' => new Query\Criterion\LogicalAnd($criteria),
'sortClauses' => [
new Query\SortClause\DatePublished(Query::SORT_DESC),
],
'limit' => isset($parameters['limit']) ? $parameters['limit'] : 10,
]);
}
public function getSupportedParameters()
{
return ['contentType', 'limit'];
}
}
|
Tip
When the custom Query type is in the App
namespace, like in the example above, it is registered automatically as a service.
Otherwise, register it with the ezplatform.query_type
service tag.
The name defined in getName()
is the one you use to identify the Query type in content view configuration.
| public static function getName()
{
return 'LatestContent';
}
|
Caution
Query type name must be unique.
The getQuery()
method constructs the query based on Search Criteria and Sort Clauses.
See Content search for more information about queries
and Search reference for a reference of available Criteria and Sort Clauses.
The getSupportedParameters()
method provides the parameters you can set in content view configuration.
| public function getSupportedParameters()
{
return ['contentType', 'limit'];
}
|
Then, in the content view configuration, indicate that the content view should use the custom Query type:
1
2
3
4
5
6
7
8
9
10
11
12
13 | content_view:
full:
latest:
controller: ez_query::locationQueryAction
template: '@ezdesign/full/latest.html.twig'
match:
Identifier\ContentType: "latest"
params:
query:
query_type: LatestContent
parameters:
contentType: [article, blog_post]
assign_results_to: latest
|
Options resolver-based Query type
Additionally, your custom Query type can extend the OptionsResolverBasedQueryType
abstract class.
This gives you more flexibility when defining parameters.
In the configureOptions()
method you can define the allowed parameters, their types and default values.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 | <?php declare(strict_types=1);
namespace App\QueryType;
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
use eZ\Publish\API\Repository\Values\Content\Query;
use eZ\Publish\Core\QueryType\OptionsResolverBasedQueryType;
use eZ\Publish\Core\QueryType\QueryType;
use Symfony\Component\OptionsResolver\OptionsResolver;
class OptionsBasedLatestContentQueryType extends OptionsResolverBasedQueryType implements QueryType
{
public static function getName()
{
return 'OptionsLatestContent';
}
protected function doGetQuery(array $parameters)
{
$criteria[] = new Query\Criterion\Visibility(Query\Criterion\Visibility::VISIBLE);
if (isset($parameters['contentType'])) {
$criteria[] = new Query\Criterion\ContentTypeIdentifier($parameters['contentType']);
}
return new LocationQuery([
'filter' => new Query\Criterion\LogicalAnd($criteria),
'sortClauses' => [
new Query\SortClause\DatePublished(Query::SORT_DESC),
],
'limit' => isset($parameters['limit']) ? $parameters['limit'] : 10,
]);
}
protected function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefined(['contentType', 'limit']);
$resolver->setAllowedTypes('contentType', 'array');
$resolver->setAllowedTypes('limit', 'int');
$resolver->setDefault('limit', 10);
}
}
|
Note
In contrast with the previous example, a Query type that extends OptionsResolverBasedQueryType
must implement the doGetQuery()
method instead of getQuery()
.