1. www.e-net.info
Extbase zu Ende gespielt...!?
T3ak12 - Februar 2012
e-net Consulting GmbH & Co. KG
Helge Funk - @tox234
Christian Kuhn - @lolli42
2. Übersicht
• XCLASS on steroids
• Globaler Namespace in Fluid
• Argumente für Partials
• Request Handler
• Objekthierarchien auf Datenbankebene
• Propertyabhängige Validierung
• Fluid Goodies
3. XCLASS on steroids
• Klassen und Interface-Implementierungen werden per TypoScript registriert
config.tx_extbase {
objects {
Tx_Extbase_MVC_Controller_FlashMessages {
className = Tx_T3Ak12_MVC_Controller_FlashMessageContainer
}
Tx_T3Ak12_MyObjectInterface {
className = Tx_T3Ak12_Domain_Model_MyObject
}
}
}
• t3lib_div::makeInstance vs. Tx_Extbase_Object_ObjectManager
$myObject = t3lib_div::makeInstance('Tx_T3Ak12_Domain_Model_MyObject');
$myObject = $this->objectManager->get('Tx_T3Ak12_MyObjectInterface');
Der Object Manager ruft – im Gegensatz zu makeInstance() – nach dem Konstruktor zuerst existierende
inject* Methoden und dann initializeObject() auf.
4. XCLASS on steroids
• Implementierung
interface Tx_T3Ak12_MyObjectInterface {
public function setValue(array $data);
}
class Tx_T3Ak12_Domain_Model_MyObject implements Tx_T3Ak12_MyObjectInterface {
protected $data;
public function setValue(array $data) {
$this->data = $data;
}
}
• Injection
class Tx_T3Ak12_Controller_MyController {
/**
* @var Tx_T3Ak12_MyObjectInterface
*/
protected $myObject;
/**
* @param Tx_T3Ak12_MyObjectInterface $myObject
*/
public function injectMyObject(Tx_T3Ak12_MyObjectInterface $myObject) {
$this->myObject = $myObject;
}
}
5. Globaler Namespace in Fluid
• Globale Anmeldung eines Namespaces in Fluid-Templates für Standard-Libraries
config.tx_extbase {
objects {
Tx_Fluid_Core_Parser_TemplateParser {
className = Tx_T3Ak12_View_TemplateParser
}
}
}
class Tx_T3Ak12_View_TemplateParser extends Tx_Fluid_Core_Parser_TemplateParser {
protected $namespacesBase = array();
public function initializeObject() {
$this->namespacesBase = $this->namespaces += array(
't3ak12' => 'Tx_T3Ak12_ViewHelpers'
);
}
protected function reset() {
$this->namespaces = $this->namespacesBase;
}
}
Der Namespace steht nun global in Fluid-Templates zur Verfügung:
<t3ak12:customViewHelper foo=“bar“ />
6. Argumente für Partials
• Übergabe aller Templatevariablen über {_all} ab TYPO3 4.6 möglich
<f:render partial="ListElement" arguments="{_all}" />
• Backport für TYPO3 4.5
class Tx_T3Ak12_Core_ViewHelper_TemplateVariableContainer
extends Tx_Fluid_Core_ViewHelper_TemplateVariableContainer {
static protected $reservedVariableNames = array(
'true', 'false', 'on', 'off', 'yes', 'no', '_all'
);
public function get($identifier) {
if ($identifier === '_all') {
return $this->variables;
}
if (!array_key_exists($identifier, $this->variables)) {
// throw Exception here ...
}
return $this->variables[$identifier];
}
public function exists($identifier) {
if ($identifier === '_all') {
return TRUE;
}
return array_key_exists($identifier, $this->variables);
}
}
7. Request Handler
• Aufbereitung des Requests in verschiedenen Scopes: Web (FE/BE), CLI,
WebService
• z.B. FrontendRequestHandler: Verifizierung des Request Hash, Cache Handling
• CLI Request Handler ab TYPO3 4.7 verfügbar
• LwEnetMultipleActionForms -> Aufbereitung des Request mit Session-Daten
config.tx_extbase.mvc.requestHandlers {
Tx_T3Ak12_Web_FrontendRequestHandler = Tx_T3Ak12_Web_FrontendRequestHandler
}
class Tx_T3Ak12_Web_FrontendRequestHandler ... {
public function handleRequest() {
…
$this->dispatcher->dispatch($request, $response);
return $response;
}
public function canHandleRequest() {
// Can this request be handled
}
public function getPriority() {
return 110; // Priority chain
}
}
9. Objekthierarchien auf Datenbankebene
• Basisklasse: Übergreifende Eigenschaften
interface Tx_T3Ak12_Domain_Model_ProductInterface extends Tx_Extbase_DomainObject_DomainObjectInterface
{
public function getName();
public function setName($name);
public function getPrice();
public function setPrice($price);
}
class Tx_T3Ak12_Domain_Model_Product extends Tx_Extbase_DomainObject_AbstractEntity implements
Tx_T3Ak12_Domain_Model_ProductInterface {
protected $name;
public function getName() {code for getter}
public function setName($name) {code for setter}
protected $price;
public function getPrice() {code for getter}
public function setPrice($price) {code for setter}
}
10. Objekthierarchien auf Datenbankebene
• Erweiterte Produktklasse
interface Tx_T3Ak12_Domain_Model_ShirtInterface {
public function getColor();
public function setColor($color);
public function getSize();
public function setSize($size);
}
class Tx_T3Ak12_Domain_Model_Shirt extends Tx_T3Ak12_Domain_Model_Product implements
Tx_T3Ak12_Domain_Model_ShirtInterface {
protected $color;
public function getColor() {code for getter}
public function setColor($color) {code for setter}
protected $size;
public function getSize() {code for getter}
public function setSize($size) {code for setter}
}
11. Objekthierarchien auf Datenbankebene
• Repositories: Über findAll() werden nur die entsprechenden Objekte geliefert
class Tx_T3Ak12_Domain_Repository_ProductRepository
extends Tx_Extbase_Persistence_Repository {}
class Tx_T3Ak12_Domain_Repository_ShirtRepository
extends Tx_T3Ak12_Domain_Repository_ProductRepository {}
• TCA
$TCA['tx_lwsmaproducts_domain_model_product']['ctrl']['type'] = 'record_type';
• Mapping
config.tx_extbase.persistence.classes {
Tx_T3Ak12_Domain_Model_Product {
mapping.tableName = tx_t3ak12_domain_model_product
mapping.recordType = Tx_T3Ak12_Domain_Model_Product
subclasses {
Tx_T3Ak12_Domain_Model_Shirt = Tx_T3Ak12_Domain_Model_Shirt
}
}
Tx_T3Ak12_Domain_Model_Shirt {
mapping.tableName = tx_t3ak12_domain_model_product
mapping.recordType = Tx_T3Ak12_Domain_Model_Shirt
}
}
12. Propertyabhängige Validierung
• Property kann nicht in Abhängigkeit zu anderen Properties validiert werden
• kein Zugriff auf andere Property-Werte innerhalb eines Property-Validators
/**
* @var string
* @validate StringLength(minimum='42')
*/
protected $property;
• Standardlösung in extbase: ModelValidator
• Automatischer Aufruf, keine Registrierung notwendig, Aufruf nach Property-
Validatoren
class Tx_T3Ak12_Domain_Model_'ModelName' extends
Tx_Extbase_DomainObject_AbstractEntity {
}
class Tx_T3Ak12_Domain_Validator_'ModelName'Validator extends
Tx_Extbase_Validation_Validator_AbstractValidator {
public function isValid($object) {
$isValid = TRUE;
if ($object->getSecondProperty() === 'foo' ) {
$notEmptyValidator = $this->validatorResolver->createValidator('NotEmpty');
$isValid = $notEmptyValidator->isValid($object->getFirstProperty());
}
return $isValid;
}
}
14. Fluid Goodies
• Partials einer anderen Extension rendern
• Externe Partials können verschachtelt werden
• Innerhalb von Forms verwendbar → Tokengenerierung
<fx:render partial="Foo/Bar/Baz" arguments="{_all}" extensionName="T3Ak12" />
• String-Vergleich für if-ViewHelper
<f:if condition="{object.property} == abc">
baz
</f:if>