TYPO3 Extension
development using
new Extbase
framework

2011/02/18, T3Ski11 Tokyo
Christian Trabold
Christian Trabold
Senior Developer
dkd Internet Service GmbH

TYPO3 since 2004

Focus on quality assurance

Author of TYPO3 Cookbook, O'Reilly




About me
Carrier            12:34 PM
                Web Page Title

   http://host.domain.tld




               320 x 480
          Vertical Resolution
- TYPO3 basics
- Find extensions with TER
- Get your ideas into TYPO3
- Question and answers



Agenda - Part 1
- Create example application
- See kickstarter in action
- Customize les to your needs
- Question and answers



Agenda - Part 2
Goal of this workshop
Get the big picture
Understand concepts
Find nice Sushi bars
Carrier            12:34 PM
                Web Page Title

   http://host.domain.tld




               320 x 480
          Vertical Resolution
Part 1
TYPO3 Basics
Frontend


                                                                            Backend

                                                                            Extensions



http://www.flickr.com/photos/grendelkhan/121671781/sizes/l/in/photostream/




      TYPO3 is like Sushi
Extensions extend
everything
Extensions contain
your PHP code
Extensions contain
your 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
It is very important
that you check every
detail of an extension
before you install.


Security and con dence
What if nothing ts?
http://www.flickr.com/photos/rreid/420388478/




     Add your own creation
How do you start
your own creation?
Understand
extension structure
Install
extbase kickstarter
And
start 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_base
     New extbase
We will focus on the
new extbase kickstarter


       ✘
     Old pi_base
     New extbase
Old = less structure
hard 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
          !""   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
<?php
/***************************************************************
 * Copyright notice
 *
 * (c) 1999-2004 Kasper SkÌ´rhÌüj (kasperYYYY@typo3.com)
 * (c) 2004-2009 Rupert Germann (rupi@gmx.li)
 * 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 <rupi@gmx.li>
 * @co-author Ingo Renner <typo3@ingo-renner.com>
 */

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 <rupi@gmx.li>
  * @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
	    * @return	string	    	    $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
	    * @return	void
	    */
	   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 structure
easy 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
Because it forces you to
think in components
 !        !""
          #  
          #  
                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
How do I get
started?
Download extbase
kickstarter
cd ./typo3conf/ext/

git clone git://git.typo3.org/
TYPO3v4/Extensions/
extbase_kickstarter.git

(one line)
Download extbase
kickstarter
cd ./typo3conf/ext/

git clone
git://git.typo3.org/TYPO3v4/Extensions/
extbase_kickstarter.git

(all in one line)
Why git?
Fast, comfortable version control system

Smooth development even with large files

Graphical interfaces available
http://git-scm.com/tools

Download it
http://git-scm.com/download
Use extbase
kickstarter




     Demo
We created le with
our 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 2
Example
- Create a web application
  to manage sushi bars
- Click on a bar to get details
- Find bar on Google Maps

Goal: Find Sushi Bars
Sushi Bar


- Name
- Location
- Business hours
- Images

Our Bar model
Sushi Bar     Review




Add Relations
- Allow Feedback
- Rating
- Statement


Review model
- Link Website
- Add QRCode to open a map
- Easy to nd


Improve view
Final result
Many happy customers!
http://forge.typo3.org/projects/typo3v4-mvc

http://wiki.typo3.org/Category:Topic/extbase



Further reading
Thank you!
Have fun with
   TYPO3!

TYPO3 Extension development using new Extbase framework

  • 1.
    TYPO3 Extension development using newExtbase framework 2011/02/18, T3Ski11 Tokyo Christian Trabold
  • 2.
    Christian Trabold Senior Developer dkdInternet Service GmbH TYPO3 since 2004 Focus on quality assurance Author of TYPO3 Cookbook, O'Reilly About me
  • 4.
    Carrier 12:34 PM Web Page Title http://host.domain.tld 320 x 480 Vertical Resolution
  • 5.
    - TYPO3 basics -Find extensions with TER - Get your ideas into TYPO3 - Question and answers Agenda - Part 1
  • 6.
    - Create exampleapplication - See kickstarter in action - Customize les to your needs - Question and answers Agenda - Part 2
  • 7.
    Goal of thisworkshop
  • 8.
    Get the bigpicture
  • 9.
  • 10.
  • 13.
    Carrier 12:34 PM Web Page Title http://host.domain.tld 320 x 480 Vertical Resolution
  • 14.
  • 15.
    Frontend Backend Extensions http://www.flickr.com/photos/grendelkhan/121671781/sizes/l/in/photostream/ TYPO3 is like Sushi
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
    How to ndextensions
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
    It is veryimportant that you check every detail of an extension before you install. Security and con dence
  • 30.
  • 31.
  • 32.
    How do youstart your own creation?
  • 33.
  • 34.
  • 35.
  • 36.
    Why do Ineed a kickstarter?
  • 37.
  • 38.
    The kickstarter does allthe boring work
  • 39.
    You can focuson your ideas and design = more fun!
  • 40.
    TYPO3 has oldand new extension styles Old pi_base New extbase
  • 41.
    We will focuson the new extbase kickstarter ✘ Old pi_base New extbase
  • 42.
    Old = lessstructure hard 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
  • 43.
    You tend tobuild huge classes !"" 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
  • 44.
    <?php /*************************************************************** * Copyrightnotice * * (c) 1999-2004 Kasper SkÌ´rhÌüj (kasperYYYY@typo3.com) * (c) 2004-2009 Rupert Germann (rupi@gmx.li) * 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 <rupi@gmx.li> * @co-author Ingo Renner <typo3@ingo-renner.com> */ 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');
  • 45.
    * *@author Rupert Germann <rupi@gmx.li> * @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
  • 46.
    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 * @return string $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']) {
  • 47.
    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';
  • 48.
    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'];
  • 49.
    } // 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 * @return void */ 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
  • 50.
    $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');
  • 51.
    Does this tellyou anything about the application?
  • 52.
    Maybe #wtf!
  • 53.
    New = morestructure easy 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
  • 54.
    Because it forcesyou to think in components ! !"" #   #   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
  • 55.
    How do Iget started?
  • 56.
    Download extbase kickstarter cd ./typo3conf/ext/ gitclone git://git.typo3.org/ TYPO3v4/Extensions/ extbase_kickstarter.git (one line)
  • 57.
    Download extbase kickstarter cd ./typo3conf/ext/ gitclone git://git.typo3.org/TYPO3v4/Extensions/ extbase_kickstarter.git (all in one line)
  • 58.
    Why git? Fast, comfortableversion control system Smooth development even with large files Graphical interfaces available http://git-scm.com/tools Download it http://git-scm.com/download
  • 59.
  • 67.
    We created lewith our 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
  • 68.
  • 69.
    You can instantlycreate new content for our website!
  • 70.
  • 71.
  • 72.
    - Create aweb application to manage sushi bars - Click on a bar to get details - Find bar on Google Maps Goal: Find Sushi Bars
  • 73.
    Sushi Bar - Name -Location - Business hours - Images Our Bar model
  • 74.
    Sushi Bar Review Add Relations
  • 75.
    - Allow Feedback -Rating - Statement Review model
  • 76.
    - Link Website -Add QRCode to open a map - Easy to nd Improve view
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.