How to use it in your own project? In short words:
- Create class extending eZ\Publish\API\Repository\Values\Content\Query\Criterion\CompositeCriterion. Give it a meaningful name e.g. IsRelatedBlogPost
- Override class constructor. Create your criteria and pass it into the parent constructor call
Example is worth more than thousand words so let’s take a look on the following code snippet:
<?php
namespace App\Query\Search\Query\Criterion;
use eZ\Publish\API\Repository\Values\Content\Content;
use eZ\Publish\API\Repository\Values\Content\Query\Criterion\CompositeCriterion;
use eZ\Publish\API\Repository\Values\Content\Query\Criterion\ContentTypeIdentifier;
use eZ\Publish\API\Repository\Values\Content\Query\Criterion\FieldRelation;
use eZ\Publish\API\Repository\Values\Content\Query\Criterion\LogicalAnd;
use eZ\Publish\API\Repository\Values\Content\Query\Criterion\Operator;
final class IsRelatedBlogPost extends CompositeCriterion
{
public function __construct(Content $content)
{
$criteria = new LogicalAnd([
new ContentTypeIdentifier('blog_post'),
new FieldRelation('relations', Operator::CONTAINS, [$content->id]),
]);
parent::__construct($criteria);
}
}
Now whenever you need to select blog posts related to some content you can use IsRelatedBlogPost criterion:
$query = new Query();
$query->filter = new IsRelatedBlogPost($product);
If you need to narrow down the results to specific subsets e.g. related blog posts published in the last 2 weeks combine IsRelatedBlogPost criterion with DateMetadata criterion using logical “and” operator. You don’t have to repeat yourself.
Also Composite Criterion could help you improve a code readability. Could you tell at first sight what the following code snippet does?
$query = new Query();
$query->filter = new LogicalAnd([
new ParentLocationId($location->parentLocationId),
new LogicalNot(
new LocationId($location->id)
),
]);
$result = $searchService->findLocations($query);
Even if you know the answer, let’s refactor this code by moving filter creation logic to custom criterion based on Composite Criterion.
$query = new Query(); $query->filter = Sibling::fromLocation($location); $result = $searchService->findLocations($query);
Right now it’s a way more readable and self explanatory.