1<?php 2 3/* 4 * This file is part of the TYPO3 CMS project. 5 * 6 * It is free software; you can redistribute it and/or modify it under 7 * the terms of the GNU General Public License, either version 2 8 * of the License, or any later version. 9 * 10 * For the full copyright and license information, please read the 11 * LICENSE.txt file that was distributed with this source code. 12 * 13 * The TYPO3 project - inspiring people to share! 14 */ 15 16namespace TYPO3\CMS\Backend\Form\Container; 17 18use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; 19use TYPO3\CMS\Core\Imaging\Icon; 20use TYPO3\CMS\Core\Imaging\IconFactory; 21use TYPO3\CMS\Core\Localization\LanguageService; 22use TYPO3\CMS\Core\Utility\GeneralUtility; 23 24/** 25 * Flex form container implementation 26 * This one is called by FlexFormSectionContainer and renders HTML for a single container. 27 * For processing of single elements FlexFormElementContainer is called 28 */ 29class FlexFormContainerContainer extends AbstractContainer 30{ 31 /** 32 * Entry method 33 * 34 * @return array As defined in initializeResultArray() of AbstractNode 35 */ 36 public function render() 37 { 38 $languageService = $this->getLanguageService(); 39 40 $table = $this->data['tableName']; 41 $row = $this->data['databaseRow']; 42 $fieldName = $this->data['fieldName']; 43 $flexFormFormPrefix = $this->data['flexFormFormPrefix']; 44 $flexFormContainerElementCollapsed = $this->data['flexFormContainerElementCollapsed']; 45 $flexFormDataStructureArray = $this->data['flexFormDataStructureArray']; 46 $parameterArray = $this->data['parameterArray']; 47 48 $iconFactory = GeneralUtility::makeInstance(IconFactory::class); 49 $flexFormContainerIdentifier = $this->data['flexFormContainerIdentifier']; 50 $actionFieldName = '_ACTION_FLEX_FORM' 51 . $parameterArray['itemFormElName'] 52 . $this->data['flexFormFormPrefix'] 53 . '[_ACTION]' 54 . '[' . $flexFormContainerIdentifier . ']'; 55 $toggleFieldName = 'data[' . $table . '][' . $row['uid'] . '][' . $fieldName . ']' 56 . $flexFormFormPrefix 57 . '[' . $flexFormContainerIdentifier . ']' 58 . '[_TOGGLE]'; 59 60 $moveAndDeleteContent = []; 61 $userHasAccessToDefaultLanguage = $this->getBackendUserAuthentication()->checkLanguageAccess(0); 62 if ($userHasAccessToDefaultLanguage) { 63 $moveAndDeleteContent[] = '<button type="button" class="btn btn-default t3js-delete"><span title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:delete')) . '">' . $iconFactory->getIcon('actions-edit-delete', Icon::SIZE_SMALL)->render() . '</span></button>'; 64 $moveAndDeleteContent[] = '<button type="button" class="btn btn-default t3js-sortable-handle sortableHandle"><span title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:sortable.dragmove')) . '">' . $iconFactory->getIcon('actions-move-move', Icon::SIZE_SMALL)->render() . '</span></button>'; 65 } 66 67 $options = $this->data; 68 // Append container specific stuff to field prefix 69 $options['flexFormFormPrefix'] = $flexFormFormPrefix . '[' . $flexFormContainerIdentifier . '][' . $this->data['flexFormContainerName'] . '][el]'; 70 $options['flexFormDataStructureArray'] = $flexFormDataStructureArray['el']; 71 $options['renderType'] = 'flexFormElementContainer'; 72 $containerContentResult = $this->nodeFactory->create($options)->render(); 73 74 $containerTitle = ''; 75 if (!empty(trim($flexFormDataStructureArray['title']))) { 76 $containerTitle = $languageService->sL(trim($flexFormDataStructureArray['title'])); 77 } 78 79 $resultArray = $this->initializeResultArray(); 80 81 $flexFormDomContainerId = sprintf('flexform-container-%s', $flexFormContainerIdentifier); 82 $parentSectionContainer = sprintf('flexform-section-container-%s-%s', $this->data['fieldName'], $this->data['flexFormFieldName']); 83 $containerAttributes = [ 84 'class' => 'form-irre-object panel panel-default panel-condensed t3js-flex-section', 85 'data-parent' => $parentSectionContainer, 86 'data-flexform-container-id' => $flexFormContainerIdentifier, 87 ]; 88 89 $panelHeaderAttributes = [ 90 'class' => 'panel-heading', 91 'data-bs-toggle' => 'flexform-inline', 92 'data-bs-target' => '#' . $flexFormDomContainerId, 93 ]; 94 95 $toggleAttributes = [ 96 'class' => 'form-irre-header-cell form-irre-header-button', 97 'type' => 'button', 98 'aria-controls' => $flexFormDomContainerId, 99 'aria-expanded' => $flexFormContainerElementCollapsed ? 'false' : 'true', 100 ]; 101 102 $html = []; 103 $html[] = '<div ' . GeneralUtility::implodeAttributes($containerAttributes, true) . '>'; 104 $html[] = '<input class="t3js-flex-control-action" type="hidden" name="' . htmlspecialchars($actionFieldName) . '" value="" />'; 105 $html[] = '<div ' . GeneralUtility::implodeAttributes($panelHeaderAttributes, true) . '>'; 106 $html[] = '<div class="form-irre-header ' . ($flexFormContainerElementCollapsed ? ' collapsed' : '') . '">'; 107 $html[] = '<div class="form-irre-header-cell form-irre-header-icon">'; 108 $html[] = '<span class="caret"></span>'; 109 $html[] = '</div>'; 110 $html[] = '<button ' . GeneralUtility::implodeAttributes($toggleAttributes, true) . '>'; 111 $html[] = '<div class="form-irre-header-cell form-irre-header-body">'; 112 $html[] = htmlspecialchars($containerTitle); 113 $html[] = '<output class="content-preview"></output>'; 114 $html[] = '</div>'; 115 $html[] = '</button>'; 116 $html[] = '<div class="form-irre-header-cell form-irre-header-control t3js-formengine-irre-control">'; 117 $html[] = '<div class="btn-group btn-group-sm">'; 118 $html[] = implode(LF, $moveAndDeleteContent); 119 $html[] = '</div>'; 120 $html[] = '</div>'; 121 $html[] = '</div>'; 122 $html[] = '</div>'; 123 $html[] = '<div id="' . htmlspecialchars($flexFormDomContainerId) . '" class="collapse t3js-flex-section-content ' . ($flexFormContainerElementCollapsed ? '' : 'show') . '">'; 124 $html[] = $containerContentResult['html']; 125 $html[] = '</div>'; 126 $html[] = '<input'; 127 $html[] = 'class="t3js-flex-control-toggle"'; 128 $html[] = 'type="hidden"'; 129 $html[] = 'id="flexform-toggle-container-' . htmlspecialchars($flexFormContainerIdentifier) . '"'; 130 $html[] = 'name="' . htmlspecialchars($toggleFieldName) . '"'; 131 $html[] = 'value="' . ($flexFormContainerElementCollapsed ? '1' : '0') . '"'; 132 $html[] = '/>'; 133 $html[] = '</div>'; 134 135 $resultArray['html'] = implode(LF, $html); 136 $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $containerContentResult, false); 137 138 return $resultArray; 139 } 140 141 /** 142 * @return BackendUserAuthentication 143 */ 144 protected function getBackendUserAuthentication() 145 { 146 return $GLOBALS['BE_USER']; 147 } 148 149 /** 150 * @return LanguageService 151 */ 152 protected function getLanguageService() 153 { 154 return $GLOBALS['LANG']; 155 } 156} 157