Extbase - Zugriff auf Tabellen anderer Extbase Extensions
Für manche Tabellen (z.B. fe_user) bietet Extbase bereits vorgefertigte Mappings und Models, die man per extends erben kann. In diesem Fall spart man sich das erstellen eigener Models, Domains und getter und setter Funktionen. Auch das Mapping fällt kürzer aus. Beispiele siehe hier:
Extbase - Zugriff auf die fe user Tabelle
In den folgenden Beispielen gehen wir davon aus, das Extbase nichts zur Verfügung stellt.
Beispiele
Beispiel für tt_content von t3developer.com
http://t3-developer.com/extbase-fluid/extensions-erweitern/allgemein/tt-content-in-extbase/ (2015-06)
tt_content Inhalte in Extbase Fluid Extensions
Um auf die Inhalte der tt_content Tabelle zugreifen zu können, werden folgende Dateien benötigt:
myExtension/Configuration/TypoScript/Setup.txt
Mapping der Tabelle auf ein Extension Model. Die Setup Datei muss in der ext_tables.php eingebunden werden:
t3lib_extMgm::addStaticFile($_EXTKEY, 'Configuration/TypoScript', 'Setup');
Das wurde normalerweise schon vom Extension Builder erledigt.
myExtension/Classes/Domain/Model/Content.php
Im Snippet sind nur die Getters für die wichtigsten tt_content Inhalte angelegt. Wer tt_content Daten in seiner Extension ändern will, muss die entsprechenden Setters nachtragen.
myExtension/Classes/Domain/Repositoryl/ContentRepository.php
Normale Repository Class für individuelle Abfragen.
Mapping im Setup
Hinweis: Felder deren Namen in der Syntax field_name werden automatisch in UpperCamelCase Felder gemapped und müssen in den columns nicht aufgeführt werden, in dem Beispiel sind sie nur volsständiger weise angegeben.
config.tx_extbase {
persistence{
enableAutomaticCacheClearing = 1
updateReferenceIndex = 0
classes {
Tx_MyExtension_Domain_Model_Content {
mapping {
tableName = tt_content
columns {
uid.mapOnProperty = uid
pid.mapOnProperty = pid
sorting.mapOnProperty = sorting
CType.mapOnProperty = contentType
header.mapOnProperty = header
header_link.mapOnProperty = headerLink
bodytext.mapOnProperty = bodytext
image.mapOnProperty = image
image_link.mapOnProperty = imageLink
colPos.mapOnProperty = colPos
}
}
}
}
}
}
Model
Nach und nach werden ja auch viele Core Tabellen um Models ergänzt. Hier könnte also auch das Core Model extended werden und man spart sich die ganzen Objektdeklarationen und Getter.
/***************************************************************
* Copyright notice
*
* (c) 2012 Klaus Heuer <klaus.heuer@t3-developer.com>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* Class for the tt_content
*
* represents the Content Model
*
*
*/
/**
* @scope prototype
* @entity
*/
class Tx_MyExtension_Domain_Model_Content extends Tx_Extbase_DomainObject_AbstractEntity {
/**
* uid
* @var int
* @validate NotEmpty
*/
protected $uid;
/**
* pid
* @var int
* @validate NotEmpty
*/
protected $pid;
/**
* sorting
* @var int
* @validate NotEmpty
*/
protected $sorting;
/**
* header
* @var string
*
*/
protected $header;
/**
* headerLink
* @var string
*
*/
protected $headerLink;
/**
* bodytext
* @var string
*
*/
protected $bodytext;
/**
* image
* @var string
*
*/
protected $image;
/**
* imageLink
* @var string
*
*/
protected $imageLink;
/**
* colPos
* @var int
*
*/
protected $colPos;
/**
* Returns the pid
*
* @return int $pid
*/
public function getPid() {
return $this->pid;
}
/**
* Returns the sorting
*
* @return int $sorting
*/
public function getSorting() {
return $this->sorting;
}
/**
* Returns the header
*
* @return string $header
*/
public function getHeader() {
return $this->header;
}
/**
* Returns the headerLink
*
* @return string $headerLink
*/
public function getHeaderLink() {
return $this->headerLink;
}
/**
* Returns the bodytext
*
* @return string $bodytext
*/
public function getBodytext() {
return $this->bodytext;
}
/**
* Returns the image
*
* @return string $image
*/
public function getImage() {
return $this->image;
}
/**
* Returns the imageLink
*
* @return string $imageLink
*/
public function getImageLink() {
return $this->imageLink;
}
/**
* Returns the colPos
*
* @return int $colPos
*/
public function getColPos() {
return $this->colPos;
}
}
Repository
class Tx_MyExtension_Domain_Repository_ContentRepository extends Tx_Extbase_Persistence_Repository {
protected $defaultOrderings = array('sorting' => Tx_Extbase_Persistence_QueryInterface::ORDER_ASCENDING);
}
Beispiel: Daten von anderen Extensions - Kurzform
Basiert auf dem derhansen Beispiel von unten.
Ziel Extension2 (ext2) nutzt Daten von Extension1 (ext1). Beide sind selbst erstellt. An ext1 wird nichts geändert. Alle Codes betreffen ext2. Die Daten sind hier gespeichert.
plugin.tx_ext1. persistence.storagePid = 5
plugin.tx_ext2. persistence.storagePid = 6
Domainmodel anlegen
Für die Daten von ext1 wird ein Model in ext2 angelegt. Das Model erweitert das Model von ext1 und erbt so seine Eigenschaften. Diese sind dann ext2 bekannt.
ext2\Classes\Domain\Model\ Modelname.php
<?php
namespace Vendor\Ext2\Domain\Model;
class Modelname extends \Vendor\Ext1\Domain\Model\Modelname {
}
Repository anlegen
Zum Datenzugriff benötigen wir ein Repository für das neue Model.
ext2\Classes\Domain\Repository\ ModelnameRepository.php
<?php
namespace Vendor\Ext2\Domain\Repository;
class ModelnameRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
}
Repository injecten
Das neue Repository wird im gewünschten Controller von ext2 per Dependency Injection verfügbar gemacht.
/**
* @var \Vendor\Ext2\Domain\Repository\DeviceRepository
* @inject
*/
protected $deviceRepository = NULL;
Wer an dieser Stelle jetzt schon erste Ergebnisse aus dem implementierten Repository erwartet, wird enttäuscht und bekommt beim Versuch Daten aus dem Repository abzufragen/anzuzeigen eine Exception vom Typ Tx_Extbase_Persistence_Storage_Exception_SqlError, welche besagt, dass eine Tabelle nicht existiert.
Die Extension testext2 weiß also anscheinend noch gar nicht, aus welcher Tabelle die Daten des neuen Repositories abgefragt werden sollen. Um dieses einzurichten, muss man im Typoscript Setup von testext2 ein Mapping einrichten.
config.tx_extbase {
persistence {
classes {
Tx_Testext2_Domain_Model_Testext1Table {
mapping.tableName = tx_testext1_domain_model_testext1table
}
}
}
}
An dieser Stelle ist es wichtig, dass das Mapping direkt auf den Tabellennamen in der Datenbank stattfindet.
Auch jetzt erhalten wir über das neue Repository in testext2 noch keine Daten, da die testext2 noch nicht weiß, in welcher 'StoragePid' die Datensätze von testext1 liegen. Hierzu ergänzt man lediglich die Typoscript Constants von testext2 wie folgt.
plugin.tx_testext2 {
persistence {
storagePid = 6,5
}
}
Die StoragePid von testext1 wurde hinter der StoragePid von testext2 angehängt. Nun kann das neue Repository in testext2 angesprochen und die erwarteten Daten erfolgreich zurückgeliefert werden.
Beispiel von derhansen.de
http://www.derhansen.de/2012/10/mapping-anderer-tabellen-in-extbase.html
Mapping anderer Tabellen in Extbase
Neulich stand ich vor der eigentlich recht simplen Aufgabe aus einer Extbase Extension heraus auf die erzeugten Daten einer anderen Extbase Extension zuzugreifen. Im Web gibt es auch einige Tutorials, welche beschreiben wie man dieses macht, aber fast alle zeigen, wie man auf die Tabellen fe_users und fe_groups zugreift, welche beide schon als Domain-Model bei Extbase mitgeliefert werden. Ein funktionierendes Praxisbeispiel für den Zugriff auf eigene Datenstrukturen konnte ich leider nicht finden.
In diesem Beitrag zeige ich deshalb, wie man aus einer Extbase Extension heraus auf die Daten einer anderen Extbase Extensions zugreifen kann.
Ausgangssituation:
In einer TYPO3 Installation wurden 2 Extbase Extensions (testext1 und testext2) eingerichtet, welche jeweils eigene Repositories und Storagefolder haben. Die Typoscript Constants der Extensions sind wie folgt eingerichtet:
plugin.tx_testext1 {
persistence {
storagePid = 5
}
}
plugin.tx_testext2 {
persistence {
storagePid = 6
}
}
Die Datensätze von testext1 werden also im Sysordner mit der Pid 5 abgelegt und die Datensätze von testext2 im Sysordner mit der Pid 6. In testext1 gibt es ein Domainmodel mit dem Namen Testext1Table und in testext2 gibt es ein Domainmodel mit dem Namen Testext2Table.
Ziel ist es nun, aus einem Controller in testext2 auf die angelegten Daten von testext1 zuzugreifen.
Vorgehensweise:
Als erstes muss in testext2 ein Domainmodel angelegt werden, welches das Domainmodel von textext1 extended. Also wird in textext2\Classes\Domain\Model\ die Datei Testext1Table.php angelegt.
textext2\Classes\Domain\Model\ Testext1Table.php
class Tx_Testext2_Domain_Model_Testext1Table extends Tx_Testext1_Domain_Model_Testext1Table {
}
Somit wurde der testext2 schon mal das Domainmodel aus testext1 bekannt gemacht. Damit wir auf die Daten aus testext1 zugreifen können, wird noch ein entsprechendes Repository benötigt. Dieses wird in
textext2\Classes\Domain\Repository\Testext1TableRepository.php definiert.
class Tx_Testext2_Domain_Repository_Testext1TableRepository extends Tx_Extbase_Persistence_Repository {
}
Nun kennt die Extension testext2 das Domainmodel und hat auch ein entsprechendes Repository. Das neue Repository wird in einem Controller von testext2 per Dependency Injection implementiert.
/**
* testext1TableRepository
*
* @var Tx_Testext2_Domain_Repository_Testext1TableRepository
*/
protected $testext1TableRepository;
/**
* injectTestext1TableRepository
*
* @param Tx_Testext2_Domain_Repository_Testext1TableRepository $testext1TableRepository
* @return void
*/
public function injectTestext1TableRepositoryRepository(Tx_Testext2_Domain_Repository_Testext1TableRepository $testext1TableRepository) {
$this->testext1TableRepository = $testext1TableRepository;
}
Wer an dieser Stelle jetzt schon erste Ergebnisse aus dem implementierten Repository erwartet, wird enttäuscht und bekommt beim Versuch Daten aus dem Repository abzufragen/anzuzeigen eine Exception vom Typ Tx_Extbase_Persistence_Storage_Exception_SqlError, welche besagt, dass eine Tabelle nicht existiert.
Die Extension testext2 weiß also anscheinend noch gar nicht, aus welcher Tabelle die Daten des neuen Repositories abgefragt werden sollen. Um dieses einzurichten, muss man im Typoscript Setup von testext2 ein Mapping einrichten.
config.tx_extbase {
persistence {
classes {
Tx_Testext2_Domain_Model_Testext1Table {
mapping.tableName = tx_testext1_domain_model_testext1table
}
}
}
}
An dieser Stelle ist es wichtig, dass das Mapping direkt auf den Tabellennamen in der Datenbank stattfindet.
Auch jetzt erhalten wir über das neue Repository in testext2 noch keine Daten, da die testext2 noch nicht weiß, in welcher 'StoragePid' die Datensätze von testext1 liegen. Hierzu ergänzt man lediglich die Typoscript Constants von testext2 wie folgt.
plugin.tx_testext2 {
persistence {
storagePid = 6,5
}
}
Die StoragePid von testext1 wurde hinter der StoragePid von testext2 angehängt. Nun kann das neue Repository in testext2 angesprochen und die erwarteten Daten erfolgreich zurückgeliefert werden.