首页 文章

TYPO3 Extbase - 如何使用核心信号/插槽

提问于
浏览
6

我在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();

            }   

    }

}

Update 15.06.2015
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);

   });

Update 29.06.2015
https://forge.typo3.org/issues/61979弗朗索瓦写道,"Object Manager may only be used in Extbase Context, not in ext_localconf.php" . 但是,给定的答案甚至对我不起作用 . 但也许它可以帮助别人 .

1 回答

  • 3

    目前没有官方文档,但在该问题中您可以找到非官方文档: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';
    

    在那里,您将类配置为Hook for t3lib_tcemain 在TYPO3 6.2处理之前的旧Classname,然后处理List View的数据 .

    在您的课程内部,您可以像以前一样实现您的代码:

    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只会迭代配置的钩子并调用方法 . 所以没什么好看的 . 您可以获得一些由实现定义的参数,并可以使用它们 .

    在上面的例子中,如果表和动作匹配,则只有一个检查来执行钩子 . 由于许多原因调用此代码,因此请确保将其列入白名单,以便仅在您了解的环境中执行 . 出于安全和性能原因 .

相关问题