Search code examples
typo3fluidextbasetypo3-6.2.xtypo3-extensions

How does my frontend usergroup list get lost between Extbase action controller and Fluid template partial in TYPO3 6.2?


I'm using TYPO3 CMS 6.2.12 and Extension Builder 6.2.0 to model a Report class and build an extension to manage it.

One of the domain driven design requirements is that a report author be a logged-in front end user. A second requirement is that the author choose a single group from a list of their front end user groups while entering their report information.

Extension Builder did most of the work in producing code and files, so far. It built the Report model and all the action controllers and Fluid templates and partials. That's a huge leap forward. I did not have it build a model for front end users or their groups, opting instead to inject dependencies from existing classes. I am now trying to work on the user and usergroup requirements, mostly by adding code to the `newAction` controller and the Fluid partial for `FormFields`.

On my development server, I can enter new reports successfully. I bring up a web form for a new report; I can enter information and submit the new report; the newly created report appears in the list page and in the database; and I can show that single report in the web browser.

My problem now is that the frontend usergroup list does not appear in the web form for a new report.

I've been trying a variety of experiments over the last several days.

  • ["A journey through the blog example"][blogexample] in the Extbase Fluid Book gave a good example to follow, and confidence that what I'm attempting to do should work. ["Alternative route: creating a new posting"][newposting] was especially useful as a guide, after reading the rest of the chapter.

  • TYPO3 Wiki's ["Dependency Injection" article][depinj] seems to say we need only @inject annotation, and although the article warns against t3lib_div::makeInstance, I found that a relocated version of that method became useful during the testing, below.

  • The Fluid debug instruction in the code below came from the TYPO3 Wiki's [Fluid page][fluid]. During testing, though, it seemed to give only TypoScript setting variables.

  • I found a number of Stack Overflow articles, including ["How to set the FrontendUserGroup in AllowViewHelper of VHS in a partial?"][so1] asked by Vertex, ["how to: use Tx_Extbase_Domain_Repository_FrontendUserRepository in typo3 v4.5"][so2] asked by The Newbie Qs, ["TYPO3 - Call another repository"][so3] asked by Jeppe Donslund, and ["Typo3 6.1 Extbase - select all fe users"][so4] asked by cili. This last article gave the $feUserRepository snippet I used in testing, below. The second-to-last article gave the warning, "After adding a Dependency Injection, you have to clear the cache!" It didn't say which cache, and that led to my drastic procedure of clearing everything I could think of for this test.

Today, I ran my most recent test with the code shown here, below. In the TYPO3 back end, I flushed frontend caches and flushed general caches. I went into the Install Tool's "Important actions" and clicked "Clear all cache". It was successful. I then went into the Extension Manager, where I deactivated and reactivated my extension. I then ran Debug in PhpStorm 8.0.3, which followed events. In my development website, I logged in to the front end. I navigated to the report listing page, and clicked "New Report". With break points set in `newAction()`, PhpStorm's watches told me they had an "error evaluating code" for both `$frontendUserRepository` and `$frontendUserGroupRepository`, with no further information that I knew how to find. (I'm new to PhpStorm.) However, `$feUserRepository` became an object of type `TYPO3\CMS\Extbase\Domain\Model\FrontendUser`, containing many items including an `identifierMap` array that contained arrays of `typo3\cms\extbase\domain\model\frontenduser` and `typo3\cms\extbase\domain\model\frontendusergroup` items. The frontenduser array contained a `TYPO3\CMS\Extbase\Domain\Model\FrontendUser` object that contained the correct user record. The frontendusergroup array contained 2 `TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup` objects that contained the correct user group records. In the next debug step, the `TYPO3\CMS\Extbase\Domain\Model\FrontendUser $user` object contained the same correct user record. After all this, though, the output HTML page for the new report's web form produced blanks for my author's username display and my author's usergroup select list. (The Extbase utility debugger showed only irrelevant TypoScript settings.)

This test leads me to believe that the Extbase `newAction` controller can find the frontend usergroups for `$feUserRepository`, but is having trouble with `$frontendUserRepository` and `$frontendUserGroupRepository`. However, indicated by the second empty break tag output line, below, even the `authortest` variable assigned to `$feUserRepository got lost, somehow, on the way to Fluid.

I'm trying for minimal impact on the rest of the package, and what I can find tells me this code below should be working. But it's not.

Can you tell what I missed?

(Please excuse my missing hyperlinks. Stack Overflow is telling me, "You need at least 10 reputation to post more than 2 links. This is my first question, so that obviously hasn't happened, yet.)

From myextension\Classes\Controller\ReportController.php:

/**
 * reportRepository
 * 
 * @var \MyVendor\Myextension\Domain\Repository\ReportRepository
 * @inject
 */
protected $reportRepository = NULL;

/**
 * @var \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository
 * @inject
 */
protected $frontendUserRepository;

/**
 * @var \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserGroupRepository
 * @inject
 */
protected $frontendUserGroupRepository;

/**
 * action new
 *
 * @param \MyVendor\Myextension\Domain\Model\Report $newReport
 * @ignorevalidation $newReport
 * @return void
 */
public function newAction(\MyVendor\Myextension\Domain\Model\Report $newReport = NULL) {
    $this->view->assign('newReport', $newReport);
    $this->view->assign('author', $this->frontendUserRepository->findByUid($GLOBALS['TSFE']->fe_user->user['uid']));
    $this->view->assign('groups', $this->frontendUserGroupRepository->findAll());
    $feUserRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( 'TYPO3\\CMS\\Extbase\\Domain\\Repository\\FrontendUserRepository' );
    $user = $feUserRepository->findByUid( 1 );
    $this->view->assign('authortest', $user);
}

From myextension\Resources\Private\Templates\Report\New.html:

<f:form action="create"  name="newReport" object="{newReport}">
<f:render partial="Report/FormFields" />
<f:form.submit value="Create new" />
</f:form>

From myextension\Resources\Private\Partials\Report\FormFields.html:

<f:debug title="All available variables">{_all}</f:debug>
{author.username}<br />
{authortest.username}<br />
<label for="authorGroupId"><f:translate key="tx_myextension_domain_model_report.author_group_id" /></label><br />
    <f:form.select property="authorGroupId" options="{groups}" optionLabelField="title" optionValueField="uid" /><br />

From HTML output in the web form for a new report:

<br />
<br />
<label for="authorGroupId">Author Group Id</label><br />
    <select name="tx_myextension_myextensionauthorplugin[newReport][authorGroupId]"><option value=""></option>
</select><br />

Solution

  • Your variables are not passed to the partial, so {groups} is not a variable inside your Partial.

    You can specify the variables you want to use in the partial by giving the attribute arguments on your <f:render.partial> like in your case:

    <f:render partial="Report/FormFields" arguments="{groups : groups}" />
    

    Since TYPO3 4.6 you can also use arguments="{_all}" to pass all variables to the partial.

    See also:

    http://docs.typo3.org/flow/TYPO3FlowDocumentation/stable/TheDefinitiveGuide/PartV/FluidViewHelperReference.html#f-render

    • arguments (array, optional): Arguments to pass to the partial.