diff --git a/Build/Sources/TypeScript/backend/form-engine-validation.ts b/Build/Sources/TypeScript/backend/form-engine-validation.ts index 511dcfe338c848c40c53b4d3c5dee3ded0011587..045ca4c02706cf66676189827de6accc764b7df1 100644 --- a/Build/Sources/TypeScript/backend/form-engine-validation.ts +++ b/Build/Sources/TypeScript/backend/form-engine-validation.ts @@ -552,7 +552,7 @@ export default (function() { $(sectionElement).find(FormEngineValidation.rulesSelector).each((index: number, field: HTMLElement) => { const $field = $(field); - if (!$field.closest('.t3js-flex-section-deleted, .t3js-inline-record-deleted').length) { + if (!$field.closest('.t3js-flex-section-deleted, .t3js-inline-record-deleted, .t3js-file-reference-deleted').length) { let modified = false; const currentValue = $field.val(); const newValue = FormEngineValidation.validateField($field, currentValue); diff --git a/Build/Sources/TypeScript/backend/form-engine/container/files-control-container.ts b/Build/Sources/TypeScript/backend/form-engine/container/files-control-container.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3dc1945a14a33052ec8182475bee456e4201ab6 --- /dev/null +++ b/Build/Sources/TypeScript/backend/form-engine/container/files-control-container.ts @@ -0,0 +1,705 @@ +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +import AjaxRequest from '@typo3/core/ajax/ajax-request'; +import {MessageUtility} from '../../utility/message-utility'; +import {AjaxDispatcher} from './../inline-relation/ajax-dispatcher'; +import {InlineResponseInterface} from './../inline-relation/inline-response-interface'; +import NProgress from 'nprogress'; +import Sortable from 'sortablejs'; +import FormEngine from '@typo3/backend/form-engine'; +import FormEngineValidation from '@typo3/backend/form-engine-validation'; +import Icons from '../../icons'; +import InfoWindow from '../../info-window'; +import Modal, {ModalElement} from '../../modal'; +import RegularEvent from '@typo3/core/event/regular-event'; +import Severity from '../../severity'; +import Utility from '../../utility'; + +enum Selectors { + toggleSelector = '[data-bs-toggle="formengine-file"]', + controlSectionSelector = '.t3js-formengine-file-header-control', + deleteRecordButtonSelector = '.t3js-editform-delete-file-reference', + enableDisableRecordButtonSelector = '.t3js-toggle-visibility-button', + infoWindowButton = '[data-action="infowindow"]', + synchronizeLocalizeRecordButtonSelector = '.t3js-synchronizelocalize-button', + controlContainer = '.t3js-file-controls', +} + +enum States { + new = 'isNewFileReference', + visible = 'panel-visible', + collapsed = 'panel-collapsed', + notLoaded = 't3js-not-loaded', +} + +enum Separators { + structureSeparator = '-', +} + +enum SortDirections { + DOWN = 'down', + UP = 'up', +} + +interface RequestQueue { + [key: string]: AjaxRequest; +} + +interface ProgressQueue { + [key: string]: any; +} + +interface Appearance { + expandSingle?: boolean; + useSortable?: boolean; +} + +/** + * Module: @typo3/backend/form-engine/container/files-control-container + * + * Functionality for the files control container + * + * @example + * <typo3-formengine-container-files identifier="some-id"> + * ... + * </typo3-formengine-container-files> + * + * This is based on W3C custom elements ("web components") specification, see + * https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements + */ +class FilesControlContainer extends HTMLElement { + private container: HTMLElement = null; + private ajaxDispatcher: AjaxDispatcher = null; + private appearance: Appearance = null; + private requestQueue: RequestQueue = {}; + private progessQueue: ProgressQueue = {}; + private noTitleString: string = (TYPO3.lang ? TYPO3.lang['FormEngine.noRecordTitle'] : '[No title]'); + + private static getFileReferenceContainer(objectId: string): HTMLDivElement { + return <HTMLDivElement>document.querySelector('[data-object-id="' + objectId + '"]'); + } + + private static getCollapseButton(objectId: string): HTMLButtonElement { + return <HTMLButtonElement>document.querySelector('[aria-controls="' + objectId + '_fields"]'); + } + + private static toggleElement(objectId: string): void { + const fileReferenceContainer = FilesControlContainer.getFileReferenceContainer(objectId); + if (fileReferenceContainer.classList.contains(States.collapsed)) { + FilesControlContainer.expandElement(fileReferenceContainer, objectId); + } else { + FilesControlContainer.collapseElement(fileReferenceContainer, objectId); + } + } + + private static collapseElement(recordContainer: HTMLDivElement, objectId: string): void { + const collapseButton = FilesControlContainer.getCollapseButton(objectId); + recordContainer.classList.remove(States.visible); + recordContainer.classList.add(States.collapsed); + collapseButton.setAttribute('aria-expanded', 'false'); + } + + private static expandElement(recordContainer: HTMLDivElement, objectId: string): void { + const collapseButton = FilesControlContainer.getCollapseButton(objectId); + recordContainer.classList.remove(States.collapsed); + recordContainer.classList.add(States.visible); + collapseButton.setAttribute('aria-expanded', 'true'); + } + + private static isNewRecord(objectId: string): boolean { + const fileReferenceContainer = FilesControlContainer.getFileReferenceContainer(objectId); + return fileReferenceContainer.classList.contains(States.new); + } + + private static updateExpandedCollapsedStateLocally(objectId: string, value: boolean): void { + const fileReferenceContainer = FilesControlContainer.getFileReferenceContainer(objectId); + + const ucFormObj = document.getElementsByName( + 'uc[inlineView]' + + '[' + fileReferenceContainer.dataset.topmostParentTable + ']' + + '[' + fileReferenceContainer.dataset.topmostParentUid + ']' + + fileReferenceContainer.dataset.fieldName + ); + + if (ucFormObj.length) { + (<HTMLInputElement>ucFormObj[0]).value = value ? '1' : '0'; + } + } + + public connectedCallback(): void { + const identifier = this.getAttribute('identifier') || '' as string; + this.container = <HTMLElement>this.querySelector('#' + identifier); + + if (this.container !== null) { + this.ajaxDispatcher = new AjaxDispatcher(this.container.dataset.objectGroup); + this.registerEvents(); + } + } + + private registerEvents(): void { + this.registerInfoButton(); + this.registerSort(); + this.registerEnableDisableButton(); + this.registerDeleteButton(); + this.registerSynchronizeLocalize(); + this.registerToggle(); + + new RegularEvent('message', this.handlePostMessage).bindTo(window); + + if (this.getAppearance().useSortable) { + const recordListContainer = <HTMLDivElement>document.getElementById(this.container.getAttribute('id') + '_records'); + // tslint:disable-next-line:no-unused-expression + new Sortable(recordListContainer, { + group: recordListContainer.getAttribute('id'), + handle: '.sortableHandle', + onSort: (): void => { + this.updateSorting(); + }, + }); + } + } + + private registerToggle(): void { + const me = this; + new RegularEvent('click', function(this: HTMLElement, e: Event) { + e.preventDefault(); + e.stopImmediatePropagation(); + + me.loadRecordDetails(this.closest(Selectors.toggleSelector).parentElement.dataset.objectId); + }).delegateTo(this.container, `${Selectors.toggleSelector} .form-irre-header-cell:not(${Selectors.controlSectionSelector}`); + } + + private registerSort(): void { + const me = this; + new RegularEvent('click', function(this: HTMLElement, e: Event) { + e.preventDefault(); + e.stopImmediatePropagation(); + + me.changeSortingByButton( + (<HTMLDivElement>this.closest('[data-object-id]')).dataset.objectId, + <SortDirections>this.dataset.direction, + ); + }).delegateTo(this.container, Selectors.controlSectionSelector + ' [data-action="sort"]'); + } + + private handlePostMessage = (e: MessageEvent): void => { + if (!MessageUtility.verifyOrigin(e.origin)) { + throw 'Denied message sent by ' + e.origin; + } + + if (e.data.actionName === 'typo3:foreignRelation:insert') { + if (typeof e.data.objectGroup === 'undefined') { + throw 'No object group defined for message'; + } + + if (e.data.objectGroup !== this.container.dataset.objectGroup) { + // Received message isn't provisioned for current FilesContainer instance + return; + } + + this.importRecord([e.data.objectGroup, e.data.uid]).then((): void => { + if (e.source) { + const message = { + actionName: 'typo3:foreignRelation:inserted', + objectGroup: e.data.objectId, + table: e.data.table, + uid: e.data.uid, + }; + MessageUtility.send(message, e.source as Window); + } + }); + } + } + + private createRecord(uid: string, markup: string, afterUid: string = null, selectedValue: string = null): void { + let objectId = this.container.dataset.objectGroup; + if (afterUid !== null) { + objectId += Separators.structureSeparator + afterUid; + } + + if (afterUid !== null) { + FilesControlContainer.getFileReferenceContainer(objectId).insertAdjacentHTML('afterend', markup); + this.memorizeAddRecord(uid, afterUid, selectedValue); + } else { + document.getElementById(this.container.getAttribute('id') + '_records').insertAdjacentHTML('beforeend', markup); + this.memorizeAddRecord(uid, null, selectedValue); + } + } + + private async importRecord(params: Array<any>, afterUid?: string): Promise<void> { + return this.ajaxDispatcher.send( + this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint('file_reference_create')), + params, + ).then(async (response: InlineResponseInterface): Promise<void> => { + if (this.isBelowMax()) { + this.createRecord( + response.compilerInput.uid, + response.data, + typeof afterUid !== 'undefined' ? afterUid : null, + typeof response.compilerInput.childChildUid !== 'undefined' ? response.compilerInput.childChildUid : null, + ); + } + }); + } + + private registerEnableDisableButton(): void { + new RegularEvent('click', (e: Event, target: HTMLElement): void => { + e.preventDefault(); + e.stopImmediatePropagation(); + + const objectId = (<HTMLDivElement>target.closest('[data-object-id]')).dataset.objectId; + const recordContainer = FilesControlContainer.getFileReferenceContainer(objectId); + const hiddenFieldName = 'data' + recordContainer.dataset.fieldName + '[' + target.dataset.hiddenField + ']'; + const hiddenValueCheckBox = <HTMLInputElement>document.querySelector('[data-formengine-input-name="' + hiddenFieldName + '"'); + const hiddenValueInput = <HTMLInputElement>document.querySelector('[name="' + hiddenFieldName + '"'); + + if (hiddenValueCheckBox !== null && hiddenValueInput !== null) { + hiddenValueCheckBox.checked = !hiddenValueCheckBox.checked; + hiddenValueInput.value = hiddenValueCheckBox.checked ? '1' : '0'; + FormEngineValidation.markFieldAsChanged(hiddenValueCheckBox); + } + + const hiddenClass = 't3-form-field-container-inline-hidden'; + const isHidden = recordContainer.classList.contains(hiddenClass); + let toggleIcon: string; + + if (isHidden) { + toggleIcon = 'actions-edit-hide'; + recordContainer.classList.remove(hiddenClass); + } else { + toggleIcon = 'actions-edit-unhide'; + recordContainer.classList.add(hiddenClass); + } + + Icons.getIcon(toggleIcon, Icons.sizes.small).then((markup: string): void => { + target.replaceChild(document.createRange().createContextualFragment(markup), target.querySelector('.t3js-icon')); + }); + }).delegateTo(this.container, Selectors.enableDisableRecordButtonSelector); + } + + private registerInfoButton(): void { + new RegularEvent('click', function(this: HTMLElement, e: Event) { + e.preventDefault(); + e.stopImmediatePropagation(); + + InfoWindow.showItem(this.dataset.infoTable, this.dataset.infoUid); + }).delegateTo(this.container, Selectors.infoWindowButton); + } + + private registerDeleteButton(): void { + const me = this; + new RegularEvent('click', function(this: HTMLElement, e: Event) { + e.preventDefault(); + e.stopImmediatePropagation(); + + const title = TYPO3.lang['label.confirm.delete_record.title'] || 'Delete this record?'; + const content = TYPO3.lang['label.confirm.delete_record.content'] || 'Are you sure you want to delete this record?'; + Modal.confirm(title, content, Severity.warning, [ + { + text: TYPO3.lang['buttons.confirm.delete_record.no'] || 'Cancel', + active: true, + btnClass: 'btn-default', + name: 'no', + trigger: (e: Event, modal: ModalElement) => modal.hideModal(), + }, + { + text: TYPO3.lang['buttons.confirm.delete_record.yes'] || 'Yes, delete this record', + btnClass: 'btn-warning', + name: 'yes', + trigger: (e: Event, modal: ModalElement): void => { + me.deleteRecord((<HTMLDivElement>this.closest('[data-object-id]')).dataset.objectId); + modal.hideModal(); + } + }, + ]); + }).delegateTo(this.container, Selectors.deleteRecordButtonSelector); + } + + private registerSynchronizeLocalize(): void { + const me = this; + new RegularEvent('click', function(this: HTMLElement, e: Event) { + e.preventDefault(); + e.stopImmediatePropagation(); + + me.ajaxDispatcher.send( + me.ajaxDispatcher.newRequest(me.ajaxDispatcher.getEndpoint('file_reference_synchronizelocalize')), + [me.container.dataset.objectGroup, this.dataset.type], + ).then(async (response: InlineResponseInterface): Promise<any> => { + document.getElementById(me.container.getAttribute('id') + '_records').insertAdjacentHTML('beforeend', response.data); + + const objectIdPrefix = me.container.dataset.objectGroup + Separators.structureSeparator; + for (let itemUid of response.compilerInput.delete) { + me.deleteRecord(objectIdPrefix + itemUid, true); + } + + for (let item of Object.values(response.compilerInput.localize)) { + if (typeof item.remove !== 'undefined') { + const removableRecordContainer = FilesControlContainer.getFileReferenceContainer(objectIdPrefix + item.remove); + removableRecordContainer.parentElement.removeChild(removableRecordContainer); + } + + me.memorizeAddRecord(item.uid, null, item.selectedValue); + } + }); + }).delegateTo(this.container, Selectors.synchronizeLocalizeRecordButtonSelector); + } + + private loadRecordDetails(objectId: string): void { + const recordFieldsContainer = document.getElementById(objectId + '_fields'); + const recordContainer = FilesControlContainer.getFileReferenceContainer(objectId); + const isLoading = typeof this.requestQueue[objectId] !== 'undefined'; + const isLoaded = recordFieldsContainer !== null && !recordContainer.classList.contains(States.notLoaded); + + if (!isLoaded) { + const progress = this.getProgress(objectId, recordContainer.dataset.objectIdHash); + + if (!isLoading) { + const ajaxRequest = this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint('file_reference_details')); + const request = this.ajaxDispatcher.send(ajaxRequest, [objectId]); + + request.then(async (response: InlineResponseInterface): Promise<any> => { + delete this.requestQueue[objectId]; + delete this.progessQueue[objectId]; + + recordContainer.classList.remove(States.notLoaded); + recordFieldsContainer.innerHTML = response.data; + this.collapseExpandRecord(objectId); + + progress.done(); + + FormEngine.reinitialize(); + FormEngineValidation.initializeInputFields(); + FormEngineValidation.validate(this.container); + }); + + this.requestQueue[objectId] = ajaxRequest; + progress.start(); + } else { + // Abort loading if collapsed again + this.requestQueue[objectId].abort(); + delete this.requestQueue[objectId]; + delete this.progessQueue[objectId]; + progress.done(); + } + + return; + } + + this.collapseExpandRecord(objectId); + } + + private collapseExpandRecord(objectId: string): void { + const recordElement = FilesControlContainer.getFileReferenceContainer(objectId); + const expandSingle = this.getAppearance().expandSingle === true; + const isCollapsed: boolean = recordElement.classList.contains(States.collapsed); + let collapse: Array<string> = []; + const expand: Array<string> = []; + + if (expandSingle && isCollapsed) { + collapse = this.collapseAllRecords(recordElement.dataset.objectUid); + } + + FilesControlContainer.toggleElement(objectId); + + if (FilesControlContainer.isNewRecord(objectId)) { + FilesControlContainer.updateExpandedCollapsedStateLocally(objectId, isCollapsed); + } else if (isCollapsed) { + expand.push(recordElement.dataset.objectUid); + } else if (!isCollapsed) { + collapse.push(recordElement.dataset.objectUid); + } + + this.ajaxDispatcher.send( + this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint('file_reference_expandcollapse')), + [objectId, expand.join(','), collapse.join(',')] + ); + } + + private memorizeAddRecord(newUid: string, afterUid: string = null, selectedValue: string = null): void { + const formField = this.getFormFieldForElements(); + if (formField === null) { + return; + } + + let records = Utility.trimExplode(',', (<HTMLInputElement>formField).value); + if (afterUid) { + const newRecords = []; + for (let i = 0; i < records.length; i++) { + if (records[i].length) { + newRecords.push(records[i]); + } + if (afterUid === records[i]) { + newRecords.push(newUid); + } + } + records = newRecords; + } else { + records.push(newUid); + } + + (<HTMLInputElement>formField).value = records.join(','); + (<HTMLInputElement>formField).classList.add('has-change'); + document.dispatchEvent(new Event('change')); + + this.redrawSortingButtons(this.container.dataset.objectGroup, records); + + if (!this.isBelowMax()) { + this.toggleContainerControls(false); + } + + FormEngine.reinitialize(); + FormEngineValidation.initializeInputFields(); + FormEngineValidation.validate(this.container); + } + + private memorizeRemoveRecord(objectUid: string): Array<string> { + const formField = this.getFormFieldForElements(); + if (formField === null) { + return []; + } + + let records = Utility.trimExplode(',', (<HTMLInputElement>formField).value); + const indexOfRemoveUid = records.indexOf(objectUid); + if (indexOfRemoveUid > -1) { + delete records[indexOfRemoveUid]; + + (<HTMLInputElement>formField).value = records.join(','); + (<HTMLInputElement>formField).classList.add('has-change'); + document.dispatchEvent(new Event('change')); + + this.redrawSortingButtons(this.container.dataset.objectGroup, records); + } + + return records; + } + + private changeSortingByButton(objectId: string, direction: SortDirections): void { + const fileReferenceContainer = FilesControlContainer.getFileReferenceContainer(objectId); + const objectUid = fileReferenceContainer.dataset.objectUid; + const recordListContainer = <HTMLDivElement>document.getElementById(this.container.getAttribute('id') + '_records'); + const records = Array.from(recordListContainer.children).map((child: HTMLElement) => child.dataset.objectUid); + let position = records.indexOf(objectUid); + let isChanged = false; + + if (direction === SortDirections.UP && position > 0) { + records[position] = records[position - 1]; + records[position - 1] = objectUid; + isChanged = true; + } else if (direction === SortDirections.DOWN && position < records.length - 1) { + records[position] = records[position + 1]; + records[position + 1] = objectUid; + isChanged = true; + } + + if (isChanged) { + const objectIdPrefix = this.container.dataset.objectGroup + Separators.structureSeparator; + const adjustment = direction === SortDirections.UP ? 1 : 0; + fileReferenceContainer.parentElement.insertBefore( + FilesControlContainer.getFileReferenceContainer(objectIdPrefix + records[position - adjustment]), + FilesControlContainer.getFileReferenceContainer(objectIdPrefix + records[position + 1 - adjustment]), + ); + + this.updateSorting(); + } + } + + private updateSorting(): void { + const formField = this.getFormFieldForElements(); + if (formField === null) { + return; + } + + const recordListContainer = <HTMLDivElement>document.getElementById(this.container.getAttribute('id') + '_records'); + const records = Array.from(recordListContainer.querySelectorAll('[data-object-parent-group="' + this.container.dataset.objectGroup + '"][data-placeholder-record="0"]')) + .map((child: HTMLElement) => child.dataset.objectUid); + + (<HTMLInputElement>formField).value = records.join(','); + (<HTMLInputElement>formField).classList.add('has-change'); + document.dispatchEvent(new Event('formengine:files:sorting-changed')); + document.dispatchEvent(new Event('change')); + + this.redrawSortingButtons(this.container.dataset.objectGroup, records); + } + + private deleteRecord(objectId: string, forceDirectRemoval: boolean = false): void { + const recordContainer = FilesControlContainer.getFileReferenceContainer(objectId); + const objectUid = recordContainer.dataset.objectUid; + + recordContainer.classList.add('t3js-file-reference-deleted'); + + if (!FilesControlContainer.isNewRecord(objectId) && !forceDirectRemoval) { + const deleteCommandInput = this.container.querySelector('[name="cmd' + recordContainer.dataset.fieldName + '[delete]"]'); + deleteCommandInput.removeAttribute('disabled'); + + // Move input field to inline container so we can remove the record container + recordContainer.parentElement.insertAdjacentElement('afterbegin', deleteCommandInput); + } + + new RegularEvent('transitionend', (): void => { + recordContainer.parentElement.removeChild(recordContainer); + FormEngineValidation.validate(this.container); + }).bindTo(recordContainer); + + this.memorizeRemoveRecord(objectUid); + recordContainer.classList.add('form-irre-object--deleted'); + + if (this.isBelowMax()) { + this.toggleContainerControls(true); + } + } + + private toggleContainerControls(visible: boolean): void { + const controlContainer = this.container.querySelector(Selectors.controlContainer); + if (controlContainer === null) { + return; + } + const controlContainerButtons = controlContainer.querySelectorAll('button, a'); + controlContainerButtons.forEach((button: HTMLElement): void => { + button.style.display = visible ? null : 'none'; + }); + } + + private getProgress(objectId: string, objectIdHash: string): any { + const headerIdentifier = '#' + objectIdHash + '_header'; + let progress: any; + + if (typeof this.progessQueue[objectId] !== 'undefined') { + progress = this.progessQueue[objectId]; + } else { + progress = NProgress; + progress.configure({parent: headerIdentifier, showSpinner: false}); + this.progessQueue[objectId] = progress; + } + + return progress; + } + + private collapseAllRecords(excludeUid: string): Array<string> { + const formField = this.getFormFieldForElements(); + const collapse: Array<string> = []; + + if (formField !== null) { + const records = Utility.trimExplode(',', (<HTMLInputElement>formField).value); + for (let recordUid of records) { + if (recordUid === excludeUid) { + continue; + } + + const recordObjectId = this.container.dataset.objectGroup + Separators.structureSeparator + recordUid; + const recordContainer = FilesControlContainer.getFileReferenceContainer(recordObjectId); + if (recordContainer.classList.contains(States.visible)) { + FilesControlContainer.collapseElement(recordContainer, recordObjectId); + + if (FilesControlContainer.isNewRecord(recordObjectId)) { + FilesControlContainer.updateExpandedCollapsedStateLocally(recordObjectId, false); + } else { + collapse.push(recordUid); + } + } + } + } + + return collapse; + } + + private getFormFieldForElements(): HTMLInputElement | null { + const formFields = document.getElementsByName(this.container.dataset.formField); + if (formFields.length > 0) { + return <HTMLInputElement>formFields[0]; + } + + return null; + } + + private redrawSortingButtons(objectId: string, records: Array<string> = []): void { + if (records.length === 0) { + const formField = this.getFormFieldForElements(); + if (formField !== null) { + records = Utility.trimExplode(',', (<HTMLInputElement>formField).value); + } + } + + if (records.length === 0) { + return; + } + + records.forEach((recordUid: string, index: number): void => { + const recordContainer = FilesControlContainer.getFileReferenceContainer(objectId + Separators.structureSeparator + recordUid); + const headerIdentifier = recordContainer.dataset.objectIdHash + '_header'; + const headerElement = document.getElementById(headerIdentifier); + const sortUp = headerElement.querySelector('[data-action="sort"][data-direction="' + SortDirections.UP + '"]'); + + if (sortUp !== null) { + let iconIdentifier = 'actions-move-up'; + if (index === 0) { + sortUp.classList.add('disabled'); + iconIdentifier = 'empty-empty'; + } else { + sortUp.classList.remove('disabled'); + } + Icons.getIcon(iconIdentifier, Icons.sizes.small).then((markup: string): void => { + sortUp.replaceChild(document.createRange().createContextualFragment(markup), sortUp.querySelector('.t3js-icon')); + }); + } + + const sortDown = headerElement.querySelector('[data-action="sort"][data-direction="' + SortDirections.DOWN + '"]'); + if (sortDown !== null) { + let iconIdentifier = 'actions-move-down'; + if (index === records.length - 1) { + sortDown.classList.add('disabled'); + iconIdentifier = 'empty-empty'; + } else { + sortDown.classList.remove('disabled'); + } + Icons.getIcon(iconIdentifier, Icons.sizes.small).then((markup: string): void => { + sortDown.replaceChild(document.createRange().createContextualFragment(markup), sortDown.querySelector('.t3js-icon')); + }); + } + }); + } + + private isBelowMax(): boolean { + const formField = this.getFormFieldForElements(); + if (formField === null) { + return true; + } + + if (typeof TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup] !== 'undefined') { + const records = Utility.trimExplode(',', (<HTMLInputElement>formField).value); + if (records.length >= TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup].max) { + return false; + } + } + + return true; + } + + private getAppearance(): Appearance { + if (this.appearance === null) { + this.appearance = {}; + + if (typeof this.container.dataset.appearance === 'string') { + try { + this.appearance = JSON.parse(this.container.dataset.appearance); + } catch (e) { + console.error(e); + } + } + } + + return this.appearance; + } +} + +window.customElements.define('typo3-formengine-container-files', FilesControlContainer); diff --git a/Build/phpstan/phpstan-baseline.neon b/Build/phpstan/phpstan-baseline.neon index 73b3fff2ab5b3312440905928f13b5f7b2ccfced..50d91ef3ae541d53654604891798945aa830d28d 100644 --- a/Build/phpstan/phpstan-baseline.neon +++ b/Build/phpstan/phpstan-baseline.neon @@ -435,11 +435,6 @@ parameters: count: 1 path: ../../typo3/sysext/core/Classes/DataHandling/DataHandler.php - - - message: "#^Variable \\$uids in empty\\(\\) always exists and is not falsy\\.$#" - count: 1 - path: ../../typo3/sysext/core/Classes/DataHandling/DataHandler.php - - message: "#^Method TYPO3\\\\CMS\\\\Core\\\\DataHandling\\\\Localization\\\\DataMapProcessor\\:\\:fetchDependencies\\(\\) should return array\\<array\\<TYPO3\\\\CMS\\\\Core\\\\DataHandling\\\\Localization\\\\DataMapItem\\>\\> but returns array\\<int\\|string, array\\<string, array\\<int, TYPO3\\\\CMS\\\\Core\\\\DataHandling\\\\Localization\\\\DataMapItem\\>\\>\\>\\.$#" count: 1 diff --git a/composer.lock b/composer.lock index a5b4dda0ec3b220846d8f3bc6e4c1f3dfbbe40c2..682f8815e6402bf8f07c13605253e266f8bcc246 100644 --- a/composer.lock +++ b/composer.lock @@ -8483,12 +8483,12 @@ "source": { "type": "git", "url": "https://github.com/TYPO3/styleguide.git", - "reference": "5759503933c13dd5ea13c535ac0c026b3a2a0281" + "reference": "e9076c14eb9fb62582c4c3c5912b21f4c75b2bf7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/TYPO3/styleguide/zipball/5759503933c13dd5ea13c535ac0c026b3a2a0281", - "reference": "5759503933c13dd5ea13c535ac0c026b3a2a0281", + "url": "https://api.github.com/repos/TYPO3/styleguide/zipball/e9076c14eb9fb62582c4c3c5912b21f4c75b2bf7", + "reference": "e9076c14eb9fb62582c4c3c5912b21f4c75b2bf7", "shasum": "" }, "require-dev": { @@ -8547,7 +8547,7 @@ "issues": "https://github.com/TYPO3/styleguide/issues", "source": "https://github.com/TYPO3/styleguide/tree/main" }, - "time": "2022-09-26T09:45:10+00:00" + "time": "2022-10-01T13:43:50+00:00" }, { "name": "typo3/testing-framework", @@ -8650,5 +8650,5 @@ "platform-overrides": { "php": "8.1.1" }, - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.2.0" } diff --git a/typo3/sysext/backend/Classes/Backend/Avatar/DefaultAvatarProvider.php b/typo3/sysext/backend/Classes/Backend/Avatar/DefaultAvatarProvider.php index cdb61eeb5041485309b6923d273867cc2e2f118d..1ece7193d9ff79b9e3b3dedad445726744b4f039 100644 --- a/typo3/sysext/backend/Classes/Backend/Avatar/DefaultAvatarProvider.php +++ b/typo3/sysext/backend/Classes/Backend/Avatar/DefaultAvatarProvider.php @@ -84,10 +84,6 @@ class DefaultAvatarProvider implements AvatarProviderInterface 'fieldname', $queryBuilder->createNamedParameter('avatar', \PDO::PARAM_STR) ), - $queryBuilder->expr()->eq( - 'table_local', - $queryBuilder->createNamedParameter('sys_file', \PDO::PARAM_STR) - ), $queryBuilder->expr()->eq( 'uid_foreign', $queryBuilder->createNamedParameter((int)$backendUserId, \PDO::PARAM_INT) diff --git a/typo3/sysext/backend/Classes/Controller/FormFilesAjaxController.php b/typo3/sysext/backend/Classes/Controller/FormFilesAjaxController.php new file mode 100644 index 0000000000000000000000000000000000000000..629abcf7e3077ec160c1cd7a8b7558635e5e4e7c --- /dev/null +++ b/typo3/sysext/backend/Classes/Controller/FormFilesAjaxController.php @@ -0,0 +1,531 @@ +<?php + +declare(strict_types=1); + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +namespace TYPO3\CMS\Backend\Controller; + +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\StreamFactoryInterface; +use TYPO3\CMS\Backend\Form\Container\FileReferenceContainer; +use TYPO3\CMS\Backend\Form\FormDataCompiler; +use TYPO3\CMS\Backend\Form\FormDataGroup\TcaDatabaseRecord; +use TYPO3\CMS\Backend\Form\InlineStackProcessor; +use TYPO3\CMS\Backend\Form\NodeFactory; +use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; +use TYPO3\CMS\Core\DataHandling\DataHandler; +use TYPO3\CMS\Core\Messaging\FlashMessageService; +use TYPO3\CMS\Core\Page\JavaScriptItems; +use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity; +use TYPO3\CMS\Core\Utility\ArrayUtility; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\Utility\MathUtility; + +/** + * Handle FormEngine files ajax calls + */ +class FormFilesAjaxController extends AbstractFormEngineAjaxController +{ + private const FILE_REFERENCE_TABLE = 'sys_file_reference'; + + public function __construct( + private readonly ResponseFactoryInterface $responseFactory, + private readonly StreamFactoryInterface $streamFactory + ) { + } + + /** + * Create a new file reference via AJAX. + */ + public function createAction(ServerRequestInterface $request): ResponseInterface + { + $arguments = $request->getParsedBody()['ajax']; + $parentConfig = $this->extractSignedParentConfigFromRequest((string)($arguments['context'] ?? '')); + + $domObjectId = (string)($arguments[0] ?? ''); + $inlineFirstPid = $this->getInlineFirstPidFromDomObjectId($domObjectId); + if (!MathUtility::canBeInterpretedAsInteger($inlineFirstPid) && !str_starts_with((string)$inlineFirstPid, 'NEW')) { + throw new \RuntimeException( + 'inlineFirstPid should either be an integer or a "NEW..." string', + 1664440476 + ); + } + $fileId = null; + if (isset($arguments[1]) && MathUtility::canBeInterpretedAsInteger($arguments[1])) { + $fileId = (int)$arguments[1]; + } + + $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class); + $inlineStackProcessor->initializeByParsingDomObjectIdString($domObjectId); + $inlineStackProcessor->injectAjaxConfiguration($parentConfig); + $inlineTopMostParent = $inlineStackProcessor->getStructureLevel(0); + + $parent = $inlineStackProcessor->getStructureLevel(-1); + $fileReference = $inlineStackProcessor->getUnstableStructure(); + + if (isset($fileReference['uid']) && MathUtility::canBeInterpretedAsInteger($fileReference['uid'])) { + // If uid comes in, it is the id of the record neighbor record "create after" + $fileReferenceVanillaUid = -1 * abs((int)$fileReference['uid']); + } else { + // Else inline first Pid is the storage pid of new inline records + $fileReferenceVanillaUid = $inlineFirstPid; + } + + $formDataCompilerInput = [ + 'command' => 'new', + 'tableName' => self::FILE_REFERENCE_TABLE, + 'vanillaUid' => $fileReferenceVanillaUid, + 'isInlineChild' => true, + 'inlineStructure' => $inlineStackProcessor->getStructure(), + 'inlineFirstPid' => $inlineFirstPid, + 'inlineParentUid' => $parent['uid'], + 'inlineParentTableName' => $parent['table'], + 'inlineParentFieldName' => $parent['field'], + 'inlineParentConfig' => $parentConfig, + 'inlineTopMostParentUid' => $inlineTopMostParent['uid'], + 'inlineTopMostParentTableName' => $inlineTopMostParent['table'], + 'inlineTopMostParentFieldName' => $inlineTopMostParent['field'], + ]; + if ($fileId) { + $formDataCompilerInput['inlineChildChildUid'] = $fileId; + } + + $fileReferenceData = GeneralUtility::makeInstance( + FormDataCompiler::class, + GeneralUtility::makeInstance(TcaDatabaseRecord::class) + )->compile($formDataCompilerInput); + + $fileReferenceData['inlineParentUid'] = $parent['uid']; + $fileReferenceData['renderType'] = FileReferenceContainer::NODE_TYPE_IDENTIFIER; + + return $this->jsonResponse( + $this->mergeFileReferenceResultIntoJsonResult( + [ + 'data' => '', + 'stylesheetFiles' => [], + 'scriptItems' => GeneralUtility::makeInstance(JavaScriptItems::class), + 'scriptCall' => [], + 'compilerInput' => [ + 'uid' => $fileReferenceData['databaseRow']['uid'], + 'childChildUid' => $fileId, + 'parentConfig' => $parentConfig, + ], + ], + GeneralUtility::makeInstance(NodeFactory::class)->create($fileReferenceData)->render() + ) + ); + } + + /** + * Show the details of a file reference + */ + public function detailsAction(ServerRequestInterface $request): ResponseInterface + { + $arguments = $request->getParsedBody()['ajax'] ?? $request->getQueryParams()['ajax']; + + $domObjectId = (string)($arguments[0] ?? ''); + $inlineFirstPid = $this->getInlineFirstPidFromDomObjectId($domObjectId); + $parentConfig = $this->extractSignedParentConfigFromRequest((string)($arguments['context'] ?? '')); + + $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class); + $inlineStackProcessor->initializeByParsingDomObjectIdString($domObjectId); + $inlineStackProcessor->injectAjaxConfiguration($parentConfig); + + $parent = $inlineStackProcessor->getStructureLevel(-1); + $parentFieldName = $parent['field']; + + // Set flag in config so that only the fields are rendered + // @todo: Solve differently / rename / whatever + $parentConfig['renderFieldsOnly'] = true; + + $parentData = [ + 'processedTca' => [ + 'columns' => [ + $parentFieldName => [ + 'config' => $parentConfig, + ], + ], + ], + 'uid' => $parent['uid'], + 'tableName' => $parent['table'], + 'inlineFirstPid' => $inlineFirstPid, + 'returnUrl' => $parentConfig['originalReturnUrl'], + ]; + + $fileReference = $inlineStackProcessor->getUnstableStructure(); + $fileReferenceData = $this->compileFileReference( + $parentData, + $parentFieldName, + (int)$fileReference['uid'], + $inlineStackProcessor->getStructure() + ); + $fileReferenceData['inlineParentUid'] = (int)$parent['uid']; + $fileReferenceData['renderType'] = FileReferenceContainer::NODE_TYPE_IDENTIFIER; + + return $this->jsonResponse( + $this->mergeFileReferenceResultIntoJsonResult( + [ + 'data' => '', + 'stylesheetFiles' => [], + 'scriptItems' => GeneralUtility::makeInstance(JavaScriptItems::class), + 'scriptCall' => [], + ], + GeneralUtility::makeInstance(NodeFactory::class)->create($fileReferenceData)->render() + ) + ); + } + + /** + * Adds localizations or synchronizes the locations of all file references. + */ + public function synchronizeLocalizeAction(ServerRequestInterface $request): ResponseInterface + { + $arguments = $request->getParsedBody()['ajax']; + + $domObjectId = (string)($arguments[0] ?? ''); + $type = $arguments[1] ?? null; + $parentConfig = $this->extractSignedParentConfigFromRequest((string)($arguments['context'] ?? '')); + + $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class); + $inlineStackProcessor->initializeByParsingDomObjectIdString($domObjectId); + $inlineStackProcessor->injectAjaxConfiguration($parentConfig); + $inlineFirstPid = $this->getInlineFirstPidFromDomObjectId($domObjectId); + + $jsonArray = [ + 'data' => '', + 'stylesheetFiles' => [], + 'scriptItems' => GeneralUtility::makeInstance(JavaScriptItems::class), + 'compilerInput' => [ + 'localize' => [], + ], + ]; + if ($type === 'localize' || $type === 'synchronize' || MathUtility::canBeInterpretedAsInteger($type)) { + // Parent, this table embeds the sys_file_reference table + $parent = $inlineStackProcessor->getStructureLevel(-1); + $parentFieldName = $parent['field']; + + $processedTca = $GLOBALS['TCA'][$parent['table']]; + $processedTca['columns'][$parentFieldName]['config'] = $parentConfig; + + $formDataCompilerInputForParent = [ + 'vanillaUid' => (int)$parent['uid'], + 'command' => 'edit', + 'tableName' => $parent['table'], + 'processedTca' => $processedTca, + 'inlineFirstPid' => $inlineFirstPid, + 'columnsToProcess' => [ + $parentFieldName, + ], + // @todo: still needed? NO! + 'inlineStructure' => $inlineStackProcessor->getStructure(), + // Do not compile existing file references, we don't need them now + 'inlineCompileExistingChildren' => false, + ]; + // Full TcaDatabaseRecord is required here to have the list of connected uids $oldItemList + $parentData = GeneralUtility::makeInstance( + FormDataCompiler::class, + GeneralUtility::makeInstance(TcaDatabaseRecord::class) + )->compile($formDataCompilerInputForParent); + $parentLanguageField = $parentData['processedTca']['ctrl']['languageField']; + $parentLanguage = $parentData['databaseRow'][$parentLanguageField]; + $oldItemList = $parentData['databaseRow'][$parentFieldName]; + + // DataHandler cannot handle arrays as field value + if (is_array($parentLanguage)) { + $parentLanguage = implode(',', $parentLanguage); + } + + $cmd = []; + // Localize a single file reference from default language of the parent element + if (MathUtility::canBeInterpretedAsInteger($type)) { + $cmd[$parent['table']][$parent['uid']]['inlineLocalizeSynchronize'] = [ + 'field' => $parent['field'], + 'language' => $parentLanguage, + 'ids' => [$type], + ]; + } else { + // Either localize or synchronize all file references from default language of the parent element + $cmd[$parent['table']][$parent['uid']]['inlineLocalizeSynchronize'] = [ + 'field' => $parent['field'], + 'language' => $parentLanguage, + 'action' => $type, + ]; + } + + $tce = GeneralUtility::makeInstance(DataHandler::class); + $tce->start([], $cmd); + $tce->process_cmdmap(); + + $oldItems = $this->getFileReferenceUids((string)$oldItemList); + + $newItemList = (string)($tce->registerDBList[$parent['table']][$parent['uid']][$parentFieldName] ?? ''); + $newItems = $this->getFileReferenceUids($newItemList); + + // Render error messages from DataHandler + $tce->printLogErrorMessages(); + $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class); + $messages = $flashMessageService->getMessageQueueByIdentifier()->getAllMessagesAndFlush(); + if (!empty($messages)) { + foreach ($messages as $message) { + $jsonArray['messages'][] = [ + 'title' => $message->getTitle(), + 'message' => $message->getMessage(), + 'severity' => $message->getSeverity(), + ]; + if ($message->getSeverity() === ContextualFeedbackSeverity::ERROR) { + $jsonArray['hasErrors'] = true; + } + } + } + + // Set the items that should be removed in the forms view: + $removedItems = array_diff($oldItems, $newItems); + $jsonArray['compilerInput']['delete'] = $removedItems; + + $localizedItems = array_diff($newItems, $oldItems); + foreach ($localizedItems as $i => $localizedFileReferenceUid) { + $fileReferenceData = $this->compileFileReference($parentData, $parentFieldName, (int)$localizedFileReferenceUid, $inlineStackProcessor->getStructure()); + $fileReferenceData['inlineParentUid'] = (int)$parent['uid']; + $fileReferenceData['renderType'] = FileReferenceContainer::NODE_TYPE_IDENTIFIER; + + $jsonArray = $this->mergeFileReferenceResultIntoJsonResult( + $jsonArray, + GeneralUtility::makeInstance(NodeFactory::class)->create($fileReferenceData)->render() + ); + + // Get the name of the field used as foreign selector (if any): + $selectedValue = $fileReferenceData['databaseRow']['uid_local']; + if (is_array($selectedValue)) { + $selectedValue = $selectedValue[0]; + } + + $jsonArray['compilerInput']['localize'][$i] = [ + 'uid' => $localizedFileReferenceUid, + 'selectedValue' => $selectedValue, + ]; + + // Remove possible virtual records in the form which showed that a file reference could be + // localized: + $transOrigPointerFieldName = $fileReferenceData['processedTca']['ctrl']['transOrigPointerField']; + if (isset($fileReferenceData['databaseRow'][$transOrigPointerFieldName]) && $fileReferenceData['databaseRow'][$transOrigPointerFieldName]) { + $transOrigPointerFieldValue = $fileReferenceData['databaseRow'][$transOrigPointerFieldName]; + if (is_array($transOrigPointerFieldValue)) { + $transOrigPointerFieldValue = $transOrigPointerFieldValue[0]; + if (is_array($transOrigPointerFieldValue) && ($transOrigPointerFieldValue['uid'] ?? false)) { + $transOrigPointerFieldValue = $transOrigPointerFieldValue['uid']; + } + } + $jsonArray['compilerInput']['localize'][$i]['remove'] = $transOrigPointerFieldValue; + } + } + } + return $this->jsonResponse($jsonArray); + } + + /** + * Store status of file references' expand / collapse state in backend user UC. + */ + public function expandOrCollapseAction(ServerRequestInterface $request): ResponseInterface + { + [$domObjectId, $expand, $collapse] = $request->getParsedBody()['ajax']; + + $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class); + $inlineStackProcessor->initializeByParsingDomObjectIdString($domObjectId); + + $currentTable = $inlineStackProcessor->getUnstableStructure()['table']; + $top = $inlineStackProcessor->getStructureLevel(0); + $stateArray = $this->getReferenceExpandCollapseStateArray(); + // Only do some action if the top record and the current record were saved before + if (MathUtility::canBeInterpretedAsInteger($top['uid'])) { + // Set records to be expanded + foreach (GeneralUtility::trimExplode(',', $expand) as $uid) { + $stateArray[$top['table']][$top['uid']][$currentTable][] = $uid; + } + // Set records to be collapsed + foreach (GeneralUtility::trimExplode(',', $collapse) as $uid) { + $stateArray[$top['table']][$top['uid']][$currentTable] = $this->removeFromArray( + $uid, + $stateArray[$top['table']][$top['uid']][$currentTable] + ); + } + // Save states back to database + if (is_array($stateArray[$top['table']][$top['uid']][$currentTable] ?? false)) { + $stateArray[$top['table']][$top['uid']][$currentTable] = array_unique($stateArray[$top['table']][$top['uid']][$currentTable]); + $backendUser = $this->getBackendUserAuthentication(); + $backendUser->uc['inlineView'] = json_encode($stateArray); + $backendUser->writeUC(); + } + } + return $this->jsonResponse(); + } + + protected function compileFileReference(array $parentData, $parentFieldName, $fileReferenceUid, array $inlineStructure): array + { + $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class); + $inlineStackProcessor->initializeByGivenStructure($inlineStructure); + $inlineTopMostParent = $inlineStackProcessor->getStructureLevel(0); + + return GeneralUtility::makeInstance( + FormDataCompiler::class, + GeneralUtility::makeInstance(TcaDatabaseRecord::class) + )->compile([ + 'command' => 'edit', + 'tableName' => self::FILE_REFERENCE_TABLE, + 'vanillaUid' => (int)$fileReferenceUid, + 'returnUrl' => $parentData['returnUrl'], + 'isInlineChild' => true, + 'inlineStructure' => $inlineStructure, + 'inlineFirstPid' => $parentData['inlineFirstPid'], + 'inlineParentConfig' => $parentData['processedTca']['columns'][$parentFieldName]['config'], + 'isInlineAjaxOpeningContext' => true, + 'inlineParentUid' => $parentData['databaseRow']['uid'] ?? $parentData['uid'], + 'inlineParentTableName' => $parentData['tableName'], + 'inlineParentFieldName' => $parentFieldName, + 'inlineTopMostParentUid' => $inlineTopMostParent['uid'], + 'inlineTopMostParentTableName' => $inlineTopMostParent['table'], + 'inlineTopMostParentFieldName' => $inlineTopMostParent['field'], + ]); + } + + /** + * Merge compiled file reference data into the json result array. + */ + protected function mergeFileReferenceResultIntoJsonResult(array $jsonResult, array $fileReferenceData): array + { + /** @var JavaScriptItems $scriptItems */ + $scriptItems = $jsonResult['scriptItems']; + + $jsonResult['data'] .= $fileReferenceData['html']; + $jsonResult['stylesheetFiles'] = []; + foreach ($fileReferenceData['stylesheetFiles'] as $stylesheetFile) { + $jsonResult['stylesheetFiles'][] = $this->getRelativePathToStylesheetFile($stylesheetFile); + } + if (!empty($fileReferenceData['inlineData'])) { + $jsonResult['inlineData'] = $fileReferenceData['inlineData']; + } + // @todo deprecate with TYPO3 v12.0 + foreach ($fileReferenceData['additionalJavaScriptPost'] as $singleAdditionalJavaScriptPost) { + $jsonResult['scriptCall'][] = $singleAdditionalJavaScriptPost; + } + if (!empty($fileReferenceData['additionalInlineLanguageLabelFiles'])) { + $labels = []; + foreach ($fileReferenceData['additionalInlineLanguageLabelFiles'] as $additionalInlineLanguageLabelFile) { + ArrayUtility::mergeRecursiveWithOverrule( + $labels, + $this->getLabelsFromLocalizationFile($additionalInlineLanguageLabelFile) + ); + } + $scriptItems->addGlobalAssignment(['TYPO3' => ['lang' => $labels]]); + } + $this->addRegisteredRequireJsModulesToJavaScriptItems($fileReferenceData, $scriptItems); + + return $jsonResult; + } + + /** + * Gets an array with the uids of file references out of a list of items. + */ + protected function getFileReferenceUids(string $itemList): array + { + $itemArray = GeneralUtility::trimExplode(',', $itemList, true); + // Perform modification of the selected items array: + foreach ($itemArray as &$value) { + $parts = explode('|', $value, 2); + $value = $parts[0]; + } + unset($value); + return $itemArray; + } + + /** + * Get expand / collapse state of inline items + * + * @return array + */ + protected function getReferenceExpandCollapseStateArray(): array + { + $backendUser = $this->getBackendUserAuthentication(); + if (empty($backendUser->uc['inlineView'])) { + return []; + } + + $state = json_decode($backendUser->uc['inlineView'], true); + if (!is_array($state)) { + $state = []; + } + + return $state; + } + + /** + * Remove an element from an array. + */ + protected function removeFromArray(mixed $needle, array $haystack, bool $strict = false): array + { + $pos = array_search($needle, $haystack, $strict); + if ($pos !== false) { + unset($haystack[$pos]); + } + return $haystack; + } + + /** + * Get inlineFirstPid from a given objectId string + */ + protected function getInlineFirstPidFromDomObjectId(string $domObjectId): int|string|null + { + // Substitute FlexForm addition and make parsing a bit easier + $domObjectId = str_replace('---', ':', $domObjectId); + // The starting pattern of an object identifier (e.g. "data-<firstPidValue>-<anything>) + $pattern = '/^data-(.+?)-(.+)$/'; + if (preg_match($pattern, $domObjectId, $match)) { + return $match[1]; + } + return null; + } + + /** + * Validates the config that is transferred over the wire to provide the + * correct TCA config for the parent table + */ + protected function extractSignedParentConfigFromRequest(string $contextString): array + { + if ($contextString === '') { + throw new \RuntimeException('Empty context string given', 1664486783); + } + $context = json_decode($contextString, true); + if (empty($context['config'])) { + throw new \RuntimeException('Empty context config section given', 1664486790); + } + if (!hash_equals(GeneralUtility::hmac((string)$context['config'], 'FilesContext'), (string)$context['hmac'])) { + throw new \RuntimeException('Hash does not validate', 1664486791); + } + return json_decode($context['config'], true); + } + + protected function jsonResponse(array $json = []): ResponseInterface + { + return $this->responseFactory->createResponse() + ->withHeader('Content-Type', 'application/json; charset=utf-8') + ->withBody($this->streamFactory->createStream((string)json_encode($json))); + } + + protected function getBackendUserAuthentication(): BackendUserAuthentication + { + return $GLOBALS['BE_USER']; + } +} diff --git a/typo3/sysext/backend/Classes/Controller/FormInlineAjaxController.php b/typo3/sysext/backend/Classes/Controller/FormInlineAjaxController.php index 8775767befe0ee8d6a6d23e07b71572c9ba73cde..53cb7beb695ca9e78b33958e9a805b9c508da0eb 100644 --- a/typo3/sysext/backend/Classes/Controller/FormInlineAjaxController.php +++ b/typo3/sysext/backend/Classes/Controller/FormInlineAjaxController.php @@ -365,7 +365,7 @@ class FormInlineAjaxController extends AbstractFormEngineAjaxController $transOrigPointerFieldValue = $transOrigPointerFieldValue[0]; if (is_array($transOrigPointerFieldValue) && ($transOrigPointerFieldValue['uid'] ?? false)) { // With nested inline containers (eg. fal sys_file_reference), row[l10n_parent][0] is sometimes - // a table / row combination again. See tx_styleguide_inline_fal inline_5. If this happens we + // a table / row combination again. See tx_styleguide_file file_5. If this happens we // pick the uid field from the array ... Basically, we need the uid of the 'default language' record, // since this is used in JS to locate and remove the 'shadowed' container. // @todo: Find out if this is really necessary that sometimes ['databaseRow']['l10n_parent'][0] @@ -579,25 +579,6 @@ class FormInlineAjaxController extends AbstractFormEngineAjaxController return $itemArray; } - /** - * Return expand / collapse state array for a given table / uid combination - * - * @param string $table Handled table - * @param int $uid Handled uid - * @return array - */ - protected function getInlineExpandCollapseStateArrayForTableUid($table, $uid) - { - $inlineView = $this->getInlineExpandCollapseStateArray(); - $result = []; - if (MathUtility::canBeInterpretedAsInteger($uid)) { - if (!empty($inlineView[$table][$uid])) { - $result = $inlineView[$table][$uid]; - } - } - return $result; - } - /** * Get expand / collapse state of inline items * diff --git a/typo3/sysext/backend/Classes/ElementBrowser/ElementBrowserInterface.php b/typo3/sysext/backend/Classes/ElementBrowser/ElementBrowserInterface.php index 88bcc7ab5635f2f91641f102d3662c1b66186473..b0035be353776deea1643b3d0acd603750627f04 100644 --- a/typo3/sysext/backend/Classes/ElementBrowser/ElementBrowserInterface.php +++ b/typo3/sysext/backend/Classes/ElementBrowser/ElementBrowserInterface.php @@ -20,7 +20,7 @@ namespace TYPO3\CMS\Backend\ElementBrowser; /** * Element browsers are modals rendered when records are attached to FormEngine elements. * Core usages: - * * Managing TCA inline FAL file relations of some record + * * Managing TCA type=file relations * * Managing FAL folder relations a TCA type=folder * * Managing various target relations of a TCA type=group */ diff --git a/typo3/sysext/backend/Classes/Form/Container/FileReferenceContainer.php b/typo3/sysext/backend/Classes/Form/Container/FileReferenceContainer.php new file mode 100644 index 0000000000000000000000000000000000000000..a66448108283fc9ded96800e59861b89ee5eb54b --- /dev/null +++ b/typo3/sysext/backend/Classes/Form/Container/FileReferenceContainer.php @@ -0,0 +1,551 @@ +<?php + +declare(strict_types=1); + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +namespace TYPO3\CMS\Backend\Form\Container; + +use Psr\EventDispatcher\EventDispatcherInterface; +use TYPO3\CMS\Backend\Form\Event\ModifyFileReferenceControlsEvent; +use TYPO3\CMS\Backend\Form\Event\ModifyFileReferenceEnabledControlsEvent; +use TYPO3\CMS\Backend\Form\InlineStackProcessor; +use TYPO3\CMS\Backend\Form\NodeFactory; +use TYPO3\CMS\Backend\Routing\UriBuilder; +use TYPO3\CMS\Backend\Utility\BackendUtility; +use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; +use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Core\Imaging\Icon; +use TYPO3\CMS\Core\Imaging\IconFactory; +use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection; +use TYPO3\CMS\Core\Localization\LanguageService; +use TYPO3\CMS\Core\Resource\Exception\InvalidUidException; +use TYPO3\CMS\Core\Resource\Index\MetaDataRepository; +use TYPO3\CMS\Core\Resource\ProcessedFile; +use TYPO3\CMS\Core\Resource\ResourceFactory; +use TYPO3\CMS\Core\Type\Bitmask\Permission; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\Utility\MathUtility; + +/** + * Render a single file reference. + * + * This container is called by FilesControlContainer to render a single file (reference). The container is also + * called by FormEngine for an incoming ajax request to expand an existing file (reference) or to create a new one. + * + * This container creates the outer HTML of single file (references) - e.g. drag and drop and delete buttons. + * For rendering of the record itself processing is handed over to FullRecordContainer. + */ +class FileReferenceContainer extends AbstractContainer +{ + public const NODE_TYPE_IDENTIFIER = 'fileReferenceContainer'; + + private const FILE_REFERENCE_TABLE = 'sys_file_reference'; + private const FOREIGN_SELECTOR = 'uid_local'; + + private const SYS_FILE_LABEL_FIELDS = [ + 'title', + 'name', + ]; + + /** + * File reference data used for JSON output + */ + protected array $fileReferenceData = []; + + protected InlineStackProcessor $inlineStackProcessor; + protected IconFactory $iconFactory; + protected EventDispatcherInterface $eventDispatcher; + + public function __construct(NodeFactory $nodeFactory, array $data) + { + parent::__construct($nodeFactory, $data); + $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class); + $this->inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class); + $this->eventDispatcher = GeneralUtility::makeInstance(EventDispatcherInterface::class); + } + + public function render(): array + { + $inlineStackProcessor = $this->inlineStackProcessor; + $inlineStackProcessor->initializeByGivenStructure($this->data['inlineStructure']); + + // 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->fileReferenceData = $this->data['inlineData']; + $this->fileReferenceData['map'][$formPrefix] = $domObjectId; + + $resultArray = $this->initializeResultArray(); + $resultArray['inlineData'] = $this->fileReferenceData; + + $html = ''; + $classes = []; + $combinationHtml = ''; + $record = $this->data['databaseRow']; + $uid = $record['uid'] ?? 0; + $appendFormFieldNames = '[' . self::FILE_REFERENCE_TABLE . '][' . $uid . ']'; + $objectId = $domObjectId . '-' . self::FILE_REFERENCE_TABLE . '-' . $uid; + $isNewRecord = $this->data['command'] === 'new'; + $hiddenFieldName = (string)($this->data['processedTca']['ctrl']['enablecolumns']['disabled'] ?? ''); + if (!$this->data['isInlineDefaultLanguageRecordInLocalizedParentContext']) { + if ($isNewRecord || $this->data['isInlineChildExpanded']) { + $fileReferenceData = $this->renderFileReference($this->data); + $html = $fileReferenceData['html']; + $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fileReferenceData, false); + } else { + // This class is the marker for the JS-function to check if the full content has already been loaded + $classes[] = 't3js-not-loaded'; + } + if ($isNewRecord) { + // Add pid of file reference as hidden field + $html .= '<input type="hidden" name="data' . htmlspecialchars($appendFormFieldNames) + . '[pid]" value="' . (int)$record['pid'] . '"/>'; + // Tell DataHandler this file reference is expanded + $ucFieldName = 'uc[inlineView]' + . '[' . $this->data['inlineTopMostParentTableName'] . ']' + . '[' . $this->data['inlineTopMostParentUid'] . ']' + . htmlspecialchars($appendFormFieldNames); + $html .= '<input type="hidden" name="' . htmlspecialchars($ucFieldName) + . '" value="' . (int)$this->data['isInlineChildExpanded'] . '" />'; + } else { + // Set additional field for processing for saving + $html .= '<input type="hidden" name="cmd' . htmlspecialchars($appendFormFieldNames) + . '[delete]" value="1" disabled="disabled" />'; + if ($hiddenFieldName !== '' + && (!$this->data['isInlineChildExpanded'] + || !in_array($hiddenFieldName, $this->data['columnsToProcess'], true)) + ) { + $isHidden = (bool)($record[$hiddenFieldName] ?? false); + $html .= '<input type="checkbox" class="d-none" data-formengine-input-name="data' + . htmlspecialchars($appendFormFieldNames) + . '[' . htmlspecialchars($hiddenFieldName) . ']" value="1"' + . ($isHidden ? ' checked="checked"' : '') . ' />'; + $html .= '<input type="input" class="d-none" name="data' . htmlspecialchars($appendFormFieldNames) + . '[' . htmlspecialchars($hiddenFieldName) . ']" value="' . (int)$isHidden . '" />'; + } + } + // If this file reference should be shown collapsed + $classes[] = $this->data['isInlineChildExpanded'] ? 'panel-visible' : 'panel-collapsed'; + } + $hiddenFieldHtml = implode("\n", $resultArray['additionalHiddenFields'] ?? []); + + if ($this->data['inlineParentConfig']['renderFieldsOnly'] ?? false) { + // Render "body" part only + $resultArray['html'] = $html . $hiddenFieldHtml . $combinationHtml; + return $resultArray; + } + + // Render header row and content (if expanded) + if ($this->data['isInlineDefaultLanguageRecordInLocalizedParentContext']) { + $classes[] = 't3-form-field-container-inline-placeHolder'; + } + if ($record[$hiddenFieldName] ?? false) { + $classes[] = 't3-form-field-container-inline-hidden'; + } + if ($isNewRecord) { + $classes[] = 'isNewFileReference'; + } + + // The hashed object id needs a non-numeric prefix, the value is used as ID selector in JavaScript + $hashedObjectId = 'hash-' . md5($objectId); + $containerAttributes = [ + 'id' => $objectId . '_div', + 'class' => 'form-irre-object panel panel-default panel-condensed ' . trim(implode(' ', $classes)), + 'data-object-uid' => $record['uid'] ?? 0, + 'data-object-id' => $objectId, + 'data-object-id-hash' => $hashedObjectId, + 'data-object-parent-group' => $domObjectId . '-' . self::FILE_REFERENCE_TABLE, + 'data-field-name' => $appendFormFieldNames, + 'data-topmost-parent-table' => $this->data['inlineTopMostParentTableName'], + 'data-topmost-parent-uid' => $this->data['inlineTopMostParentUid'], + 'data-placeholder-record' => $this->data['isInlineDefaultLanguageRecordInLocalizedParentContext'] ? '1' : '0', + ]; + + $ariaControls = htmlspecialchars($objectId . '_fields', ENT_QUOTES | ENT_HTML5); + $resultArray['html'] = ' + <div ' . GeneralUtility::implodeAttributes($containerAttributes, true) . '> + <div class="panel-heading" data-bs-toggle="formengine-file" id="' . htmlspecialchars($hashedObjectId, ENT_QUOTES | ENT_HTML5) . '_header" data-expandSingle="' . (($this->data['inlineParentConfig']['appearance']['expandSingle'] ?? false) ? 1 : 0) . '"> + <div class="form-irre-header"> + <div class="form-irre-header-cell form-irre-header-icon"> + <span class="caret"></span> + </div> + ' . $this->renderFileHeader('aria-expanded="' . (($this->data['isInlineChildExpanded'] ?? false) ? 'true' : 'false') . '" aria-controls="' . $ariaControls . '"') . ' + </div> + </div> + <div class="panel-collapse" id="' . $ariaControls . '">' . $html . $hiddenFieldHtml . $combinationHtml . '</div> + </div>'; + + return $resultArray; + } + + protected function renderFileReference(array $data): array + { + $data['tabAndInlineStack'][] = [ + 'inline', + $this->inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($data['inlineFirstPid']) + . '-' + . $data['tableName'] + . '-' + . $data['databaseRow']['uid'], + ]; + + return $this->nodeFactory->create(array_replace_recursive($data, [ + 'inlineData' => $this->fileReferenceData, + 'renderType' => 'fullRecordContainer', + ]))->render(); + } + + /** + * Renders the HTML header for the file, such as the title, toggle-function, drag'n'drop, etc. + * Later on the command-icons are inserted here, too. + */ + protected function renderFileHeader(string $ariaAttributesString): string + { + $languageService = $this->getLanguageService(); + + $databaseRow = $this->data['databaseRow']; + $recordTitle = $this->getRecordTitle(); + + if (empty($recordTitle)) { + $recordTitle = '<em>[' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.no_title')) . ']</em>'; + } + + $objectId = $this->inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']) + . '-' . self::FILE_REFERENCE_TABLE + . '-' . ($databaseRow['uid'] ?? 0); + + $altText = BackendUtility::getRecordIconAltText($databaseRow, self::FILE_REFERENCE_TABLE); + + // Renders a thumbnail for the header + $thumbnail = ''; + if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['thumbnails'] ?? false) { + $fileUid = $databaseRow[self::FOREIGN_SELECTOR][0]['uid'] ?? null; + if (!empty($fileUid)) { + try { + $fileObject = GeneralUtility::makeInstance(ResourceFactory::class)->getFileObject($fileUid); + if ($fileObject->isMissing()) { + $thumbnail = ' + <span class="badge badge-danger">' + . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:warning.file_missing')) . ' + </span> + ' . htmlspecialchars($fileObject->getName()) . ' + <br />'; + } elseif ($fileObject->isImage()) { + $imageSetup = $this->data['inlineParentConfig']['appearance']['headerThumbnail'] ?? []; + $cropVariantCollection = CropVariantCollection::create($databaseRow['crop'] ?? ''); + if (!$cropVariantCollection->getCropArea()->isEmpty()) { + $imageSetup['crop'] = $cropVariantCollection->getCropArea()->makeAbsoluteBasedOnFile($fileObject); + } + $processedImage = $fileObject->process( + ProcessedFile::CONTEXT_IMAGECROPSCALEMASK, + array_merge(['maxWidth' => '145', 'maxHeight' => '45'], $imageSetup) + ); + // Only use a thumbnail if the processing process was successful by checking if image width is set + if ($processedImage->getProperty('width')) { + $imageUrl = $processedImage->getPublicUrl() ?? ''; + $thumbnail = '<img src="' . htmlspecialchars($imageUrl) . '" ' . + 'width="' . $processedImage->getProperty('width') . '" ' . + 'height="' . $processedImage->getProperty('height') . '" ' . + 'alt="' . $altText . '" ' . + 'title="' . $altText . '">'; + } + } + } catch (\InvalidArgumentException $e) { + $fileObject = null; + } + } + } + + if ($thumbnail !== '') { + $headerImage = ' + <div class="form-irre-header-thumbnail" id="' . $objectId . '_thumbnailcontainer"> + ' . $thumbnail . ' + </div>'; + } else { + $headerImage = ' + <div class="form-irre-header-icon" id="' . $objectId . '_iconcontainer"> + <span title="' . $altText . '" id="' . htmlspecialchars($objectId) . '_icon"> + ' . $this->iconFactory->getIconForRecord(self::FILE_REFERENCE_TABLE, $databaseRow, Icon::SIZE_SMALL)->render() . ' + </span> + </div>'; + } + + // @todo check classes and change to dedicated file related ones if possible + return ' + <button class="form-irre-header-cell form-irre-header-button" ' . $ariaAttributesString . '> + ' . $headerImage . ' + <div class="form-irre-header-body"> + <span id="' . $objectId . '_label">' . $recordTitle . '</span> + </div> + </button> + <div class="form-irre-header-cell form-irre-header-control t3js-formengine-file-header-control"> + ' . $this->renderFileReferenceHeaderControl() . ' + </div>'; + } + + /** + * Render the control-icons for a file reference (e.g. create new, sorting, delete, disable/enable). + */ + protected function renderFileReferenceHeaderControl(): string + { + $controls = []; + $databaseRow = $this->data['databaseRow']; + $databaseRow += [ + 'uid' => 0, + ]; + $parentConfig = $this->data['inlineParentConfig']; + $languageService = $this->getLanguageService(); + $backendUser = $this->getBackendUserAuthentication(); + $isNewItem = str_starts_with((string)$databaseRow['uid'], 'NEW'); + $fileReferenceTableTca = $GLOBALS['TCA'][self::FILE_REFERENCE_TABLE]; + $calcPerms = new Permission( + $backendUser->calcPerms(BackendUtility::readPageAccess( + (int)($this->data['parentPageRow']['uid'] ?? 0), + $backendUser->getPagePermsClause(Permission::PAGE_SHOW) + )) + ); + $event = $this->eventDispatcher->dispatch( + new ModifyFileReferenceEnabledControlsEvent($this->data, $databaseRow) + ); + if ($this->data['isInlineDefaultLanguageRecordInLocalizedParentContext']) { + $controls['localize'] = ' + <span title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:localize.isLocalizable')) . '"> + ' . $this->iconFactory->getIcon('actions-edit-localize-status-low', Icon::SIZE_SMALL)->render() . ' + </span>'; + } + if ($event->isControlEnabled('info')) { + if ($isNewItem) { + $controls['info'] = ' + <span class="btn btn-default disabled"> + ' . $this->iconFactory->getIcon('empty-empty', Icon::SIZE_SMALL)->render() . ' + </span>'; + } else { + $controls['info'] = ' + <button type="button" class="btn btn-default" data-action="infowindow" data-info-table="' . htmlspecialchars('_FILE') . '" data-info-uid="' . (int)$databaseRow['uid_local'][0]['uid'] . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:showInfo')) . '"> + ' . $this->iconFactory->getIcon('actions-document-info', Icon::SIZE_SMALL)->render() . ' + </button>'; + } + } + // If the table is NOT a read-only table, then show these links: + if (!($parentConfig['readOnly'] ?? false) + && !($fileReferenceTableTca['ctrl']['readOnly'] ?? false) + && !($this->data['isInlineDefaultLanguageRecordInLocalizedParentContext'] ?? false) + ) { + if ($event->isControlEnabled('sort')) { + $icon = 'actions-move-up'; + $class = ''; + if ((int)$parentConfig['inline']['first'] === (int)$databaseRow['uid']) { + $class = ' disabled'; + $icon = 'empty-empty'; + } + $controls['sort.up'] = ' + <button type="button" class="btn btn-default' . $class . '" data-action="sort" data-direction="up" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:moveUp')) . '"> + ' . $this->iconFactory->getIcon($icon, Icon::SIZE_SMALL)->render() . ' + </button>'; + + $icon = 'actions-move-down'; + $class = ''; + if ((int)$parentConfig['inline']['last'] === (int)$databaseRow['uid']) { + $class = ' disabled'; + $icon = 'empty-empty'; + } + $controls['sort.down'] = ' + <button type="button" class="btn btn-default' . $class . '" data-action="sort" data-direction="down" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:moveDown')) . '"> + ' . $this->iconFactory->getIcon($icon, Icon::SIZE_SMALL)->render() . ' + </button>'; + } + if (!$isNewItem + && ($languageField = ($GLOBALS['TCA']['sys_file_metadata']['ctrl']['languageField'] ?? false)) + && $backendUser->check('tables_modify', 'sys_file_metadata') + && $event->isControlEnabled('edit') + ) { + $languageId = (int)(is_array($databaseRow[$languageField] ?? null) + ? ($databaseRow[$languageField][0] ?? 0) + : ($databaseRow[$languageField] ?? 0)); + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) + ->getQueryBuilderForTable('sys_file_metadata'); + $metadataRecord = $queryBuilder + ->select('uid') + ->from('sys_file_metadata') + ->where( + $queryBuilder->expr()->eq( + 'file', + $queryBuilder->createNamedParameter((int)$databaseRow['uid_local'][0]['uid'], \PDO::PARAM_INT) + ), + $queryBuilder->expr()->eq( + $languageField, + $queryBuilder->createNamedParameter($languageId, \PDO::PARAM_INT) + ) + ) + ->setMaxResults(1) + ->executeQuery() + ->fetchAssociative(); + if (!empty($metadataRecord)) { + $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); + $url = (string)$uriBuilder->buildUriFromRoute('record_edit', [ + 'edit[sys_file_metadata][' . (int)$metadataRecord['uid'] . ']' => 'edit', + 'returnUrl' => $this->data['returnUrl'], + ]); + $controls['edit'] = ' + <a class="btn btn-default" href="' . htmlspecialchars($url) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.editMetadata')) . '"> + ' . $this->iconFactory->getIcon('actions-open', Icon::SIZE_SMALL)->render() . ' + </a>'; + } + } + if ($event->isControlEnabled('delete') && $calcPerms->editPagePermissionIsGranted()) { + $recordInfo = $this->data['databaseRow']['uid_local'][0]['title'] ?? $this->data['recordTitle'] ?? ''; + if ($this->getBackendUserAuthentication()->shallDisplayDebugInformation()) { + $recordInfo .= ' [' . $this->data['tableName'] . ':' . $this->data['vanillaUid'] . ']'; + } + $controls['delete'] = ' + <button type="button" class="btn btn-default t3js-editform-delete-file-reference" data-record-info="' . htmlspecialchars(trim($recordInfo)) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:delete')) . '"> + ' . $this->iconFactory->getIcon('actions-edit-delete', Icon::SIZE_SMALL)->render() . ' + </button>'; + } + if (($hiddenField = (string)($fileReferenceTableTca['ctrl']['enablecolumns']['disabled'] ?? '')) !== '' + && ($fileReferenceTableTca['columns'][$hiddenField] ?? false) + && $event->isControlEnabled('hide') + && ( + !($fileReferenceTableTca['columns'][$hiddenField]['exclude'] ?? false) + || $backendUser->check('non_exclude_fields', self::FILE_REFERENCE_TABLE . ':' . $hiddenField) + ) + ) { + if ($databaseRow[$hiddenField] ?? false) { + $controls['hide'] = ' + <button type="button" class="btn btn-default t3js-toggle-visibility-button" data-hidden-field="' . htmlspecialchars($hiddenField) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:unHide')) . '"> + ' . $this->iconFactory->getIcon('actions-edit-unhide', Icon::SIZE_SMALL)->render() . ' + </button>'; + } else { + $controls['hide'] = ' + <button type="button" class="btn btn-default t3js-toggle-visibility-button" data-hidden-field="' . htmlspecialchars($hiddenField) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:hide')) . '"> + ' . $this->iconFactory->getIcon('actions-edit-hide', Icon::SIZE_SMALL)->render() . ' + </button>'; + } + } + if (($parentConfig['appearance']['useSortable'] ?? false) && $event->isControlEnabled('dragdrop')) { + $controls['dragdrop'] = ' + <span class="btn btn-default sortableHandle" data-id="' . (int)$databaseRow['uid'] . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.move')) . '"> + ' . $this->iconFactory->getIcon('actions-move-move', Icon::SIZE_SMALL)->render() . ' + </span>'; + } + } elseif (($this->data['isInlineDefaultLanguageRecordInLocalizedParentContext'] ?? false) + && MathUtility::canBeInterpretedAsInteger($this->data['inlineParentUid']) + && $event->isControlEnabled('localize') + ) { + $controls['localize'] = ' + <button type="button" class="btn btn-default t3js-synchronizelocalize-button" data-type="' . htmlspecialchars((string)$databaseRow['uid']) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:localize')) . '"> + ' . $this->iconFactory->getIcon('actions-document-localize', Icon::SIZE_SMALL)->render() . ' + </button>'; + } + if ($lockInfo = BackendUtility::isRecordLocked(self::FILE_REFERENCE_TABLE, $databaseRow['uid'])) { + $controls['locked'] = ' + <button type="button" class="btn btn-default" data-bs-toggle="tooltip" title="' . htmlspecialchars($lockInfo['msg']) . '"> + ' . $this->iconFactory->getIcon('status-user-backend', Icon::SIZE_SMALL, 'overlay-edit')->render() . ' + </button>'; + } + + // Get modified controls. This means their markup was modified, new controls were added or controls got removed. + $controls = $this->eventDispatcher->dispatch( + new ModifyFileReferenceControlsEvent($controls, $this->data, $databaseRow) + )->getControls(); + + $out = ''; + if (($controls['edit'] ?? false) || ($controls['hide'] ?? false) || ($controls['delete'] ?? false)) { + $out .= ' + <div class="btn-group btn-group-sm" role="group"> + ' . ($controls['edit'] ?? '') . ($controls['hide'] ?? '') . ($controls['delete'] ?? '') . ' + </div>'; + unset($controls['edit'], $controls['hide'], $controls['delete']); + } + if (($controls['info'] ?? false) || ($controls['new'] ?? false) || ($controls['sort.up'] ?? false) || ($controls['sort.down'] ?? false) || ($controls['dragdrop'] ?? false)) { + $out .= ' + <div class="btn-group btn-group-sm" role="group"> + ' . ($controls['info'] ?? '') . ($controls['new'] ?? '') . ($controls['sort.up'] ?? '') . ($controls['sort.down'] ?? '') . ($controls['dragdrop'] ?? '') . ' + </div>'; + unset($controls['info'], $controls['new'], $controls['sort.up'], $controls['sort.down'], $controls['dragdrop']); + } + if ($controls['localize'] ?? false) { + $out .= '<div class="btn-group btn-group-sm" role="group">' . $controls['localize'] . '</div>'; + unset($controls['localize']); + } + if ($controls !== [] && ($remainingControls = trim(implode('', $controls))) !== '') { + $out .= '<div class="btn-group btn-group-sm" role="group">' . $remainingControls . '</div>'; + } + return $out; + } + + protected function getRecordTitle(): string + { + $databaseRow = $this->data['databaseRow']; + $fileRecord = $databaseRow['uid_local'][0]['row'] ?? null; + + if ($fileRecord === null) { + return $this->data['recordTitle'] ?: (string)$databaseRow['uid']; + } + + $title = ''; + foreach (self::SYS_FILE_LABEL_FIELDS as $field) { + $value = ''; + if ($field === 'title') { + $fullTitle = ''; + if (isset($databaseRow['title'])) { + $fullTitle = $databaseRow['title']; + } elseif ($fileRecord['uid'] ?? false) { + try { + $metaDataRepository = GeneralUtility::makeInstance(MetaDataRepository::class); + $metaData = $metaDataRepository->findByFileUid($fileRecord['uid']); + $fullTitle = $metaData['title'] ?? ''; + } catch (InvalidUidException $e) { + } + } + $value = BackendUtility::getRecordTitlePrep($fullTitle); + } elseif (isset($databaseRow[$field])) { + $value = htmlspecialchars((string)$databaseRow[$field]); + } elseif (isset($fileRecord[$field])) { + $value = BackendUtility::getRecordTitlePrep($fileRecord[$field]); + } + if ($value === '') { + continue; + } + + $title = ' + <dt class="col text-truncate"> + ' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file.' . $field)) . ' + </dt> + <dd class="col"> + ' . $value . ' + </dd>'; + + // In debug mode, add the table name to the record title + if ($this->getBackendUserAuthentication()->shallDisplayDebugInformation()) { + $title .= '<div class="col"><code class="m-0">[' . self::FILE_REFERENCE_TABLE . ']</code></div>'; + } + } + + return '<dl class="row row-cols-auto g-2">' . $title . '</dl>'; + } + + protected function getBackendUserAuthentication(): BackendUserAuthentication + { + return $GLOBALS['BE_USER']; + } + + protected function getLanguageService(): LanguageService + { + return $GLOBALS['LANG']; + } +} diff --git a/typo3/sysext/backend/Classes/Form/Container/FilesControlContainer.php b/typo3/sysext/backend/Classes/Form/Container/FilesControlContainer.php new file mode 100644 index 0000000000000000000000000000000000000000..dd87ea1feb7d1e4478cf47def13d348fcc08abd8 --- /dev/null +++ b/typo3/sysext/backend/Classes/Form/Container/FilesControlContainer.php @@ -0,0 +1,431 @@ +<?php + +declare(strict_types=1); + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +namespace TYPO3\CMS\Backend\Form\Container; + +use Psr\EventDispatcher\EventDispatcherInterface; +use TYPO3\CMS\Backend\Form\Event\CustomFileControlsEvent; +use TYPO3\CMS\Backend\Form\InlineStackProcessor; +use TYPO3\CMS\Backend\Form\NodeFactory; +use TYPO3\CMS\Backend\Utility\BackendUtility; +use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; +use TYPO3\CMS\Core\Imaging\Icon; +use TYPO3\CMS\Core\Imaging\IconFactory; +use TYPO3\CMS\Core\Localization\LanguageService; +use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction; +use TYPO3\CMS\Core\Resource\Folder; +use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\Utility\MathUtility; +use TYPO3\CMS\Core\Utility\StringUtility; +use TYPO3Fluid\Fluid\View\TemplateView; + +/** + * Files entry container. + * + * This container is the entry step to rendering a file reference. It is created by SingleFieldContainer. + * + * The code creates the main structure for the single file reference, initializes the inlineData array, + * that is manipulated and also returned back in its manipulated state. The "control" stuff of file + * references is rendered here, for example the "create new" button. + * + * For each existing file reference, a FileReferenceContainer is called for further processing. + */ +class FilesControlContainer extends AbstractContainer +{ + public const NODE_TYPE_IDENTIFIER = 'file'; + + private const FILE_REFERENCE_TABLE = 'sys_file_reference'; + + /** + * Inline data array used in JS, returned as JSON object to frontend + */ + protected array $fileReferenceData = []; + + /** + * @var array<int,JavaScriptModuleInstruction|string|array<string,string>> + */ + protected array $requireJsModules = []; + + protected IconFactory $iconFactory; + protected InlineStackProcessor $inlineStackProcessor; + + protected $defaultFieldInformation = [ + 'tcaDescription' => [ + 'renderType' => 'tcaDescription', + ], + ]; + + protected $defaultFieldWizard = [ + 'localizationStateSelector' => [ + 'renderType' => 'localizationStateSelector', + ], + ]; + + /** + * Container objects give $nodeFactory down to other containers. + * + * @param NodeFactory $nodeFactory + * @param array $data + */ + public function __construct(NodeFactory $nodeFactory, array $data) + { + parent::__construct($nodeFactory, $data); + $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class); + } + + /** + * Entry method + * + * @return array As defined in initializeResultArray() of AbstractNode + */ + public function render() + { + $languageService = $this->getLanguageService(); + + $this->fileReferenceData = $this->data['inlineData']; + + $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class); + $this->inlineStackProcessor = $inlineStackProcessor; + $inlineStackProcessor->initializeByGivenStructure($this->data['inlineStructure']); + + $table = $this->data['tableName']; + $row = $this->data['databaseRow']; + $field = $this->data['fieldName']; + $parameterArray = $this->data['parameterArray']; + + $resultArray = $this->initializeResultArray(); + + $config = $parameterArray['fieldConf']['config']; + $isReadOnly = (bool)($config['readOnly'] ?? false); + $language = 0; + if (BackendUtility::isTableLocalizable($table)) { + $languageFieldName = $GLOBALS['TCA'][$table]['ctrl']['languageField'] ?? ''; + $language = isset($row[$languageFieldName][0]) ? (int)$row[$languageFieldName][0] : (int)$row[$languageFieldName]; + } + + // Add the current inline job to the structure stack + $newStructureItem = [ + 'table' => $table, + 'uid' => $row['uid'], + 'field' => $field, + 'config' => $config, + ]; + + // Extract FlexForm parts (if any) from element name, e.g. array('vDEF', 'lDEF', 'FlexField', 'vDEF') + $itemName = (string)$parameterArray['itemFormElName']; + if ($itemName !== '') { + $flexFormParts = $this->extractFlexFormParts($itemName); + if ($flexFormParts !== null) { + $newStructureItem['flexform'] = $flexFormParts; + if ($flexFormParts !== [] + && isset($this->data['processedTca']['columns'][$field]['config']['dataStructureIdentifier']) + ) { + // Transport the flexform DS identifier fields to the FormFilesAjaxController + $config['dataStructureIdentifier'] = $this->data['processedTca']['columns'][$field]['config']['dataStructureIdentifier']; + } + } + } + + $inlineStackProcessor->pushStableStructureItem($newStructureItem); + + // Hand over original returnUrl to FormFilesAjaxController. Needed if opening for instance a + // nested element in a new view to then go back to the original returnUrl and not the url of + // the inline ajax controller + $config['originalReturnUrl'] = $this->data['returnUrl']; + + // e.g. data[<table>][<uid>][<field>] + $formFieldName = $inlineStackProcessor->getCurrentStructureFormPrefix(); + // e.g. data-<pid>-<table1>-<uid1>-<field1>-<table2>-<uid2>-<field2> + $formFieldIdentifier = $inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']); + + $config['inline']['first'] = false; + + $firstChild = reset($this->data['parameterArray']['fieldConf']['children']); + if (isset($firstChild['databaseRow']['uid'])) { + $config['inline']['first'] = $firstChild['databaseRow']['uid']; + } + $config['inline']['last'] = false; + $lastChild = end($this->data['parameterArray']['fieldConf']['children']); + if (isset($lastChild['databaseRow']['uid'])) { + $config['inline']['last'] = $lastChild['databaseRow']['uid']; + } + + $top = $inlineStackProcessor->getStructureLevel(0); + + $this->fileReferenceData['config'][$formFieldIdentifier] = [ + 'table' => self::FILE_REFERENCE_TABLE, + ]; + $configJson = (string)json_encode($config); + $this->fileReferenceData['config'][$formFieldIdentifier . '-' . self::FILE_REFERENCE_TABLE] = [ + 'min' => $config['minitems'], + 'max' => $config['maxitems'], + 'sortable' => $config['appearance']['useSortable'] ?? false, + 'top' => [ + 'table' => $top['table'], + 'uid' => $top['uid'], + ], + 'context' => [ + 'config' => $configJson, + 'hmac' => GeneralUtility::hmac($configJson, 'FilesContext'), + ], + ]; + $this->fileReferenceData['nested'][$formFieldIdentifier] = $this->data['tabAndInlineStack']; + + $resultArray['inlineData'] = $this->fileReferenceData; + + // @todo: It might be a good idea to have something like "isLocalizedRecord" or similar set by a data provider + $uidOfDefaultRecord = $row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] ?? null] ?? 0; + $isLocalizedParent = $language > 0 + && ($uidOfDefaultRecord[0] ?? $uidOfDefaultRecord) > 0 + && MathUtility::canBeInterpretedAsInteger($row['uid']); + $numberOfFullLocalizedChildren = 0; + $numberOfNotYetLocalizedChildren = 0; + foreach ($this->data['parameterArray']['fieldConf']['children'] as $child) { + if (!$child['isInlineDefaultLanguageRecordInLocalizedParentContext']) { + $numberOfFullLocalizedChildren++; + } + if ($isLocalizedParent && $child['isInlineDefaultLanguageRecordInLocalizedParentContext']) { + $numberOfNotYetLocalizedChildren++; + } + } + + if ($isReadOnly || $numberOfFullLocalizedChildren >= ($config['maxitems'] ?? 0)) { + $config['inline']['showNewFileReferenceButton'] = false; + $config['inline']['showCreateNewRelationButton'] = false; + $config['inline']['showOnlineMediaAddButtonStyle'] = false; + } + + $fieldInformationResult = $this->renderFieldInformation(); + $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false); + + $fieldWizardResult = $this->renderFieldWizard(); + $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false); + + $sortableRecordUids = $fileReferencesHtml = []; + foreach ($this->data['parameterArray']['fieldConf']['children'] as $options) { + $options['inlineParentUid'] = $row['uid']; + $options['inlineFirstPid'] = $this->data['inlineFirstPid']; + $options['inlineParentConfig'] = $config; + $options['inlineData'] = $this->fileReferenceData; + $options['inlineStructure'] = $inlineStackProcessor->getStructure(); + $options['inlineExpandCollapseStateArray'] = $this->data['inlineExpandCollapseStateArray']; + $options['renderType'] = FileReferenceContainer::NODE_TYPE_IDENTIFIER; + $fileReference = $this->nodeFactory->create($options)->render(); + $fileReferencesHtml[] = $fileReference['html']; + $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fileReference, false); + if (!$options['isInlineDefaultLanguageRecordInLocalizedParentContext'] && isset($options['databaseRow']['uid'])) { + // Don't add record to list of "valid" uids if it is only the default + // language record of a not yet localized child + $sortableRecordUids[] = $options['databaseRow']['uid']; + } + } + + // @todo: It's unfortunate we're using Typo3Fluid TemplateView directly here. We can't + // inject BackendViewFactory here since __construct() is polluted by NodeInterface. + // Remove __construct() from NodeInterface to have DI, then use BackendViewFactory here. + $view = GeneralUtility::makeInstance(TemplateView::class); + $templatePaths = $view->getRenderingContext()->getTemplatePaths(); + $templatePaths->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]); + $view->assignMultiple([ + 'formFieldIdentifier' => $formFieldIdentifier, + 'formFieldName' => $formFieldName, + 'formGroupAttributes' => GeneralUtility::implodeAttributes([ + 'class' => 'form-group', + 'id' => $formFieldIdentifier, + 'data-uid' => (string)$row['uid'], + 'data-local-table' => (string)$top['table'], + 'data-local-field' => (string)$top['field'], + 'data-foreign-table' => self::FILE_REFERENCE_TABLE, + 'data-object-group' => $formFieldIdentifier . '-' . self::FILE_REFERENCE_TABLE, + 'data-form-field' => $formFieldName, + 'data-appearance' => (string)json_encode($config['appearance'] ?? ''), + ], true), + 'fieldInformation' => $fieldInformationResult['html'], + 'fieldWizard' => $fieldWizardResult['html'], + 'fileReferences' => [ + 'id' => $formFieldIdentifier . '_records', + 'title' => $languageService->sL(trim($parameterArray['fieldConf']['label'] ?? '')), + 'records' => implode(LF, $fileReferencesHtml), + ], + 'sortableRecordUids' => implode(',', $sortableRecordUids), + 'validationRules' => $this->getValidationDataAsJsonString([ + 'type' => 'inline', + 'minitems' => $config['minitems'] ?? null, + 'maxitems' => $config['maxitems'] ?? null, + ]), + ]); + + if (!$isReadOnly && ($config['appearance']['showFileSelectors'] ?? true) !== false) { + $allowedFileTypes = GeneralUtility::trimExplode(',', (string)($config['allowed'] ?? ''), true); + $view->assign('fileSelectors', $this->getFileSelectors($config, $allowedFileTypes)); + $view->assign('allowedFileTypes', $allowedFileTypes); + // Render the localization buttons if needed + if ($numberOfNotYetLocalizedChildren) { + $view->assignMultiple([ + 'showAllLocalizationLink' => !empty($config['appearance']['showAllLocalizationLink']), + 'showSynchronizationLink' => !empty($config['appearance']['showSynchronizationLink']), + ]); + } + } + + $controls = GeneralUtility::makeInstance(EventDispatcherInterface::class)->dispatch( + new CustomFileControlsEvent($resultArray, $table, $field, $row, $config, $formFieldIdentifier, $formFieldName) + )->getControls(); + + if ($controls !== []) { + $view->assign('customControls', [ + 'id' => $formFieldIdentifier . '_customControls', + 'controls' => implode("\n", $controls), + ]); + } + + $resultArray['html'] = $view->render('Form/FilesControlContainer'); + $resultArray['requireJsModules'] = array_merge($resultArray['requireJsModules'], $this->requireJsModules); + $resultArray['requireJsModules'][] = JavaScriptModuleInstruction::create('@typo3/backend/form-engine/container/files-control-container.js'); + + return $resultArray; + } + + /** + * Generate buttons to select, reference and upload files. + */ + protected function getFileSelectors(array $inlineConfiguration, array $allowedFileTypes): array + { + $languageService = $this->getLanguageService(); + $backendUser = $this->getBackendUserAuthentication(); + + $currentStructureDomObjectIdPrefix = $this->inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']); + $objectPrefix = $currentStructureDomObjectIdPrefix . '-' . self::FILE_REFERENCE_TABLE; + + $controls = []; + if ($inlineConfiguration['appearance']['elementBrowserEnabled'] ?? true) { + if ($inlineConfiguration['appearance']['createNewRelationLinkTitle'] ?? false) { + $createNewRelationLinkTitle = $languageService->sL($inlineConfiguration['appearance']['createNewRelationLinkTitle']); + } else { + $createNewRelationLinkTitle = $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.createNewRelation'); + } + $attributes = [ + 'type' => 'button', + 'class' => 'btn btn-default t3js-element-browser', + 'style' => !($inlineConfiguration['inline']['showCreateNewRelationButton'] ?? true) ? 'display: none;' : '', + 'title' => $createNewRelationLinkTitle, + 'data-mode' => 'file', + 'data-params' => '|||' . implode(',', $allowedFileTypes) . '|' . $objectPrefix, + ]; + $controls[] = ' + <button ' . GeneralUtility::implodeAttributes($attributes, true) . '> + ' . $this->iconFactory->getIcon('actions-insert-record', Icon::SIZE_SMALL)->render() . ' + ' . htmlspecialchars($createNewRelationLinkTitle) . ' + </button>'; + } + + $onlineMediaAllowed = GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class)->getSupportedFileExtensions(); + if ($allowedFileTypes !== []) { + $onlineMediaAllowed = array_intersect($allowedFileTypes, $onlineMediaAllowed); + } + + $showUpload = (bool)($inlineConfiguration['appearance']['fileUploadAllowed'] ?? true); + $showByUrl = ($inlineConfiguration['appearance']['fileByUrlAllowed'] ?? true) && $onlineMediaAllowed !== []; + + if (($showUpload || $showByUrl) && ($backendUser->uc['edit_docModuleUpload'] ?? false)) { + $folder = $backendUser->getDefaultUploadFolder( + $this->data['tableName'] === 'pages' ? $this->data['vanillaUid'] : ($this->data['parentPageRow']['uid'] ?? 0), + $this->data['tableName'], + $this->data['fieldName'] + ); + if ( + $folder instanceof Folder + && $folder->getStorage()->checkUserActionPermission('add', 'File') + ) { + if ($showUpload) { + $attributes = [ + 'type' => 'button', + 'class' => 'btn btn-default t3js-drag-uploader', + 'style' => !($inlineConfiguration['inline']['showCreateNewRelationButton'] ?? true) ? 'display: none;' : '', + 'data-dropzone-target' => '#' . StringUtility::escapeCssSelector($currentStructureDomObjectIdPrefix), + 'data-insert-dropzone-before' => '1', + 'data-file-irre-object' => $objectPrefix, + 'data-file-allowed' => implode(',', $allowedFileTypes), + 'data-target-folder' => $folder->getCombinedIdentifier(), + 'data-max-file-size' => (string)(GeneralUtility::getMaxUploadFileSize() * 1024), + ]; + $controls[] = ' + <button ' . GeneralUtility::implodeAttributes($attributes, true) . '> + ' . $this->iconFactory->getIcon('actions-upload', Icon::SIZE_SMALL)->render() . ' + ' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_upload.select-and-submit')) . ' + </button>'; + + $this->requireJsModules[] = JavaScriptModuleInstruction::create('@typo3/backend/drag-uploader.js'); + } + if ($showByUrl) { + $buttonText = $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.button'); + $attributes = [ + 'type' => 'button', + 'class' => 'btn btn-default t3js-online-media-add-btn', + 'title' => $buttonText, + 'style' => !($inlineConfiguration['inline']['showOnlineMediaAddButtonStyle'] ?? true) ? 'display: none;' : '', + 'data-target-folder' => $folder->getCombinedIdentifier(), + 'data-file-irre-object' => $objectPrefix, + 'data-online-media-allowed' => implode(',', $onlineMediaAllowed), + 'data-btn-submit' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.placeholder'), + 'data-placeholder' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.placeholder'), + 'data-online-media-allowed-help-text' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.allowEmbedSources'), + ]; + + // @todo Should be implemented as web component + $controls[] = ' + <button ' . GeneralUtility::implodeAttributes($attributes, true) . '> + ' . $this->iconFactory->getIcon('actions-online-media-add', Icon::SIZE_SMALL)->render() . ' + ' . htmlspecialchars($buttonText) . ' + </button>'; + + $this->requireJsModules[] = JavaScriptModuleInstruction::create('@typo3/backend/online-media.js'); + } + } + } + + return $controls; + } + + /** + * Extracts FlexForm parts of a form element name like + * data[table][uid][field][sDEF][lDEF][FlexForm][vDEF] + */ + protected function extractFlexFormParts(string $formElementName): ?array + { + $flexFormParts = null; + $matches = []; + if (preg_match('#^data(?:\[[^]]+\]){3}(\[data\](?:\[[^]]+\]){4,})$#', $formElementName, $matches)) { + $flexFormParts = GeneralUtility::trimExplode( + '][', + trim($matches[1], '[]') + ); + } + return $flexFormParts; + } + + protected function getBackendUserAuthentication(): BackendUserAuthentication + { + return $GLOBALS['BE_USER']; + } + + protected function getLanguageService(): LanguageService + { + return $GLOBALS['LANG']; + } +} diff --git a/typo3/sysext/backend/Classes/Form/Container/InlineControlContainer.php b/typo3/sysext/backend/Classes/Form/Container/InlineControlContainer.php index 0b240fb5154de7ba6f4a3f9dcaba76c317e133d8..7c104fc40a8aee574be8338f36ef16bca69a63ca 100644 --- a/typo3/sysext/backend/Classes/Form/Container/InlineControlContainer.php +++ b/typo3/sysext/backend/Classes/Form/Container/InlineControlContainer.php @@ -23,11 +23,8 @@ use TYPO3\CMS\Core\Imaging\Icon; use TYPO3\CMS\Core\Imaging\IconFactory; use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction; -use TYPO3\CMS\Core\Resource\Folder; -use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\MathUtility; -use TYPO3\CMS\Core\Utility\StringUtility; /** * Inline element entry container. @@ -122,9 +119,9 @@ class InlineControlContainer extends AbstractContainer $foreign_table = $config['foreign_table']; $isReadOnly = isset($config['readOnly']) && $config['readOnly']; $language = 0; - $languageFieldName = $GLOBALS['TCA'][$table]['ctrl']['languageField'] ?? ''; if (BackendUtility::isTableLocalizable($table)) { - $language = isset($row[$languageFieldName][0]) ? (int)$row[$languageFieldName][0] : (int)$row[$languageFieldName]; + $languageFieldName = $GLOBALS['TCA'][$table]['ctrl']['languageField'] ?? ''; + $language = isset($row[$languageFieldName][0]) ? (int)$row[$languageFieldName][0] : (int)($row[$languageFieldName] ?? 0); } // Add the current inline job to the structure stack @@ -279,8 +276,6 @@ class InlineControlContainer extends AbstractContainer // Define how to show the "Create new record" button - if there are more than maxitems, hide it if ($isReadOnly || $numberOfFullLocalizedChildren >= ($config['maxitems'] ?? 0) || ($uniqueMax > 0 && $numberOfFullLocalizedChildren >= $uniqueMax)) { $config['inline']['inlineNewButtonStyle'] = 'display: none;'; - $config['inline']['inlineNewRelationButtonStyle'] = 'display: none;'; - $config['inline']['inlineOnlineMediaAddButtonStyle'] = 'display: none;'; } // Render the "new record" level button: @@ -475,136 +470,47 @@ class InlineControlContainer extends AbstractContainer * @param array $inlineConfiguration TCA inline configuration of the parent(!) field * @return string A HTML button that opens an element browser in a new window */ - protected function renderPossibleRecordsSelectorTypeGroupDB(array $inlineConfiguration) + protected function renderPossibleRecordsSelectorTypeGroupDB(array $inlineConfiguration): string { - $backendUser = $this->getBackendUserAuthentication(); $languageService = $this->getLanguageService(); - $groupFieldConfiguration = $inlineConfiguration['selectorOrUniqueConfiguration']['config']; - - $foreign_table = $inlineConfiguration['foreign_table']; - $allowed = $groupFieldConfiguration['allowed']; - $currentStructureDomObjectIdPrefix = $this->inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']); - $objectPrefix = $currentStructureDomObjectIdPrefix . '-' . $foreign_table; - $mode = 'db'; - $showUpload = false; - $showByUrl = false; + $objectPrefix = $this->inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']) . '-' . $inlineConfiguration['foreign_table']; $elementBrowserEnabled = true; - if (!empty($inlineConfiguration['appearance']['createNewRelationLinkTitle'])) { - $createNewRelationText = htmlspecialchars($languageService->sL($inlineConfiguration['appearance']['createNewRelationLinkTitle'])); - } else { - $createNewRelationText = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.createNewRelation')); - } - if (is_array($groupFieldConfiguration['appearance'] ?? null)) { - if (isset($groupFieldConfiguration['appearance']['elementBrowserType'])) { - $mode = $groupFieldConfiguration['appearance']['elementBrowserType']; - } - if ($mode === 'file') { - $showUpload = true; - $showByUrl = true; - } - if (isset($inlineConfiguration['appearance']['fileUploadAllowed'])) { - $showUpload = (bool)$inlineConfiguration['appearance']['fileUploadAllowed']; - } - if (isset($inlineConfiguration['appearance']['fileByUrlAllowed'])) { - $showByUrl = (bool)$inlineConfiguration['appearance']['fileByUrlAllowed']; - } - if (isset($groupFieldConfiguration['appearance']['elementBrowserAllowed'])) { - $allowed = $groupFieldConfiguration['appearance']['elementBrowserAllowed']; - } - if (isset($inlineConfiguration['appearance']['elementBrowserEnabled'])) { - $elementBrowserEnabled = (bool)$inlineConfiguration['appearance']['elementBrowserEnabled']; - } + if (is_array($groupFieldConfiguration['appearance'] ?? null) + && isset($inlineConfiguration['appearance']['elementBrowserEnabled']) + ) { + $elementBrowserEnabled = (bool)$inlineConfiguration['appearance']['elementBrowserEnabled']; } // Remove any white-spaces from the allowed extension lists - $allowed = implode(',', GeneralUtility::trimExplode(',', $allowed, true)); - $browserParams = '|||' . $allowed . '|' . $objectPrefix; + $allowed = GeneralUtility::trimExplode(',', (string)($groupFieldConfiguration['allowed'] ?? ''), true); $buttonStyle = ''; if (isset($inlineConfiguration['inline']['inlineNewRelationButtonStyle'])) { $buttonStyle = ' style="' . $inlineConfiguration['inline']['inlineNewRelationButtonStyle'] . '"'; } $item = ''; if ($elementBrowserEnabled) { - $item .= ' - <button type="button" class="btn btn-default t3js-element-browser" data-mode="' . htmlspecialchars($mode) . '" data-params="' . htmlspecialchars($browserParams) . '" - ' . $buttonStyle . ' title="' . $createNewRelationText . '"> - ' . $this->iconFactory->getIcon('actions-insert-record', Icon::SIZE_SMALL)->render() . ' - ' . $createNewRelationText . ' - </button>'; - } - - $isDirectFileUploadEnabled = (bool)$backendUser->uc['edit_docModuleUpload']; - $allowedArray = GeneralUtility::trimExplode(',', $allowed, true); - $onlineMediaAllowed = GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class)->getSupportedFileExtensions(); - if (!empty($allowedArray)) { - $onlineMediaAllowed = array_intersect($allowedArray, $onlineMediaAllowed); - } - if (($showUpload || $showByUrl) && $isDirectFileUploadEnabled) { - $folder = $backendUser->getDefaultUploadFolder( - $this->data['tableName'] === 'pages' ? $this->data['vanillaUid'] : ($this->data['parentPageRow']['uid'] ?? 0), - $this->data['tableName'], - $this->data['fieldName'] - ); - if ( - $folder instanceof Folder - && $folder->getStorage()->checkUserActionPermission('add', 'File') - ) { - if ($showUpload) { - $maxFileSize = GeneralUtility::getMaxUploadFileSize() * 1024; - $item .= ' <button type="button" class="btn btn-default t3js-drag-uploader inlineNewFileUploadButton" - ' . $buttonStyle . ' - data-dropzone-target="#' . htmlspecialchars(StringUtility::escapeCssSelector($currentStructureDomObjectIdPrefix)) . '" - data-insert-dropzone-before="1" - data-file-irre-object="' . htmlspecialchars($objectPrefix) . '" - data-file-allowed="' . htmlspecialchars($allowed) . '" - data-target-folder="' . htmlspecialchars($folder->getCombinedIdentifier()) . '" - data-max-file-size="' . htmlspecialchars((string)$maxFileSize) . '" - >'; - $item .= $this->iconFactory->getIcon('actions-upload', Icon::SIZE_SMALL)->render() . ' '; - $item .= htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_upload.select-and-submit')); - $item .= '</button>'; - - $this->requireJsModules[] = JavaScriptModuleInstruction::create('@typo3/backend/drag-uploader.js'); - } - if (!empty($onlineMediaAllowed) && $showByUrl) { - $buttonStyle = ''; - if (isset($inlineConfiguration['inline']['inlineOnlineMediaAddButtonStyle'])) { - $buttonStyle = ' style="' . $inlineConfiguration['inline']['inlineOnlineMediaAddButtonStyle'] . '"'; - } - $this->requireJsModules[] = JavaScriptModuleInstruction::create('@typo3/backend/online-media.js'); - $buttonText = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.button')); - $placeholder = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.placeholder')); - $buttonSubmit = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.submit')); - $allowedMediaUrl = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.allowEmbedSources')); - $item .= ' - <button type="button" class="btn btn-default t3js-online-media-add-btn" - ' . $buttonStyle . ' - data-file-irre-object="' . htmlspecialchars($objectPrefix) . '" - data-online-media-allowed="' . htmlspecialchars(implode(',', $onlineMediaAllowed)) . '" - data-online-media-allowed-help-text="' . $allowedMediaUrl . '" - data-target-folder="' . htmlspecialchars($folder->getCombinedIdentifier()) . '" - title="' . $buttonText . '" - data-btn-submit="' . $buttonSubmit . '" - data-placeholder="' . $placeholder . '" - > - ' . $this->iconFactory->getIcon('actions-online-media-add', Icon::SIZE_SMALL)->render() . ' - ' . $buttonText . '</button>'; - } + if (!empty($inlineConfiguration['appearance']['createNewRelationLinkTitle'])) { + $createNewRelationText = htmlspecialchars($languageService->sL($inlineConfiguration['appearance']['createNewRelationLinkTitle'])); + } else { + $createNewRelationText = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.createNewRelation')); } + $item .= ' + <button type="button" class="btn btn-default t3js-element-browser" data-mode="db" data-params="' . htmlspecialchars('|||' . implode(',', $allowed) . '|' . $objectPrefix) . '" + ' . $buttonStyle . ' title="' . $createNewRelationText . '"> + ' . $this->iconFactory->getIcon('actions-insert-record', Icon::SIZE_SMALL)->render() . ' + ' . $createNewRelationText . ' + </button>'; } - $item = '<div class="form-control-wrap t3js-inline-controls">' . $item . '</div>'; - $allowedList = ''; - $allowedLabelKey = ($mode === 'file') ? 'allowedFileExtensions' : 'allowedRelations'; - $allowedLabel = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.' . $allowedLabelKey)); - foreach ($allowedArray as $allowedItem) { - $allowedList .= '<span class="badge badge-success">' . strtoupper($allowedItem) . '</span> '; - } - if (!empty($allowedList)) { - $item .= '<div class="help-block">' . $allowedLabel . '<br>' . $allowedList . '</div>'; + if (!empty($allowed)) { + $item .= ' + <div class="help-block"> + ' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.allowedRelations')) . ' + <br> + ' . implode(' ', array_map(static fn ($item) => '<span class="badge badge-success">' . strtoupper($item) . '</span>', $allowed)) . ' + </div>'; } - $item = '<div class="form-group t3js-formengine-validation-marker t3js-inline-controls-top-outer-container">' . $item . '</div>'; - return $item; + return '<div class="form-group t3js-formengine-validation-marker t3js-inline-controls-top-outer-container">' . $item . '</div>'; } /** diff --git a/typo3/sysext/backend/Classes/Form/Container/InlineRecordContainer.php b/typo3/sysext/backend/Classes/Form/Container/InlineRecordContainer.php index 3d272bf0aedc436ba57337304bf0c04ef0f61d42..36558bef81ac143643cdc00650201fc31ad14107 100644 --- a/typo3/sysext/backend/Classes/Form/Container/InlineRecordContainer.php +++ b/typo3/sysext/backend/Classes/Form/Container/InlineRecordContainer.php @@ -21,16 +21,11 @@ use TYPO3\CMS\Backend\Form\Event\ModifyInlineElementEnabledControlsEvent; use TYPO3\CMS\Backend\Form\Exception\AccessDeniedContentEditException; use TYPO3\CMS\Backend\Form\InlineStackProcessor; use TYPO3\CMS\Backend\Form\NodeFactory; -use TYPO3\CMS\Backend\Routing\UriBuilder; use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; -use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Imaging\Icon; use TYPO3\CMS\Core\Imaging\IconFactory; -use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection; use TYPO3\CMS\Core\Localization\LanguageService; -use TYPO3\CMS\Core\Resource\ProcessedFile; -use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Type\Bitmask\Permission; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\MathUtility; @@ -324,24 +319,20 @@ class InlineRecordContainer extends AbstractContainer * @param string $ariaAttributesString HTML aria attributes for the collapse button * @return string The HTML code of the header */ - protected function renderForeignRecordHeader(array $data, string $ariaAttributesString) + protected function renderForeignRecordHeader(array $data, string $ariaAttributesString): string { - $languageService = $this->getLanguageService(); - $inlineConfig = $data['inlineParentConfig']; - $foreignTable = $inlineConfig['foreign_table']; - $rec = $data['databaseRow']; - // Init: + $record = $data['databaseRow']; + $recordTitle = $data['recordTitle']; + $foreignTable = $data['inlineParentConfig']['foreign_table']; $domObjectId = $this->inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($data['inlineFirstPid']); - $objectId = $domObjectId . '-' . $foreignTable . '-' . ($rec['uid'] ?? 0); - $recordTitle = $data['recordTitle']; if (!empty($recordTitle)) { // The user function may return HTML, therefore we can't escape it if (empty($data['processedTca']['ctrl']['formattedLabel_userFunc'])) { $recordTitle = BackendUtility::getRecordTitlePrep($recordTitle); } } else { - $recordTitle = '<em>[' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.no_title')) . ']</em>'; + $recordTitle = '<em>[' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.no_title')) . ']</em>'; } // In case the record title is not generated by a formattedLabel_userFunc, which already @@ -352,67 +343,19 @@ class InlineRecordContainer extends AbstractContainer $recordTitle .= ' <code class="m-0">[' . htmlspecialchars($foreignTable) . ']</code>'; } - $altText = BackendUtility::getRecordIconAltText($rec, $foreignTable); - - $iconImg = '<span title="' . $altText . '" id="' . htmlspecialchars($objectId) . '_icon">' . $this->iconFactory->getIconForRecord($foreignTable, $rec, Icon::SIZE_SMALL)->render() . '</span>'; - $label = '<span id="' . $objectId . '_label">' . $recordTitle . '</span>'; - $ctrl = $this->renderForeignRecordHeaderControl($data); - $thumbnail = false; - - // Renders a thumbnail for the header - if (($GLOBALS['TYPO3_CONF_VARS']['GFX']['thumbnails'] ?? false) && !empty($inlineConfig['appearance']['headerThumbnail']['field'])) { - $fieldValue = $rec[$inlineConfig['appearance']['headerThumbnail']['field']]; - $fileUid = $fieldValue[0]['uid'] ?? null; - - if (!empty($fileUid)) { - try { - $fileObject = GeneralUtility::makeInstance(ResourceFactory::class)->getFileObject($fileUid); - } catch (\InvalidArgumentException $e) { - $fileObject = null; - } - if ($fileObject && $fileObject->isMissing()) { - $thumbnail .= '<span class="badge badge-danger">' - . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:warning.file_missing')) - . '</span> ' . htmlspecialchars($fileObject->getName()) . '<br />'; - } elseif ($fileObject) { - $imageSetup = $inlineConfig['appearance']['headerThumbnail'] ?? []; - unset($imageSetup['field']); - $cropVariantCollection = CropVariantCollection::create($rec['crop'] ?? ''); - if (!$cropVariantCollection->getCropArea()->isEmpty()) { - $imageSetup['crop'] = $cropVariantCollection->getCropArea()->makeAbsoluteBasedOnFile($fileObject); - } - $imageSetup = array_merge(['maxWidth' => '145', 'maxHeight' => '45'], $imageSetup); - - if (($GLOBALS['TYPO3_CONF_VARS']['GFX']['thumbnails'] ?? false) && $fileObject->isImage()) { - $processedImage = $fileObject->process(ProcessedFile::CONTEXT_IMAGECROPSCALEMASK, $imageSetup); - // Only use a thumbnail if the processing process was successful by checking if image width is set - if ($processedImage->getProperty('width')) { - $imageUrl = $processedImage->getPublicUrl() ?? ''; - $thumbnail = '<img src="' . htmlspecialchars($imageUrl) . '" ' . - 'width="' . $processedImage->getProperty('width') . '" ' . - 'height="' . $processedImage->getProperty('height') . '" ' . - 'alt="' . htmlspecialchars($altText) . '" ' . - 'title="' . htmlspecialchars($altText) . '">'; - } - } else { - $thumbnail = ''; - } - } - } - } - - if (!empty($inlineConfig['appearance']['headerThumbnail']['field']) && $thumbnail) { - $mediaContainer = '<div class="form-irre-header-thumbnail" id="' . $objectId . '_thumbnailcontainer">' . $thumbnail . '</div>'; - } else { - $mediaContainer = '<div class="form-irre-header-icon" id="' . $objectId . '_iconcontainer">' . $iconImg . '</div>'; - } - $header = '<button class="form-irre-header-cell form-irre-header-button" ' . $ariaAttributesString . '>' . - $mediaContainer . - '<div class="form-irre-header-body">' . $label . '</div>' . - '</button>' . - '<div class="form-irre-header-cell form-irre-header-control t3js-formengine-irre-control">' . $ctrl . '</div>'; - - return $header; + $objectId = htmlspecialchars($domObjectId . '-' . $foreignTable . '-' . ($record['uid'] ?? 0)); + return ' + <button class="form-irre-header-cell form-irre-header-button" ' . $ariaAttributesString . '> + <div class="form-irre-header-icon" id="' . $objectId . '_iconcontainer"> + <span title="' . BackendUtility::getRecordIconAltText($record, $foreignTable) . '" id="' . $objectId . '_icon"> + ' . $this->iconFactory->getIconForRecord($foreignTable, $record, Icon::SIZE_SMALL)->render() . ' + </span> + </div> + <div class="form-irre-header-body"><span id="' . $objectId . '_label">' . $recordTitle . '</span></div> + </button> + <div class="form-irre-header-cell form-irre-header-control t3js-formengine-irre-control"> + ' . $this->renderForeignRecordHeaderControl($data) . ' + </div>'; } /** @@ -428,7 +371,6 @@ class InlineRecordContainer extends AbstractContainer $rec = $data['databaseRow']; $rec += [ 'uid' => 0, - 'table_local' => '', ]; $inlineConfig = $data['inlineParentConfig']; $foreignTable = $inlineConfig['foreign_table']; @@ -436,7 +378,6 @@ class InlineRecordContainer extends AbstractContainer $backendUser = $this->getBackendUserAuthentication(); // Initialize: $cells = [ - 'edit' => '', 'hide' => '', 'delete' => '', 'info' => '', @@ -453,7 +394,6 @@ class InlineRecordContainer extends AbstractContainer $tcaTableCtrl = $GLOBALS['TCA'][$foreignTable]['ctrl']; $tcaTableCols = $GLOBALS['TCA'][$foreignTable]['columns']; $isPagesTable = $foreignTable === 'pages'; - $isSysFileReferenceTable = $foreignTable === 'sys_file_reference'; $enableManualSorting = ($tcaTableCtrl['sortby'] ?? false) || ($inlineConfig['MM'] ?? false) || (!($data['isOnSymmetricSide'] ?? false) && ($inlineConfig['foreign_sortby'] ?? false)) @@ -474,20 +414,12 @@ class InlineRecordContainer extends AbstractContainer </span>'; } // "Info": (All records) - // @todo: hardcoded sys_file! - if ($rec['table_local'] === 'sys_file') { - $uid = $rec['uid_local'][0]['uid']; - $table = '_FILE'; - } else { - $uid = $rec['uid']; - $table = $foreignTable; - } if ($event->isControlEnabled('info')) { if ($isNewItem) { $cells['info'] = '<span class="btn btn-default disabled">' . $this->iconFactory->getIcon('empty-empty', Icon::SIZE_SMALL)->render() . '</span>'; } else { $cells['info'] = ' - <button type="button" class="btn btn-default" data-action="infowindow" data-info-table="' . htmlspecialchars($table) . '" data-info-uid="' . htmlspecialchars($uid) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:showInfo')) . '"> + <button type="button" class="btn btn-default" data-action="infowindow" data-info-table="' . htmlspecialchars($foreignTable) . '" data-info-uid="' . htmlspecialchars($rec['uid']) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:showInfo')) . '"> ' . $this->iconFactory->getIcon('actions-document-info', Icon::SIZE_SMALL)->render() . ' </button>'; } @@ -533,50 +465,12 @@ class InlineRecordContainer extends AbstractContainer ' . $this->iconFactory->getIcon($icon, Icon::SIZE_SMALL)->render() . ' </button>'; } - // "Edit" link: - if (($rec['table_local'] === 'sys_file') - && !$isNewItem - && ($languageField = ($GLOBALS['TCA']['sys_file_metadata']['ctrl']['languageField'] ?? false)) - && $backendUser->check('tables_modify', 'sys_file_metadata') - ) { - $languageId = (int)(is_array($rec[$languageField] ?? null) - ? ($rec[$languageField][0] ?? 0) - : ($rec[$languageField] ?? 0)); - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) - ->getQueryBuilderForTable('sys_file_metadata'); - $recordInDatabase = $queryBuilder - ->select('uid') - ->from('sys_file_metadata') - ->where( - $queryBuilder->expr()->eq( - 'file', - $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT) - ), - $queryBuilder->expr()->eq( - $languageField, - $queryBuilder->createNamedParameter($languageId, \PDO::PARAM_INT) - ) - ) - ->setMaxResults(1) - ->executeQuery() - ->fetchAssociative(); - if (!empty($recordInDatabase)) { - $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); - $url = (string)$uriBuilder->buildUriFromRoute('record_edit', [ - 'edit[sys_file_metadata][' . (int)$recordInDatabase['uid'] . ']' => 'edit', - 'returnUrl' => $this->data['returnUrl'], - ]); - $title = $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.editMetadata'); - $cells['edit'] = ' - <a class="btn btn-default" href="' . htmlspecialchars($url) . '" title="' . htmlspecialchars($title) . '"> - ' . $this->iconFactory->getIcon('actions-open', Icon::SIZE_SMALL)->render() . ' - </a>'; - } - } // "Delete" link: - if ($event->isControlEnabled('delete') && (($isPagesTable && $localCalcPerms->deletePagePermissionIsGranted()) + if ($event->isControlEnabled('delete') + && ( + ($isPagesTable && $localCalcPerms->deletePagePermissionIsGranted()) || (!$isPagesTable && $calcPerms->editContentPermissionIsGranted()) - || ($isSysFileReferenceTable && $calcPerms->editPagePermissionIsGranted())) + ) ) { $title = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:delete')); $icon = $this->iconFactory->getIcon('actions-edit-delete', Icon::SIZE_SMALL)->render(); @@ -641,9 +535,9 @@ class InlineRecordContainer extends AbstractContainer $cells = $this->eventDispatcher->dispatch(new ModifyInlineElementControlsEvent($cells, $data, $rec))->getControls(); $out = ''; - if (!empty($cells['edit']) || !empty($cells['hide']) || !empty($cells['delete'])) { - $out .= '<div class="btn-group btn-group-sm" role="group">' . $cells['edit'] . $cells['hide'] . $cells['delete'] . '</div>'; - unset($cells['edit'], $cells['hide'], $cells['delete']); + if (!empty($cells['hide']) || !empty($cells['delete'])) { + $out .= '<div class="btn-group btn-group-sm" role="group">' . $cells['hide'] . $cells['delete'] . '</div>'; + unset($cells['hide'], $cells['delete']); } if (!empty($cells['info']) || !empty($cells['new']) || !empty($cells['sort.up']) || !empty($cells['sort.down']) || !empty($cells['dragdrop'])) { $out .= '<div class="btn-group btn-group-sm" role="group">' . $cells['info'] . $cells['new'] . $cells['sort.up'] . $cells['sort.down'] . $cells['dragdrop'] . '</div>'; @@ -655,7 +549,7 @@ class InlineRecordContainer extends AbstractContainer } if (!empty($cells)) { $cellContent = trim(implode('', $cells)); - $out .= $cellContent != '' ? ' <div class="btn-group btn-group-sm" role="group">' . $cellContent . '</div>': ''; + $out .= $cellContent !== '' ? ' <div class="btn-group btn-group-sm" role="group">' . $cellContent . '</div>': ''; } return $out; } diff --git a/typo3/sysext/backend/Classes/Form/Event/CustomFileControlsEvent.php b/typo3/sysext/backend/Classes/Form/Event/CustomFileControlsEvent.php new file mode 100644 index 0000000000000000000000000000000000000000..bec56fb4847f83b363ce27b2690aec1a88ea90ff --- /dev/null +++ b/typo3/sysext/backend/Classes/Form/Event/CustomFileControlsEvent.php @@ -0,0 +1,109 @@ +<?php + +declare(strict_types=1); + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +namespace TYPO3\CMS\Backend\Form\Event; + +/** + * Listeners to this Event will be able to add custom controls to a TCA type="file" field in FormEngine + */ +final class CustomFileControlsEvent +{ + private array $controls = []; + + public function __construct( + private array $resultArray, + private readonly string $tableName, + private readonly string $fieldName, + private readonly array $databaseRow, + private readonly array $fieldConfig, + private readonly string $formFieldIdentifier, + private readonly string $formFieldName, + ) { + } + + public function getResultArray(): array + { + return $this->resultArray; + } + + /** + * WARNING: Modifying the result array should be used with care. It mostly + * only exists to allow additional $resultArray['requireJsModules']. + */ + public function setResultArray(array $resultArray): void + { + $this->resultArray = $resultArray; + } + + public function getControls(): array + { + return $this->controls; + } + + public function setControls(array $controls): void + { + $this->controls = $controls; + } + + public function addControl(string $control, string $identifier = ''): void + { + if ($identifier !== '') { + $this->controls[$identifier] = $control; + } else { + $this->controls[] = $control; + } + } + + public function removeControl(string $identifier): bool + { + if (!isset($this->controls[$identifier])) { + return false; + } + unset($this->controls[$identifier]); + return true; + } + + public function getTableName(): string + { + return $this->tableName; + } + + public function getFieldName(): string + { + return $this->fieldName; + } + + public function getDatabaseRow(): array + { + return $this->databaseRow; + } + + public function getFieldConfig(): array + { + return $this->fieldConfig; + } + + public function getFormFieldIdentifier(): string + { + return $this->formFieldIdentifier; + } + + public function getFormFieldName(): string + { + return $this->formFieldName; + } +} diff --git a/typo3/sysext/backend/Classes/Form/Event/ModifyFileReferenceControlsEvent.php b/typo3/sysext/backend/Classes/Form/Event/ModifyFileReferenceControlsEvent.php new file mode 100644 index 0000000000000000000000000000000000000000..ca0832f6f62463829e57f4e9dcfc49b4169a613e --- /dev/null +++ b/typo3/sysext/backend/Classes/Form/Event/ModifyFileReferenceControlsEvent.php @@ -0,0 +1,136 @@ +<?php + +declare(strict_types=1); + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +namespace TYPO3\CMS\Backend\Form\Event; + +/** + * Listeners to this Event will be able to modify the controls + * of a single file reference of a TCA type=file field. + */ +final class ModifyFileReferenceControlsEvent +{ + public function __construct( + private array $controls, + private readonly array $data, + private readonly array $record, + ) { + } + + /** + * Returns all controls with their markup + */ + public function getControls(): array + { + return $this->controls; + } + + /** + * Overwrite the controls + */ + public function setControls(array $controls): void + { + $this->controls = $controls; + } + + /** + * Returns the markup for the requested control + */ + public function getControl(string $identifier): string + { + return $this->controls[$identifier] ?? ''; + } + + /** + * Set a control with the given identifier and markup + * IMPORTANT: Overwrites an existing control with the same identifier + */ + public function setControl(string $identifier, string $markup): void + { + $this->controls[$identifier] = $markup; + } + + /** + * Returns whether a control exists for the given identifier + */ + public function hasControl(string $identifier): bool + { + return isset($this->controls[$identifier]); + } + + /** + * Removes a control from the file reference, if it exists + * + * @return bool Whether the control could be removed + */ + public function removeControl(string $identifier): bool + { + if (!$this->hasControl($identifier)) { + return false; + } + + unset($this->controls[$identifier]); + return true; + } + + /** + * Returns the whole element data + */ + public function getElementData(): array + { + return $this->data; + } + + /** + * Returns the current record, the controls are created for + */ + public function getRecord(): array + { + return $this->record; + } + + /** + * Returns the uid of the parent (embedding) record (uid or NEW...) + */ + public function getParentUid(): string + { + return (string)($this->data['inlineParentUid'] ?? ''); + } + + /** + * Returns the table (foreign_table) the controls are created for + */ + public function getForeignTable(): string + { + return (string)($this->getFieldConfiguration()['foreign_table'] ?? 'sys_file_reference'); + } + + /** + * Returns the TCA configuration of the TCA type=file field + */ + public function getFieldConfiguration(): array + { + return (array)($this->data['inlineParentConfig'] ?? []); + } + + /** + * Returns whether the current records is only virtually shown and not physically part of the parent record + */ + public function isVirtual(): bool + { + return (bool)($this->data['isInlineDefaultLanguageRecordInLocalizedParentContext'] ?? false); + } +} diff --git a/typo3/sysext/backend/Classes/Form/Event/ModifyFileReferenceEnabledControlsEvent.php b/typo3/sysext/backend/Classes/Form/Event/ModifyFileReferenceEnabledControlsEvent.php new file mode 100644 index 0000000000000000000000000000000000000000..25ccbbe320d796da519bf2035f26c2dea250259d --- /dev/null +++ b/typo3/sysext/backend/Classes/Form/Event/ModifyFileReferenceEnabledControlsEvent.php @@ -0,0 +1,147 @@ +<?php + +declare(strict_types=1); + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +namespace TYPO3\CMS\Backend\Form\Event; + +/** + * Listeners to this Event will be able to modify the state (enabled or disabled) for controls of a file reference + */ +final class ModifyFileReferenceEnabledControlsEvent +{ + /** + * @var array<string, bool> + */ + private array $controlsState; + + public function __construct( + private readonly array $data, + private readonly array $record, + ) { + $this->controlsState = (array)($data['inlineParentConfig']['appearance']['enabledControls'] ?? []); + } + + /** + * Enable a control, if it exists + * + * @return bool Whether the control could be enabled + */ + public function enableControl(string $identifier): bool + { + if (!$this->hasControl($identifier)) { + return false; + } + + $this->controlsState[$identifier] = true; + return true; + } + + /** + * Disable a control, if it exists + * + * @return bool Whether the control could be disabled + */ + public function disableControl(string $identifier): bool + { + if (!$this->hasControl($identifier)) { + return false; + } + + $this->controlsState[$identifier] = false; + return true; + } + + /** + * Returns whether a control exists for the given identifier + */ + public function hasControl(string $identifier): bool + { + return isset($this->controlsState[$identifier]); + } + + /** + * Returns whether the control is enabled. + * Note: Will also return FALSE in case no control exists for the requested identifier + */ + public function isControlEnabled(string $identifier): bool + { + return (bool)($this->controlsState[$identifier] ?? false); + } + + /** + * Returns all controls with their state (enabled or disabled) + */ + public function getControlsState(): array + { + return $this->controlsState; + } + + /** + * Returns all enabled controls + */ + public function getEnabledControls(): array + { + return array_filter($this->controlsState, static fn ($control) => (bool)$control === true); + } + + /** + * Returns the whole element data + */ + public function getElementData(): array + { + return $this->data; + } + + /** + * Returns the current record of the controls are created for + */ + public function getRecord(): array + { + return $this->record; + } + + /** + * Returns the uid of the parent (embedding) record (uid or NEW...) + */ + public function getParentUid(): string + { + return (string)($this->data['inlineParentUid'] ?? ''); + } + + /** + * Returns the table (foreign_table) the controls are created for + */ + public function getForeignTable(): string + { + return (string)($this->getFieldConfiguration()['foreign_table'] ?? ''); + } + + /** + * Returns the TCA configuration of the TCA type=file field + */ + public function getFieldConfiguration(): array + { + return (array)($this->data['inlineParentConfig'] ?? []); + } + + /** + * Returns whether the current records is only virtually shown and not physically part of the parent record + */ + public function isVirtual(): bool + { + return (bool)($this->data['isInlineDefaultLanguageRecordInLocalizedParentContext'] ?? false); + } +} diff --git a/typo3/sysext/backend/Classes/Form/FieldControl/ElementBrowser.php b/typo3/sysext/backend/Classes/Form/FieldControl/ElementBrowser.php index d99501c5e68fb56bc15c0dc672bdd9754e3d17aa..8f3276c6d01f99b51923207571aac0da9d61ac9f 100644 --- a/typo3/sysext/backend/Classes/Form/FieldControl/ElementBrowser.php +++ b/typo3/sysext/backend/Classes/Form/FieldControl/ElementBrowser.php @@ -42,7 +42,9 @@ class ElementBrowser extends AbstractNode $elementName = $parameterArray['itemFormElName']; $config = $parameterArray['fieldConf']['config']; $type = $config['type']; - $allowed = $config['allowed'] ?? ''; + + // Remove any white-spaces from the allowed extension lists + $allowed = implode(',', GeneralUtility::trimExplode(',', (string)($config['allowed'] ?? ''), true)); if (isset($config['readOnly']) && $config['readOnly']) { return []; @@ -67,23 +69,24 @@ class ElementBrowser extends AbstractNode ) { $objectPrefix = $inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']) . '-' . $table; } - $elementBrowserType = $type === 'group' ? 'db' : 'folder'; - if (is_array($config['appearance'] ?? null)) { - if (isset($config['appearance']['elementBrowserType'])) { - $elementBrowserType = $config['appearance']['elementBrowserType']; - } - if (isset($config['appearance']['elementBrowserAllowed'])) { - $allowed = $config['appearance']['elementBrowserAllowed']; + + if ($type === 'group') { + if (($this->data['inlineParentConfig']['type'] ?? '') === 'file') { + $elementBrowserType = 'file'; + // Remove any white-spaces from the allowed extension lists + $allowed = implode(',', GeneralUtility::trimExplode(',', (string)($this->data['inlineParentConfig']['allowed'] ?? ''), true)); + } else { + $elementBrowserType = 'db'; } + } else { + $elementBrowserType = 'folder'; } - // Remove any white-spaces from the allowed extension lists - $elementBrowserAllowed = implode(',', GeneralUtility::trimExplode(',', $allowed, true)); // Initialize link attributes $linkAttributes = [ 'class' => 't3js-element-browser', 'data-mode' => htmlspecialchars($elementBrowserType), - 'data-params' => htmlspecialchars($elementName . '|||' . $elementBrowserAllowed . '|' . $objectPrefix), + 'data-params' => htmlspecialchars($elementName . '|||' . $allowed . '|' . $objectPrefix), ]; // Add the default entry point - if found diff --git a/typo3/sysext/backend/Classes/Form/FieldWizard/DefaultLanguageDifferences.php b/typo3/sysext/backend/Classes/Form/FieldWizard/DefaultLanguageDifferences.php index 3d7f9d29add937518d65910691e3f4f57628f6d8..ffcc4a6655d4da0a6fc754db6a503c54de94b029 100644 --- a/typo3/sysext/backend/Classes/Form/FieldWizard/DefaultLanguageDifferences.php +++ b/typo3/sysext/backend/Classes/Form/FieldWizard/DefaultLanguageDifferences.php @@ -53,6 +53,7 @@ class DefaultLanguageDifferences extends AbstractNode || GeneralUtility::inList($l10nDisplay, 'defaultAsReadonly') || !isset($defaultLanguageDiffRow[$fieldName]) || $fieldConfig['config']['type'] === 'inline' + || $fieldConfig['config']['type'] === 'file' || $fieldConfig['config']['type'] === 'flex' ) { // Early return if there is no diff row or if display is disabled diff --git a/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageContent.php b/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageContent.php index ed26b35203c93a53a146a2f44166319268c2ed40..0c84cfca8f46969fa82d5ac24d33153e9ae902c3 100644 --- a/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageContent.php +++ b/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageContent.php @@ -48,6 +48,7 @@ class OtherLanguageContent extends AbstractNode || GeneralUtility::inList($l10nDisplay, 'hideDiff') || GeneralUtility::inList($l10nDisplay, 'defaultAsReadonly') || $fieldType === 'inline' + || $fieldType === 'file' || $fieldType === 'flex' || (in_array($fieldType, ['select', 'category', 'group'], true) && isset($fieldConfig['config']['MM'])) ) { diff --git a/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageThumbnails.php b/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageThumbnails.php index 3f776388c620dd20f75ae150ab4d807106e240f8..ffba2a1c2772b37bea1fe25379f1f5a02f578f00 100644 --- a/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageThumbnails.php +++ b/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageThumbnails.php @@ -66,7 +66,7 @@ class OtherLanguageThumbnails extends AbstractNode $file = null; $fileUid = (int)($languageRow['uid_local'] ?? 0); - if (!$fileUid || $languageRow['table_local'] !== 'sys_file') { + if (!$fileUid) { continue; } diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php index f26027e3f285678c51226f2c56ee4b414bd47d0e..870ad1c0a4e6168ceae4046a0eabe00a1a05b223 100644 --- a/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php +++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php @@ -302,18 +302,15 @@ abstract class AbstractItemProvider // If the foreign table sets selicon_field, this field can contain an image // that represents this specific row. $iconFieldName = ''; - $isReferenceField = false; + $isFileReference = false; if (!empty($GLOBALS['TCA'][$foreignTable]['ctrl']['selicon_field'])) { $iconFieldName = $GLOBALS['TCA'][$foreignTable]['ctrl']['selicon_field']; - if (isset($GLOBALS['TCA'][$foreignTable]['columns'][$iconFieldName]['config']['type']) - && $GLOBALS['TCA'][$foreignTable]['columns'][$iconFieldName]['config']['type'] === 'inline' - && $GLOBALS['TCA'][$foreignTable]['columns'][$iconFieldName]['config']['foreign_table'] === 'sys_file_reference' - ) { - $isReferenceField = true; + if (($GLOBALS['TCA'][$foreignTable]['columns'][$iconFieldName]['config']['type'] ?? '') === 'file') { + $isFileReference = true; } } $icon = ''; - if ($isReferenceField) { + if ($isFileReference) { $references = $fileRepository->findByRelation($foreignTable, $iconFieldName, $foreignRow['uid']); if (is_array($references) && !empty($references)) { $icon = reset($references); diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFiles.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFiles.php new file mode 100644 index 0000000000000000000000000000000000000000..1cad32ec58ceb30cdf7355f2e8ff15240860f552 --- /dev/null +++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFiles.php @@ -0,0 +1,352 @@ +<?php + +declare(strict_types=1); + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +namespace TYPO3\CMS\Backend\Form\FormDataProvider; + +use TYPO3\CMS\Backend\Form\Exception\DatabaseRecordException; +use TYPO3\CMS\Backend\Form\FormDataCompiler; +use TYPO3\CMS\Backend\Form\FormDataGroup\TcaDatabaseRecord; +use TYPO3\CMS\Backend\Form\FormDataProviderInterface; +use TYPO3\CMS\Backend\Form\InlineStackProcessor; +use TYPO3\CMS\Backend\Utility\BackendUtility; +use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; +use TYPO3\CMS\Core\Database\RelationHandler; +use TYPO3\CMS\Core\Localization\LanguageService; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\Utility\MathUtility; +use TYPO3\CMS\Core\Versioning\VersionState; + +/** + * Resolve and prepare files data. + */ +class TcaFiles extends AbstractDatabaseRecordProvider implements FormDataProviderInterface +{ + private const FILE_REFERENCE_TABLE = 'sys_file_reference'; + private const FOREIGN_SELECTOR = 'uid_local'; + + public function addData(array $result): array + { + // inlineFirstPid is currently resolved by TcaInline + // @todo check if duplicating the functionality makes sense to resolve dependencies + + foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) { + if (($fieldConfig['config']['type'] ?? '') !== 'file') { + continue; + } + + if (!$this->getBackendUser()->check('tables_modify', self::FILE_REFERENCE_TABLE)) { + // Early return if user is not allowed to modify the file reference table + continue; + } + + if (!($GLOBALS['TCA'][self::FILE_REFERENCE_TABLE] ?? false)) { + throw new \RuntimeException('Table ' . self::FILE_REFERENCE_TABLE . ' does not exists', 1664364262); + } + + $childConfiguration = $GLOBALS['TCA'][self::FILE_REFERENCE_TABLE]['columns'][self::FOREIGN_SELECTOR]['config'] ?? []; + if (($childConfiguration['type'] ?? '') !== 'group' || !($childConfiguration['allowed'] ?? false)) { + throw new \UnexpectedValueException( + 'Table ' . $result['tableName'] . ' field ' . $fieldName . ' points to field ' + . self::FOREIGN_SELECTOR . ' of table ' . self::FILE_REFERENCE_TABLE . ', but this field ' + . 'is either not defined, is not of type "group" or does not define the "allowed" option.', + 1664364263 + ); + } + + $result['processedTca']['columns'][$fieldName]['children'] = []; + + $result = $this->initializeMinMaxItems($result, $fieldName); + $result = $this->initializeParentSysLanguageUid($result, $fieldName); + $result = $this->initializeAppearance($result, $fieldName); + + // If field is set to readOnly, set all fields of the relation to readOnly as well + if ($result['inlineParentConfig']['readOnly'] ?? false) { + foreach ($result['processedTca']['columns'] as $columnName => $columnConfiguration) { + $result['processedTca']['columns'][$columnName]['config']['readOnly'] = true; + } + } + + // Resolve existing file references - this is usually always done except on ajax calls + if ($result['inlineResolveExistingChildren']) { + $result = $this->resolveFileReferences($result, $fieldName); + if (!empty($fieldConfig['config']['selectorOrUniqueConfiguration'])) { + throw new \RuntimeException('selectorOrUniqueConfiguration not implemented for TCA type "file"', 1664380909); + } + } + } + + return $result; + } + + protected function initializeMinMaxItems(array $result, string $fieldName): array + { + $config = $result['processedTca']['columns'][$fieldName]['config']; + $config['minitems'] = isset($config['minitems']) ? MathUtility::forceIntegerInRange($config['minitems'], 0) : 0; + $config['maxitems'] = isset($config['maxitems']) ? MathUtility::forceIntegerInRange($config['maxitems'], 1) : 99999; + $result['processedTca']['columns'][$fieldName]['config'] = $config; + + return $result; + } + + protected function initializeParentSysLanguageUid(array $result, string $fieldName): array + { + if (($parentLanguageFieldName = (string)($result['processedTca']['ctrl']['languageField'] ?? '')) === '' + || !($GLOBALS['TCA'][self::FILE_REFERENCE_TABLE]['ctrl']['languageField'] ?? false) + || isset($result['processedTca']['columns'][$fieldName]['config']['inline']['parentSysLanguageUid']) + || !isset($result['databaseRow'][$parentLanguageFieldName]) + ) { + return $result; + } + + $result['processedTca']['columns'][$fieldName]['config']['inline']['parentSysLanguageUid'] = + is_array($result['databaseRow'][$parentLanguageFieldName]) + ? (int)($result['databaseRow'][$parentLanguageFieldName][0] ?? 0) + : (int)$result['databaseRow'][$parentLanguageFieldName]; + + return $result; + } + + protected function initializeAppearance(array $result, string $fieldName): array + { + $result['processedTca']['columns'][$fieldName]['config']['appearance'] = array_replace_recursive( + [ + 'useSortable' => true, + 'headerThumbnail' => [ + 'height' => '45m', + ], + 'enabledControls' => [ + 'edit' => true, + 'info' => true, + 'dragdrop' => true, + 'sort' => false, + 'hide' => true, + 'delete' => true, + 'localize' => true, + ], + ], + $result['processedTca']['columns'][$fieldName]['config']['appearance'] ?? [] + ); + + return $result; + } + + /** + * Substitute the value in databaseRow of this inline field with an array + * that contains the databaseRows of currently connected records and some meta information. + */ + protected function resolveFileReferences(array $result, string $fieldName): array + { + if ($result['defaultLanguageRow'] !== null) { + return $this->resolveFileReferenceOverlays($result, $fieldName); + } + + $fileReferenceUidsOfDefaultLanguageRecord = $this->resolveFileReferenceUids( + $result['processedTca']['columns'][$fieldName]['config'], + $result['tableName'], + $result['databaseRow']['uid'], + $result['databaseRow'][$fieldName] + ); + $result['databaseRow'][$fieldName] = implode(',', $fileReferenceUidsOfDefaultLanguageRecord); + + if ($result['inlineCompileExistingChildren']) { + foreach ($this->getSubstitutedWorkspacedUids($fileReferenceUidsOfDefaultLanguageRecord) as $uid) { + try { + $compiledFileReference = $this->compileFileReference($result, $fieldName, $uid); + $result['processedTca']['columns'][$fieldName]['children'][] = $compiledFileReference; + } catch (DatabaseRecordException $e) { + // Nothing to do here, missing file reference is just not being rendered. + } + } + } + return $result; + } + + /** + * Substitute the value in databaseRow of this file field with an array + * that contains the databaseRows of currently connected file references + * and some meta information. + */ + protected function resolveFileReferenceOverlays(array $result, string $fieldName): array + { + $fileReferenceUidsOfLocalizedOverlay = []; + $fieldConfig = $result['processedTca']['columns'][$fieldName]['config']; + if ($result['command'] === 'edit') { + $fileReferenceUidsOfLocalizedOverlay = $this->resolveFileReferenceUids( + $fieldConfig, + $result['tableName'], + $result['databaseRow']['uid'], + $result['databaseRow'][$fieldName] + ); + } + $result['databaseRow'][$fieldName] = implode(',', $fileReferenceUidsOfLocalizedOverlay); + $fileReferenceUidsOfLocalizedOverlay = $this->getSubstitutedWorkspacedUids($fileReferenceUidsOfLocalizedOverlay); + if ($result['inlineCompileExistingChildren']) { + $tableNameWithDefaultRecords = $result['tableName']; + $fileReferenceUidsOfDefaultLanguageRecord = $this->getSubstitutedWorkspacedUids( + $this->resolveFileReferenceUids( + $fieldConfig, + $tableNameWithDefaultRecords, + $result['defaultLanguageRow']['uid'], + $result['defaultLanguageRow'][$fieldName] + ) + ); + + // Find which records are localized, which records are not localized and which are + // localized but miss default language record + $fieldNameWithDefaultLanguageUid = (string)($GLOBALS['TCA'][self::FILE_REFERENCE_TABLE]['ctrl']['transOrigPointerField'] ?? ''); + foreach ($fileReferenceUidsOfLocalizedOverlay as $localizedUid) { + try { + $localizedRecord = $this->getRecordFromDatabase(self::FILE_REFERENCE_TABLE, $localizedUid); + } catch (DatabaseRecordException $e) { + // The child could not be compiled, probably it was deleted and a dangling mm record exists + $this->logger->warning( + $e->getMessage(), + [ + 'table' => self::FILE_REFERENCE_TABLE, + 'uid' => $localizedUid, + 'exception' => $e, + ] + ); + continue; + } + $uidOfDefaultLanguageRecord = (int)$localizedRecord[$fieldNameWithDefaultLanguageUid]; + if (in_array($uidOfDefaultLanguageRecord, $fileReferenceUidsOfDefaultLanguageRecord, true)) { + // This localized child has a default language record. Remove this record from list of default language records + $fileReferenceUidsOfDefaultLanguageRecord = array_diff($fileReferenceUidsOfDefaultLanguageRecord, [$uidOfDefaultLanguageRecord]); + } + // Compile localized record + $compiledFileReference = $this->compileFileReference($result, $fieldName, $localizedUid); + $result['processedTca']['columns'][$fieldName]['children'][] = $compiledFileReference; + } + if ($fieldConfig['appearance']['showPossibleLocalizationRecords'] ?? false) { + foreach ($fileReferenceUidsOfDefaultLanguageRecord as $defaultLanguageUid) { + // If there are still uids in $connectedUidsOfDefaultLanguageRecord, these are records that + // exist in default language, but are not localized yet. Compile and mark those + try { + $compiledFileReference = $this->compileFileReference($result, $fieldName, $defaultLanguageUid); + } catch (DatabaseRecordException $e) { + // The child could not be compiled, probably it was deleted and a dangling mm record exists + $this->logger->warning( + $e->getMessage(), + [ + 'table' => self::FILE_REFERENCE_TABLE, + 'uid' => $defaultLanguageUid, + 'exception' => $e, + ] + ); + continue; + } + $compiledFileReference['isInlineDefaultLanguageRecordInLocalizedParentContext'] = true; + $result['processedTca']['columns'][$fieldName]['children'][] = $compiledFileReference; + } + } + } + + return $result; + } + + protected function compileFileReference(array $result, string $parentFieldName, int $childUid): array + { + $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class); + $inlineStackProcessor->initializeByGivenStructure($result['inlineStructure']); + $inlineTopMostParent = $inlineStackProcessor->getStructureLevel(0) ?: []; + + return GeneralUtility::makeInstance(FormDataCompiler::class, GeneralUtility::makeInstance(TcaDatabaseRecord::class))->compile([ + 'command' => 'edit', + 'tableName' => self::FILE_REFERENCE_TABLE, + 'vanillaUid' => $childUid, + 'returnUrl' => $result['returnUrl'], + 'isInlineChild' => true, + 'inlineStructure' => $result['inlineStructure'], + 'inlineExpandCollapseStateArray' => $result['inlineExpandCollapseStateArray'], + 'inlineFirstPid' => $result['inlineFirstPid'], + 'inlineParentConfig' => $result['processedTca']['columns'][$parentFieldName]['config'], + 'inlineParentUid' => $result['databaseRow']['uid'], + 'inlineParentTableName' => $result['tableName'], + 'inlineParentFieldName' => $parentFieldName, + 'inlineTopMostParentUid' => $result['inlineTopMostParentUid'] ?: $inlineTopMostParent['uid'] ?? '', + 'inlineTopMostParentTableName' => $result['inlineTopMostParentTableName'] ?: $inlineTopMostParent['table'] ?? '', + 'inlineTopMostParentFieldName' => $result['inlineTopMostParentFieldName'] ?: $inlineTopMostParent['field'] ?? '', + ]); + } + + /** + * Substitute given list of uids with corresponding workspace uids - if needed + * + * @param int[] $connectedUids List of file reference uids + * @return int[] List of substituted uids + */ + protected function getSubstitutedWorkspacedUids(array $connectedUids): array + { + $workspace = $this->getBackendUser()->workspace; + if ($workspace === 0 || !BackendUtility::isTableWorkspaceEnabled(self::FILE_REFERENCE_TABLE)) { + return $connectedUids; + } + + $substitutedUids = []; + foreach ($connectedUids as $uid) { + $workspaceVersion = BackendUtility::getWorkspaceVersionOfRecord( + $workspace, + self::FILE_REFERENCE_TABLE, + $uid, + 'uid,t3ver_state' + ); + if (!empty($workspaceVersion)) { + $versionState = VersionState::cast($workspaceVersion['t3ver_state']); + if ($versionState->equals(VersionState::DELETE_PLACEHOLDER)) { + continue; + } + $uid = $workspaceVersion['uid']; + } + $substitutedUids[] = (int)$uid; + } + return $substitutedUids; + } + + /** + * Resolve file reference uids using the RelationHandler + * + * @return int[] + */ + protected function resolveFileReferenceUids( + array $parentConfig, + $parentTableName, + $parentUid, + $parentFieldValue + ): array { + $relationHandler = GeneralUtility::makeInstance(RelationHandler::class); + $relationHandler->start( + $parentFieldValue, + self::FILE_REFERENCE_TABLE, + '', + BackendUtility::getLiveVersionIdOfRecord($parentTableName, $parentUid) ?? $parentUid, + $parentTableName, + $parentConfig + ); + return array_map('intval', $relationHandler->getValueArray()); + } + + protected function getBackendUser(): BackendUserAuthentication + { + return $GLOBALS['BE_USER']; + } + + protected function getLanguageService(): LanguageService + { + return $GLOBALS['LANG']; + } +} diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php index 210b40ebd1bc0028d1e330b0fe6aa71b981033c6..e2972e63913d4656e2b102cd6591ed6e32d80013 100644 --- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php +++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php @@ -153,6 +153,11 @@ class TcaFlexPrepare implements FormDataProviderInterface /** * Recursively migrate flex form TCA * + * @todo This is already partially done in FlexFormTools and should be harmonized. Therefore, + * all migration / preparation should go into FlexFormTools, because DataHandler also + * needs the migrated / prepared config and does not call this FormEngine specific + * FormDataProvider. + * * @param array $structure Given hierarchy * @param string $table * @param string $fieldName diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexProcess.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexProcess.php index f0bb1db2866be361af6e7aa08666b984a2275578..ba1a33de45e6b2e61d7acfc6b0506413bb3e3941 100644 --- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexProcess.php +++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexProcess.php @@ -99,13 +99,23 @@ class TcaFlexProcess implements FormDataProviderInterface if (isset($containerConfiguration['el']) && is_array($containerConfiguration['el'])) { foreach ($containerConfiguration['el'] as $singleFieldName => $singleFieldConfiguration) { // Nesting type=inline in container sections is not supported. Throw an exception if configured. - if (isset($singleFieldConfiguration['config']['type']) && $singleFieldConfiguration['config']['type'] === 'inline') { - throw new \UnexpectedValueException( - 'Invalid flex form data structure on field name "' . $fieldName . '" with element "' . $singleFieldName . '"' - . ' in section container "' . $containerName . '": Nesting inline elements in flex form' - . ' sections is not allowed.', - 1458745468 - ); + if (isset($singleFieldConfiguration['config']['type'])) { + if ($singleFieldConfiguration['config']['type'] === 'inline') { + throw new \UnexpectedValueException( + 'Invalid flex form data structure on field name "' . $fieldName . '" with element "' . $singleFieldName . '"' + . ' in section container "' . $containerName . '": Nesting inline elements in flex form' + . ' sections is not allowed.', + 1458745468 + ); + } + if ($singleFieldConfiguration['config']['type'] === 'file') { + throw new \UnexpectedValueException( + 'Invalid flex form data structure on field name "' . $fieldName . '" with element "' . $singleFieldName . '"' + . ' in section container "' . $containerName . '": Nesting file elements in flex form' + . ' sections is not allowed.', + 1664473929 + ); + } } // Nesting sections is not supported. Throw an exception if configured. diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInline.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInline.php index 4a91cc870ab4869c2ea0712fe2904a3d0276372d..673fba1810772eceb42d2414578bd90cb0497288 100644 --- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInline.php +++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInline.php @@ -457,7 +457,6 @@ class TcaInline extends AbstractDatabaseRecordProvider implements FormDataProvid $parentUid = $this->getLiveDefaultId($parentTableName, $parentUid); } $relationHandler = GeneralUtility::makeInstance(RelationHandler::class); - $relationHandler->registerNonTableValues = (bool)($parentConfig['allowedIdValues'] ?? false); $relationHandler->start($parentFieldValue, $parentConfig['foreign_table'] ?? '', $parentConfig['MM'] ?? '', $parentUid, $parentTableName, $parentConfig); $foreignRecordUids = $relationHandler->getValueArray(); $resolvedForeignRecordUids = []; diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInputPlaceholders.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInputPlaceholders.php index aedad2f6ed10e480fbbfd834ae20bddc6c4a77a0..583d7b81e60d4dd1261d7ee86f821441c5646924 100644 --- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInputPlaceholders.php +++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInputPlaceholders.php @@ -127,6 +127,7 @@ class TcaInputPlaceholders implements FormDataProviderInterface $foreignTableName = $this->getAllowedTableForGroupField($fieldConfig); break; case 'inline': + case 'file': $possibleUids = array_filter(GeneralUtility::trimExplode(',', $value, true)); $foreignTableName = $fieldConfig['foreign_table']; break; diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaRecordTitle.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaRecordTitle.php index ef6a7482825085dbd42a40a7cc1ff8187a073569..1673ecc9ed00fafabb3407658cfbe715a9b95090 100644 --- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaRecordTitle.php +++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaRecordTitle.php @@ -156,6 +156,7 @@ class TcaRecordTitle implements FormDataProviderInterface $recordTitle = $this->getRecordTitleForRadioType($rawValue, $fieldConfig); break; case 'inline': + case 'file': $recordTitle = $this->getRecordTitleForInlineType( $rawValue, $result['processedTca']['columns'][$fieldName]['children'] diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSiteLanguage.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSiteLanguage.php index aafee70c532b9918b5ee1533e7bb822cb2bc2115..075185acffd257729de09bbc8b6e8233812e6cc2 100644 --- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSiteLanguage.php +++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSiteLanguage.php @@ -108,7 +108,7 @@ class TcaSiteLanguage extends AbstractDatabaseRecordProvider implements FormData } $config['appearance']['showPossibleLocalizationRecords'] = false; $config['appearance']['collapseAll'] = true; - $config['appearance']['expandSignle'] = false; + $config['appearance']['expandSingle'] = false; $config['appearance']['enabledControls'] = [ 'info' => false, 'new' => false, diff --git a/typo3/sysext/backend/Classes/Form/NodeFactory.php b/typo3/sysext/backend/Classes/Form/NodeFactory.php index c8de41c4a3073cb367ffdd41c7d77f48bc7ace3a..92bdadbd402c3644025f858e8110d7f48b3506d3 100644 --- a/typo3/sysext/backend/Classes/Form/NodeFactory.php +++ b/typo3/sysext/backend/Classes/Form/NodeFactory.php @@ -15,6 +15,7 @@ namespace TYPO3\CMS\Backend\Form; +use TYPO3\CMS\Backend\Form\Container\FilesControlContainer; use TYPO3\CMS\Core\Utility\GeneralUtility; /** @@ -58,8 +59,10 @@ class NodeFactory 'flexFormTabsContainer' => Container\FlexFormTabsContainer::class, 'fullRecordContainer' => Container\FullRecordContainer::class, 'inline' => Container\InlineControlContainer::class, - 'siteLanguage' => Container\SiteLanguageContainer::class, 'inlineRecordContainer' => Container\InlineRecordContainer::class, + FilesControlContainer::NODE_TYPE_IDENTIFIER => Container\FilesControlContainer::class, + Container\FileReferenceContainer::NODE_TYPE_IDENTIFIER => Container\FileReferenceContainer::class, + 'siteLanguage' => Container\SiteLanguageContainer::class, 'listOfFieldsContainer' => Container\ListOfFieldsContainer::class, 'noTabsContainer' => Container\NoTabsContainer::class, 'outerWrapContainer' => Container\OuterWrapContainer::class, diff --git a/typo3/sysext/backend/Classes/Form/Utility/FormEngineUtility.php b/typo3/sysext/backend/Classes/Form/Utility/FormEngineUtility.php index 057a7a7d28dc06698762b7bd674f9952d6e87916..bd962e30501308607339465f2af7bfb588691091 100644 --- a/typo3/sysext/backend/Classes/Form/Utility/FormEngineUtility.php +++ b/typo3/sysext/backend/Classes/Form/Utility/FormEngineUtility.php @@ -57,6 +57,7 @@ class FormEngineUtility 'group' => ['size', 'autoSizeMax', 'maxitems', 'minitems', 'readOnly', 'elementBrowserEntryPoints'], 'folder' => ['size', 'autoSizeMax', 'maxitems', 'minitems', 'readOnly', 'elementBrowserEntryPoints'], 'inline' => ['appearance', 'behaviour', 'foreign_label', 'foreign_selector', 'foreign_unique', 'maxitems', 'minitems', 'size', 'autoSizeMax', 'symmetric_label', 'readOnly'], + 'file' => ['appearance', 'behaviour', 'maxitems', 'minitems', 'readOnly'], 'imageManipulation' => ['ratios', 'cropVariants'], ]; diff --git a/typo3/sysext/backend/Classes/RecordList/ElementBrowserRecordList.php b/typo3/sysext/backend/Classes/RecordList/ElementBrowserRecordList.php index aca436be6fcf50f5b2cca578f55b2383383f2abb..35fd3585d1b6f07057efdc29bb7d0e7e35641a20 100644 --- a/typo3/sysext/backend/Classes/RecordList/ElementBrowserRecordList.php +++ b/typo3/sysext/backend/Classes/RecordList/ElementBrowserRecordList.php @@ -17,6 +17,7 @@ namespace TYPO3\CMS\Backend\RecordList; use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\Imaging\Icon; +use TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter; use TYPO3\CMS\Core\Utility\GeneralUtility; /** @@ -92,6 +93,17 @@ class ElementBrowserRecordList extends DatabaseRecordList } } } + if (($tcaFieldConfig['type'] ?? '') === 'file') { + $valueArray = GeneralUtility::makeInstance(FileExtensionFilter::class)->filter( + [$table . '_' . $row['uid']], + (string)($tcaFieldConfig['allowed'] ?? ''), + (string)($tcaFieldConfig['disallowed'] ?? ''), + $this + ); + if (empty($valueArray)) { + $returnValue = false; + } + } } return $returnValue; } diff --git a/typo3/sysext/backend/Classes/Utility/BackendUtility.php b/typo3/sysext/backend/Classes/Utility/BackendUtility.php index ffd2b34b675ee97603c60418b6d2d300c9cbc469..cf04665c9850f8c2c4042974c464e6b179e2501f 100644 --- a/typo3/sysext/backend/Classes/Utility/BackendUtility.php +++ b/typo3/sysext/backend/Classes/Utility/BackendUtility.php @@ -914,9 +914,7 @@ class BackendUtility return null; } $configuration = $GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config']; - if (empty($configuration['type']) || $configuration['type'] !== 'inline' - || empty($configuration['foreign_table']) || $configuration['foreign_table'] !== 'sys_file_reference' - ) { + if (($configuration['type'] ?? '') !== 'file') { return null; } @@ -1554,6 +1552,7 @@ class BackendUtility $l = $lang->sL($l); break; case 'inline': + case 'file': if ($uid) { $finalValues = static::resolveRelationLabels($theColConf, $table, $uid, $value, $noRecordLookup); $l = implode(', ', $finalValues); diff --git a/typo3/sysext/backend/Configuration/Backend/AjaxRoutes.php b/typo3/sysext/backend/Configuration/Backend/AjaxRoutes.php index 97fddae3bdbaa1efb6de8e16c2afd1c5cb517426..3fbb138a86bf98dd7cb5dd586e30584a86cb31f5 100644 --- a/typo3/sysext/backend/Configuration/Backend/AjaxRoutes.php +++ b/typo3/sysext/backend/Configuration/Backend/AjaxRoutes.php @@ -23,6 +23,33 @@ return [ 'target' => Controller\File\FileController::class . '::fileExistsInFolderAction', ], + // Get details of a file reference in FormEngine + 'file_reference_details' => [ + 'path' => '/file/reference/details', + 'target' => Controller\FormFilesAjaxController::class . '::detailsAction', + ], + + // Create a new file reference in FormEngine + 'file_reference_create' => [ + 'path' => '/file/reference/create', + 'methods' => ['POST'], + 'target' => Controller\FormFilesAjaxController::class . '::createAction', + ], + + // Synchronize localization of a file reference in FormEngine + 'file_reference_synchronizelocalize' => [ + 'path' => '/file/reference/synchronizelocalize', + 'methods' => ['POST'], + 'target' => Controller\FormFilesAjaxController::class . '::synchronizeLocalizeAction', + ], + + // Expand / Collapse a file reference in FormEngine + 'file_reference_expandcollapse' => [ + 'path' => '/file/reference/expandcollapse', + 'methods' => ['POST'], + 'target' => Controller\FormFilesAjaxController::class . '::expandOrCollapseAction', + ], + // Get record details of a child record in IRRE 'record_inline_details' => [ 'path' => '/record/inline/details', diff --git a/typo3/sysext/backend/Configuration/Services.yaml b/typo3/sysext/backend/Configuration/Services.yaml index 13ece77f5b5e461b457a500aefb1696e2ef0e2dc..7c57fbccb53b8771a75bc3096e03c382eb39b3da 100644 --- a/typo3/sysext/backend/Configuration/Services.yaml +++ b/typo3/sysext/backend/Configuration/Services.yaml @@ -95,6 +95,9 @@ services: TYPO3\CMS\Backend\Controller\ElementBrowserController: tags: ['backend.controller'] + TYPO3\CMS\Backend\Controller\FormFilesAjaxController: + tags: ['backend.controller'] + TYPO3\CMS\Backend\Controller\FormSlugAjaxController: tags: ['backend.controller'] diff --git a/typo3/sysext/backend/Resources/Private/Templates/Form/FilesControlContainer.html b/typo3/sysext/backend/Resources/Private/Templates/Form/FilesControlContainer.html new file mode 100644 index 0000000000000000000000000000000000000000..4f9c92b7236cdea40b96ca6ea16ed724b9ff09b9 --- /dev/null +++ b/typo3/sysext/backend/Resources/Private/Templates/Form/FilesControlContainer.html @@ -0,0 +1,52 @@ +<html + xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" + xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" + data-namespace-typo3-fluid="true" +> +<typo3-formengine-container-files identifier="{formFieldIdentifier}"> + <div {formGroupAttributes -> f:format.raw()}> + <f:format.raw>{fieldInformation}</f:format.raw> + <div class="form-group t3js-formengine-validation-marker"> + <div class="form-control-wrap t3js-file-controls"> + <f:for each="{fileSelectors}" as="fileSelector"> + {fileSelector -> f:format.raw()} + </f:for> + </div> + <f:if condition="{allowedFileTypes}"> + <div class="help-block"> + <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.allowedFileExtensions"/><br> + <f:for each="{allowedFileTypes}" as="allowedFileType"> + <span class="badge badge-success">{allowedFileType}</span> + </f:for> + </div> + </f:if> + </div> + <f:if condition="{showAllLocalizationLink}"> + <div class="typo3-localizationLink" title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:localizeAllRecords')}"> + <button type="button" class="btn btn-default t3js-synchronizelocalize-button" data-type="localize"> + <core:icon identifier="actions-document-localize" size="small" /> + <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:localizeAllRecords" /> + </button> + </div> + </f:if> + <f:if condition="{showSynchronizationLink}"> + <div class="typo3-synchronizationLink" title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:synchronizeWithOriginalLanguage')}"> + <button type="button" class="btn btn-default t3js-synchronizelocalize-button" data-type="synchronize"> + <core:icon identifier="actions-document-synchronize" size="small" /> + <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:synchronizeWithOriginalLanguage" /> + </button> + </div> + </f:if> + <div class="panel-group panel-hover {f:if(condition: '{showAllLocalizationLink} || {showSynchronizationLink}', then: 'mt-3')}" id="{fileReferences.id}" data-title="{fileReferences.title}"> + <f:format.raw>{fileReferences.records}</f:format.raw> + </div> + <f:format.raw>{fieldWizard}</f:format.raw> + <f:if condition="{customControls}"> + <div id="{customControls.id}"> + <f:format.raw>{customControls.controls}</f:format.raw> + </div> + </f:if> + <input type="hidden" class="inlineRecord" name="{formFieldName}" value="{sortableRecordUids}" data-formengine-validation-rules="{validationRules}" /> + </div> +</typo3-formengine-container-files> +</html> diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/form-engine-validation.js b/typo3/sysext/backend/Resources/Public/JavaScript/form-engine-validation.js index 8ca52deb0a7030f5a59e4786ba131a3e83821a14..bd80d9853a4a3c675e6066307fb2c3fd04d639cb 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/form-engine-validation.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/form-engine-validation.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import $ from"jquery";import moment from"moment";import Md5 from"@typo3/backend/hashing/md5.js";import DocumentSaveActions from"@typo3/backend/document-save-actions.js";import Modal from"@typo3/backend/modal.js";import Severity from"@typo3/backend/severity.js";export default(function(){const FormEngineValidation={rulesSelector:"[data-formengine-validation-rules]",inputSelector:"[data-formengine-input-params]",markerSelector:".t3js-formengine-validation-marker",groupFieldHiddenElement:".t3js-formengine-field-group input[type=hidden]",relatedFieldSelector:"[data-relatedfieldname]",errorClass:"has-error",lastYear:0,lastDate:0,lastTime:0,passwordDummy:"********"},customEvaluations=new Map;return FormEngineValidation.initialize=function(){$(document).find("."+FormEngineValidation.errorClass).removeClass(FormEngineValidation.errorClass),FormEngineValidation.initializeInputFields().promise().done((function(){$(document).on("change",FormEngineValidation.rulesSelector,(e=>{FormEngineValidation.validateField(e.currentTarget),FormEngineValidation.markFieldAsChanged(e.currentTarget)})),FormEngineValidation.registerSubmitCallback()}));const e=new Date;FormEngineValidation.lastYear=FormEngineValidation.getYear(e),FormEngineValidation.lastDate=FormEngineValidation.getDate(e),FormEngineValidation.lastTime=0,FormEngineValidation.validate()},FormEngineValidation.initializeInputFields=function(){return $(document).find(FormEngineValidation.inputSelector).each((function(e,n){const t=$(n).data("formengine-input-params"),a=t.field,i=$('[name="'+a+'"]');void 0===i.data("main-field")&&(i.data("main-field",a),i.data("config",t),FormEngineValidation.initializeInputField(a))}))},FormEngineValidation.initializeInputField=function(e){const n=$('[name="'+e+'"]'),t=$('[data-formengine-input-name="'+e+'"]');let a=$('[name="'+n.data("main-field")+'"]');0===a.length&&(a=n);const i=a.data("config");if(void 0!==i){const e=FormEngineValidation.trimExplode(",",i.evalList);let a=n.val();for(let n=0;n<e.length;n++)a=FormEngineValidation.formatValue(e[n],a,i);a.length&&t.val(a)}t.data("main-field",e),t.data("config",i),t.on("change",(function(){FormEngineValidation.updateInputField(t.attr("data-formengine-input-name"))})),t.attr("data-formengine-input-initialized","true")},FormEngineValidation.registerCustomEvaluation=function(e,n){customEvaluations.has(e)||customEvaluations.set(e,n)},FormEngineValidation.formatValue=function(e,n,t){let a,i,o="";switch(e){case"date":if(n.toString().indexOf("-")>0){o=moment.utc(n).format("DD-MM-YYYY")}else{if(a=1*n,!a)return"";i=new Date(1e3*a);o=i.getUTCDate().toString(10).padStart(2,"0")+"-"+(i.getUTCMonth()+1).toString(10).padStart(2,"0")+"-"+this.getYear(i)}break;case"datetime":if(n.toString().indexOf("-")<=0&&!("number"==typeof n?n:parseInt(n)))return"";o=FormEngineValidation.formatValue("time",n,t)+" "+FormEngineValidation.formatValue("date",n,t);break;case"time":case"timesec":let r;if(n.toString().indexOf("-")>0)r=moment.utc(n);else{if(a="number"==typeof n?n:parseInt(n),!a&&"0"!==n.toString())return"";r=moment.unix(a).utc()}o="timesec"===e?r.format("HH:mm:ss"):r.format("HH:mm");break;case"password":o=n?FormEngineValidation.passwordDummy:"";break;default:o=n}return o},FormEngineValidation.updateInputField=function(e){const n=$('[name="'+e+'"]');let t=$('[name="'+n.data("main-field")+'"]');0===t.length&&(t=n);const a=$('[data-formengine-input-name="'+t.attr("name")+'"]'),i=t.data("config");if(void 0!==i){const e=FormEngineValidation.trimExplode(",",i.evalList);let n=a.val();for(let t=0;t<e.length;t++)n=FormEngineValidation.processValue(e[t],n,i);let o=n;for(let n=0;n<e.length;n++)o=FormEngineValidation.formatValue(e[n],o,i);t.val(n),t.get(0).dispatchEvent(new Event("change")),a.val(o)}},FormEngineValidation.validateField=function(e,n){const t=e instanceof $?e.get(0):e;if(n=n||t.value||"",void 0===t.dataset.formengineValidationRules)return n;const a=JSON.parse(t.dataset.formengineValidationRules);let i,o,r,l=!1,s=0,m=n;$.isArray(n)||(n=FormEngineValidation.ltrim(n)),$.each(a,(function(e,a){if(l)return!1;switch(a.type){case"required":""===n&&(l=!0,t.closest(FormEngineValidation.markerSelector).classList.add(FormEngineValidation.errorClass));break;case"range":if(""!==n){if((a.minItems||a.maxItems)&&(i=$(document).find('[name="'+t.dataset.relatedfieldname+'"]'),s=i.length?FormEngineValidation.trimExplode(",",i.val()).length:t.value,void 0!==a.minItems&&(o=1*a.minItems,!isNaN(o)&&s<o&&(l=!0)),void 0!==a.maxItems&&(r=1*a.maxItems,!isNaN(r)&&s>r&&(l=!0))),void 0!==a.lower){const e=1*a.lower;!isNaN(e)&&n<e&&(l=!0)}if(void 0!==a.upper){const e=1*a.upper;!isNaN(e)&&n>e&&(l=!0)}}break;case"select":case"category":(a.minItems||a.maxItems)&&(i=$(document).find('[name="'+t.dataset.relatedfieldname+'"]'),s=i.length?FormEngineValidation.trimExplode(",",i.val()).length:t instanceof HTMLSelectElement?t.querySelectorAll("option:checked").length:t.querySelectorAll("input[value]:checked").length,void 0!==a.minItems&&(o=1*a.minItems,!isNaN(o)&&s<o&&(l=!0)),void 0!==a.maxItems&&(r=1*a.maxItems,!isNaN(r)&&s>r&&(l=!0)));break;case"group":case"inline":(a.minItems||a.maxItems)&&(s=FormEngineValidation.trimExplode(",",t.value).length,void 0!==a.minItems&&(o=1*a.minItems,!isNaN(o)&&s<o&&(l=!0)),void 0!==a.maxItems&&(r=1*a.maxItems,!isNaN(r)&&s>r&&(l=!0)));break;case"min":(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement)&&t.value.length>0&&t.value.length<t.minLength&&(l=!0)}}));const d=!l,g=t.closest(FormEngineValidation.markerSelector);return null!==g&&g.classList.toggle(FormEngineValidation.errorClass,!d),FormEngineValidation.markParentTab($(t),d),$(document).trigger("t3-formengine-postfieldvalidation"),m},FormEngineValidation.processValue=function(e,n,t){let a="",i="",o="",r=0,l=n;switch(e){case"alpha":case"num":case"alphanum":case"alphanum_x":for(a="",r=0;r<n.length;r++){const t=n.substr(r,1);let i="_"===t||"-"===t,o=t>="a"&&t<="z"||t>="A"&&t<="Z",l=t>="0"&&t<="9";switch(e){case"alphanum":i=!1;break;case"alpha":l=!1,i=!1;break;case"num":o=!1,i=!1}(o||l||i)&&(a+=t)}a!==n&&(l=a);break;case"is_in":if(t.is_in){i=""+n,t.is_in=t.is_in.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&");const e=new RegExp("[^"+t.is_in+"]+","g");a=i.replace(e,"")}else a=i;l=a;break;case"nospace":l=(""+n).replace(/ /g,"");break;case"md5":""!==n&&(l=Md5.hash(n));break;case"upper":l=n.toUpperCase();break;case"lower":l=n.toLowerCase();break;case"integer":""!==n&&(l=FormEngineValidation.parseInt(n));break;case"decimal":""!==n&&(l=FormEngineValidation.parseDouble(n));break;case"trim":l=String(n).trim();break;case"datetime":""!==n&&(o=n.substr(0,1),l=FormEngineValidation.parseDateTime(n));break;case"date":""!==n&&(o=n.substr(0,1),l=FormEngineValidation.parseDate(n));break;case"time":case"timesec":""!==n&&(o=n.substr(0,1),l=FormEngineValidation.parseTime(n,e));break;case"year":""!==n&&(o=n.substr(0,1),l=FormEngineValidation.parseYear(n));break;case"null":case"password":break;default:customEvaluations.has(e)?l=customEvaluations.get(e).call(null,n):"object"==typeof TBE_EDITOR&&void 0!==TBE_EDITOR.customEvalFunctions&&"function"==typeof TBE_EDITOR.customEvalFunctions[e]&&(l=TBE_EDITOR.customEvalFunctions[e](n))}return l},FormEngineValidation.validate=function(e){(void 0===e||e instanceof Document)&&$(document).find(FormEngineValidation.markerSelector+", .t3js-tabmenu-item").removeClass(FormEngineValidation.errorClass).removeClass("has-validation-error");const n=e||document;$(n).find(FormEngineValidation.rulesSelector).each(((e,n)=>{const t=$(n);if(!t.closest(".t3js-flex-section-deleted, .t3js-inline-record-deleted").length){let e=!1;const n=t.val(),a=FormEngineValidation.validateField(t,n);if($.isArray(a)&&$.isArray(n)){if(a.length!==n.length)e=!0;else for(let t=0;t<a.length;t++)if(a[t]!==n[t]){e=!0;break}}else a.length&&n!==a&&(e=!0);e&&t.val(a)}}))},FormEngineValidation.markFieldAsChanged=function(e){if(e instanceof $&&(e=e.get(0)),!(e instanceof HTMLElement))return;const n=e.closest(".t3js-formengine-palette-field");null!==n&&n.classList.add("has-change")},FormEngineValidation.trimExplode=function(e,n){const t=[],a=n.split(e);for(let e=0;e<a.length;e++){const n=a[e].trim();n.length>0&&t.push(n)}return t},FormEngineValidation.parseInt=function(e){let n;return e?(n=parseInt(""+e,10),isNaN(n)?0:n):0},FormEngineValidation.parseDouble=function(e,n=2){let t=""+e;t=t.replace(/[^0-9,\.-]/g,"");const a="-"===t.substring(0,1);t=t.replace(/-/g,""),t=t.replace(/,/g,"."),-1===t.indexOf(".")&&(t+=".0");const i=t.split("."),o=i.pop();let r=Number(i.join("")+"."+o);return a&&(r*=-1),t=r.toFixed(n),t},FormEngineValidation.ltrim=function(e){return e?(""+e).replace(/^\s+/,""):""},FormEngineValidation.btrim=function(e){return e?(""+e).replace(/\s+$/,""):""},FormEngineValidation.parseDateTime=function(e){const n=e.indexOf(" ");if(-1!==n){const t=FormEngineValidation.parseDate(e.substr(n,e.length));FormEngineValidation.lastTime=t+FormEngineValidation.parseTime(e.substr(0,n),"time")}else FormEngineValidation.lastTime=FormEngineValidation.parseDate(e);return FormEngineValidation.lastTime},FormEngineValidation.parseDate=function(e){const n=new Date;let t=FormEngineValidation.split(e);if(t.values[1]&&t.values[1].length>2){const e=t.values[1];t=FormEngineValidation.splitSingle(e)}const a=t.values[3]?FormEngineValidation.parseInt(t.values[3]):FormEngineValidation.getYear(n),i=t.values[2]?FormEngineValidation.parseInt(t.values[2]):n.getUTCMonth()+1,o=t.values[1]?FormEngineValidation.parseInt(t.values[1]):n.getUTCDate(),r=moment.utc();return r.year(parseInt(a)).month(parseInt(i)-1).date(parseInt(o)).hour(0).minute(0).second(0),FormEngineValidation.lastDate=r.unix(),FormEngineValidation.lastDate},FormEngineValidation.parseTime=function(e,n){const t=new Date;let a=FormEngineValidation.split(e);if(a.values[1]&&a.values[1].length>2){const e=a.values[1];a=FormEngineValidation.splitSingle(e)}const i=a.values[3]?FormEngineValidation.parseInt(a.values[3]):t.getUTCSeconds(),o=a.values[2]?FormEngineValidation.parseInt(a.values[2]):t.getUTCMinutes(),r=a.values[1]?FormEngineValidation.parseInt(a.values[1]):t.getUTCHours(),l=moment.utc();return l.year(1970).month(0).date(1).hour(r).minute(o).second("timesec"===n?i:0),FormEngineValidation.lastTime=l.unix(),FormEngineValidation.lastTime<0&&(FormEngineValidation.lastTime+=86400),FormEngineValidation.lastTime},FormEngineValidation.parseYear=function(e){const n=new Date,t=FormEngineValidation.split(e);return FormEngineValidation.lastYear=t.values[1]?FormEngineValidation.parseInt(t.values[1]):FormEngineValidation.getYear(n),FormEngineValidation.lastYear},FormEngineValidation.getYear=function(e){return null===e?null:e.getUTCFullYear()},FormEngineValidation.getDate=function(e){const n=new Date(FormEngineValidation.getYear(e),e.getUTCMonth(),e.getUTCDate());return FormEngineValidation.getTimestamp(n)},FormEngineValidation.pol=function(foreign,value){return eval(("-"==foreign?"-":"")+value)},FormEngineValidation.convertClientTimestampToUTC=function(e,n){const t=new Date(1e3*e);return t.setTime(1e3*(e-60*t.getTimezoneOffset())),n?FormEngineValidation.getTime(t):FormEngineValidation.getTimestamp(t)},FormEngineValidation.getTimestamp=function(e){return Date.parse(e instanceof Date?e.toISOString():e)/1e3},FormEngineValidation.getTime=function(e){return 60*e.getUTCHours()*60+60*e.getUTCMinutes()+FormEngineValidation.getSecs(e)},FormEngineValidation.getSecs=function(e){return e.getUTCSeconds()},FormEngineValidation.getTimeSecs=function(e){return 60*e.getHours()*60+60*e.getMinutes()+e.getSeconds()},FormEngineValidation.markParentTab=function(e,n){e.parents(".tab-pane").each((function(e,t){const a=$(t);n&&(n=0===a.find(".has-error").length);const i=a.attr("id");$(document).find('a[href="#'+i+'"]').closest(".t3js-tabmenu-item").toggleClass("has-validation-error",!n)}))},FormEngineValidation.splitSingle=function(e){const n=""+e,t={values:[],pointer:3};return t.values[1]=n.substr(0,2),t.values[2]=n.substr(2,2),t.values[3]=n.substr(4,10),t},FormEngineValidation.splitStr=function(e,n,t){const a=""+e,i=n.length;let o=-i;t<1&&(t=1);for(let e=1;e<t;e++)if(o=a.indexOf(n,o+i),-1==o)return null;let r=a.indexOf(n,o+i);return-1==r&&(r=a.length),a.substring(o+i,r)},FormEngineValidation.split=function(e){const n={values:[],valPol:[],pointer:0,numberMode:0,theVal:""};e+=" ";for(let t=0;t<e.length;t++){const a=e.substr(t,1);a<"0"||a>"9"?(n.numberMode&&(n.pointer++,n.values[n.pointer]=n.theVal,n.theVal="",n.numberMode=0),"+"!=a&&"-"!=a||(n.valPol[n.pointer+1]=a)):(n.theVal+=a,n.numberMode=1)}return n},FormEngineValidation.registerSubmitCallback=function(){DocumentSaveActions.getInstance().addPreSubmitCallback((function(e){if($("."+FormEngineValidation.errorClass).length>0){const n=Modal.confirm(TYPO3.lang.alert||"Alert",TYPO3.lang["FormEngine.fieldsMissing"],Severity.error,[{text:TYPO3.lang["button.ok"]||"OK",active:!0,btnClass:"btn-default",name:"ok"}]);n.addEventListener("button.clicked",(()=>n.hideModal())),e.stopImmediatePropagation()}}))},FormEngineValidation}()); \ No newline at end of file +import $ from"jquery";import moment from"moment";import Md5 from"@typo3/backend/hashing/md5.js";import DocumentSaveActions from"@typo3/backend/document-save-actions.js";import Modal from"@typo3/backend/modal.js";import Severity from"@typo3/backend/severity.js";export default(function(){const FormEngineValidation={rulesSelector:"[data-formengine-validation-rules]",inputSelector:"[data-formengine-input-params]",markerSelector:".t3js-formengine-validation-marker",groupFieldHiddenElement:".t3js-formengine-field-group input[type=hidden]",relatedFieldSelector:"[data-relatedfieldname]",errorClass:"has-error",lastYear:0,lastDate:0,lastTime:0,passwordDummy:"********"},customEvaluations=new Map;return FormEngineValidation.initialize=function(){$(document).find("."+FormEngineValidation.errorClass).removeClass(FormEngineValidation.errorClass),FormEngineValidation.initializeInputFields().promise().done((function(){$(document).on("change",FormEngineValidation.rulesSelector,(e=>{FormEngineValidation.validateField(e.currentTarget),FormEngineValidation.markFieldAsChanged(e.currentTarget)})),FormEngineValidation.registerSubmitCallback()}));const e=new Date;FormEngineValidation.lastYear=FormEngineValidation.getYear(e),FormEngineValidation.lastDate=FormEngineValidation.getDate(e),FormEngineValidation.lastTime=0,FormEngineValidation.validate()},FormEngineValidation.initializeInputFields=function(){return $(document).find(FormEngineValidation.inputSelector).each((function(e,n){const t=$(n).data("formengine-input-params"),a=t.field,i=$('[name="'+a+'"]');void 0===i.data("main-field")&&(i.data("main-field",a),i.data("config",t),FormEngineValidation.initializeInputField(a))}))},FormEngineValidation.initializeInputField=function(e){const n=$('[name="'+e+'"]'),t=$('[data-formengine-input-name="'+e+'"]');let a=$('[name="'+n.data("main-field")+'"]');0===a.length&&(a=n);const i=a.data("config");if(void 0!==i){const e=FormEngineValidation.trimExplode(",",i.evalList);let a=n.val();for(let n=0;n<e.length;n++)a=FormEngineValidation.formatValue(e[n],a,i);a.length&&t.val(a)}t.data("main-field",e),t.data("config",i),t.on("change",(function(){FormEngineValidation.updateInputField(t.attr("data-formengine-input-name"))})),t.attr("data-formengine-input-initialized","true")},FormEngineValidation.registerCustomEvaluation=function(e,n){customEvaluations.has(e)||customEvaluations.set(e,n)},FormEngineValidation.formatValue=function(e,n,t){let a,i,o="";switch(e){case"date":if(n.toString().indexOf("-")>0){o=moment.utc(n).format("DD-MM-YYYY")}else{if(a=1*n,!a)return"";i=new Date(1e3*a);o=i.getUTCDate().toString(10).padStart(2,"0")+"-"+(i.getUTCMonth()+1).toString(10).padStart(2,"0")+"-"+this.getYear(i)}break;case"datetime":if(n.toString().indexOf("-")<=0&&!("number"==typeof n?n:parseInt(n)))return"";o=FormEngineValidation.formatValue("time",n,t)+" "+FormEngineValidation.formatValue("date",n,t);break;case"time":case"timesec":let r;if(n.toString().indexOf("-")>0)r=moment.utc(n);else{if(a="number"==typeof n?n:parseInt(n),!a&&"0"!==n.toString())return"";r=moment.unix(a).utc()}o="timesec"===e?r.format("HH:mm:ss"):r.format("HH:mm");break;case"password":o=n?FormEngineValidation.passwordDummy:"";break;default:o=n}return o},FormEngineValidation.updateInputField=function(e){const n=$('[name="'+e+'"]');let t=$('[name="'+n.data("main-field")+'"]');0===t.length&&(t=n);const a=$('[data-formengine-input-name="'+t.attr("name")+'"]'),i=t.data("config");if(void 0!==i){const e=FormEngineValidation.trimExplode(",",i.evalList);let n=a.val();for(let t=0;t<e.length;t++)n=FormEngineValidation.processValue(e[t],n,i);let o=n;for(let n=0;n<e.length;n++)o=FormEngineValidation.formatValue(e[n],o,i);t.val(n),t.get(0).dispatchEvent(new Event("change")),a.val(o)}},FormEngineValidation.validateField=function(e,n){const t=e instanceof $?e.get(0):e;if(n=n||t.value||"",void 0===t.dataset.formengineValidationRules)return n;const a=JSON.parse(t.dataset.formengineValidationRules);let i,o,r,l=!1,s=0,m=n;$.isArray(n)||(n=FormEngineValidation.ltrim(n)),$.each(a,(function(e,a){if(l)return!1;switch(a.type){case"required":""===n&&(l=!0,t.closest(FormEngineValidation.markerSelector).classList.add(FormEngineValidation.errorClass));break;case"range":if(""!==n){if((a.minItems||a.maxItems)&&(i=$(document).find('[name="'+t.dataset.relatedfieldname+'"]'),s=i.length?FormEngineValidation.trimExplode(",",i.val()).length:t.value,void 0!==a.minItems&&(o=1*a.minItems,!isNaN(o)&&s<o&&(l=!0)),void 0!==a.maxItems&&(r=1*a.maxItems,!isNaN(r)&&s>r&&(l=!0))),void 0!==a.lower){const e=1*a.lower;!isNaN(e)&&n<e&&(l=!0)}if(void 0!==a.upper){const e=1*a.upper;!isNaN(e)&&n>e&&(l=!0)}}break;case"select":case"category":(a.minItems||a.maxItems)&&(i=$(document).find('[name="'+t.dataset.relatedfieldname+'"]'),s=i.length?FormEngineValidation.trimExplode(",",i.val()).length:t instanceof HTMLSelectElement?t.querySelectorAll("option:checked").length:t.querySelectorAll("input[value]:checked").length,void 0!==a.minItems&&(o=1*a.minItems,!isNaN(o)&&s<o&&(l=!0)),void 0!==a.maxItems&&(r=1*a.maxItems,!isNaN(r)&&s>r&&(l=!0)));break;case"group":case"inline":(a.minItems||a.maxItems)&&(s=FormEngineValidation.trimExplode(",",t.value).length,void 0!==a.minItems&&(o=1*a.minItems,!isNaN(o)&&s<o&&(l=!0)),void 0!==a.maxItems&&(r=1*a.maxItems,!isNaN(r)&&s>r&&(l=!0)));break;case"min":(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement)&&t.value.length>0&&t.value.length<t.minLength&&(l=!0)}}));const d=!l,g=t.closest(FormEngineValidation.markerSelector);return null!==g&&g.classList.toggle(FormEngineValidation.errorClass,!d),FormEngineValidation.markParentTab($(t),d),$(document).trigger("t3-formengine-postfieldvalidation"),m},FormEngineValidation.processValue=function(e,n,t){let a="",i="",o="",r=0,l=n;switch(e){case"alpha":case"num":case"alphanum":case"alphanum_x":for(a="",r=0;r<n.length;r++){const t=n.substr(r,1);let i="_"===t||"-"===t,o=t>="a"&&t<="z"||t>="A"&&t<="Z",l=t>="0"&&t<="9";switch(e){case"alphanum":i=!1;break;case"alpha":l=!1,i=!1;break;case"num":o=!1,i=!1}(o||l||i)&&(a+=t)}a!==n&&(l=a);break;case"is_in":if(t.is_in){i=""+n,t.is_in=t.is_in.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&");const e=new RegExp("[^"+t.is_in+"]+","g");a=i.replace(e,"")}else a=i;l=a;break;case"nospace":l=(""+n).replace(/ /g,"");break;case"md5":""!==n&&(l=Md5.hash(n));break;case"upper":l=n.toUpperCase();break;case"lower":l=n.toLowerCase();break;case"integer":""!==n&&(l=FormEngineValidation.parseInt(n));break;case"decimal":""!==n&&(l=FormEngineValidation.parseDouble(n));break;case"trim":l=String(n).trim();break;case"datetime":""!==n&&(o=n.substr(0,1),l=FormEngineValidation.parseDateTime(n));break;case"date":""!==n&&(o=n.substr(0,1),l=FormEngineValidation.parseDate(n));break;case"time":case"timesec":""!==n&&(o=n.substr(0,1),l=FormEngineValidation.parseTime(n,e));break;case"year":""!==n&&(o=n.substr(0,1),l=FormEngineValidation.parseYear(n));break;case"null":case"password":break;default:customEvaluations.has(e)?l=customEvaluations.get(e).call(null,n):"object"==typeof TBE_EDITOR&&void 0!==TBE_EDITOR.customEvalFunctions&&"function"==typeof TBE_EDITOR.customEvalFunctions[e]&&(l=TBE_EDITOR.customEvalFunctions[e](n))}return l},FormEngineValidation.validate=function(e){(void 0===e||e instanceof Document)&&$(document).find(FormEngineValidation.markerSelector+", .t3js-tabmenu-item").removeClass(FormEngineValidation.errorClass).removeClass("has-validation-error");const n=e||document;$(n).find(FormEngineValidation.rulesSelector).each(((e,n)=>{const t=$(n);if(!t.closest(".t3js-flex-section-deleted, .t3js-inline-record-deleted, .t3js-file-reference-deleted").length){let e=!1;const n=t.val(),a=FormEngineValidation.validateField(t,n);if($.isArray(a)&&$.isArray(n)){if(a.length!==n.length)e=!0;else for(let t=0;t<a.length;t++)if(a[t]!==n[t]){e=!0;break}}else a.length&&n!==a&&(e=!0);e&&t.val(a)}}))},FormEngineValidation.markFieldAsChanged=function(e){if(e instanceof $&&(e=e.get(0)),!(e instanceof HTMLElement))return;const n=e.closest(".t3js-formengine-palette-field");null!==n&&n.classList.add("has-change")},FormEngineValidation.trimExplode=function(e,n){const t=[],a=n.split(e);for(let e=0;e<a.length;e++){const n=a[e].trim();n.length>0&&t.push(n)}return t},FormEngineValidation.parseInt=function(e){let n;return e?(n=parseInt(""+e,10),isNaN(n)?0:n):0},FormEngineValidation.parseDouble=function(e,n=2){let t=""+e;t=t.replace(/[^0-9,\.-]/g,"");const a="-"===t.substring(0,1);t=t.replace(/-/g,""),t=t.replace(/,/g,"."),-1===t.indexOf(".")&&(t+=".0");const i=t.split("."),o=i.pop();let r=Number(i.join("")+"."+o);return a&&(r*=-1),t=r.toFixed(n),t},FormEngineValidation.ltrim=function(e){return e?(""+e).replace(/^\s+/,""):""},FormEngineValidation.btrim=function(e){return e?(""+e).replace(/\s+$/,""):""},FormEngineValidation.parseDateTime=function(e){const n=e.indexOf(" ");if(-1!==n){const t=FormEngineValidation.parseDate(e.substr(n,e.length));FormEngineValidation.lastTime=t+FormEngineValidation.parseTime(e.substr(0,n),"time")}else FormEngineValidation.lastTime=FormEngineValidation.parseDate(e);return FormEngineValidation.lastTime},FormEngineValidation.parseDate=function(e){const n=new Date;let t=FormEngineValidation.split(e);if(t.values[1]&&t.values[1].length>2){const e=t.values[1];t=FormEngineValidation.splitSingle(e)}const a=t.values[3]?FormEngineValidation.parseInt(t.values[3]):FormEngineValidation.getYear(n),i=t.values[2]?FormEngineValidation.parseInt(t.values[2]):n.getUTCMonth()+1,o=t.values[1]?FormEngineValidation.parseInt(t.values[1]):n.getUTCDate(),r=moment.utc();return r.year(parseInt(a)).month(parseInt(i)-1).date(parseInt(o)).hour(0).minute(0).second(0),FormEngineValidation.lastDate=r.unix(),FormEngineValidation.lastDate},FormEngineValidation.parseTime=function(e,n){const t=new Date;let a=FormEngineValidation.split(e);if(a.values[1]&&a.values[1].length>2){const e=a.values[1];a=FormEngineValidation.splitSingle(e)}const i=a.values[3]?FormEngineValidation.parseInt(a.values[3]):t.getUTCSeconds(),o=a.values[2]?FormEngineValidation.parseInt(a.values[2]):t.getUTCMinutes(),r=a.values[1]?FormEngineValidation.parseInt(a.values[1]):t.getUTCHours(),l=moment.utc();return l.year(1970).month(0).date(1).hour(r).minute(o).second("timesec"===n?i:0),FormEngineValidation.lastTime=l.unix(),FormEngineValidation.lastTime<0&&(FormEngineValidation.lastTime+=86400),FormEngineValidation.lastTime},FormEngineValidation.parseYear=function(e){const n=new Date,t=FormEngineValidation.split(e);return FormEngineValidation.lastYear=t.values[1]?FormEngineValidation.parseInt(t.values[1]):FormEngineValidation.getYear(n),FormEngineValidation.lastYear},FormEngineValidation.getYear=function(e){return null===e?null:e.getUTCFullYear()},FormEngineValidation.getDate=function(e){const n=new Date(FormEngineValidation.getYear(e),e.getUTCMonth(),e.getUTCDate());return FormEngineValidation.getTimestamp(n)},FormEngineValidation.pol=function(foreign,value){return eval(("-"==foreign?"-":"")+value)},FormEngineValidation.convertClientTimestampToUTC=function(e,n){const t=new Date(1e3*e);return t.setTime(1e3*(e-60*t.getTimezoneOffset())),n?FormEngineValidation.getTime(t):FormEngineValidation.getTimestamp(t)},FormEngineValidation.getTimestamp=function(e){return Date.parse(e instanceof Date?e.toISOString():e)/1e3},FormEngineValidation.getTime=function(e){return 60*e.getUTCHours()*60+60*e.getUTCMinutes()+FormEngineValidation.getSecs(e)},FormEngineValidation.getSecs=function(e){return e.getUTCSeconds()},FormEngineValidation.getTimeSecs=function(e){return 60*e.getHours()*60+60*e.getMinutes()+e.getSeconds()},FormEngineValidation.markParentTab=function(e,n){e.parents(".tab-pane").each((function(e,t){const a=$(t);n&&(n=0===a.find(".has-error").length);const i=a.attr("id");$(document).find('a[href="#'+i+'"]').closest(".t3js-tabmenu-item").toggleClass("has-validation-error",!n)}))},FormEngineValidation.splitSingle=function(e){const n=""+e,t={values:[],pointer:3};return t.values[1]=n.substr(0,2),t.values[2]=n.substr(2,2),t.values[3]=n.substr(4,10),t},FormEngineValidation.splitStr=function(e,n,t){const a=""+e,i=n.length;let o=-i;t<1&&(t=1);for(let e=1;e<t;e++)if(o=a.indexOf(n,o+i),-1==o)return null;let r=a.indexOf(n,o+i);return-1==r&&(r=a.length),a.substring(o+i,r)},FormEngineValidation.split=function(e){const n={values:[],valPol:[],pointer:0,numberMode:0,theVal:""};e+=" ";for(let t=0;t<e.length;t++){const a=e.substr(t,1);a<"0"||a>"9"?(n.numberMode&&(n.pointer++,n.values[n.pointer]=n.theVal,n.theVal="",n.numberMode=0),"+"!=a&&"-"!=a||(n.valPol[n.pointer+1]=a)):(n.theVal+=a,n.numberMode=1)}return n},FormEngineValidation.registerSubmitCallback=function(){DocumentSaveActions.getInstance().addPreSubmitCallback((function(e){if($("."+FormEngineValidation.errorClass).length>0){const n=Modal.confirm(TYPO3.lang.alert||"Alert",TYPO3.lang["FormEngine.fieldsMissing"],Severity.error,[{text:TYPO3.lang["button.ok"]||"OK",active:!0,btnClass:"btn-default",name:"ok"}]);n.addEventListener("button.clicked",(()=>n.hideModal())),e.stopImmediatePropagation()}}))},FormEngineValidation}()); \ No newline at end of file diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/container/files-control-container.js b/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/container/files-control-container.js new file mode 100644 index 0000000000000000000000000000000000000000..d3579e1785a27e6aebf1dfada60ef4ce43ae377d --- /dev/null +++ b/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/container/files-control-container.js @@ -0,0 +1,13 @@ +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ +import{MessageUtility}from"@typo3/backend/utility/message-utility.js";import{AjaxDispatcher}from"@typo3/backend/form-engine/inline-relation/ajax-dispatcher.js";import NProgress from"nprogress";import Sortable from"sortablejs";import FormEngine from"@typo3/backend/form-engine.js";import FormEngineValidation from"@typo3/backend/form-engine-validation.js";import Icons from"@typo3/backend/icons.js";import InfoWindow from"@typo3/backend/info-window.js";import Modal from"@typo3/backend/modal.js";import RegularEvent from"@typo3/core/event/regular-event.js";import Severity from"@typo3/backend/severity.js";import Utility from"@typo3/backend/utility.js";var Selectors,States,Separators,SortDirections;!function(e){e.toggleSelector='[data-bs-toggle="formengine-file"]',e.controlSectionSelector=".t3js-formengine-file-header-control",e.deleteRecordButtonSelector=".t3js-editform-delete-file-reference",e.enableDisableRecordButtonSelector=".t3js-toggle-visibility-button",e.infoWindowButton='[data-action="infowindow"]',e.synchronizeLocalizeRecordButtonSelector=".t3js-synchronizelocalize-button",e.controlContainer=".t3js-file-controls"}(Selectors||(Selectors={})),function(e){e.new="isNewFileReference",e.visible="panel-visible",e.collapsed="panel-collapsed",e.notLoaded="t3js-not-loaded"}(States||(States={})),function(e){e.structureSeparator="-"}(Separators||(Separators={})),function(e){e.DOWN="down",e.UP="up"}(SortDirections||(SortDirections={}));class FilesControlContainer extends HTMLElement{constructor(){super(...arguments),this.container=null,this.ajaxDispatcher=null,this.appearance=null,this.requestQueue={},this.progessQueue={},this.noTitleString=TYPO3.lang?TYPO3.lang["FormEngine.noRecordTitle"]:"[No title]",this.handlePostMessage=e=>{if(!MessageUtility.verifyOrigin(e.origin))throw"Denied message sent by "+e.origin;if("typo3:foreignRelation:insert"===e.data.actionName){if(void 0===e.data.objectGroup)throw"No object group defined for message";if(e.data.objectGroup!==this.container.dataset.objectGroup)return;this.importRecord([e.data.objectGroup,e.data.uid]).then((()=>{if(e.source){const t={actionName:"typo3:foreignRelation:inserted",objectGroup:e.data.objectId,table:e.data.table,uid:e.data.uid};MessageUtility.send(t,e.source)}}))}}}static getFileReferenceContainer(e){return document.querySelector('[data-object-id="'+e+'"]')}static getCollapseButton(e){return document.querySelector('[aria-controls="'+e+'_fields"]')}static toggleElement(e){const t=FilesControlContainer.getFileReferenceContainer(e);t.classList.contains(States.collapsed)?FilesControlContainer.expandElement(t,e):FilesControlContainer.collapseElement(t,e)}static collapseElement(e,t){const n=FilesControlContainer.getCollapseButton(t);e.classList.remove(States.visible),e.classList.add(States.collapsed),n.setAttribute("aria-expanded","false")}static expandElement(e,t){const n=FilesControlContainer.getCollapseButton(t);e.classList.remove(States.collapsed),e.classList.add(States.visible),n.setAttribute("aria-expanded","true")}static isNewRecord(e){return FilesControlContainer.getFileReferenceContainer(e).classList.contains(States.new)}static updateExpandedCollapsedStateLocally(e,t){const n=FilesControlContainer.getFileReferenceContainer(e),o=document.getElementsByName("uc[inlineView]["+n.dataset.topmostParentTable+"]["+n.dataset.topmostParentUid+"]"+n.dataset.fieldName);o.length&&(o[0].value=t?"1":"0")}connectedCallback(){const e=this.getAttribute("identifier")||"";this.container=this.querySelector("#"+e),null!==this.container&&(this.ajaxDispatcher=new AjaxDispatcher(this.container.dataset.objectGroup),this.registerEvents())}registerEvents(){if(this.registerInfoButton(),this.registerSort(),this.registerEnableDisableButton(),this.registerDeleteButton(),this.registerSynchronizeLocalize(),this.registerToggle(),new RegularEvent("message",this.handlePostMessage).bindTo(window),this.getAppearance().useSortable){const e=document.getElementById(this.container.getAttribute("id")+"_records");new Sortable(e,{group:e.getAttribute("id"),handle:".sortableHandle",onSort:()=>{this.updateSorting()}})}}registerToggle(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation(),e.loadRecordDetails(this.closest(Selectors.toggleSelector).parentElement.dataset.objectId)})).delegateTo(this.container,`${Selectors.toggleSelector} .form-irre-header-cell:not(${Selectors.controlSectionSelector}`)}registerSort(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation(),e.changeSortingByButton(this.closest("[data-object-id]").dataset.objectId,this.dataset.direction)})).delegateTo(this.container,Selectors.controlSectionSelector+' [data-action="sort"]')}createRecord(e,t,n=null,o=null){let i=this.container.dataset.objectGroup;null!==n&&(i+=Separators.structureSeparator+n),null!==n?(FilesControlContainer.getFileReferenceContainer(i).insertAdjacentHTML("afterend",t),this.memorizeAddRecord(e,n,o)):(document.getElementById(this.container.getAttribute("id")+"_records").insertAdjacentHTML("beforeend",t),this.memorizeAddRecord(e,null,o))}async importRecord(e,t){return this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("file_reference_create")),e).then((async e=>{this.isBelowMax()&&this.createRecord(e.compilerInput.uid,e.data,void 0!==t?t:null,void 0!==e.compilerInput.childChildUid?e.compilerInput.childChildUid:null)}))}registerEnableDisableButton(){new RegularEvent("click",((e,t)=>{e.preventDefault(),e.stopImmediatePropagation();const n=t.closest("[data-object-id]").dataset.objectId,o=FilesControlContainer.getFileReferenceContainer(n),i="data"+o.dataset.fieldName+"["+t.dataset.hiddenField+"]",r=document.querySelector('[data-formengine-input-name="'+i+'"'),a=document.querySelector('[name="'+i+'"');null!==r&&null!==a&&(r.checked=!r.checked,a.value=r.checked?"1":"0",FormEngineValidation.markFieldAsChanged(r));const s="t3-form-field-container-inline-hidden";let l;o.classList.contains(s)?(l="actions-edit-hide",o.classList.remove(s)):(l="actions-edit-unhide",o.classList.add(s)),Icons.getIcon(l,Icons.sizes.small).then((e=>{t.replaceChild(document.createRange().createContextualFragment(e),t.querySelector(".t3js-icon"))}))})).delegateTo(this.container,Selectors.enableDisableRecordButtonSelector)}registerInfoButton(){new RegularEvent("click",(function(e){e.preventDefault(),e.stopImmediatePropagation(),InfoWindow.showItem(this.dataset.infoTable,this.dataset.infoUid)})).delegateTo(this.container,Selectors.infoWindowButton)}registerDeleteButton(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation();const n=TYPO3.lang["label.confirm.delete_record.title"]||"Delete this record?",o=TYPO3.lang["label.confirm.delete_record.content"]||"Are you sure you want to delete this record?";Modal.confirm(n,o,Severity.warning,[{text:TYPO3.lang["buttons.confirm.delete_record.no"]||"Cancel",active:!0,btnClass:"btn-default",name:"no",trigger:(e,t)=>t.hideModal()},{text:TYPO3.lang["buttons.confirm.delete_record.yes"]||"Yes, delete this record",btnClass:"btn-warning",name:"yes",trigger:(t,n)=>{e.deleteRecord(this.closest("[data-object-id]").dataset.objectId),n.hideModal()}}])})).delegateTo(this.container,Selectors.deleteRecordButtonSelector)}registerSynchronizeLocalize(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation(),e.ajaxDispatcher.send(e.ajaxDispatcher.newRequest(e.ajaxDispatcher.getEndpoint("file_reference_synchronizelocalize")),[e.container.dataset.objectGroup,this.dataset.type]).then((async t=>{document.getElementById(e.container.getAttribute("id")+"_records").insertAdjacentHTML("beforeend",t.data);const n=e.container.dataset.objectGroup+Separators.structureSeparator;for(let o of t.compilerInput.delete)e.deleteRecord(n+o,!0);for(let o of Object.values(t.compilerInput.localize)){if(void 0!==o.remove){const e=FilesControlContainer.getFileReferenceContainer(n+o.remove);e.parentElement.removeChild(e)}e.memorizeAddRecord(o.uid,null,o.selectedValue)}}))})).delegateTo(this.container,Selectors.synchronizeLocalizeRecordButtonSelector)}loadRecordDetails(e){const t=document.getElementById(e+"_fields"),n=FilesControlContainer.getFileReferenceContainer(e),o=void 0!==this.requestQueue[e];if(null!==t&&!n.classList.contains(States.notLoaded))this.collapseExpandRecord(e);else{const i=this.getProgress(e,n.dataset.objectIdHash);if(o)this.requestQueue[e].abort(),delete this.requestQueue[e],delete this.progessQueue[e],i.done();else{const o=this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("file_reference_details"));this.ajaxDispatcher.send(o,[e]).then((async o=>{delete this.requestQueue[e],delete this.progessQueue[e],n.classList.remove(States.notLoaded),t.innerHTML=o.data,this.collapseExpandRecord(e),i.done(),FormEngine.reinitialize(),FormEngineValidation.initializeInputFields(),FormEngineValidation.validate(this.container)})),this.requestQueue[e]=o,i.start()}}}collapseExpandRecord(e){const t=FilesControlContainer.getFileReferenceContainer(e),n=!0===this.getAppearance().expandSingle,o=t.classList.contains(States.collapsed);let i=[];const r=[];n&&o&&(i=this.collapseAllRecords(t.dataset.objectUid)),FilesControlContainer.toggleElement(e),FilesControlContainer.isNewRecord(e)?FilesControlContainer.updateExpandedCollapsedStateLocally(e,o):o?r.push(t.dataset.objectUid):o||i.push(t.dataset.objectUid),this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("file_reference_expandcollapse")),[e,r.join(","),i.join(",")])}memorizeAddRecord(e,t=null,n=null){const o=this.getFormFieldForElements();if(null===o)return;let i=Utility.trimExplode(",",o.value);if(t){const n=[];for(let o=0;o<i.length;o++)i[o].length&&n.push(i[o]),t===i[o]&&n.push(e);i=n}else i.push(e);o.value=i.join(","),o.classList.add("has-change"),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,i),this.isBelowMax()||this.toggleContainerControls(!1),FormEngine.reinitialize(),FormEngineValidation.initializeInputFields(),FormEngineValidation.validate(this.container)}memorizeRemoveRecord(e){const t=this.getFormFieldForElements();if(null===t)return[];let n=Utility.trimExplode(",",t.value);const o=n.indexOf(e);return o>-1&&(delete n[o],t.value=n.join(","),t.classList.add("has-change"),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,n)),n}changeSortingByButton(e,t){const n=FilesControlContainer.getFileReferenceContainer(e),o=n.dataset.objectUid,i=document.getElementById(this.container.getAttribute("id")+"_records"),r=Array.from(i.children).map((e=>e.dataset.objectUid));let a=r.indexOf(o),s=!1;if(t===SortDirections.UP&&a>0?(r[a]=r[a-1],r[a-1]=o,s=!0):t===SortDirections.DOWN&&a<r.length-1&&(r[a]=r[a+1],r[a+1]=o,s=!0),s){const e=this.container.dataset.objectGroup+Separators.structureSeparator,o=t===SortDirections.UP?1:0;n.parentElement.insertBefore(FilesControlContainer.getFileReferenceContainer(e+r[a-o]),FilesControlContainer.getFileReferenceContainer(e+r[a+1-o])),this.updateSorting()}}updateSorting(){const e=this.getFormFieldForElements();if(null===e)return;const t=document.getElementById(this.container.getAttribute("id")+"_records"),n=Array.from(t.querySelectorAll('[data-object-parent-group="'+this.container.dataset.objectGroup+'"][data-placeholder-record="0"]')).map((e=>e.dataset.objectUid));e.value=n.join(","),e.classList.add("has-change"),document.dispatchEvent(new Event("formengine:files:sorting-changed")),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,n)}deleteRecord(e,t=!1){const n=FilesControlContainer.getFileReferenceContainer(e),o=n.dataset.objectUid;if(n.classList.add("t3js-file-reference-deleted"),!FilesControlContainer.isNewRecord(e)&&!t){const e=this.container.querySelector('[name="cmd'+n.dataset.fieldName+'[delete]"]');e.removeAttribute("disabled"),n.parentElement.insertAdjacentElement("afterbegin",e)}new RegularEvent("transitionend",(()=>{n.parentElement.removeChild(n),FormEngineValidation.validate(this.container)})).bindTo(n),this.memorizeRemoveRecord(o),n.classList.add("form-irre-object--deleted"),this.isBelowMax()&&this.toggleContainerControls(!0)}toggleContainerControls(e){const t=this.container.querySelector(Selectors.controlContainer);if(null===t)return;t.querySelectorAll("button, a").forEach((t=>{t.style.display=e?null:"none"}))}getProgress(e,t){const n="#"+t+"_header";let o;return void 0!==this.progessQueue[e]?o=this.progessQueue[e]:(o=NProgress,o.configure({parent:n,showSpinner:!1}),this.progessQueue[e]=o),o}collapseAllRecords(e){const t=this.getFormFieldForElements(),n=[];if(null!==t){const o=Utility.trimExplode(",",t.value);for(let t of o){if(t===e)continue;const o=this.container.dataset.objectGroup+Separators.structureSeparator+t,i=FilesControlContainer.getFileReferenceContainer(o);i.classList.contains(States.visible)&&(FilesControlContainer.collapseElement(i,o),FilesControlContainer.isNewRecord(o)?FilesControlContainer.updateExpandedCollapsedStateLocally(o,!1):n.push(t))}}return n}getFormFieldForElements(){const e=document.getElementsByName(this.container.dataset.formField);return e.length>0?e[0]:null}redrawSortingButtons(e,t=[]){if(0===t.length){const e=this.getFormFieldForElements();null!==e&&(t=Utility.trimExplode(",",e.value))}0!==t.length&&t.forEach(((n,o)=>{const i=FilesControlContainer.getFileReferenceContainer(e+Separators.structureSeparator+n).dataset.objectIdHash+"_header",r=document.getElementById(i),a=r.querySelector('[data-action="sort"][data-direction="'+SortDirections.UP+'"]');if(null!==a){let e="actions-move-up";0===o?(a.classList.add("disabled"),e="empty-empty"):a.classList.remove("disabled"),Icons.getIcon(e,Icons.sizes.small).then((e=>{a.replaceChild(document.createRange().createContextualFragment(e),a.querySelector(".t3js-icon"))}))}const s=r.querySelector('[data-action="sort"][data-direction="'+SortDirections.DOWN+'"]');if(null!==s){let e="actions-move-down";o===t.length-1?(s.classList.add("disabled"),e="empty-empty"):s.classList.remove("disabled"),Icons.getIcon(e,Icons.sizes.small).then((e=>{s.replaceChild(document.createRange().createContextualFragment(e),s.querySelector(".t3js-icon"))}))}}))}isBelowMax(){const e=this.getFormFieldForElements();if(null===e)return!0;if(void 0!==TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup]){if(Utility.trimExplode(",",e.value).length>=TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup].max)return!1}return!0}getAppearance(){if(null===this.appearance&&(this.appearance={},"string"==typeof this.container.dataset.appearance))try{this.appearance=JSON.parse(this.container.dataset.appearance)}catch(e){console.error(e)}return this.appearance}}window.customElements.define("typo3-formengine-container-files",FilesControlContainer); \ No newline at end of file diff --git a/typo3/sysext/backend/Tests/Unit/Form/FieldControl/ElementBrowserTest.php b/typo3/sysext/backend/Tests/Unit/Form/FieldControl/ElementBrowserTest.php index f9c078dbc8c24be573ddde2a4c9e4f8b2de15e9b..a270e717efbd2e1e1c013c9199d9fbf34e0127de 100644 --- a/typo3/sysext/backend/Tests/Unit/Form/FieldControl/ElementBrowserTest.php +++ b/typo3/sysext/backend/Tests/Unit/Form/FieldControl/ElementBrowserTest.php @@ -56,7 +56,7 @@ class ElementBrowserTest extends UnitTestCase /** * @test */ - public function renderTrimsAllowedValuesFromAppearanceSection(): void + public function renderTrimsAllowedValues(): void { $nodeFactory = $this->prophesize(NodeFactory::class); $elementBrowser = new ElementBrowser($nodeFactory->reveal(), [ @@ -68,16 +68,14 @@ class ElementBrowserTest extends UnitTestCase 'itemFormElName' => '', 'fieldConf' => [ 'config' => [ - 'type' => 'group', - 'appearance' => [ - 'elementBrowserAllowed' => 'be_users, be_groups', - ], + 'type' => 'file', + 'allowed' => 'jpg, png', ], ], ], ]); $result = $elementBrowser->render(); - self::assertSame($result['linkAttributes']['data-params'], '|||be_users,be_groups|'); + self::assertSame($result['linkAttributes']['data-params'], '|||jpg,png|'); } /** diff --git a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/InlineOverrideChildTcaTest.php b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/InlineOverrideChildTcaTest.php index fc294383b58a64fbbeb624e9cc957c8ec4354f33..706db951ab2539db16e79b09f6253a5d0f18b242 100644 --- a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/InlineOverrideChildTcaTest.php +++ b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/InlineOverrideChildTcaTest.php @@ -119,8 +119,8 @@ class InlineOverrideChildTcaTest extends UnitTestCase 'aGivenSetting' => 'overrideValue', 'aNewSetting' => 'anotherNewValue', 'appearance' => [ - 'elementBrowserType' => 'file', - 'elementBrowserAllowed' => 'jpg,png', + 'useSortable' => true, + 'showPossibleLocalizationRecords' => false, ], ], ], @@ -135,7 +135,7 @@ class InlineOverrideChildTcaTest extends UnitTestCase 'aGivenSetting' => 'aValue', 'doNotChangeMe' => 'doNotChangeMe', 'appearance' => [ - 'elementBrowserType' => 'db', + 'useSortable' => false, ], ], ], @@ -150,8 +150,8 @@ class InlineOverrideChildTcaTest extends UnitTestCase 'aGivenSetting' => 'overrideValue', 'doNotChangeMe' => 'doNotChangeMe', 'appearance' => [ - 'elementBrowserType' => 'file', - 'elementBrowserAllowed' => 'jpg,png', + 'useSortable' => true, + 'showPossibleLocalizationRecords' => false, ], 'aNewSetting' => 'anotherNewValue', ], diff --git a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaInlineConfigurationTest.php b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaInlineConfigurationTest.php index 81496b5a5a8f48a3de2c8942bf0aa5b093d91ec3..1e4e3851275d7907f8fa42ced59da0333588df27 100644 --- a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaInlineConfigurationTest.php +++ b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaInlineConfigurationTest.php @@ -572,8 +572,7 @@ class TcaInlineConfigurationTest extends UnitTestCase 'aGivenSetting' => 'aOverrideValue', 'aNewSetting' => 'aNewSetting', 'appearance' => [ - 'elementBrowserType' => 'file', - 'elementBrowserAllowed' => 'jpg,png', + 'useSortable' => true, ], ], ], @@ -602,8 +601,7 @@ class TcaInlineConfigurationTest extends UnitTestCase 'aGivenSetting' => 'aOverrideValue', 'aNewSetting' => 'aNewSetting', 'appearance' => [ - 'elementBrowserType' => 'file', - 'elementBrowserAllowed' => 'jpg,png', + 'useSortable' => true, ], ], ]; @@ -619,8 +617,7 @@ class TcaInlineConfigurationTest extends UnitTestCase 'aGivenSetting' => 'aOverrideValue', 'aNewSetting' => 'aNewSetting', 'appearance' => [ - 'elementBrowserType' => 'file', - 'elementBrowserAllowed' => 'jpg,png', + 'useSortable' => true, ], ], 'foreignTable' => 'anotherForeignTableName', diff --git a/typo3/sysext/backend/Tests/Unit/Utility/BackendUtilityTest.php b/typo3/sysext/backend/Tests/Unit/Utility/BackendUtilityTest.php index a7d29c556d9ba5a546b82b696a4fff52527fc1f2..51a761c25c0c6947d212d6f08c163b0c05ca385c 100644 --- a/typo3/sysext/backend/Tests/Unit/Utility/BackendUtilityTest.php +++ b/typo3/sysext/backend/Tests/Unit/Utility/BackendUtilityTest.php @@ -1201,14 +1201,14 @@ class BackendUtilityTest extends UnitTestCase '', 42, $tableName, - ['type' => 'inline', 'foreign_table' => 'sys_file_reference'] + ['type' => 'file', 'foreign_table' => 'sys_file_reference'] )->shouldBeCalled(); $relationHandlerProphecy->processDeletePlaceholder()->shouldBeCalled(); $relationHandler = $relationHandlerProphecy->reveal(); $relationHandler->tableArray = ['sys_file_reference' => []]; GeneralUtility::addInstance(RelationHandler::class, $relationHandler); $GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config'] = [ - 'type' => 'inline', + 'type' => 'file', 'foreign_table' => 'sys_file_reference', ]; $elementData = [ diff --git a/typo3/sysext/core/Classes/Configuration/FlexForm/FlexFormTools.php b/typo3/sysext/core/Classes/Configuration/FlexForm/FlexFormTools.php index 1bd0d8c9e0d3a00f8872370b01fcfd1d383aff4c..0f1ef2368ed412afba4d30d4f05f6c8ceb683ae3 100644 --- a/typo3/sysext/core/Classes/Configuration/FlexForm/FlexFormTools.php +++ b/typo3/sysext/core/Classes/Configuration/FlexForm/FlexFormTools.php @@ -33,6 +33,7 @@ use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidSinglePointerFieldExc use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidTcaException; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; +use TYPO3\CMS\Core\Preparations\TcaPreparation; use TYPO3\CMS\Core\Utility\ArrayUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\MathUtility; @@ -716,7 +717,9 @@ class FlexFormTools $dataStructure = $this->removeElementTceFormsRecursive($dataStructure); if (is_array($dataStructure['sheets'][$sheetName])) { + // @todo Use TcaMigration and TcaPreparation instead of duplicating the code $dataStructure['sheets'][$sheetName] = $this->prepareCategoryFields($dataStructure['sheets'][$sheetName]); + $dataStructure['sheets'][$sheetName] = $this->prepareFileFields($dataStructure['sheets'][$sheetName]); } } } @@ -999,6 +1002,57 @@ class FlexFormTools return $dataStructurSheets; } + /** + * Prepare type=file fields if given. + * + * @param array $dataStructurSheets + * @return array The processed $dataStructureSheets + */ + protected function prepareFileFields(array $dataStructurSheets): array + { + if ($dataStructurSheets === []) { + // Early return in case the no sheets are given + return $dataStructurSheets; + } + + foreach ($dataStructurSheets as &$structure) { + if (!is_array($structure['el'] ?? false) || $structure['el'] === []) { + // Skip if no elements (fields) are defined + continue; + } + foreach ($structure['el'] as $fieldName => &$fieldConfig) { + if (($fieldConfig['config']['type'] ?? '') !== 'file') { + // Skip if type is not "file" + continue; + } + + $fieldConfig['config'] = array_replace_recursive( + $fieldConfig['config'], + [ + 'foreign_table' => 'sys_file_reference', + 'foreign_field' => 'uid_foreign', + 'foreign_sortby' => 'sorting_foreign', + 'foreign_table_field' => 'tablenames', + 'foreign_match_fields' => [ + 'fieldname' => $fieldName, + ], + 'foreign_label' => 'uid_local', + 'foreign_selector' => 'uid_local', + ] + ); + + if (!empty(($allowed = ($fieldConfig['config']['allowed'] ?? null)))) { + $fieldConfig['config']['allowed'] = TcaPreparation::prepareFileExtensions($allowed); + } + if (!empty(($disallowed = ($fieldConfig['config']['disallowed'] ?? null)))) { + $fieldConfig['config']['disallowed'] = TcaPreparation::prepareFileExtensions($disallowed); + } + } + } + + return $dataStructurSheets; + } + /** * Remove "TCEforms" key from all elements in data structure to simplify further parsing. * diff --git a/typo3/sysext/core/Classes/DataHandling/DataHandler.php b/typo3/sysext/core/Classes/DataHandling/DataHandler.php index f09884b08e2906cde7837a39602cd491ad155d12..98d9687a3b204f5bf5e482076a98776b6f2e07ef 100644 --- a/typo3/sysext/core/Classes/DataHandling/DataHandler.php +++ b/typo3/sysext/core/Classes/DataHandling/DataHandler.php @@ -54,6 +54,7 @@ use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Log\LogDataTrait; use TYPO3\CMS\Core\Messaging\FlashMessage; use TYPO3\CMS\Core\Messaging\FlashMessageService; +use TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter; use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Service\OpcodeCacheService; use TYPO3\CMS\Core\Site\Entity\SiteLanguage; @@ -1497,6 +1498,7 @@ class DataHandler implements LoggerAwareInterface 'email' => $this->checkValueForEmail((string)$value, $tcaFieldConf, $table, $id, (int)$realPid, $checkField), 'flex' => $field ? $this->checkValueForFlex($res, $value, $tcaFieldConf, $table, $id, $curValue, $status, $realPid, $recFID, $tscPID, $field) : [], 'inline' => $this->checkValueForInline($res, $value, $tcaFieldConf, $table, $id, $status, $field, $additionalData) ?: [], + 'file' => $this->checkValueForFile($res, (string)$value, $tcaFieldConf, $table, $id, $field, $additionalData), 'input' => $this->checkValueForInput($value, $tcaFieldConf, $table, $id, $realPid, $field), 'language' => $this->checkValueForLanguage((int)$value, $table, $field), 'link' => $this->checkValueForLink((string)$value, $tcaFieldConf, $table, $id, $checkField), @@ -2614,6 +2616,36 @@ class DataHandler implements LoggerAwareInterface return $res; } + /** + * Evaluates 'file' type values. + */ + public function checkValueForFile( + array $res, + string $value, + array $tcaFieldConf, + string $table, + int|string $id, + string $field, + ?array $additionalData = null + ): array { + $valueArray = array_unique(GeneralUtility::trimExplode(',', $value)); + if ($value !== '' && (str_contains($value, 'NEW') || !MathUtility::canBeInterpretedAsInteger($id))) { + $this->remapStackRecords[$table][$id] = ['remapStackIndex' => count($this->remapStack)]; + $this->addNewValuesToRemapStackChildIds($valueArray); + $this->remapStack[] = [ + 'func' => 'checkValue_file_processDBdata', + 'args' => [$valueArray, $tcaFieldConf, $id, $table], + 'pos' => ['valueArray' => 0, 'tcaFieldConf' => 1, 'id' => 2, 'table' => 3], + 'additionalData' => $additionalData, + 'field' => $field, + ]; + unset($res['value']); + } elseif ($value !== '' || MathUtility::canBeInterpretedAsInteger($id)) { + $res['value'] = $this->checkValue_file_processDBdata($valueArray, $tcaFieldConf, $id, $table); + } + return $res; + } + /** * Checks if a fields has more items than defined via TCA in maxitems. * If there are more items than allowed, the item list is truncated to the defined number. @@ -3247,7 +3279,7 @@ class DataHandler implements LoggerAwareInterface // update record in intermediate table (sorting & pointer uid to parent record) $dbAnalysis->writeForeignField($tcaFieldConf, $id, 0); $newValue = $dbAnalysis->countItems(false); - } elseif ($this->getInlineFieldType($tcaFieldConf) === 'mm') { + } elseif ($this->getRelationFieldType($tcaFieldConf) === 'mm') { // In order to fully support all the MM stuff, directly call checkValue_group_select_processDBdata instead of repeating the needed code here $valueArray = $this->checkValue_group_select_processDBdata($valueArray, $tcaFieldConf, $id, $status, 'select', $table, $field); $newValue = $valueArray[0]; @@ -3260,6 +3292,24 @@ class DataHandler implements LoggerAwareInterface return $newValue; } + /** + * Returns data for file fields. + */ + protected function checkValue_file_processDBdata($valueArray, $tcaFieldConf, $id, $table): mixed + { + $valueArray = GeneralUtility::makeInstance(FileExtensionFilter::class)->filter( + $valueArray, + (string)($tcaFieldConf['allowed'] ?? ''), + (string)($tcaFieldConf['disallowed'] ?? ''), + $this + ); + + $dbAnalysis = $this->createRelationHandlerInstance(); + $dbAnalysis->start(implode(',', $valueArray), $tcaFieldConf['foreign_table'], '', 0, $table, $tcaFieldConf); + $dbAnalysis->writeForeignField($tcaFieldConf, $id); + return $dbAnalysis->countItems(false); + } + /********************************************* * * PROCESSING COMMANDS @@ -3910,13 +3960,13 @@ class DataHandler implements LoggerAwareInterface */ public function copyRecord_procBasedOnFieldType($table, $uid, $field, $value, $row, $conf, $realDestPid, $language = 0, array $workspaceOptions = []) { - $inlineSubType = $this->getInlineFieldType($conf); + $relationFieldType = $this->getRelationFieldType($conf); // Get the localization mode for the current (parent) record (keep|select): // Register if there are references to take care of or MM is used on an inline field (no change to value): - if ($this->isReferenceField($conf) || $inlineSubType === 'mm') { + if ($this->isReferenceField($conf) || $relationFieldType === 'mm') { $value = $this->copyRecord_processManyToMany($table, $uid, $field, $value, $conf, $language); - } elseif ($inlineSubType !== false) { - $value = $this->copyRecord_processInline($table, $uid, $field, $value, $row, $conf, $realDestPid, $language, $workspaceOptions); + } elseif ($relationFieldType !== false) { + $value = $this->copyRecord_processRelation($table, $uid, $field, $value, $row, $conf, $realDestPid, $language, $workspaceOptions); } // For "flex" fieldtypes we need to traverse the structure for two reasons: If there are file references they have to be prepended with absolute paths and if there are database reference they MIGHT need to be remapped (still done in remapListedDBRecords()) if (isset($conf['type']) && $conf['type'] === 'flex') { @@ -4001,7 +4051,7 @@ class DataHandler implements LoggerAwareInterface } /** - * Processes child records in an inline (IRRE) element when the parent record is copied. + * Processes relations in an inline (IRRE) or file element when the parent record is copied. * * @param string $table * @param int $uid @@ -4014,7 +4064,7 @@ class DataHandler implements LoggerAwareInterface * @param array $workspaceOptions * @return string */ - protected function copyRecord_processInline( + protected function copyRecord_processRelation( $table, $uid, $field, @@ -4110,7 +4160,7 @@ class DataHandler implements LoggerAwareInterface // Extract parameters: [$table, $uid, $field, $realDestPid] = $pParams; // If references are set for this field, set flag so they can be corrected later (in ->remapListedDBRecords()) - if (($this->isReferenceField($dsConf) || $this->getInlineFieldType($dsConf) !== false) && (string)$dataValue !== '') { + if (($this->isReferenceField($dsConf) || $this->getRelationFieldType($dsConf) !== false) && (string)$dataValue !== '') { $dataValue = $this->copyRecord_procBasedOnFieldType($table, $uid, $field, $dataValue, [], $dsConf, $realDestPid, 0, $workspaceOptions); $this->registerDBList[$table][$uid][$field] = 'FlexForm_reference'; } @@ -4531,32 +4581,26 @@ class DataHandler implements LoggerAwareInterface * @param array $conf TCA configuration of current field * @internal should only be used from within DataHandler */ - public function moveRecord_procBasedOnFieldType($table, $uid, $destPid, $value, $conf) + public function moveRecord_procBasedOnFieldType($table, $uid, $destPid, $value, $conf): void { - $dbAnalysis = null; - if (!empty($conf['type']) && $conf['type'] === 'inline') { - $foreign_table = $conf['foreign_table']; - $moveChildrenWithParent = !isset($conf['behaviour']['disableMovingChildrenWithParent']) || !$conf['behaviour']['disableMovingChildrenWithParent']; - if ($foreign_table && $moveChildrenWithParent) { - $inlineType = $this->getInlineFieldType($conf); - if ($inlineType === 'list' || $inlineType === 'field') { - if ($table === 'pages') { - // If the inline elements are related to a page record, - // make sure they reside at that page and not at its parent - $destPid = $uid; - } - $dbAnalysis = $this->createRelationHandlerInstance(); - $dbAnalysis->start($value, $conf['foreign_table'], '', $uid, $table, $conf); - } - } + if (($conf['behaviour']['disableMovingChildrenWithParent'] ?? false) + || !in_array($this->getRelationFieldType($conf), ['list', 'field'], true) + ) { + return; } - // Move the records - if (isset($dbAnalysis)) { - // Moving records to a positive destination will insert each - // record at the beginning, thus the order is reversed here: - foreach (array_reverse($dbAnalysis->itemArray) as $v) { - $this->moveRecord($v['table'], $v['id'], $destPid); - } + + if ($table === 'pages') { + // If the relations are related to a page record, make sure they reside at that page and not at its parent + $destPid = $uid; + } + + $dbAnalysis = $this->createRelationHandlerInstance(); + $dbAnalysis->start($value, $conf['foreign_table'], '', $uid, $table, $conf); + + // Moving records to a positive destination will insert each + // record at the beginning, thus the order is reversed here: + foreach (array_reverse($dbAnalysis->itemArray) as $item) { + $this->moveRecord($item['table'], $item['id'], $destPid); } } @@ -4872,15 +4916,15 @@ class DataHandler implements LoggerAwareInterface return; } - $inlineSubType = $this->getInlineFieldType($config); - if ($inlineSubType === false) { + $relationFieldType = $this->getRelationFieldType($config); + if ($relationFieldType === false) { return; } $transOrigRecord = BackendUtility::getRecordWSOL($table, $transOrigPointer); $removeArray = []; - $mmTable = $inlineSubType === 'mm' && isset($config['MM']) && $config['MM'] ? $config['MM'] : ''; + $mmTable = $relationFieldType === 'mm' && isset($config['MM']) && $config['MM'] ? $config['MM'] : ''; // Fetch children from original language parent: $dbAnalysisOriginal = $this->createRelationHandlerInstance(); $dbAnalysisOriginal->start($transOrigRecord[$field], $foreignTable, $mmTable, $transOrigRecord['uid'], $table, $config); @@ -4948,12 +4992,12 @@ class DataHandler implements LoggerAwareInterface } $updateFields = []; // Handle, reorder and store relations: - if ($inlineSubType === 'list') { + if ($relationFieldType === 'list') { $updateFields = [$field => $value]; - } elseif ($inlineSubType === 'field') { + } elseif ($relationFieldType === 'field') { $dbAnalysisCurrent->writeForeignField($config, $id); $updateFields = [$field => $dbAnalysisCurrent->countItems(false)]; - } elseif ($inlineSubType === 'mm') { + } elseif ($relationFieldType === 'mm') { $dbAnalysisCurrent->writeMM($config['MM'], $id); $updateFields = [$field => $dbAnalysisCurrent->countItems(false)]; } @@ -5492,26 +5536,20 @@ class DataHandler implements LoggerAwareInterface if (!isset($conf['type'])) { return; } - if ($conf['type'] === 'inline') { - $foreign_table = $conf['foreign_table']; - if ($foreign_table) { - $inlineType = $this->getInlineFieldType($conf); - if ($inlineType === 'list' || $inlineType === 'field') { - $dbAnalysis = $this->createRelationHandlerInstance(); - $dbAnalysis->start($value, $conf['foreign_table'], '', $uid, $table, $conf); - $dbAnalysis->undeleteRecord = true; - $enableCascadingDelete = true; - // non type save comparison is intended! - if (isset($conf['behaviour']['enableCascadingDelete']) && $conf['behaviour']['enableCascadingDelete'] == false) { - $enableCascadingDelete = false; - } + if ($conf['type'] === 'inline' || $conf['type'] === 'file') { + if (in_array($this->getRelationFieldType($conf), ['list', 'field'], true)) { + $dbAnalysis = $this->createRelationHandlerInstance(); + $dbAnalysis->start($value, $conf['foreign_table'], '', $uid, $table, $conf); + $dbAnalysis->undeleteRecord = true; + // non type save comparison is intended! + if (!isset($conf['behaviour']['enableCascadingDelete']) + || $conf['behaviour']['enableCascadingDelete'] != false + ) { // Walk through the items and remove them foreach ($dbAnalysis->itemArray as $v) { - if ($enableCascadingDelete) { - $this->deleteAction($v['table'], $v['id']); - } + $this->deleteAction($v['table'], $v['id']); } } } @@ -5715,11 +5753,9 @@ class DataHandler implements LoggerAwareInterface continue; } $foreignTable = (string)($fieldConfig['foreign_table'] ?? ''); - if ($fieldType === 'inline') { + if ($fieldType === 'inline' || $fieldType === 'file') { // @todo: Inline MM not handled here, and what about group / select? - if ($foreignTable === '' - || !in_array($this->getInlineFieldType($fieldConfig), ['list', 'field'], true) - ) { + if (!in_array($this->getRelationFieldType($fieldConfig), ['list', 'field'], true)) { continue; } $relationHandler = $this->createRelationHandlerInstance(); @@ -5928,16 +5964,15 @@ class DataHandler implements LoggerAwareInterface if (!isset($fieldConfig['type'])) { continue; } - if ($fieldConfig['type'] === 'inline') { - $foreignTable = $fieldConfig['foreign_table'] ?? null; - if (!$foreignTable + if ($fieldConfig['type'] === 'inline' || $fieldConfig['type'] === 'file') { + $foreignTable = (string)($fieldConfig['foreign_table'] ?? ''); + if ($foreignTable === '' || (isset($fieldConfig['behaviour']['enableCascadingDelete']) && (bool)$fieldConfig['behaviour']['enableCascadingDelete'] === false) ) { continue; } - $inlineType = $this->getInlineFieldType($fieldConfig); - if ($inlineType === 'list' || $inlineType === 'field') { + if (in_array($this->getRelationFieldType($fieldConfig), ['list', 'field'], true)) { $dbAnalysis = $this->createRelationHandlerInstance(); $dbAnalysis->start($value, $fieldConfig['foreign_table'], '', (int)$record['uid'], $table, $fieldConfig); $dbAnalysis->undeleteRecord = true; @@ -6413,6 +6448,9 @@ class DataHandler implements LoggerAwareInterface case 'inline': $this->remapListedDBRecords_procInline($conf, $value, $uid, $table); break; + case 'file': + $this->remapListedDBRecords_procFile($conf, $value, $uid, $table); + break; default: $this->logger->debug('Field type should not appear here: {type}', ['type' => $conf['type']]); } @@ -6534,10 +6572,10 @@ class DataHandler implements LoggerAwareInterface { $theUidToUpdate = $this->copyMappingArray_merged[$table][$uid] ?? null; if ($conf['foreign_table']) { - $inlineType = $this->getInlineFieldType($conf); - if ($inlineType === 'mm') { + $relationFieldType = $this->getRelationFieldType($conf); + if ($relationFieldType === 'mm') { $this->remapListedDBRecords_procDBRefs($conf, $value, $theUidToUpdate, $table); - } elseif ($inlineType !== false) { + } elseif ($relationFieldType !== false) { $dbAnalysis = $this->createRelationHandlerInstance(); $dbAnalysis->start($value, $conf['foreign_table'], '', 0, $table, $conf); @@ -6553,7 +6591,7 @@ class DataHandler implements LoggerAwareInterface } // Update child records if using pointer fields ('foreign_field'): - if ($inlineType === 'field') { + if ($relationFieldType === 'field') { $dbAnalysis->writeForeignField($conf, $uid, $theUidToUpdate); } $thePidToUpdate = null; @@ -6577,7 +6615,7 @@ class DataHandler implements LoggerAwareInterface } $updateValues = ['pid' => $thePidToUpdate]; foreach ($updatePidForRecords as $tableName => $uids) { - if (empty($tableName) || empty($uids)) { + if (empty($tableName)) { continue; } $conn = GeneralUtility::makeInstance(ConnectionPool::class) @@ -6591,6 +6629,58 @@ class DataHandler implements LoggerAwareInterface } } + /** + * Performs remapping of old UID values to NEW uid values for an file field. + * + * @internal should only be used from within DataHandler + */ + public function remapListedDBRecords_procFile($conf, $value, $uid, $table) + { + $thePidToUpdate = null; + $updatePidForRecords = []; + $theUidToUpdate = $this->copyMappingArray_merged[$table][$uid] ?? null; + + $dbAnalysis = $this->createRelationHandlerInstance(); + $dbAnalysis->start($value, $conf['foreign_table'], '', 0, $table, $conf); + + foreach ($dbAnalysis->itemArray as &$item) { + $updatePidForRecords[$item['table']][] = $item['id']; + $versionedId = $this->getAutoVersionId($item['table'], $item['id']); + if ($versionedId !== null) { + $updatePidForRecords[$item['table']][] = $versionedId; + $item['id'] = $versionedId; + } + } + unset($item); + + $dbAnalysis->writeForeignField($conf, $uid, $theUidToUpdate); + + if ($table === 'pages') { + $thePidToUpdate = $theUidToUpdate; + } elseif (isset($this->registerDBPids[$table][$uid])) { + $thePidToUpdate = $this->registerDBPids[$table][$uid]; + $thePidToUpdate = $this->copyMappingArray_merged['pages'][$thePidToUpdate]; + } + + if ($thePidToUpdate && $updatePidForRecords !== []) { + $thePidToUpdate = $this->getDefaultLanguagePageId($thePidToUpdate); + $liveId = BackendUtility::getLiveVersionIdOfRecord('pages', $theUidToUpdate); + if ($liveId !== null) { + $thePidToUpdate = $liveId; + } + $updateValues = ['pid' => $thePidToUpdate]; + foreach ($updatePidForRecords as $tableName => $uids) { + if (empty($tableName)) { + continue; + } + $conn = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($tableName); + foreach ($uids as $updateUid) { + $conn->update($tableName, $updateValues, ['uid' => $updateUid]); + } + } + } + } + /** * Processes the $this->remapStack at the end of copying, inserting, etc. actions. * The remapStack takes care about the correct mapping of new and old uids in case of relational data. @@ -8658,16 +8748,20 @@ class DataHandler implements LoggerAwareInterface } /** - * Returns the subtype as a string of an inline field. - * If it's not an inline field at all, it returns FALSE. + * Returns the subtype as a string of a relation (inline / file) field. + * If it's not a relation field at all, it returns FALSE. * * @param array $conf Config array for TCA/columns field * @return string|bool string Inline subtype (field|mm|list), boolean: FALSE * @internal should only be used from within DataHandler */ - public function getInlineFieldType($conf) + public function getRelationFieldType($conf): bool|string { - if (empty($conf['type']) || $conf['type'] !== 'inline' || empty($conf['foreign_table'])) { + if ( + empty($conf['foreign_table']) + || !in_array($conf['type'] ?? '', ['inline', 'file'], true) + || ($conf['type'] === 'file' && !($conf['foreign_field'] ?? false)) + ) { return false; } if ($conf['foreign_field'] ?? false) { @@ -9294,7 +9388,7 @@ class DataHandler implements LoggerAwareInterface foreach ($fieldArray as $field => $value) { if (!MathUtility::canBeInterpretedAsInteger($value) && isset($GLOBALS['TCA'][$table]['columns'][$field]['config']['type']) - && $GLOBALS['TCA'][$table]['columns'][$field]['config']['type'] === 'inline' + && in_array($GLOBALS['TCA'][$table]['columns'][$field]['config']['type'], ['inline', 'file'], true) && ($GLOBALS['TCA'][$table]['columns'][$field]['config']['foreign_field'] ?? false) ) { $result[$field] = count(GeneralUtility::trimExplode(',', $value, true)); diff --git a/typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php b/typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php index 75009f4658c5bf404e8abe78a2122fe288e2c911..9060487c3c255c7eda3389d65e52f9a92f6e05b6 100644 --- a/typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php +++ b/typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php @@ -448,12 +448,12 @@ class DataMapProcessor $item->getId(), [$fieldName => $fromValue] ); - } elseif (!$this->isInlineRelationField($item->getTableName(), $fieldName)) { + } elseif (!$this->isReferenceField($item->getTableName(), $fieldName)) { // direct relational values $this->synchronizeDirectRelations($item, $fieldName, $fromRecord); } else { - // inline relational values - $this->synchronizeInlineRelations($item, $fieldName, $fromRecord, $forRecord); + // reference values + $this->synchronizeReferences($item, $fieldName, $fromRecord, $forRecord); } } @@ -518,10 +518,11 @@ class DataMapProcessor } /** - * Handle synchronization of inline relations. - * Inline Relational Record Editing ("IRRE") always is modelled as 1:n composite relation - which means that - * direct(!) children cannot exist without their parent. Removing a relative parent results in cascaded removal - * of all direct(!) children as well. + * Handle synchronization of references (inline or file). + * References are always modelled as 1:n composite relation - which + * means that direct(!) children cannot exist without their parent. + * Removing a relative parent results in cascaded removal of all direct(!) + * children as well. * * @param DataMapItem $item * @param string $fieldName @@ -529,7 +530,7 @@ class DataMapProcessor * @param array $forRecord * @throws \RuntimeException */ - protected function synchronizeInlineRelations(DataMapItem $item, string $fieldName, array $fromRecord, array $forRecord) + protected function synchronizeReferences(DataMapItem $item, string $fieldName, array $fromRecord, array $forRecord) { $configuration = $GLOBALS['TCA'][$item->getTableName()]['columns'][$fieldName]; $isLocalizationModeExclude = ($configuration['l10n_mode'] ?? null) === 'exclude'; @@ -1509,18 +1510,18 @@ class DataMapProcessor && !empty($configuration['foreign_table']) && !empty($GLOBALS['TCA'][$configuration['foreign_table']]) ) - || $this->isInlineRelationField($tableName, $fieldName) + || $this->isReferenceField($tableName, $fieldName) ; } /** - * True if we're dealing with an inline field + * True if we're dealing with a reference field (either "inline" or "file") * * @param string $tableName * @param string $fieldName * @return bool TRUE if field is of type inline with foreign_table set */ - protected function isInlineRelationField(string $tableName, string $fieldName): bool + protected function isReferenceField(string $tableName, string $fieldName): bool { if (empty($GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config']['type'])) { return false; @@ -1529,7 +1530,7 @@ class DataMapProcessor $configuration = $GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config']; return - $configuration['type'] === 'inline' + ($configuration['type'] === 'inline' || $configuration['type'] === 'file') && !empty($configuration['foreign_table']) && !empty($GLOBALS['TCA'][$configuration['foreign_table']]) ; diff --git a/typo3/sysext/core/Classes/DataHandling/TableColumnType.php b/typo3/sysext/core/Classes/DataHandling/TableColumnType.php index 45e184e2dbd1e2a3e860b2100fdc47ada43ce0fd..86c2be2fe6e558deacc66e49a92c8e4954a52b8b 100644 --- a/typo3/sysext/core/Classes/DataHandling/TableColumnType.php +++ b/typo3/sysext/core/Classes/DataHandling/TableColumnType.php @@ -49,6 +49,7 @@ final class TableColumnType extends Enumeration const DATETIME = 'DATETIME'; const COLOR = 'COLOR'; const NUMBER = 'NUMBER'; + const FILE = 'FILE'; /** * @param mixed $type diff --git a/typo3/sysext/core/Classes/Database/ReferenceIndex.php b/typo3/sysext/core/Classes/Database/ReferenceIndex.php index 5d8a33643ad6923d7d7d7a022f2b4f8009e118cb..e1198823ff24b38e8889fbe87e6059d5efd31968 100644 --- a/typo3/sysext/core/Classes/Database/ReferenceIndex.php +++ b/typo3/sysext/core/Classes/Database/ReferenceIndex.php @@ -581,7 +581,7 @@ class ReferenceIndex implements LoggerAwareInterface if (empty($conf)) { return false; } - if ($conf['type'] === 'inline' && !empty($conf['foreign_table']) && empty($conf['MM'])) { + if (($conf['type'] === 'inline' || $conf['type'] === 'file') && !empty($conf['foreign_table']) && empty($conf['MM'])) { $dbAnalysis = GeneralUtility::makeInstance(RelationHandler::class); $dbAnalysis->setUseLiveReferenceIds(false); $dbAnalysis->setWorkspaceId($this->getWorkspaceId()); @@ -860,7 +860,7 @@ class ReferenceIndex implements LoggerAwareInterface return $configuration['type'] === 'group' || ( - in_array($configuration['type'], ['select', 'category', 'inline'], true) + in_array($configuration['type'], ['select', 'category', 'inline', 'file'], true) && !empty($configuration['foreign_table']) ); } diff --git a/typo3/sysext/core/Classes/Database/RelationHandler.php b/typo3/sysext/core/Classes/Database/RelationHandler.php index a5bfc49680fee30f6c78ac520a874c7f9d264afa..a7540d45b16333fbd8b53157f1a8394ec9de54cf 100644 --- a/typo3/sysext/core/Classes/Database/RelationHandler.php +++ b/typo3/sysext/core/Classes/Database/RelationHandler.php @@ -405,7 +405,7 @@ class RelationHandler } // Skip if not dealing with IRRE in a CSV list on a workspace - if (!isset($configuration['type']) || $configuration['type'] !== 'inline' + if (!isset($configuration['type']) || ($configuration['type'] !== 'inline' && $configuration['type'] !== 'file') || empty($configuration['foreign_table']) || !empty($configuration['foreign_field']) || !empty($configuration['MM']) || count($this->tableArray) !== 1 || empty($this->tableArray[$configuration['foreign_table']]) || $this->getWorkspaceId() === 0 || !BackendUtility::isTableWorkspaceEnabled($configuration['foreign_table']) diff --git a/typo3/sysext/core/Classes/Migrations/TcaMigration.php b/typo3/sysext/core/Classes/Migrations/TcaMigration.php index 42ee3355fc6410e77898260fa25aae8b788bf1c0..1542bf33e44d6774c96d5ac88dfeda9eb600ac4b 100644 --- a/typo3/sysext/core/Classes/Migrations/TcaMigration.php +++ b/typo3/sysext/core/Classes/Migrations/TcaMigration.php @@ -18,6 +18,7 @@ declare(strict_types=1); namespace TYPO3\CMS\Core\Migrations; use TYPO3\CMS\Core\Database\Query\QueryHelper; +use TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\MathUtility; @@ -81,7 +82,10 @@ class TcaMigration $tca = $this->migrateRenderTypeColorpickerToTypeColor($tca); $tca = $this->migrateEvalIntAndDouble2ToTypeNumber($tca); $tca = $this->removeAlwaysDescription($tca); + $tca = $this->migrateFalHandlingInInlineToTypeFile($tca); $tca = $this->removeCtrlCruserId($tca); + $tca = $this->removeFalRelatedElementBrowserOptions($tca); + $tca = $this->removeFalRelatedOptionsFromTypeInline($tca); return $tca; } @@ -957,7 +961,7 @@ class TcaMigration continue; } - // Set the TCA type to "link" + // Set the TCA type to "color" $tca[$table]['columns'][$fieldName]['config']['type'] = 'color'; // Unset "renderType", "max" and "eval" @@ -1149,4 +1153,224 @@ class TcaMigration } return $tca; } + + /** + * Migrates type='inline' with foreign_table='sys_file_reference' to type='file'. + * Removes table relation related options. + * Removes no longer available appearance options. + * Detects usage of "customControls" hook. + * Migrates renamed appearance options. + * Migrates allowed file extensions. + */ + protected function migrateFalHandlingInInlineToTypeFile(array $tca): array + { + foreach ($tca as $table => &$tableDefinition) { + if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'] ?? false)) { + continue; + } + + foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) { + if (($fieldConfig['config']['type'] ?? '') !== 'inline' + || ($fieldConfig['config']['foreign_table'] ?? '') !== 'sys_file_reference' + ) { + // Early return in case column is not of type=inline with foreign_table=sys_file_reference + continue; + } + + // Place to add additional information, which will later be appended to the deprecation message + $additionalInformation = ''; + + // Set the TCA type to "file" + $fieldConfig['config']['type'] = 'file'; + + // Remove table relation related options, since they are + // either not needed anymore or set by TcaPreperation automatically. + unset( + $fieldConfig['config']['foreign_table'], + $fieldConfig['config']['foreign_field'], + $fieldConfig['config']['foreign_sortby'], + $fieldConfig['config']['foreign_table_field'], + $fieldConfig['config']['foreign_match_fields'], + $fieldConfig['config']['foreign_label'], + $fieldConfig['config']['foreign_selector'], + $fieldConfig['config']['foreign_unique'], + ); + + // "new" control is not supported for this type so remove it altogether for cleaner TCA + unset($fieldConfig['config']['appearance']['enabledControls']['new']); + + // [appearance][headerThumbnail][field] is not needed anymore + unset($fieldConfig['config']['appearance']['headerThumbnail']['field']); + + // A couple of further appearance options are not supported by type "file", unset them as well + unset( + $fieldConfig['config']['appearance']['showNewRecordLink'], + $fieldConfig['config']['appearance']['newRecordLinkAddTitle'], + $fieldConfig['config']['appearance']['newRecordLinkTitle'], + $fieldConfig['config']['appearance']['levelLinksPosition'], + $fieldConfig['config']['appearance']['useCombination'], + $fieldConfig['config']['appearance']['suppressCombinationWarning'] + ); + + // Migrate [appearance][showPossibleRecordsSelector] to [appearance][showFileSelectors] + if (isset($fieldConfig['config']['appearance']['showPossibleRecordsSelector'])) { + $fieldConfig['config']['appearance']['showFileSelectors'] = $fieldConfig['config']['appearance']['showPossibleRecordsSelector']; + unset($fieldConfig['config']['appearance']['showPossibleRecordsSelector']); + } + + // "customControls" hook has been replaced by the CustomFileControlsEvent + if (isset($fieldConfig['config']['customControls'])) { + $additionalInformation .= ' The \'customControls\' option is not evaluated anymore and has ' + . 'to be replaced with the PSR-14 \'CustomFileControlsEvent\'.'; + unset($fieldConfig['config']['customControls']); + } + + // Migrate element browser related settings + if (!empty($fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config']['appearance'])) { + if (!empty($fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config']['appearance']['elementBrowserAllowed'])) { + // Migrate "allowed" file extensions from appearance + $fieldConfig['config']['allowed'] = $fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config']['appearance']['elementBrowserAllowed']; + } + unset( + $fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config']['appearance']['elementBrowserType'], + $fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config']['appearance']['elementBrowserAllowed'] + ); + if (empty($fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config']['appearance'])) { + unset($fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config']['appearance']); + if (empty($fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config'])) { + unset($fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config']); + if (empty($fieldConfig['config']['overrideChildTca']['columns']['uid_local'])) { + unset($fieldConfig['config']['overrideChildTca']['columns']['uid_local']); + if (empty($fieldConfig['config']['overrideChildTca']['columns'])) { + unset($fieldConfig['config']['overrideChildTca']['columns']); + if (empty($fieldConfig['config']['overrideChildTca'])) { + unset($fieldConfig['config']['overrideChildTca']); + } + } + } + } + } + } + + // Migrate file extension filter + if (!empty($fieldConfig['config']['filter'])) { + foreach ($fieldConfig['config']['filter'] as $key => $filter) { + if (($filter['userFunc'] ?? '') === (FileExtensionFilter::class . '->filterInlineChildren')) { + $allowedFileExtensions = (string)($filter['parameters']['allowedFileExtensions'] ?? ''); + // Note: Allowed file extensions in the filter take precedence over possible + // extensions defined for the element browser. This is due to filters are evaluated + // by the DataHandler while element browser is only applied in FormEngine UI. + if ($allowedFileExtensions !== '') { + $fieldConfig['config']['allowed'] = $allowedFileExtensions; + } + $disallowedFileExtensions = (string)($filter['parameters']['disallowedFileExtensions'] ?? ''); + if ($disallowedFileExtensions !== '') { + $fieldConfig['config']['disallowed'] = $disallowedFileExtensions; + } + unset($fieldConfig['config']['filter'][$key]); + } + } + // Remove filter if it got empty + if (empty($fieldConfig['config']['filter'])) { + unset($fieldConfig['config']['filter']); + } + } + + $this->messages[] = 'The TCA field \'' . $fieldName . '\' of table \'' . $table . '\' defines ' + . 'type="inline" with foreign_table=sys_file_reference. The field has therefore been ' + . 'migrated to the dedicated TCA type \'file\'. This includes corresponding migration of ' + . 'the table mapping fields and filters, which were usually added to the field using the ' + . 'ExtensionManagementUtility::getFileFieldTCAConfig().' . $additionalInformation . ' ' + . 'Please adjust your TCA accordingly.'; + } + } + + return $tca; + } + + /** + * Removes the [appearance][elementBrowserType] and [appearance][elementBrowserAllowed] + * options from TCA type "group" fields. + */ + protected function removeFalRelatedElementBrowserOptions(array $tca): array + { + foreach ($tca as $table => &$tableDefinition) { + if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'] ?? false)) { + continue; + } + + foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) { + if (($fieldConfig['config']['type'] ?? '') !== 'group' + || ( + !isset($fieldConfig['config']['appearance']['elementBrowserType']) + && !isset($fieldConfig['config']['appearance']['elementBrowserAllowed']) + ) + ) { + // Early return in case column is not of type=group or does not define the options in question + continue; + } + + unset( + $fieldConfig['config']['appearance']['elementBrowserType'], + $fieldConfig['config']['appearance']['elementBrowserAllowed'] + ); + + // Also unset "appearance" if empty + if (empty($fieldConfig['config']['appearance'])) { + unset($fieldConfig['config']['appearance']); + } + + $this->messages[] = 'The TCA field \'' . $fieldName . '\' of table \'' . $table . '\' defines ' + . 'fal related element browser options, which are no longer needed and therefore removed. ' + . 'Please adjust your TCA accordingly.'; + } + } + + return $tca; + } + + /** + * Removes the following options from TCA type "inline" fields: + * - [appearance][headerThumbnail] + * - [appearance][fileUploadAllowed] + * - [appearance][fileByUrlAllowed] + */ + protected function removeFalRelatedOptionsFromTypeInline(array $tca): array + { + foreach ($tca as $table => &$tableDefinition) { + if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'] ?? false)) { + continue; + } + + foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) { + if (($fieldConfig['config']['type'] ?? '') !== 'inline' + || ( + !isset($fieldConfig['config']['appearance']['headerThumbnail']) + && !isset($fieldConfig['config']['appearance']['fileUploadAllowed']) + && !isset($fieldConfig['config']['appearance']['fileByUrlAllowed']) + ) + ) { + // Early return in case column is not of type=inline or does not define the options in question + continue; + } + + unset( + $fieldConfig['config']['appearance']['headerThumbnail'], + $fieldConfig['config']['appearance']['fileUploadAllowed'], + $fieldConfig['config']['appearance']['fileByUrlAllowed'] + ); + + // Also unset "appearance" if empty + if (empty($fieldConfig['config']['appearance'])) { + unset($fieldConfig['config']['appearance']); + } + + $this->messages[] = 'The TCA field \'' . $fieldName . '\' of table \'' . $table . '\' defines ' + . 'fal related appearance options, which are no longer evaluated and therefore removed. ' + . 'Please adjust your TCA accordingly.'; + } + } + + return $tca; + } } diff --git a/typo3/sysext/core/Classes/Preparations/TcaPreparation.php b/typo3/sysext/core/Classes/Preparations/TcaPreparation.php index da0e3196842ed18698eb145b731918940d5bd72f..3bf79c2892ea41a351f1585d06cc4026d84adf6a 100644 --- a/typo3/sysext/core/Classes/Preparations/TcaPreparation.php +++ b/typo3/sysext/core/Classes/Preparations/TcaPreparation.php @@ -17,6 +17,8 @@ declare(strict_types=1); namespace TYPO3\CMS\Core\Preparations; +use TYPO3\CMS\Core\Utility\StringUtility; + /** * Prepare TCA. Used in bootstrap and Flex Form Data Structures. * @@ -41,6 +43,7 @@ class TcaPreparation public function prepare(array $tca): array { $tca = $this->configureCategoryRelations($tca); + $tca = $this->configureFileReferences($tca); return $tca; } @@ -165,4 +168,73 @@ class TcaPreparation return $tca; } + + protected function configureFileReferences(array $tca): array + { + foreach ($tca as $table => &$tableDefinition) { + if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) { + continue; + } + foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) { + if (($fieldConfig['config']['type'] ?? '') !== 'file') { + continue; + } + + // Set static values for this type. Most of them are not needed due to the + // dedicated TCA type. However a lot of underlying code in DataHandler and + // friends relies on those keys, especially "foreign_table" and "foreign_selector". + // @todo Check which of those values can be removed since only used by FormEngine + $fieldConfig['config'] = array_replace_recursive( + $fieldConfig['config'], + [ + 'foreign_table' => 'sys_file_reference', + 'foreign_field' => 'uid_foreign', + 'foreign_sortby' => 'sorting_foreign', + 'foreign_table_field' => 'tablenames', + 'foreign_match_fields' => [ + 'fieldname' => $fieldName, + ], + 'foreign_label' => 'uid_local', + 'foreign_selector' => 'uid_local', + ] + ); + + if (!empty(($allowed = ($fieldConfig['config']['allowed'] ?? null)))) { + $fieldConfig['config']['allowed'] = self::prepareFileExtensions($allowed); + } + if (!empty(($disallowed = ($fieldConfig['config']['disallowed'] ?? null)))) { + $fieldConfig['config']['disallowed'] = self::prepareFileExtensions($disallowed); + } + } + } + + return $tca; + } + + /** + * Ensures format, replaces placeholders and remove duplicates + * + * @todo Does not need to be static, once FlexFormTools calls configureFileReferences() directly + */ + public static function prepareFileExtensions(mixed $fileExtensions): string + { + if (is_array($fileExtensions)) { + $fileExtensions = implode(',', $fileExtensions); + } else { + $fileExtensions = (string)$fileExtensions; + } + + // Replace placeholders with the corresponding $GLOBALS value for now + if (preg_match_all('/common-(image|text|media)-types/', $fileExtensions, $matches)) { + foreach ($matches[1] as $key => $type) { + $fileExtensions = str_replace( + $matches[0][$key], + $GLOBALS['TYPO3_CONF_VARS'][$type === 'image' ? 'GFX' : 'SYS'][$type . 'file_ext'] ?? '', + $fileExtensions + ); + } + } + + return StringUtility::uniqueList($fileExtensions); + } } diff --git a/typo3/sysext/core/Classes/Resource/Filter/FileExtensionFilter.php b/typo3/sysext/core/Classes/Resource/Filter/FileExtensionFilter.php index 0d28f856602a5fbb3f826e054afde23f7c93b089..696fc2c0e714324eebca8b8fa31e4fc17ba53379 100644 --- a/typo3/sysext/core/Classes/Resource/Filter/FileExtensionFilter.php +++ b/typo3/sysext/core/Classes/Resource/Filter/FileExtensionFilter.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -15,9 +17,10 @@ namespace TYPO3\CMS\Core\Resource\Filter; +use TYPO3\CMS\Backend\RecordList\DatabaseRecordList; use TYPO3\CMS\Core\DataHandling\DataHandler; use TYPO3\CMS\Core\Resource\Driver\DriverInterface; -use TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException; +use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException; use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -29,56 +32,78 @@ class FileExtensionFilter /** * Allowed file extensions. If NULL, all extensions are allowed. * - * @var array + * @var string[]|null */ - protected $allowedFileExtensions; + protected ?array $allowedFileExtensions = null; /** * Disallowed file extensions. If NULL, no extension is disallowed (i.e. all are allowed). * - * @var array + * @var string[]|null */ - protected $disallowedFileExtensions; + protected ?array $disallowedFileExtensions = null; + + public function filter( + array $references, + string $allowedFileExtensions, + string $disallowedFileExtensions, + DataHandler|DatabaseRecordList $dataHandler + ): array { + if ($allowedFileExtensions !== '') { + $this->setAllowedFileExtensions($allowedFileExtensions); + } + if ($disallowedFileExtensions !== '') { + $this->setDisallowedFileExtensions($disallowedFileExtensions); + } + + $cleanReferences = []; + foreach ($references as $reference) { + if (empty($reference)) { + continue; + } + $parts = GeneralUtility::revExplode('_', (string)$reference, 2); + $fileReferenceUid = $parts[count($parts) - 1]; + try { + $fileReference = GeneralUtility::makeInstance(ResourceFactory::class)->getFileReferenceObject($fileReferenceUid); + $file = $fileReference->getOriginalFile(); + if ($this->isAllowed($file->getExtension())) { + $cleanReferences[] = $reference; + } else { + // Remove the erroneously created reference record again + $dataHandler->deleteAction('sys_file_reference', $fileReferenceUid); + } + } catch (ResourceDoesNotExistException $e) { + // do nothing + } + } + return $cleanReferences; + } /** * Entry method for use as DataHandler "inline" field filter * * @param array $parameters - * @param DataHandler $dataHandler + * @param DataHandler|DatabaseRecordList $dataHandler * @return array + * @deprecated Will be removed in TYPO3 v13. Use filterFileReferences() directly instead. */ - public function filterInlineChildren(array $parameters, DataHandler $dataHandler) + public function filterInlineChildren(array $parameters, DataHandler|DatabaseRecordList $dataHandler): array { - $values = $parameters['values']; - if ($parameters['allowedFileExtensions'] ?? false) { - $this->setAllowedFileExtensions($parameters['allowedFileExtensions']); - } - if ($parameters['disallowedFileExtensions'] ?? false) { - $this->setDisallowedFileExtensions($parameters['disallowedFileExtensions']); - } - $cleanValues = []; - if (is_array($values)) { - foreach ($values as $value) { - if (empty($value)) { - continue; - } - $parts = GeneralUtility::revExplode('_', (string)$value, 2); - $fileReferenceUid = $parts[count($parts) - 1]; - try { - $fileReference = GeneralUtility::makeInstance(ResourceFactory::class)->getFileReferenceObject($fileReferenceUid); - $file = $fileReference->getOriginalFile(); - if ($this->isAllowed($file->getExtension())) { - $cleanValues[] = $value; - } else { - // Remove the erroneously created reference record again - $dataHandler->deleteAction('sys_file_reference', $fileReferenceUid); - } - } catch (FileDoesNotExistException $e) { - // do nothing - } - } + trigger_error( + 'FileExtensionFilter->filterInlineChildren() will be removed in TYPO3 v13.0. Use FileExtensionFilter->filter() instead.', + E_USER_DEPRECATED + ); + + $references = $parameters['values'] ?? []; + if (!is_array($references)) { + $references = []; } - return $cleanValues; + return $this->filter( + $references, + (string)($parameters['allowedFileExtensions'] ?? ''), + (string)($parameters['disallowedFileExtensions'] ?? ''), + $dataHandler + ); } /** @@ -108,7 +133,7 @@ class FileExtensionFilter } catch (\InvalidArgumentException $e) { $fileInfo = []; } - if (!$this->isAllowed($fileInfo['extension'] ?? '')) { + if (!$this->isAllowed((string)($fileInfo['extension'] ?? ''))) { $returnCode = -1; } } @@ -118,20 +143,18 @@ class FileExtensionFilter /** * Checks whether a file is allowed according to the criteria defined in the class variables ($this->allowedFileExtensions etc.) * - * @param string $fileExt - * @return bool * @internal this is used internally for TYPO3 core only */ - public function isAllowed($fileExt) + public function isAllowed(string $fileExtension): bool { - $fileExt = strtolower($fileExt); + $fileExtension = strtolower($fileExtension); $result = true; // Check allowed file extensions - if ($this->allowedFileExtensions !== null && !empty($this->allowedFileExtensions) && !in_array($fileExt, $this->allowedFileExtensions)) { + if (!empty($this->allowedFileExtensions) && !in_array($fileExtension, $this->allowedFileExtensions, true)) { $result = false; } // Check disallowed file extensions - if ($this->disallowedFileExtensions !== null && !empty($this->disallowedFileExtensions) && in_array($fileExt, $this->disallowedFileExtensions)) { + if (!empty($this->disallowedFileExtensions) && in_array($fileExtension, $this->disallowedFileExtensions, true)) { $result = false; } return $result; @@ -140,9 +163,9 @@ class FileExtensionFilter /** * Set allowed file extensions * - * @param mixed $allowedFileExtensions Comma-separated list or array, of allowed file extensions + * @param mixed $allowedFileExtensions Comma-separated list or array, of allowed file extensions */ - public function setAllowedFileExtensions($allowedFileExtensions) + public function setAllowedFileExtensions(mixed $allowedFileExtensions): void { $this->allowedFileExtensions = $this->convertToLowercaseArray($allowedFileExtensions); } @@ -150,9 +173,9 @@ class FileExtensionFilter /** * Set disallowed file extensions * - * @param mixed $disallowedFileExtensions Comma-separated list or array, of allowed file extensions + * @param mixed $disallowedFileExtensions Comma-separated list or array, of allowed file extensions */ - public function setDisallowedFileExtensions($disallowedFileExtensions) + public function setDisallowedFileExtensions(mixed $disallowedFileExtensions): void { $this->disallowedFileExtensions = $this->convertToLowercaseArray($disallowedFileExtensions); } @@ -161,11 +184,8 @@ class FileExtensionFilter * Converts mixed (string or array) input arguments into an array, NULL if empty. * * All array values will be converted to lower case. - * - * @param mixed $inputArgument Comma-separated list or array. - * @return array */ - protected function convertToLowercaseArray($inputArgument) + protected function convertToLowercaseArray(mixed $inputArgument): ?array { $returnValue = null; if (is_array($inputArgument)) { diff --git a/typo3/sysext/core/Classes/Resource/Processing/FileDeletionAspect.php b/typo3/sysext/core/Classes/Resource/Processing/FileDeletionAspect.php index 7d15c2b9f79a8f8b338e5da0136ee13f320bd4d7..72dfd9fd885670ebbaa8c067532c5742089d56cf 100644 --- a/typo3/sysext/core/Classes/Resource/Processing/FileDeletionAspect.php +++ b/typo3/sysext/core/Classes/Resource/Processing/FileDeletionAspect.php @@ -72,7 +72,6 @@ final class FileDeletionAspect 'sys_file_reference', [ 'uid_local' => (int)$fileObject->getUid(), - 'table_local' => 'sys_file', ] ); } elseif ($fileObject instanceof ProcessedFile) { diff --git a/typo3/sysext/core/Classes/Resource/Service/UserFileInlineLabelService.php b/typo3/sysext/core/Classes/Resource/Service/UserFileInlineLabelService.php index 9d2c30757a434551fa269d29af5d6bc7cfcea032..0a0d182f53820538f8f929c0206aa8caef730457 100644 --- a/typo3/sysext/core/Classes/Resource/Service/UserFileInlineLabelService.php +++ b/typo3/sysext/core/Classes/Resource/Service/UserFileInlineLabelService.php @@ -24,9 +24,19 @@ use TYPO3\CMS\Extbase\Utility\LocalizationUtility; /** * User file inline label service + * + * @deprecated since v12, will be removed in v13. */ class UserFileInlineLabelService { + public function __construct() + { + trigger_error( + 'Class ' . __CLASS__ . ' has been deprecated in v12 and will be removed with v13.', + E_USER_DEPRECATED + ); + } + /** * Get the user function label for the file_reference table * diff --git a/typo3/sysext/core/Classes/Tree/TableConfiguration/DatabaseTreeDataProvider.php b/typo3/sysext/core/Classes/Tree/TableConfiguration/DatabaseTreeDataProvider.php index a7d4b470231147c2c93cac63d64edbf15ca432c2..f34953c5bc0fb596f119934a7d3fe8376ca56480 100644 --- a/typo3/sysext/core/Classes/Tree/TableConfiguration/DatabaseTreeDataProvider.php +++ b/typo3/sysext/core/Classes/Tree/TableConfiguration/DatabaseTreeDataProvider.php @@ -380,7 +380,7 @@ class DatabaseTreeDataProvider extends AbstractTableConfigurationTreeDataProvide protected function getChildrenUidsFromParentRelation(array $row): array { $uid = $row['uid']; - if (in_array($this->columnConfiguration['type'] ?? '', ['select', 'category', 'inline'], true)) { + if (in_array($this->columnConfiguration['type'] ?? '', ['select', 'category', 'inline', 'file'], true)) { if ($this->columnConfiguration['MM'] ?? null) { $dbGroup = GeneralUtility::makeInstance(RelationHandler::class); // Dummy field for setting "look from other site" @@ -409,6 +409,7 @@ class DatabaseTreeDataProvider extends AbstractTableConfigurationTreeDataProvide $value = (string)$row[$this->getLookupField()]; switch ((string)$this->columnConfiguration['type']) { case 'inline': + case 'file': // Intentional fall-through case 'select': case 'category': diff --git a/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php b/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php index 3fd875184aea1f4234ffbc955bd1b3570bdbe60e..d40081a22d7af32d8dba648deecf3be89c0e60f2 100644 --- a/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php +++ b/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php @@ -28,7 +28,6 @@ use TYPO3\CMS\Core\Package\Cache\PackageDependentCacheIdentifier; use TYPO3\CMS\Core\Package\Exception as PackageException; use TYPO3\CMS\Core\Package\PackageManager; use TYPO3\CMS\Core\Preparations\TcaPreparation; -use TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter; /** * Extension Management functions @@ -534,57 +533,19 @@ class ExtensionManagementUtility * @param string $disallowedFileExtensions Comma-separated list of disallowed file extensions (e.g. "doc,docx") * * @return array + * @deprecated since TYPO3 v12.0. Use the TCA type "file" directly */ public static function getFileFieldTCAConfig(string $fieldName, array $customSettingOverride = [], string $allowedFileExtensions = '', string $disallowedFileExtensions = ''): array { + trigger_error( + 'ExtensionManagementUtility::getFileFieldTCAConfig() will be removed in TYPO3 v13.0. Use TCA type "file" directly instead.', + E_USER_DEPRECATED + ); + $fileFieldTCAConfig = [ - 'type' => 'inline', - 'foreign_table' => 'sys_file_reference', - 'foreign_field' => 'uid_foreign', - 'foreign_sortby' => 'sorting_foreign', - 'foreign_table_field' => 'tablenames', - 'foreign_match_fields' => [ - 'fieldname' => $fieldName, - ], - 'foreign_label' => 'uid_local', - 'foreign_selector' => 'uid_local', - 'overrideChildTca' => [ - 'columns' => [ - 'uid_local' => [ - 'config' => [ - 'appearance' => [ - 'elementBrowserType' => 'file', - 'elementBrowserAllowed' => $allowedFileExtensions, - ], - ], - ], - ], - ], - 'filter' => [ - [ - 'userFunc' => FileExtensionFilter::class . '->filterInlineChildren', - 'parameters' => [ - 'allowedFileExtensions' => $allowedFileExtensions, - 'disallowedFileExtensions' => $disallowedFileExtensions, - ], - ], - ], - 'appearance' => [ - 'useSortable' => true, - 'headerThumbnail' => [ - 'field' => 'uid_local', - 'height' => '45m', - ], - - 'enabledControls' => [ - 'info' => true, - 'new' => false, - 'dragdrop' => true, - 'sort' => false, - 'hide' => true, - 'delete' => true, - ], - ], + 'type' => 'file', + 'allowed' => $allowedFileExtensions, + 'disallowed'=> $disallowedFileExtensions, ]; ArrayUtility::mergeRecursiveWithOverrule($fileFieldTCAConfig, $customSettingOverride); return $fileFieldTCAConfig; diff --git a/typo3/sysext/core/Classes/Utility/RootlineUtility.php b/typo3/sysext/core/Classes/Utility/RootlineUtility.php index 512b06d280aab67d5d89367d2dbee5f22729b1d4..9567325197af0703529146343cb06f3d79f5a56b 100644 --- a/typo3/sysext/core/Classes/Utility/RootlineUtility.php +++ b/typo3/sysext/core/Classes/Utility/RootlineUtility.php @@ -286,7 +286,7 @@ class RootlineUtility if (!empty($configuration['MM']) && !empty($configuration['type']) && in_array($configuration['type'], ['select', 'inline', 'group'])) { return true; } - if (!empty($configuration['foreign_field']) && !empty($configuration['type']) && in_array($configuration['type'], ['select', 'inline'])) { + if (!empty($configuration['foreign_field']) && !empty($configuration['type']) && in_array($configuration['type'], ['select', 'inline', 'file'])) { return true; } if (($configuration['type'] ?? '') === 'category' && ($configuration['relationship'] ?? '') === 'manyToMany') { diff --git a/typo3/sysext/core/Configuration/DefaultConfiguration.php b/typo3/sysext/core/Configuration/DefaultConfiguration.php index 1149a583276242057139e6c776e9f82c86a29cee..cd04f4aef107cc91c6b77ffb46f51a8e4e20f87a 100644 --- a/typo3/sysext/core/Configuration/DefaultConfiguration.php +++ b/typo3/sysext/core/Configuration/DefaultConfiguration.php @@ -665,6 +665,11 @@ return [ \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInlineConfiguration::class, ], ], + \TYPO3\CMS\Backend\Form\FormDataProvider\TcaFiles::class => [ + 'depends' => [ + \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline::class, + ], + ], \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInputPlaceholders::class => [ 'depends' => [ \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInlineConfiguration::class, @@ -890,6 +895,11 @@ return [ \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInlineConfiguration::class, ], ], + \TYPO3\CMS\Backend\Form\FormDataProvider\TcaFiles::class => [ + 'depends' => [ + \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline::class, + ], + ], \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInputPlaceholders::class => [ 'depends' => [ \TYPO3\CMS\Backend\Form\FormDataProvider\SiteResolving::class, @@ -976,6 +986,11 @@ return [ \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInlineConfiguration::class, ], ], + \TYPO3\CMS\Backend\Form\FormDataProvider\TcaFiles::class => [ + 'depends' => [ + \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline::class, + ], + ], ], 'siteConfiguration' => [ \TYPO3\CMS\Backend\Form\FormDataProvider\InitializeProcessedTca::class => [], diff --git a/typo3/sysext/core/Configuration/TCA/be_users.php b/typo3/sysext/core/Configuration/TCA/be_users.php index fe22a0bd9b2ce033c7a10832e4fd2d8da2b9fffc..0bcf831bdbe5dc04e708af6e7825cf92b7a858b4 100644 --- a/typo3/sysext/core/Configuration/TCA/be_users.php +++ b/typo3/sysext/core/Configuration/TCA/be_users.php @@ -97,11 +97,11 @@ return [ ], 'avatar' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.avatar', - 'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig( - 'avatar', - ['maxitems' => 1], - $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] - ), + 'config' => [ + 'type' => 'file', + 'maxitems' => 1, + 'allowed' => 'common-image-types', + ], ], 'db_mountpoints' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.options_db_mounts', diff --git a/typo3/sysext/core/Configuration/TCA/pages.php b/typo3/sysext/core/Configuration/TCA/pages.php index 2307c76a3f1e89a5f4bf4044c114d62d4b99d59e..530f784a744b7db7ba08ed1b0a72bda707556152 100644 --- a/typo3/sysext/core/Configuration/TCA/pages.php +++ b/typo3/sysext/core/Configuration/TCA/pages.php @@ -671,49 +671,47 @@ return [ 'media' => [ 'exclude' => true, 'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.media', - 'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig( - 'media', - [ - // Use the imageoverlayPalette instead of the basicoverlayPalette - 'overrideChildTca' => [ - 'types' => [ - '0' => [ - 'showitem' => ' + 'config' => [ + 'type' => 'file', + 'behaviour' => [ + 'allowLanguageSynchronization' => true, + ], + // Use the imageoverlayPalette instead of the basicoverlayPalette + 'overrideChildTca' => [ + 'types' => [ + '0' => [ + 'showitem' => ' --palette--;;imageoverlayPalette, --palette--;;filePalette', - ], - \TYPO3\CMS\Core\Resource\File::FILETYPE_TEXT => [ - 'showitem' => ' + ], + \TYPO3\CMS\Core\Resource\File::FILETYPE_TEXT => [ + 'showitem' => ' --palette--;;imageoverlayPalette, --palette--;;filePalette', - ], - \TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [ - 'showitem' => ' + ], + \TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [ + 'showitem' => ' --palette--;;imageoverlayPalette, --palette--;;filePalette', - ], - \TYPO3\CMS\Core\Resource\File::FILETYPE_AUDIO => [ - 'showitem' => ' + ], + \TYPO3\CMS\Core\Resource\File::FILETYPE_AUDIO => [ + 'showitem' => ' --palette--;;audioOverlayPalette, --palette--;;filePalette', - ], - \TYPO3\CMS\Core\Resource\File::FILETYPE_VIDEO => [ - 'showitem' => ' + ], + \TYPO3\CMS\Core\Resource\File::FILETYPE_VIDEO => [ + 'showitem' => ' --palette--;;videoOverlayPalette, --palette--;;filePalette', - ], - \TYPO3\CMS\Core\Resource\File::FILETYPE_APPLICATION => [ - 'showitem' => ' + ], + \TYPO3\CMS\Core\Resource\File::FILETYPE_APPLICATION => [ + 'showitem' => ' --palette--;;imageoverlayPalette, --palette--;;filePalette', - ], ], ], - 'behaviour' => [ - 'allowLanguageSynchronization' => true, - ], - ] - ), + ], + ], ], 'is_siteroot' => [ 'exclude' => true, diff --git a/typo3/sysext/core/Configuration/TCA/sys_file_collection.php b/typo3/sysext/core/Configuration/TCA/sys_file_collection.php index 93bc6925c591265dfed65d3bae4b7b8129b7af28..26804de41848fc6a821c4546e165c5bf5639d27d 100644 --- a/typo3/sysext/core/Configuration/TCA/sys_file_collection.php +++ b/typo3/sysext/core/Configuration/TCA/sys_file_collection.php @@ -100,7 +100,9 @@ return [ ], 'files' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_collection.files', - 'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig('files'), + 'config' => [ + 'type' => 'file', + ], ], 'title' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_collection.title', diff --git a/typo3/sysext/core/Configuration/TCA/sys_file_reference.php b/typo3/sysext/core/Configuration/TCA/sys_file_reference.php index 8ec0dc09655d8c32e2f9654964e867274c300410..133429650faedee4ed0186f55cec6e1914cd61f2 100644 --- a/typo3/sysext/core/Configuration/TCA/sys_file_reference.php +++ b/typo3/sysext/core/Configuration/TCA/sys_file_reference.php @@ -4,13 +4,6 @@ return [ 'ctrl' => [ 'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference', 'label' => 'uid_local', - 'formattedLabel_userFunc' => 'TYPO3\\CMS\\Core\\Resource\\Service\\UserFileInlineLabelService->getInlineLabel', - 'formattedLabel_userFunc_options' => [ - 'sys_file' => [ - 'title', - 'name', - ], - ], 'tstamp' => 'tstamp', 'crdate' => 'crdate', 'type' => 'uid_local:type', @@ -104,14 +97,6 @@ return [ 'default' => 0, ], ], - 'table_local' => [ - 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.table_local', - 'config' => [ - 'type' => 'input', - 'size' => 20, - 'default' => 'sys_file', - ], - ], 'title' => [ 'l10n_mode' => 'prefixLangTitle', 'exclude' => true, diff --git a/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-98479-RemovedFileReferenceRelatedFunctionality.rst b/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-98479-RemovedFileReferenceRelatedFunctionality.rst new file mode 100644 index 0000000000000000000000000000000000000000..c3577e224d428c14e0842ff1aade1c5400504d93 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-98479-RemovedFileReferenceRelatedFunctionality.rst @@ -0,0 +1,65 @@ +.. include:: /Includes.rst.txt + +.. _breaking-98479-1664622195: + +=============================================================== +Breaking: #98479 - Removed file reference related functionality +=============================================================== + +See :issue:`98479` + +Description +=========== + +With the introduction of the new TCA type :php:`file`, a couple of cross +dependencies have been removed, mainly related to FormEngine. + +The :php:`customControls` hook option is not available for the new +TCA type :php:`file`. It has been replaced by the new PSR-14 +:php:`CustomFileControlsEvent` for this use case. + +The field :sql:`table_local` of table :sql:`sys_file_reference`: is no longer +evaluated by TYPO3 and has therefore been removed. + +The following options are no longer evaluated for TCA type :php:`inline`: + +- :php:`[appearance][headerThumbnail]` +- :php:`[appearance][fileUploadAllowed]` +- :php:`[appearance][fileByUrlAllowed]` + +A TCA migration is in place, removing those values from custom configurations. + +Impact +====== + +Adding custom controls with the :php:`customControls` option does no longer +work for FAL fields. + +Using the :sql:`table_local` field of table :sql:`sys_file_reference` does +no longer work and might lead to database errors. + +Using one of the mentioned :php:`[appearance]` TCA options does no longer +have any effect. + +Affected installations +====================== + +All installations making use of the :php:`customControls` option for FAL +fields, directly using the sql:`table_local` field of table +:sql:`sys_file_reference` or using one of the mentioned :php:`[appearance]` +TCA options for TCA type :php:`inline` fields. + +Migration +========= + +Migrate corresponding user functions for the :php:`customControls` option to +a PSR-14 event listeners of the +:doc:`CustomFileControlsEvent <../12.0/Feature-98479-NewTCATypeFile.rst>`. + +Remove any usage of the :sql:`table_local` field of +table :sql:`sys_file_reference` in custom extension code. + +Remove the mentioned :php:`[appearance]` TCA options from your custom TCA +configurations. + +.. index:: Backend, Database, FAL, PHP-API, TCA, PartiallyScanned, ext:backend diff --git a/typo3/sysext/core/Documentation/Changelog/12.0/Deprecation-98479-DeprecatedFileReferenceRelatedFunctionality.rst b/typo3/sysext/core/Documentation/Changelog/12.0/Deprecation-98479-DeprecatedFileReferenceRelatedFunctionality.rst new file mode 100644 index 0000000000000000000000000000000000000000..62475466c287d78c17c2ebf54a50d2abbe9b53a5 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/12.0/Deprecation-98479-DeprecatedFileReferenceRelatedFunctionality.rst @@ -0,0 +1,59 @@ +.. include:: /Includes.rst.txt + +.. _deprecation-98479-1664622350: + +===================================================================== +Deprecation: #98479 - Deprecated file reference related functionality +===================================================================== + +See :issue:`98479` + +Description +=========== + +With the introduction of the new TCA type :php:`file`, a couple of cross +dependencies have been deprecated, mainly related to FormEngine. + +The :php:`UserFileInlineLabelService` class has been deprecated, since it was +only used for generating the inline label for file references in TCA type +:php:`inline`. This is now handled by the new TCA type :php:`file` directly. + +The :php:`FileExtensionFilter->filterInlineChildren()` method, which was +previously used as :php:`[filter][userFunc]` to filter the available +file extensions in FormEngine as well as :php:`DataHandler` has been +deprecated. This is now done internally. + +The :php:`ExtensionManagementUtility::getFileFieldTCAConfig()` method, which +was usually used to simplify configuration of FAL fields in TCA has been +deprecated as well, since the applied configuration is now handled internally. + +Impact +====== + +Instantiating the :php:`UserFileInlineLabelService` class, as well as +calling the :php:`FileExtensionFilter->filterInlineChildren()` and +:php:`ExtensionManagementUtility::getFileFieldTCAConfig()` methods will +trigger a PHP :php:`E_USER_DEPRECATED` level error. The extension scanner +also reports any usage. + +Affected installations +====================== + +All installations with extensions using the :php:`UserFileInlineLabelService` +class or one of the mentioned methods. + +Migration +========= + +Remove any usage of the :php:`UserFileInlineLabelService` class. There is no +migration available, since this FAL specific functionality is now handled +internally. + +Replace any usage of :php:`FileExtensionFilter->filterInlineChildren()` with +:php:`FileExtensionFilter->filter()`. However, usage of this method in custom +extension code should usually not be necessary. + +Replace any usage of :php:`ExtensionManagementUtility::getFileFieldTCAConfig()` +by directly using the new TCA type :doc:`file <../12.0/Feature-98479-NewTCATypeFile.rst>`. + +.. index:: Backend, Database, FAL, PHP-API, TCA, PartiallyScanned, ext:backend diff --git a/typo3/sysext/core/Documentation/Changelog/12.0/Feature-98479-NewTCATypeFile.rst b/typo3/sysext/core/Documentation/Changelog/12.0/Feature-98479-NewTCATypeFile.rst new file mode 100644 index 0000000000000000000000000000000000000000..bb811dd108bb7e2d587d1b009df1ebea2ea00356 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/12.0/Feature-98479-NewTCATypeFile.rst @@ -0,0 +1,200 @@ +.. include:: /Includes.rst.txt + +.. _feature-98479-1664537749: + +===================================== +Feature: #98479 - New TCA type "file" +===================================== + +See :issue:`98479` + +Description +=========== + +A new TCA field type called :php:`file` has been added to TYPO3 Core. Its +main purpose is to simplify the TCA configuration for adding file reference +fields to records. It therefore supersedes the usage of TCA type :php:`inline` +with :php:`foreign_table` set to :php:`sys_file_reference`, which had previously +usually been configured using the now deprecated API method +:php:`ExtensionManagementUtility->getFileFieldTCAConfig()` for this use case. + +This helps on determination of the semantic meaning and also allows to +reduce internal cross dependencies between TCA type `inline` and FAL. + +The new TCA type :php:`file` features the following column configuration: + +- :php:`allowed` +- :php:`appearance`: :php:`collapseAll`, :php:`expandSingle`, :php:`createNewRelationLinkTitle`, :php:`useSortable`, :php:`enabledControls`, :php:`headerThumbnail`, :php:`fileUploadAllowed`, :php:`fileByUrlAllowed`, :php:`elementBrowserEnabled`, :php:`showPossibleLocalizationRecords`, :php:`showAllLocalizationLink`, :php:`showSynchronizationLink`, :php:`showFileSelectors` +- :php:`behaviour`: :php:`allowLanguageSynchronization`, :php:`disableMovingChildrenWithParent`, :php:`enableCascadingDelete` +- :php:`disallowed` +- :php:`fieldInformation` +- :php:`fieldWizard` +- :php:`maxitems` +- :php:`minitems` +- :php:`overrideChildTca` +- :php:`readOnly` + +.. note:: + + The option :php:`showFileSelectors` can be used to define whether the + file selectors, such as "Select & upload files" are displayed. This is + similar to the the :php:`showPossibleRecordsSelector` option, available + for TCA type :php:`inline`. + +The following column configuration can be overwritten by Page TSconfig: + +- :typoscript:`appearance` +- :typoscript:`behaviour` +- :typoscript:`maxitems` +- :typoscript:`minitems` +- :typoscript:`readOnly` + +A possible migration using the API method therefore looks like the following: + +.. code-block:: php + + // Before + 'columns' => [ + 'image' => [ + 'label' => 'My image', + 'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig( + 'image', + [ + 'maxitems' => 6, + ], + $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] + ), + ], + ], + + // After + 'columns' => [ + 'image' => [ + 'label' => 'My image', + 'config' => [ + 'type' => 'file', + 'maxitems' => 6, + 'allowed' => 'common-image-types' + ], + ], + ], + +The example uses the :php:`common-image-types` placeholder for the +:php:`allowed` option. This placeholder is internally replaced and +helps to further reduce the usage of :php:`$GLOBALS`. Further placeholders +are :php:`common-text-types` and :php:`common-media-types`. It's possible +to use multiple placeholders. It's also possible to mix them with single +file extensions. Additionally, it's also possible to define the file +extensions as `array`. + +Another example without usage of the API method would therefore look like this: + +.. code-block:: php + + // Before + 'columns' => [ + 'image' => [ + 'label' => 'My image', + 'config' => [ + 'type' => 'inline', + 'foreign_table' => 'sys_file_reference', + 'foreign_field' => 'uid_foreign', + 'foreign_sortby' => 'sorting_foreign', + 'foreign_table_field' => 'tablenames', + 'foreign_match_fields' => [ + 'fieldname' => 'image', + ], + 'foreign_label' => 'uid_local', + 'foreign_selector' => 'uid_local', + 'overrideChildTca' => [ + 'columns' => [ + 'uid_local' => [ + 'config' => [ + 'appearance' => [ + 'elementBrowserType' => 'file', + 'elementBrowserAllowed' => 'jpg,png,gif', + ], + ], + ], + ], + ], + ] + ], + ], + + // After + 'columns' => [ + 'image' => [ + 'label' => 'My image', + 'config' => [ + 'type' => 'file', + 'allowed' => ['jpg','png','gif'], + ], + ], + ], + +Together with the new TCA type, three new PSR-14 Events have been introduced: + +* :php:`TYPO3\CMS\Backend\Form\Event\CustomFileControlsEvent` +* :php:`TYPO3\CMS\Backend\Form\Event\ModifyFileReferenceControlsEvent` +* :php:`TYPO3\CMS\Backend\Form\Event\ModifyFileReferenceEnabledControlsEvent` + +CustomFileControlsEvent +======================= + +Listeners to this Event will be able to add custom controls to a TCA type +:php:`file` field in FormEngine. This replaces the :php:`customControls` +hook option, which is only available for TCA type :php:`inline`. + +The new event provides the following methods: + +- :php:`getResultArray()`: Returns the whole result array +- :php:`setResultArray(array $resultArray)`: Allows to overwrite the result array, e.g. to add additional JS modules +- :php:`getControls()`: Returns all configured custom controls +- :php:`setControls()`: Overwrites the custom controls +- :php:`addControl()`: Adds a custom control. It's recommended to set the optional :php:`$identifier` argument. +- :php:`removeControl()`: Removes a custom control. This only works in case the custom control was added with an identifier. +- :php:`getTableName()`: Returns the table name in question +- :php:`getFieldName()`: Returns the field name in question +- :php:`getDatabaseRow()`: Returns the database row of the record in question +- :php:`getFieldConfig()`: Returns the fields' TCA configuration +- :php:`getFormFieldIdentifier()`: Returns the form elements' identifier +- :php:`getFormFieldName()`: Returns the form elements' name + +.. note:: + + Custom controls are always displayed below the file references. In contrast + to the selectors, e.g. "Select & upload files" are custom controls + independent of the :php:`readonly` and :php:`showFileSelectors` options. + This means, you have full control in which scenario your custom controls + are being displayed. + +ModifyFileReferenceControlsEvent +================================ + +Listeners to this Event will be able to modify the controls of a single +file reference of a TCA type `file` field. This event is similar to the +:php:`ModifyInlineElementControlsEvent`, which is only available for TCA +type `inline`. See corresponding PHP class or the other +:doc:`changelog <../12.0/Feature-97231-PSR-14EventsForModifyingInlineElementControls>` +for more information about available methods and their usage. + +ModifyFileReferenceEnabledControlsEvent +======================================= + +Listeners to this Event will be able to modify the state (enabled or disabled) +for the controls of a single file reference of a TCA type `file` field. This +event is similar to the :php:`ModifyInlineElementEnabledControlsEvent`, which +is only available for TCA type `inline`. See corresponding PHP class or the +other :doc:`changelog <../12.0/Feature-97231-PSR-14EventsForModifyingInlineElementControls>` +for more information about available methods and their usage. + +Impact +====== + +It's now possible to simplify the TCA configuration for file reference +fields, using the new TCA type `file`. Three new PSR-14 Events allow to +modify available controls of the TCA field as well as the related file +references. + +.. index:: Backend, FAL, PHP-API, TCA, ext:backend diff --git a/typo3/sysext/core/Resources/Private/Language/locallang_tca.xlf b/typo3/sysext/core/Resources/Private/Language/locallang_tca.xlf index 7f389f0f553390a4d3322179005248a2e3797f2d..eb5aa0e0cbad80f1234739a9a35025bb612eb823 100644 --- a/typo3/sysext/core/Resources/Private/Language/locallang_tca.xlf +++ b/typo3/sysext/core/Resources/Private/Language/locallang_tca.xlf @@ -522,9 +522,6 @@ <trans-unit id="sys_file_reference.sorting_foreign" resname="sys_file_reference.sorting_foreign"> <source>Sorting foreign</source> </trans-unit> - <trans-unit id="sys_file_reference.table_local" resname="sys_file_reference.table_local"> - <source>Local table</source> - </trans-unit> <trans-unit id="sys_file_reference.basicoverlayPalette" resname="sys_file_reference.basicoverlayPalette"> <source>File Metadata</source> </trans-unit> diff --git a/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/InlineFalCest.php b/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/FileCest.php similarity index 88% rename from typo3/sysext/core/Tests/Acceptance/Application/FormEngine/InlineFalCest.php rename to typo3/sysext/core/Tests/Acceptance/Application/FormEngine/FileCest.php index a7be00465210024e98aa12229c30e77d1918d5a8..274c541b6cea819ac989c581b5fffe4e5570e8b3 100644 --- a/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/InlineFalCest.php +++ b/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/FileCest.php @@ -22,15 +22,15 @@ use TYPO3\CMS\Core\Tests\Acceptance\Support\Helper\ModalDialog; use TYPO3\CMS\Core\Tests\Acceptance\Support\Helper\PageTree; /** - * Tests for inline fal + * Tests for type=file (FAL) */ -class InlineFalCest +class FileCest { protected static string $filenameSelector = '.form-irre-header-body > span > dl.row:first-child > dd.col'; protected static string $saveButtonLink = '//*/button[@name="_savedok"][1]'; /** - * Open styleguide inline fal page in list module + * Open styleguide file page in list module */ public function _before(ApplicationTester $I, PageTree $pageTree): void { @@ -38,11 +38,11 @@ class InlineFalCest $I->click('List'); $I->waitForElement('svg .nodes .node'); - $pageTree->openPath(['styleguide TCA demo', 'inline fal']); + $pageTree->openPath(['styleguide TCA demo', 'file']); $I->switchToContentFrame(); - $I->waitForText('inline fal', 20); - $editRecordLinkCssPath = '#recordlist-tx_styleguide_inline_fal a[aria-label="Edit record"]'; + $I->waitForText('file', 20); + $editRecordLinkCssPath = '#recordlist-tx_styleguide_file a[aria-label="Edit record"]'; $I->click($editRecordLinkCssPath); $I->waitForText('Edit Form', 3, 'h1'); } @@ -70,7 +70,7 @@ class InlineFalCest public function deleteFalRelation(ApplicationTester $I, ModalDialog $modalDialog): void { - $deleteButtonSelector = '.tab-content .t3js-editform-delete-inline-record'; + $deleteButtonSelector = '.tab-content .t3js-editform-delete-file-reference'; $filename = $I->grabTextFrom(self::$filenameSelector); $I->click($deleteButtonSelector); diff --git a/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/NullPlaceholderCest.php b/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/NullPlaceholderCest.php index 8611c01ad4a5230359291814a822275ce2786074..b6280016863bab98f9848f60eee32131322bea4a 100644 --- a/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/NullPlaceholderCest.php +++ b/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/NullPlaceholderCest.php @@ -43,11 +43,11 @@ class NullPlaceholderCest { $I->amGoingTo('Check if deactivating null checkboxes marks as "changed"'); - $editRecordLinkCssPath = '#recordlist-tx_styleguide_inline_fal a[aria-label="Edit record"]'; + $editRecordLinkCssPath = '#recordlist-tx_styleguide_file a[aria-label="Edit record"]'; $I->click($editRecordLinkCssPath); $I->waitForElementNotVisible('#t3js-ui-block'); - $I->waitForText('Edit Form engine - inline fal "1" on page "inline fal"'); + $I->waitForText('Edit Form engine - file "1" on page "file"'); $I->click('typical fal'); $I->click('.form-irre-header'); $I->waitForElementNotVisible('.nprogress-custom-parent'); @@ -73,8 +73,8 @@ class NullPlaceholderCest $I->switchToMainFrame(); $I->click('List'); $I->waitForElement('svg .nodes .node'); - $pageTree->openPath(['styleguide TCA demo', 'inline fal']); + $pageTree->openPath(['styleguide TCA demo', 'file']); $I->switchToContentFrame(); - $I->waitForText('inline fal'); + $I->waitForText('file'); } } diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/FlexformIrre/DataSet/ImportDefault.csv b/typo3/sysext/core/Tests/Functional/DataHandling/FlexformIrre/DataSet/ImportDefault.csv index 21edd416b0818467ed3db584a1bd7811dda5832d..e8c489b68d4cd8ec89f2c345c9aee3cd190d4eb1 100644 --- a/typo3/sysext/core/Tests/Functional/DataHandling/FlexformIrre/DataSet/ImportDefault.csv +++ b/typo3/sysext/core/Tests/Functional/DataHandling/FlexformIrre/DataSet/ImportDefault.csv @@ -13,8 +13,8 @@ ,"uid","pid","storage","identifier","name",,,,,,,,, ,20,0,1,"/typo3-logo.png","typo3-logo.png",,,,,,,,, "sys_file_reference",,,,,,,,,,,,,, -,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid",, -,1,1,20,100,"tt_content","files",1,"sys_file",0,0,0,0,, +,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid",, +,1,1,20,100,"tt_content","files",1,0,0,0,0,, "sys_refindex",,,,,,,,,,,,,, ,"hash","tablename","recuid","field","flexpointer","softref_key","softref_id","sorting","workspace","ref_table","ref_uid","ref_string",, ,"0ad00e77a175a4a5d134cc2b115839fd","sys_file",20,"storage",,,,0,0,"sys_file_storage",1,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/DataSet/ImportDefault.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/DataSet/ImportDefault.csv index a156b6b56549ee55c25cf91b531f18dd729e2105..02927690a7100e9c25cbc1ff94bf82ef6b8036de 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/DataSet/ImportDefault.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/DataSet/ImportDefault.csv @@ -13,11 +13,11 @@ ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link","l10n_diffsource" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link","l10n_diffsource" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,, "tt_content",,,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/DataSet/ImportDefaultWorkspaces.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/DataSet/ImportDefaultWorkspaces.csv index 89870306468efe08b688db532a8c105389c898d4..8332a6e64b712785e3eddd493edc3115d3c11baa 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/DataSet/ImportDefaultWorkspaces.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/DataSet/ImportDefaultWorkspaces.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link","l10n_diffsource" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link","l10n_diffsource" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,, "tt_content",,,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/changeContentSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/changeContentSorting.csv index bbb752715c173190770f05e55bf6697671e1894b..ed4c9f92d3a74aec2024de686812460aedd023c5 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/changeContentSorting.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/changeContentSorting.csv @@ -13,11 +13,11 @@ ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,, ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,, ,330,89,768,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/copyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/copyContent.csv index 01cbaefa9e725367ea5a2c2bf384cb72b87eb977..36428e525bb5a81195027a7d11f5099fba400dab 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/copyContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/copyContent.csv @@ -13,13 +13,13 @@ ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,, ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,0,0,0,0,0,0,21,332,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,131,89,0,0,0,0,0,0,0,1,332,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,0,0,0,0,0,0,21,332,"tt_content","image",1,"Taken at T3BOARD",,, +,131,89,0,0,0,0,0,0,0,1,332,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,, ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/copyContentToLanguage.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/copyContentToLanguage.csv index 725acbd7a93deb986ebf8532ca8994199ef0086f..a4827a604369b7d2a257ebdf31c1682a906eeb27 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/copyContentToLanguage.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/copyContentToLanguage.csv @@ -14,13 +14,13 @@ ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,, ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,1,0,0,0,0,0,21,332,"tt_content","image",1,"sys_file","[Translate to Dansk:] Taken at T3BOARD",,, -,131,89,0,1,0,0,0,0,0,1,332,"tt_content","image",2,"sys_file","[Translate to Dansk:] This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,1,0,0,0,0,0,21,332,"tt_content","image",1,"[Translate to Dansk:] Taken at T3BOARD",,, +,131,89,0,1,0,0,0,0,0,1,332,"tt_content","image",2,"[Translate to Dansk:] This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,, ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/createContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/createContentWFileReference.csv index febd26ed6a6dd605c37918d5abad169a3bf3426d..731a11312c5cc2199e064a3577cdd241100a572b 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/createContentWFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/createContentWFileReference.csv @@ -13,12 +13,12 @@ ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,, ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,0,0,0,0,0,0,1,332,"tt_content","image",1,"sys_file","Image #1",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,0,0,0,0,0,0,1,332,"tt_content","image",1,"Image #1",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,, ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/createContentWFileReferenceNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/createContentWFileReferenceNDeleteFileReference.csv index 72853835b64c734029c0f5ee09fbded3da897fe5..bdf9f266b79d8185eb35160c591655579b1d289a 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/createContentWFileReferenceNDeleteFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/createContentWFileReferenceNDeleteFileReference.csv @@ -13,12 +13,12 @@ ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,, ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,1,0,0,0,0,0,0,1,332,"tt_content","image",1,"sys_file","Image #1",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,1,0,0,0,0,0,0,1,332,"tt_content","image",1,"Image #1",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/deleteContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/deleteContent.csv index a9f6a1a9e31041c9bdd7b1a57556047b1328ec0f..4c972c9c42ec69ea7f34cc4af7d5f8582f63176a 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/deleteContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/deleteContent.csv @@ -13,11 +13,11 @@ ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,, ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,, ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/localizeContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/localizeContent.csv index 0e8a90429ba50ec4cf9492fbc47c073f549158f5..5a6e4ddb6dee5af2f75d37f9b2c7da11ce0fc3bb 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/localizeContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/localizeContent.csv @@ -14,13 +14,13 @@ ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,, ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,1,128,0,0,0,0,21,332,"tt_content","image",1,"sys_file","[Translate to Dansk:] Taken at T3BOARD",,, -,131,89,0,1,129,0,0,0,0,1,332,"tt_content","image",2,"sys_file","[Translate to Dansk:] This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,1,128,0,0,0,0,21,332,"tt_content","image",1,"[Translate to Dansk:] Taken at T3BOARD",,, +,131,89,0,1,129,0,0,0,0,1,332,"tt_content","image",2,"[Translate to Dansk:] This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,, ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContent.csv index 8105472eac756a4e28ace3de792d86dfbba4ba53..aaaabdaeb2da6882ff4f53dda021a56b25bf8285 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContent.csv @@ -13,11 +13,11 @@ ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,, ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,, ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNAddFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNAddFileReference.csv index d19f3a80046812db783d61400f5f84225f6f2fc8..d4a98600a85ac69e0a35ffe71aae3b7d26445e46 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNAddFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNAddFileReference.csv @@ -13,12 +13,12 @@ ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,, ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,0,0,0,0,0,0,1,331,"tt_content","image",3,"sys_file","Image #3",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,0,0,0,0,0,0,1,331,"tt_content","image",3,"Image #3",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,, ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNDeleteAllFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNDeleteAllFileReference.csv index 9bb8ff1e336f78b8ef9490f85ae38eef86e42e03..c5a6ba0275c5fbecc884aed910f4c4f3ac18c5d4 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNDeleteAllFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNDeleteAllFileReference.csv @@ -13,11 +13,11 @@ ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,, ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,, ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNDeleteFileReference.csv index 864d37a8b0e6787582ef013dea35c7b5f5bd7464..963115ffa644bfd6cfc249463734f4268183ef33 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNDeleteFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNDeleteFileReference.csv @@ -13,11 +13,11 @@ ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,, ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",1,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",1,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,, ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentWFileReference.csv index 8ed5b887fb23d4df258f05738b945799abb25b34..c158e98ace11e873c98b379b1517e5a1af7349ec 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentWFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentWFileReference.csv @@ -13,11 +13,11 @@ ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,, ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","Image #1",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"Image #1",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,, ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/moveContentToDifferentPage.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/moveContentToDifferentPage.csv index e97f5d00899c49e91c5890d1e32ccddeab93222d..2a09aa18083270747fddcd953ccb6cfc8b090e2b 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/moveContentToDifferentPage.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/moveContentToDifferentPage.csv @@ -13,11 +13,11 @@ ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,, ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,, ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/moveContentToDifferentPageNChangeSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/moveContentToDifferentPageNChangeSorting.csv index d467ab3a6599fb6a77ac6e8967e9c36472f74fee..227963285f2cd164101aafad8f05f5773c2d5cfd 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/moveContentToDifferentPageNChangeSorting.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/moveContentToDifferentPageNChangeSorting.csv @@ -13,11 +13,11 @@ ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,, ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,90,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,90,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,90,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,90,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,, ,330,90,512,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/changeContentSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/changeContentSorting.csv index 3a3338f7583d97d111a15e55774fdefa2a890836..21895dbe437ffa7dc650bf45941eda16717e04e9 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/changeContentSorting.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/changeContentSorting.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/copyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/copyContent.csv index 3a3338f7583d97d111a15e55774fdefa2a890836..21895dbe437ffa7dc650bf45941eda16717e04e9 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/copyContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/copyContent.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/createContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/createContentWFileReference.csv index 3a3338f7583d97d111a15e55774fdefa2a890836..21895dbe437ffa7dc650bf45941eda16717e04e9 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/createContentWFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/createContentWFileReference.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/createContentWFileReferenceNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/createContentWFileReferenceNDeleteFileReference.csv index 3a3338f7583d97d111a15e55774fdefa2a890836..21895dbe437ffa7dc650bf45941eda16717e04e9 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/createContentWFileReferenceNDeleteFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/createContentWFileReferenceNDeleteFileReference.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/deleteContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/deleteContent.csv index 3a3338f7583d97d111a15e55774fdefa2a890836..21895dbe437ffa7dc650bf45941eda16717e04e9 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/deleteContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/deleteContent.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/localizeContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/localizeContent.csv index 98da3f0316719d23811718c5520d604837685ea0..c3062fa44e91a1c36656e93f97eebe912da7451b 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/localizeContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/localizeContent.csv @@ -21,11 +21,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContent.csv index 3a3338f7583d97d111a15e55774fdefa2a890836..21895dbe437ffa7dc650bf45941eda16717e04e9 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContent.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNAddFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNAddFileReference.csv index 3a3338f7583d97d111a15e55774fdefa2a890836..21895dbe437ffa7dc650bf45941eda16717e04e9 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNAddFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNAddFileReference.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNDeleteAllFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNDeleteAllFileReference.csv index 3a3338f7583d97d111a15e55774fdefa2a890836..21895dbe437ffa7dc650bf45941eda16717e04e9 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNDeleteAllFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNDeleteAllFileReference.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNDeleteFileReference.csv index 3a3338f7583d97d111a15e55774fdefa2a890836..21895dbe437ffa7dc650bf45941eda16717e04e9 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNDeleteFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNDeleteFileReference.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentWFileReference.csv index 3a3338f7583d97d111a15e55774fdefa2a890836..21895dbe437ffa7dc650bf45941eda16717e04e9 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentWFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentWFileReference.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/moveContentToDifferentPage.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/moveContentToDifferentPage.csv index 3a3338f7583d97d111a15e55774fdefa2a890836..21895dbe437ffa7dc650bf45941eda16717e04e9 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/moveContentToDifferentPage.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/moveContentToDifferentPage.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/moveContentToDifferentPageNChangeSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/moveContentToDifferentPageNChangeSorting.csv index 3a3338f7583d97d111a15e55774fdefa2a890836..21895dbe437ffa7dc650bf45941eda16717e04e9 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/moveContentToDifferentPageNChangeSorting.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/moveContentToDifferentPageNChangeSorting.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/changeContentSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/changeContentSorting.csv index fd80c6e2a67d5a2645b0d25136de366193c8bfc7..589bd43de805c7d5b1213cd2fe5b63721ef4582d 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/changeContentSorting.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/changeContentSorting.csv @@ -20,13 +20,13 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,0,0,1,0,0,127,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,131,89,0,0,0,1,0,0,126,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,0,0,1,0,0,127,21,330,"tt_content","image",1,"Kasper",,, +,131,89,0,0,0,1,0,0,126,1,330,"tt_content","image",2,"T3BOARD",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/copyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/copyContent.csv index 2b1baf7abe131b74eda9241a573550ec605d66e0..fcdd6cd16dc29a61ee13cf6c301b7b89512dca8c 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/copyContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/copyContent.csv @@ -20,13 +20,13 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,0,0,1,1,0,0,21,332,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,131,89,0,0,0,1,1,0,0,1,332,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,0,0,1,1,0,0,21,332,"tt_content","image",1,"Taken at T3BOARD",,, +,131,89,0,0,0,1,1,0,0,1,332,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/createContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/createContentWFileReference.csv index dfabc7afddbb63bc43ab24d523ffa326fb8bd9c0..07fe6f89e5d6cdbfd083babba9a86cdd65ef2cc4 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/createContentWFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/createContentWFileReference.csv @@ -20,12 +20,12 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,0,0,1,1,0,0,1,332,"tt_content","image",1,"sys_file","Image #1",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,0,0,1,1,0,0,1,332,"tt_content","image",1,"Image #1",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/createContentWFileReferenceNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/createContentWFileReferenceNDeleteFileReference.csv index 3f3387daeaa61d8a65c7ab7604e68432cf29e8de..1949be6927edc6f995dea5ca037272ddc288bb44 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/createContentWFileReferenceNDeleteFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/createContentWFileReferenceNDeleteFileReference.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/deleteContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/deleteContent.csv index 15e20dd78aa58eda1b6b4a88c4050f3968cbaa54..50fd4434c77b2fe7fe8df603e213177c867b11cc 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/deleteContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/deleteContent.csv @@ -20,13 +20,13 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,0,0,1,2,0,128,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,131,89,0,0,0,1,2,0,129,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,0,0,1,2,0,128,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,131,89,0,0,0,1,2,0,129,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/localizeContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/localizeContent.csv index 58f6b2db83cce272faf0f981419a4fbc6e991540..823d98e38e9a6ba60349e924e97257afdb801fd1 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/localizeContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/localizeContent.csv @@ -21,13 +21,13 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,1,128,1,1,0,0,21,332,"tt_content","image",1,"sys_file","[Translate to Dansk:] Taken at T3BOARD",,, -,131,89,0,1,129,1,1,0,0,1,332,"tt_content","image",2,"sys_file","[Translate to Dansk:] This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,1,128,1,1,0,0,21,332,"tt_content","image",1,"[Translate to Dansk:] Taken at T3BOARD",,, +,131,89,0,1,129,1,1,0,0,1,332,"tt_content","image",2,"[Translate to Dansk:] This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContent.csv index 3f6af745d3506a6645836850b7ebd5e35a6a17c0..f8e4ac0b358c76d6c8304862ad6fdb6cfac48a5f 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContent.csv @@ -20,13 +20,13 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,0,0,1,0,0,128,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,131,89,0,0,0,1,0,0,129,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,0,0,1,0,0,128,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,131,89,0,0,0,1,0,0,129,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNAddFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNAddFileReference.csv index deff0ceb24e3c9d914f95a51a04990c3ad9a3e64..2d305a67ade48e32e2be93edd9de64b5b512fed4 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNAddFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNAddFileReference.csv @@ -20,14 +20,14 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,0,0,1,0,0,128,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,131,89,0,0,0,1,0,0,129,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,132,89,0,0,0,1,1,0,0,1,331,"tt_content","image",3,"sys_file","Image #3",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,0,0,1,0,0,128,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,131,89,0,0,0,1,0,0,129,1,331,"tt_content","image",2,"This is Kasper",,, +,132,89,0,0,0,1,1,0,0,1,331,"tt_content","image",3,"Image #3",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNDeleteAllFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNDeleteAllFileReference.csv index 961bac5f081f3d30c27310cc232bd9cba3c838c3..a6729f6470889697fb4e502c153cd060e4d73140 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNDeleteAllFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNDeleteAllFileReference.csv @@ -20,13 +20,13 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,0,0,1,2,0,129,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,131,89,0,0,0,1,2,0,128,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,0,0,1,2,0,129,1,331,"tt_content","image",2,"This is Kasper",,, +,131,89,0,0,0,1,2,0,128,21,331,"tt_content","image",1,"Taken at T3BOARD",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNDeleteFileReference.csv index 720e90523a9fc5d9c65661d0481883c922d7dc41..3fb3ac2a1ec7614c0a673fb0a4f28e1f560fe2cc 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNDeleteFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNDeleteFileReference.csv @@ -20,13 +20,13 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,0,0,1,0,0,129,1,331,"tt_content","image",1,"sys_file","This is Kasper",,, -,131,89,0,0,0,1,2,0,128,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,0,0,1,0,0,129,1,331,"tt_content","image",1,"This is Kasper",,, +,131,89,0,0,0,1,2,0,128,21,331,"tt_content","image",1,"Taken at T3BOARD",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentWFileReference.csv index 7e254b5d5d241394935ab1541a1cba1a43225336..6c3f3d093c0557f0a85e2910bfc1c25da1c02cdd 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentWFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentWFileReference.csv @@ -20,13 +20,13 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,0,0,1,0,0,128,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,131,89,0,0,0,1,0,0,129,1,331,"tt_content","image",2,"sys_file","Image #1",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,0,0,1,0,0,128,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,131,89,0,0,0,1,0,0,129,1,331,"tt_content","image",2,"Image #1",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/moveContentToDifferentPage.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/moveContentToDifferentPage.csv index 5616ed55fac27732c8db69ccab4b88810fa70230..336953e86f21f79d46e4f3f1a4c8f8114806f6c9 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/moveContentToDifferentPage.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/moveContentToDifferentPage.csv @@ -20,13 +20,13 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,90,0,0,0,1,4,0,128,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,131,90,0,0,0,1,4,0,129,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,90,0,0,0,1,4,0,128,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,131,90,0,0,0,1,4,0,129,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/moveContentToDifferentPageNChangeSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/moveContentToDifferentPageNChangeSorting.csv index 548abc790cbec1d473e6fcbe902db4a6b0e4309c..42b51569c69eb3bd1d68d8dd9ffc1e026896b325 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/moveContentToDifferentPageNChangeSorting.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/moveContentToDifferentPageNChangeSorting.csv @@ -20,15 +20,15 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,90,0,0,0,1,4,0,128,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,131,90,0,0,0,1,4,0,129,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,132,90,0,0,0,1,4,0,127,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,133,90,0,0,0,1,4,0,126,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,90,0,0,0,1,4,0,128,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,131,90,0,0,0,1,4,0,129,1,331,"tt_content","image",2,"This is Kasper",,, +,132,90,0,0,0,1,4,0,127,21,330,"tt_content","image",1,"Kasper",,, +,133,90,0,0,0,1,4,0,126,1,330,"tt_content","image",2,"T3BOARD",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/changeContentSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/changeContentSorting.csv index d000f128ef37f22f0f577478079343f61799e0ff..92fd2290bc0bbba90349f9b26209ee4226936573 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/changeContentSorting.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/changeContentSorting.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,768,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/copyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/copyContent.csv index f7d1066a736a9ee630481e3e32015b1ff412c68a..d248dd0d0daf42ba778c69ed9591502501d7708b 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/copyContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/copyContent.csv @@ -20,13 +20,13 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,0,0,0,0,0,0,21,332,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,131,89,0,0,0,0,0,0,0,1,332,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,0,0,0,0,0,0,21,332,"tt_content","image",1,"Taken at T3BOARD",,, +,131,89,0,0,0,0,0,0,0,1,332,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/createContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/createContentWFileReference.csv index 354483d046e33cb9e07aa97e069660993e05a643..1ae00eac28989843f5262f60fb67c95014dfadba 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/createContentWFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/createContentWFileReference.csv @@ -20,12 +20,12 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,0,0,0,0,0,0,1,332,"tt_content","image",1,"sys_file","Image #1",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,0,0,0,0,0,0,1,332,"tt_content","image",1,"Image #1",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/createContentWFileReferenceNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/createContentWFileReferenceNDeleteFileReference.csv index 72c2d7c516ec005b2f8c499a2180ff157bfd21ad..24c562a6e8acb6b6898f633d5a273e24f38922e3 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/createContentWFileReferenceNDeleteFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/createContentWFileReferenceNDeleteFileReference.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/deleteContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/deleteContent.csv index 61a0cfdd380d47bdc3f4c2df1895d06c6404536b..c804470d289bd31d12c89485c0d4c575d7bd8ab2 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/deleteContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/deleteContent.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/localizeContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/localizeContent.csv index bfcf01a1262b0369d40192a89822775e73aad622..a40f7107f9c21d3bf5ca2f3bfebd8e5eefb84515 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/localizeContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/localizeContent.csv @@ -21,13 +21,13 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,1,128,0,0,0,0,21,332,"tt_content","image",1,"sys_file","[Translate to Dansk:] Taken at T3BOARD",,, -,131,89,0,1,129,0,0,0,0,1,332,"tt_content","image",2,"sys_file","[Translate to Dansk:] This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,1,128,0,0,0,0,21,332,"tt_content","image",1,"[Translate to Dansk:] Taken at T3BOARD",,, +,131,89,0,1,129,0,0,0,0,1,332,"tt_content","image",2,"[Translate to Dansk:] This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContent.csv index 76ed244b715ffbcf12eef2e5c0da79b523ccb121..eb168714bae92665d17291b8ef06a7a1117b0bcc 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContent.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNAddFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNAddFileReference.csv index 4c1b80e494c41b56cb0d08c1963d87d24ee78bc5..a442bfcb6a0f779a3d1026e6ba0b43215223cf7b 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNAddFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNAddFileReference.csv @@ -20,12 +20,12 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,132,89,0,0,0,0,0,0,0,1,331,"tt_content","image",3,"sys_file","Image #3",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,132,89,0,0,0,0,0,0,0,1,331,"tt_content","image",3,"Image #3",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNDeleteAllFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNDeleteAllFileReference.csv index f54079c0549a513c0211e67a7d680bf20993e07d..22a11ed0382fcee0f12476b28d5a3ef508a79a82 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNDeleteAllFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNDeleteAllFileReference.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNDeleteFileReference.csv index 4eaae9b44016406b289a3239252be466ed0da742..9fe4cb370c02e2c6964e10e359b5640a2fadca50 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNDeleteFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNDeleteFileReference.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",1,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",1,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentWFileReference.csv index 1a5b7a6c9b4f5b93600f1cd682f8d1f2c33f17ed..2cd656ae2ba484b84e230369636ffa8e8b20e331 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentWFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentWFileReference.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","Image #1",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"Image #1",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/moveContentToDifferentPage.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/moveContentToDifferentPage.csv index c01bf9871bedc91eeb28b882d65d049d549a4cea..17aac23f6575f192b4bcd55c76dbdd93feff34a2 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/moveContentToDifferentPage.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/moveContentToDifferentPage.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/moveContentToDifferentPageNChangeSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/moveContentToDifferentPageNChangeSorting.csv index 46eaf5e869af85982e9a71ed626528f20efe82e4..52d1ecfe8a8d0058aa63bb5c5d1da8cf61c67250 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/moveContentToDifferentPageNChangeSorting.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/moveContentToDifferentPageNChangeSorting.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,90,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,90,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,90,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,90,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,90,512,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/changeContentSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/changeContentSorting.csv index fc9e1dd2216c04e3c6d8703603001d21129538ad..b3a4e948416238fc636cc7a465647934ec19bfe9 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/changeContentSorting.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/changeContentSorting.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link","l10n_diffsource" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link","l10n_diffsource" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,, "tt_content",,,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,, ,330,89,768,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/copyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/copyContent.csv index f7d1066a736a9ee630481e3e32015b1ff412c68a..d248dd0d0daf42ba778c69ed9591502501d7708b 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/copyContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/copyContent.csv @@ -20,13 +20,13 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,0,0,0,0,0,0,21,332,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,131,89,0,0,0,0,0,0,0,1,332,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,0,0,0,0,0,0,21,332,"tt_content","image",1,"Taken at T3BOARD",,, +,131,89,0,0,0,0,0,0,0,1,332,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/createContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/createContentWFileReference.csv index 354483d046e33cb9e07aa97e069660993e05a643..1ae00eac28989843f5262f60fb67c95014dfadba 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/createContentWFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/createContentWFileReference.csv @@ -20,12 +20,12 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,0,0,0,0,0,0,1,332,"tt_content","image",1,"sys_file","Image #1",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,0,0,0,0,0,0,1,332,"tt_content","image",1,"Image #1",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/createContentWFileReferenceNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/createContentWFileReferenceNDeleteFileReference.csv index 72c2d7c516ec005b2f8c499a2180ff157bfd21ad..24c562a6e8acb6b6898f633d5a273e24f38922e3 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/createContentWFileReferenceNDeleteFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/createContentWFileReferenceNDeleteFileReference.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/deleteContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/deleteContent.csv index 61a0cfdd380d47bdc3f4c2df1895d06c6404536b..c804470d289bd31d12c89485c0d4c575d7bd8ab2 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/deleteContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/deleteContent.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/localizeContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/localizeContent.csv index 967e6e95a684117760775750456c1d3c61891313..1c76806343044f1a84dd1701a3013013b45bd574 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/localizeContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/localizeContent.csv @@ -21,13 +21,13 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,130,89,0,1,128,0,0,0,0,21,332,"tt_content","image",1,"sys_file","[Translate to Dansk:] Taken at T3BOARD",,, -,131,89,0,1,129,0,0,0,0,1,332,"tt_content","image",2,"sys_file","[Translate to Dansk:] This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,130,89,0,1,128,0,0,0,0,21,332,"tt_content","image",1,"[Translate to Dansk:] Taken at T3BOARD",,, +,131,89,0,1,129,0,0,0,0,1,332,"tt_content","image",2,"[Translate to Dansk:] This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContent.csv index 76ed244b715ffbcf12eef2e5c0da79b523ccb121..eb168714bae92665d17291b8ef06a7a1117b0bcc 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContent.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContent.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNAddFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNAddFileReference.csv index 4c1b80e494c41b56cb0d08c1963d87d24ee78bc5..a442bfcb6a0f779a3d1026e6ba0b43215223cf7b 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNAddFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNAddFileReference.csv @@ -20,12 +20,12 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, -,132,89,0,0,0,0,0,0,0,1,331,"tt_content","image",3,"sys_file","Image #3",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, +,132,89,0,0,0,0,0,0,0,1,331,"tt_content","image",3,"Image #3",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNDeleteAllFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNDeleteAllFileReference.csv index f54079c0549a513c0211e67a7d680bf20993e07d..22a11ed0382fcee0f12476b28d5a3ef508a79a82 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNDeleteAllFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNDeleteAllFileReference.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNDeleteFileReference.csv index 4eaae9b44016406b289a3239252be466ed0da742..9fe4cb370c02e2c6964e10e359b5640a2fadca50 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNDeleteFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNDeleteFileReference.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",1,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",1,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentWFileReference.csv index 1a5b7a6c9b4f5b93600f1cd682f8d1f2c33f17ed..2cd656ae2ba484b84e230369636ffa8e8b20e331 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentWFileReference.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentWFileReference.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","Image #1",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"Image #1",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/moveContentToDifferentPage.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/moveContentToDifferentPage.csv index c01bf9871bedc91eeb28b882d65d049d549a4cea..17aac23f6575f192b4bcd55c76dbdd93feff34a2 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/moveContentToDifferentPage.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/moveContentToDifferentPage.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/moveContentToDifferentPageNChangeSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/moveContentToDifferentPageNChangeSorting.csv index 46eaf5e869af85982e9a71ed626528f20efe82e4..52d1ecfe8a8d0058aa63bb5c5d1da8cf61c67250 100644 --- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/moveContentToDifferentPageNChangeSorting.csv +++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/moveContentToDifferentPageNChangeSorting.csv @@ -20,11 +20,11 @@ ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,, -,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link" -,126,90,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,, -,127,90,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,, -,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,, -,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,, +,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link" +,126,90,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,, +,127,90,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,, +,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,, +,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,, "tt_content",,,,,,,,,,,,,,,,,,, ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,, ,330,90,512,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,, diff --git a/typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript b/typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript index 418661e3a90ea5421aca899b5947dcdc74b9ab83..dd48118b9cea9db5282258657947942ade2e1e25 100644 --- a/typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript +++ b/typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript @@ -12,7 +12,7 @@ config { pages = uid,_PAGES_OVERLAY_UID,pid,sorting,title sys_category = uid,_ORIG_uid,_LOCALIZED_UID,pid,sys_language_uid,title,parent,items,sys_language_uid sys_file = uid,_ORIG_uid,_LOCALIZED_UID,pid,title,sys_language_uid - sys_file_reference = uid,_ORIG_uid,_LOCALIZED_UID,title,description,alternative,link,missing,identifier,file,pid,sys_language_uid,title,parent,items,sys_language_uid,uid_local,uid_foreign,tablenames,fieldname,table_local + sys_file_reference = uid,_ORIG_uid,_LOCALIZED_UID,title,description,alternative,link,missing,identifier,file,pid,sys_language_uid,title,parent,items,sys_language_uid,uid_local,uid_foreign,tablenames,fieldname tt_content = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,header,categories,tx_testdatahandler_categories,tx_testdatahandler_category tx_testdatahandler_element = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title } diff --git a/typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php b/typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php index 021897a693d794bb668d24c008a2f54dd22fbf4f..9977747af9a9b53b795b6eab692f6c1a6611f202 100644 --- a/typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php +++ b/typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php @@ -1079,8 +1079,8 @@ class DataHandlerTest extends UnitTestCase '1' => ['table' => StringUtility::getUniqueId('bar_'), 'id' => 67], ]; - $mockDataHandler = $this->getAccessibleMock(DataHandler::class, ['getInlineFieldType', 'deleteAction', 'createRelationHandlerInstance'], [], '', false); - $mockDataHandler->expects(self::once())->method('getInlineFieldType')->willReturn('field'); + $mockDataHandler = $this->getAccessibleMock(DataHandler::class, ['getRelationFieldType', 'deleteAction', 'createRelationHandlerInstance'], [], '', false); + $mockDataHandler->expects(self::once())->method('getRelationFieldType')->willReturn('field'); $mockDataHandler->expects(self::once())->method('createRelationHandlerInstance')->willReturn($mockRelationHandler); $mockDataHandler->expects(self::never())->method('deleteAction'); $mockDataHandler->deleteRecord_procBasedOnFieldType($table, 42, 'bar', $conf); diff --git a/typo3/sysext/core/Tests/Unit/Migrations/TcaMigrationTest.php b/typo3/sysext/core/Tests/Unit/Migrations/TcaMigrationTest.php index f99f64932e494301f7a917655e77c1171a06eb57..79779b5cd3dfd48c6dc6ae5ce759cf7609e23b67 100644 --- a/typo3/sysext/core/Tests/Unit/Migrations/TcaMigrationTest.php +++ b/typo3/sysext/core/Tests/Unit/Migrations/TcaMigrationTest.php @@ -18,6 +18,7 @@ declare(strict_types=1); namespace TYPO3\CMS\Core\Tests\Unit\Migrations; use TYPO3\CMS\Core\Migrations\TcaMigration; +use TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; /** @@ -3109,4 +3110,381 @@ class TcaMigrationTest extends UnitTestCase $subject = new TcaMigration(); self::assertSame($expected, $subject->migrate($input)); } + + private function falHandlingInTypeInlineIsMigratedToTypeFileDataProvider(): iterable + { + yield 'Full example of type=inline with foreign_table=sys_file_reference migrated to type=file' => [ + 'input' => [ + 'aTable' => [ + 'columns' => [ + 'aColumn' => [ + 'config' => [ + 'type' => 'inline', + 'minitems' => 1, + 'maxitems' => 2, + 'foreign_field' => 'uid_foreign', + 'foreign_label' => 'uid_local', + 'foreign_match_fields' => [ + 'fieldname' => 'aColumn', + ], + 'foreign_selector' => 'uid_local', + 'foreign_unique' => 'uid_local', + 'foreign_sortby' => 'sorting_foreign', + 'foreign_table' => 'sys_file_reference', + 'foreign_table_field' => 'tablenames', + 'appearance' => [ + 'createNewRelationLinkTitle' => 'Add file', + 'enabledControls' => [ + 'delete' => true, + 'dragdrop' => true, + 'sort' => false, + 'hide' => true, + 'info' => true, + 'new' => false, + ], + 'headerThumbnail' => [ + 'field' => 'uid_local', + 'height' => '45m', + ], + 'showPossibleLocalizationRecords' => true, + 'useSortable' => true, + 'showNewRecordLink' => true, + 'newRecordLinkAddTitle' => true, + 'newRecordLinkTitle' => true, + 'levelLinksPosition' => 'both', + 'useCombination' => true, + 'suppressCombinationWarning' => true, + ], + 'filter' => [ + [ + 'userFunc' => FileExtensionFilter::class . '->filterInlineChildren', + 'parameters' => [ + 'allowedFileExtensions' => 'jpg,png', + 'disallowedFileExtensions' => '', + ], + ], + ], + 'overrideChildTca' => [ + 'columns' => [ + 'uid_local' => [ + 'config' => [ + 'appearance' => [ + 'elementBrowserAllowed' => 'jpg,png', + 'elementBrowserType' => 'file', + ], + ], + ], + ], + 'types' => [ + '0' => [ + 'showitem' => '--palette--;;somePalette', + ], + ], + ], + ], + ], + ], + ], + ], + 'expected' => [ + 'aTable' => [ + 'columns' => [ + 'aColumn' => [ + 'config' => [ + 'type' => 'file', + 'minitems' => 1, + 'maxitems' => 2, + 'appearance' => [ + 'createNewRelationLinkTitle' => 'Add file', + 'enabledControls' => [ + 'delete' => true, + 'dragdrop' => true, + 'sort' => false, + 'hide' => true, + 'info' => true, + ], + 'headerThumbnail' => [ + 'height' => '45m', + ], + 'showPossibleLocalizationRecords' => true, + 'useSortable' => true, + ], + 'overrideChildTca' => [ + 'types' => [ + '0' => [ + 'showitem' => '--palette--;;somePalette', + ], + ], + ], + 'allowed' => 'jpg,png', + ], + ], + ], + ], + ], + ]; + yield 'Allowed and disallowed list is migrated from unused filter' => [ + 'input' => [ + 'aTable' => [ + 'columns' => [ + 'aColumn' => [ + 'config' => [ + 'type' => 'inline', + 'foreign_table' => 'sys_file_reference', + 'filter' => [ + [ + 'userFunc' => FileExtensionFilter::class . '->filterInlineChildren', + 'parameters' => [ + 'allowedFileExtensions' => 'jpg,png', + 'disallowedFileExtensions' => 'pdf,pages', + ], + ], + ], + ], + ], + ], + ], + ], + 'expected' => [ + 'aTable' => [ + 'columns' => [ + 'aColumn' => [ + 'config' => [ + 'type' => 'file', + 'allowed' => 'jpg,png', + 'disallowed' => 'pdf,pages', + ], + ], + ], + ], + ], + ]; + yield 'Allowed list from filter takes precedence over element browser related option' => [ + 'input' => [ + 'aTable' => [ + 'columns' => [ + 'aColumn' => [ + 'config' => [ + 'type' => 'inline', + 'foreign_table' => 'sys_file_reference', + 'overrideChildTca' => [ + 'columns' => [ + 'uid_local' => [ + 'config' => [ + 'appearance' => [ + 'elementBrowserAllowed' => 'jpg,png', + ], + ], + ], + ], + ], + 'filter' => [ + [ + 'userFunc' => FileExtensionFilter::class . '->filterInlineChildren', + 'parameters' => [ + 'allowedFileExtensions' => 'pdf,docx', + ], + ], + ], + ], + ], + ], + ], + ], + 'expected' => [ + 'aTable' => [ + 'columns' => [ + 'aColumn' => [ + 'config' => [ + 'type' => 'file', + 'allowed' => 'pdf,docx', + ], + ], + ], + ], + ], + ]; + yield 'customControls hook is removed' => [ + 'input' => [ + 'aTable' => [ + 'columns' => [ + 'aColumn' => [ + 'config' => [ + 'type' => 'inline', + 'foreign_table' => 'sys_file_reference', + 'customControls' => [ + 'userFunc' => '->someFunc()', + ], + ], + ], + ], + ], + ], + 'expected' => [ + 'aTable' => [ + 'columns' => [ + 'aColumn' => [ + 'config' => [ + 'type' => 'file', + ], + ], + ], + ], + ], + 'The \'customControls\' option is not evaluated anymore', + ]; + yield 'renamed appearance options are migrated' => [ + 'input' => [ + 'aTable' => [ + 'columns' => [ + 'aColumn' => [ + 'config' => [ + 'type' => 'inline', + 'foreign_table' => 'sys_file_reference', + 'appearance' => [ + 'showPossibleRecordsSelector' => false, + ], + ], + ], + ], + ], + ], + 'expected' => [ + 'aTable' => [ + 'columns' => [ + 'aColumn' => [ + 'config' => [ + 'type' => 'file', + 'appearance' => [ + 'showFileSelectors' => false, + ], + ], + ], + ], + ], + ], + ]; + yield 'Usage of sys_file_reference as foreign_table without type=inline is still possible' => [ + 'input' => [ + 'aTable' => [ + 'columns' => [ + 'aColumn' => [ + 'config' => [ + 'type' => 'select', + 'foreign_table' => 'sys_file_reference', + ], + ], + ], + ], + ], + 'expected' => [ + 'aTable' => [ + 'columns' => [ + 'aColumn' => [ + 'config' => [ + 'type' => 'select', + 'foreign_table' => 'sys_file_reference', + ], + ], + ], + ], + ], + ]; + } + + /** + * @dataProvider falHandlingInTypeInlineIsMigratedToTypeFileDataProvider + * @test + * @param array<string, mixed> $input + * @param array<string, mixed> $expected + * @param string $expectedMessagePart + */ + public function falHandlingInTypeInlineIsMigratedToTypeFile(array $input, array $expected, $expectedMessagePart = ''): void + { + $subject = new TcaMigration(); + self::assertSame($expected, $subject->migrate($input)); + if ($expectedMessagePart !== '') { + $messageFound = false; + foreach ($subject->getMessages() as $message) { + if (str_contains($message, $expectedMessagePart)) { + $messageFound = true; + break; + } + } + self::assertTrue($messageFound); + } + } + + /** + * @test + */ + public function falRelatedElementBrowserOptionsAreRemovedFromTypeGroup(): void + { + $input = [ + 'aTable' => [ + 'columns' => [ + 'aColumns' => [ + 'config' => [ + 'type' => 'group', + 'appearance' => [ + 'elementBrowserAllowed' => 'jpg,png', + 'elementBrowserType' => 'file', + ], + ], + ], + ], + ], + ]; + $expected = [ + 'aTable' => [ + 'columns' => [ + 'aColumns' => [ + 'config' => [ + 'type' => 'group', + ], + ], + ], + ], + ]; + $subject = new TcaMigration(); + self::assertSame($expected, $subject->migrate($input)); + } + + /** + * @test + */ + public function falRelatedOptionsAreRemovedFromTypeInline(): void + { + $input = [ + 'aTable' => [ + 'columns' => [ + 'aColumns' => [ + 'config' => [ + 'type' => 'inline', + 'appearance' => [ + 'headerThumbnail' => [ + 'height' => '45c', + ], + 'fileUploadAllowed' => true, + 'fileByUrlAllowed' => true, + ], + ], + ], + ], + ], + ]; + $expected = [ + 'aTable' => [ + 'columns' => [ + 'aColumns' => [ + 'config' => [ + 'type' => 'inline', + ], + ], + ], + ], + ]; + $subject = new TcaMigration(); + self::assertSame($expected, $subject->migrate($input)); + } } diff --git a/typo3/sysext/core/Tests/Unit/Preparations/TcaPreparationTest.php b/typo3/sysext/core/Tests/Unit/Preparations/TcaPreparationTest.php index 7543d1227d88483d0179b53e64b965b7d650ef54..c5cf0ac403ac2e460fd2491b545adf6de3e29f8c 100644 --- a/typo3/sysext/core/Tests/Unit/Preparations/TcaPreparationTest.php +++ b/typo3/sysext/core/Tests/Unit/Preparations/TcaPreparationTest.php @@ -348,4 +348,30 @@ class TcaPreparationTest extends UnitTestCase ], ]); } + + /** + * @test + */ + public function prepareFileExtensionsReplacesPlaceholders(): void + { + $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] = 'jpg,png'; + + self::assertEquals( + 'jpg,png,gif', + TcaPreparation::prepareFileExtensions(['common-image-types', 'gif']) + ); + } + + /** + * @test + */ + public function prepareFileExtensionsRemovesDuplicates(): void + { + $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] = 'jpg,png'; + + self::assertEquals( + 'jpg,png,gif', + TcaPreparation::prepareFileExtensions('common-image-types,jpg,gif') + ); + } } diff --git a/typo3/sysext/core/Tests/Unit/Resource/Utility/FileExtensionFilterTest.php b/typo3/sysext/core/Tests/Unit/Resource/Utility/FileExtensionFilterTest.php index b398b808bf29e04253f6826109b57975490fcc78..f2c976d2e4bc9730ea787e2022a80b1d1501ec32 100644 --- a/typo3/sysext/core/Tests/Unit/Resource/Utility/FileExtensionFilterTest.php +++ b/typo3/sysext/core/Tests/Unit/Resource/Utility/FileExtensionFilterTest.php @@ -41,37 +41,16 @@ class FileExtensionFilterTest extends UnitTestCase } /** - * @return array - */ - public function invalidInlineChildrenFilterParametersDataProvider(): array - { - return [ - [null, null, null], - ['', '', [0, '', null, false]], - [null, null, [0, '', null, false]], - ]; - } - - /** - * @param array|string $allowed - * @param array|string $disallowed - * @param array|string $values * @test - * @dataProvider invalidInlineChildrenFilterParametersDataProvider */ - public function areInlineChildrenFilteredWithInvalidParameters($allowed, $disallowed, $values): void + public function areInlineChildrenFilteredWithInvalidParameters(): void { - $parameters = [ - 'allowedFileExtensions' => $allowed, - 'disallowedFileExtensions' => $disallowed, - 'values' => $values, - ]; $dataHandlerProphecy = $this->prophesize(DataHandler::class); $dataHandlerProphecy->deleteAction()->shouldNotBeCalled(); $resourceFactoryProphecy = $this->prophesize(ResourceFactory::class); $resourceFactoryProphecy->getFileReferenceObject()->shouldNotBeCalled(); GeneralUtility::setSingletonInstance(ResourceFactory::class, $resourceFactoryProphecy->reveal()); - (new FileExtensionFilter())->filterInlineChildren($parameters, $dataHandlerProphecy->reveal()); + (new FileExtensionFilter())->filter([0, '', null, false], '', '', $dataHandlerProphecy->reveal()); } /** diff --git a/typo3/sysext/core/Tests/UnitDeprecated/Resource/Utility/FileExtensionFilterTest.php b/typo3/sysext/core/Tests/UnitDeprecated/Resource/Utility/FileExtensionFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..592dc09832e4fc074f51eb72ddb4da3d59a5855f --- /dev/null +++ b/typo3/sysext/core/Tests/UnitDeprecated/Resource/Utility/FileExtensionFilterTest.php @@ -0,0 +1,77 @@ +<?php + +declare(strict_types=1); + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +namespace TYPO3\CMS\Core\Tests\UnitDeprecated\Resource\Utility; + +use Prophecy\PhpUnit\ProphecyTrait; +use TYPO3\CMS\Core\DataHandling\DataHandler; +use TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter; +use TYPO3\CMS\Core\Resource\ResourceFactory; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\TestingFramework\Core\Unit\UnitTestCase; + +/** + * Test suite for filtering files by their extensions. + */ +class FileExtensionFilterTest extends UnitTestCase +{ + use ProphecyTrait; + + /** + * Cleans up this test suite. + */ + protected function tearDown(): void + { + GeneralUtility::purgeInstances(); + parent::tearDown(); + } + + /** + * @return array + */ + public function invalidInlineChildrenFilterParametersDataProvider(): array + { + return [ + [null, null, null], + ['', '', [0, '', null, false]], + [null, null, [0, '', null, false]], + ]; + } + + /** + * @param array|string $allowed + * @param array|string $disallowed + * @param array|string $values + * @test + * @dataProvider invalidInlineChildrenFilterParametersDataProvider + */ + public function areInlineChildrenFilteredWithInvalidParameters($allowed, $disallowed, $values): void + { + $parameters = [ + 'allowedFileExtensions' => $allowed, + 'disallowedFileExtensions' => $disallowed, + 'values' => $values, + ]; + + $dataHandlerProphecy = $this->prophesize(DataHandler::class); + $dataHandlerProphecy->deleteAction()->shouldNotBeCalled(); + $resourceFactoryProphecy = $this->prophesize(ResourceFactory::class); + $resourceFactoryProphecy->getFileReferenceObject()->shouldNotBeCalled(); + GeneralUtility::setSingletonInstance(ResourceFactory::class, $resourceFactoryProphecy->reveal()); + (new FileExtensionFilter())->filterInlineChildren($parameters, $dataHandlerProphecy->reveal()); + } +} diff --git a/typo3/sysext/core/ext_tables.sql b/typo3/sysext/core/ext_tables.sql index 273a59b313d76ae651573b6f020e4ac488b54bbe..30e164f7ec4cf193b0a24df023ed67683b2e93c1 100644 --- a/typo3/sysext/core/ext_tables.sql +++ b/typo3/sysext/core/ext_tables.sql @@ -257,7 +257,6 @@ CREATE TABLE sys_file_reference ( tablenames varchar(64) DEFAULT '' NOT NULL, fieldname varchar(64) DEFAULT '' NOT NULL, sorting_foreign int(11) DEFAULT '0' NOT NULL, - table_local varchar(64) DEFAULT '' NOT NULL, # Local usage overlay fields title tinytext, diff --git a/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Configuration/TCA/tx_blogexample_domain_model_blog.php b/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Configuration/TCA/tx_blogexample_domain_model_blog.php index 029d8cc23ba88cf320e629bb512f1392d2517c96..076098eded4208e9503fb232e3002d18e63af2a3 100644 --- a/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Configuration/TCA/tx_blogexample_domain_model_blog.php +++ b/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Configuration/TCA/tx_blogexample_domain_model_blog.php @@ -118,7 +118,9 @@ return [ 'logo' => [ 'exclude' => true, 'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xlf:tx_blogexample_domain_model_blog.logo', - 'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig('logo', ['default' => 0]), + 'config' => [ + 'type' => 'file', + ], ], 'posts' => [ 'exclude' => true, diff --git a/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Mapper/DataMapFactoryTest.php b/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Mapper/DataMapFactoryTest.php index 5a501ef9880bb40b841b0dc07795fa75d6f4b9c0..99cfc085bf60e01d277b7cb4914cb75855901f8c 100644 --- a/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Mapper/DataMapFactoryTest.php +++ b/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Mapper/DataMapFactoryTest.php @@ -471,6 +471,7 @@ class DataMapFactoryTest extends UnitTestCase [['type' => 'datetime'], TableColumnType::DATETIME], [['type' => 'color'], TableColumnType::COLOR], [['type' => 'number'], TableColumnType::NUMBER], + [['type' => 'file'], TableColumnType::FILE], ]; } diff --git a/typo3/sysext/fluid/Tests/Functional/Fixtures/ViewHelpers/Link/FileViewHelper/DatabaseImport.csv b/typo3/sysext/fluid/Tests/Functional/Fixtures/ViewHelpers/Link/FileViewHelper/DatabaseImport.csv index 5da9e77a55e4a122aeaac6d167439c1fd7882625..a7d8f26019ddebf1c09788120d84b28d8c6c40ec 100644 --- a/typo3/sysext/fluid/Tests/Functional/Fixtures/ViewHelpers/Link/FileViewHelper/DatabaseImport.csv +++ b/typo3/sysext/fluid/Tests/Functional/Fixtures/ViewHelpers/Link/FileViewHelper/DatabaseImport.csv @@ -5,8 +5,8 @@ sys_file,,,,,,,,,,,,,, ,uid,pid,storage,type,identifier,identifier_hash,folder_hash,extension,mime_type,name,sha1,size,creation_date,modification_date ,1,0,1,2,/user_upload/typo3_image2.jpg,f90bb9a35622f35b5279195e324eddbaec8164b2,19669f1e02c2f16705ec7587044c66443be70725,jpg,image/jpeg,typo3_image2.jpg,da9acdf1e105784a57bbffec9520969578287797,7958,1389878273,1389878273 sys_file_reference,,,,,,,,,,,,,, -,uid,uid_local,uid_foreign,tablenames,fieldname,table_local,,,,,,,, -,2,1,1,tt_content,image,sys_file,,,,,,,, +,uid,uid_local,uid_foreign,tablenames,fieldname,,,,,,,, +,2,1,1,tt_content,image,,,,,,,, sys_file_processedfile,,,,,,,,,,,,,, ,uid,storage,original,identifier,name,configuration,width,height,task_type,,,,, ,3,1,1,/_processed_/csm_typo3_image2_5c2670fd59.jpg,csm_typo3_image2_5c2670fd59.jpg,a:0:{},300,225,Image.Preview,,,,, diff --git a/typo3/sysext/form/Documentation/I/Concepts/Finishers/Index.rst b/typo3/sysext/form/Documentation/I/Concepts/Finishers/Index.rst index ddab24a77dd0f0508e68439a0a28386ce48a4402..300157112f562f25b8e1dcebff1c87582fb6d49d 100644 --- a/typo3/sysext/form/Documentation/I/Concepts/Finishers/Index.rst +++ b/typo3/sysext/form/Documentation/I/Concepts/Finishers/Index.rst @@ -207,8 +207,6 @@ Here is an example for adding uploads to ext:news (fal_related_files and fal_med mapOnDatabaseColumn: uid_local skipIfValueIsEmpty: true databaseColumnMappings: - table_local: - value: sys_file tablenames: value: tx_news_domain_model_news fieldname: @@ -229,8 +227,6 @@ Here is an example for adding uploads to ext:news (fal_related_files and fal_med mapOnDatabaseColumn: uid_local skipIfValueIsEmpty: true databaseColumnMappings: - table_local: - value: sys_file tablenames: value: tx_news_domain_model_news fieldname: diff --git a/typo3/sysext/frontend/Configuration/TCA/backend_layout.php b/typo3/sysext/frontend/Configuration/TCA/backend_layout.php index 6249545a53f51556786bb294be86d39c07bb3415..ac202e27111357864494841288e34f8c9adcb573 100644 --- a/typo3/sysext/frontend/Configuration/TCA/backend_layout.php +++ b/typo3/sysext/frontend/Configuration/TCA/backend_layout.php @@ -63,16 +63,14 @@ return [ 'icon' => [ 'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:backend_layout.icon', 'exclude' => true, - 'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig( - 'icon', - [ - 'maxitems' => 1, - 'appearance' => [ - 'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference', - ], + 'config' => [ + 'type' => 'file', + 'allowed' => 'common-image-types', + 'maxitems' => 1, + 'appearance' => [ + 'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference', ], - $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] - ), + ], ], ], 'types' => [ diff --git a/typo3/sysext/frontend/Configuration/TCA/fe_users.php b/typo3/sysext/frontend/Configuration/TCA/fe_users.php index 7557fcac54b53d7b5e4f501a9cc3eb845867a571..dfbc885832bc43e702ba2a93973adc1c7e641e5e 100644 --- a/typo3/sysext/frontend/Configuration/TCA/fe_users.php +++ b/typo3/sysext/frontend/Configuration/TCA/fe_users.php @@ -191,13 +191,11 @@ return [ 'image' => [ 'exclude' => true, 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.image', - 'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig( - 'image', - [ - 'maxitems' => 6, - ], - $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] - ), + 'config' => [ + 'type' => 'file', + 'allowed' => 'common-image-types', + 'maxitems' => 6, + ], ], 'disable' => [ 'exclude' => true, diff --git a/typo3/sysext/frontend/Configuration/TCA/tt_content.php b/typo3/sysext/frontend/Configuration/TCA/tt_content.php index 946b4a4e8cf3456923cca5083dd9e3f71fc28a15..ec8a89b05683567c9c0e8cff6653a05b50850f57 100644 --- a/typo3/sysext/frontend/Configuration/TCA/tt_content.php +++ b/typo3/sysext/frontend/Configuration/TCA/tt_content.php @@ -595,7 +595,9 @@ return [ ], 'image' => [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.images', - 'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig('image', [ + 'config' => [ + 'type' => 'file', + 'allowed' => 'common-image-types', 'appearance' => [ 'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference', 'showPossibleLocalizationRecords' => true, @@ -636,11 +638,13 @@ return [ ], ], ], - ], $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']), + ], ], 'assets' => [ 'label' => 'LLL:EXT:frontend/Resources/Private/Language/Database.xlf:tt_content.asset_references', - 'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig('assets', [ + 'config' => [ + 'type' => 'file', + 'allowed' => 'common-media-types', 'appearance' => [ 'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/Database.xlf:tt_content.asset_references.addFileReference', 'showPossibleLocalizationRecords' => true, @@ -681,7 +685,7 @@ return [ ], ], ], - ], $GLOBALS['TYPO3_CONF_VARS']['SYS']['mediafile_ext']), + ], ], 'imagewidth' => [ 'exclude' => true, @@ -973,12 +977,13 @@ return [ ], 'media' => [ 'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:media', - 'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig('media', [ + 'config' => [ + 'type' => 'file', 'appearance' => [ 'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:media.addFileReference', 'showPossibleLocalizationRecords' => true, ], - ]), + ], ], 'filelink_size' => [ 'exclude' => true, diff --git a/typo3/sysext/frontend/Tests/Functional/ContentObject/DataSet/FileReferences.csv b/typo3/sysext/frontend/Tests/Functional/ContentObject/DataSet/FileReferences.csv index d44afc82297d39d10c54544e358b44d6bc82fc45..8cb29a6dbe87928f16e838064bcc3cc36da0ae6a 100644 --- a/typo3/sysext/frontend/Tests/Functional/ContentObject/DataSet/FileReferences.csv +++ b/typo3/sysext/frontend/Tests/Functional/ContentObject/DataSet/FileReferences.csv @@ -6,5 +6,5 @@ ,1,0,2,1,"/user_upload/team-t3board10.jpg","jpg","image/jpeg","team-t3board10.jpg","ae6951147687ed1f94f60973fca7ef46e2ba2372",166843,1375080761,1374139442,0,0,"16ba2a587da8ef10dfccbe8b9841bde85afbd2d4","19669f1e02c2f16705ec7587044c66443be70725",0,,, ,,,,,,,,,,,,,,,,,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,,, -,"uid","pid","title","uid_local","uid_foreign","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","deleted","tablenames","fieldname","sorting_foreign","table_local","description","alternative","link","l10n_diffsource" -,1,1,"T3BOARD",1,297,0,0,0,0,0,0,0,"tt_content","image",2,"sys_file",,,, +,"uid","pid","title","uid_local","uid_foreign","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","deleted","tablenames","fieldname","sorting_foreign","description","alternative","link","l10n_diffsource" +,1,1,"T3BOARD",1,297,0,0,0,0,0,0,0,"tt_content","image",2,,,, diff --git a/typo3/sysext/frontend/Tests/Functional/ContentObject/DataSet/FilesContentObjectDataSet.csv b/typo3/sysext/frontend/Tests/Functional/ContentObject/DataSet/FilesContentObjectDataSet.csv index 9b7e00916bd4a81b726a20bf8412933d007bc308..5cebb12b878b74925d2b1d57cde368a81dbe2eea 100644 --- a/typo3/sysext/frontend/Tests/Functional/ContentObject/DataSet/FilesContentObjectDataSet.csv +++ b/typo3/sysext/frontend/Tests/Functional/ContentObject/DataSet/FilesContentObjectDataSet.csv @@ -18,23 +18,23 @@ ,9,0,2,1,"/user_upload/file9.jpg","jpg","image/png","file9.jpg","ae6951147687ed1f94f60973fca7ef46e2ba2372",166843,1375080761,1374139442,0,0,"16ba2a587da8ef10dfccbe8b9841bde85afbd2d4","19669f1e02c2f16705ec7587044c66443be70725",0,,, ,,,,,,,,,,,,,,,,,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,,, -,"uid","pid","title","uid_local","uid_foreign","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","deleted","tablenames","fieldname","sorting_foreign","table_local","description","alternative","link","l10n_diffsource" -,1,1,"T3BOARD",1,297,0,0,0,0,0,0,0,"tt_content","image",1,"sys_file",,,, -,2,1,"Kasper",2,297,0,0,0,0,0,0,0,"tt_content","image",2,"sys_file",,,, -,3,1,"TYPO3 Logo",3,297,0,0,0,0,0,0,0,"tt_content","image",3,"sys_file",,,, -,4,1,"T3BOARD in collection",1,1,0,0,0,0,0,0,0,"sys_file_collection","files",1,"sys_file",,,, -,5,1,"Kasper in collection",2,1,0,0,0,0,0,0,0,"sys_file_collection","files",2,"sys_file",,,, -,6,1,"TYPO3 Logo in collection",3,1,0,0,0,0,0,0,0,"sys_file_collection","files",3,"sys_file",,,, -,7,1,"T3BOARD in collection",4,2,0,0,0,0,0,0,0,"sys_file_collection","files",1,"sys_file",,,, -,8,1,"Kasper in collection",5,2,0,0,0,0,0,0,0,"sys_file_collection","files",2,"sys_file",,,, -,9,1,"TYPO3 Logo in collection",6,2,0,0,0,0,0,0,0,"sys_file_collection","files",3,"sys_file",,,, -,10,1,"T3BOARD in collection",7,3,0,0,0,0,0,0,0,"sys_file_collection","files",1,"sys_file",,,, -,11,1,"Kasper in collection",8,3,0,0,0,0,0,0,0,"sys_file_collection","files",2,"sys_file",,,, -,12,1,"TYPO3 Logo in collection",9,3,0,0,0,0,0,0,0,"sys_file_collection","files",3,"sys_file",,,, -,13,1,"File 4",4,298,0,0,0,0,0,0,0,"tt_content","image",1,"sys_file",,,, -,14,1,"File 5",5,298,0,0,0,0,0,0,0,"tt_content","image",2,"sys_file",,,, -,15,1,"File 6",6,298,0,0,0,0,0,0,0,"tt_content","image",3,"sys_file",,,, -,16,1,"File 7",7,1,0,0,0,0,0,0,0,"pages","media",2,"sys_file",,,, +,"uid","pid","title","uid_local","uid_foreign","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","deleted","tablenames","fieldname","sorting_foreign","description","alternative","link","l10n_diffsource" +,1,1,"T3BOARD",1,297,0,0,0,0,0,0,0,"tt_content","image",1,,,, +,2,1,"Kasper",2,297,0,0,0,0,0,0,0,"tt_content","image",2,,,, +,3,1,"TYPO3 Logo",3,297,0,0,0,0,0,0,0,"tt_content","image",3,,,, +,4,1,"T3BOARD in collection",1,1,0,0,0,0,0,0,0,"sys_file_collection","files",1,,,, +,5,1,"Kasper in collection",2,1,0,0,0,0,0,0,0,"sys_file_collection","files",2,,,, +,6,1,"TYPO3 Logo in collection",3,1,0,0,0,0,0,0,0,"sys_file_collection","files",3,,,, +,7,1,"T3BOARD in collection",4,2,0,0,0,0,0,0,0,"sys_file_collection","files",1,,,, +,8,1,"Kasper in collection",5,2,0,0,0,0,0,0,0,"sys_file_collection","files",2,,,, +,9,1,"TYPO3 Logo in collection",6,2,0,0,0,0,0,0,0,"sys_file_collection","files",3,,,, +,10,1,"T3BOARD in collection",7,3,0,0,0,0,0,0,0,"sys_file_collection","files",1,,,, +,11,1,"Kasper in collection",8,3,0,0,0,0,0,0,0,"sys_file_collection","files",2,,,, +,12,1,"TYPO3 Logo in collection",9,3,0,0,0,0,0,0,0,"sys_file_collection","files",3,,,, +,13,1,"File 4",4,298,0,0,0,0,0,0,0,"tt_content","image",1,,,, +,14,1,"File 5",5,298,0,0,0,0,0,0,0,"tt_content","image",2,,,, +,15,1,"File 6",6,298,0,0,0,0,0,0,0,"tt_content","image",3,,,, +,16,1,"File 7",7,1,0,0,0,0,0,0,0,"pages","media",2,,,, "sys_file_storage",,,,,,,,,,,,,,,,,,,, ,"uid","pid","name","driver","configuration","is_browsable","is_public","is_writable","is_online",,,,,,,,,,, ,1,0,"Storage 1","Local","<?xml version='1.0' encoding='utf-8' standalone='yes' ?><T3FlexForms><data><sheet index='sDEF'><language index='lDEF'><field index='basePath'><value index='vDEF'>fileadmin/</value></field><field index='pathType'><value index='vDEF'>relative</value></field><field index='caseSensitive'><value index='vDEF'>1</value></field></language></sheet></data></T3FlexForms>",1,1,1,1,,,,,,,,,,, diff --git a/typo3/sysext/frontend/Tests/Functional/Rendering/DataSet/LiveDefaultElements.csv b/typo3/sysext/frontend/Tests/Functional/Rendering/DataSet/LiveDefaultElements.csv index 77104f4c6f8afd1e4c1afce0d2b7589fda09ee16..473ba480380c4f154ee4ce2de4752fd3f6347241 100644 --- a/typo3/sysext/frontend/Tests/Functional/Rendering/DataSet/LiveDefaultElements.csv +++ b/typo3/sysext/frontend/Tests/Functional/Rendering/DataSet/LiveDefaultElements.csv @@ -24,14 +24,14 @@ ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,, ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,, "sys_file_reference",,,,,,,,,,,,,,,,,,,, -,"uid","pid","title","uid_local","uid_foreign","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","deleted","tablenames","fieldname","sorting_foreign","table_local","description","alternative","link","l10n_diffsource" -,126,89,"T3BOARD",1,297,0,0,0,0,0,0,0,"tt_content","image",2,"sys_file",,,, -,127,89,"Kasper",21,299,0,0,0,0,0,0,0,"tt_content","image",1,"sys_file",,,, -,128,89,"[Kasper] Image translated to Dansk",21,300,1,127,0,0,0,0,0,"tt_content","image",1,"sys_file",,,, -,129,89,"[T3BOARD] Image added in Dansk (without parent)",1,300,1,0,0,0,0,0,0,"tt_content","image",2,"sys_file",,,, -,130,89,"[T3BOARD] Image added to DK element without default language",1,303,1,0,0,0,0,0,0,"tt_content","image",1,"sys_file",,,, -,131,89,"[T3BOARD] image translated to DE from DK",1,302,2,0,0,0,0,0,0,"tt_content","image",1,"sys_file",,,, -,132,89,"Kasper2",1,298,0,0,0,0,0,0,0,"tt_content","image",1,"sys_file",,,, +,"uid","pid","title","uid_local","uid_foreign","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","deleted","tablenames","fieldname","sorting_foreign","description","alternative","link","l10n_diffsource" +,126,89,"T3BOARD",1,297,0,0,0,0,0,0,0,"tt_content","image",2,,,, +,127,89,"Kasper",21,299,0,0,0,0,0,0,0,"tt_content","image",1,,,, +,128,89,"[Kasper] Image translated to Dansk",21,300,1,127,0,0,0,0,0,"tt_content","image",1,,,, +,129,89,"[T3BOARD] Image added in Dansk (without parent)",1,300,1,0,0,0,0,0,0,"tt_content","image",2,,,, +,130,89,"[T3BOARD] Image added to DK element without default language",1,303,1,0,0,0,0,0,0,"tt_content","image",1,,,, +,131,89,"[T3BOARD] image translated to DE from DK",1,302,2,0,0,0,0,0,0,"tt_content","image",1,,,, +,132,89,"Kasper2",1,298,0,0,0,0,0,0,0,"tt_content","image",1,,,, "sys_category",,,,,,,,,,,,,,,,,,,, ,"uid","pid","title","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","deleted",,,,,,,,,, ,1,89,"Category 1",0,0,0,0,0,0,0,,,,,,,,,, diff --git a/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentWithImagesTest.php b/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentWithImagesTest.php index 6815c38059733ef87f20a74adc949acb4b7ee6a9..4ba68165af85b4b704e0242dcac8a74b5c9c4f49 100644 --- a/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentWithImagesTest.php +++ b/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentWithImagesTest.php @@ -165,7 +165,6 @@ class PagesAndTtContentWithImagesTest extends AbstractImportExportTestCase 'tablenames', 'fieldname', 'sorting_foreign', - 'table_local', 'title', 'description', 'alternative', diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithDifferentImageToExistingData.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithDifferentImageToExistingData.csv index 818c3f2ab1026aa53fde53e06a60858f9836757e..218517efe9220cfbfac462266f6e70adbbb70feb 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithDifferentImageToExistingData.csv +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithDifferentImageToExistingData.csv @@ -19,9 +19,9 @@ ,3,0,1,2,"/user_upload/typo3_image5.jpg","8180e85d25c96697ec9d2004683216831b91ffc1","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image5.jpg","c3511df85d21bc578faf71c6a19eeb3ff44af370",7425 ,4,0,1,2,"/user_upload/typo3_image2_01.jpg","299dc37e3c3428b85d9b39c353c6557fa834dac5","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2_01.jpg","e873c1e2ffd0f191e183a1057de3eef4d62e782d",5565 "sys_file_reference",,,,,,,,,,,, -,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link", -,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, -,2,4,4,2,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, +,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link", +,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,, +,2,4,4,2,"tt_content","image",\NULL,\NULL,\NULL,, "sys_file_metadata",,,,,,,,,,,, ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",, ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",0,0,, diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImageWithForcedUids.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImageWithForcedUids.csv index 0244828fa9ef11ce2ea4f4b1fc15179025bf1863..16accd19096ebabbfd8deb1448d05377a34742c5 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImageWithForcedUids.csv +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImageWithForcedUids.csv @@ -12,8 +12,8 @@ ,"uid","pid","storage","type","identifier","identifier_hash","folder_hash","extension","mime_type","name","sha1","size" ,1,0,1,2,"/user_upload/typo3_image2.jpg","f90bb9a35622f35b5279195e324eddbaec8164b2","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2.jpg","da9acdf1e105784a57bbffec9520969578287797",7958 "sys_file_reference",,,,,,,,,,,, -,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link", -,101,8,1,21,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, +,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link", +,101,8,1,21,"tt_content","image",\NULL,\NULL,\NULL,, "sys_file_metadata",,,,,,,,,,,, ,"uid","pid","file","title","width","height","description","alternative",,,, ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",,,, diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButNotIncluded.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButNotIncluded.csv index 9572387bf7d17edbb33ac60a8903addacbb8bc45..614380e45535cc1463e97b9b130613949e3e2ca9 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButNotIncluded.csv +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButNotIncluded.csv @@ -12,8 +12,8 @@ ,"uid","pid","storage","type","identifier","identifier_hash","folder_hash","extension","mime_type","name","sha1","size" ,1,0,1,2,"/user_upload/typo3_image2.jpg","f90bb9a35622f35b5279195e324eddbaec8164b2","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2.jpg","da9acdf1e105784a57bbffec9520969578287797",7958 "sys_file_reference",,,,,,,,,,,, -,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link", -,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, +,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link", +,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,, "sys_file_metadata",,,,,,,,,,,, ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",, ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",0,0,, diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseInsensitiveFilesystems.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseInsensitiveFilesystems.csv index 644b4706c2319e19cdc5589371781b28ec7716c4..5dfe3b76eafed257ca0f8cc52e916d501fcd7db0 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseInsensitiveFilesystems.csv +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseInsensitiveFilesystems.csv @@ -12,8 +12,8 @@ ,"uid","pid","storage","type","identifier","identifier_hash","folder_hash","extension","mime_type","name","sha1","size" ,1,0,1,2,"/user_upload/typo3_image2.jpg","f90bb9a35622f35b5279195e324eddbaec8164b2","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2.jpg","da9acdf1e105784a57bbffec9520969578287797",7958 "sys_file_reference",,,,,,,,,,,, -,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link", -,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, +,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link", +,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,, "sys_file_metadata",,,,,,,,,,,, ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",, ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",0,0,, diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseSensitiveFilesystems.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseSensitiveFilesystems.csv index e67dab07d8f0429ec78229d8c9e7782772ce8369..fa13768e34ee4aef9bf5eed28fe27038917ac314 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseSensitiveFilesystems.csv +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseSensitiveFilesystems.csv @@ -12,8 +12,8 @@ ,"uid","pid","storage","type","identifier","identifier_hash","folder_hash","extension","mime_type","name","sha1","size" ,1,0,1,2,"/user_upload/typo3_image2.jpg","f90bb9a35622f35b5279195e324eddbaec8164b2","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2.jpg","da9acdf1e105784a57bbffec9520969578287797",7958 "sys_file_reference",,,,,,,,,,,, -,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link", -,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, +,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link", +,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,, "sys_file_metadata",,,,,,,,,,,, ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",, ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",0,0,, diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesOnCaseInsensitiveFilesystems.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesOnCaseInsensitiveFilesystems.csv index 4620e2d286683dc83c6055393a5976b3375c4148..9cd8fca77de150b463a32b242f70942e8f811360 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesOnCaseInsensitiveFilesystems.csv +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesOnCaseInsensitiveFilesystems.csv @@ -12,8 +12,8 @@ ,"uid","pid","storage","type","identifier","identifier_hash","folder_hash","extension","mime_type","name","sha1","size" ,1,0,1,2,"/user_upload/typo3_image2.jpg","f90bb9a35622f35b5279195e324eddbaec8164b2","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2.jpg","da9acdf1e105784a57bbffec9520969578287797",7958 "sys_file_reference",,,,,,,,,,,, -,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link", -,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, +,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link", +,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,, "sys_file_metadata",,,,,,,,,,,, ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",, ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",0,0,, diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesOnCaseSensitiveFilesystems.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesOnCaseSensitiveFilesystems.csv index 5185d10d3916d87fda123112cf8f60896c1e2438..41b0a032e04742650a22c1e96f5306a3822b04ce 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesOnCaseSensitiveFilesystems.csv +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesOnCaseSensitiveFilesystems.csv @@ -12,8 +12,8 @@ ,"uid","pid","storage","type","identifier","identifier_hash","folder_hash","extension","mime_type","name","sha1","size" ,1,0,1,2,"/user_upload/typo3_image2.jpg","f90bb9a35622f35b5279195e324eddbaec8164b2","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2.jpg","da9acdf1e105784a57bbffec9520969578287797",7958 "sys_file_reference",,,,,,,,,,,, -,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link", -,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, +,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link", +,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,, "sys_file_metadata",,,,,,,,,,,, ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",, ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",0,0,, diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesWithSpacesInPath.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesWithSpacesInPath.csv index d60382d11a868efa9381efdcd185ab9898b98502..54dcb72467ba7263d48f05e4b3ec73fcf4a1906d 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesWithSpacesInPath.csv +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesWithSpacesInPath.csv @@ -13,8 +13,8 @@ ,1,0,1,2,"/user_upload/folder_with_spaces/typo3_image2.jpg","060a2cd7f623c1c4c3edaf20f2dd561dadc30354","9de358f64a020b01f020a76ff7c59674913ba5c5","jpg","image/jpeg","typo3_image2.jpg","da9acdf1e105784a57bbffec9520969578287797",7958 ,2,0,1,2,"/user_upload/folder_with_spaces/typo3_image3.jpg","53313966f99b5d632c1db8799ae25349ad3318f8","9de358f64a020b01f020a76ff7c59674913ba5c5","jpg","image/jpeg","typo3_image3.jpg","e873c1e2ffd0f191e183a1057de3eef4d62e782d",5565 "sys_file_reference",,,,,,,,,,,, -,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link", -,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, +,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link", +,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,, "sys_file_metadata",,,,,,,,,,,, ,"uid","pid","file","title","width","height","description","alternative",,,, ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",,,, diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithSameImageToExistingData.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithSameImageToExistingData.csv index b1b6fe9be26c3e3e6e871ec1de78dc4e7aef7ec2..7ad34fde038f0f5001521454953f275369d689be 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithSameImageToExistingData.csv +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithSameImageToExistingData.csv @@ -18,9 +18,9 @@ ,2,0,1,2,"/user_upload/typo3_image3.jpg","25777b72e5e1cbed2d1b33e4fe5b737304b5bd28","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image3.jpg","e873c1e2ffd0f191e183a1057de3eef4d62e782d",5565 ,3,0,1,2,"/user_upload/typo3_image5.jpg","8180e85d25c96697ec9d2004683216831b91ffc1","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image5.jpg","c3511df85d21bc578faf71c6a19eeb3ff44af370",7425 "sys_file_reference",,,,,,,,,,,, -,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link", -,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, -,2,4,1,2,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, +,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link", +,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,, +,2,4,1,2,"tt_content","image",\NULL,\NULL,\NULL,, "sys_file_metadata",,,,,,,,,,,, ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",, ,1,0,1,"New title of the dummy image",400,300,"This is a dummy image.","Photo of program code",0,0,, diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndTtContentWithRemappingNewSysFileEntries.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndTtContentWithRemappingNewSysFileEntries.csv index 7c40c540654c4e4096b0eb8064d8d3f4ae7c0e29..de2638de2ddbc8253e86abf27c509035cfc3eaac 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndTtContentWithRemappingNewSysFileEntries.csv +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndTtContentWithRemappingNewSysFileEntries.csv @@ -15,7 +15,7 @@ ,2,0,1,2,"/user_upload/used-1.jpg","a0d28ab6398a25c7a0c24f6ace6a3b43d773115e","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","used-1.jpg","da9acdf1e105784a57bbffec9520969578287797",7958 ,3,0,1,2,"/user_upload/used-2.jpg","5fd92415f6154c29349bbfb214b9e2d9dbb3d89a","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","used-2.jpg","c3511df85d21bc578faf71c6a19eeb3ff44af370",7425 "sys_file_reference",,,,,,,,,,,, -,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link", -,1,1,3,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, -,2,1,3,2,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, -,3,1,2,3,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, +,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link", +,1,1,3,1,"tt_content","image",\NULL,\NULL,\NULL,, +,2,1,3,2,"tt_content","image",\NULL,\NULL,\NULL,, +,3,1,2,3,"tt_content","image",\NULL,\NULL,\NULL,, diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentKeepsRelationsBetweenImportedPagesAndRecords.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentKeepsRelationsBetweenImportedPagesAndRecords.csv index 70a30e464fbca61fba26c75b8355a256058e730c..9bffe8fd622b5f5648e282304a4aa358048f3968 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentKeepsRelationsBetweenImportedPagesAndRecords.csv +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentKeepsRelationsBetweenImportedPagesAndRecords.csv @@ -18,9 +18,9 @@ ,2,0,1,2,"/user_upload/typo3_image3.jpg","25777b72e5e1cbed2d1b33e4fe5b737304b5bd28","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image3.jpg","e873c1e2ffd0f191e183a1057de3eef4d62e782d",5565 ,3,0,1,2,"/user_upload/typo3_image5.jpg","8180e85d25c96697ec9d2004683216831b91ffc1","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image5.jpg","c3511df85d21bc578faf71c6a19eeb3ff44af370",7425 "sys_file_reference",,,,,,,,,,,, -,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link", -,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, -,2,5,1,2,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, +,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link", +,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,, +,2,5,1,2,"tt_content","image",\NULL,\NULL,\NULL,, "sys_file_metadata",,,,,,,,,,,, ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",, ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",0,0,, diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentWithDifferentImageToExistingData.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentWithDifferentImageToExistingData.csv index 07a657ff30ca323b9b7b3cbe87bd80ca956ac25e..19cfb86c56c0dc4edd4cc2b149520fea5c1a1475 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentWithDifferentImageToExistingData.csv +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentWithDifferentImageToExistingData.csv @@ -16,8 +16,8 @@ ,3,0,1,2,"/user_upload/typo3_image5.jpg","8180e85d25c96697ec9d2004683216831b91ffc1","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image5.jpg","c3511df85d21bc578faf71c6a19eeb3ff44af370",7425 ,4,0,1,2,"/user_upload/typo3_image2_01.jpg","299dc37e3c3428b85d9b39c353c6557fa834dac5","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2_01.jpg","e873c1e2ffd0f191e183a1057de3eef4d62e782d",5565 "sys_file_reference",,,,,,,,,,,, -,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link", -,1,1,4,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, +,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link", +,1,1,4,1,"tt_content","image",\NULL,\NULL,\NULL,, "sys_file_metadata",,,,,,,,,,,, ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",, ,1,0,4,\NULL,400,267,\NULL,\NULL,0,0,, diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentWithDifferentImageToExistingDataAndPagesAsNew.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentWithDifferentImageToExistingDataAndPagesAsNew.csv index aa8bb6cadae5bc4c0ab020aaa4549f837ca85a1f..13d6ab978689159f91ce11bf62a71c1f8c3affd2 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentWithDifferentImageToExistingDataAndPagesAsNew.csv +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentWithDifferentImageToExistingDataAndPagesAsNew.csv @@ -18,8 +18,8 @@ ,3,0,1,2,"/user_upload/typo3_image5.jpg","8180e85d25c96697ec9d2004683216831b91ffc1","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image5.jpg","c3511df85d21bc578faf71c6a19eeb3ff44af370",7425 ,4,0,1,2,"/user_upload/typo3_image2_01.jpg","299dc37e3c3428b85d9b39c353c6557fa834dac5","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2_01.jpg","e873c1e2ffd0f191e183a1057de3eef4d62e782d",5565 "sys_file_reference",,,,,,,,,,,, -,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link", -,1,4,4,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,, +,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link", +,1,4,4,1,"tt_content","image",\NULL,\NULL,\NULL,, "sys_file_metadata",,,,,,,,,,,, ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",, ,1,0,4,\NULL,400,267,\NULL,\NULL,0,0,, diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseImports/sys_file_reference.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseImports/sys_file_reference.csv index 9a7b9ea39fd5b03ca9da3771411e443215c18ffb..d48d37520f879db33b2b2a67f490ce2e1419fe4f 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseImports/sys_file_reference.csv +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseImports/sys_file_reference.csv @@ -1,3 +1,3 @@ sys_file_reference,,,,,,,, -,uid,pid,uid_local,uid_foreign,tablenames,fieldname,table_local,l10n_diffsource -,1,1,1,1,tt_content,image,sys_file, +,uid,pid,uid_local,uid_foreign,tablenames,fieldname,l10n_diffsource +,1,1,1,1,tt_content,image, diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-corrupt-image.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-corrupt-image.xml index 6bac66560de2f4041df9352343f0ef41e1c6639b..ca506751cf52c7a7a598fa54227f5474b4a3e1b1 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-corrupt-image.xml +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-corrupt-image.xml @@ -209,7 +209,6 @@ <field index="tablenames">tt_content</field> <field index="fieldname">image</field> <field index="sorting_foreign" type="integer">0</field> - <field index="table_local">sys_file</field> <field index="title" type="NULL"></field> <field index="description" type="NULL"></field> <field index="alternative" type="NULL"></field> diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-image-but-not-included.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-image-but-not-included.xml index 9723ad2656c2b447281d9c994ebea8c948066e4b..9d9a20b6c6076169f94f29dfc433cdacae14aae7 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-image-but-not-included.xml +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-image-but-not-included.xml @@ -209,7 +209,6 @@ <field index="tablenames">tt_content</field> <field index="fieldname">image</field> <field index="sorting_foreign" type="integer">0</field> - <field index="table_local">sys_file</field> <field index="title" type="NULL"></field> <field index="description" type="NULL"></field> <field index="alternative" type="NULL"></field> diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-image.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-image.xml index f24eb2d59c1dde28937f3411bb21d7775a5a1838..01d6d5e16aaa304bc041531491c5772c4c43b8cb 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-image.xml +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-image.xml @@ -209,7 +209,6 @@ <field index="tablenames">tt_content</field> <field index="fieldname">image</field> <field index="sorting_foreign" type="integer">0</field> - <field index="table_local">sys_file</field> <field index="title" type="NULL"></field> <field index="description" type="NULL"></field> <field index="alternative" type="NULL"></field> diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-existing-different-image.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-existing-different-image.xml index 28daee188dba19a8af51e37e3e9fa6504ad87665..30a8cfc6dfe1ed902a6da6ff3b9a9b985fd08e2a 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-existing-different-image.xml +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-existing-different-image.xml @@ -192,7 +192,6 @@ <field index="tablenames">tt_content</field> <field index="fieldname">image</field> <field index="sorting_foreign">0</field> - <field index="table_local">sys_file</field> <field index="title" type="NULL"></field> <field index="description" type="NULL"></field> <field index="alternative" type="NULL"></field> diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-existing-same-image.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-existing-same-image.xml index ba40131497d9fe363f959fa8f91a0daa7007434f..ffcd35bd9a028e6ef5c777689b4c8b180cd39481 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-existing-same-image.xml +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-existing-same-image.xml @@ -192,7 +192,6 @@ <field index="tablenames">tt_content</field> <field index="fieldname">image</field> <field index="sorting_foreign">0</field> - <field index="table_local">sys_file</field> <field index="title" type="NULL"></field> <field index="description" type="NULL"></field> <field index="alternative" type="NULL"></field> diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-but-not-included.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-but-not-included.xml index 10a05be16bb9bc98e0f3e0965fc2849bf60ab5d4..aee0f50e09a389e7c8be55ed7110d3800da0427c 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-but-not-included.xml +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-but-not-included.xml @@ -245,7 +245,6 @@ <field index="tablenames">tt_content</field> <field index="fieldname">image</field> <field index="sorting_foreign">0</field> - <field index="table_local">sys_file</field> <field index="title" type="NULL"></field> <field index="description" type="NULL"></field> <field index="alternative" type="NULL"></field> diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-forced-uids.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-forced-uids.xml index 14c2037491cc7e1dade26fdcef56243093374788..dcc509250044a7a8df87c50b898b30dbabfd1a13 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-forced-uids.xml +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-forced-uids.xml @@ -237,7 +237,6 @@ <field index="tablenames">tt_content</field> <field index="fieldname">image</field> <field index="sorting_foreign">0</field> - <field index="table_local">sys_file</field> <field index="title" type="NULL"></field> <field index="description" type="NULL"></field> <field index="alternative" type="NULL"></field> diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-invalid-storage.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-invalid-storage.xml index 6ad29a728f87f8d964387506eaa101c51adef5e8..2f909459b8b96018d1ed0743ca03ed4f61ffac02 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-invalid-storage.xml +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-invalid-storage.xml @@ -245,7 +245,6 @@ <field index="tablenames">tt_content</field> <field index="fieldname">image</field> <field index="sorting_foreign">0</field> - <field index="table_local">sys_file</field> <field index="title" type="NULL"></field> <field index="description" type="NULL"></field> <field index="alternative" type="NULL"></field> diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-spaces-in-path.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-spaces-in-path.xml index f0da39847a8d2336f61fa5ed1697f49253362418..81b2635eed6d29147a3a6f7291aa48c659e55f3b 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-spaces-in-path.xml +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-spaces-in-path.xml @@ -211,7 +211,6 @@ <field index="tablenames">tt_content</field> <field index="fieldname">image</field> <field index="sorting_foreign">0</field> - <field index="table_local">sys_file</field> <field index="title" type="NULL"></field> <field index="description" type="NULL"></field> <field index="alternative" type="NULL"></field> diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-without-storage.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-without-storage.xml index 6a6c21be699f2ee77abe50df9280912e45cea535..51bba33540151d18ef0f2a1357807abb2d52d2e6 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-without-storage.xml +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-without-storage.xml @@ -202,7 +202,6 @@ <field index="tablenames">tt_content</field> <field index="fieldname">image</field> <field index="sorting_foreign">0</field> - <field index="table_local">sys_file</field> <field index="title" type="NULL"></field> <field index="description" type="NULL"></field> <field index="alternative" type="NULL"></field> diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image.xml index c14399d80338d593388e45c4750a15d16be247a2..65626d0c7935b6e1f38634c3d1738b4b9b9a987b 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image.xml +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image.xml @@ -245,7 +245,6 @@ <field index="tablenames">tt_content</field> <field index="fieldname">image</field> <field index="sorting_foreign">0</field> - <field index="table_local">sys_file</field> <field index="title" type="NULL"></field> <field index="description" type="NULL"></field> <field index="alternative" type="NULL"></field> diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-missing-image.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-missing-image.xml index 6894844bf3b35975ba4863e3504abee0b721857f..933827009260324ec16bdbd7c1f4378921de43ee 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-missing-image.xml +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-missing-image.xml @@ -192,7 +192,6 @@ <field index="tablenames">tt_content</field> <field index="fieldname">image</field> <field index="sorting_foreign">0</field> - <field index="table_local">sys_file</field> <field index="title" type="NULL"></field> <field index="description" type="NULL"></field> <field index="alternative" type="NULL"></field> diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-two-images.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-two-images.xml index b8c1f00976949af3c4746ea4e0a7b30142f5a8bf..d358b74ad98b371925754d58cf3bbb6b59c1d756 100644 --- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-two-images.xml +++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-two-images.xml @@ -263,7 +263,6 @@ <field index="tablenames">tt_content</field> <field index="fieldname">image</field> <field index="sorting_foreign">0</field> - <field index="table_local">sys_file</field> <field index="title" type="NULL"></field> <field index="description" type="NULL"></field> <field index="alternative" type="NULL"></field> @@ -290,7 +289,6 @@ <field index="tablenames">tt_content</field> <field index="fieldname">image</field> <field index="sorting_foreign">0</field> - <field index="table_local">sys_file</field> <field index="title" type="NULL"></field> <field index="description" type="NULL"></field> <field index="alternative" type="NULL"></field> @@ -317,7 +315,6 @@ <field index="tablenames">tt_content</field> <field index="fieldname">image</field> <field index="sorting_foreign">0</field> - <field index="table_local">sys_file</field> <field index="title" type="NULL"></field> <field index="description" type="NULL"></field> <field index="alternative" type="NULL"></field> diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php index 66650f5d74fcda1539b4c52c649cebb20b33f6f3..501230959b8b9b0e2f7503a22877ed5e0f2b6310 100644 --- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php @@ -2182,4 +2182,9 @@ return [ 'Breaking-98490-VariousHooksAndMethodsChangedInDatabaseRecordList.rst', ], ], + 'TYPO3\CMS\Core\Resource\Service\UserFileInlineLabelService' => [ + 'restFiles' => [ + 'Deprecation-98479-DeprecatedFileReferenceRelatedFunctionality.rst', + ], + ], ]; diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php index 6b67de65662a4214a3df8705df29523ab1923104..f9ff9b58f2d4e94544980594f9b3205bb425a031 100644 --- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php @@ -5351,5 +5351,11 @@ return [ 'Breaking-98490-VariousHooksAndMethodsChangedInDatabaseRecordList.rst', ], ], - + 'TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter->filterInlineChildren' => [ + 'numberOfMandatoryArguments' => 2, + 'maximumNumberOfArguments' => 2, + 'restFiles' => [ + 'Deprecation-98479-DeprecatedFileReferenceRelatedFunctionality.rst', + ], + ], ]; diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php index d9dd1f44ecc4b342b9e21d9501cb74ff66a3a8a3..5671d1f86d615650add1b51247727c4ac75daeb4 100644 --- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php @@ -1392,4 +1392,11 @@ return [ 'Deprecation-97544-PreviewURIGenerationRelatedFunctionalityInBackendUtility.rst', ], ], + 'TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig' => [ + 'numberOfMandatoryArguments' => 1, + 'maximumNumberOfArguments' => 4, + 'restFiles' => [ + 'Deprecation-98479-DeprecatedFileReferenceRelatedFunctionality.rst', + ], + ], ]; diff --git a/typo3/sysext/seo/Configuration/TCA/Overrides/pages.php b/typo3/sysext/seo/Configuration/TCA/Overrides/pages.php index f784c40268cc01151d11da7b66e106550ce83ccf..11146a456a3d16882a53680e33939a53e757bbbf 100644 --- a/typo3/sysext/seo/Configuration/TCA/Overrides/pages.php +++ b/typo3/sysext/seo/Configuration/TCA/Overrides/pages.php @@ -181,33 +181,31 @@ $tca = [ 'og_image' => [ 'exclude' => true, 'label' => 'LLL:EXT:seo/Resources/Private/Language/locallang_tca.xlf:pages.og_image', - 'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig( - 'og_image', - [ - // Use the imageoverlayPalette instead of the basicoverlayPalette - 'overrideChildTca' => [ - 'types' => [ - '0' => [ - 'showitem' => ' - --palette--;;imageoverlayPalette, - --palette--;;filePalette', - ], - \TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [ - 'showitem' => ' - --palette--;;imageoverlayPalette, - --palette--;;filePalette', - ], + 'config' => [ + 'type' => 'file', + 'allowed' => 'common-image-types', + 'behaviour' => [ + 'allowLanguageSynchronization' => true, + ], + // Use the imageoverlayPalette instead of the basicoverlayPalette + 'overrideChildTca' => [ + 'types' => [ + '0' => [ + 'showitem' => ' + --palette--;;imageoverlayPalette, + --palette--;;filePalette', ], - 'columns' => [ - 'crop' => $openGraphCropConfiguration, + \TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [ + 'showitem' => ' + --palette--;;imageoverlayPalette, + --palette--;;filePalette', ], ], - 'behaviour' => [ - 'allowLanguageSynchronization' => true, + 'columns' => [ + 'crop' => $openGraphCropConfiguration, ], ], - $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] - ), + ], ], 'twitter_title' => [ 'exclude' => true, @@ -233,33 +231,31 @@ $tca = [ 'twitter_image' => [ 'exclude' => true, 'label' => 'LLL:EXT:seo/Resources/Private/Language/locallang_tca.xlf:pages.twitter_image', - 'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig( - 'twitter_image', - [ - // Use the imageoverlayPalette instead of the basicoverlayPalette - 'overrideChildTca' => [ - 'types' => [ - '0' => [ - 'showitem' => ' - --palette--;;imageoverlayPalette, - --palette--;;filePalette', - ], - \TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [ - 'showitem' => ' - --palette--;;imageoverlayPalette, - --palette--;;filePalette', - ], + 'config' => [ + 'type' => 'file', + 'allowed' => 'common-image-types', + 'behaviour' => [ + 'allowLanguageSynchronization' => true, + ], + // Use the imageoverlayPalette instead of the basicoverlayPalette + 'overrideChildTca' => [ + 'types' => [ + '0' => [ + 'showitem' => ' + --palette--;;imageoverlayPalette, + --palette--;;filePalette', ], - 'columns' => [ - 'crop' => $openGraphCropConfiguration, + \TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [ + 'showitem' => ' + --palette--;;imageoverlayPalette, + --palette--;;filePalette', ], ], - 'behaviour' => [ - 'allowLanguageSynchronization' => true, + 'columns' => [ + 'crop' => $openGraphCropConfiguration, ], ], - $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] - ), + ], ], 'twitter_card' => [ 'exclude' => true, diff --git a/typo3/sysext/setup/Classes/Controller/SetupModuleController.php b/typo3/sysext/setup/Classes/Controller/SetupModuleController.php index 9303aaa17c9f8a4dcdbeebb8b1c18e54fca27c3d..4bd5950e870f59dc256bcf9bf99c6c162a6361e1 100644 --- a/typo3/sysext/setup/Classes/Controller/SetupModuleController.php +++ b/typo3/sysext/setup/Classes/Controller/SetupModuleController.php @@ -724,10 +724,6 @@ class SetupModuleController 'fieldname', $queryBuilder->createNamedParameter('avatar', \PDO::PARAM_STR) ), - $queryBuilder->expr()->eq( - 'table_local', - $queryBuilder->createNamedParameter('sys_file', \PDO::PARAM_STR) - ), $queryBuilder->expr()->eq( 'uid_foreign', $queryBuilder->createNamedParameter($beUserId, \PDO::PARAM_INT) @@ -771,10 +767,6 @@ class SetupModuleController 'fieldname', $queryBuilder->createNamedParameter('avatar', \PDO::PARAM_STR) ), - $queryBuilder->expr()->eq( - 'table_local', - $queryBuilder->createNamedParameter('sys_file', \PDO::PARAM_STR) - ), $queryBuilder->expr()->eq( 'uid_foreign', $queryBuilder->createNamedParameter($beUserId, \PDO::PARAM_INT) @@ -811,7 +803,6 @@ class SetupModuleController 'tablenames' => 'be_users', 'fieldname' => 'avatar', 'pid' => 0, - 'table_local' => 'sys_file', ]; $storeRec['be_users'][(int)$beUserId]['avatar'] = 'NEW1234'; } diff --git a/typo3/sysext/setup/ext_tables.php b/typo3/sysext/setup/ext_tables.php index 9255c607a1366ce306180a71bf0aea745641e1bc..94b7e8e0cbb87e522ed31cb38dc3c707fdfb52b4 100644 --- a/typo3/sysext/setup/ext_tables.php +++ b/typo3/sysext/setup/ext_tables.php @@ -43,7 +43,7 @@ $GLOBALS['TYPO3_USER_SETTINGS'] = [ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.avatar', 'type' => 'avatar', 'table' => 'be_users', - 'allowed' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], + 'allowed' => 'common-image-types', ], 'lang' => [ 'type' => 'language', diff --git a/typo3/sysext/workspaces/Classes/Controller/Remote/RemoteServer.php b/typo3/sysext/workspaces/Classes/Controller/Remote/RemoteServer.php index b864784666871ac371380b6f41a17bf8c807d5bc..68e817f60c2f3181018fa5acc3cabb15c9915093 100644 --- a/typo3/sysext/workspaces/Classes/Controller/Remote/RemoteServer.php +++ b/typo3/sysext/workspaces/Classes/Controller/Remote/RemoteServer.php @@ -150,11 +150,11 @@ class RemoteServer // check for exclude fields if ($this->getBackendUser()->isAdmin() || $GLOBALS['TCA'][$parameter->table]['columns'][$fieldName]['exclude'] == 0 || GeneralUtility::inList($this->getBackendUser()->groupData['non_exclude_fields'], $parameter->table . ':' . $fieldName)) { // call diff class only if there is a difference - if ($configuration['type'] === 'inline' && $configuration['foreign_table'] === 'sys_file_reference') { + if ($configuration['type'] === 'file') { $useThumbnails = false; - if (!empty($configuration['overrideChildTca']['columns']['uid_local']['config']['appearance']['elementBrowserAllowed']) && !empty($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'])) { + if (!empty($configuration['allowed']) && !empty($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'])) { $fileExtensions = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], true); - $allowedExtensions = GeneralUtility::trimExplode(',', $configuration['overrideChildTca']['columns']['uid_local']['config']['appearance']['elementBrowserAllowed'], true); + $allowedExtensions = GeneralUtility::trimExplode(',', $configuration['allowed'], true); $differentExtensions = array_diff($allowedExtensions, $fileExtensions); $useThumbnails = empty($differentExtensions); } diff --git a/typo3/sysext/workspaces/Classes/Dependency/ElementEntityProcessor.php b/typo3/sysext/workspaces/Classes/Dependency/ElementEntityProcessor.php index 61c07aa2fb554777be4cb4b2061a9c3863a4da79..2bb08be718d16af2fb73053e39ef78351321d4d2 100644 --- a/typo3/sysext/workspaces/Classes/Dependency/ElementEntityProcessor.php +++ b/typo3/sysext/workspaces/Classes/Dependency/ElementEntityProcessor.php @@ -99,7 +99,7 @@ class ElementEntityProcessor return ElementEntity::RESPONSE_Skip; } $fieldConfiguration = BackendUtility::getTcaFieldConfiguration($caller->getTable(), $callerArguments['field']); - $inlineFieldType = $this->getDataHandler()->getInlineFieldType($fieldConfiguration); + $inlineFieldType = $this->getDataHandler()->getRelationFieldType($fieldConfiguration); if (!$fieldConfiguration || ($fieldConfiguration['type'] !== 'flex' && $inlineFieldType !== 'field' && $inlineFieldType !== 'list')) { return ElementEntity::RESPONSE_Skip; } @@ -118,7 +118,7 @@ class ElementEntityProcessor public function createNewDependentElementParentReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName) { $fieldConfiguration = BackendUtility::getTcaFieldConfiguration($callerArguments['table'], $callerArguments['field']); - $inlineFieldType = $this->getDataHandler()->getInlineFieldType($fieldConfiguration); + $inlineFieldType = $this->getDataHandler()->getRelationFieldType($fieldConfiguration); if (!$fieldConfiguration || ($fieldConfiguration['type'] !== 'flex' && $inlineFieldType !== 'field' && $inlineFieldType !== 'list')) { return ElementEntity::RESPONSE_Skip; } diff --git a/typo3/sysext/workspaces/Classes/Hook/DataHandlerHook.php b/typo3/sysext/workspaces/Classes/Hook/DataHandlerHook.php index f44b78fb0b94e879d7c38b7e804b4d4dc8a595d8..09bbfab1358db49c43cfd3e53d79c653c2555749 100644 --- a/typo3/sysext/workspaces/Classes/Hook/DataHandlerHook.php +++ b/typo3/sysext/workspaces/Classes/Hook/DataHandlerHook.php @@ -431,36 +431,34 @@ class DataHandlerHook */ protected function moveRecord_processFieldValue(DataHandler $dataHandler, $resolvedPageId, $table, $uid, $value, array $configuration): void { - $inlineFieldType = $dataHandler->getInlineFieldType($configuration); - $inlineProcessing = ( - ($inlineFieldType === 'list' || $inlineFieldType === 'field') - && BackendUtility::isTableWorkspaceEnabled($configuration['foreign_table']) - && (!isset($configuration['behaviour']['disableMovingChildrenWithParent']) || !$configuration['behaviour']['disableMovingChildrenWithParent']) - ); + if (($configuration['behaviour']['disableMovingChildrenWithParent'] ?? false) + || !in_array($dataHandler->getRelationFieldType($configuration), ['list', 'field'], true) + || !BackendUtility::isTableWorkspaceEnabled($configuration['foreign_table']) + ) { + return; + } - if ($inlineProcessing) { - if ($table === 'pages') { - // If the inline elements are related to a page record, - // make sure they reside at that page and not at its parent - $resolvedPageId = $uid; - } + if ($table === 'pages') { + // If the inline elements are related to a page record, + // make sure they reside at that page and not at its parent + $resolvedPageId = $uid; + } - $dbAnalysis = $this->createRelationHandlerInstance(); - $dbAnalysis->start($value, $configuration['foreign_table'], '', $uid, $table, $configuration); + $dbAnalysis = $this->createRelationHandlerInstance(); + $dbAnalysis->start($value, $configuration['foreign_table'], '', $uid, $table, $configuration); - // Moving records to a positive destination will insert each - // record at the beginning, thus the order is reversed here: - foreach ($dbAnalysis->itemArray as $item) { - $versionedRecord = BackendUtility::getWorkspaceVersionOfRecord($dataHandler->BE_USER->workspace, $item['table'], $item['id'], 'uid,t3ver_state'); - if (empty($versionedRecord)) { - continue; - } - $versionState = VersionState::cast($versionedRecord['t3ver_state']); - if ($versionState->indicatesPlaceholder()) { - continue; - } - $dataHandler->moveRecord($item['table'], $item['id'], $resolvedPageId); + // Moving records to a positive destination will insert each + // record at the beginning, thus the order is reversed here: + foreach ($dbAnalysis->itemArray as $item) { + $versionedRecord = BackendUtility::getWorkspaceVersionOfRecord($dataHandler->BE_USER->workspace, $item['table'], $item['id'], 'uid,t3ver_state'); + if (empty($versionedRecord)) { + continue; + } + $versionState = VersionState::cast($versionedRecord['t3ver_state']); + if ($versionState->indicatesPlaceholder()) { + continue; } + $dataHandler->moveRecord($item['table'], $item['id'], $resolvedPageId); } } @@ -895,8 +893,7 @@ class DataHandlerHook */ protected function version_swap_processFields($tableName, array $configuration, array $liveData, array $versionData, DataHandler $dataHandler) { - $inlineType = $dataHandler->getInlineFieldType($configuration); - if ($inlineType !== 'field') { + if ($dataHandler->getRelationFieldType($configuration) !== 'field') { return; } $foreignTable = $configuration['foreign_table'];