TYPO3 extbase和IRRE:使用"foreign_selector"添加现有记录 [英] TYPO3 extbase & IRRE: add existing records with 'foreign_selector'

查看:60
本文介绍了TYPO3 extbase和IRRE:使用"foreign_selector"添加现有记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用包含1:1和1:n关系的extbase扩展构建器启动了"扩展.它会自动将字段类型设置为"inline",并在后端显示一个漂亮的IRRE UI.

I "kickstarted" an extension with the extbase extension builder that contains some 1:1 and 1:n relations. It automatically set the field types to 'inline' and displayed a nice IRRE UI in the backend.

但是默认情况下,无法选择现有记录,而只能创建新记录.

But by default, there is no way to select an existing record, just create new ones.

我找到了有关如何使用"foreign_selector"实现此目标的各种解释,但所有这些解释都很粗略.该功能本身应该可以正常工作,请参见 https://forge.typo3.org/issues/43239

I found various explanations on how to achieve this with 'foreign_selector', but all of them very sketchy. The feature itself should be working, see https://forge.typo3.org/issues/43239

有人可以引导我完成这个过程,还是可以在TER中指出一个可行的例子?一旦可以使用,我可以根据示例创建分步教程.

Can someone walk me through this or point to a working example in the TER? I could create a step-by-step tutorial from the example, once I get it to work.

PS extension_builder生成的字段的TCA配置:

PS The field's TCA config as generated by extension_builder:

'myfield' => array(
    'exclude' => 1,
    'label' => 'LLL:EXT:myextension/Resources/Private/Language/locallang_db.xlf:tx_myextension_domain_model_myitem.myfield',
    'config' => array(
        'type' => 'inline',
        'foreign_table' => 'tx_myextension_domain_model_myfield',
        'foreign_field' => 'myitem',
        'maxitems'      => 9999,
        'appearance' => array(
            'collapseAll' => 0,
            'levelLinksPosition' => 'top',
            'showSynchronizationLink' => 1,
            'showPossibleLocalizationRecords' => 1,
            'showAllLocalizationLink' => 1
        ),
    ),
),

推荐答案

主要问题是类型为1:n的IRRE关系的工作方式如下:子记录包含其父记录的uid.因此,您的表tx_myext_domain_model_city保留了(虚构的)tx_myext_domain_model_address的UID.

The main problem is that IRRE relations of type 1:n work like this: A child record holds the uid of its parent. So your table tx_myext_domain_model_city holds the UID of your (imaginary) tx_myext_domain_model_address.

因此,在默认配置下,您将只能选择一个城市,因此无法多次选择城市.

Therefore with the default configuration you will not be able to select a city multiple times as it can only have exactly one parent.

因此,您需要为此字段使用关系表.该表需要同时包含地址(uid_address)和城市(uid_city)的uid字段:

So you will need to use a relation table for this field. This table needs to contain a uid field for both the address (uid_address) and the city (uid_city):

CREATE TABLE tx_irreforeignselectordemo_address_city_mm (

    uid int(11) NOT NULL auto_increment,
    pid int(11) DEFAULT '0' NOT NULL,
    uid_address int(11) unsigned DEFAULT '0' NOT NULL,
    uid_city int(11) unsigned DEFAULT '0' NOT NULL,
    sorting int(11) unsigned DEFAULT '0' NOT NULL,

    PRIMARY KEY (uid),
    KEY parent (pid)
);

并且这些字段需要具有TCA配置(而表本身可以隐藏):

And it needs to have a TCA configuration for these fields (while the table itself can be hidden):

return array(
    'ctrl'      => array(
        'title'     => 'Relation table',
        'hideTable' => TRUE,
        'sortby'    => 'sorting',
    ),
    'columns'   => array(
        'uid_address' => Array(
            'label'  => 'Address',
            'config' => Array(
                'type'          => 'select',
                'foreign_table' => 'tx_irreforeignselectordemo_domain_model_address',
                'size'          => 1,
                'minitems'      => 0,
                'maxitems'      => 1,
            ),
        ),
        'uid_city'   => Array(
            'label'  => 'City',
            'config' => Array(
                'type'                => 'select',
                'foreign_table'       => 'tx_irreforeignselectordemo_domain_model_city',
                'foreign_table_where' => ' AND sys_language_uid IN (0,-1)',
                'size'                => 1,
                'minitems'            => 0,
                'maxitems'            => 1,
            ),
        ),
    ),
    'types'     => array(
        '0' => array('showitem' => 'uid_address,uid_city')
    ),
    'palettes'  => array()
);

然后,您可以配置地址的TCA,使其成为IRRE字段:

You can then configure the TCA of your address to make it an IRRE field:

'type' => 'inline',
'foreign_table' => 'tx_yourext_address_city_mm',
'foreign_field' => 'uid_address',
'foreign_label' => 'uid_city',
'foreign_selector' => 'uid_city',
'foreign_unique' => 'uid_city',
'foreign_sortby' => 'sorting',

请注意,foreign_unique告诉TYPO3一个城市只能选择一次.

Note that foreign_unique tells TYPO3 that a city can only selected once.

您需要从另一边(从您的城市TCA)定义关系:

And you need to define the relation from the other side (from your city TCA):

    'addresses' => array(
        'exclude' => 1,
        'label'   => 'Addresses',
        'config'  => array(
            'type' => 'inline',
            'foreign_table' => 'tx_irreforeignselectordemo_address_city_mm',
            'foreign_field' => 'uid_city',
            'foreign_label' => 'uid_address',
        ),
    ),

配置完成后,您将可以在后端中使用它.

Once your configuration is complete, you will be able to use this in the Backend.

由于这是非标准的MM关系,因此默认情况下,Extbase将无法对其进行处理.但是我们可以将其与TYPO3 6中引入的sys_file_reference表进行比较.因此,我们为CityRelation构建了一个具有属性"address"和"city"的Extbase模型,并将该模型映射到我们的mm表:

Since this is a non-standard MM relation, Extbase will not be able to deal with it by default. But we can compare this to the sys_file_reference table that was introduced in TYPO3 6. So we build an Extbase model for the CityRelation with the properties "address" and "city" and map this model to our mm table:

config.tx_extbase.persistence.classes {
    Visol\Irreforeignselectordemo\Domain\Model\CityRelation {
        mapping {
            tableName = tx_irreforeignselectordemo_address_city_mm
            columns {
                uid_address.mapOnProperty = address
                uid_city.mapOnProperty = city
            }
        }
    }
}

现在,在我们的地址模型中,我们将城市(或多个城市-您允许多个选择)定义为CityRelation类型的ObjectStorage:

Now in our address model, we define the city (or cities - of you allow more than one choice) as ObjectStorage of type CityRelation:

/**
 * Cities
 *
 * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Visol\Irreforeignselectordemo\Domain\Model\CityRelation>
 */
protected $cities = NULL;

我们现在有了一个城市"属性,其中包含对所有选定城市的引用.您可以遍历它们并使用它们:

We now have a property "cities" that contains the references to all selected cities. You can iterate through them and use them:

<f:for each="{address.cities}" as="cityRelation">
  <li>{cityRelation.city.name}</li>
</f:for>

由于我无法为此找到一个完整的演示,并且对此主题感兴趣,因此我创建了一个演示扩展,该扩展实现了我刚刚描述的功能-基于Core和两个与该主题相关的扩展: > https://github.com/lorenzulrich/irreforeignselectordemo

Since I couldn't find an all-in-one demo for this and was interested in the topic, I created a demo extension that does what I just described - based on the Core and two extensions that deal with the topic: https://github.com/lorenzulrich/irreforeignselectordemo

无论如何,该解决方案是一种m:n的方法(因为出于上述原因,1:n无效),所以我决定使用城市"而不是城市".虽然这对于选择城市可能没有意义(如您的帖子所建议),但对于其他机会则可能有意义.随意用"city"替换"citys",并将内联配置中的maxItems设置为1-这样您就可以得到1:n了.

The solution is an m:n approach anyway (because 1:n wouldn't work for the reasons stated above) so I decided to use "cities" instead of "city". While this might not make sense for selecting a city (as suggested by your post), it might make sense for other opportunities. Feel free to replace "cities" by "city" and set maxItems in the inline configuration to one - then you have kind of an 1:n.

这篇关于TYPO3 extbase和IRRE:使用"foreign_selector"添加现有记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆