Ezpublish 5.4 сортировать по родительскому полю

Я использую ezpublish Search API, чтобы получить список объектов типа содержимого session, упорядоченных по полю training их родителя (имя поля - code).

Итак, если у меня есть два сеанса S1 (связанный с обучением с кодом T1) и S2 (связанный с обучением с кодом T2), я хочу, чтобы сеанс S1 был указан перед S2 в списке.

$criterions = array (
            new Criterion\ContentTypeIdentifier( 'session' )
        );
$locationQuery = new LocationQuery();
        $locationQuery->query = $criteriaArray;
        $locationQuery->sortClauses = array(
            //new SortClause\Field('session','price'),<- this works
            new SortClause\Field('training','code',Query::SORT_ASC)
           //this second sorClause does not work as code is not a field of session while price is
            );

Возможно решение этой проблемы с использованием собственного запроса mysql, но он не переносится, и некоторые идентификаторы будут жестко запрограммированы.

Мои вопросы: можем ли мы создать своего рода sesssions в соответствии с полем training'code` их родителей?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
145
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

К сожалению, это невозможно со встроенными предложениями сортировки.

Что вы можете сделать, так это получить тренировки, отсортированные по полю code, а затем для каждой тренировочной нагрузки свои сеансы отдельно. Конечно, это не будет эффективно, если в вашей базе данных много объектов контента.

Другой возможностью может быть реализация предложение произвольной сортировки, которая может помочь.

спасибо за ваш ответ, у вас нет ссылки, где на самом деле используется предложение настраиваемой сортировки, которое теоретически не упоминается, как в документах?

zizoujab 09.04.2018 11:28

К сожалению, нет. Я не знаю ни одной реализации настраиваемых предложений сортировки с открытым исходным кодом. Но вы можете проверить код ядра eZ, чтобы увидеть, как реализованы встроенные предложения сортировки, они ничем не отличаются от пользовательских, например: github.com/ezsystems/ezpublish-kernel/tree/master/eZ/Publish‌ /… и github.com/ezsystems/ezpublish-kernel/tree/master/eZ/Publish‌ /…

Edi Modrić 09.04.2018 11:36
Ответ принят как подходящий

Мне удалось заставить его работать благодаря @Edi и моему коллеге по работе.

Два класса, которые нужно создать: Класс поля:

class ParentSortClauseField extends SortClause
{

    public function __construct($typeIdentifier, $fieldIdentifier, $sortDirection = Query::SORT_ASC)
    {
        parent::__construct(
            'field',
            $sortDirection,
            new FieldTarget($typeIdentifier, $fieldIdentifier)
        );
    }

}

Класс обработчика:

class ParentSortClauseHandler extends SortClauseHandler
{

    protected $contentTypeHandler;


    public function __construct(
        DatabaseHandler $dbHandler,
        ContentTypeHandler $contentTypeHandler
    )
    {
        $this->contentTypeHandler = $contentTypeHandler;

        parent::__construct($dbHandler);
    }


    public function accept(SortClause $sortClause)
    {
        return $sortClause instanceof ParentSortClauseField;
    }


    public function applySelect(SelectQuery $query, SortClause $sortClause, $number)
    {
        $query
            ->select(
                $query->alias(
                    $query->expr->not(
                        $query->expr->isNull(
                            $this->dbHandler->quoteColumn(
                                'sort_key_int',
                                $this->getSortTableName($number)
                            )
                        )
                    ),
                    $column1 = $this->getSortColumnName($number . '_null')
                ),
                $query->alias(
                    $query->expr->not(
                        $query->expr->isNull(
                            $this->dbHandler->quoteColumn(
                                'sort_key_string',
                                $this->getSortTableName($number)
                            )
                        )
                    ),
                    $column2 = $this->getSortColumnName($number . '_bis_null')
                ),
                $query->alias(
                    $this->dbHandler->quoteColumn(
                        'sort_key_int',
                        $this->getSortTableName($number)
                    ),
                    $column3 = $this->getSortColumnName($number)
                ),
                $query->alias(
                    $this->dbHandler->quoteColumn(
                        'sort_key_string',
                        $this->getSortTableName($number)
                    ),
                    $column4 = $this->getSortColumnName($number . '_bis')
                )
            );

        return array($column1, $column2, $column3, $column4);
    }

    public function applyJoin(
        SelectQuery $query,
        SortClause $sortClause,
        $number,
        array $languageSettings
    )
    {

        /** @var \eZ\Publish\API\Repository\Values\Content\Query\SortClause\Target\FieldTarget $fieldTarget */

        $fieldTarget = $sortClause->targetData;
        $fieldMap = $this->contentTypeHandler->getSearchableFieldMap();
        if (!isset($fieldMap[$fieldTarget->typeIdentifier][$fieldTarget->fieldIdentifier]['field_definition_id'])) {
            throw new \InvalidArgumentException(
                '$sortClause->targetData',
                'No searchable fields found for the given sort clause target ' .
                "'{$fieldTarget->fieldIdentifier}' on '{$fieldTarget->typeIdentifier}'."
            );
        }
        $fieldDefinitionId = $fieldMap[$fieldTarget->typeIdentifier][$fieldTarget->fieldIdentifier]['field_definition_id'];

        $table = $this->getSortTableName($number);
        $query
            ->innerJoin(
                $query->alias('ezcontentobject_tree', 'parent')
                ,
                $query->expr->eq(
                    $this->dbHandler->quoteColumn('parent_node_id', 'ezcontentobject_tree'),
                    $this->dbHandler->quoteColumn('node_id', 'parent')
                )
            );
        $query
            ->leftJoin(
                $query->alias(
                    $this->dbHandler->quoteTable('ezcontentobject_attribute'),
                    $this->dbHandler->quoteIdentifier($table)
                ),
                $query->expr->lAnd(
                    $query->expr->eq(
                        $query->bindValue($fieldDefinitionId, null, PDO::PARAM_INT),
                        $this->dbHandler->quoteColumn('contentclassattribute_id', $table)
                    ),
                    $query->expr->eq(
                        $this->dbHandler->quoteColumn('contentobject_id', $table),
                        $this->dbHandler->quoteColumn('contentobject_id', 'parent')
                    ),
                    $query->expr->eq(
                        $this->dbHandler->quoteColumn('version', $table),
                        $this->dbHandler->quoteColumn('contentobject_version', 'parent')
                    ),
                    $query->expr->eq(
                        $this->dbHandler->quoteColumn('language_code', $table),
                        $query->bindValue('fre-FR')
                    )
                )
            );
    }
}

Объявите обработчик как сервис:

app.sort_clause_handler.location.parent:
            class: ...\SortClauseHandler\ParentSortClauseHandler
            arguments:
                - @ezpublish.api.storage_engine.legacy.dbhandler
                - @ezpublish.spi.persistence.content_type_handler
            tags:
                - {name: ezpublish.search.legacy.gateway.sort_clause_handler.content}
                - {name: ezpublish.search.legacy.gateway.sort_clause_handler.location}

И чтобы собрать части вместе в cotroller, я сделал следующее:

$sortQuery[] = new ParentSortClauseField('parentclassname', 'field', $sortOrder);

Другие вопросы по теме