|
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 * Contains TYPO3 Core Form generator - AKA "TCEforms" 00029 * 00030 * $Id: class.t3lib_tceforms.php 10577 2011-02-23 09:04:29Z francois $ 00031 * Revised for TYPO3 3.6 August/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 * 196: class t3lib_TCEforms 00042 * 302: function t3lib_TCEforms() 00043 * 338: function initDefaultBEmode() 00044 * 00045 * SECTION: Rendering the forms, fields etc 00046 * 385: function getSoloField($table,$row,$theFieldToReturn) 00047 * 424: function getMainFields($table,$row,$depth=0) 00048 * 618: function getListedFields($table,$row,$list) 00049 * 660: function getPaletteFields($table,$row,$palette,$header='',$itemList='',$collapsedHeader='') 00050 * 737: function getSingleField($table,$field,$row,$altName='',$palette=0,$extra='',$pal=0) 00051 * 900: function getSingleField_SW($table,$field,$row,&$PA) 00052 * 00053 * SECTION: Rendering of each TCEform field type 00054 * 976: function getSingleField_typeInput($table,$field,$row,&$PA) 00055 * 1057: function getSingleField_typeText($table,$field,$row,&$PA) 00056 * 1178: function getSingleField_typeCheck($table,$field,$row,&$PA) 00057 * 1244: function getSingleField_typeRadio($table,$field,$row,&$PA) 00058 * 1279: function getSingleField_typeSelect($table,$field,$row,&$PA) 00059 * 1359: function getSingleField_typeSelect_single($table,$field,$row,&$PA,$config,$selItems,$nMV_label) 00060 * 1490: function getSingleField_typeSelect_checkbox($table,$field,$row,&$PA,$config,$selItems,$nMV_label) 00061 * 1609: function getSingleField_typeSelect_singlebox($table,$field,$row,&$PA,$config,$selItems,$nMV_label) 00062 * 1719: function getSingleField_typeSelect_multiple($table,$field,$row,&$PA,$config,$selItems,$nMV_label) 00063 * 1823: function getSingleField_typeGroup($table,$field,$row,&$PA) 00064 * 1992: function getSingleField_typeNone($table,$field,$row,&$PA) 00065 * 2008: function getSingleField_typeNone_render($config,$itemValue) 00066 * 2070: function getSingleField_typeFlex($table,$field,$row,&$PA) 00067 * 2205: function getSingleField_typeFlex_langMenu($languages,$elName,$selectedLanguage,$multi=1) 00068 * 2224: function getSingleField_typeFlex_sheetMenu($sArr,$elName,$sheetKey) 00069 * 2259: function getSingleField_typeFlex_draw($dataStruct,$editData,$cmdData,$table,$field,$row,&$PA,$formPrefix='',$level=0,$tRows=array()) 00070 * 2452: function getSingleField_typeUnknown($table,$field,$row,&$PA) 00071 * 2467: function getSingleField_typeUser($table,$field,$row,&$PA) 00072 * 00073 * SECTION: Field content processing 00074 * 2496: function formatValue ($config, $itemValue) 00075 * 00076 * SECTION: "Configuration" fetching/processing functions 00077 * 2588: function getRTypeNum($table,$row) 00078 * 2614: function rearrange($fields) 00079 * 2640: function getExcludeElements($table,$row,$typeNum) 00080 * 2688: function getFieldsToAdd($table,$row,$typeNum) 00081 * 2713: function mergeFieldsWithAddedFields($fields,$fieldsToAdd) 00082 * 2745: function setTSconfig($table,$row,$field='') 00083 * 2767: function getSpecConfForField($table,$row,$field) 00084 * 2788: function getSpecConfFromString($extraString, $defaultExtras) 00085 * 3007: function loadPaletteElements($table, $row, $palette, $itemList='') 00086 * 00087 * SECTION: Display of localized content etc. 00088 * 2816: function registerDefaultLanguageData($table,$rec) 00089 * 2848: function getLanguageOverlayRawValue($table, $row, $field, $fieldConf) 00090 * 2876: function renderDefaultLanguageContent($table,$field,$row,$item) 00091 * 2899: function renderDefaultLanguageDiff($table,$field,$row,$item) 00092 * 00093 * SECTION: Form element helper functions 00094 * 2955: function dbFileIcons($fName,$mode,$allowed,$itemArray,$selector='',$params=array(),$onFocus='') 00095 * 3108: function getClipboardElements($allowed,$mode) 00096 * 3157: function getClickMenu($str,$table,$uid='') 00097 * 3178: function renderWizards($itemKinds,$wizConf,$table,$row,$field,&$PA,$itemName,$specConf,$RTE=0) 00098 * 3382: function getIcon($icon) 00099 * 3409: function optionTagStyle($iconString) 00100 * 3425: function extractValuesOnlyFromValueLabelList($itemFormElValue) 00101 * 3447: function wrapOpenPalette($header,$table,$row,$palette,$retFunc=0) 00102 * 3471: function checkBoxParams($itemName,$thisValue,$c,$iCount,$addFunc='') 00103 * 3485: function elName($itemName) 00104 * 3496: function noTitle($str,$wrapParts=array()) 00105 * 3505: function blur() 00106 * 3514: function thisReturnUrl() 00107 * 3527: function getSingleHiddenField($table,$field,$row) 00108 * 3549: function formWidth($size=48,$textarea=0) 00109 * 3576: function formWidthText($size=48,$wrap='') 00110 * 3592: function formElStyle($type) 00111 * 3603: function formElClass($type) 00112 * 3614: function formElStyleClassValue($type, $class=FALSE) 00113 * 3638: function insertDefStyle($type) 00114 * 3657: function getDynTabMenu($parts, $idString) 00115 * 00116 * SECTION: Item-array manipulation functions (check/select/radio) 00117 * 3696: function initItemArray($fieldValue) 00118 * 3714: function addItems($items,$iArray) 00119 * 3736: function procItems($items,$iArray,$config,$table,$row,$field) 00120 * 3760: function addSelectOptionsToItemArray($items,$fieldValue,$TSconfig,$field) 00121 * 3980: function addSelectOptionsToItemArray_makeModuleData($value) 00122 * 4002: function foreignTable($items,$fieldValue,$TSconfig,$field,$pFFlag=0) 00123 * 00124 * SECTION: Template functions 00125 * 4083: function setNewBEDesign() 00126 * 4138: function intoTemplate($inArr,$altTemplate='') 00127 * 4162: function addUserTemplateMarkers($marker,$table,$field,$row,&$PA) 00128 * 4173: function wrapLabels($str) 00129 * 4186: function wrapTotal($c,$rec,$table) 00130 * 4199: function replaceTableWrap($arr,$rec,$table) 00131 * 4236: function wrapBorder(&$out_array,&$out_pointer) 00132 * 4258: function rplColorScheme($inTemplate) 00133 * 4278: function getDivider() 00134 * 4288: function printPalette($palArr) 00135 * 4339: function helpTextIcon($table,$field,$force=0) 00136 * 4359: function helpText($table,$field) 00137 * 4380: function setColorScheme($scheme) 00138 * 4404: function resetSchemes() 00139 * 4415: function storeSchemes() 00140 * 4427: function restoreSchemes() 00141 * 00142 * SECTION: JavaScript related functions 00143 * 4457: function JStop() 00144 * 4508: function JSbottom($formname='forms[0]') 00145 * 4835: function dbFileCon($formObj='document.forms[0]') 00146 * 5053: function printNeededJSFunctions() 00147 * 5080: function printNeededJSFunctions_top() 00148 * 00149 * SECTION: Various helper functions 00150 * 5128: function getDefaultRecord($table,$pid=0) 00151 * 5167: function getRecordPath($table,$rec) 00152 * 5181: function readPerms() 00153 * 5195: function sL($str) 00154 * 5208: function getLL($str) 00155 * 5229: function isPalettesCollapsed($table,$palette) 00156 * 5245: function isDisplayCondition($displayCond,$row,$ffValueKey='') 00157 * 5349: function getTSCpid($table,$uid,$pid) 00158 * 5363: function doLoadTableDescr($table) 00159 * 5375: function getAvailableLanguages($onlyIsoCoded=1,$setDefault=1) 00160 * 00161 * 00162 * 5417: class t3lib_TCEforms_FE extends t3lib_TCEforms 00163 * 5425: function wrapLabels($str) 00164 * 5435: function printPalette($palArr) 00165 * 5460: function setFancyDesign() 00166 * 00167 * TOTAL FUNCTIONS: 100 00168 * (This index is automatically created/updated by the extension "extdeveval") 00169 * 00170 */ 00171 00172 00173 /** 00174 * 'TCEforms' - Class for creating the backend editing forms. 00175 * 00176 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00177 * @coauthor René Fritz <r.fritz@colorcube.de> 00178 * @package TYPO3 00179 * @subpackage t3lib 00180 */ 00181 class t3lib_TCEforms { 00182 00183 // variables not commented yet.... (do so...) 00184 var $palFieldArr = array(); 00185 var $disableWizards = 0; 00186 var $isPalettedoc = 0; 00187 var $paletteMargin = 1; 00188 var $defStyle = ''; // 'font-family:Verdana;font-size:10px;'; 00189 var $cachedTSconfig = array(); 00190 var $cachedTSconfig_fieldLevel = array(); 00191 var $cachedLanguageFlag = array(); 00192 var $cachedAdditionalPreviewLanguages = NULL; 00193 var $transformedRow = array(); 00194 var $extJSCODE = ''; 00195 var $printNeededJS = array(); 00196 var $hiddenFieldAccum = array(); 00197 var $TBE_EDITOR_fieldChanged_func = ''; 00198 var $loadMD5_JS = 1; 00199 var $prevBorderStyle = '[nothing here...]'; // Something unique... 00200 var $allowUpload = 0; // If set direct upload fields will be shown 00201 var $titleLen = 15; // @deprecated since TYPO3 4.1: $BE_USER->uc['titleLen'] but what is default?? 00202 var $defaultLanguageData = array(); // Array where records in the default language is stored. (processed by transferdata) 00203 var $defaultLanguageData_diff = array(); // Array where records in the default language is stored (raw without any processing. used for making diff) 00204 var $additionalPreviewLanguageData = array(); 00205 00206 00207 // EXTERNAL, static 00208 var $backPath = ''; // Set this to the 'backPath' pointing back to the typo3 admin directory from the script where this form is displayed. 00209 var $returnUrl = ''; // Alternative return URL path (default is t3lib_div::linkThisScript()) 00210 var $doSaveFieldName = ''; // Can be set to point to a field name in the form which will be set to '1' when the form is submitted with a *save* button. This way the recipient script can determine that the form was submitted for save and not "close" for example. 00211 var $palettesCollapsed = 0; // Can be set true/false to whether palettes (secondary options) are in the topframe or in form. True means they are NOT IN-form. So a collapsed palette is one, which is shown in the top frame, not in the page. 00212 var $disableRTE = 0; // If set, the RTE is disabled (from form display, eg. by checkbox in the bottom of the page!) 00213 var $globalShowHelp = 1; // If false, then all CSH will be disabled, regardless of settings in $this->edit_showFieldHelp 00214 var $localizationMode = ''; // If true, the forms are rendering only localization relevant fields of the records. 00215 var $fieldOrder = ''; // Overrule the field order set in TCA[types][showitem], eg for tt_content this value, 'bodytext,image', would make first the 'bodytext' field, then the 'image' field (if set for display)... and then the rest in the old order. 00216 var $doPrintPalette = 1; // If set to false, palettes will NEVER be rendered. 00217 00218 /** 00219 * Set to initialized clipboard object; Then the element browser will offer a link to paste in records from clipboard. 00220 * 00221 * @var t3lib_clipboard 00222 */ 00223 var $clipObj = FALSE; 00224 var $enableClickMenu = FALSE; // Enable click menu on reference icons. 00225 var $enableTabMenu = FALSE; // Enable Tab Menus. 00226 var $renderReadonly = FALSE; // When enabled all fields are rendered non-editable. 00227 00228 var $form_rowsToStylewidth = 9.58; // Form field width compensation: Factor from NN4 form field widths to style-aware browsers (like NN6+ and MSIE, with the $CLIENT[FORMSTYLE] value set) 00229 var $form_largeComp = 1.33; // Form field width compensation: Compensation for large documents, doc-tab (editing) 00230 var $charsPerRow = 40; // The number of chars expected per row when the height of a text area field is automatically calculated based on the number of characters found in the field content. 00231 var $maxTextareaWidth = 48; // The maximum abstract value for textareas 00232 var $maxInputWidth = 48; // The maximum abstract value for input fields 00233 var $defaultMultipleSelectorStyle = 'width:250px;'; // Default style for the selector boxes used for multiple items in "select" and "group" types. 00234 00235 00236 // INTERNAL, static 00237 var $prependFormFieldNames = 'data'; // The string to prepend formfield names with. 00238 var $prependCmdFieldNames = 'cmd'; // The string to prepend commands for tcemain::process_cmdmap with. 00239 var $prependFormFieldNames_file = 'data_files'; // The string to prepend FILE form field names with. 00240 var $formName = 'editform'; // The name attribute of the form. 00241 var $allowOverrideMatrix = array(); // Whitelist that allows TCA field configuration to be overridden by TSconfig, @see overrideFieldConf() 00242 00243 00244 // INTERNAL, dynamic 00245 var $perms_clause = ''; // Set by readPerms() (caching) 00246 var $perms_clause_set = 0; // Set by readPerms() (caching-flag) 00247 var $edit_showFieldHelp = ''; // Used to indicate the mode of CSH (Context Sensitive Help), whether it should be icons-only ('icon'), full description ('text') or not at all (blank). 00248 var $docLarge = 0; // If set, the forms will be rendered a little wider, more precisely with a factor of $this->form_largeComp. 00249 var $clientInfo = array(); // Loaded with info about the browser when class is instantiated. 00250 var $RTEenabled = 0; // True, if RTE is possible for the current user (based on result from BE_USER->isRTE()) 00251 var $RTEenabled_notReasons = ''; // If $this->RTEenabled was false, you can find the reasons listed in this array which is filled with reasons why the RTE could not be loaded) 00252 var $RTEcounter = 0; // Counter that is incremented before an RTE is created. Can be used for unique ids etc. 00253 00254 var $colorScheme; // Contains current color scheme 00255 var $classScheme; // Contains current class scheme 00256 var $defColorScheme; // Contains the default color scheme 00257 var $defClassScheme; // Contains the default class scheme 00258 var $fieldStyle; // Contains field style values 00259 var $borderStyle; // Contains border style values. 00260 00261 var $commentMessages = array(); // An accumulation of messages from the class. 00262 00263 // INTERNAL, templates 00264 var $totalWrap = '<hr />|<hr />'; // Total wrapping for the table rows. 00265 var $fieldTemplate = '<strong>###FIELD_NAME###</strong><br />###FIELD_ITEM###<hr />'; // Field template 00266 var $sectionWrap = ''; // Wrapping template code for a section 00267 var $palFieldTemplateHeader = ''; // Template for palette headers 00268 var $palFieldTemplate = ''; // Template for palettes 00269 00270 // INTERNAL, working memory 00271 var $excludeElements = ''; // Set to the fields NOT to display, if any. 00272 var $palettesRendered = array(); // During rendering of forms this will keep track of which palettes has already been rendered (so they are not rendered twice by mistake) 00273 var $hiddenFieldListArr = array(); // This array of fields will be set as hidden-fields instead of rendered normally! For instance palette fields edited in the top frame are set as hidden fields since the main form has to submit the values. The top frame actually just sets the value in the main form! 00274 var $requiredFields = array(); // Used to register input-field names, which are required. (Done during rendering of the fields). This information is then used later when the JavaScript is made. 00275 var $requiredAdditional = array(); // Used to register input-field names, which are required an have additional requirements (e.g. like a date/time must be positive integer). The information of this array is merged with $this->requiredFields later. 00276 var $requiredElements = array(); // Used to register the min and max number of elements for selectorboxes where that apply (in the "group" type for instance) 00277 var $requiredNested = array(); // Used to determine where $requiredFields or $requiredElements are nested (in Tabs or IRRE) 00278 var $renderDepth = 0; // Keeps track of the rendering depth of nested records. 00279 var $savedSchemes = array(); // Color scheme buffer. 00280 var $dynNestedStack = array(); // holds the path an element is nested in (e.g. required for RTEhtmlarea) 00281 00282 // Internal, registers for user defined functions etc. 00283 var $additionalCode_pre = array(); // Additional HTML code, printed before the form. 00284 var $additionalJS_pre = array(); // Additional JavaScript, printed before the form 00285 var $additionalJS_post = array(); // Additional JavaScript printed after the form 00286 var $additionalJS_submit = array(); // Additional JavaScript executed on submit; If you set "OK" variable it will raise an error about RTEs not being loaded and offer to block further submission. 00287 var $additionalJS_delete = array(); // Additional JavaScript executed when section element is deleted. This is neceessary, for example, to correctly clean up HTMLArea RTE (bug #8232) 00288 00289 /** 00290 * Instance of t3lib_tceforms_inline 00291 * 00292 * @var t3lib_TCEforms_inline 00293 */ 00294 var $inline; 00295 var $hookObjectsMainFields = array(); // Array containing hook class instances called once for a form 00296 var $hookObjectsSingleField = array(); // Array containing hook class instances called for each field 00297 var $extraFormHeaders = array(); // Rows gettings inserted into the alt_doc headers (when called from alt_doc.php) 00298 00299 public $templateFile = ''; // Form templates, relative to typo3 directory 00300 00301 00302 /** 00303 * Constructor function, setting internal variables, loading the styles used. 00304 * 00305 * @return void 00306 */ 00307 function t3lib_TCEforms() { 00308 global $CLIENT, $TYPO3_CONF_VARS; 00309 00310 $this->clientInfo = t3lib_div::clientInfo(); 00311 00312 $this->RTEenabled = $GLOBALS['BE_USER']->isRTE(); 00313 if (!$this->RTEenabled) { 00314 $this->RTEenabled_notReasons = implode(LF, $GLOBALS['BE_USER']->RTE_errors); 00315 $this->commentMessages[] = 'RTE NOT ENABLED IN SYSTEM due to:' . LF . $this->RTEenabled_notReasons; 00316 } 00317 00318 // Default color+class scheme 00319 $this->defColorScheme = array( 00320 $GLOBALS['SOBE']->doc->bgColor, // Background for the field AND palette 00321 t3lib_div::modifyHTMLColorAll($GLOBALS['SOBE']->doc->bgColor, -20), // Background for the field header 00322 t3lib_div::modifyHTMLColorAll($GLOBALS['SOBE']->doc->bgColor, -10), // Background for the palette field header 00323 'black', // Field header font color 00324 '#666666' // Palette field header font color 00325 ); 00326 $this->defColorScheme = array(); 00327 00328 // Override / Setting defaults from TBE_STYLES array 00329 $this->resetSchemes(); 00330 00331 // Setting the current colorScheme to default. 00332 $this->defColorScheme = $this->colorScheme; 00333 $this->defClassScheme = $this->classScheme; 00334 00335 // Define whitelist that allows TCA field configuration to be overridden by TSconfig, @see overrideFieldConf(): 00336 $this->allowOverrideMatrix = array( 00337 'input' => array('size', 'max'), 00338 'text' => array('cols', 'rows', 'wrap'), 00339 'check' => array('cols', 'showIfRTE'), 00340 'select' => array('size', 'autoSizeMax', 'maxitems', 'minitems'), 00341 'group' => array('size', 'autoSizeMax', 'max_size', 'show_thumbs', 'maxitems', 'minitems', 'disable_controls'), 00342 'inline' => array('appearance', 'behaviour', 'foreign_label', 'foreign_selector', 'foreign_unique', 'maxitems', 'minitems', 'size', 'autoSizeMax', 'symmetric_label'), 00343 ); 00344 00345 // Create instance of t3lib_TCEforms_inline only if this a non-IRRE-AJAX call: 00346 if (!isset($GLOBALS['ajaxID']) || strpos($GLOBALS['ajaxID'], 't3lib_TCEforms_inline::') !== 0) { 00347 $this->inline = t3lib_div::makeInstance('t3lib_TCEforms_inline'); 00348 } 00349 // Create instance of t3lib_TCEforms_suggest only if this a non-Suggest-AJAX call: 00350 if (!isset($GLOBALS['ajaxID']) || strpos($GLOBALS['ajaxID'], 't3lib_TCEforms_suggest::') !== 0) { 00351 $this->suggest = t3lib_div::makeInstance('t3lib_TCEforms_suggest'); 00352 } 00353 00354 // Prepare user defined objects (if any) for hooks which extend this function: 00355 $this->hookObjectsMainFields = array(); 00356 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['getMainFieldsClass'])) { 00357 foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['getMainFieldsClass'] as $classRef) { 00358 $this->hookObjectsMainFields[] = t3lib_div::getUserObj($classRef); 00359 } 00360 } 00361 $this->hookObjectsSingleField = array(); 00362 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['getSingleFieldClass'])) { 00363 foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['getSingleFieldClass'] as $classRef) { 00364 $this->hookObjectsSingleField[] = t3lib_div::getUserObj($classRef); 00365 } 00366 } 00367 00368 $this->templateFile = 'templates/tceforms.html'; 00369 00370 } 00371 00372 /** 00373 * Initialize various internal variables. 00374 * 00375 * @return void 00376 */ 00377 function initDefaultBEmode() { 00378 global $BE_USER; 00379 $this->prependFormFieldNames = 'data'; 00380 $this->formName = 'editform'; 00381 $this->setNewBEDesign(); 00382 $this->docLarge = $BE_USER->uc['edit_wideDocument'] ? 1 : 0; 00383 $this->edit_showFieldHelp = $BE_USER->uc['edit_showFieldHelp']; 00384 00385 $this->edit_docModuleUpload = $BE_USER->uc['edit_docModuleUpload']; 00386 $this->titleLen = $BE_USER->uc['titleLen']; // @deprecated since TYPO3 4.1 00387 00388 $this->inline->init($this); 00389 $this->suggest->init($this); 00390 } 00391 00392 00393 /******************************************************* 00394 * 00395 * Rendering the forms, fields etc 00396 * 00397 *******************************************************/ 00398 00399 /** 00400 * Will return the TCEform element for just a single field from a record. 00401 * The field must be listed in the currently displayed fields (as found in [types][showitem]) for the record. 00402 * This also means that the $table/$row supplied must be complete so the list of fields to show can be found correctly 00403 * 00404 * @param string The table name 00405 * @param array The record from the table for which to render a field. 00406 * @param string The field name to return the TCEform element for. 00407 * @return string HTML output 00408 * @see getMainFields() 00409 */ 00410 function getSoloField($table, $row, $theFieldToReturn) { 00411 global $TCA; 00412 00413 if ($TCA[$table]) { 00414 t3lib_div::loadTCA($table); 00415 $typeNum = $this->getRTypeNum($table, $row); 00416 if ($TCA[$table]['types'][$typeNum]) { 00417 $itemList = $TCA[$table]['types'][$typeNum]['showitem']; 00418 if ($itemList) { 00419 $fields = t3lib_div::trimExplode(',', $itemList, 1); 00420 $excludeElements = $this->excludeElements = $this->getExcludeElements($table, $row, $typeNum); 00421 00422 foreach ($fields as $fieldInfo) { 00423 $parts = explode(';', $fieldInfo); 00424 00425 $theField = trim($parts[0]); 00426 if (!in_array($theField, $excludeElements) && !strcmp($theField, $theFieldToReturn)) { 00427 if ($TCA[$table]['columns'][$theField]) { 00428 $sField = $this->getSingleField($table, $theField, $row, $parts[1], 1, $parts[3], $parts[2]); 00429 return $sField['ITEM']; 00430 } 00431 } 00432 } 00433 } 00434 } 00435 } 00436 } 00437 00438 /** 00439 * Based on the $table and $row of content, this displays the complete TCEform for the record. 00440 * The input-$row is required to be preprocessed if necessary by eg. the t3lib_transferdata class. For instance the RTE content should be transformed through this class first. 00441 * 00442 * @param string The table name 00443 * @param array The record from the table for which to render a field. 00444 * @param integer Depth level 00445 * @return string HTML output 00446 * @see getSoloField() 00447 */ 00448 function getMainFields($table, $row, $depth = 0) { 00449 global $TCA, $TYPO3_CONF_VARS; 00450 00451 $this->renderDepth = $depth; 00452 00453 // Init vars: 00454 $out_array = array(array()); 00455 $out_array_meta = array(array( 00456 'title' => $this->getLL('l_generalTab') 00457 )); 00458 00459 $out_pointer = 0; 00460 $out_sheet = 0; 00461 $this->palettesRendered = array(); 00462 $this->palettesRendered[$this->renderDepth][$table] = array(); 00463 00464 // Hook: getMainFields_preProcess (requested by Thomas Hempel for use with the "dynaflex" extension) 00465 foreach ($this->hookObjectsMainFields as $hookObj) { 00466 if (method_exists($hookObj, 'getMainFields_preProcess')) { 00467 $hookObj->getMainFields_preProcess($table, $row, $this); 00468 } 00469 } 00470 00471 if ($TCA[$table]) { 00472 00473 // Load the full TCA for the table. 00474 t3lib_div::loadTCA($table); 00475 00476 // Get dividers2tabs setting from TCA of the current table: 00477 $dividers2tabs =& $TCA[$table]['ctrl']['dividers2tabs']; 00478 00479 // Load the description content for the table. 00480 if ($this->edit_showFieldHelp || $this->doLoadTableDescr($table)) { 00481 $GLOBALS['LANG']->loadSingleTableDescription($table); 00482 } 00483 // Get the current "type" value for the record. 00484 $typeNum = $this->getRTypeNum($table, $row); 00485 00486 // Find the list of fields to display: 00487 if ($TCA[$table]['types'][$typeNum]) { 00488 $itemList = $TCA[$table]['types'][$typeNum]['showitem']; 00489 if ($itemList) { // If such a list existed... 00490 // Explode the field list and possibly rearrange the order of the fields, if configured for 00491 $fields = t3lib_div::trimExplode(',', $itemList, 1); 00492 if ($this->fieldOrder) { 00493 $fields = $this->rearrange($fields); 00494 } 00495 00496 // Get excluded fields, added fiels and put it together: 00497 $excludeElements = $this->excludeElements = $this->getExcludeElements($table, $row, $typeNum); 00498 $fields = $this->mergeFieldsWithAddedFields($fields, $this->getFieldsToAdd($table, $row, $typeNum)); 00499 00500 // If TCEforms will render a tab menu in the next step, push the name to the tab stack: 00501 $tabIdentString = ''; 00502 $tabIdentStringMD5 = ''; 00503 if (strstr($itemList, '--div--') !== false && $this->enableTabMenu && $dividers2tabs) { 00504 $tabIdentString = 'TCEforms:' . $table . ':' . $row['uid']; 00505 $tabIdentStringMD5 = $GLOBALS['TBE_TEMPLATE']->getDynTabMenuId($tabIdentString); 00506 // Remember that were currently working on the general tab: 00507 if (isset($fields[0]) && strpos($fields[0], '--div--') !== 0) { 00508 $this->pushToDynNestedStack('tab', $tabIdentStringMD5 . '-1'); 00509 } 00510 } 00511 00512 // Traverse the fields to render: 00513 $cc = 0; 00514 foreach ($fields as $fieldInfo) { 00515 // Exploding subparts of the field configuration: 00516 $parts = explode(';', $fieldInfo); 00517 00518 // Getting the style information out: 00519 $color_style_parts = t3lib_div::trimExplode('-', $parts[4]); 00520 if (strcmp($color_style_parts[0], '')) { 00521 $this->setColorScheme($GLOBALS['TBE_STYLES']['colorschemes'][intval($color_style_parts[0])]); 00522 } 00523 if (strcmp($color_style_parts[1], '')) { 00524 $this->fieldStyle = $GLOBALS['TBE_STYLES']['styleschemes'][intval($color_style_parts[1])]; 00525 if (!isset($this->fieldStyle)) { 00526 $this->fieldStyle = $GLOBALS['TBE_STYLES']['styleschemes'][0]; 00527 } 00528 } 00529 if (strcmp($color_style_parts[2], '')) { 00530 $this->wrapBorder($out_array[$out_sheet], $out_pointer); 00531 $this->borderStyle = $GLOBALS['TBE_STYLES']['borderschemes'][intval($color_style_parts[2])]; 00532 if (!isset($this->borderStyle)) { 00533 $this->borderStyle = $GLOBALS['TBE_STYLES']['borderschemes'][0]; 00534 } 00535 } 00536 00537 // Render the field: 00538 $theField = $parts[0]; 00539 if (!in_array($theField, $excludeElements)) { 00540 if ($TCA[$table]['columns'][$theField]) { 00541 $sFieldPal = ''; 00542 00543 if ($parts[2] && !isset($this->palettesRendered[$this->renderDepth][$table][$parts[2]])) { 00544 $sFieldPal = $this->getPaletteFields($table, $row, $parts[2]); 00545 $this->palettesRendered[$this->renderDepth][$table][$parts[2]] = 1; 00546 } 00547 $sField = $this->getSingleField($table, $theField, $row, $parts[1], 0, $parts[3], $parts[2]); 00548 if ($sField) { 00549 $sField .= $sFieldPal; 00550 } 00551 00552 $out_array[$out_sheet][$out_pointer] .= $sField; 00553 } elseif ($theField == '--div--') { 00554 if ($cc > 0) { 00555 $out_array[$out_sheet][$out_pointer] .= $this->getDivider(); 00556 00557 if ($this->enableTabMenu && $dividers2tabs) { 00558 $this->wrapBorder($out_array[$out_sheet], $out_pointer); 00559 // Remove last tab entry from the dynNestedStack: 00560 $out_sheet++; 00561 // Remove the previous sheet from stack (if any): 00562 $this->popFromDynNestedStack('tab', $tabIdentStringMD5 . '-' . ($out_sheet)); 00563 // Remember on which sheet we're currently working: 00564 $this->pushToDynNestedStack('tab', $tabIdentStringMD5 . '-' . ($out_sheet + 1)); 00565 $out_array[$out_sheet] = array(); 00566 $out_array_meta[$out_sheet]['title'] = $this->sL($parts[1]); 00567 // Register newline for Tab 00568 $out_array_meta[$out_sheet]['newline'] = ($parts[2] == "newline"); 00569 } 00570 } else { // Setting alternative title for "General" tab if "--div--" is the very first element. 00571 $out_array_meta[$out_sheet]['title'] = $this->sL($parts[1]); 00572 // Only add the first tab to the dynNestedStack if there are more tabs: 00573 if ($tabIdentString && strpos($itemList, '--div--', strlen($fieldInfo))) { 00574 $this->pushToDynNestedStack('tab', $tabIdentStringMD5 . '-1'); 00575 } 00576 } 00577 } elseif ($theField == '--palette--') { 00578 if ($parts[2] && !isset($this->palettesRendered[$this->renderDepth][$table][$parts[2]])) { 00579 // render a 'header' if not collapsed 00580 if ($TCA[$table]['palettes'][$parts[2]]['canNotCollapse'] AND $parts[1]) { 00581 $out_array[$out_sheet][$out_pointer] .= $this->getPaletteFields($table, $row, $parts[2], $this->sL($parts[1])); 00582 } else { 00583 $out_array[$out_sheet][$out_pointer] .= $this->getPaletteFields($table, $row, $parts[2], '', '', $this->sL($parts[1])); 00584 } 00585 $this->palettesRendered[$this->renderDepth][$table][$parts[2]] = 1; 00586 } 00587 } 00588 } 00589 00590 $cc++; 00591 } 00592 } 00593 } 00594 } 00595 00596 // Hook: getMainFields_postProcess (requested by Thomas Hempel for use with the "dynaflex" extension) 00597 foreach ($this->hookObjectsMainFields as $hookObj) { 00598 if (method_exists($hookObj, 'getMainFields_postProcess')) { 00599 $hookObj->getMainFields_postProcess($table, $row, $this); 00600 } 00601 } 00602 00603 // Wrapping a border around it all: 00604 $this->wrapBorder($out_array[$out_sheet], $out_pointer); 00605 00606 // Resetting styles: 00607 $this->resetSchemes(); 00608 00609 // Rendering Main palettes, if any 00610 $mParr = t3lib_div::trimExplode(',', $TCA[$table]['ctrl']['mainpalette']); 00611 $i = 0; 00612 if (count($mParr)) { 00613 foreach ($mParr as $mP) { 00614 if (!isset($this->palettesRendered[$this->renderDepth][$table][$mP])) { 00615 $temp_palettesCollapsed = $this->palettesCollapsed; 00616 $this->palettesCollapsed = 0; 00617 $label = ($i == 0 ? $this->getLL('l_generalOptions') : $this->getLL('l_generalOptions_more')); 00618 $out_array[$out_sheet][$out_pointer] .= $this->getPaletteFields($table, $row, $mP, $label); 00619 $this->palettesCollapsed = $temp_palettesCollapsed; 00620 $this->palettesRendered[$this->renderDepth][$table][$mP] = 1; 00621 } 00622 $this->wrapBorder($out_array[$out_sheet], $out_pointer); 00623 $i++; 00624 if ($this->renderDepth) { 00625 $this->renderDepth--; 00626 } 00627 } 00628 } 00629 00630 // Return the imploded $out_array: 00631 if ($out_sheet > 0) { // There were --div-- dividers around... 00632 00633 // Create parts array for the tab menu: 00634 $parts = array(); 00635 foreach ($out_array as $idx => $sheetContent) { 00636 $content = implode('', $sheetContent); 00637 if ($content) { 00638 // Wrap content (row) with table-tag, otherwise tab/sheet will be disabled (see getdynTabMenu() ) 00639 $content = '<table border="0" cellspacing="0" cellpadding="0" width="100%">' . $content . '</table>'; 00640 } 00641 $parts[$idx] = array( 00642 'label' => $out_array_meta[$idx]['title'], 00643 'content' => $content, 00644 'newline' => $out_array_meta[$idx]['newline'], // Newline for this tab/sheet 00645 ); 00646 } 00647 00648 if (count($parts) > 1) { 00649 // Unset the current level of tab menus: 00650 $this->popFromDynNestedStack('tab', $tabIdentStringMD5 . '-' . ($out_sheet + 1)); 00651 $dividersToTabsBehaviour = (isset($TCA[$table]['ctrl']['dividers2tabs']) ? $TCA[$table]['ctrl']['dividers2tabs'] : 1); 00652 $output = $this->getDynTabMenu($parts, $tabIdentString, $dividersToTabsBehaviour); 00653 00654 } else { 00655 // If there is only one tab/part there is no need to wrap it into the dynTab code 00656 $output = isset($parts[0]) ? trim($parts[0]['content']) : ''; 00657 } 00658 00659 $output = ' 00660 <tr> 00661 <td colspan="2"> 00662 ' . $output . ' 00663 </td> 00664 </tr>'; 00665 00666 } else { 00667 // Only one, so just implode: 00668 $output = implode('', $out_array[$out_sheet]); 00669 } 00670 00671 return $output; 00672 } 00673 00674 /** 00675 * Will return the TCEform elements for a pre-defined list of fields. 00676 * Notice that this will STILL use the configuration found in the list [types][showitem] for those fields which are found there. So ideally the list of fields given as argument to this function should also be in the current [types][showitem] list of the record. 00677 * Used for displaying forms for the frontend edit icons for instance. 00678 * 00679 * @param string The table name 00680 * @param array The record array. 00681 * @param string Commalist of fields from the table. These will be shown in the specified order in a form. 00682 * @return string TCEform elements in a string. 00683 */ 00684 function getListedFields($table, $row, $list) { 00685 global $TCA; 00686 00687 t3lib_div::loadTCA($table); 00688 if ($this->edit_showFieldHelp || $this->doLoadTableDescr($table)) { 00689 $GLOBALS['LANG']->loadSingleTableDescription($table); 00690 } 00691 00692 $out = ''; 00693 $types_fieldConfig = t3lib_BEfunc::getTCAtypes($table, $row, 1); 00694 00695 $editFieldList = array_unique(t3lib_div::trimExplode(',', $list, 1)); 00696 foreach ($editFieldList as $theFieldC) { 00697 list($theField, $palFields) = preg_split('/\[|\]/', $theFieldC); 00698 $theField = trim($theField); 00699 $palFields = trim($palFields); 00700 if ($TCA[$table]['columns'][$theField]) { 00701 $parts = t3lib_div::trimExplode(';', $types_fieldConfig[$theField]['origString']); 00702 $sField = $this->getSingleField($table, $theField, $row, $parts[1], 0, $parts[3], 0); // Don't sent palette pointer - there are no options anyways for a field-list. 00703 $out .= $sField; 00704 } elseif ($theField == '--div--') { 00705 $out .= $this->getDivider(); 00706 } 00707 if ($palFields) { 00708 $out .= $this->getPaletteFields($table, $row, '', '', implode(',', t3lib_div::trimExplode('|', $palFields, 1))); 00709 } 00710 } 00711 00712 return $out; 00713 } 00714 00715 /** 00716 * Creates a palette (collection of secondary options). 00717 * 00718 * @param string The table name 00719 * @param array The row array 00720 * @param string The palette number/pointer 00721 * @param string Header string for the palette (used when in-form). If not set, no header item is made. 00722 * @param string Optional alternative list of fields for the palette 00723 * @param string Optional Link text for activating a palette (when palettes does not have another form element to belong to). 00724 * @return string HTML code. 00725 */ 00726 function getPaletteFields($table, $row, $palette, $header = '', $itemList = '', $collapsedHeader = NULL) { 00727 if (!$this->doPrintPalette) { 00728 return ''; 00729 } 00730 00731 $out = ''; 00732 $parts = $this->loadPaletteElements($table, $row, $palette, $itemList); 00733 00734 // Put palette together if there are fields in it: 00735 if (count($parts)) { 00736 00737 $realFields = 0; 00738 00739 foreach ($parts as $part) { 00740 if ($part['NAME'] !== '--linebreak--') { 00741 $realFields++; 00742 } 00743 } 00744 00745 if ($realFields > 0) { 00746 00747 if ($header) { 00748 $out .= $this->intoTemplate( 00749 array('HEADER' => htmlspecialchars($header)), 00750 $this->palFieldTemplateHeader 00751 ); 00752 } 00753 00754 $collapsed = $this->isPalettesCollapsed($table, $palette); 00755 00756 $thePalIcon = ''; 00757 if ($collapsed && $collapsedHeader !== NULL) { 00758 list($thePalIcon,) = $this->wrapOpenPalette( 00759 t3lib_iconWorks::getSpriteIcon( 00760 'actions-system-options-view', 00761 array('title' => htmlspecialchars($this->getLL('l_moreOptions'))) 00762 ), $table, $row, $palette, 1); 00763 $thePalIcon = '<span style="margin-left: 20px;">' . $thePalIcon . $collapsedHeader . '</span>'; 00764 } 00765 00766 $paletteHtml = $this->wrapPaletteField($this->printPalette($parts), $table, $row, $palette, $collapsed); 00767 00768 $out .= $this->intoTemplate( 00769 array('PALETTE' => $thePalIcon . $paletteHtml), 00770 $this->palFieldTemplate 00771 ); 00772 } 00773 } 00774 return $out; 00775 } 00776 00777 /** 00778 * Returns the form HTML code for a database table field. 00779 * 00780 * @param string The table name 00781 * @param string The field name 00782 * @param array The record to edit from the database table. 00783 * @param string Alternative field name label to show. 00784 * @param boolean Set this if the field is on a palette (in top frame), otherwise not. (if set, field will render as a hidden field). 00785 * @param string The "extra" options from "Part 4" of the field configurations found in the "types" "showitem" list. Typically parsed by $this->getSpecConfFromString() in order to get the options as an associative array. 00786 * @param integer The palette pointer. 00787 * @return mixed String (normal) or array (palettes) 00788 */ 00789 function getSingleField($table, $field, $row, $altName = '', $palette = 0, $extra = '', $pal = 0) { 00790 global $TCA, $BE_USER; 00791 00792 // Hook: getSingleField_preProcess 00793 foreach ($this->hookObjectsSingleField as $hookObj) { 00794 if (method_exists($hookObj, 'getSingleField_preProcess')) { 00795 $hookObj->getSingleField_preProcess($table, $field, $row, $altName, $palette, $extra, $pal, $this); 00796 } 00797 } 00798 00799 $out = ''; 00800 $PA = array(); 00801 $PA['altName'] = $altName; 00802 $PA['palette'] = $palette; 00803 $PA['extra'] = $extra; 00804 $PA['pal'] = $pal; 00805 00806 // Make sure to load full $TCA array for the table: 00807 t3lib_div::loadTCA($table); 00808 00809 // Get the TCA configuration for the current field: 00810 $PA['fieldConf'] = $TCA[$table]['columns'][$field]; 00811 $PA['fieldConf']['config']['form_type'] = $PA['fieldConf']['config']['form_type'] ? $PA['fieldConf']['config']['form_type'] : $PA['fieldConf']['config']['type']; // Using "form_type" locally in this script 00812 00813 $skipThisField = $this->inline->skipField($table, $field, $row, $PA['fieldConf']['config']); 00814 00815 // Now, check if this field is configured and editable (according to excludefields + other configuration) 00816 if (is_array($PA['fieldConf']) && 00817 !$skipThisField && 00818 (!$PA['fieldConf']['exclude'] || $BE_USER->check('non_exclude_fields', $table . ':' . $field)) && 00819 $PA['fieldConf']['config']['form_type'] != 'passthrough' && 00820 ($this->RTEenabled || !$PA['fieldConf']['config']['showIfRTE']) && 00821 (!$PA['fieldConf']['displayCond'] || $this->isDisplayCondition($PA['fieldConf']['displayCond'], $row)) && 00822 (!$TCA[$table]['ctrl']['languageField'] || $PA['fieldConf']['l10n_display'] || strcmp($PA['fieldConf']['l10n_mode'], 'exclude') || $row[$TCA[$table]['ctrl']['languageField']] <= 0) && 00823 (!$TCA[$table]['ctrl']['languageField'] || !$this->localizationMode || $this->localizationMode === $PA['fieldConf']['l10n_cat']) 00824 ) { 00825 00826 00827 // Fetching the TSconfig for the current table/field. This includes the $row which means that 00828 $PA['fieldTSConfig'] = $this->setTSconfig($table, $row, $field); 00829 00830 // If the field is NOT disabled from TSconfig (which it could have been) then render it 00831 if (!$PA['fieldTSConfig']['disabled']) { 00832 // Override fieldConf by fieldTSconfig: 00833 $PA['fieldConf']['config'] = $this->overrideFieldConf($PA['fieldConf']['config'], $PA['fieldTSConfig']); 00834 00835 // Init variables: 00836 $PA['itemFormElName'] = $this->prependFormFieldNames . '[' . $table . '][' . $row['uid'] . '][' . $field . ']'; // Form field name 00837 $PA['itemFormElName_file'] = $this->prependFormFieldNames_file . '[' . $table . '][' . $row['uid'] . '][' . $field . ']'; // Form field name, in case of file uploads 00838 $PA['itemFormElValue'] = $row[$field]; // The value to show in the form field. 00839 $PA['itemFormElID'] = $this->prependFormFieldNames . '_' . $table . '_' . $row['uid'] . '_' . $field; 00840 00841 // set field to read-only if configured for translated records to show default language content as readonly 00842 if ($PA['fieldConf']['l10n_display'] && t3lib_div::inList($PA['fieldConf']['l10n_display'], 'defaultAsReadonly') && $row[$TCA[$table]['ctrl']['languageField']] > 0) { 00843 $PA['fieldConf']['config']['readOnly'] = true; 00844 $PA['itemFormElValue'] = $this->defaultLanguageData[$table . ':' . $row['uid']][$field]; 00845 } 00846 00847 // Create a JavaScript code line which will ask the user to save/update the form due to changing the element. This is used for eg. "type" fields and others configured with "requestUpdate" 00848 if ( 00849 ($TCA[$table]['ctrl']['type'] && !strcmp($field, $TCA[$table]['ctrl']['type'])) || 00850 ($TCA[$table]['ctrl']['requestUpdate'] && t3lib_div::inList($TCA[$table]['ctrl']['requestUpdate'], $field))) { 00851 if ($GLOBALS['BE_USER']->jsConfirmation(1)) { 00852 $alertMsgOnChange = 'if (confirm(TBE_EDITOR.labels.onChangeAlert) && TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };'; 00853 } else { 00854 $alertMsgOnChange = 'if (TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };'; 00855 } 00856 } else { 00857 $alertMsgOnChange = ''; 00858 } 00859 00860 // Render as a hidden field? 00861 if (in_array($field, $this->hiddenFieldListArr)) { 00862 $this->hiddenFieldAccum[] = '<input type="hidden" name="' . $PA['itemFormElName'] . '" value="' . htmlspecialchars($PA['itemFormElValue']) . '" />'; 00863 } else { // Render as a normal field: 00864 00865 // If the field is NOT a palette field, then we might create an icon which links to a palette for the field, if one exists. 00866 if (!$PA['palette']) { 00867 $paletteFields = $this->loadPaletteElements($table, $row, $PA['pal']); 00868 if ($PA['pal'] && $this->isPalettesCollapsed($table, $PA['pal']) && count($paletteFields)) { 00869 list($thePalIcon, $palJSfunc) = $this->wrapOpenPalette(t3lib_iconWorks::getSpriteIcon('actions-system-options-view', array('title' => htmlspecialchars($this->getLL('l_moreOptions')))), $table, $row, $PA['pal'], 1); 00870 } else { 00871 $thePalIcon = ''; 00872 $palJSfunc = ''; 00873 } 00874 } 00875 // onFocus attribute to add to the field: 00876 $PA['onFocus'] = ($palJSfunc && !$BE_USER->uc['dontShowPalettesOnFocusInAB']) ? ' onfocus="' . htmlspecialchars($palJSfunc) . '"' : ''; 00877 00878 // Find item 00879 $item = ''; 00880 $PA['label'] = ($PA['altName'] ? $PA['altName'] : $PA['fieldConf']['label']); 00881 $PA['label'] = ($PA['fieldTSConfig']['label'] ? $PA['fieldTSConfig']['label'] : $PA['label']); 00882 $PA['label'] = ($PA['fieldTSConfig']['label.'][$GLOBALS['LANG']->lang] ? $PA['fieldTSConfig']['label.'][$GLOBALS['LANG']->lang] : $PA['label']); 00883 $PA['label'] = $this->sL($PA['label']); 00884 // JavaScript code for event handlers: 00885 $PA['fieldChangeFunc'] = array(); 00886 $PA['fieldChangeFunc']['TBE_EDITOR_fieldChanged'] = "TBE_EDITOR.fieldChanged('" . $table . "','" . $row['uid'] . "','" . $field . "','" . $PA['itemFormElName'] . "');"; 00887 $PA['fieldChangeFunc']['alert'] = $alertMsgOnChange; 00888 // if this is the child of an inline type and it is the field creating the label 00889 if ($this->inline->isInlineChildAndLabelField($table, $field)) { 00890 $inlineObjectId = implode( 00891 t3lib_TCEforms_inline::Structure_Separator, 00892 array( 00893 $this->inline->inlineNames['object'], 00894 $table, 00895 $row['uid'] 00896 ) 00897 ); 00898 $PA['fieldChangeFunc']['inline'] = "inline.handleChangedField('" . $PA['itemFormElName'] . "','" . $inlineObjectId . "');"; 00899 } 00900 00901 // Based on the type of the item, call a render function: 00902 $item = $this->getSingleField_SW($table, $field, $row, $PA); 00903 00904 // Add language + diff 00905 if ($PA['fieldConf']['l10n_display'] && (t3lib_div::inList($PA['fieldConf']['l10n_display'], 'hideDiff') || t3lib_div::inList($PA['fieldConf']['l10n_display'], 'defaultAsReadonly'))) { 00906 $renderLanguageDiff = false; 00907 } else { 00908 $renderLanguageDiff = true; 00909 } 00910 00911 if ($renderLanguageDiff) { 00912 $item = $this->renderDefaultLanguageContent($table, $field, $row, $item); 00913 $item = $this->renderDefaultLanguageDiff($table, $field, $row, $item); 00914 } 00915 00916 // If the record has been saved and the "linkTitleToSelf" is set, we make the field name into a link, which will load ONLY this field in alt_doc.php 00917 $label = t3lib_div::deHSCentities(htmlspecialchars($PA['label'])); 00918 if (t3lib_div::testInt($row['uid']) && $PA['fieldTSConfig']['linkTitleToSelf'] && !t3lib_div::_GP('columnsOnly')) { 00919 $lTTS_url = $this->backPath . 'alt_doc.php?edit[' . $table . '][' . $row['uid'] . ']=edit&columnsOnly=' . $field . '&returnUrl=' . rawurlencode($this->thisReturnUrl()); 00920 $label = '<a href="' . htmlspecialchars($lTTS_url) . '">' . $label . '</a>'; 00921 } 00922 00923 // wrap the label with help text 00924 $PA['label'] = $label = t3lib_BEfunc::wrapInHelp($table, $field, $label); 00925 00926 // Create output value: 00927 if ($PA['fieldConf']['config']['form_type'] == 'user' && $PA['fieldConf']['config']['noTableWrapping']) { 00928 $out = $item; 00929 } elseif ($PA['palette']) { 00930 // Array: 00931 $out = array( 00932 'NAME' => $label, 00933 'ID' => $row['uid'], 00934 'FIELD' => $field, 00935 'TABLE' => $table, 00936 'ITEM' => $item 00937 ); 00938 $out = $this->addUserTemplateMarkers($out, $table, $field, $row, $PA); 00939 } else { 00940 // String: 00941 $out = array( 00942 'NAME' => $label, 00943 'ITEM' => $item, 00944 'TABLE' => $table, 00945 'ID' => $row['uid'], 00946 'PAL_LINK_ICON' => $thePalIcon, 00947 'FIELD' => $field 00948 ); 00949 $out = $this->addUserTemplateMarkers($out, $table, $field, $row, $PA); 00950 // String: 00951 $out = $this->intoTemplate($out); 00952 } 00953 } 00954 } else { 00955 $this->commentMessages[] = $this->prependFormFieldNames . '[' . $table . '][' . $row['uid'] . '][' . $field . ']: Disabled by TSconfig'; 00956 } 00957 } 00958 // Hook: getSingleField_postProcess 00959 foreach ($this->hookObjectsSingleField as $hookObj) { 00960 if (method_exists($hookObj, 'getSingleField_postProcess')) { 00961 $hookObj->getSingleField_postProcess($table, $field, $row, $out, $PA, $this); 00962 } 00963 } 00964 // Return value (string or array) 00965 return $out; 00966 } 00967 00968 /** 00969 * Rendering a single item for the form 00970 * 00971 * @param string Table name of record 00972 * @param string Fieldname to render 00973 * @param array The record 00974 * @param array parameters array containing a lot of stuff. Value by Reference! 00975 * @return string Returns the item as HTML code to insert 00976 * @access private 00977 * @see getSingleField(), getSingleField_typeFlex_draw() 00978 */ 00979 function getSingleField_SW($table, $field, $row, &$PA) { 00980 $PA['fieldConf']['config']['form_type'] = $PA['fieldConf']['config']['form_type'] ? $PA['fieldConf']['config']['form_type'] : $PA['fieldConf']['config']['type']; // Using "form_type" locally in this script 00981 00982 // Hook: getSingleField_beforeRender 00983 foreach ($this->hookObjectsSingleField as $hookObject) { 00984 if (method_exists($hookObject, 'getSingleField_beforeRender')) { 00985 $hookObject->getSingleField_beforeRender($table, $field, $row, $PA); 00986 } 00987 } 00988 00989 switch ($PA['fieldConf']['config']['form_type']) { 00990 case 'input': 00991 $item = $this->getSingleField_typeInput($table, $field, $row, $PA); 00992 break; 00993 case 'text': 00994 $item = $this->getSingleField_typeText($table, $field, $row, $PA); 00995 break; 00996 case 'check': 00997 $item = $this->getSingleField_typeCheck($table, $field, $row, $PA); 00998 break; 00999 case 'radio': 01000 $item = $this->getSingleField_typeRadio($table, $field, $row, $PA); 01001 break; 01002 case 'select': 01003 $item = $this->getSingleField_typeSelect($table, $field, $row, $PA); 01004 break; 01005 case 'group': 01006 $item = $this->getSingleField_typeGroup($table, $field, $row, $PA); 01007 break; 01008 case 'inline': 01009 $item = $this->inline->getSingleField_typeInline($table, $field, $row, $PA); 01010 break; 01011 case 'none': 01012 $item = $this->getSingleField_typeNone($table, $field, $row, $PA); 01013 break; 01014 case 'user': 01015 $item = $this->getSingleField_typeUser($table, $field, $row, $PA); 01016 break; 01017 case 'flex': 01018 $item = $this->getSingleField_typeFlex($table, $field, $row, $PA); 01019 break; 01020 default: 01021 $item = $this->getSingleField_typeUnknown($table, $field, $row, $PA); 01022 break; 01023 } 01024 01025 return $item; 01026 } 01027 01028 01029 /********************************************************** 01030 * 01031 * Rendering of each TCEform field type 01032 * 01033 ************************************************************/ 01034 01035 /** 01036 * Generation of TCEform elements of the type "input" 01037 * This will render a single-line input form field, possibly with various control/validation features 01038 * 01039 * @param string The table name of the record 01040 * @param string The field name which this element is supposed to edit 01041 * @param array The record data array where the value(s) for the field can be found 01042 * @param array An array with additional configuration options. 01043 * @return string The HTML code for the TCEform field 01044 */ 01045 function getSingleField_typeInput($table, $field, $row, &$PA) { 01046 $config = $PA['fieldConf']['config']; 01047 01048 $specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']); 01049 $size = t3lib_div::intInRange($config['size'] ? $config['size'] : 30, 5, $this->maxInputWidth); 01050 $evalList = t3lib_div::trimExplode(',', $config['eval'], 1); 01051 $classAndStyleAttributes = $this->formWidthAsArray($size); 01052 01053 $fieldAppendix = ''; 01054 $cssClasses = array($classAndStyleAttributes['class']); 01055 $cssStyle = $classAndStyleAttributes['style']; 01056 01057 if (!isset($config['checkbox'])) { 01058 $config['checkbox'] = '0'; 01059 $checkboxIsset = FALSE; 01060 } else { 01061 $checkboxIsset = TRUE; 01062 } 01063 01064 if (in_array('date', $evalList) || in_array('datetime', $evalList)) { 01065 if (in_array('datetime', $evalList)) { 01066 $class = 'datetime'; 01067 } else { 01068 $class = 'date'; 01069 } 01070 $dateRange = ''; 01071 if (isset($config['range']['lower'])) { 01072 $dateRange .= ' lower-' . intval($config['range']['lower']); 01073 } 01074 if (isset($config['range']['upper'])) { 01075 $dateRange .= ' upper-' . intval($config['range']['upper']); 01076 } 01077 $inputId = uniqid('tceforms-' . $class . 'field-'); 01078 $cssClasses[] = 'tceforms-textfield tceforms-' . $class . 'field' . $dateRange; 01079 $fieldAppendix = t3lib_iconWorks::getSpriteIcon( 01080 'actions-edit-pick-date', 01081 array( 01082 'style' => 'cursor:pointer;', 01083 'id' => 'picker-' . $inputId 01084 ) 01085 ); 01086 } elseif (in_array('timesec', $evalList)) { 01087 $inputId = uniqid('tceforms-timesecfield-'); 01088 $cssClasses[] = 'tceforms-textfield tceforms-timesecfield'; 01089 } elseif (in_array('year', $evalList)) { 01090 $inputId = uniqid('tceforms-yearfield-'); 01091 $cssClasses[] = 'tceforms-textfield tceforms-yearfield'; 01092 } elseif (in_array('time', $evalList)) { 01093 $inputId = uniqid('tceforms-timefield-'); 01094 $cssClasses[] = 'tceforms-textfield tceforms-timefield'; 01095 } elseif (in_array('int', $evalList)) { 01096 $inputId = uniqid('tceforms-intfield-'); 01097 $cssClasses[] = 'tceforms-textfield tceforms-intfield'; 01098 } elseif (in_array('double2', $evalList)) { 01099 $inputId = uniqid('tceforms-double2field-'); 01100 $cssClasses[] = 'tceforms-textfield tceforms-double2field'; 01101 } else { 01102 $inputId = uniqid('tceforms-textfield-'); 01103 $cssClasses[] = 'tceforms-textfield'; 01104 if ($checkboxIsset === FALSE) { 01105 $config['checkbox'] = ''; 01106 } 01107 } 01108 if (isset($config['wizards']['link'])) { 01109 $inputId = uniqid('tceforms-linkfield-'); 01110 $cssClasses[] = 'tceforms-textfield tceforms-linkfield'; 01111 01112 } elseif (isset($config['wizards']['color'])) { 01113 $inputId = uniqid('tceforms-colorfield-'); 01114 $cssClasses[] = 'tceforms-textfield tceforms-colorfield'; 01115 } 01116 01117 if ($this->renderReadonly || $config['readOnly']) { 01118 $itemFormElValue = $PA['itemFormElValue']; 01119 if (in_array('date', $evalList)) { 01120 $config['format'] = 'date'; 01121 } elseif (in_array('datetime', $evalList)) { 01122 $config['format'] = 'datetime'; 01123 } elseif (in_array('time', $evalList)) { 01124 $config['format'] = 'time'; 01125 } 01126 if (in_array('password', $evalList)) { 01127 $itemFormElValue = $itemFormElValue ? '*********' : ''; 01128 } 01129 return $this->getSingleField_typeNone_render($config, $itemFormElValue); 01130 } 01131 01132 foreach ($evalList as $func) { 01133 switch ($func) { 01134 case 'required': 01135 $this->registerRequiredProperty('field', $table . '_' . $row['uid'] . '_' . $field, $PA['itemFormElName']); 01136 // Mark this field for date/time disposal: 01137 if (array_intersect($evalList, array('date', 'datetime', 'time'))) { 01138 $this->requiredAdditional[$PA['itemFormElName']]['isPositiveNumber'] = true; 01139 } 01140 break; 01141 default: 01142 if (substr($func, 0, 3) == 'tx_') { 01143 // Pair hook to the one in t3lib_TCEmain::checkValue_input_Eval() 01144 $evalObj = t3lib_div::getUserObj($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tce']['formevals'][$func] . ':&' . $func); 01145 if (is_object($evalObj) && method_exists($evalObj, 'deevaluateFieldValue')) { 01146 $_params = array( 01147 'value' => $PA['itemFormElValue'] 01148 ); 01149 $PA['itemFormElValue'] = $evalObj->deevaluateFieldValue($_params); 01150 } 01151 } 01152 break; 01153 } 01154 } 01155 01156 $paramsList = "'" . $PA['itemFormElName'] . "','" . implode(',', $evalList) . "','" . trim($config['is_in']) . "'," . (isset($config['checkbox']) ? 1 : 0) . ",'" . $config['checkbox'] . "'"; 01157 if ((in_array('date', $evalList) || in_array('datetime', $evalList))) { 01158 $item .= '<span class="t3-tceforms-input-wrapper-datetime" onmouseOver="if (document.getElementById(\'' . 01159 $inputId . '\').value) {this.className=\'t3-tceforms-input-wrapper-datetime-hover\';} else {this.className=\'t3-tceforms-input-wrapper-datetime\';};" onmouseOut="this.className=\'t3-tceforms-input-wrapper-datetime\';">'; 01160 01161 // Add server timezone offset to UTC to our stored date 01162 if ($PA['itemFormElValue'] > 0) { 01163 $PA['itemFormElValue'] += date('Z', $PA['itemFormElValue']); 01164 } 01165 } else { 01166 $item .= '<span class="t3-tceforms-input-wrapper" onmouseOver="if (document.getElementById(\'' . $inputId . 01167 '\').value) {this.className=\'t3-tceforms-input-wrapper-hover\';} else {this.className=\'t3-tceforms-input-wrapper\';};" onmouseOut="this.className=\'t3-tceforms-input-wrapper\';">'; 01168 } 01169 01170 $PA['fieldChangeFunc'] = array_merge( 01171 array('typo3form.fieldGet' => 'typo3form.fieldGet(' . $paramsList . ');'), 01172 $PA['fieldChangeFunc'] 01173 ); 01174 // old function "checkbox" now the option to set the date / remove the date 01175 if (isset($config['checkbox'])) { 01176 $item .= t3lib_iconWorks::getSpriteIcon('actions-input-clear', array('tag' => 'a', 'class' => 't3-tceforms-input-clearer', 'onclick' => 'document.getElementById(\'' . $inputId . '\').value=\'\';document.getElementById(\'' . $inputId . '\').focus();' . implode('', $PA['fieldChangeFunc']))); 01177 } 01178 $mLgd = ($config['max'] ? $config['max'] : 256); 01179 $iOnChange = implode('', $PA['fieldChangeFunc']); 01180 01181 $item .= '<input type="text" id="' . $inputId . 01182 '" class="' . implode(' ', $cssClasses) . '" name="' . $PA['itemFormElName'] . 01183 '_hr" value="" style="' . $cssStyle . '" maxlength="' . $mLgd . '" onchange="' . 01184 htmlspecialchars($iOnChange) . '"' . $PA['onFocus'] . ' />'; // This is the EDITABLE form field. 01185 $item .= '<input type="hidden" name="' . $PA['itemFormElName'] . '" value="' . 01186 htmlspecialchars($PA['itemFormElValue']) . '" />'; // This is the ACTUAL form field - values from the EDITABLE field must be transferred to this field which is the one that is written to the database. 01187 $item .= $fieldAppendix . '</span><div style="clear:both;"></div>'; 01188 $this->extJSCODE .= 'typo3form.fieldSet(' . $paramsList . ');'; 01189 01190 // going through all custom evaluations configured for this field 01191 foreach ($evalList as $evalData) { 01192 if (substr($evalData, 0, 3) == 'tx_') { 01193 $evalObj = t3lib_div::getUserObj($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tce']['formevals'][$evalData] . ':&' . $evalData); 01194 if (is_object($evalObj) && method_exists($evalObj, 'returnFieldJS')) { 01195 $this->extJSCODE .= "\n\nfunction " . $evalData . "(value) {\n" . $evalObj->returnFieldJS() . "\n}\n"; 01196 } 01197 } 01198 } 01199 01200 // Creating an alternative item without the JavaScript handlers. 01201 $altItem = '<input type="hidden" name="' . $PA['itemFormElName'] . '_hr" value="" />'; 01202 $altItem .= '<input type="hidden" name="' . $PA['itemFormElName'] . '" value="' . htmlspecialchars($PA['itemFormElValue']) . '" />'; 01203 01204 // Wrap a wizard around the item? 01205 $item = $this->renderWizards(array($item, $altItem), $config['wizards'], $table, $row, $field, $PA, $PA['itemFormElName'] . '_hr', $specConf); 01206 01207 return $item; 01208 } 01209 01210 /** 01211 * Generation of TCEform elements of the type "text" 01212 * This will render a <textarea> OR RTE area form field, possibly with various control/validation features 01213 * 01214 * @param string The table name of the record 01215 * @param string The field name which this element is supposed to edit 01216 * @param array The record data array where the value(s) for the field can be found 01217 * @param array An array with additional configuration options. 01218 * @return string The HTML code for the TCEform field 01219 */ 01220 function getSingleField_typeText($table, $field, $row, &$PA) { 01221 01222 // Init config: 01223 $config = $PA['fieldConf']['config']; 01224 $evalList = t3lib_div::trimExplode(',', $config['eval'], 1); 01225 01226 if ($this->renderReadonly || $config['readOnly']) { 01227 return $this->getSingleField_typeNone_render($config, $PA['itemFormElValue']); 01228 } 01229 01230 // Setting columns number: 01231 $cols = t3lib_div::intInRange($config['cols'] ? $config['cols'] : 30, 5, $this->maxTextareaWidth); 01232 01233 // Setting number of rows: 01234 $origRows = $rows = t3lib_div::intInRange($config['rows'] ? $config['rows'] : 5, 1, 20); 01235 if (strlen($PA['itemFormElValue']) > $this->charsPerRow * 2) { 01236 $cols = $this->maxTextareaWidth; 01237 $rows = t3lib_div::intInRange(round(strlen($PA['itemFormElValue']) / $this->charsPerRow), count(explode(LF, $PA['itemFormElValue'])), 20); 01238 if ($rows < $origRows) { 01239 $rows = $origRows; 01240 } 01241 } 01242 01243 if (in_array('required', $evalList)) { 01244 $this->requiredFields[$table . '_' . $row['uid'] . '_' . $field] = $PA['itemFormElName']; 01245 } 01246 01247 // Init RTE vars: 01248 $RTEwasLoaded = 0; // Set true, if the RTE is loaded; If not a normal textarea is shown. 01249 $RTEwouldHaveBeenLoaded = 0; // Set true, if the RTE would have been loaded if it wasn't for the disable-RTE flag in the bottom of the page... 01250 01251 // "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist. Traditionally, this is where RTE configuration has been found. 01252 $specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']); 01253 01254 // Setting up the altItem form field, which is a hidden field containing the value 01255 $altItem = '<input type="hidden" name="' . htmlspecialchars($PA['itemFormElName']) . '" value="' . htmlspecialchars($PA['itemFormElValue']) . '" />'; 01256 01257 // If RTE is generally enabled (TYPO3_CONF_VARS and user settings) 01258 if ($this->RTEenabled) { 01259 $p = t3lib_BEfunc::getSpecConfParametersFromArray($specConf['rte_transform']['parameters']); 01260 if (isset($specConf['richtext']) && (!$p['flag'] || !$row[$p['flag']])) { // If the field is configured for RTE and if any flag-field is not set to disable it. 01261 t3lib_BEfunc::fixVersioningPid($table, $row); 01262 list($tscPID, $thePidValue) = $this->getTSCpid($table, $row['uid'], $row['pid']); 01263 01264 // If the pid-value is not negative (that is, a pid could NOT be fetched) 01265 if ($thePidValue >= 0) { 01266 $RTEsetup = $GLOBALS['BE_USER']->getTSConfig('RTE', t3lib_BEfunc::getPagesTSconfig($tscPID)); 01267 $RTEtypeVal = t3lib_BEfunc::getTCAtypeValue($table, $row); 01268 $thisConfig = t3lib_BEfunc::RTEsetup($RTEsetup['properties'], $table, $field, $RTEtypeVal); 01269 01270 if (!$thisConfig['disabled']) { 01271 if (!$this->disableRTE) { 01272 $this->RTEcounter++; 01273 01274 // Find alternative relative path for RTE images/links: 01275 $eFile = t3lib_parsehtml_proc::evalWriteFile($specConf['static_write'], $row); 01276 $RTErelPath = is_array($eFile) ? dirname($eFile['relEditFile']) : ''; 01277 01278 // Get RTE object, draw form and set flag: 01279 $RTEobj = t3lib_BEfunc::RTEgetObj(); 01280 $item = $RTEobj->drawRTE($this, $table, $field, $row, $PA, $specConf, $thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue); 01281 01282 // Wizard: 01283 $item = $this->renderWizards(array($item, $altItem), $config['wizards'], $table, $row, $field, $PA, $PA['itemFormElName'], $specConf, 1); 01284 01285 $RTEwasLoaded = 1; 01286 } else { 01287 $RTEwouldHaveBeenLoaded = 1; 01288 $this->commentMessages[] = $PA['itemFormElName'] . ': RTE is disabled by the on-page RTE-flag (probably you can enable it by the check-box in the bottom of this page!)'; 01289 } 01290 } else { 01291 $this->commentMessages[] = $PA['itemFormElName'] . ': RTE is disabled by the Page TSconfig, "RTE"-key (eg. by RTE.default.disabled=0 or such)'; 01292 } 01293 } else { 01294 $this->commentMessages[] = $PA['itemFormElName'] . ': PID value could NOT be fetched. Rare error, normally with new records.'; 01295 } 01296 } else { 01297 if (!isset($specConf['richtext'])) { 01298 $this->commentMessages[] = $PA['itemFormElName'] . ': RTE was not configured for this field in TCA-types'; 01299 } 01300 if (!(!$p['flag'] || !$row[$p['flag']])) { 01301 $this->commentMessages[] = $PA['itemFormElName'] . ': Field-flag (' . $PA['flag'] . ') has been set to disable RTE!'; 01302 } 01303 } 01304 } 01305 01306 // Display ordinary field if RTE was not loaded. 01307 if (!$RTEwasLoaded) { 01308 if ($specConf['rte_only']) { // Show message, if no RTE (field can only be edited with RTE!) 01309 $item = '<p><em>' . htmlspecialchars($this->getLL('l_noRTEfound')) . '</em></p>'; 01310 } else { 01311 if ($specConf['nowrap']) { 01312 $wrap = 'off'; 01313 } else { 01314 $wrap = ($config['wrap'] ? $config['wrap'] : 'virtual'); 01315 } 01316 01317 $classes = array(); 01318 if ($specConf['fixed-font']) { 01319 $classes[] = 'fixed-font'; 01320 } 01321 if ($specConf['enable-tab']) { 01322 $classes[] = 'enable-tab'; 01323 } 01324 01325 $formWidthText = $this->formWidthText($cols, $wrap); 01326 01327 // Extract class attributes from $formWidthText (otherwise it would be added twice to the output) 01328 $res = array(); 01329 if (preg_match('/ class="(.+?)"/', $formWidthText, $res)) { 01330 $formWidthText = str_replace(' class="' . $res[1] . '"', '', $formWidthText); 01331 $classes = array_merge($classes, explode(' ', $res[1])); 01332 } 01333 01334 if (count($classes)) { 01335 $class = ' class="tceforms-textarea ' . implode(' ', $classes) . '"'; 01336 } else { 01337 $class = 'tceforms-textarea'; 01338 } 01339 01340 $evalList = t3lib_div::trimExplode(',', $config['eval'], 1); 01341 foreach ($evalList as $func) { 01342 switch ($func) { 01343 case 'required': 01344 $this->registerRequiredProperty('field', $table . '_' . $row['uid'] . '_' . $field, $PA['itemFormElName']); 01345 break; 01346 default: 01347 if (substr($func, 0, 3) == 'tx_') { 01348 // Pair hook to the one in t3lib_TCEmain::checkValue_input_Eval() and t3lib_TCEmain::checkValue_text_Eval() 01349 $evalObj = t3lib_div::getUserObj($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tce']['formevals'][$func] . ':&' . $func); 01350 if (is_object($evalObj) && method_exists($evalObj, 'deevaluateFieldValue')) { 01351 $_params = array( 01352 'value' => $PA['itemFormElValue'] 01353 ); 01354 $PA['itemFormElValue'] = $evalObj->deevaluateFieldValue($_params); 01355 } 01356 } 01357 break; 01358 } 01359 } 01360 01361 $iOnChange = implode('', $PA['fieldChangeFunc']); 01362 $item .= ' 01363 <textarea id="' . uniqid('tceforms-textarea-') . '" name="' . $PA['itemFormElName'] . '"' . $formWidthText . $class . ' rows="' . $rows . '" wrap="' . $wrap . '" onchange="' . htmlspecialchars($iOnChange) . '"' . $PA['onFocus'] . '>' . 01364 t3lib_div::formatForTextarea($PA['itemFormElValue']) . 01365 '</textarea>'; 01366 $item = $this->renderWizards(array($item, $altItem), $config['wizards'], $table, $row, $field, $PA, $PA['itemFormElName'], $specConf, $RTEwouldHaveBeenLoaded); 01367 } 01368 } 01369 01370 // Return field HTML: 01371 return $item; 01372 } 01373 01374 /** 01375 * Generation of TCEform elements of the type "check" 01376 * This will render a check-box OR an array of checkboxes 01377 * 01378 * @param string The table name of the record 01379 * @param string The field name which this element is supposed to edit 01380 * @param array The record data array where the value(s) for the field can be found 01381 * @param array An array with additional configuration options. 01382 * @return string The HTML code for the TCEform field 01383 */ 01384 function getSingleField_typeCheck($table, $field, $row, &$PA) { 01385 $config = $PA['fieldConf']['config']; 01386 01387 $disabled = ''; 01388 if ($this->renderReadonly || $config['readOnly']) { 01389 $disabled = ' disabled="disabled"'; 01390 } 01391 01392 // Traversing the array of items: 01393 $selItems = $this->initItemArray($PA['fieldConf']); 01394 if ($config['itemsProcFunc']) { 01395 $selItems = $this->procItems($selItems, $PA['fieldTSConfig']['itemsProcFunc.'], $config, $table, $row, $field); 01396 } 01397 01398 if (!count($selItems)) { 01399 $selItems[] = array('', ''); 01400 } 01401 $thisValue = intval($PA['itemFormElValue']); 01402 01403 $cols = intval($config['cols']); 01404 if ($cols > 1) { 01405 $item .= '<table border="0" cellspacing="0" cellpadding="0" class="typo3-TCEforms-checkboxArray">'; 01406 for ($c = 0; $c < count($selItems); $c++) { 01407 $p = $selItems[$c]; 01408 if (!($c % $cols)) { 01409 $item .= '<tr>'; 01410 } 01411 $cBP = $this->checkBoxParams($PA['itemFormElName'], $thisValue, $c, count($selItems), implode('', $PA['fieldChangeFunc'])); 01412 $cBName = $PA['itemFormElName'] . '_' . $c; 01413 $cBID = $PA['itemFormElID'] . '_' . $c; 01414 $item .= '<td nowrap="nowrap">' . 01415 '<input type="checkbox"' . $this->insertDefStyle('check') . ' value="1" name="' . $cBName . '"' . $cBP . $disabled . ' id="' . $cBID . '" />' . 01416 $this->wrapLabels('<label for="' . $cBID . '">' . htmlspecialchars($p[0]) . '</label> ') . 01417 '</td>'; 01418 if (($c % $cols) + 1 == $cols) { 01419 $item .= '</tr>'; 01420 } 01421 } 01422 if ($c % $cols) { 01423 $rest = $cols - ($c % $cols); 01424 for ($c = 0; $c < $rest; $c++) { 01425 $item .= '<td></td>'; 01426 } 01427 if ($c > 0) { 01428 $item .= '</tr>'; 01429 } 01430 } 01431 $item .= '</table>'; 01432 } else { 01433 for ($c = 0; $c < count($selItems); $c++) { 01434 $p = $selItems[$c]; 01435 $cBP = $this->checkBoxParams($PA['itemFormElName'], $thisValue, $c, count($selItems), implode('', $PA['fieldChangeFunc'])); 01436 $cBName = $PA['itemFormElName'] . '_' . $c; 01437 $cBID = $PA['itemFormElID'] . '_' . $c; 01438 $item .= ($c > 0 ? '<br />' : '') . 01439 '<input type="checkbox"' . $this->insertDefStyle('check') . ' value="1" name="' . $cBName . '"' . $cBP . $PA['onFocus'] . $disabled . ' id="' . $cBID . '" />' . 01440 $this->wrapLabels('<label for="' . $cBID . '">' . htmlspecialchars($p[0]) . '</label>'); 01441 } 01442 } 01443 if (!$disabled) { 01444 $item .= '<input type="hidden" name="' . $PA['itemFormElName'] . '" value="' . htmlspecialchars($thisValue) . '" />'; 01445 } 01446 01447 return $item; 01448 } 01449 01450 /** 01451 * Generation of TCEform elements of the type "radio" 01452 * This will render a series of radio buttons. 01453 * 01454 * @param string The table name of the record 01455 * @param string The field name which this element is supposed to edit 01456 * @param array The record data array where the value(s) for the field can be found 01457 * @param array An array with additional configuration options. 01458 * @return string The HTML code for the TCEform field 01459 */ 01460 function getSingleField_typeRadio($table, $field, $row, &$PA) { 01461 $config = $PA['fieldConf']['config']; 01462 01463 $disabled = ''; 01464 if ($this->renderReadonly || $config['readOnly']) { 01465 $disabled = ' disabled="disabled"'; 01466 } 01467 01468 // Get items for the array: 01469 $selItems = $this->initItemArray($PA['fieldConf']); 01470 if ($config['itemsProcFunc']) { 01471 $selItems = $this->procItems($selItems, $PA['fieldTSConfig']['itemsProcFunc.'], $config, $table, $row, $field); 01472 } 01473 01474 // Traverse the items, making the form elements: 01475 for ($c = 0; $c < count($selItems); $c++) { 01476 $p = $selItems[$c]; 01477 $rID = $PA['itemFormElID'] . '_' . $c; 01478 $rOnClick = implode('', $PA['fieldChangeFunc']); 01479 $rChecked = (!strcmp($p[1], $PA['itemFormElValue']) ? ' checked="checked"' : ''); 01480 $item .= '<input type="radio"' . $this->insertDefStyle('radio') . ' name="' . $PA['itemFormElName'] . '" value="' . htmlspecialchars($p[1]) . '" onclick="' . htmlspecialchars($rOnClick) . '"' . $rChecked . $PA['onFocus'] . $disabled . ' id="' . $rID . '" /> 01481 <label for="' . $rID . '">' . htmlspecialchars($p[0]) . '</label> 01482 <br />'; 01483 } 01484 01485 return $item; 01486 } 01487 01488 /** 01489 * Generation of TCEform elements of the type "select" 01490 * This will render a selector box element, or possibly a special construction with two selector boxes. That depends on configuration. 01491 * 01492 * @param string The table name of the record 01493 * @param string The field name which this element is supposed to edit 01494 * @param array The record data array where the value(s) for the field can be found 01495 * @param array An array with additional configuration options. 01496 * @return string The HTML code for the TCEform field 01497 */ 01498 function getSingleField_typeSelect($table, $field, $row, &$PA) { 01499 global $TCA; 01500 01501 // Field configuration from TCA: 01502 $config = $PA['fieldConf']['config']; 01503 01504 $disabled = ''; 01505 if ($this->renderReadonly || $config['readOnly']) { 01506 $disabled = ' disabled="disabled"'; 01507 } 01508 01509 // "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist. See http://typo3.org/documentation/document-library/doc_core_api/Wizards_Configuratio/. 01510 $specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']); 01511 01512 // Getting the selector box items from the system 01513 $selItems = $this->addSelectOptionsToItemArray( 01514 $this->initItemArray($PA['fieldConf']), 01515 $PA['fieldConf'], 01516 $this->setTSconfig($table, $row), 01517 $field 01518 ); 01519 // Possibly filter some items: 01520 $keepItemsFunc = create_function('$value', 'return $value[1];'); 01521 $selItems = t3lib_div::keepItemsInArray($selItems, $PA['fieldTSConfig']['keepItems'], $keepItemsFunc); 01522 // Possibly add some items: 01523 $selItems = $this->addItems($selItems, $PA['fieldTSConfig']['addItems.']); 01524 // Process items by a user function: 01525 if (isset($config['itemsProcFunc']) && $config['itemsProcFunc']) { 01526 $selItems = $this->procItems($selItems, $PA['fieldTSConfig']['itemsProcFunc.'], $config, $table, $row, $field); 01527 } 01528 01529 // Possibly remove some items: 01530 $removeItems = t3lib_div::trimExplode(',', $PA['fieldTSConfig']['removeItems'], 1); 01531 foreach ($selItems as $tk => $p) { 01532 01533 // Checking languages and authMode: 01534 $languageDeny = $TCA[$table]['ctrl']['languageField'] && !strcmp($TCA[$table]['ctrl']['languageField'], $field) && !$GLOBALS['BE_USER']->checkLanguageAccess($p[1]); 01535 $authModeDeny = $config['form_type'] == 'select' && $config['authMode'] && !$GLOBALS['BE_USER']->checkAuthMode($table, $field, $p[1], $config['authMode']); 01536 if (in_array($p[1], $removeItems) || $languageDeny || $authModeDeny) { 01537 unset($selItems[$tk]); 01538 } elseif (isset($PA['fieldTSConfig']['altLabels.'][$p[1]])) { 01539 $selItems[$tk][0] = $this->sL($PA['fieldTSConfig']['altLabels.'][$p[1]]); 01540 } 01541 01542 // Removing doktypes with no access: 01543 if (($table === 'pages' || $table === 'pages_language_overlay') && $field === 'doktype') { 01544 if (!($GLOBALS['BE_USER']->isAdmin() || t3lib_div::inList($GLOBALS['BE_USER']->groupData['pagetypes_select'], $p[1]))) { 01545 unset($selItems[$tk]); 01546 } 01547 } 01548 } 01549 01550 // Creating the label for the "No Matching Value" entry. 01551 $nMV_label = isset($PA['fieldTSConfig']['noMatchingValue_label']) ? $this->sL($PA['fieldTSConfig']['noMatchingValue_label']) : '[ ' . $this->getLL('l_noMatchingValue') . ' ]'; 01552 01553 // Prepare some values: 01554 $maxitems = intval($config['maxitems']); 01555 01556 // If a SINGLE selector box... 01557 if ($maxitems <= 1 && $config['renderMode'] !== 'tree') { 01558 $item = $this->getSingleField_typeSelect_single($table, $field, $row, $PA, $config, $selItems, $nMV_label); 01559 } elseif (!strcmp($config['renderMode'], 'checkbox')) { // Checkbox renderMode 01560 $item = $this->getSingleField_typeSelect_checkbox($table, $field, $row, $PA, $config, $selItems, $nMV_label); 01561 } elseif (!strcmp($config['renderMode'], 'singlebox')) { // Single selector box renderMode 01562 $item = $this->getSingleField_typeSelect_singlebox($table, $field, $row, $PA, $config, $selItems, $nMV_label); 01563 } elseif (!strcmp($config['renderMode'], 'tree')) { // Tree renderMode 01564 $treeClass = t3lib_div::makeInstance('t3lib_TCEforms_Tree', $this); 01565 $item = $treeClass->renderField($table, $field, $row, $PA, $config, $selItems, $nMV_label); 01566 } else { // Traditional multiple selector box: 01567 $item = $this->getSingleField_typeSelect_multiple($table, $field, $row, $PA, $config, $selItems, $nMV_label); 01568 } 01569 01570 // Wizards: 01571 if (!$disabled) { 01572 $altItem = '<input type="hidden" name="' . $PA['itemFormElName'] . '" value="' . htmlspecialchars($PA['itemFormElValue']) . '" />'; 01573 $item = $this->renderWizards(array($item, $altItem), $config['wizards'], $table, $row, $field, $PA, $PA['itemFormElName'], $specConf); 01574 } 01575 01576 return $item; 01577 } 01578 01579 /** 01580 * Creates a single-selector box 01581 * (Render function for getSingleField_typeSelect()) 01582 * 01583 * @param string See getSingleField_typeSelect() 01584 * @param string See getSingleField_typeSelect() 01585 * @param array See getSingleField_typeSelect() 01586 * @param array See getSingleField_typeSelect() 01587 * @param array (Redundant) content of $PA['fieldConf']['config'] (for convenience) 01588 * @param array Items available for selection 01589 * @param string Label for no-matching-value 01590 * @return string The HTML code for the item 01591 * @see getSingleField_typeSelect() 01592 */ 01593 function getSingleField_typeSelect_single($table, $field, $row, &$PA, $config, $selItems, $nMV_label) { 01594 // check against inline uniqueness 01595 $inlineParent = $this->inline->getStructureLevel(-1); 01596 if (is_array($inlineParent) && $inlineParent['uid']) { 01597 if ($inlineParent['config']['foreign_table'] == $table && $inlineParent['config']['foreign_unique'] == $field) { 01598 $uniqueIds = $this->inline->inlineData['unique'][$this->inline->inlineNames['object'] . '[' . $table . ']']['used']; 01599 $PA['fieldChangeFunc']['inlineUnique'] = "inline.updateUnique(this,'" . $this->inline->inlineNames['object'] . '[' . $table . "]','" . $this->inline->inlineNames['form'] . "','" . $row['uid'] . "');"; 01600 } 01601 // hide uid of parent record for symmetric relations 01602 if ($inlineParent['config']['foreign_table'] == $table && ($inlineParent['config']['foreign_field'] == $field || $inlineParent['config']['symmetric_field'] == $field)) { 01603 $uniqueIds[] = $inlineParent['uid']; 01604 } 01605 } 01606 01607 // Initialization: 01608 $c = 0; 01609 $sI = 0; 01610 $noMatchingValue = 1; 01611 $opt = array(); 01612 $selicons = array(); 01613 $onlySelectedIconShown = 0; 01614 $size = intval($config['size']); 01615 $selectedStyle = ''; // Style set on <select/> 01616 01617 $disabled = ''; 01618 if ($this->renderReadonly || $config['readOnly']) { 01619 $disabled = ' disabled="disabled"'; 01620 $onlySelectedIconShown = 1; 01621 } 01622 01623 // Icon configuration: 01624 if ($config['suppress_icons'] == 'IF_VALUE_FALSE') { 01625 $suppressIcons = !$PA['itemFormElValue'] ? 1 : 0; 01626 } elseif ($config['suppress_icons'] == 'ONLY_SELECTED') { 01627 $suppressIcons = 0; 01628 $onlySelectedIconShown = 1; 01629 } elseif ($config['suppress_icons']) { 01630 $suppressIcons = 1; 01631 } else { 01632 $suppressIcons = 0; 01633 } 01634 01635 // Traverse the Array of selector box items: 01636 $optGroupStart = array(); 01637 $optGroupOpen = FALSE; 01638 $classesForSelectTag = array(); 01639 foreach ($selItems as $p) { 01640 $sM = (!strcmp($PA['itemFormElValue'], $p[1]) ? ' selected="selected"' : ''); 01641 if ($sM) { 01642 $sI = $c; 01643 $noMatchingValue = 0; 01644 } 01645 01646 // Getting style attribute value (for icons): 01647 if ($config['iconsInOptionTags']) { 01648 $styleAttrValue = $this->optionTagStyle($p[2]); 01649 if ($sM) { 01650 list($selectIconFile, $selectIconInfo) = $this->getIcon($p[2]); 01651 if (!empty($selectIconInfo)) { 01652 $selectedStyle = ' style="background-image:url(' . $selectIconFile . ');"'; 01653 $classesForSelectTag[] = 'typo3-TCEforms-select-selectedItemWithBackgroundImage'; 01654 } 01655 } 01656 } 01657 01658 // Compiling the <option> tag: 01659 if (!($p[1] != $PA['itemFormElValue'] && is_array($uniqueIds) && in_array($p[1], $uniqueIds))) { 01660 if (!strcmp($p[1], '--div--')) { 01661 $optGroupStart[0] = $p[0]; 01662 if ($config['iconsInOptionTags']) { 01663 $optGroupStart[1] = $this->optgroupTagStyle($p[2]); 01664 } else { 01665 $optGroupStart[1] = $styleAttrValue; 01666 } 01667 01668 } else { 01669 if (count($optGroupStart)) { 01670 if ($optGroupOpen) { // Closing last optgroup before next one starts 01671 $opt[] = '</optgroup>' . LF; 01672 } 01673 $opt[] = '<optgroup label="' . t3lib_div::deHSCentities(htmlspecialchars($optGroupStart[0])) . '"' . 01674 ($optGroupStart[1] ? ' style="' . htmlspecialchars($optGroupStart[1]) . '"' : '') . 01675 ' class="c-divider">' . LF; 01676 $optGroupOpen = TRUE; 01677 $c--; 01678 $optGroupStart = array(); 01679 } 01680 $opt[] = '<option value="' . htmlspecialchars($p[1]) . '"' . 01681 $sM . 01682 ($styleAttrValue ? ' style="' . htmlspecialchars($styleAttrValue) . '"' : '') . 01683 '>' . t3lib_div::deHSCentities(($p[0])) . '</option>' . LF; 01684 } 01685 } 01686 01687 // If there is an icon for the selector box (rendered in selicon-table below)...: 01688 // if there is an icon ($p[2]), icons should be shown, and, if only selected are visible, is it selected 01689 if ($p[2] && !$suppressIcons && (!$onlySelectedIconShown || $sM)) { 01690 list($selIconFile, $selIconInfo) = $this->getIcon($p[2]); 01691 if (!empty($selIconInfo)) { 01692 $iOnClick = $this->elName($PA['itemFormElName']) . '.selectedIndex=' . $c . '; ' . 01693 $this->elName($PA['itemFormElName']) . '.style.backgroundImage=' . $this->elName($PA['itemFormElName']) . '.options[' . $c . '].style.backgroundImage; ' . 01694 implode('', $PA['fieldChangeFunc']) . $this->blur() . 'return false;'; 01695 } else { 01696 $iOnClick = $this->elName($PA['itemFormElName']) . '.selectedIndex=' . $c . '; ' . 01697 $this->elName($PA['itemFormElName']) . '.className=' . $this->elName($PA['itemFormElName']) . '.options[' . $c . '].className; ' . 01698 implode('', $PA['fieldChangeFunc']) . $this->blur() . 'return false;'; 01699 } 01700 $selicons[] = array( 01701 (!$onlySelectedIconShown ? '<a href="#" onclick="' . htmlspecialchars($iOnClick) . '">' : '') . 01702 $this->getIconHtml($p[2], htmlspecialchars($p[0]), htmlspecialchars($p[0])) . 01703 (!$onlySelectedIconShown ? '</a>' : ''), 01704 $c, $sM); 01705 } 01706 $c++; 01707 } 01708 01709 if ($optGroupOpen) { // Closing optgroup if open 01710 $opt[] = '</optgroup>'; 01711 $optGroupOpen = false; 01712 } 01713 01714 // No-matching-value: 01715 if ($PA['itemFormElValue'] && $noMatchingValue && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) { 01716 $nMV_label = @sprintf($nMV_label, $PA['itemFormElValue']); 01717 $opt[] = '<option value="' . htmlspecialchars($PA['itemFormElValue']) . '" selected="selected">' . htmlspecialchars($nMV_label) . '</option>'; 01718 } 01719 01720 // Create item form fields: 01721 $sOnChange = 'if (this.options[this.selectedIndex].value==\'--div--\') {this.selectedIndex=' . $sI . ';} ' . implode('', $PA['fieldChangeFunc']); 01722 if (!$disabled) { 01723 $item .= '<input type="hidden" name="' . $PA['itemFormElName'] . '_selIconVal" value="' . htmlspecialchars($sI) . '" />'; // MUST be inserted before the selector - else is the value of the hiddenfield here mysteriously submitted... 01724 } 01725 if ($config['iconsInOptionTags']) { 01726 $classesForSelectTag[] = 'icon-select'; 01727 } 01728 $item .= '<select' . $selectedStyle . ' id="' . uniqid('tceforms-select-') . '" name="' . $PA['itemFormElName'] . '"' . 01729 $this->insertDefStyle('select', implode(' ', $classesForSelectTag)) . 01730 ($size ? ' size="' . $size . '"' : '') . 01731 ' onchange="' . htmlspecialchars($onChangeIcon . $sOnChange) . '"' . 01732 $PA['onFocus'] . $disabled . '>'; 01733 $item .= implode('', $opt); 01734 $item .= '</select>'; 01735 01736 // Create icon table: 01737 if (count($selicons) && !$config['noIconsBelowSelect']) { 01738 $item .= '<table border="0" cellpadding="0" cellspacing="0" class="typo3-TCEforms-selectIcons">'; 01739 $selicon_cols = intval($config['selicon_cols']); 01740 if (!$selicon_cols) { 01741 $selicon_cols = count($selicons); 01742 } 01743 $sR = ceil(count($selicons) / $selicon_cols); 01744 $selicons = array_pad($selicons, $sR * $selicon_cols, ''); 01745 for ($sa = 0; $sa < $sR; $sa++) { 01746 $item .= '<tr>'; 01747 for ($sb = 0; $sb < $selicon_cols; $sb++) { 01748 $sk = ($sa * $selicon_cols + $sb); 01749 $imgN = 'selIcon_' . $table . '_' . $row['uid'] . '_' . $field . '_' . $selicons[$sk][1]; 01750 $imgS = ($selicons[$sk][2] ? $this->backPath . 'gfx/content_selected.gif' : 'clear.gif'); 01751 $item .= '<td><img name="' . htmlspecialchars($imgN) . '" src="' . $imgS . '" width="7" height="10" alt="" /></td>'; 01752 $item .= '<td>' . $selicons[$sk][0] . '</td>'; 01753 } 01754 $item .= '</tr>'; 01755 } 01756 $item .= '</table>'; 01757 } 01758 01759 return $item; 01760 } 01761 01762 /** 01763 * Creates a checkbox list (renderMode = "checkbox") 01764 * (Render function for getSingleField_typeSelect()) 01765 * 01766 * @param string See getSingleField_typeSelect() 01767 * @param string See getSingleField_typeSelect() 01768 * @param array See getSingleField_typeSelect() 01769 * @param array See getSingleField_typeSelect() 01770 * @param array (Redundant) content of $PA['fieldConf']['config'] (for convenience) 01771 * @param array Items available for selection 01772 * @param string Label for no-matching-value 01773 * @return string The HTML code for the item 01774 * @see getSingleField_typeSelect() 01775 */ 01776 function getSingleField_typeSelect_checkbox( 01777 $table, $field, $row, &$PA, $config, $selItems, $nMV_label) { 01778 01779 if (empty($selItems)) { 01780 return ''; 01781 } 01782 01783 // Get values in an array (and make unique, which is fine because there can be no duplicates anyway): 01784 $itemArray = array_flip($this->extractValuesOnlyFromValueLabelList($PA['itemFormElValue'])); 01785 01786 $disabled = ''; 01787 if ($this->renderReadonly || $config['readOnly']) { 01788 $disabled = ' disabled="disabled"'; 01789 } 01790 01791 // Traverse the Array of selector box items: 01792 $tRows = array(); 01793 $c = 0; 01794 if (!$disabled) { 01795 $sOnChange = implode('', $PA['fieldChangeFunc']); 01796 $setAll = array(); // Used to accumulate the JS needed to restore the original selection. 01797 $unSetAll = array(); 01798 foreach ($selItems as $p) { 01799 // Non-selectable element: 01800 if (!strcmp($p[1], '--div--')) { 01801 $tRows[] = ' 01802 <tr class="c-header"> 01803 <td colspan="3">' . htmlspecialchars($p[0]) . '</td> 01804 </tr>'; 01805 } else { 01806 // Selected or not by default: 01807 $sM = ''; 01808 if (isset($itemArray[$p[1]])) { 01809 $sM = ' checked="checked"'; 01810 unset($itemArray[$p[1]]); 01811 } 01812 01813 // Icon: 01814 if ($p[2]) { 01815 $selIcon = $p[2]; 01816 } else { 01817 $selIcon = t3lib_iconWorks::getSpriteIcon('empty-empty'); 01818 } 01819 01820 // Compile row: 01821 $rowId = uniqid('select_checkbox_row_'); 01822 $onClickCell = $this->elName($PA['itemFormElName'] . '[' . $c . ']') . '.checked=!' . $this->elName($PA['itemFormElName'] . '[' . $c . ']') . '.checked;'; 01823 $onClick = 'this.attributes.getNamedItem("class").nodeValue = ' . $this->elName($PA['itemFormElName'] . '[' . $c . ']') . '.checked ? "c-selectedItem" : "c-unselectedItem";'; 01824 $setAll[] = $this->elName($PA['itemFormElName'] . '[' . $c . ']') . '.checked=1;'; 01825 $setAll[] .= '$(\'' . $rowId . '\').removeClassName(\'c-unselectedItem\');$(\'' . $rowId . '\').addClassName(\'c-selectedItem\');'; 01826 $unSetAll[] = $this->elName($PA['itemFormElName'] . '[' . $c . ']') . '.checked=0;'; 01827 $unSetAll[] .= '$(\'' . $rowId . '\').removeClassName(\'c-selectedItem\');$(\'' . $rowId . '\').addClassName(\'c-unselectedItem\');'; 01828 $restoreCmd[] = $this->elName($PA['itemFormElName'] . '[' . $c . ']') . '.checked=' . ($sM ? 1 : 0) . ';' . 01829 '$(\'' . $rowId . '\').removeClassName(\'c-selectedItem\');$(\'' . $rowId . '\').removeClassName(\'c-unselectedItem\');' . 01830 '$(\'' . $rowId . '\').addClassName(\'c-' . ($sM ? '' : 'un') . 'selectedItem\');'; 01831 01832 // Check if some help text is available 01833 // Since TYPO3 4.5 help text is expected to be an associative array 01834 // with two key, "title" and "description" 01835 // For the sake of backwards compatibility, we test if the help text 01836 // is a string and use it as a description (this could happen if items 01837 // are modified with an itemProcFunc) 01838 $hasHelp = FALSE; 01839 $help = ''; 01840 $helpArray = array(); 01841 if ((is_array($p[3]) && count($p[3]) > 0) || !empty($p[3])) { 01842 $hasHelp = TRUE; 01843 if (is_array($p[3])) { 01844 $helpArray = $p[3]; 01845 } else { 01846 $helpArray['description'] = $p[3]; 01847 } 01848 } 01849 01850 $label = t3lib_div::deHSCentities(htmlspecialchars($p[0])); 01851 if ($hasHelp) { 01852 $help = t3lib_BEfunc::wrapInHelp('', '', '', $helpArray); 01853 } 01854 01855 $tRows[] = ' 01856 <tr id="' . $rowId . '" class="' . ($sM ? 'c-selectedItem' : 'c-unselectedItem') . '" onclick="' . htmlspecialchars($onClick) . '" style="cursor: pointer;"> 01857 <td class="c-checkbox"><input type="checkbox"' . $this->insertDefStyle('check') . ' name="' . htmlspecialchars($PA['itemFormElName'] . '[' . $c . ']') . '" value="' . htmlspecialchars($p[1]) . '"' . $sM . ' onclick="' . htmlspecialchars($sOnChange) . '"' . $PA['onFocus'] . ' /></td> 01858 <td class="c-labelCell" onclick="' . htmlspecialchars($onClickCell) . '">' . 01859 $this->getIconHtml($selIcon) . 01860 $label . 01861 '</td> 01862 <td class="c-descr" onclick="' . htmlspecialchars($onClickCell) . '">' . ((empty($help)) ? '' : $help) . '</td> 01863 </tr>'; 01864 $c++; 01865 } 01866 } 01867 } 01868 01869 // Remaining values (invalid): 01870 if (count($itemArray) && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) { 01871 foreach ($itemArray as $theNoMatchValue => $temp) { 01872 // Compile <checkboxes> tag: 01873 array_unshift($tRows, ' 01874 <tr class="c-invalidItem"> 01875 <td class="c-checkbox"><input type="checkbox"' . $this->insertDefStyle('check') . ' name="' . htmlspecialchars($PA['itemFormElName'] . '[' . $c . ']') . '" value="' . htmlspecialchars($theNoMatchValue) . '" checked="checked" onclick="' . htmlspecialchars($sOnChange) . '"' . $PA['onFocus'] . $disabled . ' /></td> 01876 <td class="c-labelCell">' . 01877 t3lib_div::deHSCentities(htmlspecialchars(@sprintf($nMV_label, $theNoMatchValue))) . 01878 '</td><td> </td> 01879 </tr>'); 01880 $c++; 01881 } 01882 } 01883 01884 // Add an empty hidden field which will send a blank value if all items are unselected. 01885 $item .= '<input type="hidden" name="' . htmlspecialchars($PA['itemFormElName']) . '" value="" />'; 01886 01887 // Remaining checkboxes will get their set-all link: 01888 if (count($setAll)) { 01889 $tableHead = '<thead> 01890 <tr class="c-header-checkbox-controls t3-row-header"> 01891 <td class="c-checkbox"> 01892 <input type="checkbox" class="checkbox" onclick="if (checked) {' . htmlspecialchars(implode('', $setAll) . '} else {' . implode('', $unSetAll) . '}') . '"> 01893 </td> 01894 <td colspan="2"> 01895 </td> 01896 </tr></thead>'; 01897 } 01898 // Implode rows in table: 01899 $item .= ' 01900 <table border="0" cellpadding="0" cellspacing="0" class="typo3-TCEforms-select-checkbox">' . 01901 $tableHead . 01902 '<tbody>' . implode('', $tRows) . '</tbody> 01903 </table> 01904 '; 01905 01906 // Add revert icon 01907 if (is_array($restoreCmd)) { 01908 $item .= '<a href="#" onclick="' . implode('', $restoreCmd) . ' return false;' . '">' . 01909 t3lib_iconWorks::getSpriteIcon('actions-edit-undo', array('title' => htmlspecialchars($this->getLL('l_revertSelection')))) . '</a>'; 01910 } 01911 01912 return $item; 01913 } 01914 01915 /** 01916 * Creates a selectorbox list (renderMode = "singlebox") 01917 * (Render function for getSingleField_typeSelect()) 01918 * 01919 * @param string See getSingleField_typeSelect() 01920 * @param string See getSingleField_typeSelect() 01921 * @param array See getSingleField_typeSelect() 01922 * @param array See getSingleField_typeSelect() 01923 * @param array (Redundant) content of $PA['fieldConf']['config'] (for convenience) 01924 * @param array Items available for selection 01925 * @param string Label for no-matching-value 01926 * @return string The HTML code for the item 01927 * @see getSingleField_typeSelect() 01928 */ 01929 function getSingleField_typeSelect_singlebox($table, $field, $row, &$PA, $config, $selItems, $nMV_label) { 01930 01931 // Get values in an array (and make unique, which is fine because there can be no duplicates anyway): 01932 $itemArray = array_flip($this->extractValuesOnlyFromValueLabelList($PA['itemFormElValue'])); 01933 01934 $disabled = ''; 01935 if ($this->renderReadonly || $config['readOnly']) { 01936 $disabled = ' disabled="disabled"'; 01937 } 01938 01939 // Traverse the Array of selector box items: 01940 $opt = array(); 01941 $restoreCmd = array(); // Used to accumulate the JS needed to restore the original selection. 01942 $c = 0; 01943 foreach ($selItems as $p) { 01944 // Selected or not by default: 01945 $sM = ''; 01946 if (isset($itemArray[$p[1]])) { 01947 $sM = ' selected="selected"'; 01948 $restoreCmd[] = $this->elName($PA['itemFormElName'] . '[]') . '.options[' . $c . '].selected=1;'; 01949 unset($itemArray[$p[1]]); 01950 } 01951 01952 // Non-selectable element: 01953 $nonSel = ''; 01954 if (!strcmp($p[1], '--div--')) { 01955 $nonSel = ' onclick="this.selected=0;" class="c-divider"'; 01956 } 01957 01958 // Icon style for option tag: 01959 if ($config['iconsInOptionTags']) { 01960 $styleAttrValue = $this->optionTagStyle($p[2]); 01961 } 01962 01963 // Compile <option> tag: 01964 $opt[] = '<option value="' . htmlspecialchars($p[1]) . '"' . 01965 $sM . 01966 $nonSel . 01967 ($styleAttrValue ? ' style="' . htmlspecialchars($styleAttrValue) . '"' : '') . 01968 '>' . t3lib_div::deHSCentities(htmlspecialchars($p[0])) . '</option>'; 01969 $c++; 01970 } 01971 01972 // Remaining values: 01973 if (count($itemArray) && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) { 01974 foreach ($itemArray as $theNoMatchValue => $temp) { 01975 // Compile <option> tag: 01976 array_unshift($opt, '<option value="' . htmlspecialchars($theNoMatchValue) . '" selected="selected">' . t3lib_div::deHSCentities(htmlspecialchars(@sprintf($nMV_label, $theNoMatchValue))) . '</option>'); 01977 } 01978 } 01979 01980 // Compile selector box: 01981 $sOnChange = implode('', $PA['fieldChangeFunc']); 01982 $selector_itemListStyle = isset($config['itemListStyle']) ? ' style="' . htmlspecialchars($config['itemListStyle']) . '"' : ' style="' . $this->defaultMultipleSelectorStyle . '"'; 01983 $size = intval($config['size']); 01984 $cssPrefix = ($size === 1) ? 'tceforms-select' : 'tceforms-multiselect'; 01985 $size = $config['autoSizeMax'] ? t3lib_div::intInRange(count($selItems) + 1, t3lib_div::intInRange($size, 1), $config['autoSizeMax']) : $size; 01986 $selectBox = '<select id="' . uniqid($cssPrefix) . '" name="' . $PA['itemFormElName'] . '[]"' . 01987 $this->insertDefStyle('select', $cssPrefix) . 01988 ($size ? ' size="' . $size . '"' : '') . 01989 ' multiple="multiple" onchange="' . htmlspecialchars($sOnChange) . '"' . 01990 $PA['onFocus'] . 01991 $selector_itemListStyle . 01992 $disabled . '> 01993 ' . 01994 implode(' 01995 ', $opt) . ' 01996 </select>'; 01997 01998 // Add an empty hidden field which will send a blank value if all items are unselected. 01999 if (!$disabled) { 02000 $item .= '<input type="hidden" name="' . htmlspecialchars($PA['itemFormElName']) . '" value="" />'; 02001 } 02002 02003 // Put it all into a table: 02004 $item .= ' 02005 <table border="0" cellspacing="0" cellpadding="0" width="1" class="typo3-TCEforms-select-singlebox"> 02006 <tr> 02007 <td> 02008 ' . $selectBox . ' 02009 <br/> 02010 <em>' . 02011 htmlspecialchars($this->getLL('l_holdDownCTRL')) . 02012 '</em> 02013 </td> 02014 <td valign="top"> 02015 <a href="#" onclick="' . htmlspecialchars($this->elName($PA['itemFormElName'] . '[]') . '.selectedIndex=-1;' . implode('', $restoreCmd) . ' return false;') . '" title="' . htmlspecialchars($this->getLL('l_revertSelection')) . '">' . 02016 t3lib_iconWorks::getSpriteIcon('actions-edit-undo') . 02017 '</a> 02018 </td> 02019 </tr> 02020 </table> 02021 '; 02022 02023 return $item; 02024 } 02025 02026 /** 02027 * Creates a multiple-selector box (two boxes, side-by-side) 02028 * (Render function for getSingleField_typeSelect()) 02029 * 02030 * @param string See getSingleField_typeSelect() 02031 * @param string See getSingleField_typeSelect() 02032 * @param array See getSingleField_typeSelect() 02033 * @param array See getSingleField_typeSelect() 02034 * @param array (Redundant) content of $PA['fieldConf']['config'] (for convenience) 02035 * @param array Items available for selection 02036 * @param string Label for no-matching-value 02037 * @return string The HTML code for the item 02038 * @see getSingleField_typeSelect() 02039 */ 02040 function getSingleField_typeSelect_multiple($table, $field, $row, &$PA, $config, $selItems, $nMV_label) { 02041 02042 $disabled = ''; 02043 if ($this->renderReadonly || $config['readOnly']) { 02044 $disabled = ' disabled="disabled"'; 02045 } 02046 02047 // Setting this hidden field (as a flag that JavaScript can read out) 02048 if (!$disabled) { 02049 $item .= '<input type="hidden" name="' . $PA['itemFormElName'] . '_mul" value="' . ($config['multiple'] ? 1 : 0) . '" />'; 02050 } 02051 02052 // Set max and min items: 02053 $maxitems = t3lib_div::intInRange($config['maxitems'], 0); 02054 if (!$maxitems) { 02055 $maxitems = 100000; 02056 } 02057 $minitems = t3lib_div::intInRange($config['minitems'], 0); 02058 02059 // Register the required number of elements: 02060 $this->registerRequiredProperty('range', $PA['itemFormElName'], array($minitems, $maxitems, 'imgName' => $table . '_' . $row['uid'] . '_' . $field)); 02061 02062 // Get "removeItems": 02063 $removeItems = t3lib_div::trimExplode(',', $PA['fieldTSConfig']['removeItems'], 1); 02064 02065 // Get the array with selected items: 02066 $itemArray = t3lib_div::trimExplode(',', $PA['itemFormElValue'], 1); 02067 02068 // Possibly filter some items: 02069 $keepItemsFunc = create_function('$value', '$parts=explode(\'|\',$value,2); return rawurldecode($parts[0]);'); 02070 $itemArray = t3lib_div::keepItemsInArray($itemArray, $PA['fieldTSConfig']['keepItems'], $keepItemsFunc); 02071 02072 // Perform modification of the selected items array: 02073 foreach ($itemArray as $tk => $tv) { 02074 $tvP = explode('|', $tv, 2); 02075 $evalValue = $tvP[0]; 02076 $isRemoved = in_array($evalValue, $removeItems) || ($config['form_type'] == 'select' && $config['authMode'] && !$GLOBALS['BE_USER']->checkAuthMode($table, $field, $evalValue, $config['authMode'])); 02077 if ($isRemoved && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) { 02078 $tvP[1] = rawurlencode(@sprintf($nMV_label, $evalValue)); 02079 } elseif (isset($PA['fieldTSConfig']['altLabels.'][$evalValue])) { 02080 $tvP[1] = rawurlencode($this->sL($PA['fieldTSConfig']['altLabels.'][$evalValue])); 02081 } 02082 if ($tvP[1] == '') { 02083 // Case: flexform, default values supplied, no label provided (bug #9795) 02084 foreach ($selItems as $selItem) { 02085 if ($selItem[1] == $tvP[0]) { 02086 $tvP[1] = html_entity_decode($selItem[0]); 02087 break; 02088 } 02089 } 02090 } 02091 $itemArray[$tk] = implode('|', $tvP); 02092 } 02093 $itemsToSelect = ''; 02094 02095 if (!$disabled) { 02096 // Create option tags: 02097 $opt = array(); 02098 $styleAttrValue = ''; 02099 foreach ($selItems as $p) { 02100 if ($config['iconsInOptionTags']) { 02101 $styleAttrValue = $this->optionTagStyle($p[2]); 02102 } 02103 $opt[] = '<option value="' . htmlspecialchars($p[1]) . '"' . 02104 ($styleAttrValue ? ' style="' . htmlspecialchars($styleAttrValue) . '"' : '') . 02105 '>' . $p[0] . '</option>'; 02106 } 02107 02108 // Put together the selector box: 02109 $selector_itemListStyle = isset($config['itemListStyle']) ? ' style="' . htmlspecialchars($config['itemListStyle']) . '"' : ' style="' . $this->defaultMultipleSelectorStyle . '"'; 02110 $size = intval($config['size']); 02111 $size = $config['autoSizeMax'] ? t3lib_div::intInRange(count($itemArray) + 1, t3lib_div::intInRange($size, 1), $config['autoSizeMax']) : $size; 02112 if ($config['exclusiveKeys']) { 02113 $sOnChange = 'setFormValueFromBrowseWin(\'' . $PA['itemFormElName'] . '\',this.options[this.selectedIndex].value,this.options[this.selectedIndex].text,\'' . $config['exclusiveKeys'] . '\'); '; 02114 } else { 02115 $sOnChange = 'setFormValueFromBrowseWin(\'' . $PA['itemFormElName'] . '\',this.options[this.selectedIndex].value,this.options[this.selectedIndex].text); '; 02116 } 02117 $sOnChange .= implode('', $PA['fieldChangeFunc']); 02118 $itemsToSelect = ' 02119 <select id="' . uniqid('tceforms-multiselect-') . '" name="' . $PA['itemFormElName'] . '_sel"' . 02120 $this->insertDefStyle('select', 'tceforms-multiselect tceforms-itemstoselect') . 02121 ($size ? ' size="' . $size . '"' : '') . 02122 ' onchange="' . htmlspecialchars($sOnChange) . '"' . 02123 $PA['onFocus'] . 02124 $selector_itemListStyle . '> 02125 ' . implode(' 02126 ', $opt) . ' 02127 </select>'; 02128 } 02129 02130 // Pass to "dbFileIcons" function: 02131 $params = array( 02132 'size' => $size, 02133 'autoSizeMax' => t3lib_div::intInRange($config['autoSizeMax'], 0), 02134 'style' => isset($config['selectedListStyle']) ? ' style="' . htmlspecialchars($config['selectedListStyle']) . '"' : ' style="' . $this->defaultMultipleSelectorStyle . '"', 02135 'dontShowMoveIcons' => ($maxitems <= 1), 02136 'maxitems' => $maxitems, 02137 'info' => '', 02138 'headers' => array( 02139 'selector' => $this->getLL('l_selected') . ':<br />', 02140 'items' => $this->getLL('l_items') . ':<br />' 02141 ), 02142 'noBrowser' => 1, 02143 'thumbnails' => $itemsToSelect, 02144 'readOnly' => $disabled 02145 ); 02146 $item .= $this->dbFileIcons($PA['itemFormElName'], '', '', $itemArray, '', $params, $PA['onFocus']); 02147 02148 return $item; 02149 } 02150 02151 /** 02152 * Generation of TCEform elements of the type "group" 02153 * This will render a selectorbox into which elements from either the file system or database can be inserted. Relations. 02154 * 02155 * @param string The table name of the record 02156 * @param string The field name which this element is supposed to edit 02157 * @param array The record data array where the value(s) for the field can be found 02158 * @param array An array with additional configuration options. 02159 * @return string The HTML code for the TCEform field 02160 */ 02161 function getSingleField_typeGroup($table, $field, $row, &$PA) { 02162 // Init: 02163 $config = $PA['fieldConf']['config']; 02164 $internal_type = $config['internal_type']; 02165 $show_thumbs = $config['show_thumbs']; 02166 $size = intval($config['size']); 02167 $maxitems = t3lib_div::intInRange($config['maxitems'], 0); 02168 if (!$maxitems) { 02169 $maxitems = 100000; 02170 } 02171 $minitems = t3lib_div::intInRange($config['minitems'], 0); 02172 $allowed = trim($config['allowed']); 02173 $disallowed = trim($config['disallowed']); 02174 02175 $disabled = ''; 02176 if ($this->renderReadonly || $config['readOnly']) { 02177 $disabled = ' disabled="disabled"'; 02178 } 02179 02180 $item .= '<input type="hidden" name="' . $PA['itemFormElName'] . '_mul" value="' . ($config['multiple'] ? 1 : 0) . '"' . $disabled . ' />'; 02181 $this->registerRequiredProperty('range', $PA['itemFormElName'], array($minitems, $maxitems, 'imgName' => $table . '_' . $row['uid'] . '_' . $field)); 02182 $info = ''; 02183 02184 // "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist. See http://typo3.org/documentation/document-library/doc_core_api/Wizards_Configuratio/. 02185 $specConf = $this->getSpecConfFromString($PA['extra'], $PA['fieldConf']['defaultExtras']); 02186 02187 // Acting according to either "file" or "db" type: 02188 switch ((string) $config['internal_type']) { 02189 case 'file_reference': 02190 $config['uploadfolder'] = ''; 02191 // Fall through 02192 case 'file': // If the element is of the internal type "file": 02193 02194 // Creating string showing allowed types: 02195 $tempFT = t3lib_div::trimExplode(',', $allowed, 1); 02196 if (!count($tempFT)) { 02197 $info .= '*'; 02198 } 02199 foreach ($tempFT as $ext) { 02200 if ($ext) { 02201 $info .= strtoupper($ext) . ' '; 02202 } 02203 } 02204 // Creating string, showing disallowed types: 02205 $tempFT_dis = t3lib_div::trimExplode(',', $disallowed, 1); 02206 if (count($tempFT_dis)) { 02207 $info .= '<br />'; 02208 } 02209 foreach ($tempFT_dis as $ext) { 02210 if ($ext) { 02211 $info .= '-' . strtoupper($ext) . ' '; 02212 } 02213 } 02214 02215 // Making the array of file items: 02216 $itemArray = t3lib_div::trimExplode(',', $PA['itemFormElValue'], 1); 02217 02218 // Showing thumbnails: 02219 $thumbsnail = ''; 02220 if ($show_thumbs) { 02221 $imgs = array(); 02222 foreach ($itemArray as $imgRead) { 02223 $imgP = explode('|', $imgRead); 02224 $imgPath = rawurldecode($imgP[0]); 02225 02226 $rowCopy = array(); 02227 $rowCopy[$field] = $imgPath; 02228 02229 $imgs[] = '<span class="nobr">' . t3lib_BEfunc::thumbCode($rowCopy, $table, $field, $this->backPath, 'thumbs.php', $config['uploadfolder'], 0, ' align="middle"') . 02230 $imgPath . 02231 '</span>'; 02232 } 02233 $thumbsnail = implode('<br />', $imgs); 02234 } 02235 02236 // Creating the element: 02237 $noList = isset($config['disable_controls']) && t3lib_div::inList($config['disable_controls'], 'list'); 02238 $params = array( 02239 'size' => $size, 02240 'dontShowMoveIcons' => ($maxitems <= 1), 02241 'autoSizeMax' => t3lib_div::intInRange($config['autoSizeMax'], 0), 02242 'maxitems' => $maxitems, 02243 'style' => isset($config['selectedListStyle']) ? ' style="' . htmlspecialchars($config['selectedListStyle']) . '"' : ' style="' . $this->defaultMultipleSelectorStyle . '"', 02244 'info' => $info, 02245 'thumbnails' => $thumbsnail, 02246 'readOnly' => $disabled, 02247 'noBrowser' => $noList || (isset($config['disable_controls']) && t3lib_div::inList($config['disable_controls'], 'browser')), 02248 'noList' => $noList, 02249 ); 02250 $item .= $this->dbFileIcons($PA['itemFormElName'], 'file', implode(',', $tempFT), $itemArray, '', $params, $PA['onFocus']); 02251 02252 if (!$disabled && !(isset($config['disable_controls']) && t3lib_div::inList($config['disable_controls'], 'upload'))) { 02253 // Adding the upload field: 02254 if ($this->edit_docModuleUpload && $config['uploadfolder']) { 02255 $item .= '<input type="file" name="' . $PA['itemFormElName_file'] . '" size="35" onchange="' . implode('', $PA['fieldChangeFunc']) . '" />'; 02256 } 02257 } 02258 break; 02259 case 'folder': // If the element is of the internal type "folder": 02260 02261 // array of folder items: 02262 $itemArray = t3lib_div::trimExplode(',', $PA['itemFormElValue'], 1); 02263 02264 // Creating the element: 02265 $noList = isset($config['disable_controls']) && t3lib_div::inList($config['disable_controls'], 'list'); 02266 $params = array( 02267 'size' => $size, 02268 'dontShowMoveIcons' => ($maxitems <= 1), 02269 'autoSizeMax' => t3lib_div::intInRange($config['autoSizeMax'], 0), 02270 'maxitems' => $maxitems, 02271 'style' => isset($config['selectedListStyle']) ? 02272 ' style="' . htmlspecialchars($config['selectedListStyle']) . '"' 02273 : ' style="' . $this->defaultMultipleSelectorStyle . '"', 02274 'info' => $info, 02275 'readOnly' => $disabled, 02276 'noBrowser' => $noList || (isset($config['disable_controls']) && t3lib_div::inList($config['disable_controls'], 'browser')), 02277 'noList' => $noList, 02278 ); 02279 02280 $item .= $this->dbFileIcons( 02281 $PA['itemFormElName'], 02282 'folder', 02283 '', 02284 $itemArray, 02285 '', 02286 $params, 02287 $PA['onFocus'] 02288 ); 02289 break; 02290 case 'db': // If the element is of the internal type "db": 02291 02292 // Creating string showing allowed types: 02293 $tempFT = t3lib_div::trimExplode(',', $allowed, TRUE); 02294 if (!strcmp(trim($tempFT[0]), '*')) { 02295 $onlySingleTableAllowed = false; 02296 $info .= '<span class="nobr">' . 02297 htmlspecialchars($this->getLL('l_allTables')) . 02298 '</span><br />'; 02299 } elseif ($tempFT) { 02300 $onlySingleTableAllowed = (count($tempFT) == 1); 02301 foreach ($tempFT as $theT) { 02302 $info .= '<span class="nobr">' . 02303 t3lib_iconWorks::getSpriteIconForRecord($theT, array()) . 02304 htmlspecialchars($this->sL($GLOBALS['TCA'][$theT]['ctrl']['title'])) . 02305 '</span><br />'; 02306 } 02307 } 02308 02309 $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1); 02310 $itemArray = array(); 02311 $imgs = array(); 02312 02313 // Thumbnails: 02314 $temp_itemArray = t3lib_div::trimExplode(',', $PA['itemFormElValue'], 1); 02315 foreach ($temp_itemArray as $dbRead) { 02316 $recordParts = explode('|', $dbRead); 02317 list($this_table, $this_uid) = t3lib_BEfunc::splitTable_Uid($recordParts[0]); 02318 // For the case that no table was found and only a single table is defined to be allowed, use that one: 02319 if (!$this_table && $onlySingleTableAllowed) { 02320 $this_table = $allowed; 02321 } 02322 $itemArray[] = array('table' => $this_table, 'id' => $this_uid); 02323 if (!$disabled && $show_thumbs) { 02324 $rr = t3lib_BEfunc::getRecordWSOL($this_table, $this_uid); 02325 $imgs[] = '<span class="nobr">' . 02326 $this->getClickMenu( 02327 t3lib_iconWorks::getSpriteIconForRecord( 02328 $this_table, 02329 $rr, 02330 array( 02331 'style' => 'vertical-align:top', 02332 'title' => htmlspecialchars(t3lib_BEfunc::getRecordPath($rr['pid'], $perms_clause, 15) . ' [UID: ' . $rr['uid'] . ']') 02333 ) 02334 ), 02335 $this_table, 02336 $this_uid 02337 ) . 02338 ' ' . 02339 t3lib_BEfunc::getRecordTitle($this_table, $rr, TRUE) . ' <span class="typo3-dimmed"><em>[' . $rr['uid'] . ']</em></span>' . 02340 '</span>'; 02341 } 02342 } 02343 $thumbsnail = ''; 02344 if (!$disabled && $show_thumbs) { 02345 $thumbsnail = implode('<br />', $imgs); 02346 } 02347 02348 // Creating the element: 02349 $noList = isset($config['disable_controls']) && t3lib_div::inList($config['disable_controls'], 'list'); 02350 $params = array( 02351 'size' => $size, 02352 'dontShowMoveIcons' => ($maxitems <= 1), 02353 'autoSizeMax' => t3lib_div::intInRange($config['autoSizeMax'], 0), 02354 'maxitems' => $maxitems, 02355 'style' => isset($config['selectedListStyle']) ? ' style="' . htmlspecialchars($config['selectedListStyle']) . '"' : ' style="' . $this->defaultMultipleSelectorStyle . '"', 02356 'info' => $info, 02357 'thumbnails' => $thumbsnail, 02358 'readOnly' => $disabled, 02359 'noBrowser' => $noList || (isset($config['disable_controls']) && t3lib_div::inList($config['disable_controls'], 'browser')), 02360 'noList' => $noList, 02361 ); 02362 $item .= $this->dbFileIcons($PA['itemFormElName'], 'db', implode(',', $tempFT), $itemArray, '', $params, $PA['onFocus'], $table, $field, $row['uid']); 02363 02364 break; 02365 } 02366 02367 // Wizards: 02368 $altItem = '<input type="hidden" name="' . $PA['itemFormElName'] . '" value="' . htmlspecialchars($PA['itemFormElValue']) . '" />'; 02369 if (!$disabled) { 02370 $item = $this->renderWizards(array($item, $altItem), $config['wizards'], $table, $row, $field, $PA, $PA['itemFormElName'], $specConf); 02371 } 02372 02373 return $item; 02374 } 02375 02376 /** 02377 * Generation of TCEform elements of the type "none" 02378 * This will render a non-editable display of the content of the field. 02379 * 02380 * @param string The table name of the record 02381 * @param string The field name which this element is supposed to edit 02382 * @param array The record data array where the value(s) for the field can be found 02383 * @param array An array with additional configuration options. 02384 * @return string The HTML code for the TCEform field 02385 */ 02386 function getSingleField_typeNone($table, $field, $row, &$PA) { 02387 // Init: 02388 $config = $PA['fieldConf']['config']; 02389 $itemValue = $PA['itemFormElValue']; 02390 02391 return $this->getSingleField_typeNone_render($config, $itemValue); 02392 } 02393 02394 /** 02395 * HTML rendering of a value which is not editable. 02396 * 02397 * @param array Configuration for the display 02398 * @param string The value to display 02399 * @return string The HTML code for the display 02400 * @see getSingleField_typeNone(); 02401 */ 02402 function getSingleField_typeNone_render($config, $itemValue) { 02403 02404 // is colorScheme[0] the right value? 02405 $divStyle = 'border:solid 1px ' . t3lib_div::modifyHTMLColorAll($this->colorScheme[0], -30) . ';' . $this->defStyle . $this->formElStyle('none') . ' background-color: ' . $this->colorScheme[0] . '; padding-left:1px;color:#555;'; 02406 02407 if ($config['format']) { 02408 $itemValue = $this->formatValue($config, $itemValue); 02409 } 02410 02411 $rows = intval($config['rows']); 02412 if ($rows > 1) { 02413 if (!$config['pass_content']) { 02414 $itemValue = nl2br(htmlspecialchars($itemValue)); 02415 } 02416 // like textarea 02417 $cols = t3lib_div::intInRange($config['cols'] ? $config['cols'] : 30, 5, $this->maxTextareaWidth); 02418 if (!$config['fixedRows']) { 02419 $origRows = $rows = t3lib_div::intInRange($rows, 1, 20); 02420 if (strlen($itemValue) > $this->charsPerRow * 2) { 02421 $cols = $this->maxTextareaWidth; 02422 $rows = t3lib_div::intInRange(round(strlen($itemValue) / $this->charsPerRow), count(explode(LF, $itemValue)), 20); 02423 if ($rows < $origRows) { 02424 $rows = $origRows; 02425 } 02426 } 02427 } 02428 02429 if ($this->docLarge) { 02430 $cols = round($cols * $this->form_largeComp); 02431 } 02432 $width = ceil($cols * $this->form_rowsToStylewidth); 02433 // hardcoded: 12 is the height of the font 02434 $height = $rows * 12; 02435 02436 $item = ' 02437 <div style="' . htmlspecialchars($divStyle . ' overflow:auto; height:' . $height . 'px; width:' . $width . 'px;') . '" class="' . htmlspecialchars($this->formElClass('none')) . '">' . 02438 $itemValue . 02439 '</div>'; 02440 } else { 02441 if (!$config['pass_content']) { 02442 $itemValue = htmlspecialchars($itemValue); 02443 } 02444 02445 $cols = $config['cols'] ? $config['cols'] : ($config['size'] ? $config['size'] : $this->maxInputWidth); 02446 if ($this->docLarge) { 02447 $cols = round($cols * $this->form_largeComp); 02448 } 02449 $width = ceil($cols * $this->form_rowsToStylewidth); 02450 02451 // overflow:auto crashes mozilla here. Title tag is usefull when text is longer than the div box (overflow:hidden). 02452 $item = ' 02453 <div style="' . htmlspecialchars($divStyle . ' overflow:hidden; width:' . $width . 'px;') . '" class="' . htmlspecialchars($this->formElClass('none')) . '" title="' . $itemValue . '">' . 02454 '<span class="nobr">' . (strcmp($itemValue, '') ? $itemValue : ' ') . '</span>' . 02455 '</div>'; 02456 } 02457 02458 return $item; 02459 } 02460 02461 /** 02462 * Handler for Flex Forms 02463 * 02464 * @param string The table name of the record 02465 * @param string The field name which this element is supposed to edit 02466 * @param array The record data array where the value(s) for the field can be found 02467 * @param array An array with additional configuration options. 02468 * @return string The HTML code for the TCEform field 02469 */ 02470 function getSingleField_typeFlex($table, $field, $row, &$PA) { 02471 02472 // Data Structure: 02473 $dataStructArray = t3lib_BEfunc::getFlexFormDS($PA['fieldConf']['config'], $row, $table); 02474 02475 // Manipulate Flexform DS via TSConfig and group access lists 02476 if (is_array($dataStructArray)) { 02477 $flexFormHelper = t3lib_div::makeInstance('t3lib_TCEforms_Flexforms'); 02478 $dataStructArray = $flexFormHelper->modifyFlexFormDS($dataStructArray, $table, $field, $row, $PA['fieldConf']['config']); 02479 unset($flexFormHelper); 02480 } 02481 02482 // Get data structure: 02483 if (is_array($dataStructArray)) { 02484 02485 // Get data: 02486 $xmlData = $PA['itemFormElValue']; 02487 $xmlHeaderAttributes = t3lib_div::xmlGetHeaderAttribs($xmlData); 02488 $storeInCharset = strtolower($xmlHeaderAttributes['encoding']); 02489 if ($storeInCharset) { 02490 $currentCharset = $GLOBALS['LANG']->charSet; 02491 $xmlData = $GLOBALS['LANG']->csConvObj->conv($xmlData, $storeInCharset, $currentCharset, 1); 02492 } 02493 $editData = t3lib_div::xml2array($xmlData); 02494 if (!is_array($editData)) { // Must be XML parsing error... 02495 $editData = array(); 02496 } elseif (!isset($editData['meta']) || !is_array($editData['meta'])) { 02497 $editData['meta'] = array(); 02498 } 02499 02500 // Find the data structure if sheets are found: 02501 $sheet = $editData['meta']['currentSheetId'] ? $editData['meta']['currentSheetId'] : 'sDEF'; // Sheet to display 02502 02503 // Create sheet menu: 02504 //TODO; Why is this commented out? 02505 // if (is_array($dataStructArray['sheets'])) { 02506 // #$item.=$this->getSingleField_typeFlex_sheetMenu($dataStructArray['sheets'], $PA['itemFormElName'].'[meta][currentSheetId]', $sheet).'<br />'; 02507 // } 02508 02509 // Create language menu: 02510 $langChildren = $dataStructArray['meta']['langChildren'] ? 1 : 0; 02511 $langDisabled = $dataStructArray['meta']['langDisable'] ? 1 : 0; 02512 02513 $editData['meta']['currentLangId'] = array(); 02514 02515 // Look up page overlays: 02516 $checkPageLanguageOverlay = $GLOBALS['BE_USER']->getTSConfigVal('options.checkPageLanguageOverlay') ? TRUE : FALSE; 02517 if ($checkPageLanguageOverlay) { 02518 $pageOverlays = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 02519 '*', 02520 'pages_language_overlay', 02521 'pid=' . intval($row['pid']) . 02522 t3lib_BEfunc::deleteClause('pages_language_overlay') . 02523 t3lib_BEfunc::versioningPlaceholderClause('pages_language_overlay'), 02524 '', 02525 '', 02526 '', 02527 'sys_language_uid' 02528 ); 02529 } 02530 $languages = $this->getAvailableLanguages(); 02531 02532 foreach ($languages as $lInfo) { 02533 if ($GLOBALS['BE_USER']->checkLanguageAccess($lInfo['uid']) && (!$checkPageLanguageOverlay || $lInfo['uid'] <= 0 || is_array($pageOverlays[$lInfo['uid']]))) { 02534 $editData['meta']['currentLangId'][] = $lInfo['ISOcode']; 02535 } 02536 } 02537 if (!is_array($editData['meta']['currentLangId']) || !count($editData['meta']['currentLangId'])) { 02538 $editData['meta']['currentLangId'] = array('DEF'); 02539 } 02540 02541 $editData['meta']['currentLangId'] = array_unique($editData['meta']['currentLangId']); 02542 02543 //TODO: Why is this commented out? 02544 // if (!$langDisabled && count($languages) > 1) { 02545 // $item.=$this->getSingleField_typeFlex_langMenu($languages, $PA['itemFormElName'].'[meta][currentLangId]', $editData['meta']['currentLangId']).'<br />'; 02546 // } 02547 02548 $PA['_noEditDEF'] = FALSE; 02549 if ($langChildren || $langDisabled) { 02550 $rotateLang = array('DEF'); 02551 } else { 02552 if (!in_array('DEF', $editData['meta']['currentLangId'])) { 02553 array_unshift($editData['meta']['currentLangId'], 'DEF'); 02554 $PA['_noEditDEF'] = TRUE; 02555 } 02556 $rotateLang = $editData['meta']['currentLangId']; 02557 } 02558 02559 // Tabs sheets 02560 if (is_array($dataStructArray['sheets'])) { 02561 $tabsToTraverse = array_keys($dataStructArray['sheets']); 02562 } else { 02563 $tabsToTraverse = array($sheet); 02564 } 02565 02566 foreach ($rotateLang as $lKey) { 02567 if (!$langChildren && !$langDisabled) { 02568 $item .= '<strong>' . $this->getLanguageIcon($table, $row, 'v' . $lKey) . $lKey . ':</strong>'; 02569 } 02570 02571 $tabParts = array(); 02572 foreach ($tabsToTraverse as $sheet) { 02573 list ($dataStruct, $sheet) = t3lib_div::resolveSheetDefInDS($dataStructArray, $sheet); 02574 02575 // Render sheet: 02576 if (is_array($dataStruct['ROOT']) && is_array($dataStruct['ROOT']['el'])) { 02577 $lang = 'l' . $lKey; // Default language, other options are "lUK" or whatever country code (independant of system!!!) 02578 $PA['_valLang'] = $langChildren && !$langDisabled ? $editData['meta']['currentLangId'] : 'DEF'; // Default language, other options are "lUK" or whatever country code (independant of system!!!) 02579 $PA['_lang'] = $lang; 02580 // Assemble key for loading the correct CSH file 02581 $dsPointerFields = t3lib_div::trimExplode(',', $GLOBALS['TCA'][$table]['columns'][$field]['config']['ds_pointerField'], TRUE); 02582 $PA['_cshKey'] = $table . '.' . $field; 02583 foreach ($dsPointerFields as $key) { 02584 $PA['_cshKey'] .= '.' . $row[$key]; 02585 } 02586 02587 // Push the sheet level tab to DynNestedStack 02588 if (is_array($dataStructArray['sheets'])) { 02589 $tabIdentString = $GLOBALS['TBE_TEMPLATE']->getDynTabMenuId('TCEFORMS:flexform:' . $PA['itemFormElName'] . $PA['_lang']); 02590 $this->pushToDynNestedStack('tab', $tabIdentString . '-' . (count($tabParts) + 1)); 02591 } 02592 // Render flexform: 02593 $tRows = $this->getSingleField_typeFlex_draw( 02594 $dataStruct['ROOT']['el'], 02595 $editData['data'][$sheet][$lang], 02596 $table, 02597 $field, 02598 $row, 02599 $PA, 02600 '[data][' . $sheet . '][' . $lang . ']' 02601 ); 02602 $sheetContent = '<div class="typo3-TCEforms-flexForm">' . $tRows . '</div>'; 02603 02604 02605 // Pop the sheet level tab from DynNestedStack 02606 if (is_array($dataStructArray['sheets'])) { 02607 $this->popFromDynNestedStack('tab', $tabIdentString . '-' . (count($tabParts) + 1)); 02608 } 02609 } else { 02610 $sheetContent = 'Data Structure ERROR: No ROOT element found for sheet "' . $sheet . '".'; 02611 } 02612 02613 // Add to tab: 02614 $tabParts[] = array( 02615 'label' => ($dataStruct['ROOT']['TCEforms']['sheetTitle'] ? $this->sL($dataStruct['ROOT']['TCEforms']['sheetTitle']) : $sheet), 02616 'description' => ($dataStruct['ROOT']['TCEforms']['sheetDescription'] ? $this->sL($dataStruct['ROOT']['TCEforms']['sheetDescription']) : ''), 02617 'linkTitle' => ($dataStruct['ROOT']['TCEforms']['sheetShortDescr'] ? $this->sL($dataStruct['ROOT']['TCEforms']['sheetShortDescr']) : ''), 02618 'content' => $sheetContent 02619 ); 02620 } 02621 02622 if (is_array($dataStructArray['sheets'])) { 02623 $dividersToTabsBehaviour = (isset($GLOBALS['TCA'][$table]['ctrl']['dividers2tabs']) ? $GLOBALS['TCA'][$table]['ctrl']['dividers2tabs'] : 1); 02624 $item .= $this->getDynTabMenu($tabParts, 'TCEFORMS:flexform:' . $PA['itemFormElName'] . $PA['_lang'], $dividersToTabsBehaviour); 02625 } else { 02626 $item .= $sheetContent; 02627 } 02628 } 02629 } else { 02630 $item = 'Data Structure ERROR: ' . $dataStructArray; 02631 } 02632 02633 return $item; 02634 } 02635 02636 /** 02637 * Creates the language menu for FlexForms: 02638 * 02639 * @param [type] $languages: ... 02640 * @param [type] $elName: ... 02641 * @param [type] $selectedLanguage: ... 02642 * @param [type] $multi: ... 02643 * @return string HTML for menu 02644 */ 02645 function getSingleField_typeFlex_langMenu($languages, $elName, $selectedLanguage, $multi = 1) { 02646 $opt = array(); 02647 foreach ($languages as $lArr) { 02648 $opt[] = '<option value="' . htmlspecialchars($lArr['ISOcode']) . '"' . (in_array($lArr['ISOcode'], $selectedLanguage) ? ' selected="selected"' : '') . '>' . htmlspecialchars($lArr['title']) . '</option>'; 02649 } 02650 02651 $output = '<select id="' . uniqid('tceforms-multiselect-') . ' class="tceforms-select tceforms-multiselect tceforms-flexlangmenu" name="' . $elName . '[]"' . ($multi ? ' multiple="multiple" size="' . count($languages) . '"' : '') . '>' . implode('', $opt) . '</select>'; 02652 02653 return $output; 02654 } 02655 02656 /** 02657 * Creates the menu for selection of the sheets: 02658 * 02659 * @param array Sheet array for which to render the menu 02660 * @param string Form element name of the field containing the sheet pointer 02661 * @param string Current sheet key 02662 * @return string HTML for menu 02663 */ 02664 function getSingleField_typeFlex_sheetMenu($sArr, $elName, $sheetKey) { 02665 02666 $tCells = array(); 02667 $pct = round(100 / count($sArr)); 02668 foreach ($sArr as $sKey => $sheetCfg) { 02669 if ($GLOBALS['BE_USER']->jsConfirmation(1)) { 02670 $onClick = 'if (confirm(TBE_EDITOR.labels.onChangeAlert) && TBE_EDITOR.checkSubmit(-1)){' . $this->elName($elName) . ".value='" . $sKey . "'; TBE_EDITOR.submitForm()};"; 02671 } else { 02672 $onClick = 'if(TBE_EDITOR.checkSubmit(-1)){ ' . $this->elName($elName) . ".value='" . $sKey . "'; TBE_EDITOR.submitForm();}"; 02673 } 02674 02675 02676 $tCells[] = '<td width="' . $pct . '%" style="' . ($sKey == $sheetKey ? 'background-color: #9999cc; font-weight: bold;' : 'background-color: #aaaaaa;') . ' cursor: hand;" onclick="' . htmlspecialchars($onClick) . '" align="center">' . 02677 ($sheetCfg['ROOT']['TCEforms']['sheetTitle'] ? $this->sL($sheetCfg['ROOT']['TCEforms']['sheetTitle']) : $sKey) . 02678 '</td>'; 02679 } 02680 02681 return '<table border="0" cellpadding="0" cellspacing="2" class="typo3-TCEforms-flexForm-sheetMenu"><tr>' . implode('', $tCells) . '</tr></table>'; 02682 } 02683 02684 /** 02685 * Recursive rendering of flexforms 02686 * 02687 * @param array (part of) Data Structure for which to render. Keys on first level is flex-form fields 02688 * @param array (part of) Data array of flexform corresponding to the input DS. Keys on first level is flex-form field names 02689 * @param string Table name, eg. tt_content 02690 * @param string Field name, eg. tx_templavoila_flex 02691 * @param array The particular record from $table in which the field $field is found 02692 * @param array Array of standard information for rendering of a form field in TCEforms, see other rendering functions too 02693 * @param string Form field prefix, eg. "[data][sDEF][lDEF][...][...]" 02694 * @param integer Indicates nesting level for the function call 02695 * @param string Prefix for ID-values 02696 * @param boolean Defines whether the next flexform level is open or closed. Comes from _TOGGLE pseudo field in FlexForm xml. 02697 * @return string HTMl code for form. 02698 */ 02699 function getSingleField_typeFlex_draw($dataStruct, $editData, $table, $field, $row, &$PA, $formPrefix = '', $level = 0, $idPrefix = 'ID', $toggleClosed = FALSE) { 02700 02701 $output = ''; 02702 $mayRestructureFlexforms = $GLOBALS['BE_USER']->checkLanguageAccess(0); 02703 02704 // Data Structure array must be ... and array of course... 02705 if (is_array($dataStruct)) { 02706 foreach ($dataStruct as $key => $value) { // Traversing fields in structure: 02707 if (is_array($value)) { // The value of each entry must be an array. 02708 02709 // ******************** 02710 // Making the row: 02711 // ******************** 02712 // Title of field: 02713 $theTitle = htmlspecialchars(t3lib_div::fixed_lgd_cs($this->sL($value['tx_templavoila']['title']), 30)); 02714 02715 // If it's a "section" or "container": 02716 if ($value['type'] == 'array') { 02717 02718 // Creating IDs for form fields: 02719 // It's important that the IDs "cascade" - otherwise we can't dynamically expand the flex form because this relies on simple string substitution of the first parts of the id values. 02720 $thisId = t3lib_div::shortMd5(uniqid('id', TRUE)); // This is a suffix used for forms on this level 02721 $idTagPrefix = $idPrefix . '-' . $thisId; // $idPrefix is the prefix for elements on lower levels in the hierarchy and we combine this with the thisId value to form a new ID on this level. 02722 02723 // If it's a "section" containing other elements: 02724 if ($value['section']) { 02725 02726 // Load script.aculo.us if flexform sections can be moved by drag'n'drop: 02727 $GLOBALS['SOBE']->doc->getPageRenderer()->loadScriptaculous(); 02728 // Render header of section: 02729 $output .= '<div class="t3-form-field-label-flexsection"><strong>' . $theTitle . '</strong></div>'; 02730 02731 // Render elements in data array for section: 02732 $tRows = array(); 02733 $cc = 0; 02734 if (is_array($editData[$key]['el'])) { 02735 foreach ($editData[$key]['el'] as $k3 => $v3) { 02736 $cc = $k3; 02737 if (is_array($v3)) { 02738 $theType = key($v3); 02739 $theDat = $v3[$theType]; 02740 $newSectionEl = $value['el'][$theType]; 02741 if (is_array($newSectionEl)) { 02742 $tRows[] = $this->getSingleField_typeFlex_draw( 02743 array($theType => $newSectionEl), 02744 array($theType => $theDat), 02745 $table, 02746 $field, 02747 $row, 02748 $PA, 02749 $formPrefix . '[' . $key . '][el][' . $cc . ']', 02750 $level + 1, 02751 $idTagPrefix, 02752 $v3['_TOGGLE'] 02753 ); 02754 } 02755 } 02756 } 02757 } 02758 02759 // Now, we generate "templates" for new elements that could be added to this section by traversing all possible types of content inside the section: 02760 // We have to handle the fact that requiredElements and such may be set during this rendering process and therefore we save and reset the state of some internal variables - little crude, but works... 02761 02762 // Preserving internal variables we don't want to change: 02763 $TEMP_requiredElements = $this->requiredElements; 02764 02765 // Traversing possible types of new content in the section: 02766 $newElementsLinks = array(); 02767 foreach ($value['el'] as $nnKey => $nCfg) { 02768 $additionalJS_post_saved = $this->additionalJS_post; 02769 $this->additionalJS_post = array(); 02770 $additionalJS_submit_saved = $this->additionalJS_submit; 02771 $this->additionalJS_submit = array(); 02772 $newElementTemplate = $this->getSingleField_typeFlex_draw( 02773 array($nnKey => $nCfg), 02774 array(), 02775 $table, 02776 $field, 02777 $row, 02778 $PA, 02779 $formPrefix . '[' . $key . '][el][' . $idTagPrefix . '-form]', 02780 $level + 1, 02781 $idTagPrefix 02782 ); 02783 02784 // Makes a "Add new" link: 02785 $var = uniqid('idvar'); 02786 $replace = 'replace(/' . $idTagPrefix . '-/g,"' . $idTagPrefix . '-"+' . $var . '+"-")'; 02787 $onClickInsert = 'var ' . $var . ' = "' . 'idx"+(new Date()).getTime();'; 02788 // Do not replace $isTagPrefix in setActionStatus() because it needs section id! 02789 $onClickInsert .= 'new Insertion.Bottom($("' . $idTagPrefix . '"), unescape("' . rawurlencode($newElementTemplate) . '").' . $replace . '); setActionStatus("' . $idTagPrefix . '");'; 02790 $onClickInsert .= 'eval(unescape("' . rawurlencode(implode(';', $this->additionalJS_post)) . '").' . $replace . ');'; 02791 $onClickInsert .= 'TBE_EDITOR.addActionChecks("submit", unescape("' . rawurlencode(implode(';', $this->additionalJS_submit)) . '").' . $replace . ');'; 02792 $onClickInsert .= 'return false;'; 02793 // Kasper's comment (kept for history): Maybe there is a better way to do this than store the HTML for the new element in rawurlencoded format - maybe it even breaks with certain charsets? But for now this works... 02794 $this->additionalJS_post = $additionalJS_post_saved; 02795 $this->additionalJS_submit = $additionalJS_submit_saved; 02796 $new = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:cm.new', 1); 02797 $newElementsLinks[] = '<a href="#" onclick="' . htmlspecialchars($onClickInsert) . '">' . 02798 t3lib_iconWorks::getSpriteIcon('actions-document-new') . 02799 htmlspecialchars(t3lib_div::fixed_lgd_cs($this->sL($nCfg['tx_templavoila']['title']), 30)) . '</a>'; 02800 } 02801 02802 // Reverting internal variables we don't want to change: 02803 $this->requiredElements = $TEMP_requiredElements; 02804 02805 // Adding the sections: 02806 $toggleAll = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.toggleall', 1); 02807 $output .= ' 02808 <div class="t3-form-field-toggle-flexsection"> 02809 <a href="#" onclick="' . htmlspecialchars('flexFormToggleSubs("' . $idTagPrefix . '"); return false;') . '">' 02810 . t3lib_iconWorks::getSpriteIcon('actions-move-right', array('title' => $toggleAll)) . $toggleAll . ' 02811 </a> 02812 </div> 02813 02814 <div id="' . $idTagPrefix . '" class="t3-form-field-container-flexsection">' . implode('', $tRows) . '</div>'; 02815 $output .= $mayRestructureFlexforms ? '<div class="t3-form-field-add-flexsection"><strong>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.addnew', 1) . ':</strong> ' . implode(' | ', $newElementsLinks) . '</div>' : ''; 02816 } else { 02817 // It is a container 02818 02819 $toggleIcon_open = t3lib_iconWorks::getSpriteIcon('actions-move-down'); 02820 $toggleIcon_close = t3lib_iconWorks::getSpriteIcon('actions-move-right'); 02821 02822 // Create on-click actions. 02823 //$onClickCopy = 'new Insertion.After($("'.$idTagPrefix.'"), getOuterHTML("'.$idTagPrefix.'").replace(/'.$idTagPrefix.'-/g,"'.$idTagPrefix.'-copy"+Math.floor(Math.random()*100000+1)+"-")); return false;'; // Copied elements doesn't work (well) in Safari while they do in Firefox and MSIE! UPDATE: It turned out that copying doesn't work for any browser, simply because the data from the copied form never gets submitted to the server for some reason! So I decided to simply disable copying for now. If it's requested by customers we can look to enable it again and fix the issue. There is one un-fixable problem though; Copying an element like this will violate integrity if files are attached inside that element because the file reference doesn't get an absolute path prefixed to it which would be required to have TCEmain generate a new copy of the file. 02824 $onClickRemove = 'if (confirm("Are you sure?")){/*###REMOVE###*/;$("' . $idTagPrefix . '").hide();setActionStatus("' . $idPrefix . '");} return false;'; 02825 $onClickToggle = 'flexFormToggle("' . $idTagPrefix . '"); return false;'; 02826 02827 $onMove = 'flexFormSortable("' . $idPrefix . '")'; 02828 // Notice: Creating "new" elements after others seemed to be too difficult to do and since moving new elements created in the bottom is now so easy with drag'n'drop I didn't see the need. 02829 02830 02831 // Putting together header of a section. Sections can be removed, copied, opened/closed, moved up and down: 02832 // I didn't know how to make something right-aligned without a table, so I put it in a table. can be made into <div>'s if someone like to. 02833 // Notice: The fact that I make a "Sortable.create" right onmousedown is that if we initialize this when rendering the form in PHP new and copied elements will not be possible to move as a sortable. But this way a new sortable is initialized everytime someone tries to move and it will always work. 02834 $ctrlHeader = ' 02835 <table class="t3-form-field-header-flexsection" onmousedown="' . ($mayRestructureFlexforms ? htmlspecialchars($onMove) : '') . '"> 02836 <tr> 02837 <td> 02838 <a href="#" onclick="' . htmlspecialchars($onClickToggle) . '" id="' . $idTagPrefix . '-toggle"> 02839 ' . ($toggleClosed ? $toggleIcon_close : $toggleIcon_open) . ' 02840 </a> 02841 <strong>' . $theTitle . '</strong> <em><span id="' . $idTagPrefix . '-preview"></span></em> 02842 </td> 02843 <td align="right">' . 02844 ($mayRestructureFlexforms ? t3lib_iconWorks::getSpriteIcon('actions-move-move', array('title' => 'Drag to Move')) : '') . 02845 ($mayRestructureFlexforms ? '<a href="#" onclick="' . htmlspecialchars($onClickRemove) . '">' . t3lib_iconWorks::getSpriteIcon('actions-edit-delete', array('title' => 'Delete')) : '') . 02846 '</td> 02847 </tr> 02848 </table>'; 02849 02850 $s = t3lib_div::revExplode('[]', $formPrefix, 2); 02851 $actionFieldName = '_ACTION_FLEX_FORM' . $PA['itemFormElName'] . $s[0] . '][_ACTION][' . $s[1]; 02852 02853 // Push the container to DynNestedStack as it may be toggled 02854 $this->pushToDynNestedStack('flex', $idTagPrefix); 02855 02856 // Putting together the container: 02857 $this->additionalJS_delete = array(); 02858 $output .= ' 02859 <div id="' . $idTagPrefix . '" class="t3-form-field-container-flexsections"> 02860 <input id="' . $idTagPrefix . '-action" type="hidden" name="' . htmlspecialchars($actionFieldName) . '" value=""/> 02861 02862 ' . $ctrlHeader . ' 02863 <div class="t3-form-field-record-flexsection" id="' . $idTagPrefix . '-content"' . ($toggleClosed ? ' style="display:none;"' : '') . '>' . 02864 $this->getSingleField_typeFlex_draw( 02865 $value['el'], 02866 $editData[$key]['el'], 02867 $table, 02868 $field, 02869 $row, 02870 $PA, 02871 $formPrefix . '[' . $key . '][el]', 02872 $level + 1, 02873 $idTagPrefix 02874 ) . ' 02875 </div> 02876 <input id="' . $idTagPrefix . '-toggleClosed" type="hidden" name="' . htmlspecialchars('data[' . $table . '][' . $row['uid'] . '][' . $field . ']' . $formPrefix . '[_TOGGLE]') . '" value="' . ($toggleClosed ? 1 : 0) . '" /> 02877 </div>'; 02878 $output = str_replace('/*###REMOVE###*/', t3lib_div::slashJS(htmlspecialchars(implode('', $this->additionalJS_delete))), $output); 02879 // NOTICE: We are saving the toggle-state directly in the flexForm XML and "unauthorized" according to the data structure. It means that flexform XML will report unclean and a cleaning operation will remove the recorded togglestates. This is not a fatal problem. Ideally we should save the toggle states in meta-data but it is much harder to do that. And this implementation was easy to make and with no really harmful impact. 02880 02881 // Pop the container from DynNestedStack 02882 $this->popFromDynNestedStack('flex', $idTagPrefix); 02883 } 02884 02885 // If it's a "single form element": 02886 } elseif (is_array($value['TCEforms']['config'])) { // Rendering a single form element: 02887 02888 if (is_array($PA['_valLang'])) { 02889 $rotateLang = $PA['_valLang']; 02890 } else { 02891 $rotateLang = array($PA['_valLang']); 02892 } 02893 02894 $conditionData = is_array($editData) ? $editData : array(); 02895 // add current $row to data processed by isDisplayCondition() 02896 $conditionData['parentRec'] = $row; 02897 02898 $tRows = array(); 02899 foreach ($rotateLang as $vDEFkey) { 02900 $vDEFkey = 'v' . $vDEFkey; 02901 02902 if (!$value['TCEforms']['displayCond'] || $this->isDisplayCondition($value['TCEforms']['displayCond'], $conditionData, $vDEFkey)) { 02903 $fakePA = array(); 02904 $fakePA['fieldConf'] = array( 02905 'label' => $this->sL(trim($value['TCEforms']['label'])), 02906 'config' => $value['TCEforms']['config'], 02907 'defaultExtras' => $value['TCEforms']['defaultExtras'], 02908 'onChange' => $value['TCEforms']['onChange'] 02909 ); 02910 if ($PA['_noEditDEF'] && $PA['_lang'] === 'lDEF') { 02911 $fakePA['fieldConf']['config'] = array( 02912 'type' => 'none', 02913 'rows' => 2 02914 ); 02915 } 02916 02917 if ( 02918 $fakePA['fieldConf']['onChange'] == 'reload' || 02919 ($GLOBALS['TCA'][$table]['ctrl']['type'] && !strcmp($key, $GLOBALS['TCA'][$table]['ctrl']['type'])) || 02920 ($GLOBALS['TCA'][$table]['ctrl']['requestUpdate'] && t3lib_div::inList($GLOBALS['TCA'][$table]['ctrl']['requestUpdate'], $key))) { 02921 if ($GLOBALS['BE_USER']->jsConfirmation(1)) { 02922 $alertMsgOnChange = 'if (confirm(TBE_EDITOR.labels.onChangeAlert) && TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };'; 02923 } else { 02924 $alertMsgOnChange = 'if(TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm();}'; 02925 } 02926 } else { 02927 $alertMsgOnChange = ''; 02928 } 02929 02930 $fakePA['fieldChangeFunc'] = $PA['fieldChangeFunc']; 02931 if (strlen($alertMsgOnChange)) { 02932 $fakePA['fieldChangeFunc']['alert'] = $alertMsgOnChange; 02933 } 02934 $fakePA['onFocus'] = $PA['onFocus']; 02935 $fakePA['label'] = $PA['label']; 02936 02937 $fakePA['itemFormElName'] = $PA['itemFormElName'] . $formPrefix . '[' . $key . '][' . $vDEFkey . ']'; 02938 $fakePA['itemFormElName_file'] = $PA['itemFormElName_file'] . $formPrefix . '[' . $key . '][' . $vDEFkey . ']'; 02939 $fakePA['itemFormElID'] = $fakePA['itemFormElName']; 02940 02941 if (isset($editData[$key][$vDEFkey])) { 02942 $fakePA['itemFormElValue'] = $editData[$key][$vDEFkey]; 02943 } else { 02944 $fakePA['itemFormElValue'] = $fakePA['fieldConf']['config']['default']; 02945 } 02946 02947 $theFormEl = $this->getSingleField_SW($table, $field, $row, $fakePA); 02948 $theTitle = htmlspecialchars($fakePA['fieldConf']['label']); 02949 02950 if (!in_array('DEF', $rotateLang)) { 02951 $defInfo = '<div class="typo3-TCEforms-originalLanguageValue">' . $this->getLanguageIcon($table, $row, 0) . 02952 $this->previewFieldValue($editData[$key]['vDEF'], $fakePA['fieldConf'], $field) . ' </div>'; 02953 } else { 02954 $defInfo = ''; 02955 } 02956 02957 if (!$PA['_noEditDEF']) { 02958 $prLang = $this->getAdditionalPreviewLanguages(); 02959 foreach ($prLang as $prL) { 02960 $defInfo .= '<div class="typo3-TCEforms-originalLanguageValue">' . $this->getLanguageIcon($table, $row, 'v' . $prL['ISOcode']) . 02961 $this->previewFieldValue($editData[$key]['v' . $prL['ISOcode']], $fakePA['fieldConf'], $field) . ' </div>'; 02962 } 02963 } 02964 02965 $languageIcon = ''; 02966 if ($vDEFkey != 'vDEF') { 02967 $languageIcon = $this->getLanguageIcon($table, $row, $vDEFkey); 02968 } 02969 // Put row together 02970 // possible linebreaks in the label through xml: \n => <br/>, usage of nl2br() not possible, so it's done through str_replace 02971 $processedTitle = str_replace('\n', '<br />', $theTitle); 02972 $tRows[] = '<div class="t3-form-field-container t3-form-field-container-flex">' . 02973 '<div class="t3-form-field-label t3-form-field-label-flex">' . 02974 $languageIcon . 02975 t3lib_BEfunc::wrapInHelp($PA['_cshKey'], $key, $processedTitle) . 02976 '</div> 02977 <div class="t3-form-field t3-form-field-flex">' . $theFormEl . $defInfo . $this->renderVDEFDiff($editData[$key], $vDEFkey) . '</div> 02978 </div>'; 02979 } 02980 } 02981 if (count($tRows)) { 02982 $output .= implode('', $tRows); 02983 } 02984 } 02985 } 02986 } 02987 } 02988 02989 return $output; 02990 } 02991 02992 /** 02993 * Handler for unknown types. 02994 * 02995 * @param string The table name of the record 02996 * @param string The field name which this element is supposed to edit 02997 * @param array The record data array where the value(s) for the field can be found 02998 * @param array An array with additional configuration options. 02999 * @return string The HTML code for the TCEform field 03000 */ 03001 function getSingleField_typeUnknown($table, $field, $row, &$PA) { 03002 $item = 'Unknown type: ' . $PA['fieldConf']['config']['form_type'] . '<br />'; 03003 03004 return $item; 03005 } 03006 03007 /** 03008 * User defined field type 03009 * 03010 * @param string The table name of the record 03011 * @param string The field name which this element is supposed to edit 03012 * @param array The record data array where the value(s) for the field can be found 03013 * @param array An array with additional configuration options. 03014 * @return string The HTML code for the TCEform field 03015 */ 03016 function getSingleField_typeUser($table, $field, $row, &$PA) { 03017 $PA['table'] = $table; 03018 $PA['field'] = $field; 03019 $PA['row'] = $row; 03020 03021 $PA['pObj'] =& $this; 03022 03023 return t3lib_div::callUserFunction($PA['fieldConf']['config']['userFunc'], $PA, $this); 03024 } 03025 03026 03027 /************************************************************ 03028 * 03029 * Field content processing 03030 * 03031 ************************************************************/ 03032 03033 /** 03034 * Format field content of various types if $config['format'] is set to date, filesize, ..., user 03035 * This is primarily for the field type none but can be used for user field types for example 03036 * 03037 * @param array Configuration for the display 03038 * @param string The value to display 03039 * @return string Formatted Field content 03040 */ 03041 function formatValue($config, $itemValue) { 03042 $format = trim($config['format']); 03043 switch ($format) { 03044 case 'date': 03045 if ($itemValue) { 03046 $option = trim($config['format.']['option']); 03047 if ($option) { 03048 if ($config['format.']['strftime']) { 03049 $value = strftime($option, $itemValue); 03050 } else { 03051 $value = date($option, $itemValue); 03052 } 03053 } else { 03054 $value = date('d-m-Y', $itemValue); 03055 } 03056 } else { 03057 $value = ''; 03058 } 03059 if ($config['format.']['appendAge']) { 03060 $value .= ' (' . 03061 t3lib_BEfunc::calcAge(($GLOBALS['EXEC_TIME'] - $itemValue), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears')) . 03062 ')'; 03063 } 03064 $itemValue = $value; 03065 break; 03066 case 'datetime': // compatibility with "eval" (type "input") 03067 $itemValue = date('H:i d-m-Y', $itemValue); 03068 break; 03069 case 'time': // compatibility with "eval" (type "input") 03070 $itemValue = date('H:i', $itemValue); 03071 break; 03072 case 'timesec': // compatibility with "eval" (type "input") 03073 $itemValue = date('H:i:s', $itemValue); 03074 break; 03075 case 'year': // compatibility with "eval" (type "input") 03076 $itemValue = date('Y', $itemValue); 03077 break; 03078 case 'int': 03079 $baseArr = array('dec' => 'd', 'hex' => 'x', 'HEX' => 'X', 'oct' => 'o', 'bin' => 'b'); 03080 $base = trim($config['format.']['base']); 03081 $format = $baseArr[$base] ? $baseArr[$base] : 'd'; 03082 $itemValue = sprintf('%' . $format, $itemValue); 03083 break; 03084 case 'float': 03085 $precision = t3lib_div::intInRange($config['format.']['precision'], 1, 10, 2); 03086 $itemValue = sprintf('%.' . $precision . 'f', $itemValue); 03087 break; 03088 case 'number': 03089 $format = trim($config['format.']['option']); 03090 $itemValue = sprintf('%' . $format, $itemValue); 03091 break; 03092 case 'md5': 03093 $itemValue = md5($itemValue); 03094 break; 03095 case 'filesize': 03096 $value = t3lib_div::formatSize(intval($itemValue)); 03097 if ($config['format.']['appendByteSize']) { 03098 $value .= ' (' . $itemValue . ')'; 03099 } 03100 $itemValue = $value; 03101 break; 03102 case 'user': 03103 $func = trim($config['format.']['userFunc']); 03104 if ($func) { 03105 $params = array( 03106 'value' => $itemValue, 03107 'args' => $config['format.']['userFunc'], 03108 'config' => $config, 03109 'pObj' => &$this 03110 ); 03111 $itemValue = t3lib_div::callUserFunction($func, $params, $this); 03112 } 03113 break; 03114 default: 03115 break; 03116 } 03117 03118 return $itemValue; 03119 } 03120 03121 03122 /************************************************************ 03123 * 03124 * "Configuration" fetching/processing functions 03125 * 03126 ************************************************************/ 03127 03128 /** 03129 * Calculate and return the current "types" pointer value for a record 03130 * 03131 * @param string The table name. MUST be in $TCA 03132 * @param array The row from the table, should contain at least the "type" field, if applicable. 03133 * @return string Return the "type" value for this record, ready to pick a "types" configuration from the $TCA array. 03134 */ 03135 function getRTypeNum($table, $row) { 03136 global $TCA; 03137 // If there is a "type" field configured... 03138 if ($TCA[$table]['ctrl']['type']) { 03139 $typeFieldName = $TCA[$table]['ctrl']['type']; 03140 $typeFieldConfig = $TCA[$table]['columns'][$typeFieldName]; 03141 $typeNum = $this->getLanguageOverlayRawValue($table, $row, $typeFieldName, $typeFieldConfig); 03142 if (!strcmp($typeNum, '')) { 03143 $typeNum = 0; 03144 } // If that value is an empty string, set it to "0" (zero) 03145 } else { 03146 $typeNum = 0; // If no "type" field, then set to "0" (zero) 03147 } 03148 03149 $typeNum = (string) $typeNum; // Force to string. Necessary for eg '-1' to be recognized as a type value. 03150 if (!$TCA[$table]['types'][$typeNum]) { // However, if the type "0" is not found in the "types" array, then default to "1" (for historical reasons) 03151 $typeNum = 1; 03152 } 03153 03154 return $typeNum; 03155 } 03156 03157 /** 03158 * Used to adhoc-rearrange the field order normally set in the [types][showitem] list 03159 * 03160 * @param array A [types][showitem] list of fields, exploded by "," 03161 * @return array Returns rearranged version (keys are changed around as well.) 03162 * @see getMainFields() 03163 */ 03164 function rearrange($fields) { 03165 $fO = array_flip(t3lib_div::trimExplode(',', $this->fieldOrder, 1)); 03166 $newFields = array(); 03167 foreach ($fields as $cc => $content) { 03168 $cP = t3lib_div::trimExplode(';', $content); 03169 if (isset($fO[$cP[0]])) { 03170 $newFields[$fO[$cP[0]]] = $content; 03171 unset($fields[$cc]); 03172 } 03173 } 03174 ksort($newFields); 03175 $fields = array_merge($newFields, $fields); // Candidate for t3lib_div::array_merge() if integer-keys will some day make trouble... 03176 return $fields; 03177 } 03178 03179 /** 03180 * Producing an array of field names NOT to display in the form, based on settings from subtype_value_field, bitmask_excludelist_bits etc. 03181 * Notice, this list is in NO way related to the "excludeField" flag 03182 * 03183 * @param string Table name, MUST be in $TCA 03184 * @param array A record from table. 03185 * @param string A "type" pointer value, probably the one calculated based on the record array. 03186 * @return array Array with fieldnames as values. The fieldnames are those which should NOT be displayed "anyways" 03187 * @see getMainFields() 03188 */ 03189 function getExcludeElements($table, $row, $typeNum) { 03190 global $TCA; 03191 03192 // Init: 03193 $excludeElements = array(); 03194 03195 // If a subtype field is defined for the type 03196 if ($TCA[$table]['types'][$typeNum]['subtype_value_field']) { 03197 $sTfield = $TCA[$table]['types'][$typeNum]['subtype_value_field']; 03198 if (trim($TCA[$table]['types'][$typeNum]['subtypes_excludelist'][$row[$sTfield]])) { 03199 $excludeElements = t3lib_div::trimExplode(',', $TCA[$table]['types'][$typeNum]['subtypes_excludelist'][$row[$sTfield]], 1); 03200 } 03201 } 03202 03203 // If a bitmask-value field has been configured, then find possible fields to exclude based on that: 03204 if ($TCA[$table]['types'][$typeNum]['bitmask_value_field']) { 03205 $sTfield = $TCA[$table]['types'][$typeNum]['bitmask_value_field']; 03206 $sTValue = t3lib_div::intInRange($row[$sTfield], 0); 03207 if (is_array($TCA[$table]['types'][$typeNum]['bitmask_excludelist_bits'])) { 03208 foreach ($TCA[$table]['types'][$typeNum]['bitmask_excludelist_bits'] as $bitKey => $eList) { 03209 $bit = substr($bitKey, 1); 03210 if (t3lib_div::testInt($bit)) { 03211 $bit = t3lib_div::intInRange($bit, 0, 30); 03212 if ( 03213 (substr($bitKey, 0, 1) == '-' && !($sTValue & pow(2, $bit))) || 03214 (substr($bitKey, 0, 1) == '+' && ($sTValue & pow(2, $bit))) 03215 ) { 03216 $excludeElements = array_merge($excludeElements, t3lib_div::trimExplode(',', $eList, 1)); 03217 } 03218 } 03219 } 03220 } 03221 } 03222 03223 // Return the array of elements: 03224 return $excludeElements; 03225 } 03226 03227 /** 03228 * Finds possible field to add to the form, based on subtype fields. 03229 * 03230 * @param string Table name, MUST be in $TCA 03231 * @param array A record from table. 03232 * @param string A "type" pointer value, probably the one calculated based on the record array. 03233 * @return array An array containing two values: 1) Another array containing fieldnames to add and 2) the subtype value field. 03234 * @see getMainFields() 03235 */ 03236 function getFieldsToAdd($table, $row, $typeNum) { 03237 global $TCA; 03238 03239 // Init: 03240 $addElements = array(); 03241 03242 // If a subtype field is defined for the type 03243 if ($TCA[$table]['types'][$typeNum]['subtype_value_field']) { 03244 $sTfield = $TCA[$table]['types'][$typeNum]['subtype_value_field']; 03245 if (trim($TCA[$table]['types'][$typeNum]['subtypes_addlist'][$row[$sTfield]])) { 03246 $addElements = t3lib_div::trimExplode(',', $TCA[$table]['types'][$typeNum]['subtypes_addlist'][$row[$sTfield]], 1); 03247 } 03248 } 03249 // Return the return 03250 return array($addElements, $sTfield); 03251 } 03252 03253 /** 03254 * Merges the current [types][showitem] array with the array of fields to add for the current subtype field of the "type" value. 03255 * 03256 * @param array A [types][showitem] list of fields, exploded by "," 03257 * @param array The output from getFieldsToAdd() 03258 * @return array Return the modified $fields array. 03259 * @see getMainFields(),getFieldsToAdd() 03260 */ 03261 function mergeFieldsWithAddedFields($fields, $fieldsToAdd) { 03262 if (count($fieldsToAdd[0])) { 03263 $c = 0; 03264 foreach ($fields as $fieldInfo) { 03265 $parts = explode(';', $fieldInfo); 03266 if (!strcmp(trim($parts[0]), $fieldsToAdd[1])) { 03267 array_splice( 03268 $fields, 03269 $c + 1, 03270 0, 03271 $fieldsToAdd[0] 03272 ); 03273 break; 03274 } 03275 $c++; 03276 } 03277 } 03278 return $fields; 03279 } 03280 03281 03282 /** 03283 * Returns TSconfig for table/row 03284 * Multiple requests to this function will return cached content so there is no performance loss in calling this many times since the information is looked up only once. 03285 * 03286 * @param string The table name 03287 * @param array The table row (Should at least contain the "uid" value, even if "NEW..." string. The "pid" field is important as well, and negative values will be intepreted as pointing to a record from the same table.) 03288 * @param string Optionally you can specify the field name as well. In that case the TSconfig for the field is returned. 03289 * @return mixed The TSconfig values (probably in an array) 03290 * @see t3lib_BEfunc::getTCEFORM_TSconfig() 03291 */ 03292 function setTSconfig($table, $row, $field = '') { 03293 $mainKey = $table . ':' . $row['uid']; 03294 if (!isset($this->cachedTSconfig[$mainKey])) { 03295 $this->cachedTSconfig[$mainKey] = t3lib_BEfunc::getTCEFORM_TSconfig($table, $row); 03296 } 03297 if ($field) { 03298 return $this->cachedTSconfig[$mainKey][$field]; 03299 } else { 03300 return $this->cachedTSconfig[$mainKey]; 03301 } 03302 } 03303 03304 /** 03305 * Overrides the TCA field configuration by TSconfig settings. 03306 * 03307 * Example TSconfig: TCEform.<table>.<field>.config.appearance.useSortable = 1 03308 * This overrides the setting in $TCA[<table>]['columns'][<field>]['config']['appearance']['useSortable']. 03309 * 03310 * @param array $fieldConfig: TCA field configuration 03311 * @param array $TSconfig: TSconfig 03312 * @return array Changed TCA field configuration 03313 */ 03314 function overrideFieldConf($fieldConfig, $TSconfig) { 03315 if (is_array($TSconfig)) { 03316 $TSconfig = t3lib_div::removeDotsFromTS($TSconfig); 03317 $type = $fieldConfig['type']; 03318 if (is_array($TSconfig['config']) && is_array($this->allowOverrideMatrix[$type])) { 03319 // Check if the keys in TSconfig['config'] are allowed to override TCA field config: 03320 foreach (array_keys($TSconfig['config']) as $key) { 03321 if (!in_array($key, $this->allowOverrideMatrix[$type], TRUE)) { 03322 unset($TSconfig['config'][$key]); 03323 } 03324 } 03325 // Override TCA field config by remaining TSconfig['config']: 03326 if (count($TSconfig['config'])) { 03327 $fieldConfig = t3lib_div::array_merge_recursive_overrule($fieldConfig, $TSconfig['config']); 03328 } 03329 } 03330 } 03331 03332 return $fieldConfig; 03333 } 03334 03335 /** 03336 * Returns the "special" configuration (from the "types" "showitem" list) for a fieldname based on input table/record 03337 * (Not used anywhere...?) 03338 * 03339 * @param string The table name 03340 * @param array The table row (Should at least contain the "uid" value, even if "NEW..." string. The "pid" field is important as well, and negative values will be intepreted as pointing to a record from the same table.) 03341 * @param string Specify the field name. 03342 * @return array 03343 * @see getSpecConfFromString(), t3lib_BEfunc::getTCAtypes() 03344 */ 03345 function getSpecConfForField($table, $row, $field) { 03346 // Finds the current "types" configuration for the table/row: 03347 $types_fieldConfig = t3lib_BEfunc::getTCAtypes($table, $row); 03348 03349 // If this is an array, then traverse it: 03350 if (is_array($types_fieldConfig)) { 03351 foreach ($types_fieldConfig as $vconf) { 03352 // If the input field name matches one found in the 'types' list, then return the 'special' configuration. 03353 if ($vconf['field'] == $field) { 03354 return $vconf['spec']; 03355 } 03356 } 03357 } 03358 } 03359 03360 /** 03361 * Returns the "special" configuration of an "extra" string (non-parsed) 03362 * 03363 * @param string The "Part 4" of the fields configuration in "types" "showitem" lists. 03364 * @param string The ['defaultExtras'] value from field configuration 03365 * @return array An array with the special options in. 03366 * @see getSpecConfForField(), t3lib_BEfunc::getSpecConfParts() 03367 */ 03368 function getSpecConfFromString($extraString, $defaultExtras) { 03369 return t3lib_BEfunc::getSpecConfParts($extraString, $defaultExtras); 03370 } 03371 03372 03373 /** 03374 * Loads the elements of a palette (collection of secondary options) in an array. 03375 * 03376 * @param string The table name 03377 * @param array The row array 03378 * @param string The palette number/pointer 03379 * @param string Optional alternative list of fields for the palette 03380 * @return array The palette elements 03381 */ 03382 public function loadPaletteElements($table, $row, $palette, $itemList = '') { 03383 global $TCA; 03384 03385 t3lib_div::loadTCA($table); 03386 $parts = array(); 03387 03388 // Getting excludeElements, if any. 03389 if (!is_array($this->excludeElements)) { 03390 $this->excludeElements = $this->getExcludeElements($table, $row, $this->getRTypeNum($table, $row)); 03391 } 03392 03393 // Load the palette TCEform elements 03394 if ($TCA[$table] && (is_array($TCA[$table]['palettes'][$palette]) || $itemList)) { 03395 $itemList = ($itemList ? $itemList : $TCA[$table]['palettes'][$palette]['showitem']); 03396 if ($itemList) { 03397 $fields = t3lib_div::trimExplode(',', $itemList, 1); 03398 foreach ($fields as $info) { 03399 $fieldParts = t3lib_div::trimExplode(';', $info); 03400 $theField = $fieldParts[0]; 03401 if ($theField === '--linebreak--') { 03402 $parts[]['NAME'] = '--linebreak--'; 03403 } elseif (!in_array($theField, $this->excludeElements) && $TCA[$table]['columns'][$theField]) { 03404 $this->palFieldArr[$palette][] = $theField; 03405 $elem = $this->getSingleField($table, $theField, $row, $fieldParts[1], 1, '', $fieldParts[2]); 03406 if (is_array($elem)) { 03407 $parts[] = $elem; 03408 } 03409 } 03410 } 03411 } 03412 } 03413 return $parts; 03414 } 03415 03416 03417 /************************************************************ 03418 * 03419 * Display of localized content etc. 03420 * 03421 ************************************************************/ 03422 03423 /** 03424 * Will register data from original language records if the current record is a translation of another. 03425 * The original data is shown with the edited record in the form. The information also includes possibly diff-views of what changed in the original record. 03426 * Function called from outside (see alt_doc.php + quick edit) before rendering a form for a record 03427 * 03428 * @param string Table name of the record being edited 03429 * @param array Record array of the record being edited 03430 * @return void 03431 */ 03432 function registerDefaultLanguageData($table, $rec) { 03433 global $TCA; 03434 03435 // Add default language: 03436 if ($TCA[$table]['ctrl']['languageField'] 03437 && $rec[$TCA[$table]['ctrl']['languageField']] > 0 03438 && $TCA[$table]['ctrl']['transOrigPointerField'] 03439 && intval($rec[$TCA[$table]['ctrl']['transOrigPointerField']]) > 0) { 03440 03441 $lookUpTable = $TCA[$table]['ctrl']['transOrigPointerTable'] ? $TCA[$table]['ctrl']['transOrigPointerTable'] : $table; 03442 03443 // Get data formatted: 03444 $this->defaultLanguageData[$table . ':' . $rec['uid']] = t3lib_BEfunc::getRecordWSOL($lookUpTable, intval($rec[$TCA[$table]['ctrl']['transOrigPointerField']])); 03445 03446 // Get data for diff: 03447 if ($TCA[$table]['ctrl']['transOrigDiffSourceField']) { 03448 $this->defaultLanguageData_diff[$table . ':' . $rec['uid']] = unserialize($rec[$TCA[$table]['ctrl']['transOrigDiffSourceField']]); 03449 } 03450 03451 // If there are additional preview languages, load information for them also: 03452 $prLang = $this->getAdditionalPreviewLanguages(); 03453 foreach ($prLang as $prL) { 03454 $t8Tools = t3lib_div::makeInstance('t3lib_transl8tools'); 03455 $tInfo = $t8Tools->translationInfo($lookUpTable, intval($rec[$TCA[$table]['ctrl']['transOrigPointerField']]), $prL['uid']); 03456 if (is_array($tInfo['translations'][$prL['uid']])) { 03457 $this->additionalPreviewLanguageData[$table . ':' . $rec['uid']][$prL['uid']] = t3lib_BEfunc::getRecordWSOL($table, intval($tInfo['translations'][$prL['uid']]['uid'])); 03458 } 03459 } 03460 } 03461 } 03462 03463 /** 03464 * Creates language-overlay for a field value 03465 * This means the requested field value will be overridden with the data from the default language. 03466 * Can be used to render read only fields for example. 03467 * 03468 * @param string Table name of the record being edited 03469 * @param string Field name represented by $item 03470 * @param array Record array of the record being edited in current language 03471 * @param array Content of $PA['fieldConf'] 03472 * @return string Unprocessed field value merged with default language data if needed 03473 */ 03474 function getLanguageOverlayRawValue($table, $row, $field, $fieldConf) { 03475 global $TCA; 03476 03477 $value = $row[$field]; 03478 03479 if (is_array($this->defaultLanguageData[$table . ':' . $row['uid']])) { 03480 03481 if ($fieldConf['l10n_mode'] == 'exclude' 03482 || ($fieldConf['l10n_mode'] == 'mergeIfNotBlank' && strcmp(trim($this->defaultLanguageData[$table . ':' . $row['uid']][$field]), ''))) { 03483 $value = $this->defaultLanguageData[$table . ':' . $row['uid']][$field]; 03484 } 03485 03486 } 03487 03488 return $value; 03489 } 03490 03491 /** 03492 * Renders the display of default language record content around current field. 03493 * Will render content if any is found in the internal array, $this->defaultLanguageData, depending on registerDefaultLanguageData() being called prior to this. 03494 * 03495 * @param string Table name of the record being edited 03496 * @param string Field name represented by $item 03497 * @param array Record array of the record being edited 03498 * @param string HTML of the form field. This is what we add the content to. 03499 * @return string Item string returned again, possibly with the original value added to. 03500 * @see getSingleField(), registerDefaultLanguageData() 03501 */ 03502 function renderDefaultLanguageContent($table, $field, $row, $item) { 03503 if (is_array($this->defaultLanguageData[$table . ':' . $row['uid']])) { 03504 $dLVal = t3lib_BEfunc::getProcessedValue($table, $field, $this->defaultLanguageData[$table . ':' . $row['uid']][$field], 0, 1); 03505 $fCfg = $GLOBALS['TCA'][$table]['columns'][$field]; 03506 03507 // Don't show content if it's for IRRE child records: 03508 if ($fCfg['config']['type'] != 'inline') { 03509 if (strcmp($dLVal, '')) { 03510 $item .= '<div class="typo3-TCEforms-originalLanguageValue">' . $this->getLanguageIcon($table, $row, 0) . 03511 $this->previewFieldValue($dLVal, $fCfg, $field) . ' </div>'; 03512 } 03513 03514 $prLang = $this->getAdditionalPreviewLanguages(); 03515 foreach ($prLang as $prL) { 03516 $dlVal = t3lib_BEfunc::getProcessedValue($table, $field, $this->additionalPreviewLanguageData[$table . ':' . $row['uid']][$prL['uid']][$field], 0, 1); 03517 03518 if (strcmp($dlVal, '')) { 03519 $item .= '<div class="typo3-TCEforms-originalLanguageValue">' . $this->getLanguageIcon($table, $row, 'v' . $prL['ISOcode']) . 03520 $this->previewFieldValue($dlVal, $fCfg, $field) . ' </div>'; 03521 } 03522 } 03523 } 03524 } 03525 03526 return $item; 03527 } 03528 03529 /** 03530 * Renders the diff-view of default language record content compared with what the record was originally translated from. 03531 * Will render content if any is found in the internal array, $this->defaultLanguageData, depending on registerDefaultLanguageData() being called prior to this. 03532 * 03533 * @param string Table name of the record being edited 03534 * @param string Field name represented by $item 03535 * @param array Record array of the record being edited 03536 * @param string HTML of the form field. This is what we add the content to. 03537 * @return string Item string returned again, possibly with the original value added to. 03538 * @see getSingleField(), registerDefaultLanguageData() 03539 */ 03540 function renderDefaultLanguageDiff($table, $field, $row, $item) { 03541 if (is_array($this->defaultLanguageData_diff[$table . ':' . $row['uid']])) { 03542 03543 // Initialize: 03544 $dLVal = array( 03545 'old' => $this->defaultLanguageData_diff[$table . ':' . $row['uid']], 03546 'new' => $this->defaultLanguageData[$table . ':' . $row['uid']], 03547 ); 03548 03549 if (isset($dLVal['old'][$field])) { // There must be diff-data: 03550 if (strcmp($dLVal['old'][$field], $dLVal['new'][$field])) { 03551 03552 // Create diff-result: 03553 $t3lib_diff_Obj = t3lib_div::makeInstance('t3lib_diff'); 03554 $diffres = $t3lib_diff_Obj->makeDiffDisplay( 03555 t3lib_BEfunc::getProcessedValue($table, $field, $dLVal['old'][$field], 0, 1), 03556 t3lib_BEfunc::getProcessedValue($table, $field, $dLVal['new'][$field], 0, 1) 03557 ); 03558 03559 $item .= '<div class="typo3-TCEforms-diffBox">' . 03560 '<div class="typo3-TCEforms-diffBox-header">' . htmlspecialchars($this->getLL('l_changeInOrig')) . ':</div>' . 03561 $diffres . 03562 '</div>'; 03563 } 03564 } 03565 } 03566 03567 return $item; 03568 } 03569 03570 /** 03571 * Renders the diff-view of vDEF fields in flexforms 03572 * 03573 * @param string Table name of the record being edited 03574 * @param string Field name represented by $item 03575 * @param array Record array of the record being edited 03576 * @param string HTML of the form field. This is what we add the content to. 03577 * @return string Item string returned again, possibly with the original value added to. 03578 * @see getSingleField(), registerDefaultLanguageData() 03579 */ 03580 function renderVDEFDiff($vArray, $vDEFkey) { 03581 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['flexFormXMLincludeDiffBase'] && isset($vArray[$vDEFkey . '.vDEFbase']) && strcmp($vArray[$vDEFkey . '.vDEFbase'], $vArray['vDEF'])) { 03582 03583 // Create diff-result: 03584 $t3lib_diff_Obj = t3lib_div::makeInstance('t3lib_diff'); 03585 $diffres = $t3lib_diff_Obj->makeDiffDisplay($vArray[$vDEFkey . '.vDEFbase'], $vArray['vDEF']); 03586 03587 $item .= '<div class="typo3-TCEforms-diffBox">' . 03588 '<div class="typo3-TCEforms-diffBox-header">' . htmlspecialchars($this->getLL('l_changeInOrig')) . ':</div>' . 03589 $diffres . 03590 '</div>'; 03591 } 03592 03593 return $item; 03594 } 03595 03596 03597 /************************************************************ 03598 * 03599 * Form element helper functions 03600 * 03601 ************************************************************/ 03602 03603 /** 03604 * Prints the selector box form-field for the db/file/select elements (multiple) 03605 * 03606 * @param string Form element name 03607 * @param string Mode "db", "file" (internal_type for the "group" type) OR blank (then for the "select" type) 03608 * @param string Commalist of "allowed" 03609 * @param array The array of items. For "select" and "group"/"file" this is just a set of value. For "db" its an array of arrays with table/uid pairs. 03610 * @param string Alternative selector box. 03611 * @param array An array of additional parameters, eg: "size", "info", "headers" (array with "selector" and "items"), "noBrowser", "thumbnails" 03612 * @param string On focus attribute string 03613 * @param string $table: (optional) Table name processing for 03614 * @param string $field: (optional) Field of table name processing for 03615 * @param string $uid: (optional) uid of table record processing for 03616 * @return string The form fields for the selection. 03617 */ 03618 function dbFileIcons($fName, $mode, $allowed, $itemArray, $selector = '', $params = array(), $onFocus = '', $table = '', $field = '', $uid = '') { 03619 03620 03621 $disabled = ''; 03622 if ($this->renderReadonly || $params['readOnly']) { 03623 $disabled = ' disabled="disabled"'; 03624 } 03625 03626 // Sets a flag which means some JavaScript is included on the page to support this element. 03627 $this->printNeededJS['dbFileIcons'] = 1; 03628 03629 // INIT 03630 $uidList = array(); 03631 $opt = array(); 03632 $itemArrayC = 0; 03633 03634 // Creating <option> elements: 03635 if (is_array($itemArray)) { 03636 $itemArrayC = count($itemArray); 03637 switch ($mode) { 03638 case 'db': 03639 foreach ($itemArray as $pp) { 03640 $pRec = t3lib_BEfunc::getRecordWSOL($pp['table'], $pp['id']); 03641 if (is_array($pRec)) { 03642 $pTitle = t3lib_BEfunc::getRecordTitle($pp['table'], $pRec, FALSE, TRUE); 03643 $pUid = $pp['table'] . '_' . $pp['id']; 03644 $uidList[] = $pUid; 03645 $opt[] = '<option value="' . htmlspecialchars($pUid) . '">' . htmlspecialchars($pTitle) . '</option>'; 03646 } 03647 } 03648 break; 03649 case 'file_reference': 03650 case 'file': 03651 foreach ($itemArray as $item) { 03652 $itemParts = explode('|', $item); 03653 $uidList[] = $pUid = $pTitle = $itemParts[0]; 03654 $opt[] = '<option value="' . htmlspecialchars(rawurldecode($itemParts[0])) . '">' . htmlspecialchars(basename(rawurldecode($itemParts[0]))) . '</option>'; 03655 } 03656 break; 03657 case 'folder': 03658 foreach ($itemArray as $pp) { 03659 $pParts = explode('|', $pp); 03660 $uidList[] = $pUid = $pTitle = $pParts[0]; 03661 $opt[] = '<option value="' . htmlspecialchars(rawurldecode($pParts[0])) . '">' . htmlspecialchars(rawurldecode($pParts[0])) . '</option>'; 03662 } 03663 break; 03664 default: 03665 foreach ($itemArray as $pp) { 03666 $pParts = explode('|', $pp, 2); 03667 $uidList[] = $pUid = $pParts[0]; 03668 $pTitle = $pParts[1]; 03669 $opt[] = '<option value="' . htmlspecialchars(rawurldecode($pUid)) . '">' . htmlspecialchars(rawurldecode($pTitle)) . '</option>'; 03670 } 03671 break; 03672 } 03673 } 03674 03675 // Create selector box of the options 03676 $sSize = $params['autoSizeMax'] ? t3lib_div::intInRange($itemArrayC + 1, t3lib_div::intInRange($params['size'], 1), $params['autoSizeMax']) : $params['size']; 03677 if (!$selector) { 03678 $selector = '<select id="' . uniqid('tceforms-multiselect-') . '" ' . ($params['noList'] ? 'style="display: none"' : 'size="' . $sSize . '"' . $this->insertDefStyle('group', 'tceforms-multiselect')) . ' multiple="multiple" name="' . $fName . '_list" ' . $onFocus . $params['style'] . $disabled . '>' . implode('', $opt) . '</select>'; 03679 } 03680 03681 03682 $icons = array( 03683 'L' => array(), 03684 'R' => array(), 03685 ); 03686 if (!$params['readOnly'] && !$params['noList']) { 03687 if (!$params['noBrowser']) { 03688 // check against inline uniqueness 03689 $inlineParent = $this->inline->getStructureLevel(-1); 03690 if (is_array($inlineParent) && $inlineParent['uid']) { 03691 if ($inlineParent['config']['foreign_table'] == $table && $inlineParent['config']['foreign_unique'] == $field) { 03692 $objectPrefix = $this->inline->inlineNames['object'] . '[' . $table . ']'; 03693 $aOnClickInline = $objectPrefix . '|inline.checkUniqueElement|inline.setUniqueElement'; 03694 $rOnClickInline = 'inline.revertUnique(\'' . $objectPrefix . '\',null,\'' . $uid . '\');'; 03695 } 03696 } 03697 $aOnClick = 'setFormValueOpenBrowser(\'' . $mode . '\',\'' . ($fName . '|||' . $allowed . '|' . $aOnClickInline) . '\'); return false;'; 03698 $icons['R'][] = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '">' . 03699 t3lib_iconWorks::getSpriteIcon('actions-insert-record', array('title' => htmlspecialchars($this->getLL('l_browse_' . ($mode == 'db' ? 'db' : 'file'))))) . 03700 '</a>'; 03701 } 03702 if (!$params['dontShowMoveIcons']) { 03703 if ($sSize >= 5) { 03704 $icons['L'][] = '<a href="#" onclick="setFormValueManipulate(\'' . $fName . '\',\'Top\'); return false;">' . 03705 t3lib_iconWorks::getSpriteIcon('actions-move-to-top', array('title' => htmlspecialchars($this->getLL('l_move_to_top')))) . 03706 '</a>'; 03707 } 03708 $icons['L'][] = '<a href="#" onclick="setFormValueManipulate(\'' . $fName . '\',\'Up\'); return false;">' . 03709 t3lib_iconWorks::getSpriteIcon('actions-move-up', array('title' => htmlspecialchars($this->getLL('l_move_up')))) . 03710 '</a>'; 03711 $icons['L'][] = '<a href="#" onclick="setFormValueManipulate(\'' . $fName . '\',\'Down\'); return false;">' . 03712 t3lib_iconWorks::getSpriteIcon('actions-move-down', array('title' => htmlspecialchars($this->getLL('l_move_down')))) . 03713 '</a>'; 03714 if ($sSize >= 5) { 03715 $icons['L'][] = '<a href="#" onclick="setFormValueManipulate(\'' . $fName . '\',\'Bottom\'); return false;">' . 03716 t3lib_iconWorks::getSpriteIcon('actions-move-to-bottom', array('title' => htmlspecialchars($this->getLL('l_move_to_bottom')))) . 03717 '</a>'; 03718 } 03719 } 03720 03721 $clipElements = $this->getClipboardElements($allowed, $mode); 03722 if (count($clipElements)) { 03723 $aOnClick = ''; 03724 foreach ($clipElements as $elValue) { 03725 if ($mode == 'db') { 03726 list($itemTable, $itemUid) = explode('|', $elValue); 03727 $itemTitle = $GLOBALS['LANG']->JScharCode(t3lib_BEfunc::getRecordTitle($itemTable, t3lib_BEfunc::getRecordWSOL($itemTable, $itemUid))); 03728 $elValue = $itemTable . '_' . $itemUid; 03729 } else { 03730 // 'file', 'file_reference' and 'folder' mode 03731 $itemTitle = 'unescape(\'' . rawurlencode(basename($elValue)) . '\')'; 03732 } 03733 $aOnClick .= 'setFormValueFromBrowseWin(\'' . $fName . '\',unescape(\'' . rawurlencode(str_replace('%20', ' ', $elValue)) . '\'),' . $itemTitle . ');'; 03734 } 03735 $aOnClick .= 'return false;'; 03736 $icons['R'][] = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '">' . 03737 t3lib_iconWorks::getSpriteIcon('actions-document-paste-into', array('title' => htmlspecialchars(sprintf($this->getLL('l_clipInsert_' . ($mode == 'db' ? 'db' : 'file')), count($clipElements))))) . 03738 '</a>'; 03739 } 03740 $rOnClick = $rOnClickInline . 'setFormValueManipulate(\'' . $fName . '\',\'Remove\'); return false'; 03741 $icons['L'][] = '<a href="#" onclick="' . htmlspecialchars($rOnClick) . '">' . 03742 t3lib_iconWorks::getSpriteIcon('actions-selection-delete', array('title' => htmlspecialchars($this->getLL('l_remove_selected')))) . 03743 '</a>'; 03744 } 03745 $imagesOnly = FALSE; 03746 if ($params['thumbnails'] && $params['info']) { 03747 // In case we have thumbnails, check if only images are allowed. 03748 // In this case, render them below the field, instead of to the right 03749 $allowedExtensionList = t3lib_div::trimExplode(' ', strtolower($params['info']), TRUE); 03750 $imageExtensionList = t3lib_div::trimExplode(',', strtolower($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']), TRUE); 03751 $imagesOnly = TRUE; 03752 foreach ($allowedExtensionList as $allowedExtension) { 03753 if (!t3lib_div::inArray($imageExtensionList, $allowedExtension)) { 03754 $imagesOnly = FALSE; 03755 break; 03756 } 03757 } 03758 } 03759 if ($imagesOnly) { 03760 $rightbox = ''; 03761 $thumbnails = '<div class="imagethumbs">' . $this->wrapLabels($params['thumbnails']) . '</div>'; 03762 } else { 03763 $rightbox = $this->wrapLabels($params['thumbnails']); 03764 $thumbnails = ''; 03765 } 03766 03767 // Hook: dbFileIcons_postProcess (requested by FAL-team for use with the "fal" extension) 03768 if (is_array ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['dbFileIcons'])) { 03769 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['dbFileIcons'] as $classRef) { 03770 $hookObject = t3lib_div::getUserObj($classRef); 03771 03772 if (!($hookObject instanceof t3lib_TCEforms_dbFileIconsHook)) { 03773 throw new UnexpectedValueException( 03774 '$hookObject must implement interface t3lib_TCEforms_dbFileIconsHook', 03775 1290167704 03776 ); 03777 } 03778 03779 $additionalParams = array( 03780 'mode' => $mode, 03781 'allowed' => $allowed, 03782 'itemArray' => $itemArray, 03783 'onFocus' => $onFocus, 03784 'table' => $table, 03785 'field' => $field, 03786 'uid' => $uid 03787 ); 03788 $hookObject->dbFileIcons_postProcess($params, $selector, $thumbnails, $icons, $rightbox, $fName, $uidList, $additionalParams, $this); 03789 } 03790 } 03791 03792 $str = '<table border="0" cellpadding="0" cellspacing="0" width="1"> 03793 ' . ($params['headers'] ? ' 03794 <tr> 03795 <td>' . $this->wrapLabels($params['headers']['selector']) . '</td> 03796 <td></td> 03797 <td></td> 03798 <td>' . ($params['thumbnails'] ? $this->wrapLabels($params['headers']['items']) : '') . '</td> 03799 </tr>' : '') . 03800 ' 03801 <tr> 03802 <td valign="top">' . 03803 $selector . 03804 $thumbnails . 03805 ($params['noList'] ? '' : '<span class="filetypes">' . $this->wrapLabels($params['info'])) . 03806 '</span></td> 03807 <td valign="top" class="icons">' . 03808 implode('<br />', $icons['L']) . '</td> 03809 <td valign="top" class="icons">' . 03810 implode('<br />', $icons['R']) . '</td> 03811 <td valign="top" class="thumbnails">' . 03812 $rightbox . 03813 '</td> 03814 </tr> 03815 </table>'; 03816 03817 // Creating the hidden field which contains the actual value as a comma list. 03818 $str .= '<input type="hidden" name="' . $fName . '" value="' . htmlspecialchars(implode(',', $uidList)) . '" />'; 03819 03820 return $str; 03821 } 03822 03823 /** 03824 * Returns array of elements from clipboard to insert into GROUP element box. 03825 * 03826 * @param string Allowed elements, Eg "pages,tt_content", "gif,jpg,jpeg,png" 03827 * @param string Mode of relations: "db" or "file" 03828 * @return array Array of elements in values (keys are insignificant), if none found, empty array. 03829 */ 03830 function getClipboardElements($allowed, $mode) { 03831 03832 $output = array(); 03833 03834 if (is_object($this->clipObj)) { 03835 switch ($mode) { 03836 case 'file_reference': 03837 case 'file': 03838 $elFromTable = $this->clipObj->elFromTable('_FILE'); 03839 $allowedExts = t3lib_div::trimExplode(',', $allowed, 1); 03840 03841 if ($allowedExts) { // If there are a set of allowed extensions, filter the content: 03842 foreach ($elFromTable as $elValue) { 03843 $pI = pathinfo($elValue); 03844 $ext = strtolower($pI['extension']); 03845 if (in_array($ext, $allowedExts)) { 03846 $output[] = $elValue; 03847 } 03848 } 03849 } else { // If all is allowed, insert all: (This does NOT respect any disallowed extensions, but those will be filtered away by the backend TCEmain) 03850 $output = $elFromTable; 03851 } 03852 break; 03853 case 'db': 03854 $allowedTables = t3lib_div::trimExplode(',', $allowed, 1); 03855 if (!strcmp(trim($allowedTables[0]), '*')) { // All tables allowed for relation: 03856 $output = $this->clipObj->elFromTable(''); 03857 } else { // Only some tables, filter them: 03858 foreach ($allowedTables as $tablename) { 03859 $elFromTable = $this->clipObj->elFromTable($tablename); 03860 $output = array_merge($output, $elFromTable); 03861 } 03862 } 03863 $output = array_keys($output); 03864 break; 03865 } 03866 } 03867 03868 return $output; 03869 } 03870 03871 /** 03872 * Wraps the icon of a relation item (database record or file) in a link opening the context menu for the item. 03873 * Icons will be wrapped only if $this->enableClickMenu is set. This must be done only if a global SOBE object exists and if the necessary JavaScript for displaying the context menus has been added to the page properties. 03874 * 03875 * @param string The icon HTML to wrap 03876 * @param string Table name (eg. "pages" or "tt_content") OR the absolute path to the file 03877 * @param integer The uid of the record OR if file, just blank value. 03878 * @return string HTML 03879 */ 03880 function getClickMenu($str, $table, $uid = '') { 03881 if ($this->enableClickMenu) { 03882 $onClick = $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon($str, $table, $uid, 1, '', '+copy,info,edit,view', TRUE); 03883 return '<a href="#" onclick="' . htmlspecialchars($onClick) . '">' . $str . '</a>'; 03884 } 03885 } 03886 03887 /** 03888 * Rendering wizards for form fields. 03889 * 03890 * @param array Array with the real item in the first value, and an alternative item in the second value. 03891 * @param array The "wizard" key from the config array for the field (from TCA) 03892 * @param string Table name 03893 * @param array The record array 03894 * @param string The field name 03895 * @param array Additional configuration array. (passed by reference!) 03896 * @param string The field name 03897 * @param array Special configuration if available. 03898 * @param boolean Whether the RTE could have been loaded. 03899 * @return string The new item value. 03900 */ 03901 function renderWizards($itemKinds, $wizConf, $table, $row, $field, &$PA, $itemName, $specConf, $RTE = 0) { 03902 03903 // Init: 03904 $fieldChangeFunc = $PA['fieldChangeFunc']; 03905 $item = $itemKinds[0]; 03906 $outArr = array(); 03907 $colorBoxLinks = array(); 03908 $fName = '[' . $table . '][' . $row['uid'] . '][' . $field . ']'; 03909 $md5ID = 'ID' . t3lib_div::shortmd5($itemName); 03910 $listFlag = '_list'; 03911 03912 $prefixOfFormElName = 'data[' . $table . '][' . $row['uid'] . '][' . $field . ']'; 03913 if (t3lib_div::isFirstPartOfStr($PA['itemFormElName'], $prefixOfFormElName)) { 03914 $flexFormPath = str_replace('][', '/', substr($PA['itemFormElName'], strlen($prefixOfFormElName) + 1, -1)); 03915 } 03916 03917 // Manipulate the field name (to be the true form field name) and remove a suffix-value if the item is a selector box with renderMode "singlebox": 03918 if ($PA['fieldConf']['config']['form_type'] == 'select') { 03919 if ($PA['fieldConf']['config']['maxitems'] <= 1) { // Single select situation: 03920 $listFlag = ''; 03921 } elseif ($PA['fieldConf']['config']['renderMode'] == 'singlebox') { 03922 $itemName .= '[]'; 03923 $listFlag = ''; 03924 } 03925 } 03926 03927 // traverse wizards: 03928 if (is_array($wizConf) && !$this->disableWizards) { 03929 $parametersOfWizards =& $specConf['wizards']['parameters']; 03930 03931 foreach ($wizConf as $wid => $wConf) { 03932 if (substr($wid, 0, 1) != '_' 03933 && (!$wConf['enableByTypeConfig'] || is_array($parametersOfWizards) && in_array($wid, $parametersOfWizards)) 03934 && ($RTE || !$wConf['RTEonly']) 03935 ) { 03936 03937 // Title / icon: 03938 $iTitle = htmlspecialchars($this->sL($wConf['title'])); 03939 if ($wConf['icon']) { 03940 $icon = $this->getIconHtml($wConf['icon'], $iTitle, $iTitle); 03941 } else { 03942 $icon = $iTitle; 03943 } 03944 03945 // 03946 switch ((string) $wConf['type']) { 03947 case 'userFunc': 03948 case 'script': 03949 case 'popup': 03950 case 'colorbox': 03951 if (!$wConf['notNewRecords'] || t3lib_div::testInt($row['uid'])) { 03952 03953 // Setting &P array contents: 03954 $params = array(); 03955 $params['params'] = $wConf['params']; 03956 $params['exampleImg'] = $wConf['exampleImg']; 03957 $params['table'] = $table; 03958 $params['uid'] = $row['uid']; 03959 $params['pid'] = $row['pid']; 03960 $params['field'] = $field; 03961 $params['flexFormPath'] = $flexFormPath; 03962 $params['md5ID'] = $md5ID; 03963 $params['returnUrl'] = $this->thisReturnUrl(); 03964 03965 // Resolving script filename and setting URL. 03966 if (!strcmp(substr($wConf['script'], 0, 4), 'EXT:')) { 03967 $wScript = t3lib_div::getFileAbsFileName($wConf['script']); 03968 if ($wScript) { 03969 $wScript = '../' . substr($wScript, strlen(PATH_site)); 03970 } else { 03971 break; 03972 } 03973 } else { 03974 $wScript = $wConf['script']; 03975 } 03976 $url = $this->backPath . $wScript . (strstr($wScript, '?') ? '' : '?'); 03977 03978 // If there is no script and the type is "colorbox", break right away: 03979 if ((string) $wConf['type'] == 'colorbox' && !$wConf['script']) { 03980 break; 03981 } 03982 03983 // If "script" type, create the links around the icon: 03984 if ((string) $wConf['type'] == 'script') { 03985 $aUrl = $url . t3lib_div::implodeArrayForUrl('', array('P' => $params)); 03986 $outArr[] = '<a href="' . htmlspecialchars($aUrl) . '" onclick="' . $this->blur() . 'return !TBE_EDITOR.isFormChanged();">' . 03987 $icon . 03988 '</a>'; 03989 } else { 03990 03991 // ... else types "popup", "colorbox" and "userFunc" will need additional parameters: 03992 $params['formName'] = $this->formName; 03993 $params['itemName'] = $itemName; 03994 $params['fieldChangeFunc'] = $fieldChangeFunc; 03995 $params['fieldChangeFuncHash'] = t3lib_div::hmac(serialize($fieldChangeFunc)); 03996 03997 switch ((string) $wConf['type']) { 03998 case 'popup': 03999 case 'colorbox': 04000 // Current form value is passed as P[currentValue]! 04001 $addJS = $wConf['popup_onlyOpenIfSelected'] ? 'if (!TBE_EDITOR.curSelected(\'' . $itemName . $listFlag . '\')){alert(' . $GLOBALS['LANG']->JScharCode($this->getLL('m_noSelItemForEdit')) . '); return false;}' : ''; 04002 $curSelectedValues = '+\'&P[currentSelectedValues]=\'+TBE_EDITOR.curSelected(\'' . $itemName . $listFlag . '\')'; 04003 $aOnClick = $this->blur() . 04004 $addJS . 04005 'vHWin=window.open(\'' . $url . t3lib_div::implodeArrayForUrl('', array('P' => $params)) . '\'+\'&P[currentValue]=\'+TBE_EDITOR.rawurlencode(' . $this->elName($itemName) . '.value,200)' . $curSelectedValues . ',\'popUp' . $md5ID . '\',\'' . $wConf['JSopenParams'] . '\');' . 04006 'vHWin.focus();return false;'; 04007 // Setting "colorBoxLinks" - user LATER to wrap around the color box as well: 04008 $colorBoxLinks = Array('<a href="#" onclick="' . htmlspecialchars($aOnClick) . '">', '</a>'); 04009 if ((string) $wConf['type'] == 'popup') { 04010 $outArr[] = $colorBoxLinks[0] . $icon . $colorBoxLinks[1]; 04011 } 04012 break; 04013 case 'userFunc': 04014 $params['item'] = &$item; // Reference set! 04015 $params['icon'] = $icon; 04016 $params['iTitle'] = $iTitle; 04017 $params['wConf'] = $wConf; 04018 $params['row'] = $row; 04019 $outArr[] = t3lib_div::callUserFunction($wConf['userFunc'], $params, $this); 04020 break; 04021 } 04022 } 04023 04024 // Hide the real form element? 04025 if (is_array($wConf['hideParent']) || $wConf['hideParent']) { 04026 $item = $itemKinds[1]; // Setting the item to a hidden-field. 04027 if (is_array($wConf['hideParent'])) { 04028 $item .= $this->getSingleField_typeNone_render($wConf['hideParent'], $PA['itemFormElValue']); 04029 } 04030 } 04031 } 04032 break; 04033 case 'select': 04034 $fieldValue = array('config' => $wConf); 04035 $TSconfig = $this->setTSconfig($table, $row); 04036 $TSconfig[$field] = $TSconfig[$field]['wizards.'][$wid . '.']; 04037 $selItems = $this->addSelectOptionsToItemArray($this->initItemArray($fieldValue), $fieldValue, $TSconfig, $field); 04038 04039 $opt = array(); 04040 $opt[] = '<option>' . $iTitle . '</option>'; 04041 foreach ($selItems as $p) { 04042 $opt[] = '<option value="' . htmlspecialchars($p[1]) . '">' . htmlspecialchars($p[0]) . '</option>'; 04043 } 04044 if ($wConf['mode'] == 'append') { 04045 $assignValue = $this->elName($itemName) . '.value=\'\'+this.options[this.selectedIndex].value+' . $this->elName($itemName) . '.value'; 04046 } elseif ($wConf['mode'] == 'prepend') { 04047 $assignValue = $this->elName($itemName) . '.value+=\'\'+this.options[this.selectedIndex].value'; 04048 } else { 04049 $assignValue = $this->elName($itemName) . '.value=this.options[this.selectedIndex].value'; 04050 } 04051 $sOnChange = $assignValue . ';this.blur();this.selectedIndex=0;' . implode('', $fieldChangeFunc); 04052 $outArr[] = '<select id="' . uniqid('tceforms-select-') . '" class="tceforms-select tceforms-wizardselect" name="_WIZARD' . $fName . '" onchange="' . htmlspecialchars($sOnChange) . '">' . implode('', $opt) . '</select>'; 04053 break; 04054 case 'suggest': 04055 if (isset($PA['fieldTSConfig']['suggest.']['default.']['hide']) && 04056 ((bool) $PA['fieldTSConfig']['suggest.']['default.']['hide'] == TRUE)) { 04057 break; 04058 } 04059 $outArr[] = $this->suggest->renderSuggestSelector($PA['itemFormElName'], $table, $field, $row, $PA); 04060 break; 04061 } 04062 04063 // Color wizard colorbox: 04064 if ((string) $wConf['type'] == 'colorbox') { 04065 $dim = t3lib_div::intExplode('x', $wConf['dim']); 04066 $dX = t3lib_div::intInRange($dim[0], 1, 200, 20); 04067 $dY = t3lib_div::intInRange($dim[1], 1, 200, 20); 04068 $color = $PA['itemFormElValue'] ? ' bgcolor="' . htmlspecialchars($PA['itemFormElValue']) . '"' : ''; 04069 $outArr[] = '<table border="0" cellpadding="0" cellspacing="0" id="' . $md5ID . '"' . $color . ' style="' . htmlspecialchars($wConf['tableStyle']) . '"> 04070 <tr> 04071 <td>' . 04072 $colorBoxLinks[0] . '<img ' . 04073 t3lib_iconWorks::skinImg($this->backPath, 04074 (strlen(trim($color)) == 0 || strcmp(trim($color), '0') == 0) ? 'gfx/colorpicker_empty.png' : 'gfx/colorpicker.png', 04075 'width="' . $dX . '" height="' . $dY . '"' . t3lib_BEfunc::titleAltAttrib(trim($iTitle . ' ' . $PA['itemFormElValue'])) . ' border="0"') . 04076 '>' . $colorBoxLinks[1] . 04077 '</td> 04078 </tr> 04079 </table>'; 04080 } 04081 } 04082 } 04083 04084 // For each rendered wizard, put them together around the item. 04085 if (count($outArr)) { 04086 if ($wizConf['_HIDDENFIELD']) { 04087 $item = $itemKinds[1]; 04088 } 04089 04090 $outStr = ''; 04091 $vAlign = $wizConf['_VALIGN'] ? ' style="vertical-align:' . $wizConf['_VALIGN'] . '"' : ''; 04092 if (count($outArr) > 1 || $wizConf['_PADDING']) { 04093 $dist = intval($wizConf['_DISTANCE']); 04094 if ($wizConf['_VERTICAL']) { 04095 $dist = $dist ? '<tr><td><img src="clear.gif" width="1" height="' . $dist . '" alt="" /></td></tr>' : ''; 04096 $outStr = '<tr><td>' . implode('</td></tr>' . $dist . '<tr><td>', $outArr) . '</td></tr>'; 04097 } else { 04098 $dist = $dist ? '<td><img src="clear.gif" height="1" width="' . $dist . '" alt="" /></td>' : ''; 04099 $outStr = '<tr><td' . $vAlign . '>' . implode('</td>' . $dist . '<td' . $vAlign . '>', $outArr) . '</td></tr>'; 04100 } 04101 $outStr = '<table border="0" cellpadding="' . intval($wizConf['_PADDING']) . '" cellspacing="' . intval($wizConf['_PADDING']) . '">' . $outStr . '</table>'; 04102 } else { 04103 $outStr = implode('', $outArr); 04104 } 04105 04106 if (!strcmp($wizConf['_POSITION'], 'left')) { 04107 $outStr = '<tr><td' . $vAlign . '>' . $outStr . '</td><td' . $vAlign . '>' . $item . '</td></tr>'; 04108 } elseif (!strcmp($wizConf['_POSITION'], 'top')) { 04109 $outStr = '<tr><td>' . $outStr . '</td></tr><tr><td>' . $item . '</td></tr>'; 04110 } elseif (!strcmp($wizConf['_POSITION'], 'bottom')) { 04111 $outStr = '<tr><td>' . $item . '</td></tr><tr><td>' . $outStr . '</td></tr>'; 04112 } else { 04113 $outStr = '<tr><td' . $vAlign . '>' . $item . '</td><td' . $vAlign . '>' . $outStr . '</td></tr>'; 04114 } 04115 04116 $item = '<table border="0" cellpadding="0" cellspacing="0">' . $outStr . '</table>'; 04117 } 04118 } 04119 return $item; 04120 } 04121 04122 /** 04123 * Get icon (for example for selector boxes) 04124 * 04125 * @param string Icon reference 04126 * @return array Array with two values; the icon file reference (relative to PATH_typo3 minus backPath), the icon file information array (getimagesize()) 04127 */ 04128 function getIcon($icon) { 04129 if (substr($icon, 0, 4) == 'EXT:') { 04130 $file = t3lib_div::getFileAbsFileName($icon); 04131 if ($file) { 04132 $file = substr($file, strlen(PATH_site)); 04133 $selIconFile = $this->backPath . '../' . $file; 04134 $selIconInfo = @getimagesize(PATH_site . $file); 04135 } 04136 } elseif (substr($icon, 0, 3) == '../') { 04137 $selIconFile = $this->backPath . t3lib_div::resolveBackPath($icon); 04138 $selIconInfo = @getimagesize(PATH_site . t3lib_div::resolveBackPath(substr($icon, 3))); 04139 } elseif (substr($icon, 0, 4) == 'ext/' || substr($icon, 0, 7) == 'sysext/') { 04140 $selIconFile = $this->backPath . $icon; 04141 $selIconInfo = @getimagesize(PATH_typo3 . $icon); 04142 } else { 04143 $selIconFile = t3lib_iconWorks::skinImg($this->backPath, 'gfx/' . $icon, '', 1); 04144 $iconPath = substr($selIconFile, strlen($this->backPath)); 04145 $selIconInfo = @getimagesize(PATH_typo3 . $iconPath); 04146 } 04147 return array($selIconFile, $selIconInfo); 04148 } 04149 04150 /** 04151 * Renders the $icon, supports a filename for skinImg or sprite-icon-name 04152 * @param $icon the icon passed, could be a file-reference or a sprite Icon name 04153 * @param string $alt alt attribute of the icon returned 04154 * @param string $title title attribute of the icon return 04155 * @return an tag representing to show the asked icon 04156 */ 04157 protected function getIconHtml($icon, $alt = '', $title = '') { 04158 $iconArray = $this->getIcon($icon); 04159 if (is_file(t3lib_div::resolveBackPath(PATH_typo3 . PATH_typo3_mod . $iconArray[0]))) { 04160 return '<img src="' . $iconArray[0] . '" alt="' . $alt . '" ' . ($title ? 'title="' . $title . '"' : '') . ' />'; 04161 } else { 04162 return t3lib_iconWorks::getSpriteIcon($icon, array('alt'=> $alt, 'title'=> $title)); 04163 } 04164 } 04165 04166 /** 04167 * Creates style attribute content for option tags in a selector box, primarily setting it up to show the icon of an element as background image (works in mozilla) 04168 * 04169 * @param string Icon string for option item 04170 * @return string Style attribute content, if any 04171 */ 04172 function optionTagStyle($iconString) { 04173 if ($iconString) { 04174 list($selIconFile, $selIconInfo) = $this->getIcon($iconString); 04175 04176 $padLeft = $selIconInfo[0] + 4; 04177 04178 if ($padLeft >= 18 && $padLeft <= 24) { 04179 $padLeft = 22; // In order to get the same padding for all option tags even if icon sizes differ a little, set it to 22 if it was between 18 and 24 pixels 04180 } 04181 04182 $padTop = t3lib_div::intInRange(($selIconInfo[1] - 12) / 2, 0); 04183 $styleAttr = 'background: #fff url(' . $selIconFile . ') 0% 50% no-repeat; height: ' . t3lib_div::intInRange(($selIconInfo[1] + 2) - $padTop, 0) . 'px; padding-top: ' . $padTop . 'px; padding-left: ' . $padLeft . 'px;'; 04184 return $styleAttr; 04185 } 04186 } 04187 04188 /** 04189 * Creates style attribute content for optgroup tags in a selector box, primarily setting it up to show the icon of an element as background image (works in mozilla). 04190 * 04191 * @param string Icon string for option item 04192 * @return string Style attribute content, if any 04193 */ 04194 function optgroupTagStyle($iconString) { 04195 if ($iconString) { 04196 list($selIconFile, $selIconInfo) = $this->getIcon($iconString); 04197 04198 $padLeft = $selIconInfo[0] + 4; 04199 04200 if($padLeft >= 18 && $padLeft <= 24) { 04201 // In order to get the same padding for all option tags even if icon sizes differ a little, 04202 // set it to 22, if it was between 18 and 24 pixels. 04203 $padLeft = 22; 04204 } 04205 $padTop = t3lib_div::intInRange(($selIconInfo[1] - 12) / 2, 0); 04206 04207 return 'background: #ffffff url(' . $selIconFile . ') 0 0 no-repeat; padding-top: ' . $padTop . 'px; padding-left: ' . $padLeft . 'px;'; 04208 } 04209 } 04210 04211 /** 04212 * Extracting values from a value/label list (as made by transferData class) 04213 * 04214 * @param string Value string where values are comma separated, intermixed with labels and rawurlencoded (this is what is delivered to TCEforms normally!) 04215 * @param array Values in an array 04216 * @return array Input string exploded with comma and for each value only the label part is set in the array. Keys are numeric 04217 */ 04218 function extractValuesOnlyFromValueLabelList($itemFormElValue) { 04219 // Get values of selected items: 04220 $itemArray = t3lib_div::trimExplode(',', $itemFormElValue, 1); 04221 foreach ($itemArray as $tk => $tv) { 04222 $tvP = explode('|', $tv, 2); 04223 $tvP[0] = rawurldecode($tvP[0]); 04224 04225 $itemArray[$tk] = $tvP[0]; 04226 } 04227 return $itemArray; 04228 } 04229 04230 /** 04231 * Wraps a string with a link to the palette. 04232 * 04233 * @param string The string to wrap in an A-tag 04234 * @param string The table name for which to open the palette. 04235 * @param array The palette pointer. 04236 * @param integer The record array 04237 */ 04238 function wrapOpenPalette($header, $table, $row, $palette, $retFunc) { 04239 $id = 'TCEFORMS_' . $table . '_' . $palette . '_' . $row['uid']; 04240 $res = '<a href="#" onclick="TBE_EDITOR.toggle_display_states(\'' . $id . '\',\'block\',\'none\'); return false;" >' . $header . '</a>'; 04241 return array($res, ''); 04242 } 04243 04244 /** 04245 * Add the id and the style property to the field palette 04246 * 04247 * @param string Palette Code 04248 * @param string The table name for which to open the palette. 04249 * @param string Palette ID 04250 * @param string The record array 04251 * @return boolean is collapsed 04252 */ 04253 function wrapPaletteField($code, $table, $row, $palette, $collapsed) { 04254 $display = $collapsed ? 'none' : 'block'; 04255 $id = 'TCEFORMS_' . $table . '_' . $palette . '_' . $row['uid']; 04256 $code = '<div id="' . $id . '" style="display:' . $display . ';" >' . $code . '</div>'; 04257 return $code; 04258 } 04259 04260 /** 04261 * Creates checkbox parameters 04262 * 04263 * @param string Form element name 04264 * @param integer The value of the checkbox (representing checkboxes with the bits) 04265 * @param integer Checkbox # (0-9?) 04266 * @param integer Total number of checkboxes in the array. 04267 * @param string Additional JavaScript for the onclick handler. 04268 * @return string The onclick attribute + possibly the checked-option set. 04269 */ 04270 function checkBoxParams($itemName, $thisValue, $c, $iCount, $addFunc = '') { 04271 $onClick = $this->elName($itemName) . '.value=this.checked?(' . $this->elName($itemName) . '.value|' . pow(2, $c) . '):(' . $this->elName($itemName) . '.value&' . (pow(2, $iCount) - 1 - pow(2, $c)) . ');' . 04272 $addFunc; 04273 $str = ' onclick="' . htmlspecialchars($onClick) . '"' . 04274 (($thisValue & pow(2, $c)) ? ' checked="checked"' : ''); 04275 return $str; 04276 } 04277 04278 /** 04279 * Returns element reference for form element name 04280 * 04281 * @param string Form element name 04282 * @return string Form element reference (JS) 04283 */ 04284 function elName($itemName) { 04285 return 'document.' . $this->formName . "['" . $itemName . "']"; 04286 } 04287 04288 /** 04289 * Returns 'this.blur();' string, if supported. 04290 * 04291 * @return string If the current browser supports styles, the string 'this.blur();' is returned. 04292 */ 04293 function blur() { 04294 return $GLOBALS['CLIENT']['FORMSTYLE'] ? 'this.blur();' : ''; 04295 } 04296 04297 /** 04298 * Returns the "returnUrl" of the form. Can be set externally or will be taken from "t3lib_div::linkThisScript()" 04299 * 04300 * @return string Return URL of current script 04301 */ 04302 function thisReturnUrl() { 04303 return $this->returnUrl ? $this->returnUrl : t3lib_div::linkThisScript(); 04304 } 04305 04306 /** 04307 * Returns the form field for a single HIDDEN field. 04308 * (Not used anywhere...?) 04309 * 04310 * @param string Table name 04311 * @param string Field name 04312 * @param array The row 04313 * @return string The hidden-field <input> tag. 04314 */ 04315 function getSingleHiddenField($table, $field, $row) { 04316 global $TCA; 04317 $out = ''; 04318 t3lib_div::loadTCA($table); 04319 if ($TCA[$table]['columns'][$field]) { 04320 04321 $uid = $row['uid']; 04322 $itemName = $this->prependFormFieldNames . '[' . $table . '][' . $uid . '][' . $field . ']'; 04323 $itemValue = $row[$field]; 04324 $item .= '<input type="hidden" name="' . $itemName . '" value="' . htmlspecialchars($itemValue) . '" />'; 04325 $out = $item; 04326 } 04327 return $out; 04328 } 04329 04330 /** 04331 * Returns parameters to set the width for a <input>/<textarea>-element 04332 * 04333 * @param integer The abstract size value (1-48) 04334 * @param boolean If this is for a text area. 04335 * @return string Either a "style" attribute string or "cols"/"size" attribute string. 04336 */ 04337 function formWidth($size = 48, $textarea = 0) { 04338 $widthAndStyleAttributes = ''; 04339 $fieldWidthAndStyle = $this->formWidthAsArray($size, $textarea); 04340 04341 if (!$GLOBALS['CLIENT']['FORMSTYLE']) { 04342 // If not setting the width by style-attribute 04343 $widthAndStyleAttributes = ' ' . $fieldWidthAndStyle['width']; 04344 } else { 04345 // Setting width by style-attribute. 'cols' MUST be avoided with NN6+ 04346 $widthAndStyleAttributes = ' style="' . htmlspecialchars($fieldWidthAndStyle['style']) . '"'; 04347 04348 if ($fieldWidthAndStyle['class']) { 04349 $widthAndStyleAttributes .= ' class="' . htmlspecialchars($fieldWidthAndStyle['class']) . '"'; 04350 } 04351 } 04352 04353 return $widthAndStyleAttributes; 04354 } 04355 04356 /** 04357 * Returns parameters to set the width for a <input>/<textarea>-element 04358 * 04359 * @param integer The abstract size value (1-48) 04360 * @param boolean If set, calculates sizes for a text area. 04361 * @return array An array containing style, class, and width attributes. 04362 */ 04363 protected function formWidthAsArray($size = 48, $textarea = FALSE) { 04364 $fieldWidthAndStyle = array('style' => '', 'class' => '', 'width' => ''); 04365 04366 if ($this->docLarge) { 04367 $size = round($size * $this->form_largeComp); 04368 } 04369 04370 $widthAttribute = $textarea ? 'cols' : 'size'; 04371 if (!$GLOBALS['CLIENT']['FORMSTYLE']) { 04372 // If not setting the width by style-attribute 04373 $fieldWidthAndStyle['width'] = $widthAttribute . '="' . $size . '"'; 04374 } else { 04375 // Setting width by style-attribute. 'cols' MUST be avoided with NN6+ 04376 $widthInPixels = ceil($size * $this->form_rowsToStylewidth); 04377 $fieldWidthAndStyle['style'] = 'width: ' . $widthInPixels . 'px; ' 04378 . $this->defStyle 04379 . $this->formElStyle($textarea ? 'text' : 'input'); 04380 04381 $fieldWidthAndStyle['class'] = $this->formElClass($textarea ? 'text' : 'input'); 04382 } 04383 04384 return $fieldWidthAndStyle; 04385 } 04386 04387 /** 04388 * Returns parameters to set with for a textarea field 04389 * 04390 * @param integer The abstract width (1-48) 04391 * @param string Empty or "off" (text wrapping in the field or not) 04392 * @return string The "cols" attribute string (or style from formWidth()) 04393 * @see formWidth() 04394 */ 04395 function formWidthText($size = 48, $wrap = '') { 04396 $wTags = $this->formWidth($size, 1); 04397 // Netscape 6+ seems to have this ODD problem where there WILL ALWAYS be wrapping with the cols-attribute set and NEVER without the col-attribute... 04398 if (strtolower(trim($wrap)) != 'off' && $GLOBALS['CLIENT']['BROWSER'] == 'net' && $GLOBALS['CLIENT']['VERSION'] >= 5) { 04399 $wTags .= ' cols="' . $size . '"'; 04400 } 04401 return $wTags; 04402 } 04403 04404 /** 04405 * Get style CSS values for the current field type. 04406 * 04407 * @param string Field type (eg. "check", "radio", "select") 04408 * @return string CSS attributes 04409 * @see formElStyleClassValue() 04410 */ 04411 function formElStyle($type) { 04412 return $this->formElStyleClassValue($type); 04413 } 04414 04415 /** 04416 * Get class attribute value for the current field type. 04417 * 04418 * @param string Field type (eg. "check", "radio", "select") 04419 * @return string CSS attributes 04420 * @see formElStyleClassValue() 04421 */ 04422 function formElClass($type) { 04423 return $this->formElStyleClassValue($type, TRUE); 04424 } 04425 04426 /** 04427 * Get style CSS values for the current field type. 04428 * 04429 * @param string Field type (eg. "check", "radio", "select") 04430 * @param boolean If set, will return value only if prefixed with CLASS, otherwise must not be prefixed "CLASS" 04431 * @return string CSS attributes 04432 */ 04433 function formElStyleClassValue($type, $class = FALSE) { 04434 // Get value according to field: 04435 if (isset($this->fieldStyle[$type])) { 04436 $style = trim($this->fieldStyle[$type]); 04437 } else { 04438 $style = trim($this->fieldStyle['all']); 04439 } 04440 04441 // Check class prefixed: 04442 if (substr($style, 0, 6) == 'CLASS:') { 04443 $out = $class ? trim(substr($style, 6)) : ''; 04444 } else { 04445 $out = !$class ? $style : ''; 04446 } 04447 04448 return $out; 04449 } 04450 04451 /** 04452 * Return default "style" / "class" attribute line. 04453 * 04454 * @param string Field type (eg. "check", "radio", "select") 04455 * @param string Additional class(es) to be added 04456 * @return string CSS attributes 04457 */ 04458 function insertDefStyle($type, $additionalClass = '') { 04459 $out = ''; 04460 04461 $style = trim($this->defStyle . $this->formElStyle($type)); 04462 $out .= $style ? ' style="' . htmlspecialchars($style) . '"' : ''; 04463 04464 $class = $this->formElClass($type); 04465 $classAttributeValue = join(' ', array_filter(array($class, $additionalClass))); 04466 $out .= $classAttributeValue ? ' class="' . htmlspecialchars($classAttributeValue) . '"' : ''; 04467 04468 return $out; 04469 } 04470 04471 /** 04472 * Create dynamic tab menu 04473 * 04474 * @param array Parts for the tab menu, fed to template::getDynTabMenu() 04475 * @param string ID string for the tab menu 04476 * @param integer If set to '1' empty tabs will be removed, If set to '2' empty tabs will be disabled 04477 * @return string HTML for the menu 04478 */ 04479 function getDynTabMenu($parts, $idString, $dividersToTabsBehaviour = 1) { 04480 if (is_object($GLOBALS['TBE_TEMPLATE'])) { 04481 $GLOBALS['TBE_TEMPLATE']->backPath = $this->backPath; 04482 return $GLOBALS['TBE_TEMPLATE']->getDynTabMenu($parts, $idString, 0, FALSE, 0, 1, FALSE, 1, $dividersToTabsBehaviour); 04483 } else { 04484 $output = ''; 04485 foreach ($parts as $singlePad) { 04486 $output .= ' 04487 <h3>' . htmlspecialchars($singlePad['label']) . '</h3> 04488 ' . ($singlePad['description'] ? '<p class="c-descr">' . nl2br(htmlspecialchars($singlePad['description'])) . '</p>' : '') . ' 04489 ' . $singlePad['content']; 04490 } 04491 04492 return '<div class="typo3-dyntabmenu-divs">' . $output . '</div>'; 04493 } 04494 } 04495 04496 04497 /************************************************************ 04498 * 04499 * Item-array manipulation functions (check/select/radio) 04500 * 04501 ************************************************************/ 04502 04503 /** 04504 * Initialize item array (for checkbox, selectorbox, radio buttons) 04505 * Will resolve the label value. 04506 * 04507 * @param array The "columns" array for the field (from TCA) 04508 * @return array An array of arrays with three elements; label, value, icon 04509 */ 04510 function initItemArray($fieldValue) { 04511 $items = array(); 04512 if (is_array($fieldValue['config']['items'])) { 04513 foreach ($fieldValue['config']['items'] as $itemValue) { 04514 $items[] = array($this->sL($itemValue[0]), $itemValue[1], $itemValue[2]); 04515 } 04516 } 04517 return $items; 04518 } 04519 04520 /** 04521 * Merges items into an item-array 04522 * 04523 * @param array The existing item array 04524 * @param array An array of items to add. NOTICE: The keys are mapped to values, and the values and mapped to be labels. No possibility of adding an icon. 04525 * @return array The updated $item array 04526 */ 04527 function addItems($items, $iArray) { 04528 global $TCA; 04529 if (is_array($iArray)) { 04530 foreach ($iArray as $value => $label) { 04531 $items[] = array($this->sl($label), $value); 04532 } 04533 } 04534 return $items; 04535 } 04536 04537 /** 04538 * Perform user processing of the items arrays of checkboxes, selectorboxes and radio buttons. 04539 * 04540 * @param array The array of items (label,value,icon) 04541 * @param array The "itemsProcFunc." from fieldTSconfig of the field. 04542 * @param array The config array for the field. 04543 * @param string Table name 04544 * @param array Record row 04545 * @param string Field name 04546 * @return array The modified $items array 04547 */ 04548 function procItems($items, $iArray, $config, $table, $row, $field) { 04549 global $TCA; 04550 04551 $params = array(); 04552 $params['items'] = &$items; 04553 $params['config'] = $config; 04554 $params['TSconfig'] = $iArray; 04555 $params['table'] = $table; 04556 $params['row'] = $row; 04557 $params['field'] = $field; 04558 04559 t3lib_div::callUserFunction($config['itemsProcFunc'], $params, $this); 04560 return $items; 04561 } 04562 04563 /** 04564 * Add selector box items of more exotic kinds. 04565 * 04566 * @param array The array of items (label,value,icon) 04567 * @param array The "columns" array for the field (from TCA) 04568 * @param array TSconfig for the table/row 04569 * @param string The fieldname 04570 * @return array The $items array modified. 04571 */ 04572 function addSelectOptionsToItemArray($items, $fieldValue, $TSconfig, $field) { 04573 global $TCA; 04574 04575 // Values from foreign tables: 04576 if ($fieldValue['config']['foreign_table']) { 04577 $items = $this->foreignTable($items, $fieldValue, $TSconfig, $field); 04578 if ($fieldValue['config']['neg_foreign_table']) { 04579 $items = $this->foreignTable($items, $fieldValue, $TSconfig, $field, 1); 04580 } 04581 } 04582 04583 // Values from a file folder: 04584 if ($fieldValue['config']['fileFolder']) { 04585 $fileFolder = t3lib_div::getFileAbsFileName($fieldValue['config']['fileFolder']); 04586 if (@is_dir($fileFolder)) { 04587 04588 // Configurations: 04589 $extList = $fieldValue['config']['fileFolder_extList']; 04590 $recursivityLevels = isset($fieldValue['config']['fileFolder_recursions']) ? t3lib_div::intInRange($fieldValue['config']['fileFolder_recursions'], 0, 99) : 99; 04591 04592 // Get files: 04593 $fileFolder = rtrim($fileFolder, '/') . '/'; 04594 $fileArr = t3lib_div::getAllFilesAndFoldersInPath(array(), $fileFolder, $extList, 0, $recursivityLevels); 04595 $fileArr = t3lib_div::removePrefixPathFromList($fileArr, $fileFolder); 04596 04597 foreach ($fileArr as $fileRef) { 04598 $fI = pathinfo($fileRef); 04599 $icon = t3lib_div::inList('gif,png,jpeg,jpg', strtolower($fI['extension'])) ? '../' . substr($fileFolder, strlen(PATH_site)) . $fileRef : ''; 04600 $items[] = array( 04601 $fileRef, 04602 $fileRef, 04603 $icon 04604 ); 04605 } 04606 } 04607 } 04608 04609 // If 'special' is configured: 04610 if ($fieldValue['config']['special']) { 04611 switch ($fieldValue['config']['special']) { 04612 case 'tables': 04613 $temp_tc = array_keys($TCA); 04614 $descr = ''; 04615 04616 foreach ($temp_tc as $theTableNames) { 04617 if (!$TCA[$theTableNames]['ctrl']['adminOnly']) { 04618 04619 // Icon: 04620 $icon = t3lib_iconWorks::mapRecordTypeToSpriteIconName($theTableNames, array()); 04621 04622 // Add help text 04623 $helpText = array(); 04624 $GLOBALS['LANG']->loadSingleTableDescription($theTableNames); 04625 $helpTextArray = $GLOBALS['TCA_DESCR'][$theTableNames]['columns']['']; 04626 if (!empty($helpTextArray['description'])) { 04627 $helpText['description'] = $helpTextArray['description']; 04628 } 04629 04630 // Item configuration: 04631 $items[] = array( 04632 $this->sL($TCA[$theTableNames]['ctrl']['title']), 04633 $theTableNames, 04634 $icon, 04635 $helpText 04636 ); 04637 } 04638 } 04639 break; 04640 case 'pagetypes': 04641 $theTypes = $TCA['pages']['columns']['doktype']['config']['items']; 04642 04643 foreach ($theTypes as $theTypeArrays) { 04644 // Icon: 04645 $icon = t3lib_iconWorks::mapRecordTypeToSpriteIconName('pages', array('doktype' => $theTypeArrays[1])); 04646 04647 // Item configuration: 04648 $items[] = array( 04649 $this->sL($theTypeArrays[0]), 04650 $theTypeArrays[1], 04651 $icon 04652 ); 04653 } 04654 break; 04655 case 'exclude': 04656 $theTypes = t3lib_BEfunc::getExcludeFields(); 04657 $descr = ''; 04658 04659 foreach ($theTypes as $theTypeArrays) { 04660 list($theTable, $theField) = explode(':', $theTypeArrays[1]); 04661 04662 // Add help text 04663 $helpText = array(); 04664 $GLOBALS['LANG']->loadSingleTableDescription($theTable); 04665 $helpTextArray = $GLOBALS['TCA_DESCR'][$theTable]['columns'][$theField]; 04666 if (!empty($helpTextArray['description'])) { 04667 $helpText['description'] = $helpTextArray['description']; 04668 } 04669 04670 // Item configuration: 04671 $items[] = array( 04672 rtrim($theTypeArrays[0], ':'), 04673 $theTypeArrays[1], 04674 'empty-empty', 04675 $helpText 04676 ); 04677 } 04678 break; 04679 case 'explicitValues': 04680 $theTypes = t3lib_BEfunc::getExplicitAuthFieldValues(); 04681 04682 // Icons: 04683 $icons = array( 04684 'ALLOW' => 'status-status-permission-granted', 04685 'DENY' => 'status-status-permission-denied', 04686 ); 04687 04688 // Traverse types: 04689 foreach ($theTypes as $tableFieldKey => $theTypeArrays) { 04690 04691 if (is_array($theTypeArrays['items'])) { 04692 // Add header: 04693 $items[] = array( 04694 $theTypeArrays['tableFieldLabel'], 04695 '--div--', 04696 ); 04697 04698 // Traverse options for this field: 04699 foreach ($theTypeArrays['items'] as $itemValue => $itemContent) { 04700 // Add item to be selected: 04701 $items[] = array( 04702 '[' . $itemContent[2] . '] ' . $itemContent[1], 04703 $tableFieldKey . ':' . preg_replace('/[:|,]/', '', $itemValue) . ':' . $itemContent[0], 04704 $icons[$itemContent[0]] 04705 ); 04706 } 04707 } 04708 } 04709 break; 04710 case 'languages': 04711 $items = array_merge($items, t3lib_BEfunc::getSystemLanguages()); 04712 break; 04713 case 'custom': 04714 // Initialize: 04715 $customOptions = $GLOBALS['TYPO3_CONF_VARS']['BE']['customPermOptions']; 04716 if (is_array($customOptions)) { 04717 foreach ($customOptions as $coKey => $coValue) { 04718 if (is_array($coValue['items'])) { 04719 // Add header: 04720 $items[] = array( 04721 $GLOBALS['LANG']->sl($coValue['header']), 04722 '--div--', 04723 ); 04724 04725 // Traverse items: 04726 foreach ($coValue['items'] as $itemKey => $itemCfg) { 04727 // Icon: 04728 if ($itemCfg[1]) { 04729 list($icon) = $this->getIcon($itemCfg[1]); 04730 } else { 04731 $icon = 'empty-empty'; 04732 } 04733 04734 // Add help text 04735 $helpText = array(); 04736 if (!empty($itemCfg[2])) { 04737 $helpText['description'] = $GLOBALS['LANG']->sl($itemCfg[2]); 04738 } 04739 04740 // Add item to be selected: 04741 $items[] = array( 04742 $GLOBALS['LANG']->sl($itemCfg[0]), 04743 $coKey . ':' . preg_replace('/[:|,]/', '', $itemKey), 04744 $icon, 04745 $helpText, 04746 ); 04747 } 04748 } 04749 } 04750 } 04751 break; 04752 case 'modListGroup': 04753 case 'modListUser': 04754 $loadModules = t3lib_div::makeInstance('t3lib_loadModules'); 04755 $loadModules->load($GLOBALS['TBE_MODULES']); 04756 04757 $modList = $fieldValue['config']['special'] == 'modListUser' ? $loadModules->modListUser : $loadModules->modListGroup; 04758 if (is_array($modList)) { 04759 $descr = ''; 04760 04761 foreach ($modList as $theMod) { 04762 04763 // Icon: 04764 $icon = $GLOBALS['LANG']->moduleLabels['tabs_images'][$theMod . '_tab']; 04765 if ($icon) { 04766 $icon = '../' . substr($icon, strlen(PATH_site)); 04767 } 04768 04769 // Add help text 04770 $helpText = array( 04771 'title' => $GLOBALS['LANG']->moduleLabels['labels'][$theMod . '_tablabel'], 04772 'description' => $GLOBALS['LANG']->moduleLabels['labels'][$theMod . '_tabdescr'] 04773 ); 04774 04775 // Item configuration: 04776 $items[] = array( 04777 $this->addSelectOptionsToItemArray_makeModuleData($theMod), 04778 $theMod, 04779 $icon, 04780 $helpText 04781 ); 04782 } 04783 } 04784 break; 04785 } 04786 } 04787 04788 // Return the items: 04789 return $items; 04790 } 04791 04792 /** 04793 * Creates value/label pair for a backend module (main and sub) 04794 * 04795 * @param string The module key 04796 * @return string The rawurlencoded 2-part string to transfer to interface 04797 * @access private 04798 * @see addSelectOptionsToItemArray() 04799 */ 04800 function addSelectOptionsToItemArray_makeModuleData($value) { 04801 $label = ''; 04802 // Add label for main module: 04803 $pp = explode('_', $value); 04804 if (count($pp) > 1) { 04805 $label .= $GLOBALS['LANG']->moduleLabels['tabs'][$pp[0] . '_tab'] . '>'; 04806 } 04807 // Add modules own label now: 04808 $label .= $GLOBALS['LANG']->moduleLabels['tabs'][$value . '_tab']; 04809 04810 return $label; 04811 } 04812 04813 /** 04814 * Adds records from a foreign table (for selector boxes) 04815 * 04816 * @param array The array of items (label,value,icon) 04817 * @param array The 'columns' array for the field (from TCA) 04818 * @param array TSconfig for the table/row 04819 * @param string The fieldname 04820 * @param boolean If set, then we are fetching the 'neg_' foreign tables. 04821 * @return array The $items array modified. 04822 * @see addSelectOptionsToItemArray(), t3lib_BEfunc::exec_foreign_table_where_query() 04823 */ 04824 function foreignTable($items, $fieldValue, $TSconfig, $field, $pFFlag = 0) { 04825 global $TCA; 04826 04827 // Init: 04828 $pF = $pFFlag ? 'neg_' : ''; 04829 $f_table = $fieldValue['config'][$pF . 'foreign_table']; 04830 $uidPre = $pFFlag ? '-' : ''; 04831 04832 // Get query: 04833 $res = t3lib_BEfunc::exec_foreign_table_where_query($fieldValue, $field, $TSconfig, $pF); 04834 04835 // Perform lookup 04836 if ($GLOBALS['TYPO3_DB']->sql_error()) { 04837 echo($GLOBALS['TYPO3_DB']->sql_error() . "\n\nThis may indicate a table defined in tables.php is not existing in the database!"); 04838 return array(); 04839 } 04840 04841 // Get label prefix. 04842 $lPrefix = $this->sL($fieldValue['config'][$pF . 'foreign_table_prefix']); 04843 04844 // Get icon field + path if any: 04845 $iField = $TCA[$f_table]['ctrl']['selicon_field']; 04846 $iPath = trim($TCA[$f_table]['ctrl']['selicon_field_path']); 04847 04848 // Traverse the selected rows to add them: 04849 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 04850 t3lib_BEfunc::workspaceOL($f_table, $row); 04851 04852 if (is_array($row)) { 04853 // Prepare the icon if available: 04854 if ($iField && $iPath && $row[$iField]) { 04855 $iParts = t3lib_div::trimExplode(',', $row[$iField], 1); 04856 $icon = '../' . $iPath . '/' . trim($iParts[0]); 04857 } elseif (t3lib_div::inList('singlebox,checkbox', $fieldValue['config']['renderMode'])) { 04858 $icon = t3lib_iconWorks::mapRecordTypeToSpriteIconName($f_table, $row); 04859 } else { 04860 $icon = 'empty-empty'; 04861 } 04862 04863 // Add the item: 04864 $items[] = array( 04865 $lPrefix . htmlspecialchars(t3lib_BEfunc::getRecordTitle($f_table, $row)), 04866 $uidPre . $row['uid'], 04867 $icon 04868 ); 04869 } 04870 } 04871 return $items; 04872 } 04873 04874 04875 /******************************************** 04876 * 04877 * Template functions 04878 * 04879 ********************************************/ 04880 04881 /** 04882 * Sets the design to the backend design. 04883 * Backend 04884 * 04885 * @return void 04886 */ 04887 function setNewBEDesign() { 04888 $template = t3lib_div::getURL(PATH_typo3 . $this->templateFile); 04889 04890 // Wrapping all table rows for a particular record being edited: 04891 $this->totalWrap = t3lib_parsehtml::getSubpart($template, '###TOTALWRAP###'); 04892 04893 // Wrapping a single field: 04894 $this->fieldTemplate = t3lib_parsehtml::getSubpart($template, '###FIELDTEMPLATE###'); 04895 04896 $this->palFieldTemplate = t3lib_parsehtml::getSubpart($template, '###PALETTE_FIELDTEMPLATE###'); 04897 $this->palFieldTemplateHeader = t3lib_parsehtml::getSubpart($template, '###PALETTE_FIELDTEMPLATE_HEADER###'); 04898 04899 $this->sectionWrap = t3lib_parsehtml::getSubpart($template, '###SECTION_WRAP###'); 04900 } 04901 04902 /** 04903 * This inserts the content of $inArr into the field-template 04904 * 04905 * @param array Array with key/value pairs to insert in the template. 04906 * @param string Alternative template to use instead of the default. 04907 * @return string 04908 */ 04909 function intoTemplate($inArr, $altTemplate = '') { 04910 // Put into template_ 04911 $fieldTemplateParts = explode('###FIELD_', $this->rplColorScheme($altTemplate ? $altTemplate : $this->fieldTemplate)); 04912 $out = current($fieldTemplateParts); 04913 foreach ($fieldTemplateParts as $part) { 04914 list($key, $val) = explode('###', $part, 2); 04915 $out .= $inArr[$key]; 04916 $out .= $val; 04917 } 04918 return $out; 04919 } 04920 04921 /** 04922 * Overwrite this function in own extended class to add own markers for output 04923 * 04924 * @param array Array with key/value pairs to insert in the template. 04925 * @param string The table name of the record 04926 * @param string The field name which this element is supposed to edit 04927 * @param array The record data array where the value(s) for the field can be found 04928 * @param array An array with additional configuration options. 04929 * @return array marker array for template output 04930 * @see function intoTemplate() 04931 */ 04932 function addUserTemplateMarkers($marker, $table, $field, $row, &$PA) { 04933 return $marker; 04934 } 04935 04936 /** 04937 * Wrapping labels 04938 * Currently not implemented - just returns input value. 04939 * 04940 * @param string Input string. 04941 * @return string Output string. 04942 */ 04943 function wrapLabels($str) { 04944 return $str; 04945 } 04946 04947 /** 04948 * Wraps all the table rows into a single table. 04949 * Used externally from scripts like alt_doc.php and db_layout.php (which uses TCEforms...) 04950 * 04951 * @param string Code to output between table-parts; table rows 04952 * @param array The record 04953 * @param string The table name 04954 * @return string 04955 */ 04956 function wrapTotal($c, $rec, $table) { 04957 $parts = $this->replaceTableWrap(explode('|', $this->totalWrap, 2), $rec, $table); 04958 return $parts[0] . $c . $parts[1] . implode('', $this->hiddenFieldAccum); 04959 } 04960 04961 /** 04962 * Generates a token and returns an input field with it 04963 * 04964 * @param string $formName Context of the token 04965 * @param string $tokenName The name of the token GET/POST variable 04966 * @return string a complete input field 04967 */ 04968 public static function getHiddenTokenField($formName = 'securityToken', $tokenName = 'formToken') { 04969 $formprotection = t3lib_formprotection_Factory::get(); 04970 return '<input type="hidden" name="' .$tokenName . '" value="' . $formprotection->generateToken($formName) . '-' . $formName . '" />'; 04971 } 04972 04973 /** 04974 * This replaces markers in the total wrap 04975 * 04976 * @param array An array of template parts containing some markers. 04977 * @param array The record 04978 * @param string The table name 04979 * @return string 04980 */ 04981 function replaceTableWrap($arr, $rec, $table) { 04982 global $TCA; 04983 04984 // Make "new"-label 04985 if (strstr($rec['uid'], 'NEW')) { 04986 $newLabel = ' <span class="typo3-TCEforms-newToken">' . 04987 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.new', 1) . 04988 '</span>'; 04989 04990 // Kasper: Should not be used here because NEW records are not offline workspace versions... 04991 #t3lib_BEfunc::fixVersioningPid($table,$rec); 04992 $truePid = t3lib_BEfunc::getTSconfig_pidValue($table, $rec['uid'], $rec['pid']); 04993 $prec = t3lib_BEfunc::getRecordWSOL('pages', $truePid, 'title'); 04994 $pageTitle = t3lib_BEfunc::getRecordTitle('pages', $prec, TRUE, FALSE); 04995 $rLabel = '<em>[PID: ' . $truePid . '] ' . $pageTitle . '</em>'; 04996 04997 // Fetch translated title of the table 04998 $tableTitle = $GLOBALS['LANG']->sL($GLOBALS['TCA'][$table]['ctrl']['title']); 04999 if ($table === 'pages') { 05000 $label = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.createNewPage', TRUE); 05001 $pageTitle = sprintf($label, $tableTitle); 05002 } else { 05003 $label = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.createNewRecord', TRUE); 05004 05005 if ($rec['pid'] == 0) { 05006 $label = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.createNewRecordRootLevel', TRUE); 05007 } 05008 $pageTitle = sprintf($label, $tableTitle, $pageTitle); 05009 } 05010 } else { 05011 $newLabel = ' <span class="typo3-TCEforms-recUid">[' . $rec['uid'] . ']</span>'; 05012 $rLabel = t3lib_BEfunc::getRecordTitle($table, $rec, TRUE, FALSE); 05013 $prec = t3lib_BEfunc::getRecordWSOL('pages', $rec['pid'], 'uid,title'); 05014 05015 // Fetch translated title of the table 05016 $tableTitle = $GLOBALS['LANG']->sL($GLOBALS['TCA'][$table]['ctrl']['title']); 05017 if ($table === 'pages') { 05018 $label = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.editPage', TRUE); 05019 05020 // Just take the record title and prepend an edit label. 05021 $pageTitle = sprintf($label, $tableTitle, $rLabel); 05022 } else { 05023 $label = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.editRecord', TRUE); 05024 05025 $pageTitle = t3lib_BEfunc::getRecordTitle('pages', $prec, TRUE, FALSE); 05026 if ($rLabel === t3lib_BEfunc::getNoRecordTitle(TRUE)) { 05027 $label = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.editRecordNoTitle', TRUE); 05028 } 05029 if ($rec['pid'] == 0) { 05030 $label = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.editRecordRootLevel', TRUE); 05031 } 05032 05033 if ($rLabel !== t3lib_BEfunc::getNoRecordTitle(TRUE)) { 05034 05035 // Just take the record title and prepend an edit label. 05036 $pageTitle = sprintf($label, $tableTitle, $rLabel, $pageTitle); 05037 } else { 05038 05039 // Leave out the record title since it is not set. 05040 $pageTitle = sprintf($label, $tableTitle, $pageTitle); 05041 } 05042 } 05043 } 05044 05045 foreach ($arr as $k => $v) { 05046 // Make substitutions: 05047 $arr[$k] = str_replace('###PAGE_TITLE###', $pageTitle, $arr[$k]); 05048 $arr[$k] = str_replace('###ID_NEW_INDICATOR###', $newLabel, $arr[$k]); 05049 $arr[$k] = str_replace('###RECORD_LABEL###', $rLabel, $arr[$k]); 05050 $arr[$k] = str_replace('###TABLE_TITLE###', htmlspecialchars($this->sL($TCA[$table]['ctrl']['title'])), $arr[$k]); 05051 05052 $arr[$k] = str_replace('###RECORD_ICON###', t3lib_iconWorks::getSpriteIconForRecord($table, $rec, array('title' => $this->getRecordPath($table, $rec))), $arr[$k]); 05053 05054 } 05055 return $arr; 05056 } 05057 05058 /** 05059 * Wraps an element in the $out_array with the template row for a "section" ($this->sectionWrap) 05060 * 05061 * @param array The array with form elements stored in (passed by reference and changed!) 05062 * @param integer The pointer to the entry in the $out_array (passed by reference and incremented!) 05063 * @return void 05064 */ 05065 function wrapBorder(&$out_array, &$out_pointer) { 05066 if ($this->sectionWrap && $out_array[$out_pointer]) { 05067 $tableAttribs = ''; 05068 $tableAttribs .= $this->borderStyle[0] ? ' style="' . htmlspecialchars($this->borderStyle[0]) . '"' : ''; 05069 $tableAttribs .= $this->borderStyle[2] ? ' background="' . htmlspecialchars($this->backPath . $this->borderStyle[2]) . '"' : ''; 05070 $tableAttribs .= $this->borderStyle[3] ? ' class="' . htmlspecialchars($this->borderStyle[3]) . '"' : ''; 05071 if ($tableAttribs) { 05072 $tableAttribs = 'border="0" cellspacing="0" cellpadding="0" width="100%"' . $tableAttribs; 05073 $out_array[$out_pointer] = str_replace('###CONTENT###', $out_array[$out_pointer], 05074 str_replace('###TABLE_ATTRIBS###', $tableAttribs, $this->sectionWrap)); 05075 } 05076 $out_pointer++; 05077 } 05078 } 05079 05080 /** 05081 * Replaces colorscheme markers in the template string 05082 * 05083 * @param string Template string with markers to be substituted. 05084 * @return string 05085 */ 05086 function rplColorScheme($inTemplate) { 05087 // Colors: 05088 $inTemplate = str_replace('###BGCOLOR###', $this->colorScheme[0] ? ' bgcolor="' . $this->colorScheme[0] . '"' : '', $inTemplate); 05089 $inTemplate = str_replace('###BGCOLOR_HEAD###', $this->colorScheme[1] ? ' bgcolor="' . $this->colorScheme[1] . '"' : '', $inTemplate); 05090 $inTemplate = str_replace('###FONTCOLOR_HEAD###', $this->colorScheme[3], $inTemplate); 05091 05092 // Classes: 05093 $inTemplate = str_replace('###CLASSATTR_1###', $this->classScheme[0] ? ' class="' . $this->classScheme[0] . '"' : '', $inTemplate); 05094 $inTemplate = str_replace('###CLASSATTR_2###', $this->classScheme[1] ? ' class="' . $this->classScheme[1] . '"' : '', $inTemplate); 05095 $inTemplate = str_replace('###CLASSATTR_4###', $this->classScheme[3] ? ' class="' . $this->classScheme[3] . '"' : '', $inTemplate); 05096 05097 return $inTemplate; 05098 } 05099 05100 /** 05101 * Returns divider. 05102 * Currently not implemented and returns only blank value. 05103 * 05104 * @return string Empty string 05105 */ 05106 function getDivider() { 05107 return ''; 05108 } 05109 05110 /** 05111 * Creates HTML output for a palette 05112 * 05113 * @param array The palette array to print 05114 * @return string HTML output 05115 */ 05116 function printPalette($palArr) { 05117 $fieldAttributes = $labelAttributes = ''; 05118 05119 // Init color/class attributes: 05120 if ($this->colorScheme[2]) { 05121 $labelAttributes .= ' bgcolor="' . $this->colorScheme[2] . '"'; 05122 } 05123 05124 if ($this->classScheme[2]) { 05125 $labelAttributes .= ' class="t3-form-palette-field-label ' . $this->classScheme[2] . '"'; 05126 } else { 05127 $labelAttributes .= ' class="t3-form-palette-field-label"'; 05128 } 05129 05130 if ($this->colorScheme[4]) { 05131 $fieldAttributes .= ' style="color: ' . $this->colorScheme[4] . '"'; 05132 } 05133 05134 if ($this->classScheme[4]) { 05135 $fieldAttributes .= ' class="t3-form-palette-field ' . $this->classScheme[4] . '"'; 05136 } 05137 05138 $row = 0; 05139 $hRow = $iRow = array(); 05140 $lastLineWasLinebreak = FALSE; 05141 05142 // Traverse palette fields and render them into containers: 05143 foreach ($palArr as $content) { 05144 if ($content['NAME'] === '--linebreak--') { 05145 if (!$lastLineWasLinebreak) { 05146 $row++; 05147 $lastLineWasLinebreak = TRUE; 05148 } 05149 } else { 05150 $lastLineWasLinebreak = FALSE; 05151 $fieldIdentifierForJs = $content['TABLE'] . '_' . $content['ID'] . '_' . $content['FIELD']; 05152 $iRow[$row][] = '<span class="t3-form-palette-field-container">' . 05153 '<label' . $labelAttributes . '>' . 05154 $content['NAME'] . 05155 '</label>' . 05156 '<span' . $fieldAttributes . '>' . 05157 '<img name="cm_' . $fieldIdentifierForJs . '" src="clear.gif" class="t3-form-palette-icon-contentchanged" alt="" />' . 05158 '<img name="req_' . $fieldIdentifierForJs . '" src="clear.gif" class="t3-form-palette-icon-required" alt="" />' . 05159 $content['ITEM'] . 05160 '</span>' . 05161 '</span>'; 05162 } 05163 } 05164 05165 // Final wrapping into the fieldset: 05166 $out = '<fieldset class="t3-form-palette-fieldset">'; 05167 for ($i = 0; $i <= $row; $i++) { 05168 if (isset($iRow[$i])) { 05169 $out .= implode('', $iRow[$i]); 05170 $out .= ($i < $row ? '<br />' : ''); 05171 } 05172 05173 } 05174 $out .= '</fieldset>'; 05175 return $out; 05176 } 05177 05178 05179 /** 05180 * Returns help-text ICON if configured for. 05181 * 05182 * @param string The table name 05183 * @param string The field name 05184 * @param boolean Force the return of the help-text icon. 05185 * @return string HTML, <a>-tag with 05186 * @deprecated since TYPO3 4.5, will be removed in TYPO3 4.7 05187 */ 05188 function helpTextIcon($table, $field, $force = 0) { 05189 t3lib_div::logDeprecatedFunction(); 05190 if ($this->globalShowHelp && $GLOBALS['TCA_DESCR'][$table]['columns'][$field] && (($this->edit_showFieldHelp == 'icon' && !$this->doLoadTableDescr($table)) || $force)) { 05191 return t3lib_BEfunc::helpTextIcon($table, $field, $this->backPath, $force); 05192 } else { 05193 // Detects fields with no CSH and outputs dummy line to insert into CSH locallang file: 05194 return '<span class="nbsp"> </span>'; 05195 } 05196 } 05197 05198 /** 05199 * Returns help text DESCRIPTION, if configured for. 05200 * 05201 * @param string The table name 05202 * @param string The field name 05203 * @return string 05204 * @deprecated since TYPO3 4.5, will be removed in TYPO3 4.7 05205 */ 05206 function helpText($table, $field) { 05207 t3lib_div::logDeprecatedFunction(); 05208 if ($this->globalShowHelp && $GLOBALS['TCA_DESCR'][$table]['columns'][$field] && ($this->edit_showFieldHelp == 'text' || $this->doLoadTableDescr($table))) { 05209 $fDat = $GLOBALS['TCA_DESCR'][$table]['columns'][$field]; 05210 return '<table border="0" cellpadding="2" cellspacing="0" width="90%"><tr><td valign="top" width="14">' . 05211 $this->helpTextIcon( 05212 $table, 05213 $field, 05214 $fDat['details'] || $fDat['syntax'] || $fDat['image_descr'] || $fDat['image'] || $fDat['seeAlso'] 05215 ) . 05216 '</td><td valign="top"><span class="typo3-TCEforms-helpText">' . 05217 $GLOBALS['LANG']->hscAndCharConv(strip_tags($fDat['description']), 1) . 05218 '</span></td></tr></table>'; 05219 } 05220 } 05221 05222 /** 05223 * Returns help-text ICON if configured for. 05224 * 05225 * @param string Field name 05226 * @param string Field title 05227 * @param string File name with CSH labels 05228 * @return string HTML, <a>-tag with 05229 * @deprecated since TYPO3 4.5, this function will be removed in TYPO3 4.7. Use t3lib_BEfunc::wrapInHelp() instead. 05230 */ 05231 function helpTextIcon_typeFlex($field, $fieldTitle, $cshFile) { 05232 t3lib_div::logDeprecatedFunction(); 05233 if ($this->globalShowHelp && $cshFile) { 05234 $value = $GLOBALS['LANG']->sL($cshFile . ':' . $field . '.description'); 05235 if (trim($value)) { 05236 if (substr($fieldTitle, -1, 1) == ':') { 05237 $fieldTitle = substr($fieldTitle, 0, strlen($fieldTitle) - 1); 05238 } 05239 05240 // Hover popup textbox with alttitle and description 05241 if ($this->edit_showFieldHelp == 'icon') { 05242 $arrow = t3lib_iconWorks::getSpriteIcon('actions-view-go-forward'); 05243 // add description text 05244 $hoverText = '<span class="paragraph">' . nl2br(htmlspecialchars($value)) . $arrow . '</span>'; 05245 // put header before the rest of the text 05246 $alttitle = $GLOBALS['LANG']->sL($cshFile . ':' . $field . '.alttitle'); 05247 if ($alttitle) { 05248 $hoverText = '<span class="header">' . $alttitle . '</span><br />' . $hoverText; 05249 } 05250 $hoverText = '<span class="typo3-csh-inline">' . $GLOBALS['LANG']->hscAndCharConv($hoverText, FALSE) . '</span>'; 05251 } 05252 05253 // CSH exists 05254 $params = base64_encode(serialize(array( 05255 'cshFile' => $cshFile, 05256 'field' => $field, 05257 'title' => $fieldTitle 05258 ))); 05259 $aOnClick = 'vHWin=window.open(\'' . $this->backPath . 'view_help.php?ffID=' . $params . '\',\'viewFieldHelp\',\'height=400,width=600,status=0,menubar=0,scrollbars=1\');vHWin.focus();return false;'; 05260 return '<a href="#" class="typo3-csh-link" onclick="' . htmlspecialchars($aOnClick) . '">' . 05261 t3lib_iconWorks::getSpriteIcon('actions-system-help-open') . $hoverText . 05262 '</a>'; 05263 } 05264 } 05265 return ''; 05266 } 05267 05268 /** 05269 * Returns help text DESCRIPTION, if configured for. 05270 * 05271 * @param string Field name 05272 * @param string CSH file name 05273 * @return string Description for the field with cion or empty string 05274 * @deprecated since TYPO3 4.5, this function will be removed in TYPO3 4.7. Use t3lib_BEfunc::wrapInHelp() instead. 05275 */ 05276 function helpText_typeFlex($field, $fieldTitle, $cshFile) { 05277 t3lib_div::logDeprecatedFunction(); 05278 if ($this->globalShowHelp && $cshFile && $this->edit_showFieldHelp == 'text') { 05279 $value = $GLOBALS['LANG']->sL($cshFile . ':' . $field . '.description'); 05280 if (trim($value)) { 05281 return '<table border="0" cellpadding="2" cellspacing="0" width="90%"><tr><td valign="top" width="14">' . 05282 $this->helpTextIcon_typeFlex( 05283 $field, 05284 $fieldTitle, 05285 $cshFile 05286 ) . 05287 '</td><td valign="top"><span class="typo3-TCEforms-helpText-flexform">' . 05288 $GLOBALS['LANG']->hscAndCharConv(strip_tags($value), 1) . 05289 '</span></td></tr></table>'; 05290 } 05291 } 05292 return ''; 05293 } 05294 05295 05296 /** 05297 * Setting the current color scheme ($this->colorScheme) based on $this->defColorScheme plus input string. 05298 * 05299 * @param string A color scheme string. 05300 * @return void 05301 */ 05302 function setColorScheme($scheme) { 05303 $this->colorScheme = $this->defColorScheme; 05304 $this->classScheme = $this->defClassScheme; 05305 05306 $parts = t3lib_div::trimExplode(',', $scheme); 05307 foreach ($parts as $key => $col) { 05308 // Split for color|class: 05309 list($color, $class) = t3lib_div::trimExplode('|', $col); 05310 05311 // Handle color values: 05312 if ($color) { 05313 $this->colorScheme[$key] = $color; 05314 } 05315 if ($color == '-') { 05316 $this->colorScheme[$key] = ''; 05317 } 05318 05319 // Handle class values: 05320 if ($class) { 05321 $this->classScheme[$key] = $class; 05322 } 05323 if ($class == '-') { 05324 $this->classScheme[$key] = ''; 05325 } 05326 } 05327 } 05328 05329 /** 05330 * Reset color schemes. 05331 * 05332 * @return void 05333 */ 05334 function resetSchemes() { 05335 $this->setColorScheme($GLOBALS['TBE_STYLES']['colorschemes'][0]); 05336 $this->fieldStyle = $GLOBALS['TBE_STYLES']['styleschemes'][0]; 05337 $this->borderStyle = $GLOBALS['TBE_STYLES']['borderschemes'][0]; 05338 } 05339 05340 /** 05341 * Store current color scheme 05342 * 05343 * @return void 05344 */ 05345 function storeSchemes() { 05346 $this->savedSchemes['classScheme'] = $this->classScheme; 05347 $this->savedSchemes['colorScheme'] = $this->colorScheme; 05348 $this->savedSchemes['fieldStyle'] = $this->fieldStyle; 05349 $this->savedSchemes['borderStyle'] = $this->borderStyle; 05350 } 05351 05352 /** 05353 * Restore the saved color scheme 05354 * 05355 * @return void 05356 */ 05357 function restoreSchemes() { 05358 $this->classScheme = $this->savedSchemes['classScheme']; 05359 $this->colorScheme = $this->savedSchemes['colorScheme']; 05360 $this->fieldStyle = $this->savedSchemes['fieldStyle']; 05361 $this->borderStyle = $this->savedSchemes['borderStyle']; 05362 } 05363 05364 05365 /******************************************** 05366 * 05367 * JavaScript related functions 05368 * 05369 ********************************************/ 05370 05371 /** 05372 * JavaScript code added BEFORE the form is drawn: 05373 * 05374 * @return string A <script></script> section with JavaScript. 05375 */ 05376 function JStop() { 05377 05378 $out = ''; 05379 05380 // Additional top HTML: 05381 if (count($this->additionalCode_pre)) { 05382 $out .= implode(' 05383 05384 <!-- NEXT: --> 05385 ', $this->additionalCode_pre); 05386 } 05387 05388 // Additional top JavaScript 05389 if (count($this->additionalJS_pre)) { 05390 $out .= ' 05391 05392 05393 <!-- 05394 JavaScript in top of page (before form): 05395 --> 05396 05397 <script type="text/javascript"> 05398 /*<![CDATA[*/ 05399 05400 ' . implode(' 05401 05402 // NEXT: 05403 ', $this->additionalJS_pre) . ' 05404 05405 /*]]>*/ 05406 </script> 05407 '; 05408 } 05409 05410 // Return result: 05411 return $out; 05412 } 05413 05414 /** 05415 * JavaScript code used for input-field evaluation. 05416 * 05417 * Example use: 05418 * 05419 * $msg .= 'Distribution time (hh:mm dd-mm-yy):<br /><input type="text" name="send_mail_datetime_hr" onchange="typo3form.fieldGet(\'send_mail_datetime\', \'datetime\', \'\', 0,0);"' . $GLOBALS['TBE_TEMPLATE']->formWidth(20) . ' /><input type="hidden" value="' . $GLOBALS['EXEC_TIME'] . '" name="send_mail_datetime" /><br />'; 05420 * $this->extJSCODE.='typo3form.fieldSet("send_mail_datetime", "datetime", "", 0,0);'; 05421 * 05422 * ... and then include the result of this function after the form 05423 * 05424 * @param string $formname: The identification of the form on the page. 05425 * @param boolean $update: Just extend/update existing settings, e.g. for AJAX call 05426 * @return string A section with JavaScript - if $update is false, embedded in <script></script> 05427 */ 05428 function JSbottom($formname = 'forms[0]', $update = FALSE) { 05429 $jsFile = array(); 05430 $elements = array(); 05431 05432 // required: 05433 foreach ($this->requiredFields as $itemImgName => $itemName) { 05434 $match = array(); 05435 if (preg_match('/^(.+)\[((\w|\d|_)+)\]$/', $itemName, $match)) { 05436 $record = $match[1]; 05437 $field = $match[2]; 05438 $elements[$record][$field]['required'] = 1; 05439 $elements[$record][$field]['requiredImg'] = $itemImgName; 05440 if (isset($this->requiredAdditional[$itemName]) && is_array($this->requiredAdditional[$itemName])) { 05441 $elements[$record][$field]['additional'] = $this->requiredAdditional[$itemName]; 05442 } 05443 } 05444 } 05445 // range: 05446 foreach ($this->requiredElements as $itemName => $range) { 05447 if (preg_match('/^(.+)\[((\w|\d|_)+)\]$/', $itemName, $match)) { 05448 $record = $match[1]; 05449 $field = $match[2]; 05450 $elements[$record][$field]['range'] = array($range[0], $range[1]); 05451 $elements[$record][$field]['rangeImg'] = $range['imgName']; 05452 } 05453 } 05454 05455 $this->TBE_EDITOR_fieldChanged_func = 'TBE_EDITOR.fieldChanged_fName(fName,formObj[fName+"_list"]);'; 05456 05457 if (!$update) { 05458 if ($this->loadMD5_JS) { 05459 $this->loadJavascriptLib('md5.js'); 05460 } 05461 05462 /** @var $pageRenderer t3lib_PageRenderer */ 05463 $pageRenderer = $GLOBALS['SOBE']->doc->getPageRenderer(); 05464 $pageRenderer->loadPrototype(); 05465 $pageRenderer->loadExtJS(); 05466 05467 // make textareas resizable and flexible 05468 if (!($GLOBALS['BE_USER']->uc['resizeTextareas'] == '0' && $GLOBALS['BE_USER']->uc['resizeTextareas_Flexible'] == '0')) { 05469 $pageRenderer->addCssFile($this->backPath . '../t3lib/js/extjs/ux/resize.css'); 05470 $this->loadJavascriptLib('../t3lib/js/extjs/ux/ext.resizable.js'); 05471 } 05472 $resizableSettings = array( 05473 'textareaMaxHeight' => $GLOBALS['BE_USER']->uc['resizeTextareas_MaxHeight'] > 0 ? $GLOBALS['BE_USER']->uc['resizeTextareas_MaxHeight'] : '600', 05474 'textareaFlexible' => (!$GLOBALS['BE_USER']->uc['resizeTextareas_Flexible'] == '0'), 05475 'textareaResize' => (!$GLOBALS['BE_USER']->uc['resizeTextareas'] == '0'), 05476 ); 05477 $pageRenderer->addInlineSettingArray('', $resizableSettings); 05478 05479 $this->loadJavascriptLib('../t3lib/jsfunc.evalfield.js'); 05480 $this->loadJavascriptLib('jsfunc.tbe_editor.js'); 05481 05482 // needed for tceform manipulation (date picker) 05483 $typo3Settings = array( 05484 'datePickerUSmode' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['USdateFormat'] ? 1 : 0, 05485 'dateFormat' => array('j-n-Y', 'G:i j-n-Y'), 05486 'dateFormatUS' => array('n-j-Y', 'G:i n-j-Y'), 05487 ); 05488 $pageRenderer->addInlineSettingArray('', $typo3Settings); 05489 05490 $this->loadJavascriptLib('../t3lib/js/extjs/tceforms.js'); 05491 05492 // if IRRE fields were processed, add the JavaScript functions: 05493 if ($this->inline->inlineCount) { 05494 $GLOBALS['SOBE']->doc->getPageRenderer()->loadScriptaculous(); 05495 $this->loadJavascriptLib('../t3lib/jsfunc.inline.js'); 05496 $out .= ' 05497 inline.setPrependFormFieldNames("' . $this->inline->prependNaming . '"); 05498 inline.setNoTitleString("' . addslashes(t3lib_BEfunc::getNoRecordTitle(TRUE)) . '"); 05499 '; 05500 } 05501 05502 // if Suggest fields were processed, add the JS functions 05503 if ($this->suggest->suggestCount > 0) { 05504 $pageRenderer->loadScriptaculous(); 05505 $this->loadJavascriptLib('../t3lib/js/jsfunc.tceforms_suggest.js'); 05506 } 05507 05508 // Toggle icons: 05509 $toggleIcon_open = t3lib_iconWorks::getSpriteIcon('actions-move-down', array('title' => 'Open')); 05510 $toggleIcon_close = t3lib_iconWorks::getSpriteIcon('actions-move-right', array('title' => 'Close')); 05511 05512 $out .= ' 05513 function getOuterHTML(idTagPrefix) { // Function getting the outerHTML of an element with id 05514 var str=($(idTagPrefix).inspect()+$(idTagPrefix).innerHTML+"</"+$(idTagPrefix).tagName.toLowerCase()+">"); 05515 return str; 05516 } 05517 function flexFormToggle(id) { // Toggling flexform elements on/off: 05518 Element.toggle(""+id+"-content"); 05519 05520 if (Element.visible(id+"-content")) { 05521 $(id+"-toggle").update(\'' . $toggleIcon_open . '\'); 05522 $(id+"-toggleClosed").value = 0; 05523 } else { 05524 $(id+"-toggle").update(\'' . $toggleIcon_close . '\'); 05525 $(id+"-toggleClosed").value = 1; 05526 } 05527 05528 var previewContent = ""; 05529 var children = $(id+"-content").getElementsByTagName("input"); 05530 for (var i = 0, length = children.length; i < length; i++) { 05531 if (children[i].type=="text" && children[i].value) previewContent+= (previewContent?" / ":"")+children[i].value; 05532 } 05533 if (previewContent.length>80) { 05534 previewContent = previewContent.substring(0,67)+"..."; 05535 } 05536 $(id+"-preview").update(previewContent); 05537 } 05538 function flexFormToggleSubs(id) { // Toggling sub flexform elements on/off: 05539 var descendants = $(id).immediateDescendants(); 05540 var isOpen=0; 05541 var isClosed=0; 05542 // Traverse and find how many are open or closed: 05543 for (var i = 0, length = descendants.length; i < length; i++) { 05544 if (descendants[i].id) { 05545 if (Element.visible(descendants[i].id+"-content")) {isOpen++;} else {isClosed++;} 05546 } 05547 } 05548 05549 // Traverse and toggle 05550 for (var i = 0, length = descendants.length; i < length; i++) { 05551 if (descendants[i].id) { 05552 if (isOpen!=0 && isClosed!=0) { 05553 if (Element.visible(descendants[i].id+"-content")) {flexFormToggle(descendants[i].id);} 05554 } else { 05555 flexFormToggle(descendants[i].id); 05556 } 05557 } 05558 } 05559 } 05560 function flexFormSortable(id) { // Create sortables for flexform sections 05561 Position.includeScrollOffsets = true; 05562 Sortable.create(id, {tag:\'div\',constraint: false, onChange:function(){ 05563 setActionStatus(id); 05564 } }); 05565 } 05566 function setActionStatus(id) { // Updates the "action"-status for a section. This is used to move and delete elements. 05567 var descendants = $(id).immediateDescendants(); 05568 05569 // Traverse and find how many are open or closed: 05570 for (var i = 0, length = descendants.length; i < length; i++) { 05571 if (descendants[i].id) { 05572 $(descendants[i].id+"-action").value = descendants[i].visible() ? i : "DELETE"; 05573 } 05574 } 05575 } 05576 05577 TBE_EDITOR.images.req.src = "' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/required_h.gif', '', 1) . '"; 05578 TBE_EDITOR.images.cm.src = "' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/content_client.gif', '', 1) . '"; 05579 TBE_EDITOR.images.sel.src = "' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/content_selected.gif', '', 1) . '"; 05580 TBE_EDITOR.images.clear.src = "' . $this->backPath . 'clear.gif"; 05581 05582 TBE_EDITOR.auth_timeout_field = ' . intval($GLOBALS['BE_USER']->auth_timeout_field) . '; 05583 TBE_EDITOR.formname = "' . $formname . '"; 05584 TBE_EDITOR.formnameUENC = "' . rawurlencode($formname) . '"; 05585 TBE_EDITOR.backPath = "' . addslashes($this->backPath) . '"; 05586 TBE_EDITOR.prependFormFieldNames = "' . $this->prependFormFieldNames . '"; 05587 TBE_EDITOR.prependFormFieldNamesUENC = "' . rawurlencode($this->prependFormFieldNames) . '"; 05588 TBE_EDITOR.prependFormFieldNamesCnt = ' . substr_count($this->prependFormFieldNames, '[') . '; 05589 TBE_EDITOR.isPalettedoc = ' . ($this->isPalettedoc ? addslashes($this->isPalettedoc) : 'null') . '; 05590 TBE_EDITOR.doSaveFieldName = "' . ($this->doSaveFieldName ? addslashes($this->doSaveFieldName) : '') . '"; 05591 TBE_EDITOR.labels.fieldsChanged = ' . $GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.fieldsChanged')) . '; 05592 TBE_EDITOR.labels.fieldsMissing = ' . $GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.fieldsMissing')) . '; 05593 TBE_EDITOR.labels.refresh_login = ' . $GLOBALS['LANG']->JScharCode($this->getLL('m_refresh_login')) . '; 05594 TBE_EDITOR.labels.onChangeAlert = ' . $GLOBALS['LANG']->JScharCode($this->getLL('m_onChangeAlert')) . '; 05595 evalFunc.USmode = ' . ($GLOBALS['TYPO3_CONF_VARS']['SYS']['USdateFormat'] ? '1' : '0') . '; 05596 TBE_EDITOR.backend_interface = "' . $GLOBALS['BE_USER']->uc['interfaceSetup'] . '"; 05597 '; 05598 } 05599 05600 // add JS required for inline fields 05601 if (count($this->inline->inlineData)) { 05602 $out .= ' 05603 inline.addToDataArray(' . json_encode($this->inline->inlineData) . '); 05604 '; 05605 } 05606 // Registered nested elements for tabs or inline levels: 05607 if (count($this->requiredNested)) { 05608 $out .= ' 05609 TBE_EDITOR.addNested(' . json_encode($this->requiredNested) . '); 05610 '; 05611 } 05612 // elements which are required or have a range definition: 05613 if (count($elements)) { 05614 $out .= ' 05615 TBE_EDITOR.addElements(' . json_encode($elements) . '); 05616 TBE_EDITOR.initRequired(); 05617 '; 05618 } 05619 // $this->additionalJS_submit: 05620 if ($this->additionalJS_submit) { 05621 $additionalJS_submit = implode('', $this->additionalJS_submit); 05622 $additionalJS_submit = str_replace(CR, '', $additionalJS_submit); 05623 $additionalJS_submit = str_replace(LF, '', $additionalJS_submit); 05624 $out .= ' 05625 TBE_EDITOR.addActionChecks("submit", "' . addslashes($additionalJS_submit) . '"); 05626 '; 05627 } 05628 05629 $out .= LF . implode(LF, $this->additionalJS_post) . LF . $this->extJSCODE; 05630 $out .= ' 05631 TBE_EDITOR.loginRefreshed(); 05632 '; 05633 05634 // Regular direct output: 05635 if (!$update) { 05636 $spacer = LF . TAB; 05637 $out = $spacer . implode($spacer, $jsFile) . t3lib_div::wrapJS($out); 05638 } 05639 05640 return $out; 05641 } 05642 05643 /** 05644 * Used to connect the db/file browser with this document and the formfields on it! 05645 * 05646 * @param string Form object reference (including "document.") 05647 * @return string JavaScript functions/code (NOT contained in a <script>-element) 05648 */ 05649 function dbFileCon($formObj = 'document.forms[0]') { 05650 // @TODO: Export this to an own file, it is more static than dynamic JavaScript -- olly 05651 $str = ' 05652 05653 // *************** 05654 // Used to connect the db/file browser with this document and the formfields on it! 05655 // *************** 05656 05657 var browserWin=""; 05658 05659 function setFormValueOpenBrowser(mode,params) { // 05660 var url = "' . $this->backPath . 'browser.php?mode="+mode+"&bparams="+params; 05661 05662 browserWin = window.open(url,"Typo3WinBrowser","height=650,width="+(mode=="db"?650:600)+",status=0,menubar=0,resizable=1,scrollbars=1"); 05663 browserWin.focus(); 05664 } 05665 function setFormValueFromBrowseWin(fName,value,label,exclusiveValues) { 05666 var formObj = setFormValue_getFObj(fName); 05667 if (formObj && value !== "--div--") { 05668 // Check if the form object has a "_list" element or not 05669 // The "_list" element exists for multiple selection select types 05670 var isMultiple = true; 05671 if (formObj[fName + "_list"]) { 05672 fObj = formObj[fName + "_list"]; 05673 } else { 05674 fObj = formObj[fName]; 05675 var isMultiple = false; 05676 } 05677 var len = fObj.length; 05678 05679 if (isMultiple) { 05680 // Clear elements if exclusive values are found 05681 if (exclusiveValues) { 05682 var m = new RegExp("(^|,)" + value + "($|,)"); 05683 if (exclusiveValues.match(m)) { 05684 // the new value is exclusive 05685 for (a = len - 1; a >= 0; a--) { 05686 fObj[a] = null; 05687 } 05688 len = 0; 05689 } else if (len == 1) { 05690 m = new RegExp("(^|,)" + fObj.options[0].value + "($|,)"); 05691 if (exclusiveValues.match(m)) { 05692 // the old value is exclusive 05693 fObj[0] = null; 05694 len = 0; 05695 } 05696 } 05697 } 05698 // Inserting element 05699 var setOK = 1; 05700 if (!formObj[fName + "_mul"] || formObj[fName + "_mul"].value == 0) { 05701 for (a = 0; a < len; a++) { 05702 if (fObj.options[a].value == value) { 05703 setOK = 0; 05704 } 05705 } 05706 } 05707 if (setOK) { 05708 fObj.length++; 05709 fObj.options[len].value = value; 05710 fObj.options[len].text = unescape(label); 05711 05712 // Traversing list and set the hidden-field 05713 setHiddenFromList(fObj,formObj[fName]); 05714 ' . $this->TBE_EDITOR_fieldChanged_func . ' 05715 } 05716 } else { 05717 // The incoming value consists of the table name, an underscore and the uid 05718 // For a single selection field we need only the uid, so we extract it 05719 var uidValue = value; 05720 var pattern = /_(\d+)$/; 05721 var result = value.match(pattern); 05722 if (result != null) { 05723 uidValue = result[1]; 05724 } 05725 // Change the selected value 05726 fObj.value = uidValue; 05727 } 05728 } 05729 } 05730 function setHiddenFromList(fObjSel,fObjHid) { // 05731 l=fObjSel.length; 05732 fObjHid.value=""; 05733 for (a=0;a<l;a++) { 05734 fObjHid.value+=fObjSel.options[a].value+","; 05735 } 05736 } 05737 function setFormValueManipulate(fName,type) { // 05738 var formObj = setFormValue_getFObj(fName); 05739 if (formObj) { 05740 var localArray_V = new Array(); 05741 var localArray_L = new Array(); 05742 var localArray_S = new Array(); 05743 var fObjSel = formObj[fName+"_list"]; 05744 var l=fObjSel.length; 05745 var c=0; 05746 if ((type=="Remove" && fObjSel.size > 1) || type=="Top" || type=="Bottom") { 05747 if (type=="Top") { 05748 for (a=0;a<l;a++) { 05749 if (fObjSel.options[a].selected==1) { 05750 localArray_V[c]=fObjSel.options[a].value; 05751 localArray_L[c]=fObjSel.options[a].text; 05752 localArray_S[c]=1; 05753 c++; 05754 } 05755 } 05756 } 05757 for (a=0;a<l;a++) { 05758 if (fObjSel.options[a].selected!=1) { 05759 localArray_V[c]=fObjSel.options[a].value; 05760 localArray_L[c]=fObjSel.options[a].text; 05761 localArray_S[c]=0; 05762 c++; 05763 } 05764 } 05765 if (type=="Bottom") { 05766 for (a=0;a<l;a++) { 05767 if (fObjSel.options[a].selected==1) { 05768 localArray_V[c]=fObjSel.options[a].value; 05769 localArray_L[c]=fObjSel.options[a].text; 05770 localArray_S[c]=1; 05771 c++; 05772 } 05773 } 05774 } 05775 } 05776 if (type=="Down") { 05777 var tC = 0; 05778 var tA = new Array(); 05779 05780 for (a=0;a<l;a++) { 05781 if (fObjSel.options[a].selected!=1) { 05782 // Add non-selected element: 05783 localArray_V[c]=fObjSel.options[a].value; 05784 localArray_L[c]=fObjSel.options[a].text; 05785 localArray_S[c]=0; 05786 c++; 05787 05788 // Transfer any accumulated and reset: 05789 if (tA.length > 0) { 05790 for (aa=0;aa<tA.length;aa++) { 05791 localArray_V[c]=fObjSel.options[tA[aa]].value; 05792 localArray_L[c]=fObjSel.options[tA[aa]].text; 05793 localArray_S[c]=1; 05794 c++; 05795 } 05796 05797 var tC = 0; 05798 var tA = new Array(); 05799 } 05800 } else { 05801 tA[tC] = a; 05802 tC++; 05803 } 05804 } 05805 // Transfer any remaining: 05806 if (tA.length > 0) { 05807 for (aa=0;aa<tA.length;aa++) { 05808 localArray_V[c]=fObjSel.options[tA[aa]].value; 05809 localArray_L[c]=fObjSel.options[tA[aa]].text; 05810 localArray_S[c]=1; 05811 c++; 05812 } 05813 } 05814 } 05815 if (type=="Up") { 05816 var tC = 0; 05817 var tA = new Array(); 05818 var c = l-1; 05819 05820 for (a=l-1;a>=0;a--) { 05821 if (fObjSel.options[a].selected!=1) { 05822 05823 // Add non-selected element: 05824 localArray_V[c]=fObjSel.options[a].value; 05825 localArray_L[c]=fObjSel.options[a].text; 05826 localArray_S[c]=0; 05827 c--; 05828 05829 // Transfer any accumulated and reset: 05830 if (tA.length > 0) { 05831 for (aa=0;aa<tA.length;aa++) { 05832 localArray_V[c]=fObjSel.options[tA[aa]].value; 05833 localArray_L[c]=fObjSel.options[tA[aa]].text; 05834 localArray_S[c]=1; 05835 c--; 05836 } 05837 05838 var tC = 0; 05839 var tA = new Array(); 05840 } 05841 } else { 05842 tA[tC] = a; 05843 tC++; 05844 } 05845 } 05846 // Transfer any remaining: 05847 if (tA.length > 0) { 05848 for (aa=0;aa<tA.length;aa++) { 05849 localArray_V[c]=fObjSel.options[tA[aa]].value; 05850 localArray_L[c]=fObjSel.options[tA[aa]].text; 05851 localArray_S[c]=1; 05852 c--; 05853 } 05854 } 05855 c=l; // Restore length value in "c" 05856 } 05857 05858 // Transfer items in temporary storage to list object: 05859 fObjSel.length = c; 05860 for (a=0;a<c;a++) { 05861 fObjSel.options[a].value = localArray_V[a]; 05862 fObjSel.options[a].text = localArray_L[a]; 05863 fObjSel.options[a].selected = localArray_S[a]; 05864 } 05865 setHiddenFromList(fObjSel,formObj[fName]); 05866 05867 ' . $this->TBE_EDITOR_fieldChanged_func . ' 05868 } 05869 } 05870 function setFormValue_getFObj(fName) { // 05871 var formObj = ' . $formObj . '; 05872 if (formObj) { 05873 // Take the form object if it is either of type select-one or of type-multiple and it has a "_list" element 05874 if (formObj[fName] && ((formObj[fName].type == "select-one") || (formObj[fName + "_list"] && formObj[fName + "_list"].type == "select-multiple"))) { 05875 return formObj; 05876 } else { 05877 alert("Formfields missing:\n fName: " + formObj[fName] + "\n fName_list:" + formObj[fName + "_list"] + "\n type:" + formObj[fName + "_list"].type + "\n fName:" + fName); 05878 } 05879 } 05880 return ""; 05881 } 05882 05883 // END: dbFileCon parts. 05884 '; 05885 return $str; 05886 } 05887 05888 /** 05889 * Prints necessary JavaScript for TCEforms (after the form HTML). 05890 * 05891 * @return void 05892 */ 05893 function printNeededJSFunctions() { 05894 // JS evaluation: 05895 $out = $this->JSbottom($this->formName); 05896 05897 05898 // Integrate JS functions for the element browser if such fields or IRRE fields were processed: 05899 if ($this->printNeededJS['dbFileIcons'] || $this->inline->inlineCount) { 05900 $out .= ' 05901 05902 05903 05904 <!-- 05905 JavaScript after the form has been drawn: 05906 --> 05907 05908 <script type="text/javascript"> 05909 /*<![CDATA[*/ 05910 ' . $this->dbFileCon('document.' . $this->formName) . ' 05911 /*]]>*/ 05912 </script>'; 05913 } 05914 return $out; 05915 } 05916 05917 /** 05918 * Returns necessary JavaScript for the top 05919 * 05920 * @return void 05921 */ 05922 function printNeededJSFunctions_top() { 05923 // JS evaluation: 05924 $out = $this->JStop($this->formName); 05925 return $out; 05926 } 05927 05928 /** 05929 * Includes a javascript library that exists in the core /typo3/ directory. The 05930 * backpath is automatically applied. 05931 * This method acts as wrapper for $GLOBALS['SOBE']->doc->loadJavascriptLib($lib). 05932 * 05933 * @param string $lib: Library name. Call it with the full path like "contrib/prototype/prototype.js" to load it 05934 * @return void 05935 */ 05936 public function loadJavascriptLib($lib) { 05937 $GLOBALS['SOBE']->doc->loadJavascriptLib($lib); 05938 } 05939 05940 05941 /******************************************** 05942 * 05943 * Various helper functions 05944 * 05945 ********************************************/ 05946 05947 05948 /** 05949 * Gets default record. Maybe not used anymore. FE-editor? 05950 * 05951 * @param string Database Tablename 05952 * @param integer PID value (positive / negative) 05953 * @return array "default" row. 05954 */ 05955 function getDefaultRecord($table, $pid = 0) { 05956 global $TCA; 05957 if ($TCA[$table]) { 05958 t3lib_div::loadTCA($table); 05959 $row = array(); 05960 05961 if ($pid < 0 && $TCA[$table]['ctrl']['useColumnsForDefaultValues']) { 05962 // Fetches the previous record: 05963 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'uid=' . abs($pid) . t3lib_BEfunc::deleteClause($table)); 05964 if ($drow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 05965 // Gets the list of fields to copy from the previous record. 05966 $fArr = explode(',', $TCA[$table]['ctrl']['useColumnsForDefaultValues']); 05967 foreach ($fArr as $theF) { 05968 if ($TCA[$table]['columns'][$theF]) { 05969 $row[$theF] = $drow[$theF]; 05970 } 05971 } 05972 } 05973 $GLOBALS['TYPO3_DB']->sql_free_result($res); 05974 } 05975 05976 foreach ($TCA[$table]['columns'] as $field => $info) { 05977 if (isset($info['config']['default'])) { 05978 $row[$field] = $info['config']['default']; 05979 } 05980 } 05981 05982 return $row; 05983 } 05984 } 05985 05986 /** 05987 * Return record path (visually formatted, using t3lib_BEfunc::getRecordPath() ) 05988 * 05989 * @param string Table name 05990 * @param array Record array 05991 * @return string The record path. 05992 * @see t3lib_BEfunc::getRecordPath() 05993 */ 05994 function getRecordPath($table, $rec) { 05995 t3lib_BEfunc::fixVersioningPid($table, $rec); 05996 list($tscPID, $thePidValue) = $this->getTSCpid($table, $rec['uid'], $rec['pid']); 05997 if ($thePidValue >= 0) { 05998 return t3lib_BEfunc::getRecordPath($tscPID, $this->readPerms(), 15); 05999 } 06000 } 06001 06002 /** 06003 * Returns the select-page read-access SQL clause. 06004 * Returns cached string, so you can call this function as much as you like without performance loss. 06005 * 06006 * @return string 06007 */ 06008 function readPerms() { 06009 if (!$this->perms_clause_set) { 06010 $this->perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1); 06011 $this->perms_clause_set = 1; 06012 } 06013 return $this->perms_clause; 06014 } 06015 06016 /** 06017 * Fetches language label for key 06018 * 06019 * @param string Language label reference, eg. 'LLL:EXT:lang/locallang_core.php:labels.blablabla' 06020 * @return string The value of the label, fetched for the current backend language. 06021 */ 06022 function sL($str) { 06023 return $GLOBALS['LANG']->sL($str); 06024 } 06025 06026 /** 06027 * Returns language label from locallang_core.php 06028 * Labels must be prefixed with either "l_" or "m_". 06029 * The prefix "l_" maps to the prefix "labels." inside locallang_core.php 06030 * The prefix "m_" maps to the prefix "mess." inside locallang_core.php 06031 * 06032 * @param string The label key 06033 * @return string The value of the label, fetched for the current backend language. 06034 */ 06035 function getLL($str) { 06036 $content = ''; 06037 06038 switch (substr($str, 0, 2)) { 06039 case 'l_': 06040 $content = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.' . substr($str, 2)); 06041 break; 06042 case 'm_': 06043 $content = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:mess.' . substr($str, 2)); 06044 break; 06045 } 06046 return $content; 06047 } 06048 06049 /** 06050 * Returns true, if the palette, $palette, is collapsed (not shown, but found in top-frame) for the table. 06051 * 06052 * @param string The table name 06053 * @param integer The palette pointer/number 06054 * @return boolean 06055 */ 06056 function isPalettesCollapsed($table, $palette) { 06057 global $TCA; 06058 06059 if ($TCA[$table]['ctrl']['canNotCollapse']) { 06060 return 0; 06061 } 06062 if (is_array($TCA[$table]['palettes'][$palette]) && $TCA[$table]['palettes'][$palette]['canNotCollapse']) { 06063 return 0; 06064 } 06065 return $this->palettesCollapsed; 06066 } 06067 06068 /** 06069 * Returns true, if the evaluation of the required-field code is OK. 06070 * 06071 * @param string The required-field code 06072 * @param array The record to evaluate 06073 * @param string FlexForm value key, eg. vDEF 06074 * @return boolean 06075 */ 06076 function isDisplayCondition($displayCond, $row, $ffValueKey = '') { 06077 $output = FALSE; 06078 06079 $parts = explode(':', $displayCond); 06080 switch ((string) $parts[0]) { // Type of condition: 06081 case 'FIELD': 06082 if ($ffValueKey) { 06083 if (strpos($parts[1], 'parentRec.') !== FALSE) { 06084 $fParts = explode('.', $parts[1]); 06085 $theFieldValue = $row['parentRec'][$fParts[1]]; 06086 } else { 06087 $theFieldValue = $row[$parts[1]][$ffValueKey]; 06088 } 06089 } else { 06090 $theFieldValue = $row[$parts[1]]; 06091 } 06092 06093 switch ((string) $parts[2]) { 06094 case 'REQ': 06095 if (strtolower($parts[3]) == 'true') { 06096 $output = $theFieldValue ? TRUE : FALSE; 06097 } elseif (strtolower($parts[3]) == 'false') { 06098 $output = !$theFieldValue ? TRUE : FALSE; 06099 } 06100 break; 06101 case '>': 06102 $output = $theFieldValue > $parts[3]; 06103 break; 06104 case '<': 06105 $output = $theFieldValue < $parts[3]; 06106 break; 06107 case '>=': 06108 $output = $theFieldValue >= $parts[3]; 06109 break; 06110 case '<=': 06111 $output = $theFieldValue <= $parts[3]; 06112 break; 06113 case '-': 06114 case '!-': 06115 $cmpParts = explode('-', $parts[3]); 06116 $output = $theFieldValue >= $cmpParts[0] && $theFieldValue <= $cmpParts[1]; 06117 if ($parts[2]{0} == '!') { 06118 $output = !$output; 06119 } 06120 break; 06121 case 'IN': 06122 case '!IN': 06123 $output = t3lib_div::inList($parts[3], $theFieldValue); 06124 if ($parts[2]{0} == '!') { 06125 $output = !$output; 06126 } 06127 break; 06128 case '=': 06129 case '!=': 06130 $output = t3lib_div::inList($parts[3], $theFieldValue); 06131 if ($parts[2]{0} == '!') { 06132 $output = !$output; 06133 } 06134 break; 06135 } 06136 break; 06137 case 'EXT': 06138 switch ((string) $parts[2]) { 06139 case 'LOADED': 06140 if (strtolower($parts[3]) == 'true') { 06141 $output = t3lib_extMgm::isLoaded($parts[1]) ? TRUE : FALSE; 06142 } elseif (strtolower($parts[3]) == 'false') { 06143 $output = !t3lib_extMgm::isLoaded($parts[1]) ? TRUE : FALSE; 06144 } 06145 break; 06146 } 06147 break; 06148 case 'REC': 06149 switch ((string) $parts[1]) { 06150 case 'NEW': 06151 if (strtolower($parts[2]) == 'true') { 06152 $output = !(intval($row['uid']) > 0) ? TRUE : FALSE; 06153 } elseif (strtolower($parts[2]) == 'false') { 06154 $output = (intval($row['uid']) > 0) ? TRUE : FALSE; 06155 } 06156 break; 06157 } 06158 break; 06159 case 'HIDE_L10N_SIBLINGS': 06160 if ($ffValueKey === 'vDEF') { 06161 $output = TRUE; 06162 } elseif ($parts[1] === 'except_admin' && $GLOBALS['BE_USER']->isAdmin()) { 06163 $output = TRUE; 06164 } 06165 break; 06166 case 'HIDE_FOR_NON_ADMINS': 06167 $output = $GLOBALS['BE_USER']->isAdmin() ? TRUE : FALSE; 06168 break; 06169 case 'VERSION': 06170 switch ((string) $parts[1]) { 06171 case 'IS': 06172 $isNewRecord = (intval($row['uid']) > 0 ? FALSE : TRUE); 06173 06174 // detection of version can be done be detecting the workspace of the user 06175 $isUserInWorkspace = ($GLOBALS['BE_USER']->workspace > 0 ? TRUE : FALSE); 06176 if (intval($row['pid']) == -1 || intval($row['_ORIG_pid']) == -1) { 06177 $isRecordDetectedAsVersion = TRUE; 06178 } else { 06179 $isRecordDetectedAsVersion = FALSE; 06180 } 06181 06182 // New records in a workspace are not handled as a version record 06183 // if it's no new version, we detect versions like this: 06184 // -- if user is in workspace: always true 06185 // -- if editor is in live ws: only true if pid == -1 06186 $isVersion = ($isUserInWorkspace || $isRecordDetectedAsVersion) && !$isNewRecord; 06187 06188 if (strtolower($parts[2]) == 'true') { 06189 $output = $isVersion; 06190 } else { 06191 if (strtolower($parts[2]) == 'false') { 06192 $output = !$isVersion; 06193 } 06194 } 06195 break; 06196 } 06197 break; 06198 } 06199 06200 return $output; 06201 } 06202 06203 /** 06204 * Return TSCpid (cached) 06205 * Using t3lib_BEfunc::getTSCpid() 06206 * 06207 * @param string Tablename 06208 * @param string UID value 06209 * @param string PID value 06210 * @return integer Returns the REAL pid of the record, if possible. If both $uid and $pid is strings, then pid=-1 is returned as an error indication. 06211 * @see t3lib_BEfunc::getTSCpid() 06212 */ 06213 function getTSCpid($table, $uid, $pid) { 06214 $key = $table . ':' . $uid . ':' . $pid; 06215 if (!isset($this->cache_getTSCpid[$key])) { 06216 $this->cache_getTSCpid[$key] = t3lib_BEfunc::getTSCpid($table, $uid, $pid); 06217 } 06218 return $this->cache_getTSCpid[$key]; 06219 } 06220 06221 /** 06222 * Returns true if descriptions should be loaded always 06223 * 06224 * @param string Table for which to check 06225 * @return boolean 06226 */ 06227 function doLoadTableDescr($table) { 06228 global $TCA; 06229 return $TCA[$table]['interface']['always_description']; 06230 } 06231 06232 /** 06233 * Returns an array of available languages (to use for FlexForms) 06234 * 06235 * @param boolean If set, only languages which are paired with a static_info_table / static_language record will be returned. 06236 * @param boolean If set, an array entry for a default language is set. 06237 * @return array 06238 */ 06239 function getAvailableLanguages($onlyIsoCoded = 1, $setDefault = 1) { 06240 $isL = t3lib_extMgm::isLoaded('static_info_tables'); 06241 06242 // Find all language records in the system: 06243 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('static_lang_isocode,title,uid', 'sys_language', 'pid=0 AND hidden=0' . t3lib_BEfunc::deleteClause('sys_language'), '', 'title'); 06244 06245 // Traverse them: 06246 $output = array(); 06247 if ($setDefault) { 06248 $output[0] = array( 06249 'uid' => 0, 06250 'title' => 'Default language', 06251 'ISOcode' => 'DEF' 06252 ); 06253 } 06254 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 06255 $output[$row['uid']] = $row; 06256 06257 if ($isL && $row['static_lang_isocode']) { 06258 $rr = t3lib_BEfunc::getRecord('static_languages', $row['static_lang_isocode'], 'lg_iso_2'); 06259 if ($rr['lg_iso_2']) { 06260 $output[$row['uid']]['ISOcode'] = $rr['lg_iso_2']; 06261 } 06262 } 06263 06264 if ($onlyIsoCoded && !$output[$row['uid']]['ISOcode']) { 06265 unset($output[$row['uid']]); 06266 } 06267 } 06268 return $output; 06269 } 06270 06271 /** 06272 * Initializes language icons etc. 06273 * 06274 * param string Table name 06275 * param array Record 06276 * param string Sys language uid OR ISO language code prefixed with "v", eg. "vDA" 06277 * @return void 06278 */ 06279 function getLanguageIcon($table, $row, $sys_language_uid) { 06280 global $TCA, $LANG; 06281 06282 $mainKey = $table . ':' . $row['uid']; 06283 06284 if (!isset($this->cachedLanguageFlag[$mainKey])) { 06285 t3lib_BEfunc::fixVersioningPid($table, $row); 06286 list($tscPID, $thePidValue) = $this->getTSCpid($table, $row['uid'], $row['pid']); 06287 06288 $t8Tools = t3lib_div::makeInstance('t3lib_transl8tools'); 06289 $this->cachedLanguageFlag[$mainKey] = $t8Tools->getSystemLanguages($tscPID, $this->backPath); 06290 } 06291 06292 // Convert sys_language_uid to sys_language_uid if input was in fact a string (ISO code expected then) 06293 if (!t3lib_div::testInt($sys_language_uid)) { 06294 foreach ($this->cachedLanguageFlag[$mainKey] as $rUid => $cD) { 06295 if ('v' . $cD['ISOcode'] === $sys_language_uid) { 06296 $sys_language_uid = $rUid; 06297 } 06298 } 06299 } 06300 06301 $out = ''; 06302 if ($this->cachedLanguageFlag[$mainKey][$sys_language_uid]['flagIcon']) { 06303 $out .= t3lib_iconWorks::getSpriteIcon($this->cachedLanguageFlag[$mainKey][$sys_language_uid]['flagIcon']); 06304 $out .= ' '; 06305 } else if ($this->cachedLanguageFlag[$mainKey][$sys_language_uid]['title']) { 06306 $out .= '[' . $this->cachedLanguageFlag[$mainKey][$sys_language_uid]['title'] . ']'; 06307 $out .= ' '; 06308 } 06309 return $out; 06310 } 06311 06312 /** 06313 * Rendering preview output of a field value which is not shown as a form field but just outputted. 06314 * 06315 * @param string The value to output 06316 * @param array Configuration for field. 06317 * @param string Name of field. 06318 * @return string HTML formatted output 06319 */ 06320 function previewFieldValue($value, $config, $field = '') { 06321 if ($config['config']['type'] === 'group' && 06322 ($config['config']['internal_type'] === 'file' || 06323 $config['config']['internal_type'] === 'file_reference')) { 06324 // Ignore uploadfolder if internal_type is file_reference 06325 if ($config['config']['internal_type'] === 'file_reference') { 06326 $config['config']['uploadfolder'] = ''; 06327 } 06328 06329 $show_thumbs = TRUE; 06330 $table = 'tt_content'; 06331 06332 // Making the array of file items: 06333 $itemArray = t3lib_div::trimExplode(',', $value, 1); 06334 06335 // Showing thumbnails: 06336 $thumbsnail = ''; 06337 if ($show_thumbs) { 06338 $imgs = array(); 06339 foreach ($itemArray as $imgRead) { 06340 $imgP = explode('|', $imgRead); 06341 $imgPath = rawurldecode($imgP[0]); 06342 06343 $rowCopy = array(); 06344 $rowCopy[$field] = $imgPath; 06345 06346 // Icon + clickmenu: 06347 $absFilePath = t3lib_div::getFileAbsFileName($config['config']['uploadfolder'] ? $config['config']['uploadfolder'] . '/' . $imgPath : $imgPath); 06348 06349 $fileInformation = pathinfo($imgPath); 06350 $fileIcon = t3lib_iconWorks::getSpriteIconForFile($imgPath, 06351 array('title' => 06352 htmlspecialchars($fileInformation['basename'] . 06353 ($absFilePath && @is_file($absFilePath) ? 06354 ' (' . t3lib_div::formatSize(filesize($absFilePath)) . 'bytes)' : 06355 ' - FILE NOT FOUND!') 06356 ) 06357 ) 06358 ); 06359 06360 $imgs[] = '<span class="nobr">' . t3lib_BEfunc::thumbCode($rowCopy, $table, $field, $this->backPath, 'thumbs.php', $config['config']['uploadfolder'], 0, ' align="middle"') . 06361 ($absFilePath ? $this->getClickMenu($fileIcon, $absFilePath) : $fileIcon) . 06362 $imgPath . 06363 '</span>'; 06364 } 06365 $thumbsnail = implode('<br />', $imgs); 06366 } 06367 06368 return $thumbsnail; 06369 } else { 06370 return nl2br(htmlspecialchars($value)); 06371 } 06372 } 06373 06374 /** 06375 * Generates and return information about which languages the current user should see in preview, configured by options.additionalPreviewLanguages 06376 * 06377 * return array Array of additional languages to preview 06378 */ 06379 function getAdditionalPreviewLanguages() { 06380 if (!isset($this->cachedAdditionalPreviewLanguages)) { 06381 if ($GLOBALS['BE_USER']->getTSConfigVal('options.additionalPreviewLanguages')) { 06382 $uids = t3lib_div::intExplode(',', $GLOBALS['BE_USER']->getTSConfigVal('options.additionalPreviewLanguages')); 06383 foreach ($uids as $uid) { 06384 if ($sys_language_rec = t3lib_BEfunc::getRecord('sys_language', $uid)) { 06385 $this->cachedAdditionalPreviewLanguages[$uid] = array('uid' => $uid); 06386 06387 if ($sys_language_rec['static_lang_isocode'] && t3lib_extMgm::isLoaded('static_info_tables')) { 06388 $staticLangRow = t3lib_BEfunc::getRecord('static_languages', $sys_language_rec['static_lang_isocode'], 'lg_iso_2'); 06389 if ($staticLangRow['lg_iso_2']) { 06390 $this->cachedAdditionalPreviewLanguages[$uid]['uid'] = $uid; 06391 $this->cachedAdditionalPreviewLanguages[$uid]['ISOcode'] = $staticLangRow['lg_iso_2']; 06392 } 06393 } 06394 } 06395 } 06396 } else { 06397 // None: 06398 $this->cachedAdditionalPreviewLanguages = array(); 06399 } 06400 } 06401 return $this->cachedAdditionalPreviewLanguages; 06402 } 06403 06404 /** 06405 * Push a new element to the dynNestedStack. Thus, every object know, if it's 06406 * nested in a tab or IRRE level and in which order this was processed. 06407 * 06408 * @param string $type: Type of the level, e.g. "tab" or "inline" 06409 * @param string $ident: Identifier of the level 06410 * @return void 06411 */ 06412 function pushToDynNestedStack($type, $ident) { 06413 $this->dynNestedStack[] = array($type, $ident); 06414 } 06415 06416 /** 06417 * Remove an element from the dynNestedStack. If $type and $ident 06418 * are set, the last element will only be removed, if it matches 06419 * what is expected to be removed. 06420 * 06421 * @param string $type: Type of the level, e.g. "tab" or "inline" 06422 * @param string $ident: Identifier of the level 06423 * @return void 06424 */ 06425 function popFromDynNestedStack($type = NULL, $ident = NULL) { 06426 if ($type != NULL && $ident != NULL) { 06427 $last = end($this->dynNestedStack); 06428 if ($type == $last[0] && $ident == $last[1]) { 06429 array_pop($this->dynNestedStack); 06430 } 06431 } else { 06432 array_pop($this->dynNestedStack); 06433 } 06434 } 06435 06436 /** 06437 * Get the dynNestedStack as associative array. 06438 * The result is e.g. ['tab','DTM-ABCD-1'], ['inline','data[13][table][uid][field]'], ['tab','DTM-DEFG-2'], ... 06439 * 06440 * @param boolean $json: Return a JSON string instead of an array - default: false 06441 * @param boolean $skipFirst: Skip the first element in the dynNestedStack - default: false 06442 * @return mixed Returns an associative array by default. If $json is true, it will be returned as JSON string. 06443 */ 06444 function getDynNestedStack($json = FALSE, $skipFirst = FALSE) { 06445 $result = $this->dynNestedStack; 06446 if ($skipFirst) { 06447 array_shift($result); 06448 } 06449 return ($json ? json_encode($result) : $result); 06450 } 06451 06452 /** 06453 * Takes care of registering properties in requiredFields and requiredElements. 06454 * The current hierarchy of IRRE and/or Tabs is stored. Thus, it is possible to determine, 06455 * which required field/element was filled incorrectly and show it, even if the Tab or IRRE 06456 * level is hidden. 06457 * 06458 * @param string $type: Type of requirement ('field' or 'range') 06459 * @param string $name: The name of the form field 06460 * @param mixed $value: For type 'field' string, for type 'range' array 06461 * @return void 06462 */ 06463 protected function registerRequiredProperty($type, $name, $value) { 06464 if ($type == 'field' && is_string($value)) { 06465 $this->requiredFields[$name] = $value; 06466 // requiredFields have name/value swapped! For backward compatibility we keep this: 06467 $itemName = $value; 06468 } elseif ($type == 'range' && is_array($value)) { 06469 $this->requiredElements[$name] = $value; 06470 $itemName = $name; 06471 } 06472 // Set the situation of nesting for the current field: 06473 $this->registerNestedElement($itemName); 06474 } 06475 06476 /** 06477 * Sets the current situation of nested tabs and inline levels for a given element. 06478 * 06479 * @param string $itemName: The element the nesting should be stored for 06480 * @param boolean $setLevel: Set the reverse level lookup - default: true 06481 * @return void 06482 */ 06483 protected function registerNestedElement($itemName, $setLevel = TRUE) { 06484 $dynNestedStack = $this->getDynNestedStack(); 06485 if (count($dynNestedStack) && preg_match('/^(.+\])\[(\w+)\]$/', $itemName, $match)) { 06486 array_shift($match); 06487 $this->requiredNested[$itemName] = array( 06488 'parts' => $match, 06489 'level' => $dynNestedStack, 06490 ); 06491 } 06492 } 06493 06494 /** 06495 * Insert additional style sheet link 06496 * 06497 * @param string $key: some key identifying the style sheet 06498 * @param string $href: uri to the style sheet file 06499 * @param string $title: value for the title attribute of the link element 06500 * @return string $relation: value for the rel attribute of the link element 06501 * @return void 06502 */ 06503 public function addStyleSheet($key, $href, $title = '', $relation = 'stylesheet') { 06504 $GLOBALS['SOBE']->doc->addStyleSheet($key, $href, $title, $relation); 06505 } 06506 } 06507 06508 06509 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tceforms.php'])) { 06510 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tceforms.php']); 06511 } 06512 06513 ?>
1.8.0