TCA für RTE und link wizards in 7.6

Der Code für ein RTE-Feld in einer eigenen Extension hat sich mit der Version 7.6 geändert. Die Syntax von TCA wizards hat sich geändert, das betrifft vor allem RTE und Typolinks.

Fehlermeldung:

The way registering a wizard in TCA has changed in 6.2 and was removed in CMS 7. Please set module[name]=module_name instead of using script=path/to/script.php in your TCA.

Alter Code für RTE (bis 6.2):

'wizards' => array(
   'RTE' => array(
      'icon' => 'wizard_rte2.gif',
      'notNewRecords'=> 1,
      'RTEonly' => 1,
      'script' => 'wizard_rte.php',
      'title' => 'LLL:EXT:cms/locallang_ttc.xlf:bodytext.W.RTE',
      'type' => 'script'
   )
)

Neuer Code für RTE wizard:

'wizards' => array(
    '_PADDING' => 2,
    'RTE' => array(
        'notNewRecords' => 1,
        'RTEonly' => 1,
        'type' => 'script',
        'title' => 'Full screen Rich Text Editing',
        'icon' => 'wizard_rte2.gif',
        'module' => array(
            'name' => 'wizard_rte',
        ),
    ),
),

Alter Code für Links (bis 6.2):

"wizards"  => array(
     "_PADDING" => 2,
     "link"     => array(
        "type"         => "popup",
        "title"        => "Link",
        "icon"         => "link_popup.gif",
        "script"       => "browse_links.php?mode=wizard",
        "JSopenParams" => "height=300,width=500,status=0,menubar=0,scrollbars=1"
     )
),

Neuer Code für Link wizard:

'wizards' => array(
   '_PADDING' => 2,
   'link' => array(
      'type' => 'popup',
      'title' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:header_link_formlabel',
      'icon' => 'actions-wizard-link',
      'module' => array(
          'name' => 'wizard_link',
      ),
      'JSopenParams' => 'height=300,width=500,status=0,menubar=0,scrollbars=1'
   ),
),
'softref' => 'typolink'

userFunc Tutorial 7.6

Tutorial für Version 10 und 11: https://www.auxweb.de/aktuelles/userfunc-tutorial

Mit UserFunc kann man PHP Code per TypoScript einbinden. Doch je nach Version werden UserFuncs anders eingebunden:

Geänderte userFunc Syntax

Die alten Namens-Konventionen (muss mit „user“ beginnen) entfallen.

Ab 7.4 hat sich die include Syntax geändert, config.includeLibrary und config.includeLibs wurden entfernt. Userfuncs müssen ab TYPO3 7.4 folgendermaßen eingebunden werden:

page.20 = USER_INT
page.20 {
  userFunc = user_printTime
  includeLibs = fileadmin/example_time.php
}

Einfache Extension für die userFunc

Empfohlen wird aber, die benötigten Klassen über eine Extension einzubinden und das Autoload-Verhalten mit Namepaces auszunutzen. Dafür ist minimal nötig (Beispiel – danke dafür an Peter Linzenkirchner):

Ein Ordner in typo3conf/ext/ mit diesem Inhalt:

  • typo3conf/ext/myincludes
  • typo3conf/ext/myincludes/Classes/
  • typo3conf/ext/myincludes/Classes/Example.php
  • typo3conf/ext/myincludes/ext_emconf.php
  • typo3conf/ext/myincludes/ext_icon.gif

Der Inhalt der ext_emconf.php:

<?php
$EM_CONF[$_EXTKEY] = array(
    'title' => 'Include all my Classes',
    'description' => 'Einbinden der Klassen für userFunc',
    'category' => 'fe',
    'author' => 'my Name',
    'author_email' => 'my Email',
    'state' => 'alpha',
    'author_company' => 'my Company',
    'version' => '0.0.1',
    'constraints' => array(
        'depends' => array(
        ),
        'conflicts' => array(
        ),
        'suggests' => array(
        ),
    ),
);

Der Inhalt der Example.php:

<?php 
namespace Myvendor\Myincludes;
class Example {
    public function myExampleFunction($content, $conf) {
        $color = $conf['userFunc.']['color'];
        return '<p style="color:' . $color. ';">Dynamic time: ' . date('H:i:s') . '</p><br />';
    }
}

Und der Aufruf im TS:

page.30 = USER_INT
page.30 {
  userFunc = Myvendor\Myincludes\Example->myExampleFunction
  userFunc.color = #ff0000
}

ExtBase Extension mit userFunc Action

Oft hat man bereits eine Extbase Extension und will eine bestimmte Action als userFunc aufrufen. Das geht so:

10 = USER_INT
10 {
    userFunc       = TYPO3\CMS\Extbase\Core\Bootstrap->run
    vendorName     = MyVendor\Myincludes
    extensionName  = MyExtension
    pluginName     = Pi1
    switchableControllerActions {
        Example {
            1 = myUserFunc
        }
    }
}

Und das ist der zugehörige Controller. Der Eintrag in switchableControllerActions ist nötig, da sonst die default listAction aufgerufen wird:

<?php
namespace MyVendor\MyExtension\Controller;

class ExampleController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
{
    public function listAction() {
        ...
    }
    
    public function myUserFuncAction() {
        return '<p style="color: red;">Dynamic time: ' . date('H:i:s') . '</p><br />';
    }

}

Weitere Infos zu der ExtBase Variante findet man hier: http://blog.teamgeist-medien.de/2014/03/typo3-eine-extbase-extension-per-typoscript-einbinden.html

Flexform Felder in MySQL abfragen

Das Abfragen von einzelnen Flexform-Werten per MySQL Statement ist genial einfach, wenn man die Funktion „ExtractValue“ verwendet. Damit kann man direkt auf einzelne XML Werte zugreifen und Abfragen damit erstellen.
Das ist das Beispiel-XML:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<T3FlexForms>
    <data>
        <sheet index="sDEF">
            <language index="lDEF">
                <field index="settings.title">
                    <value index="vDEF">Lorem Ipsum</value>
                </field>
                <field index="settings.details_link">
                    <value index="vDEF">233</value>
                </field>
            </language>
        </sheet>
        <sheet index="sTeaserBox">
            <language index="lDEF">
                <field index="settings.teaserBox_link">
                    <value index="vDEF">http://www.schmutt.com</value>
                </field>
                <field index="settings.teaserBox_buttontitel">
                    <value index="vDEF">Zur Homepage</value>
                </field>
            </language>
        </sheet>

Und dazu die MySQL Abfrage:

SELECT uid,pid,pi_flexform,ExtractValue(pi_flexform,'/T3FlexForms/data/sheet[@index="sTeaserBox"]/language/field[@index="settings.teaserBox_link"]/value') as val
FROM `tt_content`
WHERE pi_flexform LIKE '%settings.teaserBox_link%'
ORDER by val desc

Die Funktion ExtractValue ist seit MySQL 5.1.5 verfügbar:
https://dev.mysql.com/doc/refman/5.1/en/xml-functions.html

Die Syntax dazu ist XPath – hier ein gutes Tutorial:
http://www.zvon.org/xxl/XPathTutorial/General_ger/examples.html

ExtBase Backend Extension

This is a solution for a ExtBase Backend Extension with Ajax calls (usually required for ExtJS). It is based on this solution, which required lots of debugging until it worked for me (on 4.5): http://daniel.lienert.cc/blog/blog-post/2011/04/23/typo3-extbase-und-ajax/

This is the Ajax Request – notice „actionName“ instead of „action“ and lowercase/uppercase spellings:

Ext.Ajax.request({
  url:'ajax.php',
  params: {
    ajaxID: 'importexcelAjaxDispatcher',
    request: Ext.encode({
      extensionName:'ImportExcel',
      pluginName:'importexcel',  //this is from ext_tables.php, Tx_Extbase_Utility_Extension::registerModule(x,x,pluginName,...), often Pi1 or mod1
      controllerName:'ImportExcel',
      actionName:'testAjax',
    })
  },
  success:function(response, request) {
    //do something
  },
  failure: function(response, request) {
       console.log('server-side failure with status code ' + response.status);
  }
});

Then register the Ajax Dispatcher in ext_localconf.php:

$TYPO3_CONF_VARS['BE']['AJAX']['importexcelAjaxDispatcher'] = t3lib_extMgm::extPath($_EXTKEY).'Classes/Domain/Utility/AjaxDispatcher.php:Tx_ImportExcel_Domain_Utility_AjaxDispatcher->initAndDispatch';

Get the Ajax Dispatcher from pt_extbase/Classes/Utility/AjaxDispatcher. For any unknown reason, the response is still a full HTML page, so here is my modification of dispatch function. I check the successfull calls with devLog.

public function dispatch() {
        t3lib_div::devLog('Ajax dispatch','import_excel',0,array('ExtensionName'=>$this->extensionName,'PluginName'=>$this->pluginName));

        $configuration['extensionName'] = $this->extensionName;
        $configuration['pluginName'] = $this->pluginName;

        $bootstrap = t3lib_div::makeInstance('Tx_Extbase_Core_Bootstrap');
        $bootstrap->initialize($configuration);

        $this->objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_ObjectManager');

        $request = $this->buildRequest();
        $response = $this->objectManager->create('Tx_Extbase_MVC_Web_Response');

        $dispatcher =  $this->objectManager->get('Tx_Extbase_MVC_Dispatcher');
        $dispatcher->dispatch($request, $response);       

        //parse content from HTML
        preg_match('/!#!#!(.*)!#!#!/',$response->getContent(),$match);
        t3lib_div::devLog('Ajax response','import_excel',0,array($content,$match));

        $response->sendHeaders();
        if ($match[1]) {
            echo $match[1];    
        } else{
            echo $response->getContent();
        }

        return;
    }

And finally my Action:

class Tx_ImportExcel_Controller_ImportExcelController extends Tx_Extbase_MVC_Controller_ActionController {

public function testAjaxAction() {
        t3lib_div::devLog('testAjaxAction called','import_excel',0,array());
         $test = array('test'=>1, 'test2'=>'Hello from Extbase');
         $result = json_encode($test);
         return '!#!#!'.$result.'!#!#!';
    }
}

View „TestAjax.html“ is an empty file.

Wo findet FE Login statt?

Wo ist eigentlich der Code für den TYPO3 Frontend Login? Denn der ist nicht wie gedacht in der sysext „fe_login“ – es findet noch nicht mal ein direkter Aufruf statt. Allein das übermitteln von „user“, „pass“ und „logintype“=“login“ startet bereits die Authentifizierung.

Zuerst mal die Basis-Klassen von TYPO3: Weiterlesen