extbase and beyond
DESCRIPTION
With Extbase - a new framework for extension development introduced in TYPO3 4.3 - you are able to develop with the paradigms of FLOW3 today. During this talk, you get in touch with the features of the framework to understand how it supports your development process to develop clean code cost efficient in less time. Extbase is one cornerstone for a smooth transition to TYPO3 v5, another is reusable business domain knowledge in form of Generic Domain Models available in 4.x and 5.x. The Generic Domain Models will enable you to add a Semantic Web topping.TRANSCRIPT
Extbase and Beyond
Jochen Rau <[email protected]>Irving, TexasMay 22, 2010
Who is this?
Dipl.-Ing. Mechanical Engineering
infected with TYPO3 in 2OO1
Tübingen
6O% selfemployed6O% father
6O% selfemployed6O% father
----8O%
5 years: Fraunhofer-Gesellschaft
German Aerospace Center
5 years:high school
teacher
What is Extbase all about?
v4
2OO6
v4
v5
v4
v5
v4
v5
v4
v5Extbase
v4
v5
ExtbaseFLO 4W
ExtbaseFLO 4W6O%
ExtbaseFLO 4
25%WW
ExtbaseFLO 4
25%W
ExtbaseFLO 4
2O%W
ExtbaseFLO 4W
ExtbaseFLOW 3
What is Extbase all about?
Extbase
ExtbaseMVC
DDD
VfB
OOP Aggregate
Entity
Repository
View
Helper
Extbase
Entity
View Helper
Value
clean architecturedomain driven
modularpatterns
rapid developmentuse conventions
stay focusedbe relieved
smooth transition
youcodedata
What is Extbase all about?
http://commons.wikimedia.org/wiki/File:Z%C3%BCrich_-_Seefeld_-_Heureka_IMG_1757.JPG
http://commons.wikimedia.org/wiki/File:Z%C3%BCrich_-_Seefeld_-_Heureka_IMG_1757.JPG
tx_ttnews 3397tx_pbsurvey_pi1 253Otx_ttproducts_pi1 1O9Otx_mmforum_pi1 6126tx_veguestbook_pi1 1156
<?php/**************************************************************** Copyright notice** (c) 1999-2004 Kasper Skårhøj ([email protected])* (c) 2004-2007 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 8605 2008-03-15 20:03:19Z rupertgermann $** TypoScript setup:* @See 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]>*//** * [CLASS/FUNCTION INDEX of SCRIPT] * * * * 112: class tx_ttnews extends tslib_pibase * 143: function main_news($content, $conf) * 219: function init($conf) * 373: function newsArchiveMenu() * 523: function displaySingle() * 606: function displayVersionPreview () * 659: function displayList($excludeUids = 0) * 1003: function getListContent($itemparts, $selectConf, $prefix_display) * 1172: function getSelectConf($where, $noPeriod = 0) * 1419: function generatePageArray() * 1440: function getItemMarkerArray ($row, $textRenderObj = 'displaySingle') * 1723: function insertPagebreaks($text,$firstPageWordCrop) * 1773: function makeMultiPageSView($bodytext,$lConf) * 1803: function makePageBrowser($showResultCount=1,$tableParams='',$pointerName='pointer') * 1885: function getCategories($uid, $getAll=false) * 1958: function getCategoryPath($categoryArray) * 2015: function getSubCategories($catlist, $cc = 0) * 2044: function displayCatMenu() * 2157: function getCatMenuContent($array_in,$lConf, $l=0) * 2209: function getSubCategoriesForMenu ($catlist, $fields, $addWhere, $cc = 0) * 2240: function getCatMarkerArray($markerArray, $row, $lConf) * 2380: function getImageMarkers($markerArray, $row, $lConf, $textRenderObj) * 2448: function getRelated($uid) * 2608: function userProcess($mConfKey, $passVar) * 2623: function spMarker($subpartMarker) * 2641: function searchWhere($sw) * 2652: function formatStr($str) * 2667: function getLayouts($templateCode, $alternatingLayouts, $marker) * 2685: function initLanguages () * 2705: function initCategoryVars() * 2775: function checkRecords($recordlist) * 2807: function initTemplate() * 2832: function initPidList () * 2857: function getXmlHeader() * 2958: function getW3cDate($datetime) * 2983: function main_xmlnewsfeed($content, $conf) * 2998: function getStoriesResult() * 3020: function cleanXML($str) * 3034: function convertDates() * 3073: function getHrDateSingle($tstamp) * 3086: function displayFEHelp() * 3107: function validateFields($fieldlist) * 3128: function getNewsSubpart($myTemplate, $myKey, $row = Array()) * * SECTION: DB Functions * 3149: function exec_getQuery($table, $conf) * 3167: function getQuery($table, $conf, $returnQueryArray=FALSE) * 3249: function getWhere($table,$conf, $returnQueryArray=FALSE) * * TOTAL FUNCTIONS: 45 * (This index is automatically created/updated by the extension "extdeveval") * */
require_once(PATH_t3lib . 'class.t3lib_xml.php');require_once(PATH_t3lib . 'class.t3lib_htmlmail.php');require_once(PATH_tslib . 'class.tslib_pibase.php');require_once(t3lib_extMgm::extPath('tt_news') . 'class.tx_ttnews_catmenu.php');
/** * Plugin 'news' for the 'tt_news' extension. * * @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 $tt_news_uid; // the uid of the current news record in SINGLE view var $config; // the processed TypoScript configuration array var $langArr; // the languages found in the tt_news sysfolder var $sys_language_mode; var $alternatingLayouts; var $allowCaching; var $catExclusive; var $arcExclusive; var $searchFieldList = 'short,bodytext,author,keywords,links,imagecaption,title'; var $theCode = ''; var $rdfToc = ''; var $versioningEnabled = false; // is the extension 'version' loaded var $vPrev = false; // do we display a versioning preview var $categories = array(); // Is initialized with the categories of the news system var $pageArray = array(); // Is initialized with an array of the pages in the pid-list
/** * 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->local_cObj = t3lib_div::makeInstance('tslib_cObj'); // Local cObj. $this->init($conf);
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(); $noCode = true; }
while (list(, $theCode) = each($codes)) { $theCode = (string)strtoupper(trim($theCode)); $this->theCode = $theCode; switch ($theCode) { case 'SINGLE': $content .= $this->displaySingle(); break; case 'VERSION_PREVIEW': $content .= $this->displayVersionPreview(); break; case 'LATEST': case 'LIST': case 'SEARCH': case 'XML': $content .= $this->displayList(); break; case 'AMENU': $content .= $this->newsArchiveMenu(); break; case 'CATMENU': $content .= $this->displayCatMenu(); break; default: // Adds 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 { $langKey = strtoupper($GLOBALS['TSFE']->config['config']['language']); $helpTemplate = $this->cObj->fileResource('EXT:tt_news/pi/news_help.tmpl'); // Get language version of the help-template $helpTemplate_lang = ''; if ($langKey) { $helpTemplate_lang = $this->getNewsSubpart($helpTemplate, "###TEMPLATE_" . $langKey . '###'); } $helpTemplate = $helpTemplate_lang ? $helpTemplate_lang : $this->getNewsSubpart($helpTemplate, '###TEMPLATE_DEFAULT###'); // Markers and substitution: $markerArray['###CODE###'] = $this->theCode; $markerArray['###EXTPATH###'] = $GLOBALS['TYPO3_LOADED_EXT']['tt_news']['siteRelPath']; $content .= $this->displayFEHelp(); } break; } } if($noCode) { $content .= $this->displayFEHelp(); } return $content; }
/** * Init Function: here all the needed configuration values are stored in class variables.. * * @param array $conf : configuration array from TS * @returnvoid */ function init($conf) { $this->conf = $conf; //store configuration $this->pi_loadLL(); // Loading language-labels $this->pi_setPiVarDefaults(); // Set default piVars from TS $this->pi_initPIflexForm(); // Init FlexForm configuration for plugin $this->enableFields = $this->cObj->enableFields('tt_news'); $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->getCurrentVersion(); }
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;
// "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.']);
// initialize category vars $this->initCategoryVars();
// get fieldnames from the tt_news db-table $this->fieldNames = array_keys($GLOBALS['TYPO3_DB']->admin_get_fields('tt_news'));
if ($this->conf['searchFieldList']) { $searchFieldList = $this->validateFields($this->conf['searchFieldList']); if ($searchFieldList) { $this->searchFieldList = $searchFieldList; } } // Archive: $this->config['archiveMode'] = trim($this->conf['archiveMode']) ; // month, quarter or year listing in AMENU $this->config['archiveMode'] = $this->config['archiveMode']?$this->config['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:$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->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->config['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'] = $maxWordsInSingleView>1?1:$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'); $singlePid = $singlePid?$singlePid:intval($this->cObj->stdWrap($this->conf['singlePid'],$this->conf['singlePid.'])); $this->config['singlePid'] = $singlePid ? $singlePid:intval($this->conf['PIDitemDisplay']);
// pid to return to when leaving single view $backPid = intval($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'backPid', 's_misc')); $backPid = $backPid?$backPid:intval($this->conf['backPid']); $backPid = $backPid?$backPid:intval($this->piVars['backPid']); $backPid = $backPid?$backPid:$GLOBALS['TSFE']->id ; $this->config['backPid'] = $backPid;
// max items per page $FFlimit = t3lib_div::intInRange($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'listLimit', 's_misc'), 0, 1000);
$limit = t3lib_div::intInRange($this->cObj->stdWrap($this->conf['limit'],$this->conf['limit.']), 0, 1000); $limit = $limit?$limit: 50; $this->config['limit'] = $FFlimit?$FFlimit:$limit;
$latestLimit = t3lib_div::intInRange($this->cObj->stdWrap($this->conf['latestLimit'],$this->conf['latestLimit.']), 0, 1000); $latestLimit = $latestLimit?$latestLimit:10; $this->config['latestLimit'] = $FFlimit?$FFlimit:$latestLimit;
// orderBy and groupBy statements for the list Query $orderBy = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'listOrderBy', 'sDEF'); $orderByTS = trim($this->conf['listOrderBy']); $orderBy = $orderBy?$orderBy:$orderByTS; $this->config['orderBy'] = $orderBy;
if ($orderBy) { $ascDesc = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'ascDesc', 'sDEF'); $this->config['ascDesc'] = $ascDesc; if ($this->config['ascDesc']) { // remove ASC/DESC from 'orderBy' if it is already set from TS $this->config['orderBy'] = preg_replace('/( DESC| ASC)\b/i','',$this->config['orderBy']); } } $this->config['groupBy'] = trim($this->conf['listGroupBy']);
// if this is set, the first image is handled as preview image, which is only shown in list view $fImgPreview = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'firstImageIsPreview', 's_misc'); $this->config['firstImageIsPreview'] = $fImgPreview?$fImgPreview : $this->conf['firstImageIsPreview']; $forcefImgPreview = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'forceFirstImageIsPreview', 's_misc'); $this->config['forceFirstImageIsPreview'] = $forcefImgPreview?$fImgPreview : $this->conf['forceFirstImageIsPreview'];
// List start id $listStartId = intval($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'listStartId', 's_misc')); $this->config['listStartId'] = $listStartId?$listStartId:intval($this->conf['listStartId']); // supress pagebrowser $noPageBrowser = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'noPageBrowser', 's_misc'); $this->config['noPageBrowser'] = $noPageBrowser?$noPageBrowser: $this->conf['noPageBrowser'];
// image sizes given from FlexForms $this->config['FFimgH'] = intval($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'imageMaxHeight', 's_template')); $this->config['FFimgW'] = intval($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'imageMaxWidth', 's_template'));
// Get number of alternative Layouts (loop layout in LATEST and LIST view) default is 2: $altLayouts = intval($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'alternatingLayouts', 's_template')); $altLayouts = $altLayouts?$altLayouts:intval($this->conf['alternatingLayouts']); $this->alternatingLayouts = $altLayouts?$altLayouts:2;
// Get cropping lenght $this->config['croppingLenght'] = trim($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'croppingLenght', 's_template'));
$this->initTemplate();
// Configure caching $this->allowCaching = $this->conf['allowCaching']?1:0; if (!$this->allowCaching) { $GLOBALS['TSFE']->set_no_cache(); }
// get siteUrl for links in rss feeds. the 'dontInsert' option seems to be needed in some configurations depending on the baseUrl setting if (!$this->conf['displayXML.']['dontInsertSiteUrl']) { $this->config['siteUrl'] = t3lib_div::getIndpEnv('TYPO3_SITE_URL'); } }
/** * generates the News archive menu * * @returnstring html code of the archive menu */ function newsArchiveMenu() {
$this->arcExclusive = 1; $selectConf = $this->getSelectConf('', 1); // Finding maximum and minimum values: $selectConf['selectFields'] = 'max(tt_news.datetime) as maxval, min(tt_news.datetime) as minval';
$res = $this->exec_getQuery('tt_news', $selectConf);
$row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); if ($row['minval'] || $row['maxval']) { // if ($row['minval']) { $dateArr = array(); $arcMode = $this->config['archiveMode']; $c = 0; do { switch ($arcMode) { case 'month': $theDate = mktime (0, 0, 0, date('m', $row['minval']) + $c, 1, date('Y', $row['minval'])); break; case 'quarter': $theDate = mktime (0, 0, 0, floor(date('m', $row['minval']) / 3) + 1 + (3 * $c), 1, date('Y', $row['minval'])); break; case 'year': $theDate = mktime (0, 0, 0, 1, 1, date('Y', $row['minval']) + $c); break; } $dateArr[] = $theDate; $c++; if ($c > 1000) break; } while ($theDate < $GLOBALS['SIM_EXEC_TIME']);
reset($dateArr); $periodAccum = array();
$selectConf2['where'] = $selectConf['where']; while (list($k, $v) = each($dateArr)) { if (!isset($dateArr[$k + 1])) { break; }
$periodInfo = array(); $periodInfo['start'] = $dateArr[$k]; $periodInfo['stop'] = $dateArr[$k + 1]-1; $periodInfo['HRstart'] = date('d-m-Y', $periodInfo['start']); $periodInfo['HRstop'] = date('d-m-Y', $periodInfo['stop']); $periodInfo['quarter'] = floor(date('m', $dateArr[$k]) / 3) + 1; // execute a query to count the archive periods $selectConf['selectFields'] = 'count(distinct(tt_news.uid))'; $selectConf['where'] = $selectConf2['where'] . ' AND tt_news.datetime>=' . $periodInfo['start'] . ' AND tt_news.datetime<' . $periodInfo['stop'];
$res = $this->exec_getQuery('tt_news', $selectConf);
$row = $GLOBALS['TYPO3_DB']->sql_fetch_row($res); $periodInfo['count'] = $row[0];
if (!$this->conf['archiveMenuNoEmpty'] || $periodInfo['count']) { $periodAccum[] = $periodInfo; } }
// get template subpart $t['total'] = $this->getNewsSubpart($this->templateCode, $this->spMarker('###TEMPLATE_ARCHIVE###')); $t['item'] = $this->getLayouts($t['total'], $this->alternatingLayouts, 'MENUITEM'); $cc = 0;
$veryLocal_cObj = t3lib_div::makeInstance('tslib_cObj'); // reverse amenu order if 'reverseAMenu' is given if ($this->conf['reverseAMenu']) { arsort($periodAccum); }
$archiveLink = $this->conf['archiveTypoLink.']['parameter']; $this->conf['parent.']['addParams'] = $this->conf['archiveTypoLink.']['addParams']; reset($periodAccum); $itemsOutArr = array(); while (list(, $pArr) = each($periodAccum)) { // Print Item Title $wrappedSubpartArray = array();
if (!$this->conf['disableCategoriesInAmenuLinks']) { if ($this->config['catSelection'] && $this->config['amenuWithCatSelector']) { // use the catSelection from GPvars only if 'amenuWithCatSelector' is given. $amenuLinkCat = $this->config['catSelection']; } else { $amenuLinkCat = $this->catExclusive; } }
if ($this->conf['useHRDates']) { $year = date('Y',$pArr['start']); $month = date('m',$pArr['start']); if ($arcMode == 'year') { $archLinkArr = $this->pi_linkTP_keepPIvars('|', array('cat' => ($amenuLinkCat?$amenuLinkCat:null), 'year' => $year), $this->allowCaching, 1, ($archiveLink?$archiveLink:$GLOBALS['TSFE']->id)); } else { $archLinkArr = $this->pi_linkTP_keepPIvars('|', array('cat' => ($amenuLinkCat?$amenuLinkCat:null), 'year' => $year, 'month' => $month), $this->allowCaching, 1, ($archiveLink?$archiveLink:$GLOBALS['TSFE']->id)); } $wrappedSubpartArray['###LINK_ITEM###'] = explode('|', $archLinkArr); } else { $wrappedSubpartArray['###LINK_ITEM###'] = explode('|', $this->pi_linkTP_keepPIvars('|', array('cat' => ($amenuLinkCat?$amenuLinkCat:null), 'pS' => $pArr['start'], 'pL' => ($pArr['stop'] - $pArr['start']), 'arc' => 1), $this->allowCaching, 1, ($archiveLink?$archiveLink:$GLOBALS['TSFE']->id))); }
$markerArray = array(); $veryLocal_cObj->start($pArr, ''); $markerArray['###ARCHIVE_TITLE###'] = $veryLocal_cObj->cObjGetSingle($this->conf['archiveTitleCObject'], $this->conf['archiveTitleCObject.'], 'archiveTitle'); $markerArray['###ARCHIVE_COUNT###'] = $pArr['count']; $markerArray['###ARCHIVE_ITEMS###'] = $this->pi_getLL('archiveItems');
// fill the generated data to an array to pass it to a userfuction as a single variable $itemsOutArr[] = array('html' => $this->cObj->substituteMarkerArrayCached($t['item'][($cc % count($t['item']))], $markerArray, array(), $wrappedSubpartArray), 'data' => $pArr); $cc++; } // Pass to user defined function if ($this->conf['newsAmenuUserFunc']) { $itemsOutArr = $this->userProcess('newsAmenuUserFunc', $itemsOutArr); }
foreach ($itemsOutArr as $itemHtml) { $tmpItemsArr[] = $itemHtml['html']; }
if (is_array($tmpItemsArr)) { $itemsOut = implode('', $tmpItemsArr); }
// Reset: $subpartArray = array(); $wrappedSubpartArray = array(); $markerArray = array(); $markerArray['###ARCHIVE_HEADER###'] = $this->local_cObj->stdWrap($this->pi_getLL('archiveHeader'), $this->conf['archiveHeader_stdWrap.']); // Set content $subpartArray['###CONTENT###'] = $itemsOut; $content = $this->cObj->substituteMarkerArrayCached($t['total'], $markerArray, $subpartArray, $wrappedSubpartArray); } else { // if nothing is found in the archive display the TEMPLATE_ARCHIVE_NOITEMS message $markerArray['###ARCHIVE_HEADER###'] = $this->local_cObj->stdWrap($this->pi_getLL('archiveHeader'), $this->conf['archiveHeader_stdWrap.']); $markerArray['###ARCHIVE_EMPTY_MSG###'] = $this->local_cObj->stdWrap($this->pi_getLL('archiveEmptyMsg'), $this->conf['archiveEmptyMsg_stdWrap.']); $noItemsMsg = $this->getNewsSubpart($this->templateCode, $this->spMarker('###TEMPLATE_ARCHIVE_NOITEMS###')); $content = $this->cObj->substituteMarkerArrayCached($noItemsMsg, $markerArray); }
return $content; }
/** * Displays the "single view" of a news article. Is also used when displaying single news records with the "insert records" content element. * * @returnstring html-code for the "single view" */ function displaySingle() { $singleWhere = 'tt_news.uid=' . intval($this->tt_news_uid); $singleWhere .= ' AND type NOT IN(1,2)' . $this->enableFields; // only real news -> type=0
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( '*', 'tt_news', $singleWhere);
$row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); // get the translated record if the content language is not the default language if ($GLOBALS['TSFE']->sys_language_content) { $OLmode = ($this->sys_language_mode == 'strict'?'hideNonTranslated':''); $row = $GLOBALS['TSFE']->sys_page->getRecordOverlay('tt_news', $row, $GLOBALS['TSFE']->sys_language_content, $OLmode); } if ($this->versioningEnabled) { // get workspaces Overlay $GLOBALS['TSFE']->sys_page->versionOL('tt_news',$row); // fix pid for record from workspace $GLOBALS['TSFE']->sys_page->fixVersioningPid('tt_news',$row); } $GLOBALS['TSFE']->displayedNews[]=$row['uid'];
if (is_array($row) && ($row['pid'] > 0 || $this->vPrev)) { // never display versions of a news record (having pid=-1) for normal website users // Get the subpart code if ($this->conf['displayCurrentRecord']) { $item = trim($this->getNewsSubpart($this->templateCode, $this->spMarker('###TEMPLATE_SINGLE_RECORDINSERT###'), $row)); } if (!$item) { $item = $this->getNewsSubpart($this->templateCode, $this->spMarker('###TEMPLATE_SINGLE###'), $row); } // reset marker array $wrappedSubpartArray = array(); // build the backToList link if ($this->conf['useHRDates']) { $pointerName = 'pointer'; $wrappedSubpartArray['###LINK_ITEM###'] = explode('|', $this->pi_linkTP_keepPIvars('|', array( 'tt_news' => null, 'backPid' => null, $this->config['singleViewPointerName'] => null, 'pS' => null, 'pL' => null), $this->allowCaching, ($this->conf['dontUseBackPid']?1:0), $this->config['backPid'])); } else { $wrappedSubpartArray['###LINK_ITEM###'] = explode('|', $this->pi_linkTP_keepPIvars('|', array( 'tt_news' => null, 'backPid' => null, $this->config['singleViewPointerName'] => null), $this->allowCaching, ($this->conf['dontUseBackPid']?1:0), $this->config['backPid'])); } // set the title of the single view page to the title of the news record if ($this->conf['substitutePagetitle']) { $GLOBALS['TSFE']->page['title'] = $row['title']; // set pagetitle for indexed search to news title $GLOBALS['TSFE']->indexedDocTitle = $row['title']; } if ($this->conf['displaySingle.']['catOrderBy']) { $this->config['catOrderBy'] = $this->conf['displaySingle.']['catOrderBy']; } $markerArray = $this->getItemMarkerArray($row, 'displaySingle'); // Substitute $content = $this->cObj->substituteMarkerArrayCached($item, $markerArray, array(), $wrappedSubpartArray); } elseif ($this->sys_language_mode == 'strict' && $this->tt_news_uid && $GLOBALS['TSFE']->sys_language_content) { // not existing translation $noTranslMsg = $this->local_cObj->stdWrap($this->pi_getLL('noTranslMsg'), $this->conf['noNewsIdMsg_stdWrap.']); $content = $noTranslMsg; } elseif ($row['pid'] < 0) { // a non-public version of a record was requested $nonPlublicVersion = $this->local_cObj->stdWrap($this->pi_getLL('nonPlublicVersionMsg'), $this->conf['nonPlublicVersionMsg_stdWrap.']); $content = $nonPlublicVersion; } else { // if singleview is shown with no tt_news uid given from GETvars (&tx_ttnews[tt_news]=) an error message is displayed. $noNewsIdMsg = $this->local_cObj->stdWrap($this->pi_getLL('noNewsIdMsg'), $this->conf['noNewsIdMsg_stdWrap.']); $content = $noNewsIdMsg; } return $content; }
/** * Displays the "versioning preview". * The functions checks: * - if the extension "version" is loaded * - if a BE_user is logged in * - the plausibility of the requested "version preview". * If this is all OK, "displaySingle()" is executed to display the "versioning preview". * * @returnstring html code for the "versioning preview" */ function displayVersionPreview () { if ($this->versioningEnabled) { $vPrev = t3lib_div::_GP('ADMCMD_vPrev'); if ($this->piVars['ADMCMD_vPrev']) { $piADMCMD = unserialize(rawurldecode($this->piVars['ADMCMD_vPrev'])); } if ((is_array($vPrev) || is_array($piADMCMD)) && is_object($GLOBALS['BE_USER'])) { // check if ADMCMD_vPrev is set and if a BE_user is logged in. $this->piVars['ADMCMD_vPrev'] is needed for previewing a "single view with pagebrowser" if (!is_array($vPrev)) { $vPrev = $piADMCMD; } list($table,$t3ver_oid) = explode(':',key($vPrev)); if ($table == 'tt_news') { if ($testrec = $this->pi_getRecord('tt_news', intval($vPrev[key($vPrev)]))) { // check if record exists before doing anything if ($testrec['t3ver_oid'] == intval($t3ver_oid) && $testrec['pid']==-1) { // check if requested t3ver_oid is the t3ver_oid of the requested tt_news record, and if the pid of the record is -1 (=non-plublic version) $GLOBALS['TSFE']->set_no_cache(); // version preview will never be cached // make version preview message with a link to the public version of hte record which is previewed $vPrevHeader = $this->local_cObj->stdWrap( $this->pi_getLL('versionPreviewMessage'). $this->local_cObj->typolink( $this->local_cObj->stdWrap( $this->pi_getLL('versionPreviewMessageLinkToOriginal'),$this->conf['versionPreviewMessageLinkToOriginal_stdWrap.'] ), array( 'parameter' => $this->config['singlePid'].' _blank', 'additionalParams' => '&tx_ttnews[tt_news]='.$t3ver_oid, 'no_cache' => 1 ) ), $this->conf['versionPreviewMessage_stdWrap.'] ); $this->tt_news_uid = intval($vPrev[key($vPrev)]); $this->piVars['tt_news'] = $this->tt_news_uid; $this->piVars['ADMCMD_vPrev'] = rawurlencode(serialize(array($table.':'.$t3ver_oid => $this->tt_news_uid))); $this->theCode = 'SINGLE'; $this->vPrev = true; $content = $vPrevHeader.$this->displaySingle(); } else { // error: t3ver_oid mismatch $GLOBALS['TT']->setTSlogMessage('tt_news: ERROR! The "t3ver_oid" of requested tt_news record and the "t3ver_oid" from GPvars doesn\'t match.'); } } } } } return $content; }
<?php/**************************************************************** Copyright notice** (c) 1999-2004 Kasper Skårhøj ([email protected])* (c) 2004-2007 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 8605 2008-03-15 20:03:19Z rupertgermann $** TypoScript setup:* @See 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]>*//** * [CLASS/FUNCTION INDEX of SCRIPT] * * * * 112: class tx_ttnews extends tslib_pibase * 143: function main_news($content, $conf) * 219: function init($conf) * 373: function newsArchiveMenu() * 523: function displaySingle() * 606: function displayVersionPreview () * 659: function displayList($excludeUids = 0) * 1003: function getListContent($itemparts, $selectConf, $prefix_display) * 1172: function getSelectConf($where, $noPeriod = 0) * 1419: function generatePageArray() * 1440: function getItemMarkerArray ($row, $textRenderObj = 'displaySingle') * 1723: function insertPagebreaks($text,$firstPageWordCrop) * 1773: function makeMultiPageSView($bodytext,$lConf) * 1803: function makePageBrowser($showResultCount=1,$tableParams='',$pointerName='pointer') * 1885: function getCategories($uid, $getAll=false) * 1958: function getCategoryPath($categoryArray) * 2015: function getSubCategories($catlist, $cc = 0) * 2044: function displayCatMenu() * 2157: function getCatMenuContent($array_in,$lConf, $l=0) * 2209: function getSubCategoriesForMenu ($catlist, $fields, $addWhere, $cc = 0) * 2240: function getCatMarkerArray($markerArray, $row, $lConf) * 2380: function getImageMarkers($markerArray, $row, $lConf, $textRenderObj) * 2448: function getRelated($uid) * 2608: function userProcess($mConfKey, $passVar) * 2623: function spMarker($subpartMarker) * 2641: function searchWhere($sw) * 2652: function formatStr($str) * 2667: function getLayouts($templateCode, $alternatingLayouts, $marker) * 2685: function initLanguages () * 2705: function initCategoryVars() * 2775: function checkRecords($recordlist) * 2807: function initTemplate() * 2832: function initPidList () * 2857: function getXmlHeader() * 2958: function getW3cDate($datetime) * 2983: function main_xmlnewsfeed($content, $conf) * 2998: function getStoriesResult() * 3020: function cleanXML($str) * 3034: function convertDates() * 3073: function getHrDateSingle($tstamp) * 3086: function displayFEHelp() * 3107: function validateFields($fieldlist) * 3128: function getNewsSubpart($myTemplate, $myKey, $row = Array()) * * SECTION: DB Functions * 3149: function exec_getQuery($table, $conf) * 3167: function getQuery($table, $conf, $returnQueryArray=FALSE) * 3249: function getWhere($table,$conf, $returnQueryArray=FALSE) * * TOTAL FUNCTIONS: 45 * (This index is automatically created/updated by the extension "extdeveval") * */
require_once(PATH_t3lib . 'class.t3lib_xml.php');require_once(PATH_t3lib . 'class.t3lib_htmlmail.php');require_once(PATH_tslib . 'class.tslib_pibase.php');require_once(t3lib_extMgm::extPath('tt_news') . 'class.tx_ttnews_catmenu.php');
/** * Plugin 'news' for the 'tt_news' extension. * * @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 $tt_news_uid; // the uid of the current news record in SINGLE view var $config; // the processed TypoScript configuration array var $langArr; // the languages found in the tt_news sysfolder var $sys_language_mode; var $alternatingLayouts; var $allowCaching; var $catExclusive; var $arcExclusive; var $searchFieldList = 'short,bodytext,author,keywords,links,imagecaption,title'; var $theCode = ''; var $rdfToc = ''; var $versioningEnabled = false; // is the extension 'version' loaded var $vPrev = false; // do we display a versioning preview var $categories = array(); // Is initialized with the categories of the news system var $pageArray = array(); // Is initialized with an array of the pages in the pid-list
/** * 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->local_cObj = t3lib_div::makeInstance('tslib_cObj'); // Local cObj. $this->init($conf);
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(); $noCode = true; }
while (list(, $theCode) = each($codes)) { $theCode = (string)strtoupper(trim($theCode)); $this->theCode = $theCode; switch ($theCode) { case 'SINGLE': $content .= $this->displaySingle(); break; case 'VERSION_PREVIEW': $content .= $this->displayVersionPreview(); break; case 'LATEST': case 'LIST': case 'SEARCH': case 'XML': $content .= $this->displayList(); break; case 'AMENU': $content .= $this->newsArchiveMenu(); break; case 'CATMENU': $content .= $this->displayCatMenu(); break; default: // Adds 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 { $langKey = strtoupper($GLOBALS['TSFE']->config['config']['language']); $helpTemplate = $this->cObj->fileResource('EXT:tt_news/pi/news_help.tmpl'); // Get language version of the help-template $helpTemplate_lang = ''; if ($langKey) { $helpTemplate_lang = $this->getNewsSubpart($helpTemplate, "###TEMPLATE_" . $langKey . '###'); } $helpTemplate = $helpTemplate_lang ? $helpTemplate_lang : $this->getNewsSubpart($helpTemplate, '###TEMPLATE_DEFAULT###'); // Markers and substitution: $markerArray['###CODE###'] = $this->theCode; $markerArray['###EXTPATH###'] = $GLOBALS['TYPO3_LOADED_EXT']['tt_news']['siteRelPath']; $content .= $this->displayFEHelp(); } break; } } if($noCode) { $content .= $this->displayFEHelp(); } return $content; }
/** * Init Function: here all the needed configuration values are stored in class variables.. * * @param array $conf : configuration array from TS * @returnvoid */ function init($conf) { $this->conf = $conf; //store configuration $this->pi_loadLL(); // Loading language-labels $this->pi_setPiVarDefaults(); // Set default piVars from TS $this->pi_initPIflexForm(); // Init FlexForm configuration for plugin $this->enableFields = $this->cObj->enableFields('tt_news'); $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->getCurrentVersion(); }
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;
// "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.']);
// initialize category vars $this->initCategoryVars();
// get fieldnames from the tt_news db-table $this->fieldNames = array_keys($GLOBALS['TYPO3_DB']->admin_get_fields('tt_news'));
if ($this->conf['searchFieldList']) { $searchFieldList = $this->validateFields($this->conf['searchFieldList']); if ($searchFieldList) { $this->searchFieldList = $searchFieldList; } } // Archive: $this->config['archiveMode'] = trim($this->conf['archiveMode']) ; // month, quarter or year listing in AMENU $this->config['archiveMode'] = $this->config['archiveMode']?$this->config['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:$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->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->config['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'] = $maxWordsInSingleView>1?1:$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'); $singlePid = $singlePid?$singlePid:intval($this->cObj->stdWrap($this->conf['singlePid'],$this->conf['singlePid.'])); $this->config['singlePid'] = $singlePid ? $singlePid:intval($this->conf['PIDitemDisplay']);
// pid to return to when leaving single view $backPid = intval($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'backPid', 's_misc')); $backPid = $backPid?$backPid:intval($this->conf['backPid']); $backPid = $backPid?$backPid:intval($this->piVars['backPid']); $backPid = $backPid?$backPid:$GLOBALS['TSFE']->id ; $this->config['backPid'] = $backPid;
// max items per page $FFlimit = t3lib_div::intInRange($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'listLimit', 's_misc'), 0, 1000);
$limit = t3lib_div::intInRange($this->cObj->stdWrap($this->conf['limit'],$this->conf['limit.']), 0, 1000); $limit = $limit?$limit: 50; $this->config['limit'] = $FFlimit?$FFlimit:$limit;
$latestLimit = t3lib_div::intInRange($this->cObj->stdWrap($this->conf['latestLimit'],$this->conf['latestLimit.']), 0, 1000); $latestLimit = $latestLimit?$latestLimit:10; $this->config['latestLimit'] = $FFlimit?$FFlimit:$latestLimit;
// orderBy and groupBy statements for the list Query $orderBy = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'listOrderBy', 'sDEF'); $orderByTS = trim($this->conf['listOrderBy']); $orderBy = $orderBy?$orderBy:$orderByTS; $this->config['orderBy'] = $orderBy;
if ($orderBy) { $ascDesc = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'ascDesc', 'sDEF'); $this->config['ascDesc'] = $ascDesc; if ($this->config['ascDesc']) { // remove ASC/DESC from 'orderBy' if it is already set from TS $this->config['orderBy'] = preg_replace('/( DESC| ASC)\b/i','',$this->config['orderBy']); } } $this->config['groupBy'] = trim($this->conf['listGroupBy']);
// if this is set, the first image is handled as preview image, which is only shown in list view $fImgPreview = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'firstImageIsPreview', 's_misc'); $this->config['firstImageIsPreview'] = $fImgPreview?$fImgPreview : $this->conf['firstImageIsPreview']; $forcefImgPreview = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'forceFirstImageIsPreview', 's_misc'); $this->config['forceFirstImageIsPreview'] = $forcefImgPreview?$fImgPreview : $this->conf['forceFirstImageIsPreview'];
// List start id $listStartId = intval($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'listStartId', 's_misc')); $this->config['listStartId'] = $listStartId?$listStartId:intval($this->conf['listStartId']); // supress pagebrowser $noPageBrowser = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'noPageBrowser', 's_misc'); $this->config['noPageBrowser'] = $noPageBrowser?$noPageBrowser: $this->conf['noPageBrowser'];
// image sizes given from FlexForms $this->config['FFimgH'] = intval($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'imageMaxHeight', 's_template')); $this->config['FFimgW'] = intval($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'imageMaxWidth', 's_template'));
// Get number of alternative Layouts (loop layout in LATEST and LIST view) default is 2: $altLayouts = intval($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'alternatingLayouts', 's_template')); $altLayouts = $altLayouts?$altLayouts:intval($this->conf['alternatingLayouts']); $this->alternatingLayouts = $altLayouts?$altLayouts:2;
// Get cropping lenght $this->config['croppingLenght'] = trim($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'croppingLenght', 's_template'));
$this->initTemplate();
// Configure caching $this->allowCaching = $this->conf['allowCaching']?1:0; if (!$this->allowCaching) { $GLOBALS['TSFE']->set_no_cache(); }
// get siteUrl for links in rss feeds. the 'dontInsert' option seems to be needed in some configurations depending on the baseUrl setting if (!$this->conf['displayXML.']['dontInsertSiteUrl']) { $this->config['siteUrl'] = t3lib_div::getIndpEnv('TYPO3_SITE_URL'); } }
/** * generates the News archive menu * * @returnstring html code of the archive menu */ function newsArchiveMenu() {
$this->arcExclusive = 1; $selectConf = $this->getSelectConf('', 1); // Finding maximum and minimum values: $selectConf['selectFields'] = 'max(tt_news.datetime) as maxval, min(tt_news.datetime) as minval';
$res = $this->exec_getQuery('tt_news', $selectConf);
$row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); if ($row['minval'] || $row['maxval']) { // if ($row['minval']) { $dateArr = array(); $arcMode = $this->config['archiveMode']; $c = 0; do { switch ($arcMode) { case 'month': $theDate = mktime (0, 0, 0, date('m', $row['minval']) + $c, 1, date('Y', $row['minval'])); break; case 'quarter': $theDate = mktime (0, 0, 0, floor(date('m', $row['minval']) / 3) + 1 + (3 * $c), 1, date('Y', $row['minval'])); break; case 'year': $theDate = mktime (0, 0, 0, 1, 1, date('Y', $row['minval']) + $c); break; } $dateArr[] = $theDate; $c++; if ($c > 1000) break; } while ($theDate < $GLOBALS['SIM_EXEC_TIME']);
reset($dateArr); $periodAccum = array();
$selectConf2['where'] = $selectConf['where']; while (list($k, $v) = each($dateArr)) { if (!isset($dateArr[$k + 1])) { break; }
$periodInfo = array(); $periodInfo['start'] = $dateArr[$k]; $periodInfo['stop'] = $dateArr[$k + 1]-1; $periodInfo['HRstart'] = date('d-m-Y', $periodInfo['start']); $periodInfo['HRstop'] = date('d-m-Y', $periodInfo['stop']); $periodInfo['quarter'] = floor(date('m', $dateArr[$k]) / 3) + 1; // execute a query to count the archive periods $selectConf['selectFields'] = 'count(distinct(tt_news.uid))'; $selectConf['where'] = $selectConf2['where'] . ' AND tt_news.datetime>=' . $periodInfo['start'] . ' AND tt_news.datetime<' . $periodInfo['stop'];
$res = $this->exec_getQuery('tt_news', $selectConf);
$row = $GLOBALS['TYPO3_DB']->sql_fetch_row($res); $periodInfo['count'] = $row[0];
if (!$this->conf['archiveMenuNoEmpty'] || $periodInfo['count']) { $periodAccum[] = $periodInfo; } }
// get template subpart $t['total'] = $this->getNewsSubpart($this->templateCode, $this->spMarker('###TEMPLATE_ARCHIVE###')); $t['item'] = $this->getLayouts($t['total'], $this->alternatingLayouts, 'MENUITEM'); $cc = 0;
$veryLocal_cObj = t3lib_div::makeInstance('tslib_cObj'); // reverse amenu order if 'reverseAMenu' is given if ($this->conf['reverseAMenu']) { arsort($periodAccum); }
$archiveLink = $this->conf['archiveTypoLink.']['parameter']; $this->conf['parent.']['addParams'] = $this->conf['archiveTypoLink.']['addParams']; reset($periodAccum); $itemsOutArr = array(); while (list(, $pArr) = each($periodAccum)) { // Print Item Title $wrappedSubpartArray = array();
if (!$this->conf['disableCategoriesInAmenuLinks']) { if ($this->config['catSelection'] && $this->config['amenuWithCatSelector']) { // use the catSelection from GPvars only if 'amenuWithCatSelector' is given. $amenuLinkCat = $this->config['catSelection']; } else { $amenuLinkCat = $this->catExclusive; } }
if ($this->conf['useHRDates']) { $year = date('Y',$pArr['start']); $month = date('m',$pArr['start']); if ($arcMode == 'year') { $archLinkArr = $this->pi_linkTP_keepPIvars('|', array('cat' => ($amenuLinkCat?$amenuLinkCat:null), 'year' => $year), $this->allowCaching, 1, ($archiveLink?$archiveLink:$GLOBALS['TSFE']->id)); } else { $archLinkArr = $this->pi_linkTP_keepPIvars('|', array('cat' => ($amenuLinkCat?$amenuLinkCat:null), 'year' => $year, 'month' => $month), $this->allowCaching, 1, ($archiveLink?$archiveLink:$GLOBALS['TSFE']->id)); } $wrappedSubpartArray['###LINK_ITEM###'] = explode('|', $archLinkArr); } else { $wrappedSubpartArray['###LINK_ITEM###'] = explode('|', $this->pi_linkTP_keepPIvars('|', array('cat' => ($amenuLinkCat?$amenuLinkCat:null), 'pS' => $pArr['start'], 'pL' => ($pArr['stop'] - $pArr['start']), 'arc' => 1), $this->allowCaching, 1, ($archiveLink?$archiveLink:$GLOBALS['TSFE']->id))); }
$markerArray = array(); $veryLocal_cObj->start($pArr, ''); $markerArray['###ARCHIVE_TITLE###'] = $veryLocal_cObj->cObjGetSingle($this->conf['archiveTitleCObject'], $this->conf['archiveTitleCObject.'], 'archiveTitle'); $markerArray['###ARCHIVE_COUNT###'] = $pArr['count']; $markerArray['###ARCHIVE_ITEMS###'] = $this->pi_getLL('archiveItems');
// fill the generated data to an array to pass it to a userfuction as a single variable $itemsOutArr[] = array('html' => $this->cObj->substituteMarkerArrayCached($t['item'][($cc % count($t['item']))], $markerArray, array(), $wrappedSubpartArray), 'data' => $pArr); $cc++; } // Pass to user defined function if ($this->conf['newsAmenuUserFunc']) { $itemsOutArr = $this->userProcess('newsAmenuUserFunc', $itemsOutArr); }
foreach ($itemsOutArr as $itemHtml) { $tmpItemsArr[] = $itemHtml['html']; }
if (is_array($tmpItemsArr)) { $itemsOut = implode('', $tmpItemsArr); }
// Reset: $subpartArray = array(); $wrappedSubpartArray = array(); $markerArray = array(); $markerArray['###ARCHIVE_HEADER###'] = $this->local_cObj->stdWrap($this->pi_getLL('archiveHeader'), $this->conf['archiveHeader_stdWrap.']); // Set content $subpartArray['###CONTENT###'] = $itemsOut; $content = $this->cObj->substituteMarkerArrayCached($t['total'], $markerArray, $subpartArray, $wrappedSubpartArray); } else { // if nothing is found in the archive display the TEMPLATE_ARCHIVE_NOITEMS message $markerArray['###ARCHIVE_HEADER###'] = $this->local_cObj->stdWrap($this->pi_getLL('archiveHeader'), $this->conf['archiveHeader_stdWrap.']); $markerArray['###ARCHIVE_EMPTY_MSG###'] = $this->local_cObj->stdWrap($this->pi_getLL('archiveEmptyMsg'), $this->conf['archiveEmptyMsg_stdWrap.']); $noItemsMsg = $this->getNewsSubpart($this->templateCode, $this->spMarker('###TEMPLATE_ARCHIVE_NOITEMS###')); $content = $this->cObj->substituteMarkerArrayCached($noItemsMsg, $markerArray); }
return $content; }
/** * Displays the "single view" of a news article. Is also used when displaying single news records with the "insert records" content element. * * @returnstring html-code for the "single view" */ function displaySingle() { $singleWhere = 'tt_news.uid=' . intval($this->tt_news_uid); $singleWhere .= ' AND type NOT IN(1,2)' . $this->enableFields; // only real news -> type=0
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( '*', 'tt_news', $singleWhere);
$row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); // get the translated record if the content language is not the default language if ($GLOBALS['TSFE']->sys_language_content) { $OLmode = ($this->sys_language_mode == 'strict'?'hideNonTranslated':''); $row = $GLOBALS['TSFE']->sys_page->getRecordOverlay('tt_news', $row, $GLOBALS['TSFE']->sys_language_content, $OLmode); } if ($this->versioningEnabled) { // get workspaces Overlay $GLOBALS['TSFE']->sys_page->versionOL('tt_news',$row); // fix pid for record from workspace $GLOBALS['TSFE']->sys_page->fixVersioningPid('tt_news',$row); } $GLOBALS['TSFE']->displayedNews[]=$row['uid'];
if (is_array($row) && ($row['pid'] > 0 || $this->vPrev)) { // never display versions of a news record (having pid=-1) for normal website users // Get the subpart code if ($this->conf['displayCurrentRecord']) { $item = trim($this->getNewsSubpart($this->templateCode, $this->spMarker('###TEMPLATE_SINGLE_RECORDINSERT###'), $row)); } if (!$item) { $item = $this->getNewsSubpart($this->templateCode, $this->spMarker('###TEMPLATE_SINGLE###'), $row); } // reset marker array $wrappedSubpartArray = array(); // build the backToList link if ($this->conf['useHRDates']) { $pointerName = 'pointer'; $wrappedSubpartArray['###LINK_ITEM###'] = explode('|', $this->pi_linkTP_keepPIvars('|', array( 'tt_news' => null, 'backPid' => null, $this->config['singleViewPointerName'] => null, 'pS' => null, 'pL' => null), $this->allowCaching, ($this->conf['dontUseBackPid']?1:0), $this->config['backPid'])); } else { $wrappedSubpartArray['###LINK_ITEM###'] = explode('|', $this->pi_linkTP_keepPIvars('|', array( 'tt_news' => null, 'backPid' => null, $this->config['singleViewPointerName'] => null), $this->allowCaching, ($this->conf['dontUseBackPid']?1:0), $this->config['backPid'])); } // set the title of the single view page to the title of the news record if ($this->conf['substitutePagetitle']) { $GLOBALS['TSFE']->page['title'] = $row['title']; // set pagetitle for indexed search to news title $GLOBALS['TSFE']->indexedDocTitle = $row['title']; } if ($this->conf['displaySingle.']['catOrderBy']) { $this->config['catOrderBy'] = $this->conf['displaySingle.']['catOrderBy']; } $markerArray = $this->getItemMarkerArray($row, 'displaySingle'); // Substitute $content = $this->cObj->substituteMarkerArrayCached($item, $markerArray, array(), $wrappedSubpartArray); } elseif ($this->sys_language_mode == 'strict' && $this->tt_news_uid && $GLOBALS['TSFE']->sys_language_content) { // not existing translation $noTranslMsg = $this->local_cObj->stdWrap($this->pi_getLL('noTranslMsg'), $this->conf['noNewsIdMsg_stdWrap.']); $content = $noTranslMsg; } elseif ($row['pid'] < 0) { // a non-public version of a record was requested $nonPlublicVersion = $this->local_cObj->stdWrap($this->pi_getLL('nonPlublicVersionMsg'), $this->conf['nonPlublicVersionMsg_stdWrap.']); $content = $nonPlublicVersion; } else { // if singleview is shown with no tt_news uid given from GETvars (&tx_ttnews[tt_news]=) an error message is displayed. $noNewsIdMsg = $this->local_cObj->stdWrap($this->pi_getLL('noNewsIdMsg'), $this->conf['noNewsIdMsg_stdWrap.']); $content = $noNewsIdMsg; } return $content; }
/** * Displays the "versioning preview". * The functions checks: * - if the extension "version" is loaded * - if a BE_user is logged in * - the plausibility of the requested "version preview". * If this is all OK, "displaySingle()" is executed to display the "versioning preview". * * @returnstring html code for the "versioning preview" */ function displayVersionPreview () { if ($this->versioningEnabled) { $vPrev = t3lib_div::_GP('ADMCMD_vPrev'); if ($this->piVars['ADMCMD_vPrev']) { $piADMCMD = unserialize(rawurldecode($this->piVars['ADMCMD_vPrev'])); } if ((is_array($vPrev) || is_array($piADMCMD)) && is_object($GLOBALS['BE_USER'])) { // check if ADMCMD_vPrev is set and if a BE_user is logged in. $this->piVars['ADMCMD_vPrev'] is needed for previewing a "single view with pagebrowser" if (!is_array($vPrev)) { $vPrev = $piADMCMD; } list($table,$t3ver_oid) = explode(':',key($vPrev)); if ($table == 'tt_news') { if ($testrec = $this->pi_getRecord('tt_news', intval($vPrev[key($vPrev)]))) { // check if record exists before doing anything if ($testrec['t3ver_oid'] == intval($t3ver_oid) && $testrec['pid']==-1) { // check if requested t3ver_oid is the t3ver_oid of the requested tt_news record, and if the pid of the record is -1 (=non-plublic version) $GLOBALS['TSFE']->set_no_cache(); // version preview will never be cached // make version preview message with a link to the public version of hte record which is previewed $vPrevHeader = $this->local_cObj->stdWrap( $this->pi_getLL('versionPreviewMessage'). $this->local_cObj->typolink( $this->local_cObj->stdWrap( $this->pi_getLL('versionPreviewMessageLinkToOriginal'),$this->conf['versionPreviewMessageLinkToOriginal_stdWrap.'] ), array( 'parameter' => $this->config['singlePid'].' _blank', 'additionalParams' => '&tx_ttnews[tt_news]='.$t3ver_oid, 'no_cache' => 1 ) ), $this->conf['versionPreviewMessage_stdWrap.'] ); $this->tt_news_uid = intval($vPrev[key($vPrev)]); $this->piVars['tt_news'] = $this->tt_news_uid; $this->piVars['ADMCMD_vPrev'] = rawurlencode(serialize(array($table.':'.$t3ver_oid => $this->tt_news_uid))); $this->theCode = 'SINGLE'; $this->vPrev = true; $content = $vPrevHeader.$this->displaySingle(); } else { // error: t3ver_oid mismatch $GLOBALS['TT']->setTSlogMessage('tt_news: ERROR! The "t3ver_oid" of requested tt_news record and the "t3ver_oid" from GPvars doesn\'t match.'); } } } } } return $content; }
<?php/**************************************************************** Copyright notice** (c) 1999-2004 Kasper Skårhøj ([email protected])* (c) 2004-2007 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 8605 2008-03-15 20:03:19Z rupertgermann $** TypoScript setup:* @See 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]>*//** * [CLASS/FUNCTION INDEX of SCRIPT] * * * * 112: class tx_ttnews extends tslib_pibase * 143: function main_news($content, $conf) * 219: function init($conf) * 373: function newsArchiveMenu() * 523: function displaySingle() * 606: function displayVersionPreview () * 659: function displayList($excludeUids = 0) * 1003: function getListContent($itemparts, $selectConf, $prefix_display) * 1172: function getSelectConf($where, $noPeriod = 0) * 1419: function generatePageArray() * 1440: function getItemMarkerArray ($row, $textRenderObj = 'displaySingle') * 1723: function insertPagebreaks($text,$firstPageWordCrop) * 1773: function makeMultiPageSView($bodytext,$lConf) * 1803: function makePageBrowser($showResultCount=1,$tableParams='',$pointerName='pointer') * 1885: function getCategories($uid, $getAll=false) * 1958: function getCategoryPath($categoryArray) * 2015: function getSubCategories($catlist, $cc = 0) * 2044: function displayCatMenu() * 2157: function getCatMenuContent($array_in,$lConf, $l=0) * 2209: function getSubCategoriesForMenu ($catlist, $fields, $addWhere, $cc = 0) * 2240: function getCatMarkerArray($markerArray, $row, $lConf) * 2380: function getImageMarkers($markerArray, $row, $lConf, $textRenderObj) * 2448: function getRelated($uid) * 2608: function userProcess($mConfKey, $passVar) * 2623: function spMarker($subpartMarker) * 2641: function searchWhere($sw) * 2652: function formatStr($str) * 2667: function getLayouts($templateCode, $alternatingLayouts, $marker) * 2685: function initLanguages () * 2705: function initCategoryVars() * 2775: function checkRecords($recordlist) * 2807: function initTemplate() * 2832: function initPidList () * 2857: function getXmlHeader() * 2958: function getW3cDate($datetime) * 2983: function main_xmlnewsfeed($content, $conf) * 2998: function getStoriesResult() * 3020: function cleanXML($str) * 3034: function convertDates() * 3073: function getHrDateSingle($tstamp) * 3086: function displayFEHelp() * 3107: function validateFields($fieldlist) * 3128: function getNewsSubpart($myTemplate, $myKey, $row = Array()) * * SECTION: DB Functions * 3149: function exec_getQuery($table, $conf) * 3167: function getQuery($table, $conf, $returnQueryArray=FALSE) * 3249: function getWhere($table,$conf, $returnQueryArray=FALSE) * * TOTAL FUNCTIONS: 45 * (This index is automatically created/updated by the extension "extdeveval") * */
require_once(PATH_t3lib . 'class.t3lib_xml.php');require_once(PATH_t3lib . 'class.t3lib_htmlmail.php');require_once(PATH_tslib . 'class.tslib_pibase.php');require_once(t3lib_extMgm::extPath('tt_news') . 'class.tx_ttnews_catmenu.php');
/** * Plugin 'news' for the 'tt_news' extension. * * @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 namevar $scriptRelPath = 'pi/class.tx_ttnews.php'; // Path to this script relative to the extension dir.var $extKey = 'tt_news'; // The extension key.var $tt_news_uid; // the uid of the current news record in SINGLE viewvar $config; // the processed TypoScript configuration arrayvar $langArr; // the languages found in the tt_news sysfoldervar $sys_language_mode;var $alternatingLayouts;var $allowCaching;var $catExclusive;var $arcExclusive;var $searchFieldList = 'short,bodytext,author,keywords,links,imagecaption,title';var $theCode = '';var $rdfToc = '';var $versioningEnabled = false; // is the extension 'version' loadedvar $vPrev = false; // do we display a versioning previewvar $categories = array(); // Is initialized with the categories of the news systemvar $pageArray = array(); // Is initialized with an array of the pages in the pid-list
/** * Main news function: calls the init_news() function and decides by the given CODEs which of the * functions to display news should by called. * * @paramstring $content : function output is added to this * @paramarray $conf : configuration array * @returnstring $content: complete content generated by the tt_news plugin */function main_news($content, $conf) { $this->local_cObj = t3lib_div::makeInstance('tslib_cObj'); // Local cObj. $this->init($conf);
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(); $noCode = true; }
while (list(, $theCode) = each($codes)) { $theCode = (string)strtoupper(trim($theCode)); $this->theCode = $theCode; switch ($theCode) { case 'SINGLE': $content .= $this->displaySingle(); break; case 'VERSION_PREVIEW': $content .= $this->displayVersionPreview(); break; case 'LATEST': case 'LIST': case 'SEARCH': case 'XML': $content .= $this->displayList(); break; case 'AMENU': $content .= $this->newsArchiveMenu(); break; case 'CATMENU': $content .= $this->displayCatMenu(); break; default: // Adds 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 { $langKey = strtoupper($GLOBALS['TSFE']->config['config']['language']); $helpTemplate = $this->cObj->fileResource('EXT:tt_news/pi/news_help.tmpl'); // Get language version of the help-template $helpTemplate_lang = ''; if ($langKey) { $helpTemplate_lang = $this->getNewsSubpart($helpTemplate, "###TEMPLATE_" . $langKey . '###'); } $helpTemplate = $helpTemplate_lang ? $helpTemplate_lang : $this->getNewsSubpart($helpTemplate, '###TEMPLATE_DEFAULT###'); // Markers and substitution: $markerArray['###CODE###'] = $this->theCode; $markerArray['###EXTPATH###'] = $GLOBALS['TYPO3_LOADED_EXT']['tt_news']['siteRelPath']; $content .= $this->displayFEHelp(); } break; } } if($noCode) { $content .= $this->displayFEHelp(); } return $content;}
/** * Init Function: here all the needed configuration values are stored in class variables.. * * @paramarray $conf : configuration array from TS * @returnvoid */function init($conf) { $this->conf = $conf; //store configuration $this->pi_loadLL(); // Loading language-labels $this->pi_setPiVarDefaults(); // Set default piVars from TS $this->pi_initPIflexForm(); // Init FlexForm configuration for plugin $this->enableFields = $this->cObj->enableFields('tt_news'); $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->getCurrentVersion(); }
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;
// "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.']);
// initialize category vars $this->initCategoryVars();
// get fieldnames from the tt_news db-table $this->fieldNames = array_keys($GLOBALS['TYPO3_DB']->admin_get_fields('tt_news'));
if ($this->conf['searchFieldList']) { $searchFieldList = $this->validateFields($this->conf['searchFieldList']); if ($searchFieldList) { $this->searchFieldList = $searchFieldList; } } // Archive: $this->config['archiveMode'] = trim($this->conf['archiveMode']) ; // month, quarter or year listing in AMENU $this->config['archiveMode'] = $this->config['archiveMode']?$this->config['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:$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->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->config['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'] = $maxWordsInSingleView>1?1:$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'); $singlePid = $singlePid?$singlePid:intval($this->cObj->stdWrap($this->conf['singlePid'],$this->conf['singlePid.'])); $this->config['singlePid'] = $singlePid ? $singlePid:intval($this->conf['PIDitemDisplay']);
// pid to return to when leaving single view $backPid = intval($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'backPid', 's_misc')); $backPid = $backPid?$backPid:intval($this->conf['backPid']); $backPid = $backPid?$backPid:intval($this->piVars['backPid']); $backPid = $backPid?$backPid:$GLOBALS['TSFE']->id ; $this->config['backPid'] = $backPid;
// max items per page $FFlimit = t3lib_div::intInRange($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'listLimit', 's_misc'), 0, 1000);
$limit = t3lib_div::intInRange($this->cObj->stdWrap($this->conf['limit'],$this->conf['limit.']), 0, 1000); $limit = $limit?$limit:50; $this->config['limit'] = $FFlimit?$FFlimit:$limit;
$latestLimit = t3lib_div::intInRange($this->cObj->stdWrap($this->conf['latestLimit'],$this->conf['latestLimit.']), 0, 1000); $latestLimit = $latestLimit?$latestLimit:10; $this->config['latestLimit'] = $FFlimit?$FFlimit:$latestLimit;
// orderBy and groupBy statements for the list Query $orderBy = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'listOrderBy', 'sDEF'); $orderByTS = trim($this->conf['listOrderBy']); $orderBy = $orderBy?$orderBy:$orderByTS; $this->config['orderBy'] = $orderBy;
if ($orderBy) { $ascDesc = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'ascDesc', 'sDEF'); $this->config['ascDesc'] = $ascDesc; if ($this->config['ascDesc']) { // remove ASC/DESC from 'orderBy' if it is already set from TS $this->config['orderBy'] = preg_replace('/( DESC| ASC)\b/i','',$this->config['orderBy']); } } $this->config['groupBy'] = trim($this->conf['listGroupBy']);
// if this is set, the first image is handled as preview image, which is only shown in list view $fImgPreview = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'firstImageIsPreview', 's_misc'); $this->config['firstImageIsPreview'] = $fImgPreview?$fImgPreview : $this->conf['firstImageIsPreview']; $forcefImgPreview = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'forceFirstImageIsPreview', 's_misc'); $this->config['forceFirstImageIsPreview'] = $forcefImgPreview?$fImgPreview : $this->conf['forceFirstImageIsPreview'];
// List start id $listStartId = intval($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'listStartId', 's_misc')); $this->config['listStartId'] = $listStartId?$listStartId:intval($this->conf['listStartId']); // supress pagebrowser $noPageBrowser = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'noPageBrowser', 's_misc'); $this->config['noPageBrowser'] = $noPageBrowser?$noPageBrowser:$this->conf['noPageBrowser'];
// image sizes given from FlexForms $this->config['FFimgH'] = intval($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'imageMaxHeight', 's_template')); $this->config['FFimgW'] = intval($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'imageMaxWidth', 's_template'));
// Get number of alternative Layouts (loop layout in LATEST and LIST view) default is 2: $altLayouts = intval($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'alternatingLayouts', 's_template')); $altLayouts = $altLayouts?$altLayouts:intval($this->conf['alternatingLayouts']); $this->alternatingLayouts = $altLayouts?$altLayouts:2;
// Get cropping lenght $this->config['croppingLenght'] = trim($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'croppingLenght', 's_template'));
$this->initTemplate();
// Configure caching $this->allowCaching = $this->conf['allowCaching']?1:0; if (!$this->allowCaching) { $GLOBALS['TSFE']->set_no_cache(); }
// get siteUrl for links in rss feeds. the 'dontInsert' option seems to be needed in some configurations depending on the baseUrl setting if (!$this->conf['displayXML.']['dontInsertSiteUrl']) { $this->config['siteUrl'] = t3lib_div::getIndpEnv('TYPO3_SITE_URL'); }}
/** * generates the News archive menu * * @returnstring html code of the archive menu */function newsArchiveMenu() {
$this->arcExclusive = 1; $selectConf = $this->getSelectConf('', 1); // Finding maximum and minimum values: $selectConf['selectFields'] = 'max(tt_news.datetime) as maxval, min(tt_news.datetime) as minval';
$res = $this->exec_getQuery('tt_news', $selectConf);
$row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); if ($row['minval'] || $row['maxval']) { // if ($row['minval']) { $dateArr = array(); $arcMode = $this->config['archiveMode']; $c = 0; do { switch ($arcMode) { case 'month': $theDate = mktime (0, 0, 0, date('m', $row['minval']) + $c, 1, date('Y', $row['minval'])); break; case 'quarter': $theDate = mktime (0, 0, 0, floor(date('m', $row['minval']) / 3) + 1 + (3 * $c), 1, date('Y', $row['minval'])); break; case 'year': $theDate = mktime (0, 0, 0, 1, 1, date('Y', $row['minval']) + $c); break; } $dateArr[] = $theDate; $c++; if ($c > 1000) break; } while ($theDate < $GLOBALS['SIM_EXEC_TIME']);
reset($dateArr); $periodAccum = array();
$selectConf2['where'] = $selectConf['where']; while (list($k, $v) = each($dateArr)) { if (!isset($dateArr[$k + 1])) { break; }
$periodInfo = array(); $periodInfo['start'] = $dateArr[$k]; $periodInfo['stop'] = $dateArr[$k + 1]-1; $periodInfo['HRstart'] = date('d-m-Y', $periodInfo['start']); $periodInfo['HRstop'] = date('d-m-Y', $periodInfo['stop']); $periodInfo['quarter'] = floor(date('m', $dateArr[$k]) / 3) + 1; // execute a query to count the archive periods $selectConf['selectFields'] = 'count(distinct(tt_news.uid))'; $selectConf['where'] = $selectConf2['where'] . ' AND tt_news.datetime>=' . $periodInfo['start'] . ' AND tt_news.datetime<' . $periodInfo['stop'];
$res = $this->exec_getQuery('tt_news', $selectConf);
$row = $GLOBALS['TYPO3_DB']->sql_fetch_row($res); $periodInfo['count'] = $row[0];
if (!$this->conf['archiveMenuNoEmpty'] || $periodInfo['count']) { $periodAccum[] = $periodInfo; } }
// get template subpart $t['total'] = $this->getNewsSubpart($this->templateCode, $this->spMarker('###TEMPLATE_ARCHIVE###')); $t['item'] = $this->getLayouts($t['total'], $this->alternatingLayouts, 'MENUITEM'); $cc = 0;
$veryLocal_cObj = t3lib_div::makeInstance('tslib_cObj'); // reverse amenu order if 'reverseAMenu' is given if ($this->conf['reverseAMenu']) { arsort($periodAccum); }
$archiveLink = $this->conf['archiveTypoLink.']['parameter']; $this->conf['parent.']['addParams'] = $this->conf['archiveTypoLink.']['addParams']; reset($periodAccum); $itemsOutArr = array(); while (list(, $pArr) = each($periodAccum)) { // Print Item Title $wrappedSubpartArray = array();
if (!$this->conf['disableCategoriesInAmenuLinks']) { if ($this->config['catSelection'] && $this->config['amenuWithCatSelector']) { // use the catSelection from GPvars only if 'amenuWithCatSelector' is given. $amenuLinkCat = $this->config['catSelection']; } else { $amenuLinkCat = $this->catExclusive; } }
if ($this->conf['useHRDates']) { $year = date('Y',$pArr['start']); $month = date('m',$pArr['start']); if ($arcMode == 'year') { $archLinkArr = $this->pi_linkTP_keepPIvars('|', array('cat' => ($amenuLinkCat?$amenuLinkCat:null), 'year' => $year), $this->allowCaching, 1, ($archiveLink?$archiveLink:$GLOBALS['TSFE']->id)); } else { $archLinkArr = $this->pi_linkTP_keepPIvars('|', array('cat' => ($amenuLinkCat?$amenuLinkCat:null), 'year' => $year, 'month' => $month), $this->allowCaching, 1, ($archiveLink?$archiveLink:$GLOBALS['TSFE']->id)); } $wrappedSubpartArray['###LINK_ITEM###'] = explode('|', $archLinkArr); } else { $wrappedSubpartArray['###LINK_ITEM###'] = explode('|', $this->pi_linkTP_keepPIvars('|', array('cat' => ($amenuLinkCat?$amenuLinkCat:null), 'pS' => $pArr['start'], 'pL' => ($pArr['stop'] - $pArr['start']), 'arc' => 1), $this->allowCaching, 1, ($archiveLink?$archiveLink:$GLOBALS['TSFE']->id))); }
$markerArray = array(); $veryLocal_cObj->start($pArr, ''); $markerArray['###ARCHIVE_TITLE###'] = $veryLocal_cObj->cObjGetSingle($this->conf['archiveTitleCObject'], $this->conf['archiveTitleCObject.'], 'archiveTitle'); $markerArray['###ARCHIVE_COUNT###'] = $pArr['count']; $markerArray['###ARCHIVE_ITEMS###'] = $this->pi_getLL('archiveItems');
// fill the generated data to an array to pass it to a userfuction as a single variable $itemsOutArr[] = array('html' => $this->cObj->substituteMarkerArrayCached($t['item'][($cc % count($t['item']))], $markerArray, array(), $wrappedSubpartArray), 'data' => $pArr); $cc++; } // Pass to user defined function if ($this->conf['newsAmenuUserFunc']) { $itemsOutArr = $this->userProcess('newsAmenuUserFunc', $itemsOutArr); }
foreach ($itemsOutArr as $itemHtml) { $tmpItemsArr[] = $itemHtml['html']; }
if (is_array($tmpItemsArr)) { $itemsOut = implode('', $tmpItemsArr); }
// Reset: $subpartArray = array(); $wrappedSubpartArray = array(); $markerArray = array(); $markerArray['###ARCHIVE_HEADER###'] = $this->local_cObj->stdWrap($this->pi_getLL('archiveHeader'), $this->conf['archiveHeader_stdWrap.']); // Set content $subpartArray['###CONTENT###'] = $itemsOut; $content = $this->cObj->substituteMarkerArrayCached($t['total'], $markerArray, $subpartArray, $wrappedSubpartArray); } else { // if nothing is found in the archive display the TEMPLATE_ARCHIVE_NOITEMS message $markerArray['###ARCHIVE_HEADER###'] = $this->local_cObj->stdWrap($this->pi_getLL('archiveHeader'), $this->conf['archiveHeader_stdWrap.']); $markerArray['###ARCHIVE_EMPTY_MSG###'] = $this->local_cObj->stdWrap($this->pi_getLL('archiveEmptyMsg'), $this->conf['archiveEmptyMsg_stdWrap.']); $noItemsMsg = $this->getNewsSubpart($this->templateCode, $this->spMarker('###TEMPLATE_ARCHIVE_NOITEMS###')); $content = $this->cObj->substituteMarkerArrayCached($noItemsMsg, $markerArray); }
return $content;}
/** * Displays the "single view" of a news article. Is also used when displaying single news records with the "insert records" content element. * * @returnstring html-code for the "single view" */function displaySingle() { $singleWhere = 'tt_news.uid=' . intval($this->tt_news_uid); $singleWhere .= ' AND type NOT IN(1,2)' . $this->enableFields; // only real news -> type=0
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( '*', 'tt_news', $singleWhere);
$row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); // get the translated record if the content language is not the default language if ($GLOBALS['TSFE']->sys_language_content) { $OLmode = ($this->sys_language_mode == 'strict'?'hideNonTranslated':''); $row = $GLOBALS['TSFE']->sys_page->getRecordOverlay('tt_news', $row, $GLOBALS['TSFE']->sys_language_content, $OLmode); } if ($this->versioningEnabled) { // get workspaces Overlay $GLOBALS['TSFE']->sys_page->versionOL('tt_news',$row); // fix pid for record from workspace $GLOBALS['TSFE']->sys_page->fixVersioningPid('tt_news',$row); } $GLOBALS['TSFE']->displayedNews[]=$row['uid'];
if (is_array($row) && ($row['pid'] > 0 || $this->vPrev)) { // never display versions of a news record (having pid=-1) for normal website users // Get the subpart code if ($this->conf['displayCurrentRecord']) { $item = trim($this->getNewsSubpart($this->templateCode, $this->spMarker('###TEMPLATE_SINGLE_RECORDINSERT###'), $row)); } if (!$item) { $item = $this->getNewsSubpart($this->templateCode, $this->spMarker('###TEMPLATE_SINGLE###'), $row); } // reset marker array $wrappedSubpartArray = array(); // build the backToList link if ($this->conf['useHRDates']) { $pointerName = 'pointer'; $wrappedSubpartArray['###LINK_ITEM###'] = explode('|', $this->pi_linkTP_keepPIvars('|', array( 'tt_news' => null, 'backPid' => null, $this->config['singleViewPointerName'] => null, 'pS' => null, 'pL' => null), $this->allowCaching, ($this->conf['dontUseBackPid']?1:0), $this->config['backPid'])); } else { $wrappedSubpartArray['###LINK_ITEM###'] = explode('|', $this->pi_linkTP_keepPIvars('|', array( 'tt_news' => null, 'backPid' => null, $this->config['singleViewPointerName'] => null), $this->allowCaching, ($this->conf['dontUseBackPid']?1:0), $this->config['backPid'])); } // set the title of the single view page to the title of the news record if ($this->conf['substitutePagetitle']) { $GLOBALS['TSFE']->page['title'] = $row['title']; // set pagetitle for indexed search to news title $GLOBALS['TSFE']->indexedDocTitle = $row['title']; } if ($this->conf['displaySingle.']['catOrderBy']) { $this->config['catOrderBy'] = $this->conf['displaySingle.']['catOrderBy']; } $markerArray = $this->getItemMarkerArray($row, 'displaySingle'); // Substitute $content = $this->cObj->substituteMarkerArrayCached($item, $markerArray, array(), $wrappedSubpartArray); } elseif ($this->sys_language_mode == 'strict' && $this->tt_news_uid && $GLOBALS['TSFE']->sys_language_content) { // not existing translation $noTranslMsg = $this->local_cObj->stdWrap($this->pi_getLL('noTranslMsg'), $this->conf['noNewsIdMsg_stdWrap.']); $content = $noTranslMsg; } elseif ($row['pid'] < 0) { // a non-public version of a record was requested $nonPlublicVersion = $this->local_cObj->stdWrap($this->pi_getLL('nonPlublicVersionMsg'), $this->conf['nonPlublicVersionMsg_stdWrap.']); $content = $nonPlublicVersion; } else { // if singleview is shown with no tt_news uid given from GETvars (&tx_ttnews[tt_news]=) an error message is displayed. $noNewsIdMsg = $this->local_cObj->stdWrap($this->pi_getLL('noNewsIdMsg'), $this->conf['noNewsIdMsg_stdWrap.']); $content = $noNewsIdMsg; } return $content;}
/** * Displays the "versioning preview". * The functions checks: * - if the extension "version" is loaded * - if a BE_user is logged in * - the plausibility of the requested "version preview". * If this is all OK, "displaySingle()" is executed to display the "versioning preview". * * @returnstring html code for the "versioning preview" */function displayVersionPreview () { if ($this->versioningEnabled) { $vPrev = t3lib_div::_GP('ADMCMD_vPrev'); if ($this->piVars['ADMCMD_vPrev']) { $piADMCMD = unserialize(rawurldecode($this->piVars['ADMCMD_vPrev'])); } if ((is_array($vPrev) || is_array($piADMCMD)) && is_object($GLOBALS['BE_USER'])) { // check if ADMCMD_vPrev is set and if a BE_user is logged in. $this->piVars['ADMCMD_vPrev'] is needed for previewing a "single view with pagebrowser" if (!is_array($vPrev)) { $vPrev = $piADMCMD; } list($table,$t3ver_oid) = explode(':',key($vPrev)); if ($table == 'tt_news') { if ($testrec = $this->pi_getRecord('tt_news', intval($vPrev[key($vPrev)]))) { // check if record exists before doing anything if ($testrec['t3ver_oid'] == intval($t3ver_oid) && $testrec['pid']==-1) { // check if requested t3ver_oid is the t3ver_oid of the requested tt_news record, and if the pid of the record is -1 (=non-plublic version) $GLOBALS['TSFE']->set_no_cache(); // version preview will never be cached // make version preview message with a link to the public version of hte record which is previewed $vPrevHeader = $this->local_cObj->stdWrap( $this->pi_getLL('versionPreviewMessage'). $this->local_cObj->typolink( $this->local_cObj->stdWrap( $this->pi_getLL('versionPreviewMessageLinkToOriginal'),$this->conf['versionPreviewMessageLinkToOriginal_stdWrap.'] ), array( 'parameter' => $this->config['singlePid'].' _blank', 'additionalParams' => '&tx_ttnews[tt_news]='.$t3ver_oid, 'no_cache' => 1 ) ), $this->conf['versionPreviewMessage_stdWrap.'] ); $this->tt_news_uid = intval($vPrev[key($vPrev)]); $this->piVars['tt_news'] = $this->tt_news_uid; $this->piVars['ADMCMD_vPrev'] = rawurlencode(serialize(array($table.':'.$t3ver_oid => $this->tt_news_uid))); $this->theCode = 'SINGLE'; $this->vPrev = true; $content = $vPrevHeader.$this->displaySingle(); } else { // error: t3ver_oid mismatch $GLOBALS['TT']->setTSlogMessage('tt_news: ERROR! The "t3ver_oid" of requested tt_news record and the "t3ver_oid" from GPvars doesn\'t match.'); } } } } } return $content;}
control flow
business logic
CRUD data
other , eg. config
render output
control flow
business logic
CRUD data
other , eg. config
render outputaggregate
generalize
control flow
business logic
CRUD data
other , eg. config
render output
partition
useExtbase & Fluid
control flow
business logic
CRUD data
other , eg. config
render output
Controller
Domain Model
Domain Repository
other , eg. config
View
TYPO3
ExtbaseDispatcherTYPO3
userFunc
1
ExtbaseDispatcher
Controller
Request
TYPO3
userFunc
12 BlogExample
ExtbaseDispatcher
Controller
Repository
Request
findByTitle('MyBlog')
TYPO3
Domain Model
userFunc
12
3
Blog
Post
Comment Tag
BlogExample
ExtbaseDispatcher
Controller
Repository
Request
findByTitle('MyBlog')
Blog
TYPO3
Domain Model
userFunc
12
3
4
Blog
Post
Comment Tag
BlogExample
ExtbaseDispatcher
Controller
Repository View
Request
findByTitle('MyBlog')
Blog
assign(Blog)
TYPO3
Domain Model
render()
userFunc
12
3
4
5
Blog
Post
Comment Tag
BlogExample
ExtbaseDispatcher
Controller
Repository View
Request
findByTitle('MyBlog')
Response
Blog
assign(Blog)
Response
TYPO3
Domain Model
HTML
render()
userFunc
12
3
4
5
6
Blog
Post
Comment Tag
BlogExample
ExtbaseDispatcher
Controller
Repository View
Request
findByTitle('MyBlog')
Response
Blog
assign(Blog)
Response
TYPO3
Domain Model
HTML
render()
userFunc
12
3
4
5
6
Blog
Post
Comment Tag
BlogExample
ExtbaseDispatcher
Controller
Repository View
Request
findByTitle('MyBlog')
Response
Blog
assign(Blog)
Response
TYPO3
Domain Model
HTML
render()
userFunc
12
3
4
5
6
Blog
Post
Comment Tag
BlogExample
View
Controller
Model
Spaghetti code Lasagna code
Hmmm.Much better.
What's coming
PerformanceSQL queries
object trackingcaching
Dev Experience
speaking exceptionsdocumentationkickstarter
Catalysedispatcher
persistence backendprocess for patches
And beyond Extbase?
IMHO
http://www.sxc.hu/photo/516864/
Generic Domain Models
WRUVI
William Street Rajan United States Virginia Indian
William Street Rajan United States Virginia Indian
William Street
Rajan
United States Virginia Indian
WRUVI
x
William Street Rajan United States Virginia Indian
William Street
Rajan
United States Virginia Indian
WRUVI
x
William Street Rajan United States Virginia Indian
William Street
Rajan
United States Virginia Indian
WRUVI
x
William Street Rajan United States Virginia Indian
Organization
Customer
Date
Event
Price
Invoice
Publication
Product
Article Location
NumberImage
Your Model
based on high quality, open standardsOASIS CIQ 3.0 for persons, organizations, addresses, namesBMEcat for product, suppliers, catalogs, pricesiCalendar for calendar, events, datesetc.
challengesXML2PHPinteroperabilityconsistent semantics
@jochen: it's time for an example
Generic Domain Models
Product Line Engineering
Extbase Fluid
TYPO3 v4
ViewHelpersGeneric Domain Models
Extbase Fluid
TYPO3 v4
Extbase Fluid
TYPO3 v4
Extbase Fluid
TYPO3 v4
Extbase Fluid
TYPO3 v4
FLOW3
Fluid
TYPO3 v5
ViewHelpersGeneric Domain Models
platform
FLOW3
Fluid
TYPO3 v5
ViewHelpersGeneric Domain Models
building blocks
FLOW3
Fluid
TYPO3 v5
ViewHelpersGeneric Domain Models
TYPO3
FLOW3
Fluid
TYPO3 v5
ViewHelpersGeneric Domain Models
packagesP P P P P P P P PP
FLOW3
Fluid
TYPO3 v5
ViewHelpersGeneric Domain Models
TYPO3 Social SiteP P P P P P P P PP
FLOW3
Fluid
TYPO3 v5
ViewHelpersGeneric Domain Models
TYPO3 EnterprisePP P PP P P P P P
FLOW3
Fluid
TYPO3 v5
ViewHelpersGeneric Domain Models
TYPO3 BlogPPPP PP PPPP
FLOW3
Fluid
TYPO3 v5
ViewHelpersGeneric Domain Models
Product LinePPPP PP PPPP
The meaning of things
http://webscience.org/people.html
Knublauch, Holger. KBeans Specification: Semantic Transparency for Components and Domain Models. Technical Report FAW-TR-01001, FAW Ulm, 2001.
Semantic annotations
/** * A container for defining the unique characteristics of a person only * * @version $Id$ * @copyright Copyright belongs to the respective authors * @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3 or later * @prefix foaf: <http://xmlns.com/foaf/0.1/> * @prefix owl: <http://www.w3.org/2002/07/owl#> * @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> * @prefix core: <http://www.typo3.org/semantic/core/> * @prefix gen: <http://www.typo3.org/semantic/ext/generic/domain/model/> * @semantic gen:Person rdfs:subClassOf gen:Party * @semantic gen:Person owl:disjointWith gen:Organization * @semantic gen:Person core:isMemberOf gen:Organization */class Tx_Generic_Domain_Model_Person extends Tx_Generic_Domain_Model_Party { /** * Party Names * @var Tx_Extbase_Persistence_ObjectStorage<Tx_Generic_Domain_Model_PersonName> * @semantic gen:partyNames gen:areOfType foaf:name */ protected $partyNames; /** * personInfo * @var Tx_Generic_Domain_Model_PersonInfo */ protected $personInfo;
Semantic Query with SPARQL
## Find all authors of News Articles that are posted on a page with the english title "Welcome"PREFIX core:<http:://www.typo3.org/ontology/core/#>PREFIX generic:<http:://www.typo3.org/ontology/ext/generic/#>PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#>SELECT $person $articleFROM <http:://localhost/repository.rdf>WHERE { $person rdfs:type generic:Person . $person core:authorOf $article . $article rdfs:type core:NewsArticle . $article core:isPlacedOn $page . $page core:title "Welcome"@en .}
[TYPO3-dev] The state of support for the Semantic Web / RDFA / Web 3.0 in TYPO3Jochen Rau jochen.rau at typoplanet.de Mon Aug 31 16:26:51 CEST 2009
• Previous message: [TYPO3-dev] The state of support for the Semantic Web / RDFA / Web 3.0 in TYPO3• Next message: [TYPO3-dev] The state of support for the Semantic Web / RDFA / Web 3.0 in TYPO3• Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
get Extbase ready ;-)de!ne generic domain modelsbind objects to an ontologyelaborate on the use cases of semantic contentmake the integration of semantic web technology a movement of the community
Patrick Lobacher
Sebastian KurfürstBastian Waidelich
Ingmar Schlecht
and the TYPO3 V5 Team for all the inspiration and the beautiful code
Thank YouSteffen Kamper
Xavier Perseguers
Felix Oertel
Franz Koch
Sebastian Gebhard
Franz Ripfel