Typo3 frontend plugin, use _POST data in the controller - plugins

I wrote a very simple extension in typo3 v7.6.11 with the extension builder where a visitor can ask for a taxi-ride.
everything works, only that I need to make the request more appealing by asking the pick-up point and the drop-off point ... that request goes to the actual form like this in the template (requestPid is the id of the page with the form):
<f:form pageUid="{settings.additional.requestPid}" action="form" name="request" object="{Request}">
<f:render partial="Ticket/RequestNewFields" />
<f:form.submit value="{f:translate(key: 'tx_wmnltickets_domain_model_ticket.admin.continue')}" />
</f:form>
but the formAction in the controler doesn't actually ask anything from the model (getArguments() I tried);
/**
* action form
*
* #return void
*/
public function formAction() {
$this->request->getArguments();
}
the request does send the $_POST but I see no way to get it into the form ...
if you'd like to see more code to understand, just ask, I don't know what you'd be looking for ...

Your form action should has the request parameter from you form:
/**
* action form
*
* #param array $request
*
* #return void
*/
public function formAction($request) {
}
Then you can access the data with $request['origin']
I'm not sure if the variable $request is allowed as argument. Maybe you must rename it in the function and in your fluid template if it doesn't work.

Did you create the extension with the builder? The easiest way is to create the fields (pickup-point, dropoff-point) in the builder, then create a createAction or newAction (not sure how it is called in the builder). It will create the template for the createAction where you can just copy/paste the <f:form...
There is a way to access directly POST/GET parameters (It is not recomended to use it directly when you can make it with the clean extbase way):
$myVar = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('myVar');

Related

TYPO3 - hook / signal after page rendered

Is there any hook/signal or anything else so that I can modify final HTML code of frontend page rendered by TYPO3?
My use case is:
I want to apply some regex and logging for links that are displayed across whole website - no matter if the link is rendered via tt_content bodytext (typolink or hardcoded) or by frontend plugin or comes via typoscript or possibly any other way.
The PAGE object in TypoScript has stdWrap, so you can use userFunc there.
page = PAGE
page {
...
stdWrap.userFunc = Your\NameSpace\YourClass->doStuff
}
If you prefer to use real hooks instead of stdWrap you can look at the function generatePage_postProcessing which has three hooks. In the CoreApi Documentation you can find the way how to use hooks.
In your ext_localconf.php you can define your hook usage. As example:
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-all'][] = My\NameSpace\Hooks\PageGenerateHooks::class . '->contentPostProcAll'
Now in your hook class you can modify the content:
<?php
namespace My\Namespace\Hooks;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
class PageGenerateHooks
{
/*
* \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $pObj
*/
public function contentPostProcAll(TypoScriptFrontendController $pObj)
{
$pObj->content = preg_replace('#mySearch#i','myTerm', $pObj->content;
}
}

TYPO3 set template view for controller action

I want to use the view template of the list action for my listByYear action. I tried setTemplatePathAndFilename without success. It still cannot find the template.
Sorry, the requested view was not found.
The technical reason is: No template was found. View could not be
resolved for action "listByYear" in class
"XXX\YYY\Controller\EventController".
/**
* action listByYear
* #param \XXX\YYY\Domain\Model\Event $event
*
* #return void
*/
public function listByYearAction(\XXX\YYY\Domain\Model\Event $event)
{
$date = $event->getStart();
$events = $this->eventRepository->findByYear($date->format('Y'));
$this->view->setTemplatePathAndFilename(
'typo3conf/ext/' .
$this->request->getControllerExtensionKey() .
'/Resources/Private/Templates/Event/List.html'
);
debug('typo3conf/ext/' .
$this->request->getControllerExtensionKey() .
'/Resources/Private/Templates/Event/List.html');
$this->view->assign('events', $events);
}
How do I make it use the template for the list?
The very short answer is, you can't. The view will already have been initialised and asked to resolve a template well before your action fires, indeed well before any point where you can affect the template filename that it would look for.
The template file that by convention would be resolved must always exist. This is what allows your controller action to render. You can then, but I would not recommend that you do, override the template file by setting the template name (the action).
Overall recommendation: use the default template naming logic. If you need to re-use templates, consider refactoring the template parts you need to reuse, placing them in partial templates.
// Do not forget the use in the header ...,
// or write fully qualified class path..
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Fluid\View\StandaloneView;
// then add something like this in your action before the assign...
// or maybe create a Standalone view: search the web for "Extbase Standaloneview"
// have a look at: /typo3/sysext/about/Classes/Controller/AboutController.php
$this->view = GeneralUtility::makeInstance(StandaloneView::class);
$this->view->setTemplate('ActionName');
$this->view->setTemplateRootPaths(['EXT:your_ext/Resources/Private/Templates']);
$this->view->setPartialRootPaths(['EXT:your_ext/Resources/Private/Partials']);
$this->view->setLayoutRootPaths(['EXT:your_ext/Resources/Private/Layouts']);
$this->view->assignMultiple([
'whatever' => $whatever,
'youLike' => $youLike,
]);

Extbase view variable not getting

/**
* New post form
* #param \Vendor\My\Domain\Model\Post|null $newPost New post
* #return void
* #dontvalidate $newPost
*/
public function newAction(\Vendor\My\Domain\Model\Post $newPost = NULL) {
$this->view->assign('test', 'hello');
$this->view->assign('categoryList', $this->categoryRepository->findAllByBlog(0));
$this->view->assign('postObject', $newPost);
}
public function editAction() {
$this->view->assign('categoryList', $this->categoryRepository->findAllByBlog(0));
$postObject = $this->postRepository->findOneByUid($this->request->getArgument('id'));
$this->view->assign('postObject', $postObject);
}
this is my script and my problem is that I have a categoryList array, its is only getting in edit view. I want to use that category list on newaction. When I tried to foreach that array in new action view file it is getting empty. and i can get it after saving the postObject. Any idea about this particular problem? and variable test from newaction also not visible in the newAction Template file.
Am using Typo3 7.6.11
Declare arguments you want to receive, as arguments for your controller action. Reference this argument name correctly in Fluid templates when you build links to your controller action. Do not access arguments from the Request directly. Add correct PDPdoc comments for it, too.
Basically: do the correct thing with your arguments instead of bypassing the framework. This advise applies to anything you do in Extbase.
NB: New and Edit actions should never, ever share the same template (this further indicates you bypass the framework's expected behavior). Create and New, yes. But not New and Edit. If necessary, put the form fields in a partial and the form itself in separate templates so you can control the action building and object/object-name setup correctly.
If a $this->***Repository method returns NULL, it may be that the repository had no StoragePid defined.
Make sure both newAction and editAction have the same storagePid defined in TypoScript or your Backend Plugin Settings (Flexform).
The TypoScript for this would look something like this:
plugin.tx_extension.persistence.storagePid = 100

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 />
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.

Form select method in Kohana includes "multiple" attribute in HTML if not NULL

I'm using the form::select helper in Kohana 3.2 to generate a select input with the following code (formatted for display here):
form::select('id_plyta', $plyta, $plyta_selected,
array('style' => 'width:300px', 'class' => 'sock_depend'));
This code generates the following HTML (formatted for display here):
<select name="id_plyta" class="sock_depend" style="width:300px"
multiple="multiple">
...
</select>
The problem is that it is outputting with an extra multiple="multiple" attribute in the HTML. I don't want that to be a part of it.
If I put a NULL instead of $plyta_selected then it works fine.
How do I get rid of multiple="multiple" and why is it even there?
When you check out the list of parameters it accepts, pay attention to the third:
* #param string input name
* #param array available options
* #param mixed selected option string, or an array of selected options
* #param array html attributes
When sending the paramters to the select method of the Form class, if the third parameter is an array, the helper will automatically include the multiple="multiple" to allow it to pre-select more than one option in the drop down select.
If you only send a string value, then it will not create a multibox, will not include the multiple HTML input attribute and it will only pre-select the single value.