View
1.617
Download
5
Category
Preview:
DESCRIPTION
Einige Codebeispiele sind in der Präsentation abgeschnitten. Ladet Euch die Präsentation herunter und öffnet sie mit LibreOffice 3.5, dann klappt's.
Citation preview
T3CB12
Großprojekt auf Basis von Extbase/Fluid
Datenmenge: > 1.700.000
Seitenaufbau: < 3 Sekunden
+[werk] - Was machen wir?
Agentur - Firmenverbund
unabhängig, inhabergeführt
TYPO3 & Magento
Kiel, Hamburg, Aachen, Köln, Frankfurt, München
team:inmedias
www.kennziffer.com
PAGEmachine
Splendid
creativestyle
Agenda
Vorstellung des Projekts
Extbase Query
Geschwindigkeit
Fluid
Programmierung
Wartung
Fazit
Worum geht’s eigentlich?
Austausch von Belegdaten im Extranet:
Zahlungsfälligkeiten
Kontoauszüge
Belege & Buchungshilfe
Zahlungsavise
Umsatzstatistik
Belege stehen als pdf/ZIP-Datei zur Verfügung.
Alle Daten: drucken, exportieren, herunterladen
Was war los?
Viele Requests
Spalten ausblenden
Sortieren
Geschwindigkeit (5 bis 35 Sekunden)
Alte Programmierung (piBase)
Nicht mehr wartbar
Schnuckelig groß größer kaputt→ → →
Das Projekt
Ehrlich: Kunde wünschte Extbase
Implementierung neuer Features
Flüssigeres Arbeiten (Geschwindigkeit)
Weniger SOAP-Abfragen
Besseres Dokumentenmanagement (pdf/zip)
Das Projekt
(fast) LIVE
Extbase Query
Keine Unterstützung für:
GROUP BY
SUM
SELECT field1, field2
Aufbohren des Query- und Typo3Db-Objektes
class Tx_KeZr_Persistence_Query extends Tx_Extbase_Persistence_Query {
protected $groupBy = array();
public function setGroupBy(array $columns) {
$this->groupBy = $columns;
return $this;
}
KE: QueryObjekt
class Tx_KeZr_Persistence_Storage_Typo3DbBackend extends Tx_Extbase_Persistence_Storage_Typo3DbBackend {
public function parseQuery(Tx_Extbase_Persistence_QueryInterface $query, array &$parameters) {
... $this->parseGroupBy($query->getGroupBy(), $source, $sql);
... } public function buildQuery(array $sql) { ... if (!empty($sql['groupBy'])) {
KE: Typo3DbBackend
Geschwindigkeit Cache
Einrichtung Caching-Framework
Einrichtung Redis-Server
Programmierung eines Caching-Objektes
Auch Objekte können serialisiert abgelegt werden
Caching von Benutzerdaten
Cache-Objekt
public function __construct() {
parent::__construct();
$this->initializeCache();
}
public function initializeCache() {
t3lib_cache::initializeCachingFramework();
try {
$this->cache = $GLOBALS['typo3CacheManager']->getCache('keZr');
Geschwindigkeit SOAP-Abfragen
SOAP schneller als MySQL
GROUP BY auf MySQL trotz Index zu langsam
SOAP-Abfragen werden gecached
Cache-Objekt
Programmierung eines SOAP-Objektes
Soap-Objekt
public function SfGetSuppliers($dNr, $enableColHeader = false) {
$this->initialize();
if(!empty($dNr)) {
if($this->cache->has('suppliers' . $dNr)) {
return $this->cache->get('suppliers' . $dNr);
} else {
$parameters = array(
new SoapParam($this->getPassPhrase(),
Fluid Probleme
f:format.date mit @timestamp
Datum verschiebt sich um eine Stunde
f:format.currency
Ein leerer String benötigt 24ms
Ein Floatwert wie 0.00 benötigt 1ms
Fluid ViewHelper
DurationViewHelper
Wie lange (in ms) benötigt ein Fluidabschnitt?
GetValueOfObjectViewHelper
Da {invoice.{field}} nicht geht.
Timestamp2DateTimeViewHelper
@timestamp erzeugt falsche Datumswerte
SumColsViewHelper
Summiere bestimmte Felder in einem Array/Objekt
DurationViewHelper
class Tx_KeZr_ViewHelpers_DurationViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractConditionViewHelper {
public function render($name = '') {
$label = $name ? $name : 'Milliseconds';
$start = t3lib_div::milliseconds();
$content = $this->renderChildren();
$end = t3lib_div::milliseconds();
t3lib_utility_Debug::debug($end - $start,
Timestamp2DateTimeVH
class Tx_KeZr_ViewHelpers_Timestamp2DateTimeViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractConditionViewHelper {
public function render($timestamp = NULL) {
if($timestamp === NULL) {
$timestamp = $this->renderChildren();
if($timestamp === NULL) {
return '';
FED ViewHelper
SwitchViewHelper
+1000 um den in den Fluidcore zu integrieren
IfViewHelper
Alles möglich: &&, ||, Stringvergleiche
ExplodeViewHelper
CSV ==> Array
AJAX
Danke an Alex Kellner
http://pastebin.com/pdYZLjGn
Configuration erstellen
Neuer Bootstrap
Action und Controller angeben
Extbasebasiert weitercoden...
AJAX
class Tx_KeZr_Ajax_UserConfig { protected $bootstrap; protected $configuration = array(); public function __construct() { $this->configuration = array(
'pluginName' => 'Pi1', 'extensionName' => 'KeZr', 'controller' => 'UserConfig', 'mvc' => array( 'requestHandlers' => array( 'Tx_Extbase_MVC_Web_FrontendRequestHandler' => 'Tx_Extbase_MVC_Web_FrontendRequestHandler'
) ), 'persistence' => array( 'classes' => array( 'Tx_KeZr_Domain_Model_FeUser' => array( 'mapping' => array(
'tableName' => 'fe_users', 'recordType' => '' ) ) ) ),
'settings' => array() ); $_POST['tx_kezr_pi1']['controller'] = 'UserConfig'; $this->bootstrap = new Tx_Extbase_Core_Bootstrap(); } public function addHiddenCol() {
$this->configuration['action'] = 'addHiddenCol'; $_POST['tx_kezr_pi1']['action'] = 'addHiddenCol';
OOP
Jeder erdenkliche Bereich hat ein eigenes Objekt
Zeilen pro Methode drastisch reduziert
Teilweise sogar mit TDD (phpUnit)
Used the extbase way
Teilbereiche 3mal neu programmiert
Alle Views erben von einer abstrakten Klasse
Alle Repositories erben von abstrakter Klasse
Modelle
Trotz 1 Tabelle 13 Modelle
Für jede Gruppierung ein Modell
Filter mit Selectboxen
Modelle bauen sich gegenseitig auf (extends)
Sicherheit
Used the extbase way (Validatoren)
Per TS konfigurierbare Filter pro View
Inkl. DB-Abfrage
download {
varType = string
queryType = equals
required = 1
override = NULL
}
Sicherheit GET/POST
public function getConstraint($for, $value) { $filterSettings = $this->settings['filter']; $property = $filterSettings[$for]['property'] ? $filterSettings[$for]['property'] : $for; if($filterSettings[$for]['required'] && empty($value) || $for == 'posStatus' && $value == '1') return false;
switch($filterSettings[$for]['varType']) { case 'array': if(!is_array($value)) throw new Tx_Extbase_Exception('The requested GET/POST var has the wrong var type',
1331648203); break; case 'int': case 'integer': $value = intval($value);
break; case 'date': if(!$value instanceof DateTime) { $value = $this->date->createDateTimeFromString($value); } break;
case 'string': case 'text': if(is_string($value)) { $value = htmlspecialchars($value); } break;
Default: ... } $query = $this->createQuery(); if($filterSettings[$for]['negate']) {
Dynamik
Jede Spalte pro Ansicht per TS konfigurierbar
Alternativ stdWrap zubuchbar
DirectReturn
Eigene Variablen definierbar
Class, enabled, isCurrency, isSumable
Jeder Filter als Partial verfügbar (TS)
Dynamik per TS
k_name1 {
enabled = 1
field = kName1
directReturn = 1
}
sum_nettobetrag {
enabled = 1
field = sumNettobetrag
isCurrency = 1
Usability
Ausgeblendete Spalten ohne Neuladen
Dank AJAX dauerhafte Speicherung
Sortieren ohne Neuladen
Ähnliche Filter werden übernommen
CSV-Export Dank JS (DataTables)
Schneller PDF-Export Dank PreCaching (Redis)
Wartung
Viele Arbeiten direkt über TS möglich (1223)
Dank Struktur schnelles Auffinden der richtigen Stelle möglich
Einfache Erweiterbarkeit. 1 View = 1 Stunde
+ individuelle Anpassungen :-)
TDD
MySQL
Erstellung von 5 Indizies
35 Sekunden ==> 1,5 Sekunden
Filesorts vermieden bzw. konfiguriert
Analysiert mit set profiling=1
1 Woche MySQL-Konfiguration
Inkl. Strukturänderungen
Text ==> tinytext ==> varchar/char
Int ==> tinyint oder int(2)
MySQL Konfiguration
key_buffer
innodb_buffer_pool_size
tmp_table_size
sort_buffer
query_cache_min_res_unit
query_cache_limit
read_rnd_buffer_size
Fazit
Die meisten Ansichten lassen sich in unter 3 Sekunden darstellen. Je nach Filter kann es bis zu 8 Sekunden dauern
Die meisten Wartungsarbeiten lassen sich binnen 15-30 Minuten erledigen
Erweiterungen/Zusatzwünsche lassen sich Dank Modularität und Struktur besser implementieren
Wir können Extbase!!!
1 Großprojekt
Mehrere kleine individuelle Extbaseextensions
3 Extbaseprofis und es werden mehr
Doku von Stefan Frömken wird Vorlage für extbase.typo3.org
Danke ...
für's Zuhören
für Rückfragen
für Applaus
an die Community
an die TYPO3-Entwickler
an das Catering :-)
Magnus Schubert & Stefan Frömken | www.kennziffer.com GmbH
Recommended