typo3 extbase > 从存储库获取(无序)记录 > 但是按照后端包含它们的多个 sysfolders 的顺序获取它们
typo3 extbase > Get (unordered) records from repository > But get them in the order of the MULTIPLE sysfolders containing them in Backend
例子
TYPO3 后端中的系统文件夹
sysfolder A
- tx_myextension_record 1
sysfolder B
- tx_myextension_record 2
网站上的输出
A
- record 1
B
- record 2
问题
如果小编改变了sysfolder A和sysfolder B的顺序,
存储库中记录的顺序也应该更改。
TYPO3 后端中的系统文件夹
sysfolder B
- tx_myextension_record 2
sysfolder A
- tx_myextension_record 1
网站上的输出
B
- record 2
A
- record 1
解决方案
SQL 中的解决方案
SELECT * FROM tx_myextension
LEFT JOIN pages ON pages.uid = tx_myextension.pid
ORDER by pages.sorting ASC
ORM 中的解决方案
???
到目前为止我做了什么
在 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
)
);
...
}
}
这会导致错误:
1355142232:
The ColumnMap for property "pages"
of class "MyExtension\MyExtension\Domain\Model\Area"
is missing.
解决方案通常是像这样注入丢失的存储库
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,
)
);
...
}
}
这不起作用,错误仍然存在:
1355142232:
The ColumnMap for property "pages"
of class "MyExtension\MyExtension\Domain\Model\Area"
is missing.
环境
- 错别字 7.6.21
- Extbase 7.6.22
您在 SQL 中的 解决方案 不是解决方案。因为
SELECT * FROM tx_myextension
ORDER_BY pages.sorting
将导致 SQL 错误,因为您的 table (tx_myextension
) 与 table pages
.[=14 之间没有关系=]
为了排序,您需要建立一个关系,然后添加所有字段。你不应该忘记页面内的顺序。
SELECT * FROM tx_myextension
LEFT JOIN pages ON pages.uid = tx_myextension.pid
ORDER by pages.sorting ASC, tx_myextension.sorting ASC
当您使用 extbase 时,您必须 "forget" 关于 SQL 并专注于您的域建模。
如果您的域模型没有名为 page
的 属性(我更喜欢奇点名称 page
而不是 pages
,因为您的模型只能存储在单个页面上)然后在您的存储库中对此关系的任何引用都将失败。
因此,要解决您的问题,您需要创建一个页面模型。在这种情况下,您不需要定义任何属性,因为您不需要任何属性。但是,如果您需要任何东西,只需将属性和 getter 方法添加到该模型即可。
<?php
namespace Uwe\SampleExtension\Domain\Model;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
class Page extends AbstractEntity {}
然后在您的其他域模型中,我们称之为 \Uwe\SampleExtension\Domain\Model\MyModel
,您定义页面关系。只需在 属性 和 getter 方法下方添加。
/**
* @var \Uwe\SampleExtension\Domain\Model\Page
*/
protected $page;
public function getPage()
{
return $this->page;
}
将\Uwe\SampleExtension\Domain\Model\Page
映射到数据库tablepages
和\Uwe\SampleExtension\Domain\Model\MyModel
s属性page
到数据库字段pid
我们需要一些 TypoScript。您可以将此 TypoScript 存储在扩展根目录的 ext_typoscript_setup.txt
中。
config.tx_extbase {
persistence {
classes {
Uwe\SampleExtension\Domain\Model\Page {
mapping {
tableName = pages
}
}
Uwe\SampleExtension\Domain\Model\MyModel {
mapping {
columns {
pid.mapOnProperty = page
}
}
}
}
}
}
现在,由于我们与页面有关系,因此可以在您的存储库中使用此关系属性 \Uwe\SampleExtension\Domain\Repository\MyModelRepository
。您无需为存储库定义模型中的所有属性即可使用它们,只需定义与其他模型的关系即可。
public function findStuff() {
...
$query->setOrderings(
array(
'page.sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
)
);
...
}
希望以上对你有所帮助。
如果您需要使用自定义查询,那么您始终可以选择使用 $GLOBALS['TYPO3_DB']->exec_*
方法或在 TYPO3 8.5 及更高版本中更好的查询构建器 \TYPO3\CMS\Core\Database\Query\QueryBuilder
.
在您进行查询后,它返回了一个行数组,然后您可以使用数据映射器 \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper
s map
方法来检索您的模型和相关关系。
请注意,手动执行此操作可能会对网站产生一些影响,并且可能有很多事情需要您手动处理! - 我总是尽量坚持使用存储库的默认选项。
据我了解您的问题,
您将域模型的记录存储在多个 pages/sysfolders 上。
并希望按源页面分隔显示。
我会采用一种相当简单的方法:
在您的 "plugin" 中您 select 多个源页面。然后控制器交互
在每个源页面上。并使用 PidRestrictions 获取域模型的记录。
这样你的域逻辑就简单多了。 (但 exbase 执行多个数据库查询)。只有在遇到真正的性能问题时才进行优化。如果没有必要,不要让想法变得更复杂。
例子
TYPO3 后端中的系统文件夹sysfolder A
- tx_myextension_record 1
sysfolder B
- tx_myextension_record 2
网站上的输出
A
- record 1
B
- record 2
问题
如果小编改变了sysfolder A和sysfolder B的顺序, 存储库中记录的顺序也应该更改。
TYPO3 后端中的系统文件夹sysfolder B
- tx_myextension_record 2
sysfolder A
- tx_myextension_record 1
网站上的输出
B
- record 2
A
- record 1
解决方案
SQL 中的解决方案 SELECT * FROM tx_myextension
LEFT JOIN pages ON pages.uid = tx_myextension.pid
ORDER by pages.sorting ASC
ORM 中的解决方案
???
到目前为止我做了什么
在 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
)
);
...
}
}
这会导致错误:
1355142232:
The ColumnMap for property "pages"
of class "MyExtension\MyExtension\Domain\Model\Area"
is missing.
解决方案通常是像这样注入丢失的存储库
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,
)
);
...
}
}
这不起作用,错误仍然存在:
1355142232:
The ColumnMap for property "pages"
of class "MyExtension\MyExtension\Domain\Model\Area"
is missing.
环境
- 错别字 7.6.21
- Extbase 7.6.22
您在 SQL 中的 解决方案 不是解决方案。因为
SELECT * FROM tx_myextension
ORDER_BY pages.sorting
将导致 SQL 错误,因为您的 table (tx_myextension
) 与 table pages
.[=14 之间没有关系=]
为了排序,您需要建立一个关系,然后添加所有字段。你不应该忘记页面内的顺序。
SELECT * FROM tx_myextension
LEFT JOIN pages ON pages.uid = tx_myextension.pid
ORDER by pages.sorting ASC, tx_myextension.sorting ASC
当您使用 extbase 时,您必须 "forget" 关于 SQL 并专注于您的域建模。
如果您的域模型没有名为 page
的 属性(我更喜欢奇点名称 page
而不是 pages
,因为您的模型只能存储在单个页面上)然后在您的存储库中对此关系的任何引用都将失败。
因此,要解决您的问题,您需要创建一个页面模型。在这种情况下,您不需要定义任何属性,因为您不需要任何属性。但是,如果您需要任何东西,只需将属性和 getter 方法添加到该模型即可。
<?php
namespace Uwe\SampleExtension\Domain\Model;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
class Page extends AbstractEntity {}
然后在您的其他域模型中,我们称之为 \Uwe\SampleExtension\Domain\Model\MyModel
,您定义页面关系。只需在 属性 和 getter 方法下方添加。
/**
* @var \Uwe\SampleExtension\Domain\Model\Page
*/
protected $page;
public function getPage()
{
return $this->page;
}
将\Uwe\SampleExtension\Domain\Model\Page
映射到数据库tablepages
和\Uwe\SampleExtension\Domain\Model\MyModel
s属性page
到数据库字段pid
我们需要一些 TypoScript。您可以将此 TypoScript 存储在扩展根目录的 ext_typoscript_setup.txt
中。
config.tx_extbase {
persistence {
classes {
Uwe\SampleExtension\Domain\Model\Page {
mapping {
tableName = pages
}
}
Uwe\SampleExtension\Domain\Model\MyModel {
mapping {
columns {
pid.mapOnProperty = page
}
}
}
}
}
}
现在,由于我们与页面有关系,因此可以在您的存储库中使用此关系属性 \Uwe\SampleExtension\Domain\Repository\MyModelRepository
。您无需为存储库定义模型中的所有属性即可使用它们,只需定义与其他模型的关系即可。
public function findStuff() {
...
$query->setOrderings(
array(
'page.sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
)
);
...
}
希望以上对你有所帮助。
如果您需要使用自定义查询,那么您始终可以选择使用 $GLOBALS['TYPO3_DB']->exec_*
方法或在 TYPO3 8.5 及更高版本中更好的查询构建器 \TYPO3\CMS\Core\Database\Query\QueryBuilder
.
在您进行查询后,它返回了一个行数组,然后您可以使用数据映射器 \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper
s map
方法来检索您的模型和相关关系。
请注意,手动执行此操作可能会对网站产生一些影响,并且可能有很多事情需要您手动处理! - 我总是尽量坚持使用存储库的默认选项。
据我了解您的问题, 您将域模型的记录存储在多个 pages/sysfolders 上。 并希望按源页面分隔显示。
我会采用一种相当简单的方法:
在您的 "plugin" 中您 select 多个源页面。然后控制器交互 在每个源页面上。并使用 PidRestrictions 获取域模型的记录。
这样你的域逻辑就简单多了。 (但 exbase 执行多个数据库查询)。只有在遇到真正的性能问题时才进行优化。如果没有必要,不要让想法变得更复杂。