|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com) 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00027 /** 00028 * This script contains the parent class, 'pibase', providing an API with the most basic methods for frontend plugins 00029 * 00030 * $Id: class.tslib_pibase.php 10547 2011-02-22 20:03:57Z lolli $ 00031 * Revised for TYPO3 3.6 June/2003 by Kasper Skårhøj 00032 * XHTML compliant 00033 * 00034 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00035 */ 00036 /** 00037 * [CLASS/FUNCTION INDEX of SCRIPT] 00038 * 00039 * 00040 * 00041 * 132: class tslib_pibase 00042 * 00043 * SECTION: Init functions 00044 * 214: function tslib_pibase() 00045 * 240: function pi_setPiVarDefaults() 00046 * 00047 * SECTION: Link functions 00048 * 277: function pi_getPageLink($id,$target='',$urlParameters=array()) 00049 * 293: function pi_linkToPage($str,$id,$target='',$urlParameters=array()) 00050 * 308: function pi_linkTP($str,$urlParameters=array(),$cache=0,$altPageId=0) 00051 * 331: function pi_linkTP_keepPIvars($str,$overrulePIvars=array(),$cache=0,$clearAnyway=0,$altPageId=0) 00052 * 355: function pi_linkTP_keepPIvars_url($overrulePIvars=array(),$cache=0,$clearAnyway=0,$altPageId=0) 00053 * 373: function pi_list_linkSingle($str,$uid,$cache=FALSE,$mergeArr=array(),$urlOnly=FALSE,$altPageId=0) 00054 * 401: function pi_openAtagHrefInJSwindow($str,$winName='',$winParams='width=670,height=500,status=0,menubar=0,scrollbars=1,resizable=1') 00055 * 00056 * SECTION: Functions for listing, browsing, searching etc. 00057 * 456: function pi_list_browseresults($showResultCount=1,$tableParams='',$wrapArr=array(), $pointerName = 'pointer', $hscText = TRUE) 00058 * 618: function pi_list_searchBox($tableParams='') 00059 * 649: function pi_list_modeSelector($items=array(),$tableParams='') 00060 * 687: function pi_list_makelist($res,$tableParams='') 00061 * 722: function pi_list_row($c) 00062 * 734: function pi_list_header() 00063 * 00064 * SECTION: Stylesheet, CSS 00065 * 765: function pi_getClassName($class) 00066 * 777: function pi_classParam($class) 00067 * 791: function pi_setClassStyle($class,$data,$selector='') 00068 * 802: function pi_wrapInBaseClass($str) 00069 * 00070 * SECTION: Frontend editing: Edit panel, edit icons 00071 * 858: function pi_getEditPanel($row='',$tablename='',$label='',$conf=Array()) 00072 * 900: function pi_getEditIcon($content,$fields,$title='',$row='',$tablename='',$oConf=array()) 00073 * 00074 * SECTION: Localization, locallang functions 00075 * 947: function pi_getLL($key,$alt='',$hsc=FALSE) 00076 * 970: function pi_loadLL() 00077 * 00078 * SECTION: Database, queries 00079 * 1048: function pi_list_query($table,$count=0,$addWhere='',$mm_cat='',$groupBy='',$orderBy='',$query='',$returnQueryArray=FALSE) 00080 * 1140: function pi_exec_query($table,$count=0,$addWhere='',$mm_cat='',$groupBy='',$orderBy='',$query='') 00081 * 1155: function pi_getRecord($table,$uid,$checkPage=0) 00082 * 1166: function pi_getPidList($pid_list,$recursive=0) 00083 * 1191: function pi_prependFieldsWithTable($table,$fieldList) 00084 * 1211: function pi_getCategoryTableContents($table,$pid,$whereClause='',$groupBy='',$orderBy='',$limit='') 00085 * 00086 * SECTION: Various 00087 * 1255: function pi_isOnlyFields($fList,$lowerThan=-1) 00088 * 1275: function pi_autoCache($inArray) 00089 * 1306: function pi_RTEcssText($str) 00090 * 00091 * SECTION: FlexForms related functions 00092 * 1328: function pi_initPIflexForm($field='pi_flexform') 00093 * 1346: function pi_getFFvalue($T3FlexForm_array,$fieldName,$sheet='sDEF',$lang='lDEF',$value='vDEF') 00094 * 1363: function pi_getFFvalueFromSheetArray($sheetArray,$fieldNameArr,$value) 00095 * 00096 * TOTAL FUNCTIONS: 35 00097 * (This index is automatically created/updated by the extension "extdeveval") 00098 * 00099 */ 00100 00101 00102 00103 00104 00105 00106 00107 00108 00109 00110 00111 /** 00112 * Base class for frontend plugins 00113 * Most modern frontend plugins are extension classes of this one. 00114 * This class contains functions which assists these plugins in creating lists, searching, displaying menus, page-browsing (next/previous/1/2/3) and handling links. 00115 * Functions are all prefixed "pi_" which is reserved for this class. Those functions can of course be overridden in the extension classes (that is the point...) 00116 * 00117 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00118 * @package TYPO3 00119 * @subpackage tslib 00120 */ 00121 class tslib_pibase { 00122 00123 // Reserved variables: 00124 /** 00125 * The backReference to the mother cObj object set at call time 00126 * 00127 * @var tslib_cObj 00128 */ 00129 var $cObj; 00130 var $prefixId; // Should be same as classname of the plugin, used for CSS classes, variables 00131 var $scriptRelPath; // Path to the plugin class script relative to extension directory, eg. 'pi1/class.tx_newfaq_pi1.php' 00132 var $extKey; // Extension key. 00133 var $piVars = Array ( // This is the incoming array by name $this->prefixId merged between POST and GET, POST taking precedence. Eg. if the class name is 'tx_myext' then the content of this array will be whatever comes into &tx_myext[...]=... 00134 'pointer' => '', // Used as a pointer for lists 00135 'mode' => '', // List mode 00136 'sword' => '', // Search word 00137 'sort' => '', // [Sorting column]:[ASC=0/DESC=1] 00138 ); 00139 var $internal = Array( // Used internally for general storage of values between methods 00140 'res_count' => 0, // Total query count 00141 'results_at_a_time' => 20, // pi_list_browseresults(): Show number of results at a time 00142 'maxPages' => 10, // pi_list_browseresults(): Max number of 'Page 1 - Page 2 - ...' in the list browser 00143 'currentRow' => Array(), // Current result row 00144 'currentTable' => '', // Current table 00145 ); 00146 00147 var $LOCAL_LANG = Array(); // Local Language content 00148 var $LOCAL_LANG_charset = Array(); // Local Language content charset for individual labels (overriding) 00149 var $LOCAL_LANG_loaded = 0; // Flag that tells if the locallang file has been fetch (or tried to be fetched) already. 00150 var $LLkey='default'; // Pointer to the language to use. 00151 var $altLLkey=''; // Pointer to alternative fall-back language to use. 00152 var $LLtestPrefix=''; // You can set this during development to some value that makes it easy for you to spot all labels that ARe delivered by the getLL function. 00153 var $LLtestPrefixAlt=''; // Save as LLtestPrefix, but additional prefix for the alternative value in getLL() function calls 00154 00155 var $pi_isOnlyFields = 'mode,pointer'; 00156 var $pi_alwaysPrev = 0; 00157 var $pi_lowerThan = 5; 00158 var $pi_moreParams=''; 00159 var $pi_listFields='*'; 00160 00161 var $pi_autoCacheFields=array(); 00162 var $pi_autoCacheEn=0; 00163 00164 var $pi_USER_INT_obj = FALSE; // If set, then links are 1) not using cHash and 2) not allowing pages to be cached. (Set this for all USER_INT plugins!) 00165 var $pi_checkCHash = FALSE; // If set, then caching is disabled if piVars are incoming while no cHash was set (Set this for all USER plugins!) 00166 00167 /** 00168 * Should normally be set in the main function with the TypoScript content passed to the method. 00169 * 00170 * $conf[LOCAL_LANG][_key_] is reserved for Local Language overrides. 00171 * $conf[userFunc] / $conf[includeLibs] reserved for setting up the USER / USER_INT object. See TSref 00172 */ 00173 var $conf = Array(); 00174 00175 // internal, don't mess with... 00176 var $pi_EPtemp_cObj; 00177 var $pi_tmpPageId=0; 00178 00179 00180 00181 00182 00183 00184 00185 00186 00187 00188 00189 00190 00191 00192 00193 00194 00195 /*************************** 00196 * 00197 * Init functions 00198 * 00199 **************************/ 00200 00201 /** 00202 * Class Constructor (true constructor) 00203 * Initializes $this->piVars if $this->prefixId is set to any value 00204 * Will also set $this->LLkey based on the config.language setting. 00205 * 00206 * @return void 00207 */ 00208 function tslib_pibase() { 00209 00210 // Setting piVars: 00211 if ($this->prefixId) { 00212 $this->piVars = t3lib_div::_GPmerged($this->prefixId); 00213 00214 // cHash mode check 00215 // IMPORTANT FOR CACHED PLUGINS (USER cObject): As soon as you generate cached plugin output which depends on parameters (eg. seeing the details of a news item) you MUST check if a cHash value is set. 00216 // Background: The function call will check if a cHash parameter was sent with the URL because only if it was the page may be cached. If no cHash was found the function will simply disable caching to avoid unpredictable caching behaviour. In any case your plugin can generate the expected output and the only risk is that the content may not be cached. A missing cHash value is considered a mistake in the URL resulting from either URL manipulation, "realurl" "grayzones" etc. The problem is rare (more frequent with "realurl") but when it occurs it is very puzzling! 00217 if ($this->pi_checkCHash && count($this->piVars)) { 00218 $GLOBALS['TSFE']->reqCHash(); 00219 } 00220 } 00221 if (!empty($GLOBALS['TSFE']->config['config']['language'])) { 00222 $this->LLkey = $GLOBALS['TSFE']->config['config']['language']; 00223 if (!empty($GLOBALS['TSFE']->config['config']['language_alt'])) { 00224 $this->altLLkey = $GLOBALS['TSFE']->config['config']['language_alt']; 00225 } 00226 } 00227 } 00228 00229 /** 00230 * If internal TypoScript property "_DEFAULT_PI_VARS." is set then it will merge the current $this->piVars array onto these default values. 00231 * 00232 * @return void 00233 */ 00234 function pi_setPiVarDefaults() { 00235 if (is_array($this->conf['_DEFAULT_PI_VARS.'])) { 00236 $this->piVars = t3lib_div::array_merge_recursive_overrule($this->conf['_DEFAULT_PI_VARS.'],is_array($this->piVars)?$this->piVars:array()); 00237 } 00238 } 00239 00240 00241 00242 00243 00244 00245 00246 00247 00248 00249 00250 00251 00252 /*************************** 00253 * 00254 * Link functions 00255 * 00256 **************************/ 00257 00258 /** 00259 * Get URL to some page. 00260 * Returns the URL to page $id with $target and an array of additional url-parameters, $urlParameters 00261 * Simple example: $this->pi_getPageLink(123) to get the URL for page-id 123. 00262 * 00263 * The function basically calls $this->cObj->getTypoLink_URL() 00264 * 00265 * @param integer Page id 00266 * @param string Target value to use. Affects the &type-value of the URL, defaults to current. 00267 * @param array Additional URL parameters to set (key/value pairs) 00268 * @return string The resulting URL 00269 * @see pi_linkToPage() 00270 */ 00271 function pi_getPageLink($id,$target='',$urlParameters=array()) { 00272 return $this->cObj->getTypoLink_URL($id,$urlParameters,$target); // ?$target:$GLOBALS['TSFE']->sPre 00273 } 00274 00275 /** 00276 * Link a string to some page. 00277 * Like pi_getPageLink() but takes a string as first parameter which will in turn be wrapped with the URL including target attribute 00278 * Simple example: $this->pi_linkToPage('My link', 123) to get something like <a href="index.php?id=123&type=1">My link</a> (or <a href="123.1.html">My link</a> if simulateStaticDocuments is set) 00279 * 00280 * @param string The content string to wrap in <a> tags 00281 * @param integer Page id 00282 * @param string Target value to use. Affects the &type-value of the URL, defaults to current. 00283 * @param array Additional URL parameters to set (key/value pairs) 00284 * @return string The input string wrapped in <a> tags with the URL and target set. 00285 * @see pi_getPageLink(), tslib_cObj::getTypoLink() 00286 */ 00287 function pi_linkToPage($str,$id,$target='',$urlParameters=array()) { 00288 return $this->cObj->getTypoLink($str,$id,$urlParameters,$target); // ?$target:$GLOBALS['TSFE']->sPre 00289 } 00290 00291 /** 00292 * Link string to the current page. 00293 * Returns the $str wrapped in <a>-tags with a link to the CURRENT page, but with $urlParameters set as extra parameters for the page. 00294 * 00295 * @param string The content string to wrap in <a> tags 00296 * @param array Array with URL parameters as key/value pairs. They will be "imploded" and added to the list of parameters defined in the plugins TypoScript property "parent.addParams" plus $this->pi_moreParams. 00297 * @param boolean If $cache is set (0/1), the page is asked to be cached by a &cHash value (unless the current plugin using this class is a USER_INT). Otherwise the no_cache-parameter will be a part of the link. 00298 * @param integer Alternative page ID for the link. (By default this function links to the SAME page!) 00299 * @return string The input string wrapped in <a> tags 00300 * @see pi_linkTP_keepPIvars(), tslib_cObj::typoLink() 00301 */ 00302 function pi_linkTP($str,$urlParameters=array(),$cache=0,$altPageId=0) { 00303 $conf=array(); 00304 $conf['useCacheHash'] = $this->pi_USER_INT_obj ? 0 : $cache; 00305 $conf['no_cache'] = $this->pi_USER_INT_obj ? 0 : !$cache; 00306 $conf['parameter'] = $altPageId ? $altPageId : ($this->pi_tmpPageId ? $this->pi_tmpPageId : $GLOBALS['TSFE']->id); 00307 $conf['additionalParams'] = $this->conf['parent.']['addParams'].t3lib_div::implodeArrayForUrl('', $urlParameters, '', true).$this->pi_moreParams; 00308 00309 return $this->cObj->typoLink($str, $conf); 00310 } 00311 00312 /** 00313 * Link a string to the current page while keeping currently set values in piVars. 00314 * Like pi_linkTP, but $urlParameters is by default set to $this->piVars with $overrulePIvars overlaid. 00315 * This means any current entries from this->piVars are passed on (except the key "DATA" which will be unset before!) and entries in $overrulePIvars will OVERRULE the current in the link. 00316 * 00317 * @param string The content string to wrap in <a> tags 00318 * @param array Array of values to override in the current piVars. Contrary to pi_linkTP the keys in this array must correspond to the real piVars array and therefore NOT be prefixed with the $this->prefixId string. Further, if a value is a blank string it means the piVar key will not be a part of the link (unset) 00319 * @param boolean If $cache is set, the page is asked to be cached by a &cHash value (unless the current plugin using this class is a USER_INT). Otherwise the no_cache-parameter will be a part of the link. 00320 * @param boolean If set, then the current values of piVars will NOT be preserved anyways... Practical if you want an easy way to set piVars without having to worry about the prefix, "tx_xxxxx[]" 00321 * @param integer Alternative page ID for the link. (By default this function links to the SAME page!) 00322 * @return string The input string wrapped in <a> tags 00323 * @see pi_linkTP() 00324 */ 00325 function pi_linkTP_keepPIvars($str,$overrulePIvars=array(),$cache=0,$clearAnyway=0,$altPageId=0) { 00326 if (is_array($this->piVars) && is_array($overrulePIvars) && !$clearAnyway) { 00327 $piVars = $this->piVars; 00328 unset($piVars['DATA']); 00329 $overrulePIvars = t3lib_div::array_merge_recursive_overrule($piVars,$overrulePIvars); 00330 if ($this->pi_autoCacheEn) { 00331 $cache = $this->pi_autoCache($overrulePIvars); 00332 } 00333 } 00334 $res = $this->pi_linkTP($str,Array($this->prefixId=>$overrulePIvars),$cache,$altPageId); 00335 return $res; 00336 } 00337 00338 /** 00339 * Get URL to the current page while keeping currently set values in piVars. 00340 * Same as pi_linkTP_keepPIvars but returns only the URL from the link. 00341 * 00342 * @param array See pi_linkTP_keepPIvars 00343 * @param boolean See pi_linkTP_keepPIvars 00344 * @param boolean See pi_linkTP_keepPIvars 00345 * @param integer See pi_linkTP_keepPIvars 00346 * @return string The URL ($this->cObj->lastTypoLinkUrl) 00347 * @see pi_linkTP_keepPIvars() 00348 */ 00349 function pi_linkTP_keepPIvars_url($overrulePIvars=array(),$cache=0,$clearAnyway=0,$altPageId=0) { 00350 $this->pi_linkTP_keepPIvars('|',$overrulePIvars,$cache,$clearAnyway,$altPageId); 00351 return $this->cObj->lastTypoLinkUrl; 00352 } 00353 00354 /** 00355 * Wraps the $str in a link to a single display of the record (using piVars[showUid]) 00356 * Uses pi_linkTP for the linking 00357 * 00358 * @param string The content string to wrap in <a> tags 00359 * @param integer UID of the record for which to display details (basically this will become the value of [showUid] 00360 * @param boolean See pi_linkTP_keepPIvars 00361 * @param array Array of values to override in the current piVars. Same as $overrulePIvars in pi_linkTP_keepPIvars 00362 * @param boolean If true, only the URL is returned, not a full link 00363 * @param integer Alternative page ID for the link. (By default this function links to the SAME page!) 00364 * @return string The input string wrapped in <a> tags 00365 * @see pi_linkTP(), pi_linkTP_keepPIvars() 00366 */ 00367 function pi_list_linkSingle($str,$uid,$cache=FALSE,$mergeArr=array(),$urlOnly=FALSE,$altPageId=0) { 00368 if ($this->prefixId) { 00369 if ($cache) { 00370 $overrulePIvars=$uid?array('showUid'=>$uid):Array(); 00371 $overrulePIvars=array_merge($overrulePIvars,(array)$mergeArr); 00372 $str = $this->pi_linkTP($str,Array($this->prefixId=>$overrulePIvars),$cache,$altPageId); 00373 } else { 00374 $overrulePIvars=array('showUid'=>$uid?$uid:''); 00375 $overrulePIvars=array_merge($overrulePIvars,(array)$mergeArr); 00376 $str = $this->pi_linkTP_keepPIvars($str,$overrulePIvars,$cache,0,$altPageId); 00377 } 00378 00379 // If urlOnly flag, return only URL as it has recently be generated. 00380 if ($urlOnly) { 00381 $str = $this->cObj->lastTypoLinkUrl; 00382 } 00383 } 00384 return $str; 00385 } 00386 00387 /** 00388 * Will change the href value from <a> in the input string and turn it into an onclick event that will open a new window with the URL 00389 * 00390 * @param string The string to process. This should be a string already wrapped/including a <a> tag which will be modified to contain an onclick handler. Only the attributes "href" and "onclick" will be left. 00391 * @param string Window name for the pop-up window 00392 * @param string Window parameters, see the default list for inspiration 00393 * @return string The processed input string, modified IF a <a> tag was found 00394 */ 00395 function pi_openAtagHrefInJSwindow($str,$winName='',$winParams='width=670,height=500,status=0,menubar=0,scrollbars=1,resizable=1') { 00396 if (preg_match('/(.*)(<a[^>]*>)(.*)/i',$str,$match)) { 00397 $aTagContent = t3lib_div::get_tag_attributes($match[2]); 00398 $match[2]='<a href="#" onclick="'. 00399 htmlspecialchars('vHWin=window.open(\''.$GLOBALS['TSFE']->baseUrlWrap($aTagContent['href']).'\',\''.($winName?$winName:md5($aTagContent['href'])).'\',\''.$winParams.'\');vHWin.focus();return false;'). 00400 '">'; 00401 $str=$match[1].$match[2].$match[3]; 00402 } 00403 return $str; 00404 } 00405 00406 00407 00408 00409 00410 00411 00412 00413 00414 00415 00416 00417 00418 00419 /*************************** 00420 * 00421 * Functions for listing, browsing, searching etc. 00422 * 00423 **************************/ 00424 00425 /** 00426 * Returns a results browser. This means a bar of page numbers plus a "previous" and "next" link. For each entry in the bar the piVars "pointer" will be pointing to the "result page" to show. 00427 * Using $this->piVars['pointer'] as pointer to the page to display. Can be overwritten with another string ($pointerName) to make it possible to have more than one pagebrowser on a page) 00428 * Using $this->internal['res_count'], $this->internal['results_at_a_time'] and $this->internal['maxPages'] for count number, how many results to show and the max number of pages to include in the browse bar. 00429 * Using $this->internal['dontLinkActivePage'] as switch if the active (current) page should be displayed as pure text or as a link to itself 00430 * Using $this->internal['showFirstLast'] as switch if the two links named "<< First" and "LAST >>" will be shown and point to the first or last page. 00431 * Using $this->internal['pagefloat']: this defines were the current page is shown in the list of pages in the Pagebrowser. If this var is an integer it will be interpreted as position in the list of pages. If its value is the keyword "center" the current page will be shown in the middle of the pagelist. 00432 * Using $this->internal['showRange']: this var switches the display of the pagelinks from pagenumbers to ranges f.e.: 1-5 6-10 11-15... instead of 1 2 3... 00433 * Using $this->pi_isOnlyFields: this holds a comma-separated list of fieldnames which - if they are among the GETvars - will not disable caching for the page with pagebrowser. 00434 * 00435 * The third parameter is an array with several wraps for the parts of the pagebrowser. The following elements will be recognized: 00436 * disabledLinkWrap, inactiveLinkWrap, activeLinkWrap, browseLinksWrap, showResultsWrap, showResultsNumbersWrap, browseBoxWrap. 00437 * 00438 * If $wrapArr['showResultsNumbersWrap'] is set, the formatting string is expected to hold template markers (###FROM###, ###TO###, ###OUT_OF###, ###FROM_TO###, ###CURRENT_PAGE###, ###TOTAL_PAGES###) 00439 * otherwise the formatting string is expected to hold sprintf-markers (%s) for from, to, outof (in that sequence) 00440 * 00441 * @param integer determines how the results of the pagerowser will be shown. See description below 00442 * @param string Attributes for the table tag which is wrapped around the table cells containing the browse links 00443 * @param array Array with elements to overwrite the default $wrapper-array. 00444 * @param string varname for the pointer. 00445 * @param boolean enable htmlspecialchars() for the pi_getLL function (set this to FALSE if you want f.e use images instead of text for links like 'previous' and 'next'). 00446 * @param boolean forces the output of the page browser if you set this option to "true" (otherwise it's only drawn if enough entries are available) 00447 * @return string Output HTML-Table, wrapped in <div>-tags with a class attribute (if $wrapArr is not passed, 00448 */ 00449 function pi_list_browseresults($showResultCount=1, $tableParams='', $wrapArr=array(), $pointerName='pointer', $hscText=TRUE, $forceOutput=FALSE) { 00450 00451 // example $wrapArr-array how it could be traversed from an extension 00452 /* $wrapArr = array( 00453 'browseBoxWrap' => '<div class="browseBoxWrap">|</div>', 00454 'showResultsWrap' => '<div class="showResultsWrap">|</div>', 00455 'browseLinksWrap' => '<div class="browseLinksWrap">|</div>', 00456 'showResultsNumbersWrap' => '<span class="showResultsNumbersWrap">|</span>', 00457 'disabledLinkWrap' => '<span class="disabledLinkWrap">|</span>', 00458 'inactiveLinkWrap' => '<span class="inactiveLinkWrap">|</span>', 00459 'activeLinkWrap' => '<span class="activeLinkWrap">|</span>' 00460 ); */ 00461 00462 // Initializing variables: 00463 $pointer = intval($this->piVars[$pointerName]); 00464 $count = intval($this->internal['res_count']); 00465 $results_at_a_time = t3lib_div::intInRange($this->internal['results_at_a_time'],1,1000); 00466 $totalPages = ceil($count/$results_at_a_time); 00467 $maxPages = t3lib_div::intInRange($this->internal['maxPages'],1,100); 00468 $pi_isOnlyFields = $this->pi_isOnlyFields($this->pi_isOnlyFields); 00469 00470 if (!$forceOutput && $count <= $results_at_a_time) { 00471 return ''; 00472 } 00473 00474 // $showResultCount determines how the results of the pagerowser will be shown. 00475 // If set to 0: only the result-browser will be shown 00476 // 1: (default) the text "Displaying results..." and the result-browser will be shown. 00477 // 2: only the text "Displaying results..." will be shown 00478 $showResultCount = intval($showResultCount); 00479 00480 // if this is set, two links named "<< First" and "LAST >>" will be shown and point to the very first or last page. 00481 $showFirstLast = $this->internal['showFirstLast']; 00482 00483 // if this has a value the "previous" button is always visible (will be forced if "showFirstLast" is set) 00484 $alwaysPrev = $showFirstLast?1:$this->pi_alwaysPrev; 00485 00486 if (isset($this->internal['pagefloat'])) { 00487 if (strtoupper($this->internal['pagefloat']) == 'CENTER') { 00488 $pagefloat = ceil(($maxPages - 1)/2); 00489 } else { 00490 // pagefloat set as integer. 0 = left, value >= $this->internal['maxPages'] = right 00491 $pagefloat = t3lib_div::intInRange($this->internal['pagefloat'],-1,$maxPages-1); 00492 } 00493 } else { 00494 $pagefloat = -1; // pagefloat disabled 00495 } 00496 00497 // default values for "traditional" wrapping with a table. Can be overwritten by vars from $wrapArr 00498 $wrapper['disabledLinkWrap'] = '<td nowrap="nowrap"><p>|</p></td>'; 00499 $wrapper['inactiveLinkWrap'] = '<td nowrap="nowrap"><p>|</p></td>'; 00500 $wrapper['activeLinkWrap'] = '<td'.$this->pi_classParam('browsebox-SCell').' nowrap="nowrap"><p>|</p></td>'; 00501 $wrapper['browseLinksWrap'] = trim('<table '.$tableParams).'><tr>|</tr></table>'; 00502 $wrapper['showResultsWrap'] = '<p>|</p>'; 00503 $wrapper['browseBoxWrap'] = ' 00504 <!-- 00505 List browsing box: 00506 --> 00507 <div '.$this->pi_classParam('browsebox').'> 00508 | 00509 </div>'; 00510 00511 // now overwrite all entries in $wrapper which are also in $wrapArr 00512 $wrapper = array_merge($wrapper,$wrapArr); 00513 00514 if ($showResultCount != 2) { //show pagebrowser 00515 if ($pagefloat > -1) { 00516 $lastPage = min($totalPages,max($pointer+1 + $pagefloat,$maxPages)); 00517 $firstPage = max(0,$lastPage-$maxPages); 00518 } else { 00519 $firstPage = 0; 00520 $lastPage = t3lib_div::intInRange($totalPages,1,$maxPages); 00521 } 00522 $links=array(); 00523 00524 // Make browse-table/links: 00525 if ($showFirstLast) { // Link to first page 00526 if ($pointer>0) { 00527 $links[]=$this->cObj->wrap($this->pi_linkTP_keepPIvars($this->pi_getLL('pi_list_browseresults_first','<< First',$hscText),array($pointerName => null),$pi_isOnlyFields),$wrapper['inactiveLinkWrap']); 00528 } else { 00529 $links[]=$this->cObj->wrap($this->pi_getLL('pi_list_browseresults_first','<< First',$hscText),$wrapper['disabledLinkWrap']); 00530 } 00531 } 00532 if ($alwaysPrev>=0) { // Link to previous page 00533 if ($pointer>0) { 00534 $links[]=$this->cObj->wrap($this->pi_linkTP_keepPIvars($this->pi_getLL('pi_list_browseresults_prev','< Previous',$hscText),array($pointerName => ($pointer-1?$pointer-1:'')),$pi_isOnlyFields),$wrapper['inactiveLinkWrap']); 00535 } elseif ($alwaysPrev) { 00536 $links[]=$this->cObj->wrap($this->pi_getLL('pi_list_browseresults_prev','< Previous',$hscText),$wrapper['disabledLinkWrap']); 00537 } 00538 } 00539 for($a=$firstPage;$a<$lastPage;$a++) { // Links to pages 00540 if ($this->internal['showRange']) { 00541 $pageText = (($a*$results_at_a_time)+1).'-'.min($count,(($a+1)*$results_at_a_time)); 00542 } else { 00543 $pageText = trim($this->pi_getLL('pi_list_browseresults_page','Page',$hscText).' '.($a+1)); 00544 } 00545 if ($pointer == $a) { // current page 00546 if ($this->internal['dontLinkActivePage']) { 00547 $links[] = $this->cObj->wrap($pageText,$wrapper['activeLinkWrap']); 00548 } else { 00549 $links[] = $this->cObj->wrap($this->pi_linkTP_keepPIvars($pageText,array($pointerName => ($a?$a:'')),$pi_isOnlyFields),$wrapper['activeLinkWrap']); 00550 } 00551 } else { 00552 $links[] = $this->cObj->wrap($this->pi_linkTP_keepPIvars($pageText,array($pointerName => ($a?$a:'')),$pi_isOnlyFields),$wrapper['inactiveLinkWrap']); 00553 } 00554 } 00555 if ($pointer<$totalPages-1 || $showFirstLast) { 00556 if ($pointer>=$totalPages-1) { // Link to next page 00557 $links[]=$this->cObj->wrap($this->pi_getLL('pi_list_browseresults_next','Next >',$hscText),$wrapper['disabledLinkWrap']); 00558 } else { 00559 $links[]=$this->cObj->wrap($this->pi_linkTP_keepPIvars($this->pi_getLL('pi_list_browseresults_next','Next >',$hscText),array($pointerName => $pointer+1),$pi_isOnlyFields),$wrapper['inactiveLinkWrap']); 00560 } 00561 } 00562 if ($showFirstLast) { // Link to last page 00563 if ($pointer<$totalPages-1) { 00564 $links[]=$this->cObj->wrap($this->pi_linkTP_keepPIvars($this->pi_getLL('pi_list_browseresults_last','Last >>',$hscText),array($pointerName => $totalPages-1),$pi_isOnlyFields),$wrapper['inactiveLinkWrap']); 00565 } else { 00566 $links[]=$this->cObj->wrap($this->pi_getLL('pi_list_browseresults_last','Last >>',$hscText),$wrapper['disabledLinkWrap']); 00567 } 00568 } 00569 $theLinks = $this->cObj->wrap(implode(LF,$links),$wrapper['browseLinksWrap']); 00570 } else { 00571 $theLinks = ''; 00572 } 00573 00574 $pR1 = $pointer*$results_at_a_time+1; 00575 $pR2 = $pointer*$results_at_a_time+$results_at_a_time; 00576 00577 if ($showResultCount) { 00578 if ($wrapper['showResultsNumbersWrap']) { 00579 // this will render the resultcount in a more flexible way using markers (new in TYPO3 3.8.0). 00580 // the formatting string is expected to hold template markers (see function header). Example: 'Displaying results ###FROM### to ###TO### out of ###OUT_OF###' 00581 00582 $markerArray['###FROM###'] = $this->cObj->wrap($this->internal['res_count'] > 0 ? $pR1 : 0,$wrapper['showResultsNumbersWrap']); 00583 $markerArray['###TO###'] = $this->cObj->wrap(min($this->internal['res_count'],$pR2),$wrapper['showResultsNumbersWrap']); 00584 $markerArray['###OUT_OF###'] = $this->cObj->wrap($this->internal['res_count'],$wrapper['showResultsNumbersWrap']); 00585 $markerArray['###FROM_TO###'] = $this->cObj->wrap(($this->internal['res_count'] > 0 ? $pR1 : 0).' '.$this->pi_getLL('pi_list_browseresults_to','to').' '.min($this->internal['res_count'],$pR2),$wrapper['showResultsNumbersWrap']); 00586 $markerArray['###CURRENT_PAGE###'] = $this->cObj->wrap($pointer+1,$wrapper['showResultsNumbersWrap']); 00587 $markerArray['###TOTAL_PAGES###'] = $this->cObj->wrap($totalPages,$wrapper['showResultsNumbersWrap']); 00588 // substitute markers 00589 $resultCountMsg = $this->cObj->substituteMarkerArray($this->pi_getLL('pi_list_browseresults_displays','Displaying results ###FROM### to ###TO### out of ###OUT_OF###'),$markerArray); 00590 } else { 00591 // render the resultcount in the "traditional" way using sprintf 00592 $resultCountMsg = sprintf( 00593 str_replace('###SPAN_BEGIN###','<span'.$this->pi_classParam('browsebox-strong').'>',$this->pi_getLL('pi_list_browseresults_displays','Displaying results ###SPAN_BEGIN###%s to %s</span> out of ###SPAN_BEGIN###%s</span>')), 00594 $count > 0 ? $pR1 : 0, 00595 min($count,$pR2), 00596 $count); 00597 } 00598 $resultCountMsg = $this->cObj->wrap($resultCountMsg,$wrapper['showResultsWrap']); 00599 } else { 00600 $resultCountMsg = ''; 00601 } 00602 00603 $sTables = $this->cObj->wrap($resultCountMsg.$theLinks,$wrapper['browseBoxWrap']); 00604 00605 return $sTables; 00606 } 00607 00608 /** 00609 * Returns a Search box, sending search words to piVars "sword" and setting the "no_cache" parameter as well in the form. 00610 * Submits the search request to the current REQUEST_URI 00611 * 00612 * @param string Attributes for the table tag which is wrapped around the table cells containing the search box 00613 * @return string Output HTML, wrapped in <div>-tags with a class attribute 00614 */ 00615 function pi_list_searchBox($tableParams='') { 00616 // Search box design: 00617 $sTables = ' 00618 00619 <!-- 00620 List search box: 00621 --> 00622 <div'.$this->pi_classParam('searchbox').'> 00623 <form action="'.htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI')).'" method="post" style="margin: 0 0 0 0;"> 00624 <'.trim('table '.$tableParams).'> 00625 <tr> 00626 <td><input type="text" name="'.$this->prefixId.'[sword]" value="'.htmlspecialchars($this->piVars['sword']).'"'.$this->pi_classParam('searchbox-sword').' /></td> 00627 <td><input type="submit" value="'.$this->pi_getLL('pi_list_searchBox_search','Search',TRUE).'"'.$this->pi_classParam('searchbox-button').' />'. 00628 '<input type="hidden" name="no_cache" value="1" />'. 00629 '<input type="hidden" name="'.$this->prefixId.'[pointer]" value="" />'. 00630 '</td> 00631 </tr> 00632 </table> 00633 </form> 00634 </div>'; 00635 00636 return $sTables; 00637 } 00638 00639 /** 00640 * Returns a mode selector; a little menu in a table normally put in the top of the page/list. 00641 * 00642 * @param array Key/Value pairs for the menu; keys are the piVars[mode] values and the "values" are the labels for them. 00643 * @param string Attributes for the table tag which is wrapped around the table cells containing the menu 00644 * @return string Output HTML, wrapped in <div>-tags with a class attribute 00645 */ 00646 function pi_list_modeSelector($items=array(),$tableParams='') { 00647 $cells=array(); 00648 foreach ($items as $k => $v) { 00649 $cells[]=' 00650 <td'.($this->piVars['mode']==$k?$this->pi_classParam('modeSelector-SCell'):'').'><p>'. 00651 $this->pi_linkTP_keepPIvars(htmlspecialchars($v),array('mode'=>$k),$this->pi_isOnlyFields($this->pi_isOnlyFields)). 00652 '</p></td>'; 00653 } 00654 00655 $sTables = ' 00656 00657 <!-- 00658 Mode selector (menu for list): 00659 --> 00660 <div'.$this->pi_classParam('modeSelector').'> 00661 <'.trim('table '.$tableParams).'> 00662 <tr> 00663 '.implode('',$cells).' 00664 </tr> 00665 </table> 00666 </div>'; 00667 00668 return $sTables; 00669 } 00670 00671 /** 00672 * Returns the list of items based on the input SQL result pointer 00673 * For each result row the internal var, $this->internal['currentRow'], is set with the row returned. 00674 * $this->pi_list_header() makes the header row for the list 00675 * $this->pi_list_row() is used for rendering each row 00676 * Notice that these two functions are typically ALWAYS defined in the extension class of the plugin since they are directly concerned with the specific layout for that plugins purpose. 00677 * 00678 * @param pointer Result pointer to a SQL result which can be traversed. 00679 * @param string Attributes for the table tag which is wrapped around the table rows containing the list 00680 * @return string Output HTML, wrapped in <div>-tags with a class attribute 00681 * @see pi_list_row(), pi_list_header() 00682 */ 00683 function pi_list_makelist($res,$tableParams='') { 00684 // Make list table header: 00685 $tRows=array(); 00686 $this->internal['currentRow']=''; 00687 $tRows[] = $this->pi_list_header(); 00688 00689 // Make list table rows 00690 $c=0; 00691 while($this->internal['currentRow'] = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00692 $tRows[] = $this->pi_list_row($c); 00693 $c++; 00694 } 00695 00696 $out = ' 00697 00698 <!-- 00699 Record list: 00700 --> 00701 <div'.$this->pi_classParam('listrow').'> 00702 <'.trim('table '.$tableParams).'> 00703 '.implode('',$tRows).' 00704 </table> 00705 </div>'; 00706 00707 return $out; 00708 } 00709 00710 /** 00711 * Returns a list row. Get data from $this->internal['currentRow']; 00712 * (Dummy) 00713 * Notice: This function should ALWAYS be defined in the extension class of the plugin since it is directly concerned with the specific layout of the listing for your plugins purpose. 00714 * 00715 * @param integer Row counting. Starts at 0 (zero). Used for alternating class values in the output rows. 00716 * @return string HTML output, a table row with a class attribute set (alternative based on odd/even rows) 00717 */ 00718 function pi_list_row($c) { 00719 // Dummy 00720 return '<tr'.($c%2 ? $this->pi_classParam('listrow-odd') : '').'><td><p>[dummy row]</p></td></tr>'; 00721 } 00722 00723 /** 00724 * Returns a list header row. 00725 * (Dummy) 00726 * Notice: This function should ALWAYS be defined in the extension class of the plugin since it is directly concerned with the specific layout of the listing for your plugins purpose. 00727 * 00728 * @return string HTML output, a table row with a class attribute set 00729 */ 00730 function pi_list_header() { 00731 return '<tr'.$this->pi_classParam('listrow-header').'><td><p>[dummy header row]</p></td></tr>'; 00732 } 00733 00734 00735 00736 00737 00738 00739 00740 00741 00742 00743 00744 00745 00746 00747 00748 /*************************** 00749 * 00750 * Stylesheet, CSS 00751 * 00752 **************************/ 00753 00754 00755 /** 00756 * Returns a class-name prefixed with $this->prefixId and with all underscores substituted to dashes (-) 00757 * 00758 * @param string The class name (or the END of it since it will be prefixed by $this->prefixId.'-') 00759 * @return string The combined class name (with the correct prefix) 00760 */ 00761 function pi_getClassName($class) { 00762 return str_replace('_','-',$this->prefixId).($this->prefixId?'-':'').$class; 00763 } 00764 00765 /** 00766 * Returns the class-attribute with the correctly prefixed classname 00767 * Using pi_getClassName() 00768 * 00769 * @param string The class name(s) (suffix) - separate multiple classes with commas 00770 * @param string Additional class names which should not be prefixed - separate multiple classes with commas 00771 * @return string A "class" attribute with value and a single space char before it. 00772 * @see pi_getClassName() 00773 */ 00774 function pi_classParam($class, $addClasses='') { 00775 $output = ''; 00776 foreach (t3lib_div::trimExplode(',',$class) as $v) { 00777 $output.= ' '.$this->pi_getClassName($v); 00778 } 00779 foreach (t3lib_div::trimExplode(',',$addClasses) as $v) { 00780 $output.= ' '.$v; 00781 } 00782 return ' class="'.trim($output).'"'; 00783 } 00784 00785 /** 00786 * Wraps the input string in a <div> tag with the class attribute set to the prefixId. 00787 * All content returned from your plugins should be returned through this function so all content from your plugin is encapsulated in a <div>-tag nicely identifying the content of your plugin. 00788 * 00789 * @param string HTML content to wrap in the div-tags with the "main class" of the plugin 00790 * @return string HTML content wrapped, ready to return to the parent object. 00791 */ 00792 function pi_wrapInBaseClass($str) { 00793 $content = '<div class="'.str_replace('_','-',$this->prefixId).'"> 00794 '.$str.' 00795 </div> 00796 '; 00797 00798 if(!$GLOBALS['TSFE']->config['config']['disablePrefixComment']) { 00799 $content = ' 00800 00801 00802 <!-- 00803 00804 BEGIN: Content of extension "'.$this->extKey.'", plugin "'.$this->prefixId.'" 00805 00806 --> 00807 '.$content.' 00808 <!-- END: Content of extension "'.$this->extKey.'", plugin "'.$this->prefixId.'" --> 00809 00810 '; 00811 } 00812 00813 return $content; 00814 } 00815 00816 00817 00818 00819 00820 00821 00822 00823 00824 00825 00826 00827 00828 00829 00830 00831 00832 /*************************** 00833 * 00834 * Frontend editing: Edit panel, edit icons 00835 * 00836 **************************/ 00837 00838 /** 00839 * Returns the Backend User edit panel for the $row from $tablename 00840 * 00841 * @param array Record array. 00842 * @param string Table name 00843 * @param string A label to show with the panel. 00844 * @param array TypoScript parameters to pass along to the EDITPANEL content Object that gets rendered. The property "allow" WILL get overridden/set though. 00845 * @return string Returns false/blank if no BE User login and of course if the panel is not shown for other reasons. Otherwise the HTML for the panel (a table). 00846 * @see tslib_cObj::EDITPANEL() 00847 */ 00848 function pi_getEditPanel($row='',$tablename='',$label='',$conf=Array()) { 00849 $panel=''; 00850 if (!$row || !$tablename) { 00851 $row = $this->internal['currentRow']; 00852 $tablename = $this->internal['currentTable']; 00853 } 00854 00855 if ($GLOBALS['TSFE']->beUserLogin) { 00856 // Create local cObj if not set: 00857 if (!is_object($this->pi_EPtemp_cObj)) { 00858 $this->pi_EPtemp_cObj = t3lib_div::makeInstance('tslib_cObj'); 00859 $this->pi_EPtemp_cObj->setParent($this->cObj->data,$this->cObj->currentRecord); 00860 } 00861 00862 // Initialize the cObj object with current row 00863 $this->pi_EPtemp_cObj->start($row,$tablename); 00864 00865 // Setting TypoScript values in the $conf array. See documentation in TSref for the EDITPANEL cObject. 00866 $conf['allow'] = 'edit,new,delete,move,hide'; 00867 $panel = $this->pi_EPtemp_cObj->cObjGetSingle('EDITPANEL',$conf,'editpanel'); 00868 } 00869 00870 if ($panel) { 00871 if ($label) { 00872 return '<!-- BEGIN: EDIT PANEL --><table border="0" cellpadding="0" cellspacing="0" width="100%"><tr><td valign="top">'.$label.'</td><td valign="top" align="right">'.$panel.'</td></tr></table><!-- END: EDIT PANEL -->'; 00873 } else return '<!-- BEGIN: EDIT PANEL -->'.$panel.'<!-- END: EDIT PANEL -->'; 00874 } else return $label; 00875 } 00876 00877 /** 00878 * Adds edit-icons to the input content. 00879 * tslib_cObj::editIcons used for rendering 00880 * 00881 * @param string HTML content to add icons to. The icons will be put right after the last content part in the string (that means before the ending series of HTML tags) 00882 * @param string The list of fields to edit when the icon is clicked. 00883 * @param string Title for the edit icon. 00884 * @param array Table record row 00885 * @param string Table name 00886 * @param array Conf array 00887 * @return string The processed content 00888 * @see tslib_cObj::editIcons() 00889 */ 00890 function pi_getEditIcon($content,$fields,$title='',$row='',$tablename='',$oConf=array()) { 00891 if ($GLOBALS['TSFE']->beUserLogin){ 00892 if (!$row || !$tablename) { 00893 $row = $this->internal['currentRow']; 00894 $tablename = $this->internal['currentTable']; 00895 } 00896 $conf=array_merge(array( 00897 'beforeLastTag'=>1, 00898 'iconTitle' => $title 00899 ),$oConf); 00900 $content=$this->cObj->editIcons($content,$tablename.':'.$fields,$conf,$tablename.':'.$row['uid'],$row,'&viewUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'))); 00901 } 00902 return $content; 00903 } 00904 00905 00906 00907 00908 00909 00910 00911 00912 00913 00914 00915 00916 00917 00918 00919 00920 00921 /*************************** 00922 * 00923 * Localization, locallang functions 00924 * 00925 **************************/ 00926 00927 00928 /** 00929 * Returns the localized label of the LOCAL_LANG key, $key 00930 * Notice that for debugging purposes prefixes for the output values can be set with the internal vars ->LLtestPrefixAlt and ->LLtestPrefix 00931 * 00932 * @param string The key from the LOCAL_LANG array for which to return the value. 00933 * @param string Alternative string to return IF no value is found set for the key, neither for the local language nor the default. 00934 * @param boolean If true, the output label is passed through htmlspecialchars() 00935 * @return string The value from LOCAL_LANG. 00936 */ 00937 function pi_getLL($key,$alt='',$hsc=FALSE) { 00938 // The "from" charset of csConv() is only set for strings from TypoScript via _LOCAL_LANG 00939 if (isset($this->LOCAL_LANG[$this->LLkey][$key])) { 00940 $word = $GLOBALS['TSFE']->csConv($this->LOCAL_LANG[$this->LLkey][$key], $this->LOCAL_LANG_charset[$this->LLkey][$key]); 00941 } elseif ($this->altLLkey && isset($this->LOCAL_LANG[$this->altLLkey][$key])) { 00942 $word = $GLOBALS['TSFE']->csConv($this->LOCAL_LANG[$this->altLLkey][$key], $this->LOCAL_LANG_charset[$this->altLLkey][$key]); 00943 } elseif (isset($this->LOCAL_LANG['default'][$key])) { 00944 $word = $this->LOCAL_LANG['default'][$key]; // No charset conversion because default is english and thereby ASCII 00945 } else { 00946 $word = $this->LLtestPrefixAlt.$alt; 00947 } 00948 00949 $output = $this->LLtestPrefix.$word; 00950 if ($hsc) $output = htmlspecialchars($output); 00951 00952 return $output; 00953 } 00954 00955 /** 00956 * Loads local-language values by looking for a "locallang.php" file in the plugin class directory ($this->scriptRelPath) and if found includes it. 00957 * Also locallang values set in the TypoScript property "_LOCAL_LANG" are merged onto the values found in the "locallang.php" file. 00958 * 00959 * @return void 00960 */ 00961 function pi_loadLL() { 00962 if (!$this->LOCAL_LANG_loaded && $this->scriptRelPath) { 00963 $basePath = 'EXT:' . $this->extKey . '/' . dirname($this->scriptRelPath) . '/locallang.xml'; 00964 00965 // Read the strings in the required charset (since TYPO3 4.2) 00966 $this->LOCAL_LANG = t3lib_div::readLLfile($basePath,$this->LLkey,$GLOBALS['TSFE']->renderCharset); 00967 if ($this->altLLkey) { 00968 $tempLOCAL_LANG = t3lib_div::readLLfile($basePath,$this->altLLkey); 00969 $this->LOCAL_LANG = array_merge(is_array($this->LOCAL_LANG) ? $this->LOCAL_LANG : array(),$tempLOCAL_LANG); 00970 } 00971 00972 // Overlaying labels from TypoScript (including fictitious language keys for non-system languages!): 00973 $confLL = $this->conf['_LOCAL_LANG.']; 00974 if (is_array($confLL)) { 00975 foreach ($confLL as $k => $lA) { 00976 if (is_array($lA)) { 00977 $k = substr($k,0,-1); 00978 foreach($lA as $llK => $llV) { 00979 if (!is_array($llV)) { 00980 $this->LOCAL_LANG[$k][$llK] = $llV; 00981 // For labels coming from the TypoScript (database) the charset is assumed to be "forceCharset" and if that is not set, assumed to be that of the individual system languages 00982 $this->LOCAL_LANG_charset[$k][$llK] = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] ? $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] : $GLOBALS['TSFE']->csConvObj->charSetArray[$k]; 00983 } 00984 } 00985 } 00986 } 00987 } 00988 } 00989 $this->LOCAL_LANG_loaded = 1; 00990 } 00991 00992 00993 00994 00995 00996 00997 00998 00999 01000 01001 01002 01003 01004 01005 01006 01007 01008 01009 01010 01011 01012 01013 01014 /*************************** 01015 * 01016 * Database, queries 01017 * 01018 **************************/ 01019 01020 /** 01021 * Makes a standard query for listing of records based on standard input vars from the 'browser' ($this->internal['results_at_a_time'] and $this->piVars['pointer']) and 'searchbox' ($this->piVars['sword'] and $this->internal['searchFieldList']) 01022 * Set $count to 1 if you wish to get a count(*) query for selecting the number of results. 01023 * Notice that the query will use $this->conf['pidList'] and $this->conf['recursive'] to generate a PID list within which to search for records. 01024 * 01025 * @param string See pi_exec_query() 01026 * @param boolean See pi_exec_query() 01027 * @param string See pi_exec_query() 01028 * @param mixed See pi_exec_query() 01029 * @param string See pi_exec_query() 01030 * @param string See pi_exec_query() 01031 * @param string See pi_exec_query() 01032 * @param boolean If set, the function will return the query not as a string but array with the various parts. 01033 * @return mixed The query build. 01034 * @access private 01035 * @deprecated since TYPO3 3.6, this function will be removed in TYPO3 4.5, use pi_exec_query() instead! 01036 * @todo Deprecated but still used in the Core! 01037 */ 01038 function pi_list_query($table,$count=0,$addWhere='',$mm_cat='',$groupBy='',$orderBy='',$query='',$returnQueryArray=FALSE) { 01039 t3lib_div::logDeprecatedFunction(); 01040 01041 // Begin Query: 01042 if (!$query) { 01043 // Fetches the list of PIDs to select from. 01044 // TypoScript property .pidList is a comma list of pids. If blank, current page id is used. 01045 // TypoScript property .recursive is a int+ which determines how many levels down from the pids in the pid-list subpages should be included in the select. 01046 $pidList = $this->pi_getPidList($this->conf['pidList'],$this->conf['recursive']); 01047 if (is_array($mm_cat)) { 01048 $query='FROM '.$table.','.$mm_cat['table'].','.$mm_cat['mmtable'].LF. 01049 ' WHERE '.$table.'.uid='.$mm_cat['mmtable'].'.uid_local AND '.$mm_cat['table'].'.uid='.$mm_cat['mmtable'].'.uid_foreign '.LF. 01050 (strcmp($mm_cat['catUidList'],'')?' AND '.$mm_cat['table'].'.uid IN ('.$mm_cat['catUidList'].')':'').LF. 01051 ' AND '.$table.'.pid IN ('.$pidList.')'.LF. 01052 $this->cObj->enableFields($table).LF; // This adds WHERE-clauses that ensures deleted, hidden, starttime/endtime/access records are NOT selected, if they should not! Almost ALWAYS add this to your queries! 01053 } else { 01054 $query='FROM '.$table.' WHERE pid IN ('.$pidList.')'.LF. 01055 $this->cObj->enableFields($table).LF; // This adds WHERE-clauses that ensures deleted, hidden, starttime/endtime/access records are NOT selected, if they should not! Almost ALWAYS add this to your queries! 01056 } 01057 } 01058 01059 // Split the "FROM ... WHERE" string so we get the WHERE part and TABLE names separated...: 01060 list($TABLENAMES, $WHERE) = preg_split('/WHERE/i', trim($query), 2); 01061 $TABLENAMES = trim(substr(trim($TABLENAMES),5)); 01062 $WHERE = trim($WHERE); 01063 01064 // Add '$addWhere' 01065 if ($addWhere) {$WHERE.=' '.$addWhere.LF;} 01066 01067 // Search word: 01068 if ($this->piVars['sword'] && $this->internal['searchFieldList']) { 01069 $WHERE.=$this->cObj->searchWhere($this->piVars['sword'],$this->internal['searchFieldList'],$table).LF; 01070 } 01071 01072 if ($count) { 01073 $queryParts = array( 01074 'SELECT' => 'count(*)', 01075 'FROM' => $TABLENAMES, 01076 'WHERE' => $WHERE, 01077 'GROUPBY' => '', 01078 'ORDERBY' => '', 01079 'LIMIT' => '' 01080 ); 01081 } else { 01082 // Order by data: 01083 if (!$orderBy && $this->internal['orderBy']) { 01084 if (t3lib_div::inList($this->internal['orderByList'],$this->internal['orderBy'])) { 01085 $orderBy = 'ORDER BY '.$table.'.'.$this->internal['orderBy'].($this->internal['descFlag']?' DESC':''); 01086 } 01087 } 01088 01089 // Limit data: 01090 $pointer = $this->piVars['pointer']; 01091 $pointer = intval($pointer); 01092 $results_at_a_time = t3lib_div::intInRange($this->internal['results_at_a_time'],1,1000); 01093 $LIMIT = ($pointer*$results_at_a_time).','.$results_at_a_time; 01094 01095 // Add 'SELECT' 01096 $queryParts = array( 01097 'SELECT' => $this->pi_prependFieldsWithTable($table,$this->pi_listFields), 01098 'FROM' => $TABLENAMES, 01099 'WHERE' => $WHERE, 01100 'GROUPBY' => $GLOBALS['TYPO3_DB']->stripGroupBy($groupBy), 01101 'ORDERBY' => $GLOBALS['TYPO3_DB']->stripOrderBy($orderBy), 01102 'LIMIT' => $LIMIT 01103 ); 01104 } 01105 01106 $query = $GLOBALS['TYPO3_DB']->SELECTquery ( 01107 $queryParts['SELECT'], 01108 $queryParts['FROM'], 01109 $queryParts['WHERE'], 01110 $queryParts['GROUPBY'], 01111 $queryParts['ORDERBY'], 01112 $queryParts['LIMIT'] 01113 ); 01114 return $returnQueryArray ? $queryParts : $query; 01115 } 01116 01117 /** 01118 * Executes a standard SELECT query for listing of records based on standard input vars from the 'browser' ($this->internal['results_at_a_time'] and $this->piVars['pointer']) and 'searchbox' ($this->piVars['sword'] and $this->internal['searchFieldList']) 01119 * Set $count to 1 if you wish to get a count(*) query for selecting the number of results. 01120 * Notice that the query will use $this->conf['pidList'] and $this->conf['recursive'] to generate a PID list within which to search for records. 01121 * 01122 * @param string The table name to make the query for. 01123 * @param boolean If set, you will get a "count(*)" query back instead of field selecting 01124 * @param string Additional WHERE clauses (should be starting with " AND ....") 01125 * @param mixed If an array, then it must contain the keys "table", "mmtable" and (optionally) "catUidList" defining a table to make a MM-relation to in the query (based on fields uid_local and uid_foreign). If not array, the query will be a plain query looking up data in only one table. 01126 * @param string If set, this is added as a " GROUP BY ...." part of the query. 01127 * @param string If set, this is added as a " ORDER BY ...." part of the query. The default is that an ORDER BY clause is made based on $this->internal['orderBy'] and $this->internal['descFlag'] where the orderBy field must be found in $this->internal['orderByList'] 01128 * @param string If set, this is taken as the first part of the query instead of what is created internally. Basically this should be a query starting with "FROM [table] WHERE ... AND ...". The $addWhere clauses and all the other stuff is still added. Only the tables and PID selecting clauses are bypassed. May be deprecated in the future! 01129 * @return pointer SQL result pointer 01130 */ 01131 function pi_exec_query($table, $count=0 ,$addWhere='' ,$mm_cat='' ,$groupBy='' ,$orderBy='', $query='') { 01132 // Begin Query: 01133 if (!$query) { 01134 // Fetches the list of PIDs to select from. 01135 // TypoScript property .pidList is a comma list of pids. If blank, current page id is used. 01136 // TypoScript property .recursive is a int+ which determines how many levels down from the pids in the pid-list subpages should be included in the select. 01137 $pidList = $this->pi_getPidList($this->conf['pidList'], $this->conf['recursive']); 01138 if (is_array($mm_cat)) { 01139 $query = 'FROM ' . $table . ',' . $mm_cat['table'] . ',' . $mm_cat['mmtable'] . LF . 01140 ' WHERE ' . $table . '.uid=' . $mm_cat['mmtable'] . '.uid_local AND ' . $mm_cat['table'] . '.uid=' . $mm_cat['mmtable'] . '.uid_foreign ' . LF . 01141 (strcmp($mm_cat['catUidList'],'') ? ' AND ' . $mm_cat['table'] . '.uid IN (' . $mm_cat['catUidList'] . ')' : '') . LF . 01142 ' AND ' . $table . '.pid IN (' . $pidList . ')' . LF . 01143 $this->cObj->enableFields($table) . LF; // This adds WHERE-clauses that ensures deleted, hidden, starttime/endtime/access records are NOT selected, if they should not! Almost ALWAYS add this to your queries! 01144 } else { 01145 $query='FROM ' . $table . ' WHERE pid IN (' . $pidList . ')' . LF . 01146 $this->cObj->enableFields($table) . LF; // This adds WHERE-clauses that ensures deleted, hidden, starttime/endtime/access records are NOT selected, if they should not! Almost ALWAYS add this to your queries! 01147 } 01148 } 01149 01150 // Split the "FROM ... WHERE" string so we get the WHERE part and TABLE names separated...: 01151 list($TABLENAMES, $WHERE) = preg_split('/WHERE/i', trim($query), 2); 01152 $TABLENAMES = trim(substr(trim($TABLENAMES), 5)); 01153 $WHERE = trim($WHERE); 01154 01155 // Add '$addWhere' 01156 if ($addWhere) { 01157 $WHERE .= ' ' . $addWhere . LF; 01158 } 01159 01160 // Search word: 01161 if ($this->piVars['sword'] && $this->internal['searchFieldList']) { 01162 $WHERE .= $this->cObj->searchWhere($this->piVars['sword'], $this->internal['searchFieldList'], $table) . LF; 01163 } 01164 01165 if ($count) { 01166 $queryParts = array( 01167 'SELECT' => 'count(*)', 01168 'FROM' => $TABLENAMES, 01169 'WHERE' => $WHERE, 01170 'GROUPBY' => '', 01171 'ORDERBY' => '', 01172 'LIMIT' => '' 01173 ); 01174 } else { 01175 // Order by data: 01176 if (!$orderBy && $this->internal['orderBy']) { 01177 if (t3lib_div::inList($this->internal['orderByList'], $this->internal['orderBy'])) { 01178 $orderBy = 'ORDER BY ' . $table . '.' . $this->internal['orderBy'] . ($this->internal['descFlag'] ? ' DESC' : ''); 01179 } 01180 } 01181 01182 // Limit data: 01183 $pointer = $this->piVars['pointer']; 01184 $pointer = intval($pointer); 01185 $results_at_a_time = t3lib_div::intInRange($this->internal['results_at_a_time'], 1, 1000); 01186 $LIMIT = ($pointer * $results_at_a_time) . ',' . $results_at_a_time; 01187 01188 // Add 'SELECT' 01189 $queryParts = array( 01190 'SELECT' => $this->pi_prependFieldsWithTable($table, $this->pi_listFields), 01191 'FROM' => $TABLENAMES, 01192 'WHERE' => $WHERE, 01193 'GROUPBY' => $GLOBALS['TYPO3_DB']->stripGroupBy($groupBy), 01194 'ORDERBY' => $GLOBALS['TYPO3_DB']->stripOrderBy($orderBy), 01195 'LIMIT' => $LIMIT 01196 ); 01197 } 01198 return $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryParts); 01199 } 01200 01201 /** 01202 * Returns the row $uid from $table 01203 * (Simply calling $GLOBALS['TSFE']->sys_page->checkRecord()) 01204 * 01205 * @param string The table name 01206 * @param integer The uid of the record from the table 01207 * @param boolean If $checkPage is set, it's required that the page on which the record resides is accessible 01208 * @return array If record is found, an array. Otherwise false. 01209 */ 01210 function pi_getRecord($table,$uid,$checkPage=0) { 01211 return $GLOBALS['TSFE']->sys_page->checkRecord($table,$uid,$checkPage); 01212 } 01213 01214 /** 01215 * Returns a commalist of page ids for a query (eg. 'WHERE pid IN (...)') 01216 * 01217 * @param string $pid_list is a comma list of page ids (if empty current page is used) 01218 * @param integer $recursive is an integer >=0 telling how deep to dig for pids under each entry in $pid_list 01219 * @return string List of PID values (comma separated) 01220 */ 01221 function pi_getPidList($pid_list, $recursive = 0) { 01222 if (!strcmp($pid_list, '')) { 01223 $pid_list = $GLOBALS['TSFE']->id; 01224 } 01225 01226 $recursive = t3lib_div::intInRange($recursive, 0); 01227 01228 $pid_list_arr = array_unique(t3lib_div::trimExplode(',', $pid_list, 1)); 01229 $pid_list = array(); 01230 01231 foreach($pid_list_arr as $val) { 01232 $val = t3lib_div::intInRange($val, 0); 01233 if ($val) { 01234 $_list = $this->cObj->getTreeList(-1 * $val, $recursive); 01235 if ($_list) { 01236 $pid_list[] = $_list; 01237 } 01238 } 01239 } 01240 01241 return implode(',', $pid_list); 01242 } 01243 01244 /** 01245 * Having a comma list of fields ($fieldList) this is prepended with the $table.'.' name 01246 * 01247 * @param string Table name to prepend 01248 * @param string List of fields where each element will be prepended with the table name given. 01249 * @return string List of fields processed. 01250 */ 01251 function pi_prependFieldsWithTable($table,$fieldList) { 01252 $list=t3lib_div::trimExplode(',',$fieldList,1); 01253 $return=array(); 01254 foreach ($list as $listItem) { 01255 $return[]=$table.'.'.$listItem; 01256 } 01257 return implode(',',$return); 01258 } 01259 01260 /** 01261 * Will select all records from the "category table", $table, and return them in an array. 01262 * 01263 * @param string The name of the category table to select from. 01264 * @param integer The page from where to select the category records. 01265 * @param string Optional additional WHERE clauses put in the end of the query. DO NOT PUT IN GROUP BY, ORDER BY or LIMIT! 01266 * @param string Optional GROUP BY field(s), if none, supply blank string. 01267 * @param string Optional ORDER BY field(s), if none, supply blank string. 01268 * @param string Optional LIMIT value ([begin,]max), if none, supply blank string. 01269 * @return array The array with the category records in. 01270 */ 01271 function pi_getCategoryTableContents($table,$pid,$whereClause='',$groupBy='',$orderBy='',$limit='') { 01272 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 01273 '*', 01274 $table, 01275 'pid='.intval($pid). 01276 $this->cObj->enableFields($table).' '. 01277 $whereClause, // whereClauseMightContainGroupOrderBy 01278 $groupBy, 01279 $orderBy, 01280 $limit 01281 ); 01282 $outArr = array(); 01283 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 01284 $outArr[$row['uid']] = $row; 01285 } 01286 $GLOBALS['TYPO3_DB']->sql_free_result($res); 01287 return $outArr; 01288 } 01289 01290 01291 01292 01293 01294 01295 01296 01297 01298 01299 01300 01301 /*************************** 01302 * 01303 * Various 01304 * 01305 **************************/ 01306 01307 /** 01308 * Returns true if the piVars array has ONLY those fields entered that is set in the $fList (commalist) AND if none of those fields value is greater than $lowerThan field if they are integers. 01309 * Notice that this function will only work as long as values are integers. 01310 * 01311 * @param string List of fields (keys from piVars) to evaluate on 01312 * @param integer Limit for the values. 01313 * @return boolean Returns true (1) if conditions are met. 01314 */ 01315 function pi_isOnlyFields($fList,$lowerThan=-1) { 01316 $lowerThan = $lowerThan==-1 ? $this->pi_lowerThan : $lowerThan; 01317 01318 $fList = t3lib_div::trimExplode(',',$fList,1); 01319 $tempPiVars = $this->piVars; 01320 foreach ($fList as $k) { 01321 if (!t3lib_div::testInt($tempPiVars[$k]) || $tempPiVars[$k]<$lowerThan) unset($tempPiVars[$k]); 01322 } 01323 if (!count($tempPiVars)) return 1; 01324 } 01325 01326 /** 01327 * Returns true if the array $inArray contains only values allowed to be cached based on the configuration in $this->pi_autoCacheFields 01328 * Used by ->pi_linkTP_keepPIvars 01329 * This is an advanced form of evaluation of whether a URL should be cached or not. 01330 * 01331 * @param array An array with piVars values to evaluate 01332 * @return boolean Returns true (1) if conditions are met. 01333 * @see pi_linkTP_keepPIvars() 01334 */ 01335 function pi_autoCache($inArray) { 01336 if (is_array($inArray)) { 01337 foreach ($inArray as $fN => $fV) { 01338 if (!strcmp($inArray[$fN],'')) { 01339 unset($inArray[$fN]); 01340 } elseif (is_array($this->pi_autoCacheFields[$fN])) { 01341 if (is_array($this->pi_autoCacheFields[$fN]['range']) 01342 && intval($inArray[$fN])>=intval($this->pi_autoCacheFields[$fN]['range'][0]) 01343 && intval($inArray[$fN])<=intval($this->pi_autoCacheFields[$fN]['range'][1])) { 01344 unset($inArray[$fN]); 01345 } 01346 if (is_array($this->pi_autoCacheFields[$fN]['list']) 01347 && in_array($inArray[$fN],$this->pi_autoCacheFields[$fN]['list'])) { 01348 unset($inArray[$fN]); 01349 } 01350 } 01351 } 01352 } 01353 if (!count($inArray)) return 1; 01354 } 01355 01356 /** 01357 * Will process the input string with the parseFunc function from tslib_cObj based on configuration set in "lib.parseFunc_RTE" in the current TypoScript template. 01358 * This is useful for rendering of content in RTE fields where the transformation mode is set to "ts_css" or so. 01359 * Notice that this requires the use of "css_styled_content" to work right. 01360 * 01361 * @param string The input text string to process 01362 * @return string The processed string 01363 * @see tslib_cObj::parseFunc() 01364 */ 01365 function pi_RTEcssText($str) { 01366 $parseFunc = $GLOBALS['TSFE']->tmpl->setup['lib.']['parseFunc_RTE.']; 01367 if (is_array($parseFunc)) $str = $this->cObj->parseFunc($str, $parseFunc); 01368 return $str; 01369 } 01370 01371 01372 01373 01374 01375 /******************************* 01376 * 01377 * FlexForms related functions 01378 * 01379 *******************************/ 01380 01381 /** 01382 * Converts $this->cObj->data['pi_flexform'] from XML string to flexForm array. 01383 * 01384 * @param string Field name to convert 01385 * @return void 01386 */ 01387 function pi_initPIflexForm($field='pi_flexform') { 01388 // Converting flexform data into array: 01389 if (!is_array($this->cObj->data[$field]) && $this->cObj->data[$field]) { 01390 $this->cObj->data[$field] = t3lib_div::xml2array($this->cObj->data[$field]); 01391 if (!is_array($this->cObj->data[$field])) $this->cObj->data[$field]=array(); 01392 } 01393 } 01394 01395 /** 01396 * Return value from somewhere inside a FlexForm structure 01397 * 01398 * @param array FlexForm data 01399 * @param string Field name to extract. Can be given like "test/el/2/test/el/field_templateObject" where each part will dig a level deeper in the FlexForm data. 01400 * @param string Sheet pointer, eg. "sDEF" 01401 * @param string Language pointer, eg. "lDEF" 01402 * @param string Value pointer, eg. "vDEF" 01403 * @return string The content. 01404 */ 01405 function pi_getFFvalue($T3FlexForm_array,$fieldName,$sheet='sDEF',$lang='lDEF',$value='vDEF') { 01406 $sheetArray = is_array($T3FlexForm_array) ? $T3FlexForm_array['data'][$sheet][$lang] : ''; 01407 if (is_array($sheetArray)) { 01408 return $this->pi_getFFvalueFromSheetArray($sheetArray,explode('/',$fieldName),$value); 01409 } 01410 } 01411 01412 /** 01413 * Returns part of $sheetArray pointed to by the keys in $fieldNameArray 01414 * 01415 * @param array Multidimensiona array, typically FlexForm contents 01416 * @param array Array where each value points to a key in the FlexForms content - the input array will have the value returned pointed to by these keys. All integer keys will not take their integer counterparts, but rather traverse the current position in the array an return element number X (whether this is right behavior is not settled yet...) 01417 * @param string Value for outermost key, typ. "vDEF" depending on language. 01418 * @return mixed The value, typ. string. 01419 * @access private 01420 * @see pi_getFFvalue() 01421 */ 01422 function pi_getFFvalueFromSheetArray($sheetArray,$fieldNameArr,$value) { 01423 01424 $tempArr=$sheetArray; 01425 foreach($fieldNameArr as $k => $v) { 01426 if (t3lib_div::testInt($v)) { 01427 if (is_array($tempArr)) { 01428 $c=0; 01429 foreach($tempArr as $values) { 01430 if ($c==$v) { 01431 #debug($values); 01432 $tempArr=$values; 01433 break; 01434 } 01435 $c++; 01436 } 01437 } 01438 } else { 01439 $tempArr = $tempArr[$v]; 01440 } 01441 } 01442 return $tempArr[$value]; 01443 } 01444 } 01445 01446 // NO extension of class - does not make sense here. 01447 01448 ?>
1.8.0