TYPO3 Extbase: How to sort child objects

2020-07-18 04:01发布

问题:

I have an Extbase Model Article and a 1:n Relation Product. In Article TCA i have an inline field configuered. In my Article Template I want to display all related Products. These are oredered by uid. How can i change the ordering of the child objects to the field sorting to be able to manually sort them. ( In the backend form the sorting is possible, only diplaying them sorted by field sorting is not possible )

thanks, Lukas

回答1:

Here's how I do it, in the repository class:

class ItemRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {

    /**
     * http://www.typo3.net/forum/thematik/zeige/thema/114160/?show=1
     * Returns items of this repository, sorted by sorting
     *
     * @return array An array of objects, empty if no objects found
     * @api
     */

    public function findAll() {
        $orderings = array(
            'sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
        );

        $query = $this->createQuery();
        $query->setOrderings($orderings);

        $query->getQuerySettings()->setRespectSysLanguage(FALSE);
        $query->getQuerySettings()->setSysLanguageUid(0);

        $result = $query->execute();
        return $result;
    }

}


回答2:

The easiest way to sort child elements in a object storage is to manipulate the TCA.

Example:

$TCA['tx_myext_domain_model_ordering'] = array(
...
'columns' => array(
    'services' => array(
        'exclude' => 0,
        'label' => 'LLL:EXT:myext/Resources/Private/Language/locallang_db.xml:tx_myext_domain_model_ordering.services',
        'config' => array(
            'type' => 'inline',
            'foreign_table' => 'tx_myext_domain_model_service',
            'foreign_field' => 'ordering',
            'foreign_sortby' => 'sorting',
            'maxitems'      => 9999,
            'appearance' => array(
                'collapseAll' => 0,
                'levelLinksPosition' => 'top',
                'showSynchronizationLink' => 1,
                'showPossibleLocalizationRecords' => 1,
                'showAllLocalizationLink' => 1
            ),
        ),
    ),
),
...
);

With the filed 'foreign_sortby' => 'sorting', you can easily say on which field the childs should be ordered.



回答3:

Using the dot notation you can sort by properties of subobjects:

$query->setOrderings(array(
    'sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
    'subobject.sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
));

edit: Caught me off guard, I think I read your question wrong. Yes, this sorts by child objet, but it applies that to the parent object, of course. If you want to sort the child objects themselves, you have to set that sorting in the repository of the child object, as @Urs explained.



回答4:

I dont't really like the idea of doing basic sorting inside the view (mvc).

The Downside of most Database abstraction Layers ist, that you are quite often restricted to either mixup mvc or have a (sometimes slightly) lower performance.

I am at the same point right now. I am thinking about retrieving the parents (with their children attached). Then go into every single parent and get children for this parent in a sorted way.

public function findAllSorted() {
    $query = $this->createQuery();
    /* sort parents */
    $query->setOrderings(array('name' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING));
    $parents = $query->execute();
    foreach($parents as $parent){
        /* get children for every parent */
        $children = $this->getChildrenSorted($parent);
        // add children to parent TBD

    }
    /* Debug output */
    \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($parents);
}

public function getChildrenSorted(\mynamespace\ $parent) {
    /* Generate an object manager and use dependency injection to retrieve children repository */
    $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('\TYPO3\CMS\Extbase\Object\ObjectManager');
    $childrenRepository= $objectManager->get('MYNAME\Extname\Domain\Repository\Repository');
    $children = $versionRepository->findSortedByName($parent);
    return $children;
}

The function findSortedByName inside the children repos is using

$query->matching($query->equals('parent', $parent));

to retrieve only children of this parent and

$query->setOrderings(array('name' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING));

to be able to give them back in an ordered way.

Warning: Depending on the size and quantity of all retrieved objects, this way might arise a huge performance issue.



标签: typo3 extbase