TYPO3 Extbase - 如何使用核心 Signal/Slots
TYPO3 Extbase - how to use core Signal/Slots
我在 TYPO3 V6.2 中有一个可用的 Extbase 扩展,它存储产品。
现在我想了解如何使用 Signal/Slot(Hooks 的 Extbase 变体)。我想知道为什么这个例子不起作用。当我在 TYPO3 后端的列表模块中更新产品时,它可以正确保存但没有消息出现。
文件typo3conf/ext/myext/ext_localconf.php
$signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( 'TYPO3\CMS\Extbase\SignalSlot\Dispatcher' );
$signalSlotDispatcher->connect(
'TYPO3\CMS\Extbase\Persistence\Generic\Backend',
'afterUpdateObject',
'MyVendor\MyExt\Service\Signalservice',
'myAfterUpdate',
FALSE
);
文件typo3conf/ext/myext/Service/Signalservice.php
namespace MyVendor\MyExt\Service;
class Signalservice implements \TYPO3\CMS\Core\SingletonInterface {
/**
* @param \TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface $object
*/
public function myAfterUpdate(\TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface $object){
if ($object instanceof \MyVendor\MyExt\Domain\Model\Products) {
// check if we come to this point
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump('Successfully hooked - I am a slot.');
die();
}
}
}
2015 年 6 月 15 日更新
Patrick Lobacher 的提示指出,我们不能在这种情况下使用 die()。相反,我们应该写一个日志文件。但这对我也不起作用。没有写入文件:
文件typo3conf/ext/myext/ext_localconf.php
/**
* @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher
* */
$signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager')->get('TYPO3\CMS\Extbase\SignalSlot\Dispatcher');
$signalSlotDispatcher->connect(
'TYPO3\CMS\Extbase\Persistence\Generic\Backend',
'afterUpdateObject',
function ($payload) {
$logfile = "fileadmin/test/logfile.txt";
$handle = fopen($logfile, "a+");
fwrite ($handle, 'Hi. I was written by ext_localconf.php. ' . time());
fclose ($handle);
});
2015 年 6 月 29 日更新
在 https://forge.typo3.org/issues/61979 上,Francois 写道,"Object Manager may only be used in Extbase Context, not in ext_localconf.php"。
但是,给定的答案甚至对我不起作用。但也许它可以帮助别人。
目前没有官方文档,但是在issue中可以找到非官方文档:https://forge.typo3.org/issues/59089
问题是您在列表模块中使用了 Extbase 的信号槽。在 6.2 中,列表模块未使用 Extbase 实现。所以没有您可以使用的插槽。
相反,您需要遵循使用 Hooks 的旧的、记录的方式:https://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/Hooks/Concept/Index.html
在您的情况下,以下代码应作为入口点:
ext_localconf.php
:
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'][$_EXTKEY]
= 'Vendor\ExtName\Hook\DataMapHook';
在那里,您配置 class 以用作 t3lib_tcemain
TYPO3 6.2 之前的旧类名的挂钩,处理的不仅仅是列表视图的数据。
在您的 class 中,您可以实现您已经完成的代码:
Classes/Hook/DataMapHook.php
:
<?php
namespace Vendor\ExtName\Hook;
/**
* Hook to process updated records.
*
* @author Daniel Siepmann <d.siepmann@web-vision.de>
*/
class DataMapHook
{
/**
* Hook to add latitude and longitude to locations.
*
* @param string $action The action to perform, e.g. 'update'.
* @param string $table The table affected by action, e.g. 'fe_users'.
* @param int $uid The uid of the record affected by action.
* @param array $modifiedFields The modified fields of the record.
*
* @return void
*/
public function processDatamap_postProcessFieldArray(
$action, $table, $uid, array &$modifiedFields
) {
if(!$this->executeHook($table, $action)) {
return;
}
// check if we come to this point
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump('Successfully hooked - I am a slot.');
die();
}
/**
* Check whether to execute hook or not.
*
* @param string $table
* @param string $action
* @param array $modifiedFields
*
* @return bool
*/
protected function executeHook($table, $action)
{
// Do not process if foreign table, unintended action,
// or fields were changed explicitly.
if ($table !== 'tx_extname_domain_model_modelname' || $action !== 'update') {
return false;
}
return false;
}
}
是的,您可以在此上下文中使用 die
进行调试等。由于 TYPO3 只会遍历配置的钩子并调用方法。所以这里没什么特别的。
您将获得一些由实现定义的参数并可以使用它们。
在上面的示例中,有一项检查仅在 table 和操作匹配时才执行挂钩。由于出于多种原因调用此代码,因此请确保将其列入白名单,以便仅在您了解的环境中执行。出于安全和性能原因。
我在 TYPO3 V6.2 中有一个可用的 Extbase 扩展,它存储产品。 现在我想了解如何使用 Signal/Slot(Hooks 的 Extbase 变体)。我想知道为什么这个例子不起作用。当我在 TYPO3 后端的列表模块中更新产品时,它可以正确保存但没有消息出现。
文件typo3conf/ext/myext/ext_localconf.php
$signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( 'TYPO3\CMS\Extbase\SignalSlot\Dispatcher' );
$signalSlotDispatcher->connect(
'TYPO3\CMS\Extbase\Persistence\Generic\Backend',
'afterUpdateObject',
'MyVendor\MyExt\Service\Signalservice',
'myAfterUpdate',
FALSE
);
文件typo3conf/ext/myext/Service/Signalservice.php
namespace MyVendor\MyExt\Service;
class Signalservice implements \TYPO3\CMS\Core\SingletonInterface {
/**
* @param \TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface $object
*/
public function myAfterUpdate(\TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface $object){
if ($object instanceof \MyVendor\MyExt\Domain\Model\Products) {
// check if we come to this point
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump('Successfully hooked - I am a slot.');
die();
}
}
}
2015 年 6 月 15 日更新
Patrick Lobacher 的提示指出,我们不能在这种情况下使用 die()。相反,我们应该写一个日志文件。但这对我也不起作用。没有写入文件:
文件typo3conf/ext/myext/ext_localconf.php
/**
* @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher
* */
$signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager')->get('TYPO3\CMS\Extbase\SignalSlot\Dispatcher');
$signalSlotDispatcher->connect(
'TYPO3\CMS\Extbase\Persistence\Generic\Backend',
'afterUpdateObject',
function ($payload) {
$logfile = "fileadmin/test/logfile.txt";
$handle = fopen($logfile, "a+");
fwrite ($handle, 'Hi. I was written by ext_localconf.php. ' . time());
fclose ($handle);
});
2015 年 6 月 29 日更新
在 https://forge.typo3.org/issues/61979 上,Francois 写道,"Object Manager may only be used in Extbase Context, not in ext_localconf.php"。
但是,给定的答案甚至对我不起作用。但也许它可以帮助别人。
目前没有官方文档,但是在issue中可以找到非官方文档:https://forge.typo3.org/issues/59089
问题是您在列表模块中使用了 Extbase 的信号槽。在 6.2 中,列表模块未使用 Extbase 实现。所以没有您可以使用的插槽。 相反,您需要遵循使用 Hooks 的旧的、记录的方式:https://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/Hooks/Concept/Index.html
在您的情况下,以下代码应作为入口点:
ext_localconf.php
:
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'][$_EXTKEY]
= 'Vendor\ExtName\Hook\DataMapHook';
在那里,您配置 class 以用作 t3lib_tcemain
TYPO3 6.2 之前的旧类名的挂钩,处理的不仅仅是列表视图的数据。
在您的 class 中,您可以实现您已经完成的代码:
Classes/Hook/DataMapHook.php
:
<?php
namespace Vendor\ExtName\Hook;
/**
* Hook to process updated records.
*
* @author Daniel Siepmann <d.siepmann@web-vision.de>
*/
class DataMapHook
{
/**
* Hook to add latitude and longitude to locations.
*
* @param string $action The action to perform, e.g. 'update'.
* @param string $table The table affected by action, e.g. 'fe_users'.
* @param int $uid The uid of the record affected by action.
* @param array $modifiedFields The modified fields of the record.
*
* @return void
*/
public function processDatamap_postProcessFieldArray(
$action, $table, $uid, array &$modifiedFields
) {
if(!$this->executeHook($table, $action)) {
return;
}
// check if we come to this point
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump('Successfully hooked - I am a slot.');
die();
}
/**
* Check whether to execute hook or not.
*
* @param string $table
* @param string $action
* @param array $modifiedFields
*
* @return bool
*/
protected function executeHook($table, $action)
{
// Do not process if foreign table, unintended action,
// or fields were changed explicitly.
if ($table !== 'tx_extname_domain_model_modelname' || $action !== 'update') {
return false;
}
return false;
}
}
是的,您可以在此上下文中使用 die
进行调试等。由于 TYPO3 只会遍历配置的钩子并调用方法。所以这里没什么特别的。
您将获得一些由实现定义的参数并可以使用它们。
在上面的示例中,有一项检查仅在 table 和操作匹配时才执行挂钩。由于出于多种原因调用此代码,因此请确保将其列入白名单,以便仅在您了解的环境中执行。出于安全和性能原因。