在extbase扩展中,如何从调度程序任务访问持久层? [英] In an extbase extension, how to access the persistence layer from a scheduler task?

查看:106
本文介绍了在extbase扩展中,如何从调度程序任务访问持久层?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在标题中听起来有点学术性实际上很简单:我已经设置了TYPO3 6.1 extbase扩展,该扩展已配备了调度程序任务.该任务应导入CSV文件并将其保存到扩展程序的数据库字段中.

What sounds a bit academic in the title is actually quite straightforward: I have set up a TYPO3 6.1 extbase extension that I've equipped with a scheduler task. The task is supposed to import a CSV file and save it into the extension's database fields.

但是如何告诉调度程序任务使用扩展的模型等,并将接收到的数据保存到持久层中?

But how do I tell the scheduler task to use the extension's model etc. and save the received data into the persistence layer?

我已经看到类似问题的答案:在调度程序任务中执行存储库功能,我认为这是正确的方法,但我认为需要一个完整的示例来开始理解依赖项注入的工作原理.

I've seen this answer to a similar question: Execute repository functions in scheduler task and I think it points the right way, but I think need a full example to start understanding how the dependency injection works.

推荐答案

首先,您必须考虑性能方面:

First you have to consider the aspect of performance:

如果要插入大量数据,则不应将Extbase持久性用于此类任务.因为这样做会为您要插入的每一行生成一个对象,并立即将其持久保存.这非常慢,而且占用的内存很大.

If you want to insert a big amount of data, you should not use the Extbase persistence for such a task. Because if you do so, it will generate an object for each row you want to insert and persist it immediately. This is quite slow and has a big memory footprint.

如果您没有太多数据或拆分了作业(例如,每个调度程序运行执行100个导入作业),请使用Extbase持久性.

If you don't have much data or you split the jobs (e.g. perform 100 import jobs per scheduler run), then use the Extbase persistence.

您可以在CommandController上下文中同时使用这两者,并且由于CommandControllers可以直接设置,因此您应该选择它们而不是自己的Scheduler任务.

You can have both in CommandController context, and since CommandControllers are straight-forward to set up, you should go for them instead of an own Scheduler task.

使用Extbase持久性

在CommandController中,注入您的存储库:

In the CommandController, inject your repository:

/**
 * myRepository
 *
 * @var \Venor\Myext\Domain\Repository\MyRepository
 * @inject
 */
protected $myRepository

然后遍历要导入的行(foreach),并为每行创建一个新对象,并将其添加到您的存储库中:

Then iterate through the rows you want to import (foreach) and create a new object for every row and add it to your repository:

 $myObject = $this->objectManager->get('Vendor\Myext\Domain\Model\MyModel');
 $myObject->setProperty('foo');
 $myObject->setOtherProperty('bar');
 $this->myRepository->add($myObject);

要实际将对象保存到数据库,您需要保留它们.因此,您还需要注入persistenceManager:

To actually save the objects to the database, you need to persist them. So you also inject the persistenceManager:

/**
 * @var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager
 * @inject
 */
protected $persistenceManager;

并使用它:

 $this->persistenceManager->persistAll();

您不应对每个对象都这样做(出于性能原因);但是出于内存使用的原因,您也不应该等到成千上万个对象都保留下来之后再进行操作.因此,您只需在foreach循环中插入一个迭代器,然后每20、40或任何循环都将其持久化.

You should not do that for every single object (for performance reasons); but for memory usage reasons you should not wait until after thousands of objects to persist, either. So you just insert an iterator to your foreach loop and persist every 20th, 40th, or whatever loop.

请不要忘记Scheduler在后端上下文中工作,因此TypoScript必须由module.tx_yourext提供.如果您想与应用的前端部分共享相同的设置/存储密码,请使用

Please don't forget that the Scheduler works in Backend context, so the TypoScript must be available by module.tx_yourext. If you want to share the same settings/storagePid with the frontend part of your app, use

module.tx_yourext.persistence < plugin.tx_yourext.persistence
[...]

TypoScript必须出现在网站的根页面中,后端模块/CommandController才能使用它们.我建议您将内容添加到myext/Configuration/TypoScript/setup.txt,并将扩展的静态模板添加到根页面.

The TypoScript needs to be present in the root page of your website for backend modules/CommandControllers to use them. I suggest you add the stuff to myext/Configuration/TypoScript/setup.txt and add the static template of your extension to the root page.

使用DataHandler

TYPO3数据处理程序(以前称为TCEmain)是TYPO3后端用于插入和修改数据库记录的引擎.它非常强大.

The TYPO3 DataHandler (formerly TCEmain) is the engine the TYPO3 backend uses for inserting and modifying database records. It is very powerful.

在循环内部,您将创建一个包含所有数据的数组,而不是一个对象.第一个数组索引是表,下一个级别是受影响的记录,其中NEW表示创建新记录.然后,您可以将表的每个字段设置为所需的值

Instead of an object, inside your loop you create an array containing all the data. The first array index is the table, the next level is the affected record, where NEW means that a new record is created. Then you can just set every field of a table with the desired value

    $data = array();
    $data['be_users']['NEW'] = array(
        'pid' => 0,
        'username' => $staffMember['IDPerson'],
        'password' => md5(GeneralUtility::generateRandomBytes(40)), // random password
        'usergroup' => '1,2',
        'email' => $staffMember['Email'],
        'realName' => $staffMember['Nachname'] . ' ' . $staffMember['Vorname'],
        'lang' => 'de',
    );

现在,您可以创建DataHandler的实例并保留更改:

Now you can make an Instance of DataHandler and persist the changes:

    /** @var $tce t3lib_TCEmain */
    $tce = GeneralUtility::makeInstance('TYPO3\CMS\Core\DataHandling\DataHandler');
    $tce->bypassAccessCheckForRecords = TRUE;
    $tce->start($data, array());
    $tce->admin = TRUE;
    $tce->process_datamap();
    $newRecordsUidArray = $tce->substNEWwithIDs['NEW'];

请注意行$tce->admin = TRUE.这向DataHandler暗示管理员正在执行该操作.这很方便,因为您不必为Scheduler用户设置允许的排除字段,也可以将记录插入PID0.但这是可能的安全漏洞,因此请仔细考虑其用法.

Please note the line $tce->admin = TRUE. This suggests to DataHandler that an admin is performing the action. This is convenient because you don't have to set allowed exclude fields for the Scheduler user and can also insert records to PID 0. But it is a possible security flaw, so carefully consider its usage.

由DataHandler插入/更新的记录已正确记录,可以还原等.您可以找到一些示例(例如添加图片,解决MM关系)

Records inserted/updated by DataHandler logged correctly, can be reverted etc.. You can find some examples (such as adding pictures, resolving MM relations) here. In this case all DataHandler related functions were moved to an external repository class that is injected to the CommandController as described above (it's just named in Extbase convention).

可以找到DataHandler函数的良好概述这里.

A good overview of DataHandler functions can be found here.

这篇关于在extbase扩展中,如何从调度程序任务访问持久层?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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