У моего расширения TYPO3 CMS 6.2 Extbase происходит сбой при передаче объектов между несколькими контроллерами, методами действий и постоянством

Я пишу расширение TYPO3 с использованием TYPO3 CMS 6.2.x LTS и Extension Builder. Расширение должно импортировать файл CSV в модель домена и заполнять еще две модели во время импорта.

Файл CSV импортируется нормально, но следующий метод контроллера дает сбой, и у меня возникают проблемы с решением проблемы. Я считаю, что источник проблемы может быть скрыт в том, что мой плагин вызывает первый метод, но затем каждый метод переходит непосредственно к следующему методу. Документация Extbase заставляет меня верить forward() не вернусь к вызывающему методу, и мне нужно вернуться к исходному методу, чтобы продолжить обработку большего количества записей импорта.

URI моего плагина активируется ImportMemberController->importAction(), ImportMemberController->importAction() проходит $newPerson объект и $parameters массив для PersonController->enrollAction() Хорошо. PersonController->enrollAction() проходит $person, $role, $startTime, а также $stopTime возражает против HasRoleController->commissionAction() Хорошо. HasRoleController->commissionAction() вылетает в финал persistAll() строка со следующим сообщением.

Неустранимая ошибка: вызов функции-члена persistAll() для null в typo3conf\ext\myextension\Classes\Controller\HasRoleController.php в строке 157

Конфигурации, включая 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)

3 ответа

Решение

Явное получение диспетчера постоянства от диспетчера объектов решило проблему. Это несмотря на то, что инъекция менеджера постоянства уже присутствует в главе класса.

Подсказка к решению пришла из комментария Арека ван Шайка 2015-05-26 14:18 в findAll о необъекте в extbase, который сказал: "Единственное, что здесь может происходить, это то, что 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();
}

В действительности не должно быть необходимости сохранять объект вручную, так как extbase автоматически сохраняет изменения в объектах, если они связаны с хранилищем в конце каждого действия.

Вы ввели менеджер персистентности, но не очистили все кэши.... вы должны действительно очистить ВСЕ, чтобы отразить новые инъекции. Даже очистить папку typo3temp в некоторых случаях.

Чтобы добавить Flush system caches значок для выбранных пользователей в BE без использования Install Tool просто отредактируйте необходимую учетную запись и добавьте ее в свой TSConfig:

options.clearCache.system = 1

Сохраните пользователя и обновите весь BE, нажав F5.

Довольно плохая идея разрешать кому-либо очищать системные кэши (особенно в больших случаях), поэтому оставляйте эту возможность только для разработчиков и умных администраторов.

Другие вопросы по тегам