简体   繁体   中英

typo3 extbase > Get (unordered) records from repository > But get them in the order of the MULTIPLE sysfolders containing them in Backend

EXAMPLE

SYSFOLDERS IN TYPO3 BACKEND
sysfolder A - tx_myextension_record 1 sysfolder B - tx_myextension_record 2
OUTPUT ON THE WEBSITE
B
- record 2

A
- record 1

PROBLEM

If the editor changes the order of sysfolder A and sysfolder B, the order in the records from the repository should change, too.

SYSFOLDERS IN TYPO3 BACKEND
sysfolder B - tx_myextension_record 2 sysfolder A - tx_myextension_record 1
OUTPUT ON THE WEBSITE
class MyRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
{

    /**
     * pages
     *
     * @var \I\DontKnow\Domain\Repository\WhatToPutHere
     * @inject
     */
    protected $pages = null;

    ...

    public function findStuff() {
        ...

        $query->setOrderings(
            array(
                // This is what I'm looking for
                'pages.pid' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING,
            )
        );

        ...

    }
}

SOLUTION

SOLUTION IN SQL
 SELECT * FROM tx_myextension LEFT JOIN pages ON pages.uid = tx_myextension.pid ORDER by pages.sorting ASC
SOLUTION IN ORM
???

WHAT I DID SO FAR

In the repository of tx_myextension

class MyRepository extends \\TYPO3\\CMS\\Extbase\\Persistence\\Repository { ... public function findStuff() { ... $query->setOrderings( array( // *** This is what I'm looking for *** 'pages.sorting' => \\TYPO3\\CMS\\Extbase\\Persistence\\QueryInterface::ORDER_ASCENDING, // This is not needed: // Sort the area records inside the sysfolders // 'sorting' => \\TYPO3\\CMS\\Extbase\\Persistence\\QueryInterface::ORDER_ASCENDING ) ); ... } }
THIS CAUSES AN ERROR:
 1355142232: The ColumnMap for property "pages" of class "MyExtension\\MyExtension\\Domain\\Model\\Area" is missing.
THE SOLUTION IS USUALLY, TO INJECT THE MISSING REPOSITORY LIKE
class MyRepository extends \\TYPO3\\CMS\\Extbase\\Persistence\\Repository { /** * pages * * @var \\I\\DontKnow\\Domain\\Repository\\WhatToPutHere * @inject */ protected $pages = null; ... public function findStuff() { ... $query->setOrderings( array( // This is what I'm looking for 'pages.pid' => \\TYPO3\\CMS\\Extbase\\Persistence\\QueryInterface::ORDER_ASCENDING, ) ); ... } }
THIS DOESN'T WORK, THE ERROR REMAINS:
 1355142232: The ColumnMap for property "pages" of class "MyExtension\\MyExtension\\Domain\\Model\\Area" is missing.

ENVIRONMENT

  • Typo3 7.6.21
  • Extbase 7.6.22

your solution in SQL is no solution. Because

SELECT * FROM tx_myextension 
ORDER_BY pages.sorting

will result in an SQL error as there is no relation between your table ( tx_myextension ) and the table pages .

For your sorting you need to build up a relation and then add all fields. you should not forget the ordering inside the pages.

SELECT * FROM tx_myextension 
       LEFT JOIN pages ON pages.uid = tx_myextension.pid
       ORDER by pages.sorting ASC, tx_myextension.sorting ASC

When you work with extbase then you have to "forget" about SQL and focus on your domain modeling.

If your domain model doesn't have a property named page (I prefer the singularity name page instead of pages since your model only can be storage on a single page) then any references to this relation in your repository will fail.

So to solve your issue you need to create a page model. In this case you don´t need to define any properties cause you don´t need any. But if you ever is going to need any then just add the properties and there getter methods to this model.

<?php
namespace Uwe\SampleExtension\Domain\Model;

use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;

class Page extends AbstractEntity {}

Then in your other domain model, lets call it \\Uwe\\SampleExtension\\Domain\\Model\\MyModel , you define the page relation. Just add below property and getter method.

/**
 * @var \Uwe\SampleExtension\Domain\Model\Page
 */
protected $page;

public function getPage()
{
    return $this->page;
}

To map \\Uwe\\SampleExtension\\Domain\\Model\\Page to the database table pages and \\Uwe\\SampleExtension\\Domain\\Model\\MyModel s property page to the database field pid we need a little TypoScript. You can store this TypoScript in ext_typoscript_setup.txt in the root of your extension.

config.tx_extbase {
    persistence {
        classes {
            Uwe\SampleExtension\Domain\Model\Page {
                mapping {
                    tableName = pages
                }
            }
            Uwe\SampleExtension\Domain\Model\MyModel {
                mapping {
                    columns {
                       pid.mapOnProperty = page
                    }
                }
            }
        }
    }
}

Now, since we have a relation to the page, it is possible to use this relations properties in your repository \\Uwe\\SampleExtension\\Domain\\Repository\\MyModelRepository . You do not need to define all properties in your model for your repository to use them, only relations to other models.

public function findStuff() {
    ...
    $query->setOrderings(
        array(
            'page.sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
        )
    );
    ...
}

I hope above helps you out.


If you ever needs to use custom queries then you always have the option to build them yourself with $GLOBALS['TYPO3_DB']->exec_* methods or in TYPO3 version 8.5 and up the better query builder \\TYPO3\\CMS\\Core\\Database\\Query\\QueryBuilder .

After you have made your query at it has returned an array of rows then you can use the data mapper \\TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Mapper\\DataMapper s map method to retrieve your models and there relations.

Please note that doing this manually might has some site effects and that there might be a lot of things that you will have to take care of manually! - I always tries to stick to the repository default options.

As I Understand your Problem, you have records of your domain model stored on multiple pages/sysfolders. and want to display seperated by the source Page.

i would go a rather simple approach:

in your "plugin" you select multiple source Pages. the controller then interates over every source pages. and fetches records of your domain model with PidRestrictions.

this way your domain logic is a lot simpler. (but exbase performs multiple, database queries) . only optimize if you have a real performance problem. don't make thinks more complex if they don't have to be.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM