1

我正在使用 TYPO3 CMS 6.2.x LTS 和 Extension Builder 编写 TYPO3 扩展。扩展应该将 CSV 文件导入域模型并在导入期间填充另外两个模型。

CSV 文件导入正常,但以下控制器方法崩溃,我无法解决问题。我相信问题的根源可能隐藏在我的插件调用第一个方法,但是每个方法都直接进入下一个方法。Extbase文档让我相信forward()不会返回调用方法,我需要返回原来的方法继续处理更多的导入记录。

我的插件 URI 激活ImportMemberController->importAction()ImportMemberController->importAction()将一个$newPerson对象和一个$parameters数组传递给PersonController->enrollAction()ok。PersonController->enrollAction()通过$person, $role, $startTime, 和$stopTime对象来确定HasRoleController->commissionAction()HasRoleController->commissionAction()在最后persistAll()一行崩溃并显示以下消息。

致命错误:在第 157 行的typo3conf\ext\myextension\Classes\Controller\HasRoleController.php 中的 null 上调用成员函数 persistAll()

包括 TCA 在内的配置在 Extension Builder 构建时通常是完整的。

这是一些扩展的代码。我为篇幅道歉。

<?php
namespace MyNameSpace\Myextension\Controller;
/**
 * ImportMemberController
 */
class ImportMemberController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {

    /**
     * importMemberRepository
     * 
     * @var \MyNameSpace\Myextension\Domain\Repository\ImportMemberRepository
     * @inject
     */
    protected $importMemberRepository = NULL;

    /**
     * personRepository
     *
     * @var \MyNameSpace\Myextension\Domain\Repository\PersonRepository
     * @inject
     */
    protected $personRepository = NULL;

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

    /**
     * action import
     *
     * @return void
     */
    public function importAction() {
        $importMembers = $this->importMemberRepository->findAll();
        foreach ($importMembers as $importMember) {

            // Assess the qualification of this import person.
            $newQualification = TRUE;
            if ($importMember->getEmail() == "") {
                $newQualification = FALSE;
            }
            elseif ($importMember->getFirstName() == "") {
                $newQualification = FALSE;
            }
            elseif ($importMember->getLastName() == "") {
                $newQualification = FALSE;
            }

            // Determine whether this person is already in the personRepository.
            $queryResult = $this->personRepository->findBySomeNumber($importMember->getSomeNumber());
            if ($queryResult->count() > 0) {
                $person = $queryResult->getFirst();
                // Update changes to an existing person's specified properties.
                if ($person->getFamilyName() != $importMember->getLastName()) {
                    $person->setFamilyName($importMember->getLastName());
                }
                if ($person->getFirstName() != $importMember->getFirstName()) {
                    $person->setFirstName($importMember->getFirstName());
                }
                if ($person->getEmailAddress() != $importMember->getEmail()) {
                    $person->setEmailAddress($importMember->getEmail());
                }
                $this->personRepository->update($person);
                // Obtain the qualification status of this existing person.
                $existingQualification = $person->getQualifiedUser();
                // Disenroll this existing person if they no longer qualify.
                if ($existingQualification && !$newQualification) {
                    $person->setQualifiedUser(FALSE);
                }
                // Else enroll this existing person if they qualify after being unqualified.
                elseif (!$existingQualification && $newQualification) {
                    $person->setQualifiedUser(TRUE); // @todo: Reevaluate the need for this instruction.
                }
                // Else act if this existing person qualifies but changed  Office.
                elseif ($existingQualification && $newQualification && 2==1) {
                    // @todo: Later.
                }
            }
            else {
                // Act if this new import person qualifies.
                if ($newQualification) {
                    // Enter this new import person into personRepository.
                    $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
                    $newPerson = $objectManager->get('MyNameSpace\\Myextension\\Domain\\Model\\Person');
                    $newPerson->setFamilyName($importMember->getLastName());
                    $newPerson->setFirstName($importMember->getFirstName());
                    $newPerson->setSomeNumber($importMember->getSomeNumber());
                    $newPerson->setEmailAddress($importMember->getEmail());
                    $this->personRepository->add($newPerson);
                    $this->persistenceManager->persistAll();
                    // Enroll this new import person.
                    if ($importMember->getDate()) {
                        $startTime = $importMember->getDate();
                    }
                    else {
                        $startTime = new \DateTime();
                    }
                    if ($importMember->getPaidThru()) {
                        $stopTime = $importMember->getPaidThru();
                    }
                    else {
                        $stopTime = new \DateTime();
                        $stopTime->modify('+100 years');
                    }
                    $parameters = array(
                        'title' => ' Office '.$importMember->getOffice().' Member',
                        'startTime' => $startTime,
                        'stopTime' => $stopTime
                    );
                    $newPersonController = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('MyNameSpace\\Myextension\\Controller\\PersonController');
                    $newPersonController->enrollAction($newPerson, $parameters);
                }
            }
        }
        $this->redirect('list');
    }
}

<?php
namespace MyNameSpace\Myextension\Controller;
/**
 * PersonController
 */
class PersonController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {

    /**
     * personRepository
     * 
     * @var \MyNameSpace\Myextension\Domain\Repository\PersonRepository
     * @inject
     */
    protected $personRepository = NULL;

    /**
     * roleRepository
     *
     * @var \MyNameSpace\Myextension\Domain\Repository\RoleRepository
     * @inject
     */
    protected $roleRepository = NULL;

    /**
     * action enroll
     *
     * @param \MyNameSpace\Myextension\Domain\Model\Person $person
     * @param mixed[] $parameters
     * @return void
     */
    public function enrollAction(\MyNameSpace\Myextension\Domain\Model\Person $person,
                                $parameters) {
        $person->setQualifiedUser(TRUE);
        $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
        $this->roleRepository = $objectManager->get('MyNameSpace\\Myextension\\Domain\\Repository\\RoleRepository');
        if ($parameters['title']) {
            $queryResult = $this->roleRepository->findByTitle($parameters['title']);
            if ($queryResult->count() > 0) {
                $role = $queryResult->getFirst();
                if ($parameters['startTime']) {
                    $startTime = $parameters['startTime'];
                } else {
                    $startTime = new \DateTime();
                }
                if ($parameters['stopTime']) {
                    $stopTime = $parameters['stopTime'];
                } else {
                    $stopTime = new \DateTime();
                    $stopTime->modify('+100 years');
                }
                $newHasRoleController = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('MyNameSpace\\Myextension\\Controller\\HasRoleController');
                $newHasRoleController->commissionAction($person, $role, $startTime, $stopTime);
            }
        }
    }
}

<?php
namespace MyNameSpace\Myextension\Controller;
/**
 * HasRoleController
 */
class HasRoleController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {

    /**
     * hasRoleRepository
     * 
     * @var \MyNameSpace\Myextension\Domain\Repository\HasRoleRepository
     * @inject
     */
    protected $hasRoleRepository = NULL;

    /**
     * @var \TYPO3\CMS\Extbase\Object\ObjectManager
     * @inject
     */
    protected $objectManager;

    /**
     * persistence manager
     *
     * @var \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface
     * @inject
     */
    protected $persistenceManager;

    /**
     * action commission
     *
     * @param \MyNameSpace\Myextension\Domain\Model\Person $person
     * @param \MyNameSpace\Myextension\Domain\Model\Role $role
     * @param \DateTime $startTime
     * @param \DateTime $stopTime
     * @return void
     */
    public function commissionAction(\MyNameSpace\Myextension\Domain\Model\Person $person,
                                    \MyNameSpace\Myextension\Domain\Model\Role $role,
                                    $startTime, $stopTime) {
        //$newHasRole = new \MyNameSpace\Myextension\Domain\Model\HasRole(); // @todo: Remove this line.
        $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
        $objectManager->get(\TYPO3\CMS\Extbase\Mvc\Controller\Arguments::class);
        $newHasRole = $objectManager->get('MyNameSpace\\Myextension\\Domain\\Model\\HasRole');
        //$newHasRole = $this->objectManager->get('MyNameSpace\\Myextension\\Domain\\Model\\HasRole');
        $newHasRole->setStartTime($startTime);
        $newHasRole->setStopTime($stopTime);
        $newHasRole->addPerson($person);
        //$newHasRole->setPerson($person); // @todo: Remove this line.
        $newHasRole->addRole($role);
        //$newHasRole->setRole($person); // @todo: Remove this line.
        $this->hasRoleRepository = $objectManager->get('MyNameSpace\\Myextension\\Domain\\Repository\\HasRoleRepository');
        //$this->hasRoleRepository = $this->objectManager->get('MyNameSpace\\Myextension\\Domain\\Repository\\HasRoleRepository');
        $this->hasRoleRepository->add($newHasRole);
        $this->persistenceManager->persistAll();
    }
}

在崩溃点,本地范围内的变量是:

$newHasRole = object(MyNameSpace\Myextension\Domain\Model\HasRole)
  protected 'startTime' => 
    object(DateTime)[834]
      public 'date' => string '1993-11-29 19:00:00.000000' (length=26)
      public 'timezone_type' => int 3
      public 'timezone' => string 'America/New_York' (length=16)
  protected 'stopTime' => 
    object(DateTime)[982]
      public 'date' => string '2116-03-10 17:55:43.000000' (length=26)
      public 'timezone_type' => int 3
      public 'timezone' => string 'America/New_York' (length=16)
  protected 'person' => 
    object(TYPO3\CMS\Extbase\Persistence\ObjectStorage)[1008]
      private 'warning' => string 'You should never see this warning. If you do, you probably used PHP array functions like current() on the TYPO3\CMS\Extbase\Persistence\ObjectStorage. To retrieve the first result, you can use the rewind() and current() methods.' (length=228)
      protected 'storage' => 
        array (size=1)
          '000000007303096700000000080231e7' => 
            array (size=2)
              ...
      protected 'isModified' => boolean true
      protected 'addedObjectsPositions' => 
        array (size=1)
          '000000007303096700000000080231e7' => int 1
      protected 'removedObjectsPositions' => 
        array (size=0)
          empty
      protected 'positionCounter' => int 1
  protected 'role' => 
    object(TYPO3\CMS\Extbase\Persistence\ObjectStorage)[1045]
      private 'warning' => string 'You should never see this warning. If you do, you probably used PHP array functions like current() on the TYPO3\CMS\Extbase\Persistence\ObjectStorage. To retrieve the first result, you can use the rewind() and current() methods.' (length=228)
      protected 'storage' => 
        array (size=1)
          '0000000073030eea00000000080231e7' => 
            array (size=2)
              ...
      protected 'isModified' => boolean true
      protected 'addedObjectsPositions' => 
        array (size=1)
          '0000000073030eea00000000080231e7' => int 1
      protected 'removedObjectsPositions' => 
        array (size=0)
          empty
      protected 'positionCounter' => int 1
  protected 'uid' => null
  protected '_localizedUid' => null
  protected '_languageUid' => null
  protected '_versionedUid' => null
  protected 'pid' => null
  private '_isClone' (TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject) => boolean false
  private '_cleanProperties' (TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject) => 
    array (size=0)
      empty

$objectManager = object(TYPO3\CMS\Extbase\Object\ObjectManager)
$person = object(KeystoneResearchSolutions\Grouprole\Domain\Model\Person)
$role = object(KeystoneResearchSolutions\Grouprole\Domain\Model\Role)
$startTime = object(DateTime)
$stopTime = object(DateTime)
4

3 回答 3

1

从对象管理器显式获取持久性管理器解决了这个问题。尽管 Persistence Manager 注入已经出现在班级的头部。

解决方案的线索来自Arek van Schaijk 在 2015 年 5 月 26 日 14:18 发表的关于 extbase 中非对象的 findAll 评论这里唯一可能发生的事情就是injectProductRepository()没有很好地注入你的存储库(对象)。” 下一条评论说,“所以基本上所有的注入都被缓存了,没有检查是否有新的注入。” 显然在某些情况下 Extbase 注入机制不参与。

这是有效的功能代码:

/**
 * action commission
 *
 * @param \MyNameSpace\Myextension\Domain\Model\Person $person
 * @param \MyNameSpace\Myextension\Domain\Model\Role $role
 * @param \DateTime $startTime
 * @param \DateTime $stopTime
 * @return void
 */
public function commissionAction(\MyNameSpace\Myextension\Domain\Model\Person $person,
                                 \MyNameSpace\Myextension\Domain\Model\Role $role,
                                 $startTime, $stopTime) {
    $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
    $newHasRole = $objectManager->get('MyNameSpace\\Myextension\\Domain\\Model\\HasRole');
    $newHasRole->setStartTime($startTime);
    $newHasRole->setStopTime($stopTime);
    $newHasRole->addPerson($person);
    $newHasRole->addRole($role);
    $this->hasRoleRepository = $objectManager->get('MyNameSpace\\Myextension\\Domain\\Repository\\HasRoleRepository');
    $this->hasRoleRepository->add($newHasRole);
    $this->persistenceManager = $objectManager->get('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager');
    $this->persistenceManager->persistAll();
}
于 2016-03-13T00:28:33.480 回答
0

您注入了持久性管理器,但没有清除所有缓存......您必须真正清除所有以反映新注入。在某些情况下,甚至清除typo3temp 文件夹。

要在 BE 中为选定用户添加Flush system caches图标而无需使用安装工具,只需编辑所需帐户并将其添加到其TSConfig

options.clearCache.system = 1

按 F5 保存用户并刷新整个 BE。

允许任何人清除系统缓存(尤其是在大型实例上)是相当糟糕的主意,因此只为开发人员和聪明的管理员保留这种可能性。

于 2016-03-11T11:26:51.910 回答
0

确实不需要手动持久化对象,因为 extbase 如果在每个操作结束时与存储库相关联,则会自动持久化对对象的更改。

于 2016-03-11T06:43:03.460 回答