How to get value from FlexForm to Controller - typo3

I'm practicing on a very easy Extbase Extension and used a FlexForm to get three formula fields.
One of them is called "code" which should go to the EmbedderController.php and then to the viewer List.html.
I checked all tutorials I could find.
I don't understand how to get the FlexForm-value "code" into my Controller.
I get an empty page or don't get any value.
This is my FlexForm: Embedder.xml
<T3DataStructure>
<meta type="array">
<langChildren>0</langChildren>
<langDisable>1</langDisable>
</meta>
<ROOT>
<type>array</type>
<el>
<settings.code>
<TCEforms>
<label>Video Code</label>
<config>
<type>input</type>
<size>20</size>
<max>30</max>
<eval>trim</eval>
</config>
</TCEforms>
</settings.code>
<settings.width>
<TCEforms>
<exclude>1</exclude>
<label>Breite in Pixel</label>
<config>
<type>input</type>
<size>10</size>
<max>10</max>
<eval>trim</eval>
</config>
</TCEforms>
</settings.width>
<settings.height>
<TCEforms>
<exclude>1</exclude>
<label>Höhe in Pixel</label>
<config>
<type>input</type>
<size>10</size>
<max>10</max>
<eval>trim</eval>
</config>
</TCEforms>
</settings.height>
</el>
</ROOT>
</T3DataStructure>
And this is my EmbedderController.php
<?php
namespace HhuMediathek\Hhumediathek\Controller;
/**
* EmbedderController
*/
class EmbedderController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
/**
* embedderRepository
*
* #var \HhuMediathek\Hhumediathek\Domain\Repository\EmbedderRepository
* #inject
*/
protected $embedderRepository = NULL;
/**
* action list
*
* #return void
*/
public function listAction() {
$this->settings['code'];
}
}
And this is the viewer List.html
<f:layout name="Default" />
<f:section name="main">
<iframe width='570' height='321' style='width: 570px; height: 321px; border: 1px solid #ccc;' src='//xxx.de/embed/{code}' frameborder='0' allowfullscreen></iframe>
</f:section>

Okay I could figure it out myself. For people who struggle with the same problem as I did:
My mistake was, that I didn't need the line $this->settings['code']; in the Controller at all but write {settings.code} in the viewer List.html instead of just {code}. It's completly different than I read it in my book and some tutorials but this actually worked.

The assignment of the view parameter is missing. Therefore change
public function listAction() {
$this->settings['code'];
}
to
public function listAction() {
$this->view->assign('code', $this->settings['code']);
}
This way {code} should be available in the view.

I want not to be restricted to settings.*. I use the following script in my controller.
/** #var ContentObjectRenderer $content */
$content = $this->configurationManager->getContentObject();
$flexFormString = $content->data['pi_flexform'];
$flexFormRaw = GeneralUtility::xml2array($flexFormString);
if (is_callable([FlexformUtilities::class,'arrayFlatten'])) {
$flexFormSimple = FlexformUtilities::arrayFlatten( $flexFormRaw); // second Param is ['data','sDEF','lDEF','vDEF']
$referenceUidsList = $flexFormSimple['referenceList'];
} else {
$referenceUidsList = (int)$flexFormRaw['data']['sDEF']['lDEF']['referenceList']['vDEF'];
}
The Utilities-Class contains the following flattenArray-method
protected const DEFAULT_FLATTEN_KEYS = ['data','sDEF','lDEF','vDEF'];
/**
* https://stackoverflow.com/questions/1319903/how-to-flatten-a-multidimensional-array
*
* #param array $listFlatKeys
* #param $array
* #return array
*/
public static function arrayFlatten( $array, &$listFlatKeys = self::DEFAULT_FLATTEN_KEYS)
{
if (!is_array($array)) {
return $array;
}
if (count($array) === 1) {
$key = array_key_first($array);
$value = self::arrayFlatten( $array[$key],$listFlatKeys);
if (in_array($key, $listFlatKeys)) {
return $value;
} else {
return [$key => $value];
}
}
$return = [];
foreach ($array as $key => $value) {
if (in_array($key, $listFlatKeys)) {
$return[] = self::arrayFlatten( $value, $listFlatKeys);
} else {
$return[$key] = self::arrayFlatten( $value, $listFlatKeys);
}
}
return $return;
}
I use it although in a Alias-similiar viewhelper, to get information of a flex-field in the frontend.

Related

How to upload a file with TYPO3 Fluid form.upload and pass it to Extbase controller

I am using the form.upload ViewHelper to upload a file.
<f:form enctype="multipart/form-data" action="list" name="import" object="{import}" method="POST">
<f:form.upload name="file" property="file" />
<f:form.submit value="Submit" />
</f:form>
The problem is accessing the file. The $import object contains a file name but the file does not exist.
My problem was, that the file was deleted already when it was handled. I redirected to another action in my controller action and this started a new request.
$this->redirect('list', $import);
The file will be deleted from the temporary directory at the end of the request if it has not been moved away or renamed.
(https://www.php.net/manual/en/features.file-upload.post-method.php)
How file is uploaded is not TYPO3 specific and can be handled differently, see link above.
You should also set the temporary path accordingly, see link above.
file types can be restricted with accept, e.g. accept='text/csv'
I am using this in a backend module. The following code works.
Fluid
<f:form enctype="multipart/form-data" action="create" name="import" object="{import}" method="POST">
<f:form.upload name="file" property="file" />
<f:form.submit value="Submit" />
</f:form>
Model class: Import.php
class Import extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
{
/** #var array */
protected $file = [];
/**
* #return array
*/
public function getFile()
{
return $this->file;
}
/**
* #param array $file
* #return void
*/
public function setFile(array $file)
{
$this->file = $file;
}
}
Controller createAction()
/**
* #param Import $import
* #return void
*/
public function createAction(Import $import)
{
$file = $import->getFile();
if ($file) {
$path = $file['tmp_name'];
}
// ...
}
The action gets called with Import object containing a file property with correctly filled out metadata, e.g.
['name'] = myfile.csv
['type'] = 'text/csv'
['tmp_name'] = '/tmp/hpGLv1E'
['error'] = 0
['size'] = 51550

"Could not analyse class: maybe not loaded or no autoloader?"

I created (my first) extension with one viewhelper.
Oops, an error occurred!
Could not analyse class:My\Mlv\ViewHelpers\Format\ReplacenewlinesViewHelper maybe not loaded or no autoloader?
In use (with news):
{namespace m=My\Mlv\ViewHelpers}
{newsItem.bodytext -> m:format.replacenewlines()}
Directory tree of extension:
typo3conf/ext/mlv
ext_emconf.php (copied from another ext)
/Classes
/ViewHelpers
/Format
ReplaceNewLinesViewHelper.php
ReplaceNewLinesViewHelper.php:
<?php
namespace My\Mlv\ViewHelpers\Format;
/**
* Replaces newlines in plain text with <br> tags.
*
* #author johndoe33
* #package Mlv
* #subpackage ViewHelpers\Format
*/
class ReplaceNewLinesViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* Replaces newlines in plain text with <br> tags.
*
* #param string $content
* #return string
*/
public function render($content = NULL) {
if (NULL === $content) {
$content = $this->renderChildren();
}
$content = str_replace( "\n", '<br>', $content );
return $content;
}
}
You need to use camel case in the view helper invocation:
{newsItem.bodytext -> m:format.replaceNewLines()}
Furthermore you may need to define an autoload definition in your ext_emconf.php if you're using TYPO3 >=7.6 (reinstall the extension after doing so):
'autoload' => array(
'psr-4' => array('My\\Mlv\\' => 'Classes')
)
For more information see: http://insight.helhum.io/post/130876393595/how-to-configure-class-loading-for-extensions-in

Sort by price low to high and high to low in product listing magento2

I am new in Magento 2. I am using Magento 2.1.1
I want to add custom price low to high and price high to low in Sort By dropdown in product listing page.
I didn't get toolbar.phtml page. Also I didn't get any stuff regarding this in google.
Step 1: Create plugins in
app/code/Vendor/Module/etc/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Catalog\Block\Product\ProductList\Toolbar">
<plugin name="custom_custom_block_toolbar" type="Vendor\Module\Plugin\Catalog\Block\Toolbar" />
</type>
<type name="Magento\Catalog\Model\Config">
<plugin name="custom_catalog_model_config" type="Vendor\Module\Plugin\Catalog\Model\Config" />
</type>
</config>
Step 2: Create Config.php in
app/code/Vendor/Module/Plugin/Catalog/Model/Config.php
<?php
namespace Vendor\Module\Plugin\Catalog\Model;
class Config
{
public function afterGetAttributeUsedForSortByArray(
\Magento\Catalog\Model\Config $catalogConfig,
$options
) {
$options['low_to_high'] = __('Price - Low To High');
$options['high_to_low'] = __('Price - High To Low');
return $options;
}
}
Step 3: Create Toolbar.php in
app/code/Vendor/Module/Plugin/Catalog/Block/Toolbar.php
<?php
namespace Vendor\Module\Plugin\Catalog\Block;
class Toolbar
{
/**
* Plugin
*
* #param \Magento\Catalog\Block\Product\ProductList\Toolbar $subject
* #param \Closure $proceed
* #param \Magento\Framework\Data\Collection $collection
* #return \Magento\Catalog\Block\Product\ProductList\Toolbar
*/
public function aroundSetCollection(
\Magento\Catalog\Block\Product\ProductList\Toolbar $subject,
\Closure $proceed,
$collection
) {
$currentOrder = $subject->getCurrentOrder();
$result = $proceed($collection);
if ($currentOrder) {
if ($currentOrder == 'high_to_low') {
$subject->getCollection()->setOrder('price', 'desc');
} elseif ($currentOrder == 'low_to_high') {
$subject->getCollection()->setOrder('price', 'asc');
}
}
return $result;
}
}

itemsProcFunc and selected items in TYPO3 6.2

I'm writing an extension which is configured via FlexForms. One element of the FlexForm is of type 'select', with maxitems > 1. I use itemsProcFunc to call an external class method modifying the 'items' array.
This works fine so far, but when I try to save the plugin options in BE, the entries under 'Selected:' vanish. However, the selected values are stored correctly. See below for my flexform configuration .
<settings.flexuserList>
<TCEforms>
<label>Sektionen</label>
<config>
<type>select</type>
<itemsProcFunc>tx_hevpersons_sections->dogetSectionInfo1</itemsProcFunc>
<maxitems>10000</maxitems>
<size>10</size>
</config>
</TCEforms>
</settings.flexuserList>
public function dogetSectionInfo1($params, $conf)
{
print_r($params['row']['pi_flexform']);
$flexform = \TYPO3\CMS\Core\Utility\GeneralUtility::xml2array($params['row']['pi_flexform']);
$grp = $flexform['data']['sDEF']['lDEF']['settings.flexroleList']['vDEF'];
$flexcantonval = $flexform['data']['sDEF']['lDEF']['settings.flexcanton']['vDEF'];
$flexsectionList = $flexform['data']['sDEF']['lDEF']['settings.flexsectionList']['vDEF'];
$flexuserList = $flexform['data']['sDEF']['lDEF']['settings.flexuserList']['vDEF'];
f( strstr( $grp , "|" ) ){
$string = explode(",",$grp);
foreach ($string as $key => $value) {
$array = explode('|',$value);
$nearay[$key] = $array[0];
}
}
if( count($nearay) ){
foreach ($nearay as $key => $value) {
$usergroupFind[$key] = 'FIND_IN_SET("'.$value.'",usergroup)';
}
$string = ' AND '.implode(' OR ', $usergroupFind) . ' ';
}
if( !empty($string) ){
$GLOBALS['TYPO3_DB']->store_lastBuiltQuery = 1;
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery("uid, name ", 'fe_users', 'deleted=0 AND disable=0 '.$string );
while($entry = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))
{
$params['items'][count($params['items'])] = array(trim($entry['name'] ), $entry['uid']);
}
$GLOBALS['TYPO3_DB']->sql_free_result($res);
}
return $params;
}
When a printed flexfrom , I got 2 xml records in which one has comma seperated values stored inside the xml while the other has empty values . Can some one help me with this ?
I think you should return config instead of params.
One of my working example, might be your helps:
TYPO3 v7.6.2
-FlexForm settings
<settings.eventID>
<TCEforms>
<label>Available Event</label>
<config>
<type>select</type>
<size>1</size>
<minitems>0</minitems>
<maxitems>1</maxitems>
<itemsProcFunc>VENDOR\EXT\Controller\ControllerName->flexFormsEventsListItems</itemsProcFunc>
<items type="array"></items>
</config>
</TCEforms>
</settings.eventID>
-Action
public function flexFormsEventsListItems($config){
$formsRepository = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('fields',
'table_name',
'WHERE clause', '', '', '', '');
$formsData = array(
'Events' => $formsRepository,
);
// create option list
$optionList = array();
foreach($formsRepository as $key=>$item){
$label = $item['title'];
$value = $item['uid'];
$optionList[] = array(0 => $label, 1 => $value);
}
// return config
$config['items'] = array_merge($config['items'], $optionList);
return $config;
}

Why is my Joomla user plugin not called?

I've written a small user plugin for Joomla! that should change the return url on logging in depending on the user's group. However, it's not even being called. What am I doing wrong?
class plgUserPluginName extends JPlugin
{
/**
* This method should handle any login logic and report back to the subject
*
* #param array $user Holds the user data
* #param array $options Array holding options (remember, autoregister, group)
*
* #return boolean True on success
* #since 1.5
*/
public function onUserLogin($user, $options = array())
{
$user = JFactory::getUser();
$db = JFactory::getDBO();
$db->setQuery(
'SELECT link_id FROM '.$db->quoteName('#__mt_links') .
' WHERE '.$db->quoteName('user_id').' = '.$db->quote($user->id)
);
$link_id = $db->loadResult();
if(!$link_id){
$db->setQuery(
'SELECT group_id FROM '.$db->quoteName('#__user_usergroup_map') .
' WHERE '.$db->quoteName('user_id').' = '.$db->quote($user->id)
);
$group_id = $db->loadResult();
if($group_id == somegroupid) $options['return'] = 'abc';
elseif($group_id == someothergroupid) $options['return'] = 'xyz';
}
return true;
}
}
My xml is:
<?xml version="1.0" encoding="utf-8"?>
<extension version="2.5" type="plugin" group="user">
<name>plg_user_pluginname</name>
<version>1.0.0</version>
<description>PLG_USER_PLUGINNAME_XML_DESCRIPTION</description>
<files>
<filename plugin="pluginname">pluginname.php</filename>
<filename>index.html</filename>
</files>
<languages>
<language tag="en-GB">en-GB.plg_user_pluginname.ini</language>
<language tag="en-GB">en-GB.plg_user_pluginname.sys.ini</language>
</languages>
<config>
</config>
</extension>
I am not sure which of the following two solved it, but
a) I renamed my plugin to plgUserPluginname instead of plgUserPluginName (small n for name)
b) I changed accessibility from Registered to Public
and it's being called now!