diff --git a/typo3/sysext/form/Classes/Controller/FormEditorController.php b/typo3/sysext/form/Classes/Controller/FormEditorController.php index b0eae72e6030832ba52c43213685c968406100a0..1c54bed90e6fbf1a2d2db5197f5f4493cfe44f57 100644 --- a/typo3/sysext/form/Classes/Controller/FormEditorController.php +++ b/typo3/sysext/form/Classes/Controller/FormEditorController.php @@ -22,6 +22,7 @@ use TYPO3\CMS\Core\Imaging\Icon; use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Utility\ArrayUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Extbase\Mvc\View\JsonView; use TYPO3\CMS\Fluid\View\TemplateView; use TYPO3\CMS\Form\Domain\Configuration\ConfigurationService; use TYPO3\CMS\Form\Domain\Exception\RenderingException; @@ -129,15 +130,25 @@ class FormEditorController extends AbstractBackendController $this->view->assign('addInlineSettings', $addInlineSettings); } + /** + * Initialize the save action. + * This action uses the Fluid JsonView::class as view. + * + * @internal + */ + public function initializeSaveFormAction() + { + $this->defaultViewObjectName = JsonView::class; + } + /** * Save a formDefinition which was build by the form editor. * * @param string $formPersistenceIdentifier * @param array $formDefinition - * @return string * @internal */ - public function saveFormAction(string $formPersistenceIdentifier, array $formDefinition): string + public function saveFormAction(string $formPersistenceIdentifier, array $formDefinition) { $formDefinition = ArrayUtility::stripTagsFromValuesRecursive($formDefinition); $formDefinition = $this->convertJsonArrayToAssociativeArray($formDefinition); @@ -152,8 +163,26 @@ class FormEditorController extends AbstractBackendController } } - $this->formPersistenceManager->save($formPersistenceIdentifier, $formDefinition); - return ''; + $response = [ + 'status' => 'success', + ]; + + try { + $this->formPersistenceManager->save($formPersistenceIdentifier, $formDefinition); + } catch (PersistenceManagerException $e) { + $response = [ + 'status' => 'error', + 'message' => $e->getMessage(), + 'code' => $e->getCode(), + ]; + } + + $this->view->assign('response', $response); + // saveFormAction uses the extbase JsonView::class. + // That's why we have to set the view variables in this way. + $this->view->setVariablesToRender([ + 'response', + ]); } /** diff --git a/typo3/sysext/form/Classes/Controller/FormManagerController.php b/typo3/sysext/form/Classes/Controller/FormManagerController.php index 609cb34d3de443f7be3caef0c35044a730611a5a..71f5639b647d3a31761edab0057e57b6f1c12eee 100644 --- a/typo3/sysext/form/Classes/Controller/FormManagerController.php +++ b/typo3/sysext/form/Classes/Controller/FormManagerController.php @@ -30,6 +30,7 @@ use TYPO3\CMS\Core\Utility\ArrayUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Mvc\View\JsonView; use TYPO3\CMS\Form\Exception as FormException; +use TYPO3\CMS\Form\Mvc\Persistence\Exception\PersistenceManagerException; use TYPO3\CMS\Form\Service\TranslationService; /** @@ -47,17 +48,6 @@ class FormManagerController extends AbstractBackendController */ protected $defaultViewObjectName = BackendTemplateView::class; - /** - * Initialize the references action. - * This action use the Fluid JsonView::class as view. - * - * @internal - */ - public function initializeReferencesAction() - { - $this->defaultViewObjectName = JsonView::class; - } - /** * Displays the Form Manager * @@ -78,6 +68,17 @@ class FormManagerController extends AbstractBackendController } } + /** + * Initialize the create action. + * This action uses the Fluid JsonView::class as view. + * + * @internal + */ + public function initializeCreateAction() + { + $this->defaultViewObjectName = JsonView::class; + } + /** * Creates a new Form and redirects to the Form Editor * @@ -85,11 +86,10 @@ class FormManagerController extends AbstractBackendController * @param string $templatePath * @param string $prototypeName * @param string $savePath - * @return string * @throws FormException * @internal */ - public function createAction(string $formName, string $templatePath, string $prototypeName, string $savePath): string + public function createAction(string $formName, string $templatePath, string $prototypeName, string $savePath) { if (!$this->isValidTemplatePath($prototypeName, $templatePath)) { throw new FormException(sprintf('The template path "%s" is not allowed', $templatePath), 1329233410); @@ -116,9 +116,38 @@ class FormManagerController extends AbstractBackendController } } - $this->formPersistenceManager->save($formPersistenceIdentifier, $form); + $response = [ + 'status' => 'success', + 'url' => $this->controllerContext->getUriBuilder()->uriFor('index', ['formPersistenceIdentifier' => $formPersistenceIdentifier], 'FormEditor') + ]; + + try { + $this->formPersistenceManager->save($formPersistenceIdentifier, $form); + } catch (PersistenceManagerException $e) { + $response = [ + 'status' => 'error', + 'message' => $e->getMessage(), + 'code' => $e->getCode(), + ]; + } + + $this->view->assign('response', $response); + // createAction uses the Extbase JsonView::class. + // That's why we have to set the view variables in this way. + $this->view->setVariablesToRender([ + 'response', + ]); + } - return $this->controllerContext->getUriBuilder()->uriFor('index', ['formPersistenceIdentifier' => $formPersistenceIdentifier], 'FormEditor'); + /** + * Initialize the duplicate action. + * This action uses the Fluid JsonView::class as view. + * + * @internal + */ + public function initializeDuplicateAction() + { + $this->defaultViewObjectName = JsonView::class; } /** @@ -127,10 +156,9 @@ class FormManagerController extends AbstractBackendController * @param string $formName * @param string $formPersistenceIdentifier persistence identifier of the form to duplicate * @param string $savePath - * @return string * @internal */ - public function duplicateAction(string $formName, string $formPersistenceIdentifier, string $savePath): string + public function duplicateAction(string $formName, string $formPersistenceIdentifier, string $savePath) { $formToDuplicate = $this->formPersistenceManager->load($formPersistenceIdentifier); $formToDuplicate['label'] = $formName; @@ -148,9 +176,38 @@ class FormManagerController extends AbstractBackendController } } - $this->formPersistenceManager->save($formPersistenceIdentifier, $formToDuplicate); + $response = [ + 'status' => 'success', + 'url' => $this->controllerContext->getUriBuilder()->uriFor('index', ['formPersistenceIdentifier' => $formPersistenceIdentifier], 'FormEditor') + ]; + + try { + $this->formPersistenceManager->save($formPersistenceIdentifier, $formToDuplicate); + } catch (PersistenceManagerException $e) { + $response = [ + 'status' => 'error', + 'message' => $e->getMessage(), + 'code' => $e->getCode(), + ]; + } + + $this->view->assign('response', $response); + // createAction uses the Extbase JsonView::class. + // That's why we have to set the view variables in this way. + $this->view->setVariablesToRender([ + 'response', + ]); + } - return $this->controllerContext->getUriBuilder()->uriFor('index', ['formPersistenceIdentifier' => $formPersistenceIdentifier], 'FormEditor'); + /** + * Initialize the references action. + * This action uses the Fluid JsonView::class as view. + * + * @internal + */ + public function initializeReferencesAction() + { + $this->defaultViewObjectName = JsonView::class; } /** diff --git a/typo3/sysext/form/Classes/Mvc/Configuration/Exception/FileWriteException.php b/typo3/sysext/form/Classes/Mvc/Configuration/Exception/FileWriteException.php new file mode 100644 index 0000000000000000000000000000000000000000..60b33f4c83ea10e42ccf1150250e2c38c0a7f495 --- /dev/null +++ b/typo3/sysext/form/Classes/Mvc/Configuration/Exception/FileWriteException.php @@ -0,0 +1,24 @@ +<?php +namespace TYPO3\CMS\Form\Mvc\Configuration\Exception; + +/* + * 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! + */ + +use TYPO3\CMS\Form\Mvc\Configuration\Exception; + +/** + * Exception for file write errors + */ +class FileWriteException extends Exception +{ +} diff --git a/typo3/sysext/form/Classes/Mvc/Configuration/YamlSource.php b/typo3/sysext/form/Classes/Mvc/Configuration/YamlSource.php index a82c83dcf2e84e7e5b98502504e62d362e854ef2..abce0d4c9a10a1581726521a963616ef53ca22c2 100644 --- a/typo3/sysext/form/Classes/Mvc/Configuration/YamlSource.php +++ b/typo3/sysext/form/Classes/Mvc/Configuration/YamlSource.php @@ -19,9 +19,11 @@ namespace TYPO3\CMS\Form\Mvc\Configuration; use Symfony\Component\Yaml\Exception\ParseException; use Symfony\Component\Yaml\Yaml; +use TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException; use TYPO3\CMS\Core\Resource\File; use TYPO3\CMS\Core\Utility\ArrayUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Form\Mvc\Configuration\Exception\FileWriteException; use TYPO3\CMS\Form\Mvc\Configuration\Exception\NoSuchFileException; use TYPO3\CMS\Form\Mvc\Configuration\Exception\ParseErrorException; @@ -122,17 +124,35 @@ class YamlSource * * @param File|string $fileToSave The file to write to. * @param array $configuration The configuration to save + * @throws FileWriteException if the file could not be written * @internal */ public function save($fileToSave, array $configuration) { - $header = $this->getHeaderFromFile($fileToSave); + try { + $header = $this->getHeaderFromFile($fileToSave); + } catch (InsufficientFileAccessPermissionsException $e) { + throw new FileWriteException($e->getMessage(), 1512584488, $e); + } + $yaml = Yaml::dump($configuration, 99, 2); + if ($fileToSave instanceof File) { - $fileToSave->setContents($header . LF . $yaml); + try { + $fileToSave->setContents($header . LF . $yaml); + } catch (InsufficientFileAccessPermissionsException $e) { + throw new FileWriteException($e->getMessage(), 1512582753, $e); + } } else { - @file_put_contents($fileToSave, $header . LF . $yaml); + $byteCount = @file_put_contents($fileToSave, $header . LF . $yaml); + + if ($byteCount === false) { + $error = error_get_last(); + throw new FileWriteException($error['message'], 1512582929); + } } + + return $return; } /** diff --git a/typo3/sysext/form/Classes/Mvc/Persistence/FormPersistenceManager.php b/typo3/sysext/form/Classes/Mvc/Persistence/FormPersistenceManager.php index fa5365eab8d04b6770f0a5a19674d623c1ac4caa..a0b7c52ecde34e25edb98d68ebdd49a110d696bd 100644 --- a/typo3/sysext/form/Classes/Mvc/Persistence/FormPersistenceManager.php +++ b/typo3/sysext/form/Classes/Mvc/Persistence/FormPersistenceManager.php @@ -27,6 +27,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\PathUtility; use TYPO3\CMS\Extbase\Object\ObjectManager; use TYPO3\CMS\Form\Mvc\Configuration\ConfigurationManagerInterface; +use TYPO3\CMS\Form\Mvc\Configuration\Exception\FileWriteException; use TYPO3\CMS\Form\Mvc\Persistence\Exception\NoUniqueIdentifierException; use TYPO3\CMS\Form\Mvc\Persistence\Exception\NoUniquePersistenceIdentifierException; use TYPO3\CMS\Form\Mvc\Persistence\Exception\PersistenceManagerException; @@ -154,7 +155,15 @@ class FormPersistenceManager implements FormPersistenceManagerInterface $fileToSave = $this->getOrCreateFile($persistenceIdentifier); } - $this->yamlSource->save($fileToSave, $formDefinition); + try { + $this->yamlSource->save($fileToSave, $formDefinition); + } catch (FileWriteException $e) { + throw new PersistenceManagerException(sprintf( + 'The file "%s" could not be saved: %s', + $persistenceIdentifier, + $e->getMessage() + ), 1512582637, $e); + } } /** @@ -503,7 +512,13 @@ class FormPersistenceManager implements FormPersistenceManagerInterface if (!$storage->hasFolder($pathinfo['dirname'])) { throw new PersistenceManagerException(sprintf('Could not create folder "%s".', $pathinfo['dirname']), 1471630579); } - $folder = $storage->getFolder($pathinfo['dirname']); + + try { + $folder = $storage->getFolder($pathinfo['dirname']); + } catch (InsufficientFolderAccessPermissionsException $e) { + throw new PersistenceManagerException(sprintf('No read access to folder "%s".', $pathinfo['dirname']), 1512583307); + } + if (!$storage->checkFolderActionPermission('write', $folder)) { throw new PersistenceManagerException(sprintf('No write access to folder "%s".', $pathinfo['dirname']), 1471630580); } diff --git a/typo3/sysext/form/Configuration/Yaml/FormEditorSetup.yaml b/typo3/sysext/form/Configuration/Yaml/FormEditorSetup.yaml index b66c86a640137fb131c0ab0affee39e045cf4fd2..61d1dd1b29e3ad1c4508422f20717184e9f2c583 100644 --- a/typo3/sysext/form/Configuration/Yaml/FormEditorSetup.yaml +++ b/typo3/sysext/form/Configuration/Yaml/FormEditorSetup.yaml @@ -137,6 +137,8 @@ TYPO3: saveSuccessFlashMessageTitle: 'formEditor.elements.Form.saveSuccessFlashMessageTitle' saveSuccessFlashMessageMessage: 'formEditor.elements.Form.saveSuccessFlashMessageMessage' + saveErrorFlashMessageTitle: 'formEditor.elements.Form.saveErrorFlashMessageTitle' + saveErrorFlashMessageMessage: 'formEditor.elements.Form.saveErrorFlashMessageMessage' modalValidationErrorsDialogTitle: 'formEditor.modals.validationErrors.dialogTitle' modalValidationErrorsConfirmButton: 'formEditor.modals.validationErrors.confirmButton' diff --git a/typo3/sysext/form/Documentation/Config/configuration/Index.rst b/typo3/sysext/form/Documentation/Config/configuration/Index.rst index 6e816a09ebc0e6f75b65983a3d9cadb4e85c9c57..56c6f8842b9c5fc741b1ae77108c3ab3d540352c 100644 --- a/typo3/sysext/form/Documentation/Config/configuration/Index.rst +++ b/typo3/sysext/form/Documentation/Config/configuration/Index.rst @@ -61,6 +61,8 @@ Full default configuration _isTopLevelFormElement: true saveSuccessFlashMessageTitle: formEditor.elements.Form.saveSuccessFlashMessageTitle saveSuccessFlashMessageMessage: formEditor.elements.Form.saveSuccessFlashMessageMessage + saveErrorFlashMessageTitle: formEditor.elements.Form.saveErrorFlashMessageTitle + saveErrorFlashMessageMessage: formEditor.elements.Form.saveErrorFlashMessageMessage modalValidationErrorsDialogTitle: formEditor.modals.validationErrors.dialogTitle modalValidationErrorsConfirmButton: formEditor.modals.validationErrors.confirmButton modalInsertElementsDialogTitle: formEditor.modals.insertElements.dialogTitle diff --git a/typo3/sysext/form/Documentation/Config/proto/formElements/formElementTypes/Form.rst b/typo3/sysext/form/Documentation/Config/proto/formElements/formElementTypes/Form.rst index 8b8443eec8668177147dfc8124553a654e4153a9..db8d454def10af5a4dfdf76ba0041c20b02a04af 100644 --- a/typo3/sysext/form/Documentation/Config/proto/formElements/formElementTypes/Form.rst +++ b/typo3/sysext/form/Documentation/Config/proto/formElements/formElementTypes/Form.rst @@ -90,6 +90,12 @@ Properties .. _typo3.cms.form.prototypes.<prototypeIdentifier>.formelementsdefinition.form.formeditor.savesuccessflashmessagemessage: .. include:: Form/formEditor/saveSuccessFlashMessageMessage.rst +.. _typo3.cms.form.prototypes.<prototypeIdentifier>.formelementsdefinition.form.formeditor.saveerrorflashmessagetitle: +.. include:: Form/formEditor/saveErrorFlashMessageTitle.rst + +.. _typo3.cms.form.prototypes.<prototypeIdentifier>.formelementsdefinition.form.formeditor.saveerrorflashmessagemessage: +.. include:: Form/formEditor/saveErrorFlashMessageMessage.rst + .. _typo3.cms.form.prototypes.<prototypeIdentifier>.formelementsdefinition.form.formeditor.modalvalidationerrorsdialogtitle: .. include:: Form/formEditor/modalValidationErrorsDialogTitle.rst diff --git a/typo3/sysext/form/Documentation/Config/proto/formElements/formElementTypes/Form/formEditor.rst b/typo3/sysext/form/Documentation/Config/proto/formElements/formElementTypes/Form/formEditor.rst index a0573114c88439c9e6bbe901f9269c8c2af5de4c..4d72513368d4e1327e659e784e380cf7b61870c4 100644 --- a/typo3/sysext/form/Documentation/Config/proto/formElements/formElementTypes/Form/formEditor.rst +++ b/typo3/sysext/form/Documentation/Config/proto/formElements/formElementTypes/Form/formEditor.rst @@ -61,6 +61,8 @@ formEditor _isTopLevelFormElement: true saveSuccessFlashMessageTitle: formEditor.elements.Form.saveSuccessFlashMessageTitle saveSuccessFlashMessageMessage: formEditor.elements.Form.saveSuccessFlashMessageMessage + saveErrorFlashMessageTitle: formEditor.elements.Form.saveErrorFlashMessageTitle + saveErrorFlashMessageMessage: formEditor.elements.Form.saveErrorFlashMessageMessage modalValidationErrorsDialogTitle: formEditor.modals.validationErrors.dialogTitle modalValidationErrorsConfirmButton: formEditor.modals.validationErrors.confirmButton modalInsertElementsDialogTitle: formEditor.modals.insertElements.dialogTitle diff --git a/typo3/sysext/form/Documentation/Config/proto/formElements/formElementTypes/Form/formEditor/saveErrorFlashMessageMessage.rst b/typo3/sysext/form/Documentation/Config/proto/formElements/formElementTypes/Form/formEditor/saveErrorFlashMessageMessage.rst new file mode 100644 index 0000000000000000000000000000000000000000..4779f1053259d08a6118efa010d45ef2159243f3 --- /dev/null +++ b/typo3/sysext/form/Documentation/Config/proto/formElements/formElementTypes/Form/formEditor/saveErrorFlashMessageMessage.rst @@ -0,0 +1,29 @@ +formEditor.saveErrorFlashMessageMessage +--------------------------------------- + +:aspect:`Option path` + TYPO3.CMS.Form.prototypes.<prototypeIdentifier>.formElementsDefinition.Form.formEditor.saveErrorFlashMessageMessage + +:aspect:`Data type` + string + +:aspect:`Needed by` + Backend (form editor) + +:aspect:`Mandatory` + Yes + +:aspect:`Default value (for prototype 'standard')` + .. code-block:: yaml + :linenos: + :emphasize-lines: 3 + + Form: + formEditor: + saveErrorFlashMessageMessage: formEditor.elements.Form.saveErrorFlashMessageMessage + +:aspect:`Good to know` + - :ref:`"Translate form editor settings"<concepts-formeditor-translation-formeditor>` + +:aspect:`Description` + Internal setting. diff --git a/typo3/sysext/form/Documentation/Config/proto/formElements/formElementTypes/Form/formEditor/saveErrorFlashMessageTitle.rst b/typo3/sysext/form/Documentation/Config/proto/formElements/formElementTypes/Form/formEditor/saveErrorFlashMessageTitle.rst new file mode 100644 index 0000000000000000000000000000000000000000..d14ae4980f68d8842f44fde4d2d7f8152a328a81 --- /dev/null +++ b/typo3/sysext/form/Documentation/Config/proto/formElements/formElementTypes/Form/formEditor/saveErrorFlashMessageTitle.rst @@ -0,0 +1,29 @@ +formEditor.saveErrorFlashMessageTitle +------------------------------------- + +:aspect:`Option path` + TYPO3.CMS.Form.prototypes.<prototypeIdentifier>.formElementsDefinition.Form.formEditor.saveErrorFlashMessageTitle + +:aspect:`Data type` + string + +:aspect:`Needed by` + Backend (form editor) + +:aspect:`Mandatory` + Yes + +:aspect:`Default value (for prototype 'standard')` + .. code-block:: yaml + :linenos: + :emphasize-lines: 3 + + Form: + formEditor: + saveErrorFlashMessageTitle: formEditor.elements.Form.saveErrorFlashMessageTitle + +:aspect:`Good to know` + - :ref:`"Translate form editor settings"<concepts-formeditor-translation-formeditor>` + +:aspect:`Description` + Internal setting. diff --git a/typo3/sysext/form/Resources/Private/Language/Database.xlf b/typo3/sysext/form/Resources/Private/Language/Database.xlf index 92877d9f1626faa28b53eb97d856e818f2a79c27..11d75883963186e07c7f7ad94009cae98c86aeb5 100644 --- a/typo3/sysext/form/Resources/Private/Language/Database.xlf +++ b/typo3/sysext/form/Resources/Private/Language/Database.xlf @@ -274,6 +274,13 @@ <source>The form has been successfully saved.</source> </trans-unit> + <trans-unit id="formEditor.elements.Form.saveErrorFlashMessageTitle" xml:space="preserve"> + <source>Save</source> + </trans-unit> + <trans-unit id="formEditor.elements.Form.saveErrorFlashMessageMessage" xml:space="preserve"> + <source>The form could not be saved:</source> + </trans-unit> + <trans-unit id="formEditor.modals.validationErrors.dialogTitle" xml:space="preserve"> <source>Alert</source> </trans-unit> diff --git a/typo3/sysext/form/Resources/Private/Language/locallang_formManager_javascript.xlf b/typo3/sysext/form/Resources/Private/Language/locallang_formManager_javascript.xlf index c2dfda26d1f1380074dbc32e846557171c706e6e..3e269d5fd2495b6654e330e29015170827490b27 100644 --- a/typo3/sysext/form/Resources/Private/Language/locallang_formManager_javascript.xlf +++ b/typo3/sysext/form/Resources/Private/Language/locallang_formManager_javascript.xlf @@ -48,9 +48,21 @@ <trans-unit id="formManager.newFormWizard.step3.message" xml:space="preserve"> <source>Now you are ready to create your new form.</source> </trans-unit> + <trans-unit id="formManager.newFormWizard.step4.errorTitle" xml:space="preserve"> + <source>Create</source> + </trans-unit> + <trans-unit id="formManager.newFormWizard.step4.errorMessage" xml:space="preserve"> + <source>The form could not be saved:</source> + </trans-unit> <trans-unit id="formManager.duplicateFormWizard.step1.title" xml:space="preserve"> <source>Duplicate form "{0}"</source> </trans-unit> + <trans-unit id="formManager.duplicateFormWizard.step2.errorTitle" xml:space="preserve"> + <source>Duplicate</source> + </trans-unit> + <trans-unit id="formManager.duplicateFormWizard.step2.errorMessage" xml:space="preserve"> + <source>The form could not be saved:</source> + </trans-unit> <trans-unit id="formManager.no_references" xml:space="preserve"> <source>There are no references yet</source> </trans-unit> @@ -68,4 +80,4 @@ </trans-unit> </body> </file> -</xliff> \ No newline at end of file +</xliff> diff --git a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/Core.js b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/Core.js index a2ef8c85b51d9e2135ba7d101b436e08c04c36ee..73f5165bab7521a0d4cec56131b68f542597c6a3 100644 --- a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/Core.js +++ b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/Core.js @@ -546,7 +546,7 @@ define(['jquery'], function($) { if ('array' !== $.type(formElementTypeDefinition['propertyCollections'][collectionName][i]['editors'][j]['propertyValidators'])) { continue; } - + if ( !utility().isUndefinedOrNull(formElementTypeDefinition['propertyCollections'][collectionName][i]['editors'][j]['propertyValidatorsMode']) && formElementTypeDefinition['propertyCollections'][collectionName][i]['editors'][j]['propertyValidatorsMode'] === 'OR' @@ -1989,7 +1989,11 @@ define(['jquery'], function($) { return; } _runningAjaxRequests['saveForm'] = null; - publisherSubscriber().publish('core/ajax/saveFormDefinition/success', [data]); + if (data['status'] === 'success') { + publisherSubscriber().publish('core/ajax/saveFormDefinition/success', [data]); + } else { + publisherSubscriber().publish('core/ajax/saveFormDefinition/error', [data]); + } }).fail(function(jqXHR, textStatus, errorThrown) { publisherSubscriber().publish('core/ajax/error', [jqXHR, textStatus, errorThrown]); }); diff --git a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/Mediator.js b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/Mediator.js index c9c6e6d273298cf701b724483f9f6b4f3cca5145..8a30e1068131abb4ba6866c712bfcc17cc1ad60f 100644 --- a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/Mediator.js +++ b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/Mediator.js @@ -209,6 +209,19 @@ define(['jquery', getViewModel().showSaveSuccessMessage(); }); + /** + * @private + * + * @param string + * @param array + * args[0] = object + * @return void + * @subscribe core/ajax/saveFormDefinition/error + */ + getPublisherSubscriber().subscribe('core/ajax/saveFormDefinition/error', function(topic, args) { + getViewModel().showSaveErrorMessage(args[0]); + }); + /** * @private * diff --git a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/ViewModel.js b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/ViewModel.js index c162a21bfd3a2657db9a3ca13d3884ff01d0ee75..761b60626d13f5edc1b25c3a88ff990da32cb698 100644 --- a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/ViewModel.js +++ b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/ViewModel.js @@ -518,7 +518,7 @@ define(['jquery', /** * @public * - * @param bool + * @param bool * @return void */ function setPreviewMode(previewMode) { @@ -747,7 +747,7 @@ define(['jquery', /** * @public * - * @param bool + * @param bool * @return void */ function showValidationErrorsModal() { @@ -1310,7 +1310,7 @@ define(['jquery', function removeAllStageElementSelectionsBatch() { getStage().getAllFormElementDomElements().removeClass(getHelper().getDomElementClassName('selectedFormElement')); removeStagePanelSelection(); - getStage().getAllFormElementDomElements().parent().removeClass(getHelper().getDomElementClassName('sortableHover')); + getStage().getAllFormElementDomElements().parent().removeClass(getHelper().getDomElementClassName('sortableHover')); }; /** @@ -1625,6 +1625,20 @@ define(['jquery', ); }; + /** + * @public + * + * @return void + */ + function showSaveErrorMessage(response) { + Notification.error( + getFormElementDefinition(getRootFormElement(), 'saveErrorFlashMessageTitle'), + getFormElementDefinition(getRootFormElement(), 'saveErrorFlashMessageMessage') + + " " + + response.message + ); + }; + /** * @public * @@ -1725,6 +1739,7 @@ define(['jquery', showSaveButtonSaveIcon: showSaveButtonSaveIcon, showSaveButtonSpinnerIcon: showSaveButtonSpinnerIcon, showSaveSuccessMessage: showSaveSuccessMessage, + showSaveErrorMessage: showSaveErrorMessage, showValidationErrorsModal: showValidationErrorsModal }; })($, TreeComponent, ModalsComponent, InspectorComponent, StageComponent, Helper, Icons, Notification); diff --git a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormManager/ViewModel.js b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormManager/ViewModel.js index 1d2bc79fe246c8a37a2ba25a2de00ce860fbbd83..b7f5225870fec10de7101938bdc30393ff4fd62b 100644 --- a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormManager/ViewModel.js +++ b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormManager/ViewModel.js @@ -62,7 +62,11 @@ define(['jquery', showReferences: { identifier: '[data-identifier="showReferences"]' }, referenceLink: { identifier: '[data-identifier="referenceLink"]' }, - tooltip: { identifier: '[data-toggle="tooltip"]' } + tooltip: { identifier: '[data-toggle="tooltip"]' }, + + moduleBody: { class: '.module-body.t3js-module-body' }, + t3Logo: { class: '.t3-message-page-logo' }, + t3Footer: { id: '#t3-footer' } } }; @@ -270,11 +274,23 @@ define(['jquery', savePath: Wizard.setup.settings['savePath'] } }, function(data, textStatus, jqXHR) { - document.location = data; + if (data['status'] === 'success') { + document.location = data.url; + } else { + Notification.error(TYPO3.lang['formManager.newFormWizard.step4.errorTitle'], TYPO3.lang['formManager.newFormWizard.step4.errorMessage'] + " " + data['message']); + } Wizard.dismiss(); }).fail(function(jqXHR, textStatus, errorThrown) { + var parser = new DOMParser(), + responseDocument = parser.parseFromString(jqXHR.responseText, "text/html"), + responseBody = $(responseDocument.body); + Notification.error(textStatus, errorThrown, 2); Wizard.dismiss(); + + $(getDomElementIdentifier('t3Logo', 'class'), responseBody).remove(); + $(getDomElementIdentifier('t3Footer', 'id'), responseBody).remove(); + $(getDomElementIdentifier('moduleBody', 'class')).html(responseBody.html()); }); }).done(function() { Wizard.show(); @@ -403,11 +419,23 @@ define(['jquery', savePath: Wizard.setup.settings['savePath'] } }, function(data, textStatus, jqXHR) { - document.location = data; + if (data['status'] === 'success') { + document.location = data.url; + } else { + Notification.error(TYPO3.lang['formManager.duplicateFormWizard.step2.errorTitle'], TYPO3.lang['formManager.duplicateFormWizard.step2.errorMessage'] + " " + data['message']); + } Wizard.dismiss(); }).fail(function(jqXHR, textStatus, errorThrown) { + var parser = new DOMParser(), + responseDocument = parser.parseFromString(jqXHR.responseText, "text/html"), + responseBody = $(responseDocument.body); + Notification.error(textStatus, errorThrown, 2); Wizard.dismiss(); + + $(getDomElementIdentifier('t3Logo', 'class'), responseBody).remove(); + $(getDomElementIdentifier('t3Footer', 'id'), responseBody).remove(); + $(getDomElementIdentifier('moduleBody', 'class')).html(responseBody.html()); }); }).done(function() { Wizard.show();