From 59807070a4832020a0a0aea8aa4c73dbd8e2ce93 Mon Sep 17 00:00:00 2001 From: Mart Kop Date: Wed, 9 Oct 2024 07:51:22 +0200 Subject: [PATCH] [NodeBundle] (feat) Refactor Url chooser without XHR call --- .../Resources/public/js/admin-bundle.min.js | 2 +- .../Resources/ui/js/_url-chooser.js | 104 +++++++----- .../DependencyInjection/Configuration.php | 1 + .../KunstmaanNodeExtension.php | 10 ++ .../URLChooserToLinkTransformer.php | 72 ++++++-- .../URLChooserFormSubscriber.php | 1 + .../URLChooserLinkTypeSubscriber.php | 1 + .../Form/Type/InternalURLSelectorType.php | 30 ++++ .../NodeBundle/Form/Type/URLChooserType.php | 94 +++++++--- .../NodeBundle/Form/Type/URLTypeType.php | 31 ++++ .../NodeBundle/Resources/config/services.yml | 2 + .../views/Form/formWidgets.html.twig | 160 ++++++++++++------ .../DependencyInjection/ConfigurationTest.php | 1 + .../KunstmaanNodeExtensionTest.php | 1 + 14 files changed, 377 insertions(+), 133 deletions(-) create mode 100644 src/Kunstmaan/NodeBundle/Form/Type/InternalURLSelectorType.php create mode 100644 src/Kunstmaan/NodeBundle/Form/Type/URLTypeType.php diff --git a/src/Kunstmaan/AdminBundle/Resources/public/js/admin-bundle.min.js b/src/Kunstmaan/AdminBundle/Resources/public/js/admin-bundle.min.js index bdd16a569b..96a6411fea 100644 --- a/src/Kunstmaan/AdminBundle/Resources/public/js/admin-bundle.min.js +++ b/src/Kunstmaan/AdminBundle/Resources/public/js/admin-bundle.min.js @@ -70,5 +70,5 @@ var kunstmaanbundles=kunstmaanbundles||{};kunstmaanbundles.preventDoubleClick=fu var kunstmaanbundles=kunstmaanbundles||{};kunstmaanbundles.richEditor=function(e,t){var a,n,r,o,i,s,l,d,c,m={kumaDefault:{skin:"bootstrapck",startupFocus:!1,bodyClass:"CKEditor",filebrowserWindowWidth:970,filebrowserImageWindowWidth:970,filebrowserImageUploadUrl:"",extraAllowedContent:"div(*)",toolbar:[{name:"basicstyles",items:["Bold","Italic","Underline","Strike","Subscript","Superscript","RemoveFormat"]},{name:"lists",items:["NumberedList","BulletedList"]},{name:"dents",items:["Outdent","Indent"]},{name:"links",items:["Link","Unlink","Anchor"]},{name:"insert",items:["Image","Table","SpecialChar"]},{name:"clipboard",items:["SelectAll","Cut","Copy","PasteText","PasteFromWord","-","Undo","Redo"]},{name:"editing",items:[]},{name:"document",items:["Source"]}]}};return n=function(){d(e.externalPlugins),l(e.ckEditorConfigs),$(".js-rich-editor").each(function(){$(this).hasClass("js-rich-editor--enabled")||o($(this))})},r=function(){i(),n()},l=function(e){for(var t in e){if("kumaDefault"===t)throw new Error("kumaDefault is a reserved name for the default Kunstmaan ckeditor configuration. Please choose another name.");if(e[t].constructor===Array)throw new Error("Since v3.3.0 the whole rich editor config is editable. This means a custom config should be an object instead of an array.");m[t]=e[t]}},d=function(e){if(void 0!==e&&e.length>0&&void 0!==CKEDITOR&&void 0!==CKEDITOR.plugins)for(var t=0;t0;){for(p=E.getFirst(),m=0;m')}else f.attr("src",m),t&&s&&s.attr("data-path",c);parent.$("#"+o).modal("hide")}},r=function(a){var t=new RegExp("(?:[?&]|&)"+a+"=([^&]+)","i"),n=e.location.search.match(t);return n&&n.length>1?n[1]:""},o=function(){f.on("click",".js-change-link-type",function(e){e.preventDefault();var a=$(this).closest("form"),t=$(this).parents(".urlchooser-wrapper"),n=t.data("chooser-name"),i={};$.each(a.serializeArray(),function(e,a){-1!==a.name.indexOf("link_type")||-1!==a.name.indexOf("link_url")?-1!==a.name.indexOf(n)&&-1===a.name.indexOf("link_url")&&(i[a.name]=a.value):-1===a.name.indexOf("sequence")&&(s(a.name,"[]")?void 0===i[a.name]||"string"==typeof i[a.name]?i[a.name]=[a.value]:i[a.name].push(a.value):i[a.name]=a.value)}),i[$(this).data("name")]=$(this).data("value"),$.ajax({url:a.attr("action"),type:a.attr("method"),data:i,success:function(e){t.replaceWith($(e).find("#"+t.attr("id")))}})})},s=function(e,a,t){return(void 0===t||t>e.length)&&(t=e.length),e.substring(t-a.length,t)===a},{init:t}}(window); +var kunstmaanbundles=kunstmaanbundles||{};kunstmaanbundles.urlChooser=function(e,a){var t,n,i,r,l,o,s,d,c,u,m,p,h,f=$("body");return t=function(){n(),o()},n=function(){f.on("click",".js-url-chooser-link-select a",function(e){e.preventDefault();var a=$(this).parent(),t=a.data("slug"),n=a.data("id"),i=a.closest("nav").data("replace-url");c=t||"",u=n,$.ajax({url:i,type:"GET",data:{text:c},success:function(e){h=e.text,$("#url-chooser__selection-preview").text("Selection: "+h)}})}),f.on("click",".js-url-chooser-media-select",function(a){a.preventDefault();var t=$(this),n=t.data("path"),l=t.data("thumb-path"),o=t.data("id"),s=t.data("title"),d=t.data("cke"),f=t.closest(".thumbnail-wrapper").data("replace-url");if(c=n,u=o,m=s,p=l,d)r(!0,!1);else{var v=$(e.frameElement).closest(".js-ajax-modal").data("media-chooser"),g=c.includes(".svg"),x=!g&&$(e.frameElement).closest(".js-ajax-modal").data("cropable");v?r(!1,x):$.ajax({url:f,type:"GET",data:{text:c},success:function(e){h=e.text}}).done(function(){i(!1)})}}),$("#cancel-url-chooser-modal").on("click",function(){if($(this).data("cke"))e.close();else{var a=$(e.frameElement).closest(".js-ajax-modal"),t=a.attr("id");parent.$("#"+t).modal("hide")}}),$(document).on("click","#save-url-chooser-modal",function(){var e=$(this).data("cke");i(e)})},i=function(a){if(a){var t=l("CKEditorFuncNum");e.opener.CKEDITOR.tools.callFunction(t,c),e.close()}else{var n=$(e.frameElement).closest(".js-ajax-modal"),i=n.data("linked-input-id"),r=n.attr("id");parent.$("#"+i).val(c).change(),parent.$("#"+i).parent().find(".js-urlchooser-value").val(h),parent.$("#"+r).modal("hide")}},r=function(a,t){if(a){var n=l("CKEditorFuncNum");e.opener.CKEDITOR.tools.callFunction(n,c),e.close()}else{var i=$(e.frameElement).closest(".js-ajax-modal"),r=i.data("linked-input-id"),o=i.attr("id");parent.$("#"+r).val(u).change();var s,d=parent.$("#"+r+"-widget"),h=parent.$("#"+r+"__preview__img"),f=parent.$("#"+r+"__preview__title"),v=d.find(".js-media-chooser-image-edit-btn");if(t?(s=parent.$("#"+r+"-image-edit-modal .js-image-edit"),v&&v.prop("disabled",!1)):v&&v.prop("disabled",!0),d.addClass("media-chooser--choosen"),f.html(m),""===p){f.parent().prepend('')}else h.attr("src",p),t&&s&&s.attr("data-path",c);parent.$("#"+o).modal("hide")}},l=function(a){var t=new RegExp("(?:[?&]|&)"+a+"=([^&]+)","i"),n=e.location.search.match(t);return n&&n.length>1?n[1]:""},o=function(){f.on("click",".js-change-link-type",function(e){if(e.preventDefault(),null===e.target.getAttribute("data-xhr"))return void d(e.target);var a=$(this).closest("form"),t=$(this).parents(".urlchooser-wrapper"),n=t.data("chooser-name"),i={};$.each(a.serializeArray(),function(e,a){-1!==a.name.indexOf("link_type")||-1!==a.name.indexOf("link_url")?-1!==a.name.indexOf(n)&&-1===a.name.indexOf("link_url")&&(i[a.name]=a.value):-1===a.name.indexOf("sequence")&&(s(a.name,"[]")?void 0===i[a.name]||"string"==typeof i[a.name]?i[a.name]=[a.value]:i[a.name].push(a.value):i[a.name]=a.value)}),i[$(this).data("name")]=$(this).data("value"),$.ajax({url:a.attr("action"),type:a.attr("method"),data:i,success:function(e){t.replaceWith($(e).find("#"+t.attr("id")))}})})},d=function(e){const a=e.closest(".urlchooser-wrapper"),t=a.querySelector(".urlchooser__link-type .text"),n=e.closest("[data-value]").dataset.value,i=a.querySelector("[data-toggle-on]:not(.hidden)"),r=a.querySelector('[data-toggle-on="'+n+'"]');a.querySelector('input[type="hidden"][data-button-id="'+a.getAttribute("data-link-type-id")+'"]').value=n,t.innerHTML=e.innerHTML,i.classList.add("hidden"),r.classList.remove("hidden")},s=function(e,a,t){return(void 0===t||t>e.length)&&(t=e.length),e.substring(t-a.length,t)===a},{init:t}}(window); var kunstmaanbundles=kunstmaanbundles||{};kunstmaanbundles.app=function(n,a,t){var i,s,u,e=n("#page-main-actions-top");return i=function(){cargobay.toggle.init(),cargobay.scrollToTop.init(),s(),kunstmaanbundles.sidebartoggle.init(),kunstmaanbundles.sidebartree.init(),kunstmaanbundles.urlchoosertree.init(),kunstmaanbundles.sidebarsearchfocus.init(),kunstmaanbundles.filter.init(),kunstmaanbundles.sortableTable.init(),kunstmaanbundles.checkIfEdited.init(),kunstmaanbundles.preventDoubleClick.init(),kunstmaanbundles.autoCollapseButtons.init(),kunstmaanbundles.autoCollapseTabs.init(),kunstmaanbundles.ajaxModal.init(),kunstmaanbundles.topNav.init(),u(),kunstmaanbundles.pageEditor.init(),kunstmaanbundles.pagepartEditor.init(),kunstmaanbundles.slugChooser.init(),kunstmaanbundles.urlChooser.init(),kunstmaanbundles.mediaChooser.init(),kunstmaanbundles.iconChooser.init(),kunstmaanbundles.bulkActions.init(),kunstmaanbundles.appLoading.init(),kunstmaanbundles.charactersLeft.init(),kunstmaanbundles.googleOAuth.init(),kunstmaanbundles.appNodeVersionLock.init(),kunstmaanbundles.appEntityVersionLock.init()},u=function(){kunstmaanbundles.richEditor.init(),kunstmaanbundles.nestedForm.init(),kunstmaanbundles.advancedSelect.init(),kunstmaanbundles.tooltip.init(),kunstmaanbundles.datepicker.reInit()},s=function(){if(e){var n,t,i,s=0,u=!1;n=function(){s=a.pageYOffset,t()},t=function(){u||a.requestAnimationFrame(i),u=!0},i=function(){u=!1;var n=s;kunstmaanbundles.mainActions.updateScroll(n,e)},a.onscroll=function(a){n()}}},{init:i,initModules:u}}(jQuery,window),$(function(){kunstmaanbundles.app.init()}); \ No newline at end of file diff --git a/src/Kunstmaan/AdminBundle/Resources/ui/js/_url-chooser.js b/src/Kunstmaan/AdminBundle/Resources/ui/js/_url-chooser.js index 6ff4aa60c9..93f8a3fc35 100644 --- a/src/Kunstmaan/AdminBundle/Resources/ui/js/_url-chooser.js +++ b/src/Kunstmaan/AdminBundle/Resources/ui/js/_url-chooser.js @@ -2,7 +2,7 @@ var kunstmaanbundles = kunstmaanbundles || {}; kunstmaanbundles.urlChooser = (function (window, undefined) { - var init, urlChooser, saveUrlChooserModal, saveMediaChooserModal, getUrlParam, adaptUrlChooser, endsWith; + var init, urlChooser, saveUrlChooserModal, saveMediaChooserModal, getUrlParam, adaptUrlChooser, endsWith, adaptUrl; var itemUrl, itemId, itemTitle, itemThumbPath, replacedUrl, $body = $('body'); @@ -140,7 +140,6 @@ kunstmaanbundles.urlChooser = (function (window, undefined) { } }; - // Save for Media-chooser saveMediaChooserModal = function (cke, isCropable) { if (!cke) { @@ -201,7 +200,6 @@ kunstmaanbundles.urlChooser = (function (window, undefined) { } }; - // Get Url Parameters getUrlParam = function (paramName) { var reParam = new RegExp('(?:[\?&]|&)' + paramName + '=([^&]+)', 'i'), @@ -213,54 +211,73 @@ kunstmaanbundles.urlChooser = (function (window, undefined) { // Adapt the url chooser according to the selected link type. adaptUrlChooser = function () { $body.on('click', '.js-change-link-type', function (e) { - e.preventDefault(); - var $form = $(this).closest('form'), - $urlChooser = $(this).parents('.urlchooser-wrapper'), - $urlChooserName = $urlChooser.data('chooser-name'); + e.preventDefault(); - var values = {}; + if (e.target.getAttribute('data-xhr') === null) { + adaptUrl(e.target); + return; + } - $.each($form.serializeArray(), function (i, field) { - // Only submit required values. - if (field.name.indexOf('link_type') !== -1 || field.name.indexOf('link_url') !== -1) { - if (field.name.indexOf($urlChooserName) !== -1 && field.name.indexOf('link_url') === -1) { - values[field.name] = field.value; - } + // deprecated, use adaptUrl(e.target) when enable_improved_urlchooser becomes standard + var $form = $(this).closest('form'), + $urlChooser = $(this).parents('.urlchooser-wrapper'), + $urlChooserName = $urlChooser.data('chooser-name'); + + var values = {}; + + $.each($form.serializeArray(), function (i, field) { + // Only submit required values. + if (field.name.indexOf('link_type') !== -1 || field.name.indexOf('link_url') !== -1) { + if (field.name.indexOf($urlChooserName) !== -1 && field.name.indexOf('link_url') === -1) { + values[field.name] = field.value; } - else { - // Main sequence can not be submitted. - if (field.name.indexOf('sequence') === -1) { - // handle array values - if (endsWith(field.name, '[]')) { - if (typeof values[field.name] === 'undefined' || typeof values[field.name] === 'string') { - values[field.name] = [field.value]; - } else { - values[field.name].push(field.value); - } + } + else { + // Main sequence can not be submitted. + if (field.name.indexOf('sequence') === -1) { + // handle array values + if (endsWith(field.name, '[]')) { + if (typeof values[field.name] === 'undefined' || typeof values[field.name] === 'string') { + values[field.name] = [field.value]; } else { - values[field.name] = field.value; + values[field.name].push(field.value); } + } else { + values[field.name] = field.value; } } - }); - - // Add the selected li value. - values[$(this).data('name')] = $(this).data('value'); - - $.ajax({ - url: $form.attr('action'), - type: $form.attr('method'), - data: values, - success: function (html) { - $urlChooser.replaceWith( - $(html).find('#' + $urlChooser.attr('id')) - ); - } - }); - } - ); + } + }); + + // Add the selected li value. + values[$(this).data('name')] = $(this).data('value'); + + $.ajax({ + url: $form.attr('action'), + type: $form.attr('method'), + data: values, + success: function (html) { + $urlChooser.replaceWith( + $(html).find('#' + $urlChooser.attr('id')) + ); + } + }); + }); }; + adaptUrl = function (element) { + const urlChooser = element.closest('.urlchooser-wrapper'); + const urlChooserText = urlChooser.querySelector('.urlchooser__link-type .text'); + const newValue = element.closest('[data-value]').dataset.value; + const oldActive = urlChooser.querySelector('[data-toggle-on]:not(.hidden)'); + const newActive = urlChooser.querySelector('[data-toggle-on="' + newValue + '"]'); + const typeInput = urlChooser.querySelector('input[type="hidden"][data-button-id="'+urlChooser.getAttribute('data-link-type-id')+'"]'); + typeInput.value = newValue; + urlChooserText.innerHTML = element.innerHTML; + oldActive.classList.add('hidden'); + newActive.classList.remove('hidden'); + } + /* Polyfill String.prototype.endsWith() for IE */ endsWith = function(string, search, this_len) { if (this_len === undefined || this_len > string.length) { @@ -273,5 +290,4 @@ kunstmaanbundles.urlChooser = (function (window, undefined) { init: init }; -}) -(window); +})(window); diff --git a/src/Kunstmaan/NodeBundle/DependencyInjection/Configuration.php b/src/Kunstmaan/NodeBundle/DependencyInjection/Configuration.php index d75987b283..96c88ddb56 100644 --- a/src/Kunstmaan/NodeBundle/DependencyInjection/Configuration.php +++ b/src/Kunstmaan/NodeBundle/DependencyInjection/Configuration.php @@ -48,6 +48,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->booleanNode('show_add_homepage')->defaultTrue()->end() ->booleanNode('show_duplicate_with_children')->defaultFalse()->end() ->booleanNode('enable_export_page_template')->defaultFalse()->end() + ->booleanNode('enable_improved_urlchooser')->defaultFalse()->end() ->arrayNode('lock') ->addDefaultsIfNotSet() ->canBeEnabled() diff --git a/src/Kunstmaan/NodeBundle/DependencyInjection/KunstmaanNodeExtension.php b/src/Kunstmaan/NodeBundle/DependencyInjection/KunstmaanNodeExtension.php index 3fcf64c64d..53ebd2661a 100644 --- a/src/Kunstmaan/NodeBundle/DependencyInjection/KunstmaanNodeExtension.php +++ b/src/Kunstmaan/NodeBundle/DependencyInjection/KunstmaanNodeExtension.php @@ -3,6 +3,8 @@ namespace Kunstmaan\NodeBundle\DependencyInjection; use Kunstmaan\NodeBundle\Entity\PageViewDataProviderInterface; +use Kunstmaan\NodeBundle\Form\EventListener\URLChooserFormSubscriber; +use Kunstmaan\NodeBundle\Form\EventListener\URLChooserLinkTypeSubscriber; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; @@ -40,8 +42,16 @@ public function load(array $configs, ContainerBuilder $container): void $container->setParameter('kunstmaan_node.lock_threshold', $config['lock']['threshold']); $container->setParameter('kunstmaan_node.lock_enabled', $config['lock']['enabled']); + $enableImprovedUrlchooser = $config['enable_improved_urlchooser']; + $container->setParameter('kunstmaan_node.enable_improved_urlchooser', $enableImprovedUrlchooser); + $loader->load('services.yml'); $loader->load('commands.yml'); + + if ($enableImprovedUrlchooser) { + $container->removeDefinition(URLChooserFormSubscriber::class); + $container->removeDefinition(URLChooserLinkTypeSubscriber::class); + } } public function prepend(ContainerBuilder $container): void diff --git a/src/Kunstmaan/NodeBundle/Form/DataTransformer/URLChooserToLinkTransformer.php b/src/Kunstmaan/NodeBundle/Form/DataTransformer/URLChooserToLinkTransformer.php index 2f00c284ff..d4cc249d98 100644 --- a/src/Kunstmaan/NodeBundle/Form/DataTransformer/URLChooserToLinkTransformer.php +++ b/src/Kunstmaan/NodeBundle/Form/DataTransformer/URLChooserToLinkTransformer.php @@ -10,34 +10,74 @@ class URLChooserToLinkTransformer implements DataTransformerInterface { use URLValidator; - /** - * @return array - */ - public function transform($value) + public function __construct(private bool $improvedUrlChooser = false) { - if ($this->isEmailAddress($value)) { - $linkType = URLChooserType::EMAIL; - } elseif ($this->isInternalLink($value) || $this->isInternalMediaLink($value)) { - $linkType = URLChooserType::INTERNAL; - } else { - $linkType = URLChooserType::EXTERNAL; + } + + public function transform($value): array + { + if (!$this->improvedUrlChooser) { + return [ + 'link_type' => $this->getLinkType($value), + 'link_url' => $value, + ]; + } + + if ($value === null) { + return [ + 'link_type' => URLChooserType::INTERNAL, + 'link_url' => null, + ]; } - return [ + $linkType = $this->getLinkType($value); + + return array_merge($this->getChoiceOption($linkType, $value), [ 'link_type' => $linkType, 'link_url' => $value, - ]; + ]); } - /** - * @return string|null - */ - public function reverseTransform($value) + public function reverseTransform($value): ?string { if (empty($value)) { return null; } + if ($this->improvedUrlChooser && !empty($value['link_type'])) { + switch ($value['link_type']) { + case URLChooserType::INTERNAL: + return $value['link_url']; + case URLChooserType::EXTERNAL: + return $value['choice_external']; + case URLChooserType::EMAIL: + return $value['choice_email']; + } + } + return $value['link_url']; } + + private function getLinkType(mixed $value): string + { + if ($this->isEmailAddress($value)) { + return URLChooserType::EMAIL; + } + + if ($this->isInternalLink($value) || $this->isInternalMediaLink($value)) { + return URLChooserType::INTERNAL; + } + + return URLChooserType::EXTERNAL; + } + + private function getChoiceOption(string $linkType, string $value): array + { + return match ($linkType) { + URLChooserType::INTERNAL => ['choice_internal' => ['input' => $value]], + URLChooserType::EXTERNAL => ['choice_external' => $value], + URLChooserType::EMAIL => ['choice_email' => $value], + default => [], + }; + } } diff --git a/src/Kunstmaan/NodeBundle/Form/EventListener/URLChooserFormSubscriber.php b/src/Kunstmaan/NodeBundle/Form/EventListener/URLChooserFormSubscriber.php index 3707f1e6c2..f74023dbba 100644 --- a/src/Kunstmaan/NodeBundle/Form/EventListener/URLChooserFormSubscriber.php +++ b/src/Kunstmaan/NodeBundle/Form/EventListener/URLChooserFormSubscriber.php @@ -12,6 +12,7 @@ use Symfony\Component\Validator\Constraints\Email; use Symfony\Component\Validator\Constraints\Url; +/** @deprecated */ class URLChooserFormSubscriber implements EventSubscriberInterface { use URLValidator; diff --git a/src/Kunstmaan/NodeBundle/Form/EventListener/URLChooserLinkTypeSubscriber.php b/src/Kunstmaan/NodeBundle/Form/EventListener/URLChooserLinkTypeSubscriber.php index 73d21932da..7057e67d77 100644 --- a/src/Kunstmaan/NodeBundle/Form/EventListener/URLChooserLinkTypeSubscriber.php +++ b/src/Kunstmaan/NodeBundle/Form/EventListener/URLChooserLinkTypeSubscriber.php @@ -11,6 +11,7 @@ use Symfony\Component\Validator\Constraints\Email; use Symfony\Component\Validator\Constraints\Url; +/** @deprecated */ class URLChooserLinkTypeSubscriber implements EventSubscriberInterface { /** diff --git a/src/Kunstmaan/NodeBundle/Form/Type/InternalURLSelectorType.php b/src/Kunstmaan/NodeBundle/Form/Type/InternalURLSelectorType.php new file mode 100644 index 0000000000..502cadc9bd --- /dev/null +++ b/src/Kunstmaan/NodeBundle/Form/Type/InternalURLSelectorType.php @@ -0,0 +1,30 @@ +add('input', HiddenType::class, [ + 'label' => false, + ]); + $builder->add('url', TextType::class, [ + 'label' => false, + 'disabled' => true, + 'mapped' => false, + ]); + } + + public function getBlockPrefix(): string + { + return 'internal_url_selector'; + } +} diff --git a/src/Kunstmaan/NodeBundle/Form/Type/URLChooserType.php b/src/Kunstmaan/NodeBundle/Form/Type/URLChooserType.php index 620f121b37..d31449e1ae 100644 --- a/src/Kunstmaan/NodeBundle/Form/Type/URLChooserType.php +++ b/src/Kunstmaan/NodeBundle/Form/Type/URLChooserType.php @@ -1,14 +1,24 @@ self::INTERNAL, @@ -50,33 +62,63 @@ public function buildForm(FormBuilderInterface $builder, array $options) } } - $builder->add( - 'link_type', - ChoiceType::class, - [ - 'required' => true, - 'mapped' => false, - 'attr' => [ - 'class' => 'js-change-link-type', - ], - 'choices' => $choices, - ] - ); + $builder->addViewTransformer(new URLChooserToLinkTransformer($this->improvedUrlChooser)); + if (!$this->improvedUrlChooser) { + $builder->add( + 'link_type', + ChoiceType::class, + [ + 'required' => true, + 'mapped' => false, + 'attr' => [ + 'class' => 'js-change-link-type', + ], + 'choices' => $choices, + ] + ); + $builder->get('link_type')->addEventSubscriber(new URLChooserLinkTypeSubscriber()); + $builder->addEventSubscriber(new URLChooserFormSubscriber()); - $builder->get('link_type')->addEventSubscriber(new URLChooserLinkTypeSubscriber()); + return; + } - $builder->addEventSubscriber(new URLChooserFormSubscriber()); - $builder->addViewTransformer(new URLChooserToLinkTransformer()); + $builder->add('link_url', HiddenType::class, [ + 'required' => false, + ]); + $builder->add('link_type', URLTypeType::class, [ + 'required' => true, + 'choices' => array_flip($choices), + 'attr' => [ + 'class' => 'urlchooser-type', + ], + ]); + + $builder->add('choice_external', TextType::class, [ + 'attr' => ['placeholder' => 'https://'], + 'constraints' => [ + new When($this->getLinkTypeExpression(self::EXTERNAL), [ + new ValidExternalUrl(), + ]), + ], + 'error_bubbling' => true, + ]); + $builder->add('choice_email', EmailType::class, [ + 'constraints' => [ + new When($this->getLinkTypeExpression(self::EMAIL), [ + new Email(), + ]), + ], + 'error_bubbling' => true, + ]); + $builder->add('choice_internal', InternalURLSelectorType::class); } /** * Sets the default options for this type. * * @param OptionsResolver $resolver the resolver for the options - * - * @return void */ - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults( [ @@ -87,6 +129,16 @@ public function configureOptions(OptionsResolver $resolver) ); } + public function buildView(FormView $view, FormInterface $form, array $options): void + { + $view->vars['improved_url_chooser'] = $this->improvedUrlChooser; + } + + private function getLinkTypeExpression(string $type): string + { + return 'this.getParent().get("link_type").getData() === "' . $type . '"'; + } + /** * @return string */ diff --git a/src/Kunstmaan/NodeBundle/Form/Type/URLTypeType.php b/src/Kunstmaan/NodeBundle/Form/Type/URLTypeType.php new file mode 100644 index 0000000000..78a66245f8 --- /dev/null +++ b/src/Kunstmaan/NodeBundle/Form/Type/URLTypeType.php @@ -0,0 +1,31 @@ +setRequired('choices'); + $resolver->setDefault('choices', []); + $resolver->setAllowedTypes('choices', 'array'); + } + + public function buildView(FormView $view, FormInterface $form, array $options): void + { + $view->vars['choices'] = $options['choices']; + } + + public function getParent(): string + { + return HiddenType::class; + } +} diff --git a/src/Kunstmaan/NodeBundle/Resources/config/services.yml b/src/Kunstmaan/NodeBundle/Resources/config/services.yml index 159fd7a784..a9bd4cda2f 100644 --- a/src/Kunstmaan/NodeBundle/Resources/config/services.yml +++ b/src/Kunstmaan/NodeBundle/Resources/config/services.yml @@ -56,6 +56,8 @@ services: kunstmaan_node.form.type.urlchooser: class: Kunstmaan\NodeBundle\Form\Type\URLChooserType + arguments: + $improvedUrlChooser: '%kunstmaan_node.enable_improved_urlchooser%' tags: - { name: 'form.type' } diff --git a/src/Kunstmaan/NodeBundle/Resources/views/Form/formWidgets.html.twig b/src/Kunstmaan/NodeBundle/Resources/views/Form/formWidgets.html.twig index e688dec2ea..381bbdff56 100644 --- a/src/Kunstmaan/NodeBundle/Resources/views/Form/formWidgets.html.twig +++ b/src/Kunstmaan/NodeBundle/Resources/views/Form/formWidgets.html.twig @@ -1,78 +1,136 @@ {% block urlchooser_widget %} {% apply spaceless %} - {% set linkUrl = form.link_url.vars %} + {% set improvedUrlChooser = form.vars.improved_url_chooser|default(false) %} + {% if not improvedUrlChooser %} + {% set linkUrl = form.link_url.vars %} +
+ {% block urlChooserModal %} + +