Search code examples
typo3extbasetypo3-9.x

TYPO3 Extbase sort foreign Model (1:n)


I got a Seminar and an Event model. The Seminars have a 1:n relation with the Events. Now when I select all Seminars with $this->seminarRepository->findAll(), I want the Seminars sorted by start_date.

I tried changing the TCAs foreign_sortby and foreign_default_sortby, I also tried adding the sorting directly into the given repository $query->setOrderings(['events.start_date' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING]);. None of this did work.

Seminar Model

<?php
    namespace Vendor\Myext\Domain\Model;

    use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;

    class Seminar extends AbstractEntity
    {
        /**
         * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Vendor\Myext\Domain\Model\Event>
         */
        protected $events;

Seminar TCA

'events'           => [
    'exclude' => 1,
    'label'   => 'Veranstaltungen',
    'config'  => [
            'type'                => 'inline',
            'foreign_table'       => 'tx_myext_domain_model_event',
            'foreign_field'       => 'seminar',
            'foreign_default_sortby'      => 'ORDER BY tx_myext_domain_model_event.start_date ASC',
    ],
],

Solution

  • Well it seems that foreign_default_sortby was not implemented for extbase yet: https://review.typo3.org/c/Packages/TYPO3.CMS/+/61487

    Since my first solution did not work properly (see comments for details), I am now sorting the array of events via PHP usort:

    usort($events, function ($a, $b) {
        if ($a->getStartDate() == $b->getStartDate()) {
            return 0;
        }
        return ($a->getStartDate() > $b->getStartDate()) ? +1 : -1;
    });
    

    Old no working answer

    My temporary solution is to use foreign_sortby, but only for the frontend, since foreign_default_sortby works fine in the backend.

    Seminar TCA

    $seminarTca = [
    
        // More TCA stuff; missing some array keys in this code
    
        'events'           => [
                'exclude' => 1,
                'label'   => 'Veranstaltungen',
                'config'  => [
                        'type'                   => 'inline',
                        'foreign_table'          => 'tx_myext_domain_model_event',
                        'foreign_field'          => 'seminar',
                        'foreign_default_sortby' => 'start_date',
                        'maxitems'               => 999,
                        'appearance'             => [
                                'collapseAll'           => true,
                                'expandSingle'          => true,
                                'newRecordLinkAddTitle' => true,
                                'levelLinksPosition'    => 'both',
                                'useSortable '          => false,
                        ],
                ],
        ],
    ];
    
    if (TYPO3_MODE === 'FE') {
        $seminarTca['columns']['events']['config']['foreign_sortby'] = 'start_date';
    }
    
    return $seminarTca;