Beispiel #1
0
 /**
  * Save the expanded/collapsed state of a child record in the BE_USER->uc.
  *
  * @param string $expand Whether this record is expanded.
  * @param string $collapse Whether this record is collapsed.
  * @return void
  */
 protected function setInlineExpandedCollapsedState($expand, $collapse)
 {
     $backendUser = $this->getBackendUserAuthentication();
     // The current table - for this table we should add/import records
     $currentTable = $this->inlineStackProcessor->getUnstableStructure();
     $currentTable = $currentTable['table'];
     // The top parent table - this table embeds the current table
     $top = $this->inlineStackProcessor->getStructureLevel(0);
     $topTable = $top['table'];
     $topUid = $top['uid'];
     $inlineView = $this->getInlineExpandCollapseStateArray();
     // Only do some action if the top record and the current record were saved before
     if (MathUtility::canBeInterpretedAsInteger($topUid)) {
         $expandUids = GeneralUtility::trimExplode(',', $expand);
         $collapseUids = GeneralUtility::trimExplode(',', $collapse);
         // Set records to be expanded
         foreach ($expandUids as $uid) {
             $inlineView[$topTable][$topUid][$currentTable][] = $uid;
         }
         // Set records to be collapsed
         foreach ($collapseUids as $uid) {
             $inlineView[$topTable][$topUid][$currentTable] = $this->removeFromArray($uid, $inlineView[$topTable][$topUid][$currentTable]);
         }
         // Save states back to database
         if (is_array($inlineView[$topTable][$topUid][$currentTable])) {
             $inlineView[$topTable][$topUid][$currentTable] = array_unique($inlineView[$topTable][$topUid][$currentTable]);
             $backendUser->uc['inlineView'] = serialize($inlineView);
             $backendUser->writeUC();
         }
     }
 }
    /**
     * Entry method
     *
     * @return array As defined in initializeResultArray() of AbstractNode
     * @throws AccessDeniedContentEditException
     */
    public function render()
    {
        $this->inlineData = $this->data['inlineData'];
        /** @var InlineStackProcessor $inlineStackProcessor */
        $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
        $this->inlineStackProcessor = $inlineStackProcessor;
        $inlineStackProcessor->initializeByGivenStructure($this->data['inlineStructure']);
        $this->initHookObjects();
        $parentUid = $this->data['inlineParentUid'];
        $record = $this->data['databaseRow'];
        $config = $this->data['inlineParentConfig'];
        $foreign_table = $config['foreign_table'];
        $foreign_selector = $config['foreign_selector'];
        $resultArray = $this->initializeResultArray();
        // Send a mapping information to the browser via JSON:
        // e.g. data[<curTable>][<curId>][<curField>] => data-<pid>-<parentTable>-<parentId>-<parentField>-<curTable>-<curId>-<curField>
        $formPrefix = $inlineStackProcessor->getCurrentStructureFormPrefix();
        $domObjectId = $inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']);
        $this->inlineData['map'][$formPrefix] = $domObjectId;
        $resultArray['inlineData'] = $this->inlineData;
        // Set this variable if we handle a brand new unsaved record:
        $isNewRecord = !MathUtility::canBeInterpretedAsInteger($record['uid']);
        // Set this variable if the only the default language record and inline child has not been localized yet
        $isDefaultLanguageRecord = $this->data['inlineIsDefaultLanguage'];
        // If there is a selector field, normalize it:
        if ($foreign_selector) {
            $valueToNormalize = $record[$foreign_selector];
            if (is_array($record[$foreign_selector])) {
                // @todo: this can be kicked again if always prepared rows are handled here
                $valueToNormalize = implode(',', $record[$foreign_selector]);
            }
            $record[$foreign_selector] = $this->normalizeUid($valueToNormalize);
        }
        // Get the current naming scheme for DOM name/id attributes:
        $appendFormFieldNames = '[' . $foreign_table . '][' . $record['uid'] . ']';
        $objectId = $domObjectId . '-' . $foreign_table . '-' . $record['uid'];
        $class = '';
        $html = '';
        $combinationHtml = '';
        if (!$isDefaultLanguageRecord) {
            // Get configuration:
            $collapseAll = isset($config['appearance']['collapseAll']) && $config['appearance']['collapseAll'];
            $expandAll = isset($config['appearance']['collapseAll']) && !$config['appearance']['collapseAll'];
            $ajaxLoad = !isset($config['appearance']['ajaxLoad']) || $config['appearance']['ajaxLoad'];
            if ($isNewRecord) {
                // Show this record expanded or collapsed
                $isExpanded = $expandAll || (!$collapseAll ? 1 : 0);
            } else {
                $isExpanded = $config['renderFieldsOnly'] || !$collapseAll && $this->getExpandedCollapsedState($foreign_table, $record['uid']) || $expandAll;
            }
            // Render full content ONLY IF this is an AJAX request, a new record, the record is not collapsed or AJAX loading is explicitly turned off
            if ($isNewRecord || $isExpanded || !$ajaxLoad) {
                $combinationHtml = '';
                if (isset($this->data['combinationChild'])) {
                    $combinationChild = $this->renderCombinationChild($this->data, $appendFormFieldNames);
                    $combinationHtml = $combinationChild['html'];
                    $combinationChild['html'] = '';
                    $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $combinationChild);
                }
                $childArray = $this->renderChild($this->data);
                $html = $childArray['html'];
                $childArray['html'] = '';
                $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $childArray);
            } else {
                // This string is the marker for the JS-function to check if the full content has already been loaded
                $html = '<!--notloaded-->';
            }
            if ($isNewRecord) {
                // Get the top parent table
                $top = $this->inlineStackProcessor->getStructureLevel(0);
                $ucFieldName = 'uc[inlineView][' . $top['table'] . '][' . $top['uid'] . ']' . $appendFormFieldNames;
                // Set additional fields for processing for saving
                $html .= '<input type="hidden" name="data' . $appendFormFieldNames . '[pid]" value="' . $record['pid'] . '"/>';
                $html .= '<input type="hidden" name="' . $ucFieldName . '" value="' . $isExpanded . '" />';
            } else {
                // Set additional field for processing for saving
                $html .= '<input type="hidden" name="cmd' . $appendFormFieldNames . '[delete]" value="1" disabled="disabled" />';
                if (!$isExpanded && !empty($GLOBALS['TCA'][$foreign_table]['ctrl']['enablecolumns']['disabled']) && $ajaxLoad) {
                    $checked = !empty($record['hidden']) ? ' checked="checked"' : '';
                    $html .= '<input type="checkbox" name="data' . $appendFormFieldNames . '[hidden]_0" value="1"' . $checked . ' />';
                    $html .= '<input type="input" name="data' . $appendFormFieldNames . '[hidden]" value="' . $record['hidden'] . '" />';
                }
            }
            // If this record should be shown collapsed
            $class = $isExpanded ? 'panel-visible' : 'panel-collapsed';
        }
        if ($config['renderFieldsOnly']) {
            $html = $html . $combinationHtml;
        } else {
            // Set the record container with data for output
            if ($isDefaultLanguageRecord) {
                $class .= ' t3-form-field-container-inline-placeHolder';
            }
            if (isset($record['hidden']) && (int) $record['hidden']) {
                $class .= ' t3-form-field-container-inline-hidden';
            }
            $class .= $isNewRecord ? ' inlineIsNewRecord' : '';
            $html = '
				<div class="panel panel-default panel-condensed ' . trim($class) . '" id="' . $objectId . '_div">
					<div class="panel-heading" data-toggle="formengine-inline" id="' . $objectId . '_header" data-expandSingle="' . ($config['appearance']['expandSingle'] ? 1 : 0) . '">
						<div class="form-irre-header">
							<div class="form-irre-header-cell form-irre-header-icon">
								<span class="caret"></span>
							</div>
							' . $this->renderForeignRecordHeader($parentUid, $foreign_table, $this->data, $config, $isDefaultLanguageRecord) . '
						</div>
					</div>
					<div class="panel-collapse" id="' . $objectId . '_fields" data-expandSingle="' . ($config['appearance']['expandSingle'] ? 1 : 0) . '" data-returnURL="' . htmlspecialchars(GeneralUtility::getIndpEnv('REQUEST_URI')) . '">' . $html . $combinationHtml . '</div>
				</div>';
        }
        $resultArray['html'] = $html;
        return $resultArray;
    }
    /**
     * Entry method
     *
     * @return array As defined in initializeResultArray() of AbstractNode
     */
    public function render()
    {
        $this->inlineData = $this->globalOptions['inlineData'];
        /** @var InlineStackProcessor $inlineStackProcessor */
        $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
        $this->inlineStackProcessor = $inlineStackProcessor;
        $inlineStackProcessor->initializeByGivenStructure($this->globalOptions['inlineStructure']);
        $this->initHookObjects();
        $row = $this->globalOptions['databaseRow'];
        $parentUid = $row['uid'];
        $record = $this->globalOptions['inlineRelatedRecordToRender'];
        $config = $this->globalOptions['inlineRelatedRecordConfig'];
        $foreign_table = $config['foreign_table'];
        $foreign_selector = $config['foreign_selector'];
        $resultArray = $this->initializeResultArray();
        $html = '';
        // Send a mapping information to the browser via JSON:
        // e.g. data[<curTable>][<curId>][<curField>] => data-<pid>-<parentTable>-<parentId>-<parentField>-<curTable>-<curId>-<curField>
        $formPrefix = $inlineStackProcessor->getCurrentStructureFormPrefix();
        $domObjectId = $inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->globalOptions['inlineFirstPid']);
        $this->inlineData['map'][$formPrefix] = $domObjectId;
        $resultArray['inlineData'] = $this->inlineData;
        // Set this variable if we handle a brand new unsaved record:
        $isNewRecord = !MathUtility::canBeInterpretedAsInteger($record['uid']);
        // Set this variable if the record is virtual and only show with header and not editable fields:
        $isVirtualRecord = isset($record['__virtual']) && $record['__virtual'];
        // If there is a selector field, normalize it:
        if ($foreign_selector) {
            $record[$foreign_selector] = $this->normalizeUid($record[$foreign_selector]);
        }
        if (!$this->checkAccess($isNewRecord ? 'new' : 'edit', $foreign_table, $record['uid'])) {
            // @todo: Suddenly returning something different than the usual return array is not a cool thing ...
            // @todo: Inline ajax relies on this at the moment, though.
            return FALSE;
        }
        // Get the current naming scheme for DOM name/id attributes:
        $appendFormFieldNames = '[' . $foreign_table . '][' . $record['uid'] . ']';
        $objectId = $domObjectId . '-' . $foreign_table . '-' . $record['uid'];
        $class = '';
        $html = '';
        $combinationHtml = '';
        if (!$isVirtualRecord) {
            // Get configuration:
            $collapseAll = isset($config['appearance']['collapseAll']) && $config['appearance']['collapseAll'];
            $expandAll = isset($config['appearance']['collapseAll']) && !$config['appearance']['collapseAll'];
            $ajaxLoad = !isset($config['appearance']['ajaxLoad']) || $config['appearance']['ajaxLoad'];
            if ($isNewRecord) {
                // Show this record expanded or collapsed
                $isExpanded = $expandAll || (!$collapseAll ? 1 : 0);
            } else {
                $isExpanded = $config['renderFieldsOnly'] || !$collapseAll && $this->getExpandedCollapsedState($foreign_table, $record['uid']) || $expandAll;
            }
            // Render full content ONLY IF this is a AJAX-request, a new record, the record is not collapsed or AJAX-loading is explicitly turned off
            if ($isNewRecord || $isExpanded || !$ajaxLoad) {
                $combinationChildArray = $this->renderCombinationTable($record, $appendFormFieldNames, $config);
                $combinationHtml = $combinationChildArray['html'];
                $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $combinationChildArray);
                $overruleTypesArray = isset($config['foreign_types']) ? $config['foreign_types'] : array();
                $childArray = $this->renderRecord($foreign_table, $record, $overruleTypesArray);
                $html = $childArray['html'];
                $childArray['html'] = '';
                $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $childArray);
                // Replace returnUrl in Wizard-Code, if this is an AJAX call
                $ajaxArguments = GeneralUtility::_GP('ajax');
                if (isset($ajaxArguments[2]) && trim($ajaxArguments[2]) != '') {
                    $html = str_replace('P[returnUrl]=%2F' . rawurlencode(TYPO3_mainDir) . 'ajax.php', 'P[returnUrl]=' . rawurlencode($ajaxArguments[2]), $html);
                }
            } else {
                // This string is the marker for the JS-function to check if the full content has already been loaded
                $html = '<!--notloaded-->';
            }
            if ($isNewRecord) {
                // Get the top parent table
                $top = $this->inlineStackProcessor->getStructureLevel(0);
                $ucFieldName = 'uc[inlineView][' . $top['table'] . '][' . $top['uid'] . ']' . $appendFormFieldNames;
                // Set additional fields for processing for saving
                $html .= '<input type="hidden" name="data' . $appendFormFieldNames . '[pid]" value="' . $record['pid'] . '"/>';
                $html .= '<input type="hidden" name="' . $ucFieldName . '" value="' . $isExpanded . '" />';
            } else {
                // Set additional field for processing for saving
                $html .= '<input type="hidden" name="cmd' . $appendFormFieldNames . '[delete]" value="1" disabled="disabled" />';
                if (!$isExpanded && !empty($GLOBALS['TCA'][$foreign_table]['ctrl']['enablecolumns']['disabled']) && $ajaxLoad) {
                    $checked = !empty($record['hidden']) ? ' checked="checked"' : '';
                    $html .= '<input type="checkbox" name="data' . $appendFormFieldNames . '[hidden]_0" value="1"' . $checked . ' />';
                    $html .= '<input type="input" name="data' . $appendFormFieldNames . '[hidden]" value="' . $record['hidden'] . '" />';
                }
            }
            // If this record should be shown collapsed
            $class = $isExpanded ? 'panel-visible' : 'panel-collapsed';
        }
        if ($config['renderFieldsOnly']) {
            $html = $html . $combinationHtml;
        } else {
            // Set the record container with data for output
            if ($isVirtualRecord) {
                $class .= ' t3-form-field-container-inline-placeHolder';
            }
            if (isset($record['hidden']) && (int) $record['hidden']) {
                $class .= ' t3-form-field-container-inline-hidden';
            }
            $class .= $isNewRecord ? ' inlineIsNewRecord' : '';
            $html = '
				<div class="panel panel-default panel-condensed ' . trim($class) . '" id="' . $objectId . '_div">
					<div class="panel-heading" data-toggle="formengine-inline" id="' . $objectId . '_header" data-expandSingle="' . ($config['appearance']['expandSingle'] ? 1 : 0) . '">
						<div class="form-irre-header">
							<div class="form-irre-header-cell form-irre-header-icon">
								<span class="caret"></span>
							</div>
							' . $this->renderForeignRecordHeader($parentUid, $foreign_table, $record, $config, $isVirtualRecord) . '
						</div>
					</div>
					<div class="panel-collapse" id="' . $objectId . '_fields" data-expandSingle="' . ($config['appearance']['expandSingle'] ? 1 : 0) . '" data-returnURL="' . htmlspecialchars(GeneralUtility::getIndpEnv('REQUEST_URI')) . '">' . $html . $combinationHtml . '</div>
				</div>';
        }
        $resultArray['html'] = $html;
        return $resultArray;
    }