PageRenderTime 59ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/t3lib/tceforms/element/class.t3lib_tceforms_element_abstract.php

https://github.com/andreaswolf/typo3-tceforms
PHP | 2008 lines | 1122 code | 289 blank | 597 comment | 210 complexity | 088cfd15b8f8e622a04b364ea206452b MD5 | raw file
Possible License(s): Apache-2.0, BSD-2-Clause, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. abstract class t3lib_TCEforms_Element_Abstract implements t3lib_TCEforms_Element {
  3. /**
  4. * The container containing this element (may be a sheet, a palette, ...).
  5. *
  6. * @var t3lib_TCEforms_Container
  7. */
  8. protected $container;
  9. /**
  10. * The label of this element.
  11. *
  12. * @var string
  13. */
  14. protected $label;
  15. /**
  16. * The TCA config for the field
  17. *
  18. * @var array
  19. */
  20. protected $fieldSetup;
  21. protected $hiddenFieldListArr = array();
  22. protected static $cachedTSconfig;
  23. protected static $hookObjects = array();
  24. protected $fieldChangeFunc = array();
  25. /**
  26. * The table this field belongs to
  27. *
  28. * @var string
  29. */
  30. protected $table;
  31. /**
  32. * The fieldname as used in the database. This may contain special values ("--linebreak--" and the like), but they are
  33. * not handled in this class.
  34. * TODO create special handling classes for special values
  35. *
  36. * @var string
  37. */
  38. protected $field;
  39. /**
  40. * @var mixed
  41. */
  42. protected $itemFormElValue;
  43. /**
  44. * The record data this field belongs to
  45. *
  46. * @var array
  47. */
  48. protected $record;
  49. /**
  50. * Vars related to palettes
  51. */
  52. /**
  53. * The palette object
  54. *
  55. * @var t3lib_TCEforms_Container_Palette
  56. */
  57. protected $paletteObject;
  58. protected $pal = NULL;
  59. protected $_hasPalette = false;
  60. /**
  61. * TRUE if this field belongs to a palette (which may in turn belong to another field, or be on the top level)
  62. * TODO: check if this field is still neccessary with the Fluid rendering
  63. *
  64. * @var boolean
  65. */
  66. protected $isInPalette = false;
  67. /**
  68. * The record object this element belongs to
  69. *
  70. * @var t3lib_TCEforms_Record
  71. */
  72. protected $recordObject;
  73. /**
  74. * The outermost record object (only relevant for elements in IRRE records)
  75. *
  76. * @var t3lib_TCEforms_Record
  77. */
  78. protected $contextRecordObject;
  79. /**
  80. * The context this element is in (i.e., the top-level form)
  81. *
  82. * @var t3lib_TCEforms_Context
  83. */
  84. protected $contextObject;
  85. /**
  86. * The form object this element belongs to.
  87. * @var t3lib_TCEforms_Form
  88. */
  89. protected $parentFormObject;
  90. /*
  91. * Form field width compensation: Factor from NN4 form field widths to style-aware browsers
  92. * (like NN6+ and MSIE, with the $CLIENT[FORMSTYLE] value set)
  93. *
  94. * @var float
  95. */
  96. protected $form_rowsToStylewidth = 9.58;
  97. /**
  98. * Form field width compensation: Compensation for large documents, doc-tab (editing)
  99. *
  100. * @var float
  101. */
  102. protected $form_largeComp = 1.33;
  103. /**
  104. * The number of chars expected per row when the height of a text area field is automatically
  105. * calculated based on the number of characters found in the field content.
  106. *
  107. * @var integer
  108. */
  109. protected $charsPerRow=40;
  110. /**
  111. * The maximum abstract value for textareas
  112. *
  113. * @var integer
  114. */
  115. protected $maxTextareaWidth=48;
  116. /**
  117. * The maximum abstract value for input fields
  118. *
  119. * @var integer
  120. */
  121. protected $maxInputWidth=48;
  122. /**
  123. * Default style for the selector boxes used for multiple items in "select" and "group" types.
  124. *
  125. * @var string
  126. * @deprecated
  127. */
  128. protected $defaultMultipleSelectorStyle = 'width:250px;';
  129. protected $classScheme = array();
  130. protected $borderStyle = array();
  131. protected $fieldStyle = array();
  132. /**
  133. * The style of this element
  134. *
  135. * @var t3lib_TCA_FieldStyle
  136. */
  137. protected $style;
  138. /**
  139. *
  140. *
  141. * @var t3lib_TCEforms_FormBuilder
  142. */
  143. protected $formBuilder;
  144. /**
  145. * TRUE if the field should not be rendered at all. render() will return an empty string then.
  146. *
  147. * @var boolean
  148. */
  149. protected $doNotRender;
  150. /**
  151. *
  152. *
  153. * @var t3lib_TCEforms_Language
  154. */
  155. protected $language;
  156. /**
  157. * The stack of element identifier parts used for creating element identifiers.
  158. *
  159. * This will usually be imploded with a separator to create an identifier.
  160. *
  161. * @var array<string>
  162. */
  163. protected $elementIdentifierStack = array();
  164. /**
  165. * The (HTML) field name for this element
  166. *
  167. * @var string
  168. */
  169. protected $formFieldName;
  170. /**
  171. * The (HTML) field name for file elements
  172. *
  173. * @var string
  174. */
  175. protected $fileFormFieldName;
  176. /**
  177. * The (HTML) id for this element
  178. *
  179. * @var string
  180. */
  181. protected $formFieldId;
  182. /**
  183. * Additional attributes for the HTML element
  184. *
  185. * @var array
  186. */
  187. protected $additionalAttributes = array();
  188. public function __construct($fieldName, $fieldConfig, $label='', $extra='') {
  189. global $TYPO3_CONF_VARS;
  190. $this->fieldSetup = $fieldConfig;
  191. $this->field = $fieldName;
  192. $this->extra = $extra;
  193. $this->label = $label;
  194. if (count(self::$hookObjects) == 0) {
  195. // Prepare user defined objects (if any) for hooks which extend this function:
  196. self::$hookObjects['getMainFields'] = array();
  197. if (is_array ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['getMainFieldsClass'])) {
  198. foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['getMainFieldsClass'] as $classRef) {
  199. self::$hookObjects['getMainFields'][] = &t3lib_div::getUserObj($classRef);
  200. }
  201. }
  202. self::$hookObjects['getSingleFields'] = array();
  203. if (is_array ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['getSingleFieldClass'])) {
  204. foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tceforms.php']['getSingleFieldClass'] as $classRef) {
  205. self::$hookObjects['getSingleFields'][] = &t3lib_div::getUserObj($classRef);
  206. }
  207. }
  208. }
  209. $this->resetStyles();
  210. }
  211. public function init() {
  212. global $BE_USER;
  213. // code mainly copied/moved from t3lib_tceforms::getSingleField
  214. $this->formFieldName = $this->fileFormFieldName = $this->parentFormObject->createElementIdentifier($this, 'name');
  215. $this->formFieldId = $this->parentFormObject->createElementIdentifier($this, 'id');
  216. // Hook: getSingleField_preProcess
  217. foreach (self::$hookObjects['getSingleFields'] as $hookObj) {
  218. if (method_exists($hookObj,'getSingleField_preProcess')) {
  219. $hookObj->getSingleField_preProcess($this->table, $this->field, $this->record, $this->label, $this->palette, $this->extra, $this->pal, $this);
  220. }
  221. }
  222. $this->defaultLanguageValue = $this->recordObject->getDefaultLanguageValue($this->field);
  223. // TODO move this to FormBuilder
  224. //$skipThisField = $this->inline->skipField($table, $this->field, $this->record, $this->fieldSetup['config']);
  225. // Check if this field is configured and editable (according to excludefields + other configuration).
  226. // If not, it won't be rendered
  227. if (!($this->hasFieldConfig()
  228. && !$skipThisField // TODO: check this before calling render(), i.e. in the record object -- andreaswolf
  229. && (!$this->isExcludeField() || $BE_USER->check('non_exclude_fields',$this->table.':'.$this->field))
  230. && !$this->isPassThroughField()
  231. && ($this->isRteEnabled() || !$this->isOnlyShownIfRteIsEnabled())
  232. && (!$this->hasDisplayCondition() || $this->evaluateDisplayCondition())
  233. && (!$TCA[$this->table]['ctrl']['languageField'] || $this->fieldSetup['l10n_display'] || strcmp($this->fieldSetup['l10n_mode'],'exclude') || $this->record[$TCA[$this->table]['ctrl']['languageField']]<=0)
  234. && (!$TCA[$this->table]['ctrl']['languageField'] || !$this->localizationMode || $this->localizationMode===$this->fieldSetup['l10n_cat'])
  235. )) {
  236. $this->doNotRender = TRUE;
  237. }
  238. // Fetching the TSconfig for the current table/field. This includes the $this->record which means that
  239. $this->fieldTSConfig = $this->getTSconfig();
  240. // If the field is disabled by TSconfig do not render it
  241. if (!$this->doNotRender && $this->fieldTSConfig['disabled']) {
  242. $this->commentMessages[] = $this->formFieldName . ': Disabled by TSconfig';
  243. $this->doNotRender = TRUE;
  244. }
  245. // TODO check if the label works correctly under all circumstances
  246. if (!$this->doNotRender) {
  247. $this->label = ($this->label ? $this->label : $this->fieldSetup['label']);
  248. $this->label = ($this->fieldTSConfig['label'] ? $this->fieldTSConfig['label'] : $this->label);
  249. $this->label = ($this->fieldTSConfig['label.'][$GLOBALS['LANG']->lang] ? $this->fieldTSConfig['label.'][$GLOBALS['LANG']->lang] : $this->label);
  250. $this->label = $this->sL($this->label);
  251. // 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
  252. $this->label = t3lib_div::deHSCentities(htmlspecialchars($this->label));
  253. if (t3lib_div::testInt($this->record['uid']) && $this->fieldTSConfig['linkTitleToSelf'] && !t3lib_div::_GP('columnsOnly')) {
  254. $lTTS_url = $this->backPath.'alt_doc.php?edit['.$this->table.']['.$this->record['uid'].']=edit&columnsOnly='.$this->field.'&returnUrl='.rawurlencode($this->thisReturnUrl());
  255. $this->label = '<a href="'.htmlspecialchars($lTTS_url).'">'.$this->label.'</a>';
  256. }
  257. // wrap the label with help text
  258. $this->label = t3lib_BEfunc::wrapInHelp($this->table, $this->field, $this->label);
  259. }
  260. if ($this->contextObject->isFieldHidden($this->table, $this->field)) {
  261. $this->contextObject->addHtmlForHiddenField($this->formFieldName, '<input type="hidden" name="'.$this->formFieldName.'" value="'.htmlspecialchars($this->itemFormElValue).'" />');
  262. $this->doNotRender = TRUE;
  263. }
  264. }
  265. public function injectFormBuilder(t3lib_TCEforms_FormBuilder $formBuilder) {
  266. $this->formBuilder = $formBuilder;
  267. return $this;
  268. }
  269. public function initializePalette($paletteNumber) {
  270. $this->paletteObject = t3lib_div::makeInstance('t3lib_TCEforms_Container_Palette', $paletteNumber);
  271. $this->paletteObject->setContainingObject($this)
  272. ->setContextObject($this->contextObject)
  273. ->setRecordObject($this->recordObject)
  274. ->injectFormBuilder($this->formBuilder);
  275. $this->_hasPalette = TRUE;
  276. }
  277. public function setRecord($record) {
  278. $this->record = $record;
  279. return $this;
  280. }
  281. public function setTable($table) {
  282. $this->table = $table;
  283. return $this;
  284. }
  285. public function setContextRecordObject(t3lib_TCEforms_Record $contextRecordObject) {
  286. $this->contextRecordObject = $contextRecordObject;
  287. return $this;
  288. }
  289. public function getContextRecordObject() {
  290. return $this->contextRecordObject;
  291. }
  292. public function setRecordObject($recordObject) {
  293. $this->recordObject = $recordObject;
  294. return $this;
  295. }
  296. public function getRecordObject() {
  297. return $this->recordObject;
  298. }
  299. public function setParentFormObject(t3lib_TCEforms_Form $parentFormObject) {
  300. $this->parentFormObject = $parentFormObject;
  301. return $this;
  302. }
  303. public function getParentFormObject() {
  304. return $this->parentFormObject;
  305. }
  306. public function getPalette() {
  307. return $this->paletteObject;
  308. }
  309. public function hasPalette() {
  310. return $this->_hasPalette;
  311. }
  312. public function setContextObject(t3lib_TCEforms_Context $contextObject) {
  313. $this->contextObject = $contextObject;
  314. $this->backPath = $contextObject->getBackpath();
  315. return $this;
  316. }
  317. public function setPaletteObject(t3lib_TCEforms_Container_Palette $palette) {
  318. $this->paletteObject = $palette;
  319. $this->paletteObject->setContainingObject($this);
  320. $this->_hasPalette = TRUE;
  321. }
  322. public function setIsInPalette($inPalette) {
  323. $this->isInPalette = $inPalette;
  324. return $this;
  325. }
  326. /**
  327. * Sets all information that is required for proper element identifier generation.
  328. *
  329. * @param array $elementIdentifierStack
  330. * @return t3lib_TCEforms_Element_Abstract
  331. */
  332. public function setElementIdentifierStack(array $elementIdentifierStack) {
  333. $this->elementIdentifierStack = $elementIdentifierStack;
  334. return $this;
  335. }
  336. public function getElementIdentifierStack() {
  337. return $this->elementIdentifierStack;
  338. }
  339. /**
  340. * Returns TRUE if this field is read only, i.e., it may not be changed.
  341. *
  342. * @return boolean
  343. */
  344. protected function isReadOnly() {
  345. return ($this->contextObject->isReadOnly() || $this->fieldSetup['config']['readOnly']);
  346. }
  347. /**
  348. * Returns TRUE if this field is required, means: it must not be empty.
  349. *
  350. * @return boolean
  351. */
  352. protected function isRequired() {
  353. return t3lib_div::inList('required', $this->fieldSetup['config']['eval']);
  354. }
  355. /**
  356. * Returns TRUE if this field is defined as the type field in TCA (key 'type' in control section).
  357. *
  358. * @return boolean
  359. */
  360. protected function isTypeField() {
  361. return ($GLOBALS['TCA'][$this->table]['ctrl']['type'] && !strcmp($this->field,$GLOBALS['TCA'][$this->table]['ctrl']['type']));
  362. }
  363. /**
  364. * Returns TRUE if a client side change in this fields requires a reload of the form.
  365. *
  366. * @return boolean
  367. */
  368. protected function doesFieldChangeRequestUpdate() {
  369. return $GLOBALS['TCA'][$this->table]['ctrl']['requestUpdate'] && t3lib_div::inList($GLOBALS['TCA'][$this->table]['ctrl']['requestUpdate'],$this->field);
  370. }
  371. // NOTE: these methods were extracted from the monster condition in render()
  372. protected function isPassThroughField() {
  373. return $this->fieldSetup['config']['form_type'] == 'passthrough';
  374. }
  375. protected function hasFieldConfig() {
  376. return is_array($this->fieldSetup);
  377. }
  378. protected function isRteEnabled() {
  379. return $this->RTEenabled;
  380. }
  381. protected function isOnlyShownIfRteIsEnabled() {
  382. return $this->fieldSetup['config']['showIfRTE'];
  383. }
  384. protected function hasDisplayCondition() {
  385. return $this->fieldSetup['displayCond'];
  386. }
  387. protected function isExcludeField() {
  388. return $this->fieldSetup['exclude'];
  389. }
  390. /*
  391. * TODO:refactor:
  392. *
  393. * * conditions to element object creator (AbstractForm)
  394. * * most of the code to init method
  395. * * new abstract methods: renderField(), renderFieldReadonly()
  396. * *
  397. */
  398. public function render() {
  399. global $BE_USER, $TCA;
  400. t3lib_div::devLog('Started rendering element ' . $this->field . ' in record ' . $this->recordObject->getIdentifier() . '.', 't3lib_TCEforms_Element_Abstract', t3lib_div::SYSLOG_SEVERITY_INFO);
  401. if ($this->doNotRender) {
  402. return '';
  403. }
  404. // Override fieldConf by fieldTSconfig:
  405. $this->overrideFieldConf($this->fieldTSConfig);
  406. // set field to read-only if configured for translated records to show default language content as readonly
  407. if ($this->fieldSetup['l10n_display'] && t3lib_div::inList($this->fieldSetup['l10n_display'], 'defaultAsReadonly') && $this->record[$TCA[$this->table]['ctrl']['languageField']] > 0) {
  408. $this->fieldSetup['config']['readOnly'] = true;
  409. $this->itemFormElValue = $this->defaultLanguageData[$this->table.':'.$this->record['uid']][$this->field];
  410. }
  411. $alertMsgOnChange = $this->getOnChangeAlertMessage();
  412. // 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.
  413. // TODO: move palette rendering to own method
  414. if ($this->_hasPalette) {
  415. $paletteFields = $this->paletteObject->render();
  416. if ($this->paletteObject->isCollapsed() && $paletteFields != '') {
  417. list($thePalIcon,$palJSfunc) = $this->paletteObject->wrapOpenPalette(t3lib_iconWorks::getSpriteIcon('actions-system-options-view', array('title' => htmlspecialchars(t3lib_TCEforms_Helper::getLL('l_moreOptions')))), TRUE);
  418. } else {
  419. $thePalIcon = '';
  420. $palJSfunc = '';
  421. }
  422. }
  423. // onFocus attribute to add to the field:
  424. $onFocus = ($palJSfunc && !$BE_USER->uc['dontShowPalettesOnFocusInAB']) ? ' onfocus="'.htmlspecialchars($palJSfunc).'"' : '';
  425. // Find item
  426. $item='';
  427. // JavaScript code for event handlers:
  428. $this->fieldChangeFunc=array();
  429. $this->fieldChangeFunc['TBE_EDITOR_fieldChanged'] = "TBE_EDITOR.fieldChanged('".$this->table."','".$this->record['uid']."','".$this->field."','".$this->formFieldName."');";
  430. $this->fieldChangeFunc['alert'] = $alertMsgOnChange;
  431. // if this is the child of an inline type and it is the field creating the label
  432. // disabled while IRRE is not supported -- andreaswolf, 23.07.2008
  433. // TODO: move this to IRRE
  434. /*if ($this->inline->isInlineChildAndLabelField($this->table, $this->field)) {
  435. $this->fieldChangeFunc['inline'] = "inline.handleChangedField('".$this->formFieldName."','".$this->inline->inlineNames['object']."[$this->table][".$this->record['uid']."]');";
  436. }*/
  437. $item = $this->renderContents();
  438. // Create output value:
  439. // TODO: refactor this
  440. // - new methods in Element_Abstract:
  441. // getLabel
  442. // renderHelpIcon
  443. // renderHelpText
  444. // renderPaletteIcon
  445. // renderPaletteContents
  446. // putting it all together will happen in Record object
  447. if ($this->fieldSetup['config']['form_type']=='user' && $this->fieldSetup['config']['noTableWrapping']) {
  448. $out = $item;
  449. } elseif ($this->isInPalette) {
  450. $out=array(
  451. 'NAME'=>$this->label,
  452. 'ID'=>$this->record['uid'],
  453. 'FIELD'=>$this->field,
  454. 'TABLE'=>$this->table,
  455. 'ITEM'=>$item,
  456. 'HELP_ICON' => $this->helpTextIcon(TRUE)
  457. );
  458. } else {
  459. $out=array(
  460. 'NAME'=>$this->label,
  461. 'ITEM'=>$item,
  462. 'TABLE'=>$this->table,
  463. 'ID'=>$this->record['uid'],
  464. 'HELP_ICON'=>$this->helpTextIcon(),
  465. 'HELP_TEXT'=>$this->helpText(),
  466. 'PAL_LINK_ICON'=>$thePalIcon,
  467. 'FIELD'=>$this->field
  468. );
  469. $out = $this->intoTemplate($out);
  470. }
  471. // Hook: getSingleField_postProcess
  472. foreach (self::$hookObjects['getSingleFields'] as $hookObj) {
  473. if (method_exists($hookObj,'getSingleField_postProcess')) {
  474. $hookObj->getSingleField_postProcess($this->table, $this->field, $this->record, $this->label, $this->palette, $this->extra, $this->pal, $this);
  475. }
  476. }
  477. if ($this->_hasPalette) {
  478. $out .= $paletteFields;
  479. }
  480. return $out;
  481. }
  482. protected abstract function renderField();
  483. public function renderContents() {
  484. $item = $this->renderField();
  485. // Add language + diff
  486. if ($this->fieldSetup['l10n_display'] && (t3lib_div::inList($this->fieldSetup['l10n_display'], 'hideDiff') || t3lib_div::inList($this->fieldSetup['l10n_display'], 'defaultAsReadonly'))) {
  487. $renderLanguageDiff = false;
  488. } else {
  489. $renderLanguageDiff = true;
  490. }
  491. if ($renderLanguageDiff) {
  492. $item = $this->renderDefaultLanguageContent($item);
  493. $item = $this->renderDefaultLanguageDiff($item);
  494. }
  495. return $item;
  496. }
  497. public function getContents() {
  498. return $this->renderContents();
  499. }
  500. public function getHelpText() {
  501. return $this->helpText();
  502. }
  503. public function getHelpTextIcon() {
  504. return $this->helpTextIcon();
  505. }
  506. public function getLabel() {
  507. return $this->label;
  508. }
  509. public function setValue($value) {
  510. $this->itemFormElValue = $value;
  511. }
  512. public function getValue() {
  513. return $this->itemFormElValue;
  514. }
  515. /**
  516. * Returns the config array from the TCA definition of this field.
  517. *
  518. * This access is required for FlexForm datastructure traversal to work.
  519. *
  520. * @return array
  521. */
  522. public function getFieldSetup() {
  523. return $this->fieldSetup;
  524. }
  525. /**
  526. * Create a JavaScript code line which will ask the user to save/update the form due to changing
  527. * the element. This is used for eg. "type" fields and others configured with "requestUpdate".
  528. *
  529. * @return string;
  530. */
  531. protected function getOnChangeAlertMessage() {
  532. if (
  533. ($this->isTypeField())
  534. || ($this->doesFieldChangeRequestUpdate())
  535. ) {
  536. if($GLOBALS['BE_USER']->jsConfirmation(1)) {
  537. $alertMsgOnChange = 'if (confirm(TBE_EDITOR.labels.onChangeAlert) && TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
  538. } else {
  539. $alertMsgOnChange = 'if (TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
  540. }
  541. } else {
  542. $alertMsgOnChange = '';
  543. }
  544. return $alertMsgOnChange;
  545. }
  546. //abstract public function render();
  547. // TODO: rename to setParentContainer
  548. public function setContainer(t3lib_TCEforms_Container $container) {
  549. $this->container = $container;
  550. return $this;
  551. }
  552. public function getContainer() {
  553. return $this->container;
  554. }
  555. /**
  556. * Returns TSconfig for table/row
  557. *
  558. * Multiple requests to this function will return cached content so there is no performance
  559. * loss in calling this many times since the information is looked up only once.
  560. *
  561. * Uses central caching functionality in t3lib_TCEforms_Form
  562. *
  563. * @see t3lib_TCEForms_Form::getTSconfig()
  564. */
  565. protected function getTSconfig($useField = TRUE) {
  566. return t3lib_TCEForms_Form::getTSconfig($this->table, $this->record, ($useField ? $this->field : ''));
  567. }
  568. public function getFieldname() {
  569. return $this->field;
  570. }
  571. public function getFormFieldNamePrefix() {
  572. return $this->prependFormFieldNames;
  573. }
  574. public function getFormFieldName() {
  575. return $this->formFieldName;
  576. }
  577. /**
  578. * Returns the HTML code for disabling a form field if the current field should be displayed
  579. * disabled
  580. *
  581. * @return string
  582. */
  583. protected function getDisabledCode() {
  584. if ($this->isReadOnly()) {
  585. return ' disabled="disabled"';
  586. } else {
  587. return '';
  588. }
  589. }
  590. /**
  591. * Overrides the TCA field configuration by TSconfig settings.
  592. *
  593. * Example TSconfig: TCEform.<table>.<field>.config.appearance.useSortable = 1
  594. * This overrides the setting in $TCA[<table>]['columns'][<field>]['config']['appearance']['useSortable'].
  595. *
  596. * @param array $TSconfig: TSconfig
  597. * @return array Changed TCA field configuration
  598. */
  599. protected function overrideFieldConf($TSconfig) {
  600. $fieldConfig = $this->fieldSetup['config'];
  601. if (is_array($TSconfig)) {
  602. $TSconfig = t3lib_div::removeDotsFromTS($TSconfig);
  603. $type = $fieldConfig['type'];
  604. if (is_array($TSconfig['config']) && is_array($this->allowOverrideMatrix[$type])) {
  605. // Check if the keys in TSconfig['config'] are allowed to override TCA field config:
  606. foreach (array_keys($TSconfig['config']) as $key) {
  607. if (!in_array($key, $this->allowOverrideMatrix[$type], true)) {
  608. unset($TSconfig['config'][$key]);
  609. }
  610. }
  611. // Override TCA field config by remaining TSconfig['config']:
  612. if (count($TSconfig['config'])) {
  613. $fieldConfig = t3lib_div::array_merge_recursive_overrule($fieldConfig, $TSconfig['config']);
  614. }
  615. }
  616. }
  617. $this->fieldSetup['config'] = $fieldConfig;
  618. }
  619. /**
  620. * Returns true, if the evaluation of the required-field code is OK.
  621. *
  622. * @return boolean
  623. */
  624. protected function evaluateDisplayCondition() {
  625. $output = FALSE;
  626. $displayCond = $this->fieldSetup['displayCond'];
  627. $row = $this->record;
  628. // TODO implement FlexForm value key $ffValueeKey, if still neccessary
  629. $parts = explode(':', $displayCond);
  630. switch ((string)$parts[0]) { // Type of condition:
  631. case 'FIELD':
  632. $theFieldValue = $ffValueKey ? $row[$parts[1]][$ffValueKey] : $row[$parts[1]];
  633. switch ((string)$parts[2]) {
  634. case 'REQ':
  635. if (strtolower($parts[3]) == 'true') {
  636. $output = $theFieldValue ? TRUE : FALSE;
  637. } elseif (strtolower($parts[3]) == 'false') {
  638. $output = !$theFieldValue ? TRUE : FALSE;
  639. }
  640. break;
  641. case '>':
  642. $output = $theFieldValue > $parts[3];
  643. break;
  644. case '<':
  645. $output = $theFieldValue < $parts[3];
  646. break;
  647. case '>=':
  648. $output = $theFieldValue >= $parts[3];
  649. break;
  650. case '<=':
  651. $output = $theFieldValue <= $parts[3];
  652. break;
  653. case '-':
  654. case '!-':
  655. $cmpParts = explode('-', $parts[3]);
  656. $output = $theFieldValue >= $cmpParts[0] && $theFieldValue <= $cmpParts[1];
  657. if ($parts[2]{0} == '!') {
  658. $output = !$output;
  659. }
  660. break;
  661. case 'IN':
  662. case '!IN':
  663. $output = t3lib_div::inList($parts[3], $theFieldValue);
  664. if ($parts[2]{0} == '!') {
  665. $output = !$output;
  666. }
  667. break;
  668. case '=':
  669. case '!=':
  670. $output = t3lib_div::inList($parts[3], $theFieldValue);
  671. if ($parts[2]{0} == '!') {
  672. $output = !$output;
  673. }
  674. break;
  675. }
  676. break;
  677. case 'EXT':
  678. switch ((string)$parts[2]) {
  679. case 'LOADED':
  680. if (strtolower($parts[3]) == 'true') {
  681. $output = t3lib_extMgm::isLoaded($parts[1]) ? TRUE : FALSE;
  682. } elseif (strtolower($parts[3]) == 'false') {
  683. $output = !t3lib_extMgm::isLoaded($parts[1]) ? TRUE : FALSE;
  684. }
  685. break;
  686. }
  687. break;
  688. case 'REC':
  689. switch ((string)$parts[1]) {
  690. case 'NEW':
  691. if (strtolower($parts[2]) == 'true') {
  692. $output = !(intval($row['uid']) > 0) ? TRUE : FALSE;
  693. } elseif (strtolower($parts[2]) == 'false') {
  694. $output = (intval($row['uid']) > 0) ? TRUE : FALSE;
  695. }
  696. break;
  697. }
  698. break;
  699. case 'HIDE_L10N_SIBLINGS':
  700. if ($ffValueKey === 'vDEF') {
  701. $output = TRUE;
  702. } elseif ($parts[1] === 'except_admin' && $GLOBALS['BE_USER']->isAdmin()) {
  703. $output = TRUE;
  704. }
  705. break;
  706. case 'HIDE_FOR_NON_ADMINS':
  707. $output = $GLOBALS['BE_USER']->isAdmin() ? TRUE : FALSE;
  708. break;
  709. case 'VERSION':
  710. switch ((string)$parts[1]) {
  711. case 'IS':
  712. $isNewRecord = (intval($row['uid']) > 0 ? FALSE : TRUE);
  713. // detection of version can be done be detecting the workspace of the user
  714. $isUserInWorkspace = ($GLOBALS['BE_USER']->workspace > 0 ? TRUE : FALSE);
  715. if (intval($row['pid']) == -1 || intval($row['_ORIG_pid']) == -1) {
  716. $isRecordDetectedAsVersion = TRUE;
  717. } else {
  718. $isRecordDetectedAsVersion = FALSE;
  719. }
  720. // New records in a workspace are not handled as a version record
  721. // if it's no new version, we detect versions like this:
  722. // -- if user is in workspace: always true
  723. // -- if editor is in live ws: only true if pid == -1
  724. $isVersion = ($isUserInWorkspace || $isRecordDetectedAsVersion) && !$isNewRecord;
  725. if (strtolower($parts[2]) == 'true') {
  726. $output = $isVersion;
  727. } else if (strtolower($parts[2]) == 'false') {
  728. $output = !$isVersion;
  729. }
  730. break;
  731. }
  732. break;
  733. }
  734. return $output;
  735. }
  736. /************************************
  737. *
  738. * Template functions
  739. *
  740. ************************************/
  741. // TODO: add accessors for style scheme so the container can access them for rendering
  742. /**
  743. * This inserts the content of $inArr into the field-template
  744. *
  745. * @param array Array with key/value pairs to insert in the template.
  746. * @param string Alternative template to use instead of the default.
  747. * @return string
  748. */
  749. // TODO: will be removed after refactoring render()
  750. function intoTemplate($inArr,$altTemplate='') {
  751. $parentTemplate = t3lib_parsehtml::getSubpart($this->contextObject->getTemplateContent(), '###FIELDTEMPLATE###');
  752. $template = $this->rplColorScheme($altTemplate?$altTemplate:$parentTemplate);
  753. foreach ($inArr as $key => $value) {
  754. $markerArray['###FIELD_'.$key.'###'] = $value;
  755. }
  756. $content = t3lib_parsehtml::substituteMarkerArray($template, $markerArray);
  757. return $content;
  758. }
  759. /**
  760. * Replaces colorscheme markers in the template string
  761. *
  762. * @param string Template string with markers to be substituted.
  763. * @return string
  764. */
  765. function rplColorScheme($inTemplate) {
  766. // Colors:
  767. $markerArray = array(
  768. '###BGCOLOR###' => $this->colorScheme[0] ? ' bgcolor="' . $this->colorScheme[0].'"' : '',
  769. '###BGCOLOR_HEAD###' => $this->colorScheme[1] ? ' bgcolor="' . $this->colorScheme[1].'"':'',
  770. '###FONTCOLOR_HEAD###' => $this->colorScheme[3],
  771. '###CLASSATTR_1###' => $this->classScheme[0] ? ' class="' . $this->classScheme[0] . '"' : '',
  772. '###CLASSATTR_2###' => $this->classScheme[1] ? ' class="' . $this->classScheme[1] . '"' : '',
  773. '###CLASSATTR_4###' => $this->classScheme[3] ? ' class="' . $this->classScheme[3] . '"' : ''
  774. );
  775. $inTemplate = t3lib_parsehtml::substituteMarkerArray($inTemplate, $markerArray);
  776. return $inTemplate;
  777. }
  778. /**
  779. * Setting the current color scheme ($this->colorScheme) based on $this->defColorScheme plus input string.
  780. *
  781. * @param string A color scheme string.
  782. * @return void
  783. */
  784. public function setColorScheme($scheme) {
  785. $this->colorScheme = $this->defColorScheme;
  786. $this->classScheme = $this->defClassScheme;
  787. $parts = t3lib_div::trimExplode(',',$scheme);
  788. foreach($parts as $key => $col) {
  789. // Split for color|class:
  790. list($color,$class) = t3lib_div::trimExplode('|',$col);
  791. // Handle color values:
  792. if ($color) $this->colorScheme[$key] = $color;
  793. if ($color=='-') {
  794. $this->colorScheme[$key] = '';
  795. }
  796. // Handle class values:
  797. if ($class) $this->classScheme[$key] = $class;
  798. if ($class=='-') {
  799. $this->classScheme[$key] = '';
  800. }
  801. }
  802. return $this;
  803. }
  804. public function setBorderStyle($style) {
  805. $this->borderStyle = $style;
  806. return $this;
  807. }
  808. public function getBorderStyle() {
  809. return $this->borderStyle;
  810. }
  811. public function setFieldStyle($style) {
  812. $this->fieldStyle = $style;
  813. return $this;
  814. }
  815. public function getFieldStyle() {
  816. return $this->fieldStyle;
  817. }
  818. public function getClassScheme() {
  819. return $this->classScheme;
  820. }
  821. /**
  822. * Reset element styles to default values.
  823. *
  824. * @return void
  825. */
  826. protected function resetStyles() {
  827. $this->setColorScheme($GLOBALS['TBE_STYLES']['colorschemes'][0]);
  828. $this->fieldStyle = $GLOBALS['TBE_STYLES']['styleschemes'][0];
  829. $this->borderStyle = $GLOBALS['TBE_STYLES']['borderschemes'][0];
  830. }
  831. public function setStyle(t3lib_TCA_FieldStyle $style) {
  832. $this->style = $style;
  833. }
  834. public function getStyle() {
  835. return $this->style;
  836. }
  837. /************************************************************
  838. *
  839. * Display of localized content etc.
  840. *
  841. ************************************************************/
  842. public function setDefaultLanguageValue($defaultValue) {
  843. $this->defaultLanguageValue = $defaultValue;
  844. }
  845. /**
  846. * Creates language-overlay for a field value
  847. * This means the requested field value will be overridden with the data from the default language.
  848. * Can be used to render read only fields for example.
  849. *
  850. * @param string Table name of the record being edited
  851. * @param string Field name represented by $item
  852. * @param array Record array of the record being edited in current language
  853. * @param array Content of $PA['fieldConf']
  854. * @return string Unprocessed field value merged with default language data if needed
  855. *
  856. * @TODO check if this can/should be centralized in Element_Abstract
  857. */
  858. protected function getLanguageOverlayRawValue() {
  859. global $TCA;
  860. if ($this->fieldConf['l10n_mode']=='exclude'
  861. || ($this->fieldConf['l10n_mode']=='mergeIfNotBlank'
  862. && strcmp(trim($this->defaultLanguageValue),''))) {
  863. $value = $this->defaultLanguageValue;
  864. }
  865. return $value;
  866. }
  867. /**
  868. * Renders the display of default language record content around current field.
  869. * Will render content if any is found in the internal array, $this->defaultLanguageData, depending on registerDefaultLanguageData() being called prior to this.
  870. *
  871. * @param string HTML of the form field. This is what we add the content to.
  872. * @return string Item string returned again, possibly with the original value added to.
  873. * @see getSingleField(), registerDefaultLanguageData()
  874. */
  875. // TODO: check where $this->previewFieldValue() gets its data from
  876. protected function renderDefaultLanguageContent($item) {
  877. if ($this->defaultLanguageValue != '') {
  878. $dLVal = t3lib_BEfunc::getProcessedValue($this->table, $this->field, $this->defaultLanguageValue, 0, 1);
  879. // Don't show content if it's for IRRE child records:
  880. if ($this->fieldSetup['type'] != 'inline') {
  881. if (strcmp($dLVal, '')) {
  882. $item.='<div class="typo3-TCEforms-originalLanguageValue">'.$this->recordObject->getLanguageIcon(0).$this->previewFieldValue($dLVal).'&nbsp;</div>';
  883. }
  884. $prLang = $this->recordObject->getAdditionalPreviewLanguages();
  885. foreach ($prLang as $prL) {
  886. $dlVal = t3lib_BEfunc::getProcessedValue($this->table,$this->field,$this->additionalPreviewLanguageValue[$prL['uid']][$this->field],0,1);
  887. if (strcmp($dlVal, '')) {
  888. $item .= '<div class="typo3-TCEforms-originalLanguageValue">'.$this->recordObject->getLanguageIcon('v'.$prL['ISOcode']).$this->previewFieldValue($dlVal).'&nbsp;</div>';
  889. }
  890. }
  891. }
  892. }
  893. return $item;
  894. }
  895. /**
  896. * Renders the diff-view of default language record content compared with what the record was originally translated from.
  897. * Will render content if any is found in the internal array, $this->defaultLanguageData, depending on registerDefaultLanguageData() being called prior to this.
  898. *
  899. * @param string Table name of the record being edited
  900. * @param string Field name represented by $item
  901. * @param array Record array of the record being edited
  902. * @param string HTML of the form field. This is what we add the content to.
  903. * @return string Item string returned again, possibly with the original value added to.
  904. * @see getSingleField(), registerDefaultLanguageData()
  905. */
  906. protected function renderDefaultLanguageDiff($item) {
  907. if (is_array($this->defaultLanguageData_diff[$this->table.':'.$this->record['uid']])) {
  908. // Initialize:
  909. $dLVal = array(
  910. 'old' => $this->defaultLanguageData_diff[$this->table.':'.$this->record['uid']],
  911. 'new' => $this->defaultLanguageData[$this->table.':'.$this->record['uid']],
  912. );
  913. if (isset($dLVal['old'][$this->field])) { // There must be diff-data:
  914. if (strcmp($dLVal['old'][$this->field],$dLVal['new'][$this->field])) {
  915. // Create diff-result:
  916. $t3lib_diff_Obj = t3lib_div::makeInstance('t3lib_diff');
  917. $diffres = $t3lib_diff_Obj->makeDiffDisplay(
  918. t3lib_BEfunc::getProcessedValue($this->table,$this->field,$dLVal['old'][$this->field],0,1),
  919. t3lib_BEfunc::getProcessedValue($this->table,$this->field,$dLVal['new'][$this->field],0,1)
  920. );
  921. $item .= '<div class="typo3-TCEforms-diffBox">'.
  922. '<div class="typo3-TCEforms-diffBox-header">'.htmlspecialchars(t3lib_TCEforms_Helper::getLL('l_changeInOrig')).':</div>'.
  923. $diffres.
  924. '</div>';
  925. }
  926. }
  927. }
  928. return $item;
  929. }
  930. /**
  931. * Rendering preview output of a field value which is not shown as a form field but just outputted.
  932. *
  933. * @param string The value to output
  934. * @param array Configuration for field.
  935. * @return string HTML formatted output
  936. */
  937. // TODO: move to renderField in type group
  938. protected function previewFieldValue($value) {
  939. if ($this->fieldSetup['type'] === 'group' &&
  940. ($this->fieldSetup['internal_type'] === 'file' ||
  941. $config['config']['internal_type'] === 'file_reference')) {
  942. // Ignore uploadfolder if internal_type is file_reference
  943. if ($config['config']['internal_type'] === 'file_reference') {
  944. $config['config']['uploadfolder'] = '';
  945. }
  946. $show_thumbs = TRUE;
  947. $table = 'tt_content';
  948. // Making the array of file items:
  949. $itemArray = t3lib_div::trimExplode(',', $value, 1);
  950. // Showing thumbnails:
  951. $thumbsnail = '';
  952. if ($show_thumbs) {
  953. $imgs = array();
  954. foreach($itemArray as $imgRead) {
  955. $imgP = explode('|',$imgRead);
  956. $imgPath = rawurldecode($imgP[0]);
  957. $rowCopy = array();
  958. $rowCopy[$field] = $imgPath;
  959. // Icon + clickmenu:
  960. $absFilePath = t3lib_div::getFileAbsFileName($this->fieldSetup['uploadfolder'] ? $config['config']['uploadfolder'] . '/' . $imgPath : $imgPath);
  961. $fI = pathinfo($imgPath);
  962. $fileIcon = t3lib_BEfunc::getFileIcon(strtolower($fI['extension']));
  963. $fileIcon = '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/fileicons/'.$fileIcon,'width="18" height="16"').' class="absmiddle" title="'.htmlspecialchars($fI['basename'].($absFilePath && @is_file($absFilePath) ? ' ('.t3lib_div::formatSize(filesize($absFilePath)).'bytes)' : ' - FILE NOT FOUND!')).'" alt="" />';
  964. $imgs[] = '<span class="nobr">'.t3lib_BEfunc::thumbCode($rowCopy,$table,$field,$this->backPath,'thumbs.php',$config['config']['uploadfolder'],0,' align="middle"').
  965. ($absFilePath ? $this->getClickMenu($fileIcon, $absFilePath) : $fileIcon).
  966. $imgPath.
  967. '</span>';
  968. }
  969. $thumbsnail = implode('<br />',$imgs);
  970. }
  971. return $thumbsnail;
  972. } else {
  973. return nl2br(htmlspecialchars($value));
  974. }
  975. }
  976. /**
  977. * Returns help-text ICON if configured for.
  978. *
  979. * @param string The table name
  980. * @param string The field name
  981. * @param boolean Force the return of the help-text icon.
  982. * @return string HTML, <a>-tag with
  983. */
  984. protected function helpTextIcon($force = 0) {
  985. if ($this->contextObject->isHelpGloballyShown()
  986. && $GLOBALS['TCA_DESCR'][$this->table]['columns'][$this->field]
  987. && (
  988. ($this->contextObject->getEditFieldHelpMode() =='icon'
  989. && !$this->contextObject->doLoadTableDescription($this->table)
  990. )
  991. || $force)
  992. ) {
  993. return t3lib_BEfunc::helpTextIcon($this->table, $this->field, $this->backPath, $force);
  994. } else {
  995. // Detects fields with no CSH and outputs dummy line to insert into CSH locallang file:
  996. return '<span class="nbsp">&nbsp;</span>';
  997. }
  998. }
  999. /**
  1000. * Returns help text DESCRIPTION, if configured for.
  1001. *
  1002. * @param string The table name
  1003. * @param string The field name
  1004. * @return string
  1005. */
  1006. protected function helpText() {
  1007. if ($this->contextObject->isHelpGloballyShown()
  1008. && $GLOBALS['TCA_DESCR'][$this->table]['columns'][$this->field]
  1009. && ($this->contextObject->getEditFieldHelpMode() == 'text'
  1010. || $this->contextObject->doLoadTableDescription($this->table))
  1011. ) {
  1012. $fDat = $GLOBALS['TCA_DESCR'][$this->table]['columns'][$this->field];
  1013. return '<table border="0" cellpadding="2" cellspacing="0" width="90%"><tr><td valign="top" width="14">'.
  1014. $this->helpTextIcon(
  1015. $this->table,
  1016. $this->field,
  1017. $fDat['details']||$fDat['syntax']||$fDat['image_descr']||$fDat['image']||$fDat['seeAlso']
  1018. ).
  1019. '</td><td valign="top"><span class="typo3-TCEforms-helpText">'.
  1020. $GLOBALS['LANG']->hscAndCharConv(strip_tags($fDat['description']),1).
  1021. '</span></td></tr></table>';
  1022. }
  1023. }
  1024. /**
  1025. * Returns the "special" configuration of an "extra" string (non-parsed)
  1026. *
  1027. * @param string The "Part 4" of the fields configuration in "types" "showitem" lists.
  1028. * @param string The ['defaultExtras'] value from field configuration
  1029. * @return array An array with the special options in.
  1030. * @see getSpecConfForField(), t3lib_BEfunc::getSpecConfParts()
  1031. */
  1032. protected function getSpecConfFromString($extraString, $defaultExtras) {
  1033. return t3lib_BEfunc::getSpecConfParts($extraString, $defaultExtras);
  1034. }
  1035. /**
  1036. * Creates style attribute content for option tags in a selector box, primarily setting it up to
  1037. * show the icon of an element as background image (works in mozilla)
  1038. *
  1039. * @param string Icon string for option item
  1040. * @return string Style attribute content, if any
  1041. */
  1042. protected function optionTagStyle($iconString) {
  1043. if ($iconString) {
  1044. list($selIconFile, $selIconInfo) = $this->getIcon($iconString);
  1045. $padLeft = $selIconInfo[0] + 4;
  1046. if($padLeft >= 18 && $padLeft <= 24) {
  1047. $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
  1048. }
  1049. $padTop = t3lib_div::intInRange(($selIconInfo[1]-12)/2, 0);
  1050. $styleAttr = 'background: #fff url(' . $selIconFile . ') 0% 50% no-repeat; height: ' .
  1051. t3lib_div::intInRange(($selIconInfo[1] + 2) - $padTop, 0) . 'px; padding-top: ' . $padTop .
  1052. 'px; padding-left: ' . $padLeft . 'px;';
  1053. return $styleAttr;
  1054. }
  1055. }
  1056. /**
  1057. * Get icon (for example for selector boxes)
  1058. *
  1059. * @param string Icon reference
  1060. * @return array Array with two values; the icon file reference (relative to PATH_typo3 minus backPath), the icon file information array (getimagesize())
  1061. */
  1062. protected function getIcon($icon) {
  1063. if (substr($icon, 0, 4) == 'EXT:') {
  1064. $file = t3lib_div::getFileAbsFileName($icon);
  1065. if ($file) {
  1066. $file = substr($file,strlen(PATH_site));
  1067. $selIconFile = $this->backPath.'../'.$file;
  1068. $selIconInfo = @getimagesize(PATH_site.$file);
  1069. }
  1070. } elseif (substr($icon,0,3)=='../') {
  1071. $selIconFile = $this->backPath.t3lib_div::resolveBackPath($icon);
  1072. $selIconInfo = @getimagesize(PATH_site.t3lib_div::resolveBackPath(substr($icon,3)));
  1073. } elseif (substr($icon,0,4)=='ext/' || substr($icon,0,7)=='sysext/') {
  1074. $selIconFile = $this->backPath.$icon;
  1075. $selIconInfo = @getimagesize(PATH_typo3.$icon);
  1076. } else {
  1077. $selIconFile = t3lib_iconWorks::skinImg($this->backPath,'gfx/'.$icon,'',1);
  1078. $iconPath = substr($selIconFile, strlen($this->backPath));
  1079. $selIconInfo = @getimagesize(PATH_typo3 . $iconPath);
  1080. }
  1081. return array($selIconFile,$selIconInfo);
  1082. }
  1083. /**
  1084. * Renders the $icon, supports a filename for skinImg or sprite-icon-name
  1085. * @param $icon the icon passed, could be a file-reference or a sprite Icon name
  1086. * @param string $alt alt attribute of the icon returned
  1087. * @param string $title title attribute of the icon return
  1088. * @return an tag representing to show the asked icon
  1089. */
  1090. protected function getIconHtml($icon, $alt = '', $title = '') {
  1091. $iconArray = $this->getIcon($icon);
  1092. if (is_file(t3lib_div::resolveBackPath(PATH_typo3 . $iconArray[0]))) {
  1093. return '<img src="' . $iconArray[0] . '" alt="' . $alt . '" ' . ($title ? 'title="' . $title . '"' : '') . ' />';
  1094. } else {
  1095. return t3lib_iconWorks::getSpriteIcon($icon, array('alt'=> $alt, 'title'=> $title));
  1096. }
  1097. }
  1098. /************************************************************
  1099. *
  1100. * Item-array manipulation functions (check/select/radio)
  1101. *
  1102. ************************************************************/
  1103. // TODO: check if moving these functions to a common baseclass of elements check, select and radio
  1104. // makes sense
  1105. /**
  1106. * Initialize item array (for checkbox, selectorbox, radio buttons)
  1107. * Will resolve the label value.
  1108. *
  1109. * @return array An array of arrays with three elements; label, value, icon
  1110. */
  1111. protected function initItemArray() {
  1112. $items = array();
  1113. if (is_array($this->fieldSetup['config']['items'])) {
  1114. foreach($this->fieldSetup['config']['items'] as $itemName => $itemValue) {
  1115. $items[] = array($this->sL($itemValue[0]), $itemValue[1], $itemValue[2]);
  1116. }
  1117. }
  1118. return $items;
  1119. }
  1120. /**
  1121. * Merges items into an item-array
  1122. *
  1123. * @param array The existing item array
  1124. * @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.
  1125. * @return array The updated $item array
  1126. */
  1127. protected function addItems($items,$iArray) {
  1128. global $TCA;
  1129. if (is_array($iArray)) {
  1130. reset($iArray);
  1131. while(list($value,$label)=each($iArray)) {
  1132. $items[]=array($this->sl($label),$value);
  1133. }
  1134. }
  1135. return $items;
  1136. }
  1137. /**
  1138. * Perform user processing of the items arrays of checkboxes, selectorboxes and radio buttons.
  1139. *
  1140. * @param array The array of items (label,value,icon)
  1141. * @return array The modified $items array
  1142. *
  1143. * @TODO refactor this
  1144. * - rename to processItems()
  1145. * - get config from object, not parameter
  1146. * - remove iArray parameter, get it from object properties
  1147. */
  1148. protected function procItems($items) {
  1149. global $TCA;
  1150. $params = array();
  1151. $params['items'] = &$items;
  1152. $params['config'] = $this->fieldSetup['config'];
  1153. $params['TSconfig'] = $this->fieldTSConfig['itemsProcFunc.'];
  1154. $params['table'] = $this->table;
  1155. $params['row'] = $this->record;
  1156. $params['field'] = $this->field;
  1157. $processFunction = $this->fieldSetup['config']['itemsProcFunc'];
  1158. t3lib_div::callUserFunction($processFunction, $params, $this);
  1159. return $items;
  1160. }
  1161. /********************************************
  1162. *
  1163. * Localization functions
  1164. *
  1165. ********************************************/
  1166. /**
  1167. * Fetches language label for key
  1168. *
  1169. * @param string Language label reference, eg. 'LLL:EXT:lang/locallang_core.php:labels.blablabla'
  1170. * @return string The value of the label, fetched for the current backend language.
  1171. */
  1172. // TODO: refactor the method name
  1173. protected function sL($str) {
  1174. return $GLOBALS['LANG']->sL($str);
  1175. }
  1176. /************************************************************
  1177. *
  1178. * Form element helper functions
  1179. *
  1180. ************************************************************/
  1181. /**
  1182. * Prints the selector box form-field for the db/file/select elements (multiple)
  1183. *
  1184. * @param string Form element name
  1185. * @param string Mode "db", "file" (internal_type for the "group" type) OR blank (then for the "select" type)
  1186. * @param string Commalist of "allowed"
  1187. * @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.
  1188. * @param string Alternative selector box.
  1189. * @param array An array of additional parameters, eg: "size", "info", "headers" (array with "selector" and "items"), "noBrowser", "thumbnails"
  1190. * @param string On focus attribute string
  1191. * @param string $table: (optional) Table name processing for
  1192. * @param string $field: (optional) Field of table name processing for
  1193. * @param string $uid: (optional) uid of table record processing for
  1194. * @return string The form fields for the selection.
  1195. *
  1196. * @TODO refactor this
  1197. */
  1198. function dbFileIcons($fName,$mode,$allowed,$itemArray,$selector='',$params=array(),$onFocus='',$table='',$field='',$uid='') {
  1199. return ($this->renderItemList($selector, $onFocus));
  1200. /**
  1201. * Refactoring:
  1202. * - move method to Element_AbstractSelect
  1203. * - move itemArray out of parameters
  1204. * - remove $allowed from parameters -> only required in Element_Group
  1205. * - remove $table, $field, $uid
  1206. * - remove $onFocus from parameters
  1207. * - replace $params[] by direct access to class members/methods
  1208. * - change method name to e.g. renderItemList
  1209. */
  1210. $disabled = $this->getDisabledCode();
  1211. // Sets a flag which means some JavaScript is included on the page to support this element.
  1212. $this->printNeededJS['dbFileIcons']=1;
  1213. // INIT
  1214. $uidList=array();
  1215. $opt=array();
  1216. $itemArrayC=0;
  1217. // Creating <option> elements:
  1218. if (is_array($itemArray)) {
  1219. $itemArrayC=count($itemArray);
  1220. reset($itemArray);
  1221. // TODO: factor out to method renderOptions()
  1222. switch($mode) {
  1223. // TODO: move all cases (except default) to Element_Group
  1224. case 'db':
  1225. while(list(,$pp)=each($itemArray)) {
  1226. $pRec = t3lib_BEfunc::getRecordWSOL($pp['table'],$pp['id']);
  1227. if (is_array($pRec)) {
  1228. $pTitle = t3lib_BEfunc::getRecordTitle($pp['table'], $pRec, FALSE, TRUE);
  1229. $pUid = $pp['table'].'_'.$pp['id'];
  1230. $uidList[]=$pUid;
  1231. $opt[]='<option value="'.htmlspecialchars($pUid).'">'.htmlspecialchars($pTitle).'</option>';
  1232. }
  1233. }
  1234. break;
  1235. case 'file':
  1236. case 'file_reference':
  1237. foreach ($itemArray as $item) {
  1238. $itemParts = explode('|', $item);
  1239. $uidList[] = $pUid = $pTitle = $itemParts[0];
  1240. $opt[] = '<option value="' . htmlspecialchars(rawurldecode($itemParts[0])) . '">' . htmlspecialchars(basename(rawurldecode($itemParts[0]))) . '</option>';
  1241. }
  1242. break;
  1243. case 'folder':
  1244. while(list(,$pp)=each($itemArray)) {
  1245. $pParts = explode('|',$pp);
  1246. $uidList[]=$pUid=$pTitle = $pParts[0];
  1247. $opt[]='<option value="'.htmlspecialchars(rawurldecode($pParts[0])).'">'.htmlspecialchars(rawurldecode($pParts[0])).'</option>';
  1248. }
  1249. break;
  1250. // TODO: move default to Element_Select
  1251. default:
  1252. while(list(,$pp)=each($itemArray)) {
  1253. $pParts = explode('|',$pp, 2);
  1254. $uidList[]=$pUid=$pParts[0];
  1255. $pTitle = $pParts[1];
  1256. $opt[]='<option value="'.htmlspecialchars(rawurldecode($pUid)).'">'.htmlspecialchars(rawurldecode($pTitle)).'</option>';
  1257. }
  1258. break;
  1259. }
  1260. }
  1261. // Create selector box of the options
  1262. $sSize = $params['autoSizeMax'] ? t3lib_div::intInRange($itemArrayC+1,t3lib_div::intInRange($params['size'],1),$params['autoSizeMax']) : $params['size'];
  1263. if (!$selector) {
  1264. $selector = '<select id="' . uniqid('tceforms-multiselect-') . '" ' . ($params['noList'] ? 'style="display: none"' : 'size="' . $sSize . '"' . $this->insertDefaultElementStyle('group', 'tceforms-multiselect')) . ' multiple="multiple" name="' . $this->formFieldName.'_list" ' . $onFocus . $params['style'] . $disabled . '>' . implode('', $opt) . '</select>';
  1265. }
  1266. $icons = array(
  1267. 'L' => array(),
  1268. 'R' => array(),
  1269. );
  1270. if (!$this->isReadOnly() && !$params['noList']) {
  1271. if (!$params['noBrowser']) {
  1272. // check against inline uniqueness
  1273. // TODO: re-implement for IRRE
  1274. /*$inlineParent = $this->inline->getStructureLevel(-1);
  1275. if(is_array($inlineParent) && $inlineParent['uid']) {
  1276. if ($inlineParent['config']['foreign_table'] == $table && $inlineParent['config']['foreign_unique'] == $field) {
  1277. $objectPrefix = $this->inline->inlineNames['object'].'['.$table.']';
  1278. $aOnClickInline = $objectPrefix.'|inline.checkUniqueElement|inline.setUniqueElement';
  1279. $rOnClickInline = 'inline.revertUnique(\''.$objectPrefix.'\',null,\''.$uid.'\');';
  1280. }
  1281. }*/
  1282. $aOnClick='setFormValueOpenBrowser(\''.$mode.'\',\''.($this->formFieldName.'|||'.$allowed.'|'.$aOnClickInline).'\'); return false;';
  1283. $icons['R'][]='<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.
  1284. t3lib_iconWorks::getSpriteIcon('actions-insert-record', array('title' => htmlspecialchars(t3lib_TCEforms_Helper::getLL('l_browse_' . ($mode == 'db' ? 'db' : 'file'))))) .
  1285. '</a>';
  1286. }
  1287. if (!$params['dontShowMoveIcons']) {
  1288. if ($sSize>=5) {
  1289. $icons['L'][]='<a href="#" onclick="setFormValueManipulate(\''.$this->formFieldName.'\',\'Top\'); return false;">'.
  1290. t3lib_iconWorks::getSpriteIcon('actions-move-to-top', array('title' => htmlspecialchars(t3lib_TCEforms_Helper::getLL('l_move_to_top')))) .
  1291. '</a>';
  1292. }
  1293. $icons['L'][]='<a href="#" onclick="setFormValueManipulate(\''.$this->formFieldName.'\',\'Up\'); return false;">'.
  1294. t3lib_iconWorks::getSpriteIcon('actions-move-up', array('title' => htmlspecialchars(t3lib_TCEforms_Helper::getLL('l_move_up')))) .
  1295. '</a>';
  1296. $icons['L'][]='<a href="#" onclick="setFormValueManipulate(\''.$this->formFieldName.'\',\'Down\'); return false;">'.
  1297. t3lib_iconWorks::getSpriteIcon('actions-move-down', array('title' => htmlspecialchars(t3lib_TCEforms_Helper::getLL('l_move_down')))) .
  1298. '</a>';
  1299. if ($sSize>=5) {
  1300. $icons['L'][]='<a href="#" onclick="setFormValueManipulate(\''.$this->formFieldName.'\',\'Bottom\'); return false;">'.
  1301. t3lib_iconWorks::getSpriteIcon('actions-move-to-bottom', array('title' => htmlspecialchars(t3lib_TCEforms_Helper::getLL('l_move_to_bottom')))) .
  1302. '</a>';
  1303. }
  1304. }
  1305. // mov…

Large files files are truncated, but you can click here to view the full file