From 45e03bec9c2217845f9b8a42116ff64a87fa1b65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BCrk?= <stefan@buerk.tech> Date: Wed, 30 Aug 2023 15:23:27 +0200 Subject: [PATCH] [BUGFIX] Ensure correct record type for new record in SuggestWizard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FormEngine sends some information as payload with the suggest wizard ajax request to the `SuggestWizardController` as context. The controller loads the record based on the tableName and the uid to determine the recordType to read the correct TCA field configuration, respecting special overrides like `columnsOverrides`. If a new record is created, there is no record uid available and passed to the controller. Therefore, the recordType is not properly determined. That leads to wrong record suggestions, if for example the `allowed` record table is overriden for specific recordTypes. This change adds the recordTypeValue as additional html data attribute to the suggest search field, reads and sends it along with the context payload in the ajax request to the suggest wizard controller, which now uses the passed value while keeping the record retrievement as fallback for now. Suggest records are now directly searched correctly respecting the full TCA configuration for the type, even for new records. Additionally, uid is send as null instead of the string "NaN". Used command(s): > Build/Scripts/runTests.sh -s buildJavascript Resolves: #101796 Releases: main, 12.4, 11.5 Change-Id: I3b814d37b7d4d3e9674ad6f2af882520c4f91413 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/80773 Tested-by: Stefan B�rk <stefan@buerk.tech> Reviewed-by: Stefan B�rk <stefan@buerk.tech> Tested-by: core-ci <typo3@b13.com> --- .../Sources/TypeScript/backend/form-engine-suggest.ts | 4 +++- .../Controller/Wizard/SuggestWizardController.php | 10 ++++++++-- .../backend/Classes/Form/Element/GroupElement.php | 4 ++++ .../Resources/Public/JavaScript/form-engine-suggest.js | 2 +- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Build/Sources/TypeScript/backend/form-engine-suggest.ts b/Build/Sources/TypeScript/backend/form-engine-suggest.ts index 8f9d5e34828a..754a8feea19f 100644 --- a/Build/Sources/TypeScript/backend/form-engine-suggest.ts +++ b/Build/Sources/TypeScript/backend/form-engine-suggest.ts @@ -81,18 +81,20 @@ class FormEngineSuggest { return; } + const uid = parseInt(target.dataset.uid, 10); this.currentRequest = new AjaxRequest(TYPO3.settings.ajaxUrls.record_suggest); this.currentRequest.post({ value: target.value, tableName: target.dataset.tablename, fieldName: target.dataset.fieldname, - uid: parseInt(target.dataset.uid, 10), + uid: (isNaN(uid) ? null : uid), pid: parseInt(target.dataset.pid, 10), dataStructureIdentifier: target.dataset.datastructureidentifier, flexFormSheetName: target.dataset.flexformsheetname, flexFormFieldName: target.dataset.flexformfieldname, flexFormContainerName: target.dataset.flexformcontainername, flexFormContainerFieldName: target.dataset.flexformcontainerfieldname, + recordTypeValue: target.dataset.recordtypevalue, }).then(async (response: AjaxResponse): Promise<void> => { const resultSet = await response.raw().text(); this.resultContainer.setAttribute('results', resultSet); diff --git a/typo3/sysext/backend/Classes/Controller/Wizard/SuggestWizardController.php b/typo3/sysext/backend/Classes/Controller/Wizard/SuggestWizardController.php index 8443402af54e..d464b37c8d40 100644 --- a/typo3/sysext/backend/Classes/Controller/Wizard/SuggestWizardController.php +++ b/typo3/sysext/backend/Classes/Controller/Wizard/SuggestWizardController.php @@ -54,6 +54,7 @@ class SuggestWizardController $flexFormFieldName = $parsedBody['flexFormFieldName'] ?? null; $flexFormContainerName = $parsedBody['flexFormContainerName'] ?? null; $flexFormContainerFieldName = $parsedBody['flexFormContainerFieldName'] ?? null; + $recordType = (string)($parsedBody['recordTypeValue'] ?? ''); // Determine TCA config of field if (empty($dataStructureIdentifier)) { @@ -62,8 +63,13 @@ class SuggestWizardController $fieldNameInPageTsConfig = $fieldName; // With possible columnsOverrides - $row = BackendUtility::getRecord($tableName, $uid) ?? []; - $recordType = BackendUtility::getTCAtypeValue($tableName, $row); + // @todo Validate if we can move this fallback recordType determination, should be do-able in v13?! + if ($recordType === '') { + $recordType = BackendUtility::getTCAtypeValue( + $tableName, + BackendUtility::getRecord($tableName, $uid) ?? [] + ); + } $columnsOverridesConfigOfField = $GLOBALS['TCA'][$tableName]['types'][$recordType]['columnsOverrides'][$fieldName]['config'] ?? null; if ($columnsOverridesConfigOfField) { ArrayUtility::mergeRecursiveWithOverrule($fieldConfig, $columnsOverridesConfigOfField); diff --git a/typo3/sysext/backend/Classes/Form/Element/GroupElement.php b/typo3/sysext/backend/Classes/Form/Element/GroupElement.php index d9751e978c8d..87bd519b798c 100644 --- a/typo3/sysext/backend/Classes/Form/Element/GroupElement.php +++ b/typo3/sysext/backend/Classes/Form/Element/GroupElement.php @@ -116,6 +116,7 @@ class GroupElement extends AbstractFormElement $parameterArray = $this->data['parameterArray']; $config = $parameterArray['fieldConf']['config']; $elementName = $parameterArray['itemFormElName']; + $recordTypeValue = $this->data['recordTypeValue'] ?? null; $selectedItems = $parameterArray['itemFormElValue']; $maxItems = $config['maxitems']; @@ -269,6 +270,9 @@ class GroupElement extends AbstractFormElement $html[] = ' data-flexformfieldname="' . htmlspecialchars($flexFormFieldName) . '"'; $html[] = ' data-flexformcontainername="' . htmlspecialchars($flexFormContainerName) . '"'; $html[] = ' data-flexformcontainerfieldname="' . htmlspecialchars($flexFormContainerFieldName) . '"'; + if ($recordTypeValue !== null && $recordTypeValue !== '') { + $html[] = ' data-recordtypevalue="' . htmlspecialchars($recordTypeValue) . '"'; + } $html[] = '/>'; $html[] = '</div>'; $html[] = '</div>'; diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/form-engine-suggest.js b/typo3/sysext/backend/Resources/Public/JavaScript/form-engine-suggest.js index 2d4532c702e5..7ae93231dc9d 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/form-engine-suggest.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/form-engine-suggest.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import"@typo3/backend/form-engine/element/suggest/result-container.js";import DocumentService from"@typo3/core/document-service.js";import FormEngine from"@typo3/backend/form-engine.js";import RegularEvent from"@typo3/core/event/regular-event.js";import DebounceEvent from"@typo3/core/event/debounce-event.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";class FormEngineSuggest{constructor(e){this.currentRequest=null,this.handleKeyDown=e=>{if("ArrowDown"!==e.key)"Escape"===e.key&&(e.preventDefault(),this.resultContainer.hidden=!0);else{e.preventDefault();const t=JSON.parse(this.resultContainer.getAttribute("results"));t?.length>0&&(this.resultContainer.hidden=!1);const n=this.resultContainer.querySelector("typo3-backend-formengine-suggest-result-item");n?.focus()}},this.element=e,DocumentService.ready().then((()=>{this.initialize(e),this.registerEvents()}))}initialize(e){const t=e.closest(".t3-form-suggest-container");this.resultContainer=document.createElement("typo3-backend-formengine-suggest-result-container"),this.resultContainer.hidden=!0,t.append(this.resultContainer)}registerEvents(){new RegularEvent("typo3:formengine:suggest-item-chosen",(e=>{let t="";t="select"===this.element.dataset.fieldtype?e.detail.element.uid:e.detail.element.table+"_"+e.detail.element.uid,FormEngine.setSelectOptionFromExternalSource(this.element.dataset.field,t,e.detail.element.label,e.detail.element.label),FormEngine.Validation.markFieldAsChanged(document.querySelector('input[name="'+this.element.dataset.field+'"]')),this.resultContainer.hidden=!0})).bindTo(this.resultContainer),new RegularEvent("focus",(()=>{const e=JSON.parse(this.resultContainer.getAttribute("results"));e?.length>0&&(this.resultContainer.hidden=!1)})).bindTo(this.element),new RegularEvent("blur",(e=>{"typo3-backend-formengine-suggest-result-item"!==e.relatedTarget?.tagName.toLowerCase()&&(this.resultContainer.hidden=!0)})).bindTo(this.element),new DebounceEvent("input",(e=>{this.currentRequest instanceof AjaxRequest&&this.currentRequest.abort();const t=e.target;t.value.length<parseInt(t.dataset.minchars,10)||(this.currentRequest=new AjaxRequest(TYPO3.settings.ajaxUrls.record_suggest),this.currentRequest.post({value:t.value,tableName:t.dataset.tablename,fieldName:t.dataset.fieldname,uid:parseInt(t.dataset.uid,10),pid:parseInt(t.dataset.pid,10),dataStructureIdentifier:t.dataset.datastructureidentifier,flexFormSheetName:t.dataset.flexformsheetname,flexFormFieldName:t.dataset.flexformfieldname,flexFormContainerName:t.dataset.flexformcontainername,flexFormContainerFieldName:t.dataset.flexformcontainerfieldname}).then((async e=>{const t=await e.raw().text();this.resultContainer.setAttribute("results",t),this.resultContainer.hidden=!1})))})).bindTo(this.element),new RegularEvent("keydown",this.handleKeyDown).bindTo(this.element)}}export default FormEngineSuggest; \ No newline at end of file +import"@typo3/backend/form-engine/element/suggest/result-container.js";import DocumentService from"@typo3/core/document-service.js";import FormEngine from"@typo3/backend/form-engine.js";import RegularEvent from"@typo3/core/event/regular-event.js";import DebounceEvent from"@typo3/core/event/debounce-event.js";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";class FormEngineSuggest{constructor(e){this.currentRequest=null,this.handleKeyDown=e=>{if("ArrowDown"!==e.key)"Escape"===e.key&&(e.preventDefault(),this.resultContainer.hidden=!0);else{e.preventDefault();const t=JSON.parse(this.resultContainer.getAttribute("results"));t?.length>0&&(this.resultContainer.hidden=!1);const n=this.resultContainer.querySelector("typo3-backend-formengine-suggest-result-item");n?.focus()}},this.element=e,DocumentService.ready().then((()=>{this.initialize(e),this.registerEvents()}))}initialize(e){const t=e.closest(".t3-form-suggest-container");this.resultContainer=document.createElement("typo3-backend-formengine-suggest-result-container"),this.resultContainer.hidden=!0,t.append(this.resultContainer)}registerEvents(){new RegularEvent("typo3:formengine:suggest-item-chosen",(e=>{let t="";t="select"===this.element.dataset.fieldtype?e.detail.element.uid:e.detail.element.table+"_"+e.detail.element.uid,FormEngine.setSelectOptionFromExternalSource(this.element.dataset.field,t,e.detail.element.label,e.detail.element.label),FormEngine.Validation.markFieldAsChanged(document.querySelector('input[name="'+this.element.dataset.field+'"]')),this.resultContainer.hidden=!0})).bindTo(this.resultContainer),new RegularEvent("focus",(()=>{const e=JSON.parse(this.resultContainer.getAttribute("results"));e?.length>0&&(this.resultContainer.hidden=!1)})).bindTo(this.element),new RegularEvent("blur",(e=>{"typo3-backend-formengine-suggest-result-item"!==e.relatedTarget?.tagName.toLowerCase()&&(this.resultContainer.hidden=!0)})).bindTo(this.element),new DebounceEvent("input",(e=>{this.currentRequest instanceof AjaxRequest&&this.currentRequest.abort();const t=e.target;if(t.value.length<parseInt(t.dataset.minchars,10))return;const n=parseInt(t.dataset.uid,10);this.currentRequest=new AjaxRequest(TYPO3.settings.ajaxUrls.record_suggest),this.currentRequest.post({value:t.value,tableName:t.dataset.tablename,fieldName:t.dataset.fieldname,uid:isNaN(n)?null:n,pid:parseInt(t.dataset.pid,10),dataStructureIdentifier:t.dataset.datastructureidentifier,flexFormSheetName:t.dataset.flexformsheetname,flexFormFieldName:t.dataset.flexformfieldname,flexFormContainerName:t.dataset.flexformcontainername,flexFormContainerFieldName:t.dataset.flexformcontainerfieldname,recordTypeValue:t.dataset.recordtypevalue}).then((async e=>{const t=await e.raw().text();this.resultContainer.setAttribute("results",t),this.resultContainer.hidden=!1}))})).bindTo(this.element),new RegularEvent("keydown",this.handleKeyDown).bindTo(this.element)}}export default FormEngineSuggest; \ No newline at end of file -- GitLab