TYPO3 Extension development using new Extbase framework
-
Upload
christian-trabold -
Category
Technology
-
view
6.463 -
download
4
description
Transcript of TYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase framework
2011/02/18, T3Ski11 TokyoChristian Trabold
About me
Christian TraboldSenior Developerdkd Internet Service GmbH
TYPO3 since 2004
Focus on quality assurance
Author of TYPO3 Cookbook, O'Reilly
320 x 480Vertical Resolution
Carrier 12:34 PMWeb Page Title
http://host.domain.tld
Agenda - Part 1
- TYPO3 basics
- Find extensions with TER
- Get your ideas into TYPO3
- Question and answers
Agenda - Part 2
- Create example application
- See kickstarter in action
- Customize !les to your needs
- Question and answers
Goal of this workshop
Get the big picture
Understand concepts
Find nice Sushi bars
320 x 480Vertical Resolution
Carrier 12:34 PMWeb Page Title
http://host.domain.tld
Part 1TYPO3 Basics
http://www.flickr.com/photos/grendelkhan/121671781/sizes/l/in/photostream/
Extensions
Frontend
Backend
TYPO3 is like Sushi
Extensions extendeverything
Extensions containyour PHP code
Extensions containyour ideas
Inspiring people to share
How to !nd extensions
typo3.org/extensions/
List extensions
Extension details
View !les
Extension manager
Extension details
Read documentation
Look into !les
Security and con!dence
It is very important that you check every detail of an extensionbefore you install.
What if nothing !ts?
http://www.flickr.com/photos/rreid/420388478/
Add your own creation
How do you startyour own creation?
Understandextension structure
Install extbase kickstarter
Andstart coding!
Why do I need a kickstarter?
Faster and less errors
The kickstarter does all the boring work
You can focus on your ideas and design
= more fun!
TYPO3 has old and new extension styles
Old pi_baseNew extbase
Old pi_baseNew extbase
We will focus on the new extbase kickstarter
✘
!"" ChangeLog!"" doc# !"" wizard_form.dat# %"" wizard_form.html!"" ext_emconf.php!"" ext_icon.gif!"" ext_localconf.php!"" ext_tables.php!"" ext_tables.sql!"" flexform_tx_sushifinder_bars_flex.xml!"" icon_tx_sushifinder_bars.gif!"" locallang_db.xml!"" pi1# %"" class.tx_sushifinder_pi1.php!"" README.txt%"" tca.php
Old = less structurehard to maintain
!"" ChangeLog!"" doc# !"" wizard_form.dat# %"" wizard_form.html!"" ext_emconf.php!"" ext_icon.gif!"" ext_localconf.php!"" ext_tables.php!"" ext_tables.sql!"" flexform_tx_sushifinder_bars_flex.xml!"" icon_tx_sushifinder_bars.gif!"" locallang_db.xml!"" pi1# %"" class.tx_sushifinder_pi1.php!"" README.txt%"" tca.php
You tend to build huge classes
?
<?php/*************************************************************** * Copyright notice * * (c) 1999-2004 Kasper SkÌ´rhÌüj ([email protected]) * (c) 2004-2009 Rupert Germann ([email protected]) * 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 2 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. * A copy is found in the textfile GPL.txt and important notices to the license * from the author is found in LICENSE.txt distributed with these scripts. * * * 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.tx_ttnews.php * * versatile news system for TYPO3. * $Id: class.tx_ttnews.php 27058 2009-11-27 12:24:02Z rupi $ * * TypoScript setup: * @See ext/tt_news/pi/static/ts_new/setup.txt * @See tt_news Manual: http://typo3.org/documentation/document-library/extension-manuals/tt_news/current/ * @See TSref: http://typo3.org/documentation/document-library/references/doc_core_tsref/current/ * * @author Rupert Germann <[email protected]> * @co-author Ingo Renner <[email protected]> */
require_once (PATH_tslib . 'class.tslib_pibase.php');require_once (PATH_t3lib . 'class.t3lib_htmlmail.php');
require_once (t3lib_extMgm::extPath('tt_news') . 'lib/class.tx_ttnews_catmenu.php');require_once (t3lib_extMgm::extPath('tt_news') . 'lib/class.tx_ttnews_helpers.php');require_once (t3lib_extMgm::extPath('tt_news') . 'lib/class.tx_ttnews_cache.php');
* * @author Rupert Germann <[email protected]> * @package TYPO3 * @subpackage tt_news */class tx_ttnews extends tslib_pibase { // Default plugin variables: var $prefixId = 'tx_ttnews'; // Same as class name var $scriptRelPath = 'pi/class.tx_ttnews.php'; // Path to this script relative to the extension dir. var $extKey = 'tt_news'; // The extension key.
var $hObj; // class with helper functions var $tt_news_uid = 0; // the uid of the current news record in SINGLE view var $pid_list = 0; var $config = array(); // the processed TypoScript configuration array var $confArr; // extension config from extmanager var $genericMarkerConf; var $sViewSplitLConf = array(); var $langArr = array(); // the languages found in the tt_news sysfolder var $sys_language_mode = ''; var $alternatingLayouts = 0; var $allowCaching = 1; var $catExclusive = ''; var $actuallySelectedCategories = ''; var $arcExclusive = 0; var $fieldNames = array(); var $searchFieldList = 'short,bodytext,author,keywords,links,imagecaption,title'; var $theCode = ''; // the current code var $codes; // list of all codes var $rdfToc = ''; var $templateCode = '';
var $versioningEnabled = false; // is the extension 'version' loaded var $vPrev = false; // do we display a versioning preview var $categories = array(); var $pageArray = array(); // internal cache with an array of the pages in the pid-list var $pointerName = 'pointer'; var $SIM_ACCESS_TIME = 0; // var $renderFields = array(); var $errors = array();
var $enableFields = ''; var $enableCatFields = ''; var $SPaddWhere = ''; var $catlistWhere = '';
var $token = '';
var $debugTimes = FALSE; // debug parsetimes var $useDevlog = TRUE; // write parsetimes to devlog instead printing debug messages
var $parsetimeThreshold = 0.1; // log only functions which need more than x.xx seconds var $writeCachingInfoToDevlog = FALSE; // 1 = write only cache misses to devlog, 2 = write cache hit info, too
var $start_time = NULL; var $global_start_time = 0; var $start_code_line = 0;
var $cache; var $cache_amenuPeriods = FALSE; var $cache_categoryCount = FALSE; var $cache_categories = FALSE;
/** * Main news function: calls the init_news() function and decides by the given CODEs which of the * functions to display news should by called. * * @param string $content : function output is added to this * @param array $conf : configuration array * @returnstring $content: complete content generated by the tt_news plugin */ function main_news($content, $conf) { $this->confArr = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['tt_news']); if ($this->confArr['writeParseTimesToDevlog']) { $this->debugTimes = TRUE; } if ($this->confArr['parsetimeThreshold']) { $this->parsetimeThreshold = floatval(trim($this->confArr['parsetimeThreshold'])); }
$this->hObj = new tx_ttnews_helpers($this);
if ($this->debugTimes) { $this->hObj->getParsetime(__METHOD__); }
$this->conf = $conf; //store configuration
// leave early if USER_INT $this->convertToUserIntObject = $this->conf['convertToUserIntObject'] ? 1 : 0; if (t3lib_div::int_from_ver(TYPO3_version) >= 4003000 && $this->convertToUserIntObject && $this->cObj->getUserObjectType() == tslib_cObj::OBJECTTYPE_USER) { $this->cObj->convertToUserIntObject(); return; }
$this->preInit();
if ($this->conf['enableConfigValidation']) {
if (count($this->errors)) { return $this->hObj->displayErrors(); } }
$this->init(); foreach ($this->codes as $theCode) {
$theCode = (string) strtoupper(trim($theCode)); $this->theCode = $theCode; // initialize category vars $this->initCategoryVars(); $this->initGenericMarkers();
switch ($theCode) { case 'SINGLE' : case 'SINGLE2' : $content .= $this->displaySingle(); break; case 'VERSION_PREVIEW' : $content .= $this->displayVersionPreview(); break; case 'LATEST' : case 'LIST' : case 'LIST2' : case 'LIST3' : case 'HEADER_LIST' : case 'SEARCH' : case 'XML' : $content .= $this->displayList(); break; case 'AMENU' : $content .= $this->displayArchiveMenu(); break; case 'CATMENU' : $content .= $this->displayCatMenu(); break; default :
if ($this->debugTimes) { $this->hObj->getParsetime(__METHOD__ . ' extraCodesHook start'); }
// hook for processing of extra codes if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['tt_news']['extraCodesHook'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['tt_news']['extraCodesHook'] as $_classRef) { $_procObj = & t3lib_div::getUserObj($_classRef); $content .= $_procObj->extraCodesProcessor($this); } } else { // code not known and no hook found to handle it -> displayerror $this->errors[] = 'CODE "' . $theCode . '" not known'; }
if ($this->debugTimes) { $this->hObj->getParsetime(__METHOD__ . ' extraCodesHook end'); }
break; } }
// check errors array again if ($this->conf['enableConfigValidation']) { if (count($this->errors)) { return $this->hObj->displayErrors(); } }
if ($this->debugTimes) { $this->hObj->getParsetime(__FUNCTION__, true); }
return $this->cObj->stdWrap($content, $this->conf['stdWrap.']); }
/** * [Describe function...] * * @return[type] ... */ function preInit() {
$this->pi_initPIflexForm(); // Init FlexForm configuration for plugin
$flexformTyposcript = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'myTS','s_misc'); if ($flexformTyposcript) { require_once(PATH_t3lib.'class.t3lib_tsparser.php'); $tsparser = t3lib_div::makeInstance('t3lib_tsparser'); // Copy conf into existing setup $tsparser->setup = $this->conf; // Parse the new Typoscript $tsparser->parse($flexformTyposcript); // Copy the resulting setup back into conf $this->conf = $tsparser->setup; }
// "CODE" decides what is rendered: codes can be set by TS or FF with priority on FF $code = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'what_to_display', 'sDEF'); $this->config['code'] = ($code ? $code : $this->cObj->stdWrap($this->conf['code'], $this->conf['code.']));
if ($this->conf['displayCurrentRecord']) { $this->config['code'] = $this->conf['defaultCode'] ? trim($this->conf['defaultCode']) : 'SINGLE'; $this->tt_news_uid = $this->cObj->data['uid'];
}
// get codes and decide which function is used to process the content $codes = t3lib_div::trimExplode(',', $this->config['code'] ? $this->config['code'] : $this->conf['defaultCode'], 1); if (! count($codes)) { // no code at all $codes = array(); $this->errors[] = 'No code given'; }
$this->codes = $codes; }
/** * Init Function: here all the needed configuration values are stored in class variables.. * * @param array $conf : configuration array from TS * @returnvoid */ function init() {
$this->pi_loadLL(); // Loading language-labels $this->pi_setPiVarDefaults(); // Set default piVars from TS
$this->SIM_ACCESS_TIME = $GLOBALS['SIM_ACCESS_TIME']; // fallback for TYPO3 < 4.2 if (! $this->SIM_ACCESS_TIME) { $simTime = $GLOBALS['SIM_EXEC_TIME']; $this->SIM_ACCESS_TIME = $simTime - ($simTime % 60); }
$this->initCaching();
$this->local_cObj = t3lib_div::makeInstance('tslib_cObj'); // Local cObj. $this->enableFields = $this->getEnableFields('tt_news');
if ($this->tt_news_uid === 0) { // no tt_news_uid set by displayCurrentRecord $this->tt_news_uid = intval($this->piVars['tt_news']); // Get the submitted uid of a news (if any) }
if (! isset($this->conf['compatVersion']) || ! preg_match('/^\d+\.\d+\.\d+$/', $this->conf['compatVersion'])) { $this->conf['compatVersion'] = $this->hObj->getCurrentVersion(); } $this->token = md5(microtime());
if (t3lib_extMgm::isLoaded('version')) { $this->versioningEnabled = true; } // load available syslanguages $this->initLanguages(); // sys_language_mode defines what to do if the requested translation is not found
$this->sys_language_mode = ($this->conf['sys_language_mode'] ? $this->conf['sys_language_mode'] : $GLOBALS['TSFE']->sys_language_mode);
if ($this->conf['searchFieldList']) { // get fieldnames from the tt_news db-table $this->fieldNames = array_keys($GLOBALS['TYPO3_DB']->admin_get_fields('tt_news')); $searchFieldList = $this->hObj->validateFields($this->conf['searchFieldList'], $this->fieldNames); if ($searchFieldList) { $this->searchFieldList = $searchFieldList; } } // Archive: $archiveMode = trim($this->conf['archiveMode']); // month, quarter or year listing in AMENU $this->config['archiveMode'] = $archiveMode ? $archiveMode : 'month';
// arcExclusive : -1=only non-archived; 0=don't care; 1=only archived $arcExclusive = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'archive', 'sDEF'); $this->arcExclusive = $arcExclusive ? $arcExclusive : intval($this->conf['archive']);
$this->config['datetimeDaysToArchive'] = intval($this->conf['datetimeDaysToArchive']); $this->config['datetimeHoursToArchive'] = intval($this->conf['datetimeHoursToArchive']); $this->config['datetimeMinutesToArchive'] = intval($this->conf['datetimeMinutesToArchive']);
if ($this->conf['useHRDates']) { $this->hObj->convertDates(); }
// list of pages where news records will be taken from if (! $this->conf['dontUsePidList']) { $this->initPidList(); }
// itemLinkTarget is only used for categoryLinkMode 3 (catselector) in framesets $this->conf['itemLinkTarget'] = trim($this->conf['itemLinkTarget']); // id of the page where the search results should be displayed $this->config['searchPid'] = intval($this->conf['searchPid']);
// pages in Single view will be divided by this token $this->config['pageBreakToken'] = trim($this->conf['pageBreakToken']) ? trim($this->conf['pageBreakToken']) : '<---newpage--->';
$this->config['singleViewPointerName'] = trim($this->conf['singleViewPointerName']) ? trim($this->conf['singleViewPointerName']) : 'sViewPointer';
$maxWordsInSingleView = intval($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'maxWordsInSingleView', 's_misc')); $maxWordsInSingleView = $maxWordsInSingleView ? $maxWordsInSingleView : intval($this->conf['maxWordsInSingleView']); $this->config['maxWordsInSingleView'] = $maxWordsInSingleView ? $maxWordsInSingleView : 0; $this->config['useMultiPageSingleView'] = $this->conf['useMultiPageSingleView'];
// pid of the page with the single view. the old var PIDitemDisplay is still processed if no other value is found $singlePid = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'PIDitemDisplay', 's_misc');
Does this tell you anything about the application?
Maybe
#wtf!
New = more structureeasy to maintain
!"" Classes# !"" Controller# %"" Domain!"" Configuration# !"" TCA# %"" TypoScript!"" ext_emconf.php!"" ext_icon.gif!"" ext_localconf.php!"" ext_tables.php!"" ext_tables.sql!"" kickstarter.json%"" Resources !"" Private %"" Public
!"" Classes# !"" Controller# %"" Domain!"" Configuration# !"" TCA# %"" TypoScript!"" ext_emconf.php!"" ext_icon.gif!"" ext_localconf.php!"" ext_tables.php!"" ext_tables.sql!"" kickstarter.json%"" Resources !"" Private %"" Public
!
Because it forces you to think in components
How do I get started?
cd ./typo3conf/ext/
git clone git://git.typo3.org/TYPO3v4/Extensions/extbase_kickstarter.git
(one line)
Download extbasekickstarter
cd ./typo3conf/ext/
git clone git://git.typo3.org/TYPO3v4/Extensions/extbase_kickstarter.git
(all in one line)
Download extbase kickstarter
Fast, comfortable version control system
Smooth development even with large files
Graphical interfaces availablehttp://git-scm.com/tools
Download ithttp://git-scm.com/download
Why git?
Use extbasekickstarter
Demo
We created !le withour new Domain Class
.!"" Classes# !"" Controller# %"" Domain# %"" Model# %"" Bar.php!"" Configuration# !"" TCA# %"" TypoScript!"" ext_emconf.php!"" ext_icon.gif!"" ext_localconf.php!"" ext_tables.php!"" ext_tables.sql!"" kickstarter.json%"" Resources
+ Backend forms
You can instantly create new content for our website!
"BREAK"
Part 2Example
Goal: Find Sushi Bars
- Create a web applicationto manage sushi bars
- Click on a bar to get details
- Find bar on Google Maps
Our Bar model
Sushi Bar
- Name
- Location
- Business hours
- Images
Add Relations
Sushi Bar Review
Review model
- Allow Feedback
- Rating
- Statement
Improve view
- Link Website
- Add QRCode to open a map
- Easy to !nd
Final result
Many happy customers!
Further reading
http://forge.typo3.org/projects/typo3v4-mvc
http://wiki.typo3.org/Category:Topic/extbase
どうも有難うThank you!
Have fun with TYPO3!