The attribute max is deprecated on AttachmentType since it is not applicable to input type file. A new attribute data-max was added to let you use this data in your custom templates.
To support Symfony 6 and Sulu 2.5 the usage of Swiftmailer has been deprecated.
Remove the Swiftmailer from your project to automatically use the symfony/mailer instead.
By default, the csrf protection is disabled now because of caching mechanism it is required that csrf token is loaded over ajax. Since Symfony 5.4, it is not possible todo this over ESI, as the session cookie can not be created by a Symfony subrequest, which was already the behaviour before when using a caching server like varnish.
If you want to enable csrf protection again it is required to configure:
sulu_form:
csrf_protection: trueAnd important implement ajax loading of the csrf protection. See the CSRF Ajax documentation as an example.
As an alternative protection there is HoneyPotField or Recaptcha. Which both do not require a session.
The Builder service of the SuluFormBundle requires now the security.csrf.token_manager service to be injected
this was required to solve caching problems on pages using forms.
To allow to deactivate that attachment is saved, the following needed to be adjusted in the database:
ALTER TABLE fo_form_translations ADD deactivateAttachmentSave TINYINT(1) DEFAULT '0' NOT NULL;Dynamic Entity has been reduced to some basic fields. All previous data fields are merged into the data column.
Migrate the data fields into the json data.
UPDATE
fo_dynamics as dyn
SET
dyn.data = (
CONCAT(
'{',
CONCAT_WS(
',',
IF(
STRCMP('', SUBSTRING(dyn.data, 2, LENGTH(dyn.data) -2)) = 0,
NULL,
SUBSTRING(dyn.data, 2, CHAR_LENGTH(dyn.data) -2)
),
IF(
dyn.salutation is not NULL,
CONCAT(
'\"salutation\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.salutation, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.title is not NULL,
CONCAT(
'\"title\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.title, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.firstName is not NULL,
CONCAT(
'\"firstName\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.firstName, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.lastName is not NULL,
CONCAT(
'\"lastName\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.lastName, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.email is not NULL,
CONCAT(
'\"email\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.email, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.phone is not NULL,
CONCAT(
'\"phone\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.phone, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.fax is not NULL,
CONCAT(
'\"fax\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.fax, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.street is not NULL,
CONCAT(
'\"street\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.street, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.zip is not NULL,
CONCAT(
'\"zip\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.zip, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.city is not NULL,
CONCAT(
'\"city\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.city, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.state is not NULL,
CONCAT(
'\"state\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.state, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.country is not NULL,
CONCAT(
'\"country\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.country, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.function is not NULL,
CONCAT(
'\"function\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.function, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.company is not NULL,
CONCAT(
'\"company\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.company, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.text is not NULL,
CONCAT(
'\"text\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.text, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.textarea is not NULL,
CONCAT(
'\"textarea\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.textarea, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.date is not NULL,
CONCAT(
'\"date\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.date, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.attachment is not NULL,
CONCAT(
'\"attachment\":',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.attachment, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f')
),
NULL
),
IF(
dyn.checkbox is not NULL,
CONCAT(
'\"checkbox\":',
IF(
STRCMP('',dyn.checkbox) = 0,
'\"\"',
dyn.checkbox
)
),
NULL
),
IF(
dyn.checkboxMultiple is not NULL,
CONCAT(
'\"checkboxMultiple\":',
dyn.checkboxMultiple
),
NULL
),
IF(
dyn.dropdown is not NULL,
CONCAT(
'\"dropdown\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.dropdown, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
),
IF(
dyn.dropdownMultiple is not NULL,
CONCAT(
'\"dropdownMultiple\":',
dyn.dropdownMultiple
),
NULL
),
IF(
dyn.radioButtons is not NULL,
CONCAT(
'\"radioButtons\":\"',
replace(replace(replace(replace(replace(replace(replace(replace(dyn.radioButtons, '\\', '\\\\'), '/', '\\/'), '"', '\\\"'), CHAR(10), '\\n'), CHAR(9), '\\t'), CHAR(8), '\\b'), CHAR(13), '\\r'), CHAR(12), '\\f'),
'\"'
),
NULL
)
),
'}'
)
);Delete the redundant columns.
ALTER TABLE fo_dynamics
DROP COLUMN salutation,
DROP COLUMN title,
DROP COLUMN firstName,
DROP COLUMN lastName,
DROP COLUMN email,
DROP COLUMN phone,
DROP COLUMN fax,
DROP COLUMN street,
DROP COLUMN zip,
DROP COLUMN city,
DROP COLUMN state,
DROP COLUMN country,
DROP COLUMN function,
DROP COLUMN company,
DROP COLUMN text,
DROP COLUMN textarea,
DROP COLUMN date,
DROP COLUMN attachment,
DROP COLUMN checkbox,
DROP COLUMN checkboxMultiple,
DROP COLUMN dropdown,
DROP COLUMN dropdownMultiple,
DROP COLUMN radioButtons;The routing.yml file was removed as it the routes are not needed for rendering dynamic forms.
If you did build on top of this route something register the needed routes in your project:
# config/routes/sulu_form.yaml
sulu_form.only:
path: /form/only/{key}
defaults:
_controller: Sulu\Bundle\FormBundle\Controller\FormWebsiteController::onlyAction
sulu_form.token:
path: /form/token
defaults:
_controller: Sulu\Bundle\FormBundle\Controller\FormTokenController::tokenAction
_requestAnalyzer: falseThe magic setter of the `Dynamic? entity was removed:
before:
$dynamic->__set($key, $value);
$dynamic->__get($key);
$dynamic->{$key};after:
$dynamic->setField($key, $value);
$dynamic->getField($key);The tokenAction was moved into an own Controller:
before:
'Sulu\\Bundle\\FormBundle\\Controller\\FormWebsiteController::tokenAction'after:
'Sulu\\Bundle\\FormBundle\\Controller\\FormTokenController::tokenAction'The list tab configuration need the parent route key (can be found in the related admin classes).
before:
sulu_form:
dynamic_lists:
content:
form:
template: form
property: form
type: pageafter:
sulu_form:
dynamic_lists:
sulu_page.page_edit_form:
form:
template: form
property: form
type: pageThe argument $locale = null was added to the method TitleProvider::getTitle.
It contains the locale which was used to create the form.
The field keyName need to be short to 128 length for UTF8MB4 compatibility:
ALTER TABLE fo_form_fields CHANGE keyName keyName VARCHAR(128) NOT NULL;The content type for form selection has been changed from form_select to single_form_selection also the param type has changed to resourceKey:
before:
<property name="form" type="form_select">
<params>
<param name="type" value="page" />
</params>
</property>after:
<property name="form" type="single_form_selection">
<params>
<param name="resourceKey" value="page" />
</params>
</property>No breaking changes since RC7.
Constructor of FormSelect (sulu_form.content_type.form_select) changed.
An additional Service sulu_form.reference_store.form (ReferenceStoreInterface) is needed.
Constructor of FormConfigurationFactory changed.
Additional configuration for $mailAdminPlainTextTemplate are $mailWebsitePlainTextTemplate are needed.
Interface of MailConfigurationInterface changed.
Additional getPlainTextTemplate is needed.
For the compatibility with doctrine/orm ^2.6 the function names of the FormRepository are renamed to avoid inheritance issues.
findByIdchanged toloadByIdfindAllchanged toloadAllcountchanged tocountByFilters
The dynamic_default_view parameter was removed as it is not longer used.
If you did overwrite it remove it from your configuration.
Upgrade the database schema that the defaultValue can contain a longer text:
ALTER TABLE fo_form_field_translations CHANGE defaultValue defaultValue LONGTEXT DEFAULT NULL;The MultiChoiceTrait was renamed to ChoiceTrait.
Also its getChoiceOptions function changed not longer care about expanded or multiple.
Also the traits function are all private and can not longer be called outside.
The internal api changed
Sulu\Bundle\FormBundle\Controller\TemplateController::getSortedTypes is not longer public available
POST /api/forms/{id} will return 201 instead of 200 status code.
DELETE /api/forms/{id} will return 204 no content instead of 200 status code.
Sulu\Bundle\FormBundle\Mail\HelperInterface::getReceiverTypesunused function was removed.
For the Symfony 3 Compatibility the following classes where refractored:
Sulu\Bundle\FormBundle\Controller\FormWebsiteControllerSulu\Bundle\FormBundle\Form\HandlerSulu\Bundle\FormBundle\Form\HandlerInterfaceSulu\Bundle\FormBundle\EventListener\RequestListenerSulu\Bundle\FormBundle\Form\BuilderSulu\Bundle\FormBundle\Event\MailSubscriber
If you depend on them or overridden them you need reimplement your logic based on the new classes and events.
Your custom forms and dynamic form field types
To update your custom form and form types have a look at https://github.com/symfony/symfony/blob/2.8/UPGRADE-3.0.md#form
The lastwidth and column attribute for the grid are not longer written to the dom.
If you still want them overwrite the attributes block in your theme with the default
of form_div_layout.html.twig.
Handling static forms the current way is deprecated if you still want use them you need to configure a mapping between template and the static form:
sulu_form:
static_forms:
page_template_key:
class: Client\Bundle\WebsiteBundle\Type\ExampleTypeSulu\Bundle\FormBundle\Event\DynFormSavedEvent::getFormSelectdeprecated function was removed usegetDatainstead.Sulu\Bundle\FormBundle\EventListener\RequestListenerwas moved useSulu\Bundle\FormBundle\Event\RequestListenerinsteadSulu\Bundle\FormBundle\Form\Handler::getwas removed form is now created in FormWebsiteControllerSulu\Bundle\FormBundle\Form\Handler::getTokenwas removedSulu\Bundle\FormBundle\Form\Handler::handle($form, $attributes)was replaced withSulu\Bundle\FormBundle\Form\Handler::handle($form, $configuration)Sulu\Bundle\FormBundle\Form\Handler::sendMailsis not longer overrideable use EventListener to change Email behaviour insteadSulu\Bundle\FormBundle\Form\Handler::saveFormis not longer overrideable use EventLister when you want to avoid save processSulu\Bundle\FormBundle\Form\Handler::getFormLocalewas removedSulu\Bundle\FormBundle\Form\Builder::getKeyis not longer overrideableSulu\Bundle\FormBundle\Form\Builder::createFormchanged is not longer overrideableSulu\Bundle\FormBundle\Form\Builder::loadFormEntityis not longer overrideableSulu\Bundle\FormBundle\Form\Builder::createFormTypeis not longer availableSulu\Bundle\FormBundle\Form\Builder::getWebspaceKeyis not longer overrideableSulu\Bundle\FormBundle\Form\Builder::buildreturn a FormInterface instead of an arraySulu\Bundle\FormBundle\Event\MailSubscriberwas removed
FormController:cgetTemplateAction (/admin/api/forms/template) was moved to TemplateController:formAction (/admin/api//form/templates/form.html).
ALTER TABLE fo_form_translations ADD submitLabel VARCHAR(255) DEFAULT NULL;
ALTER TABLE fo_dynamics ADD type VARCHAR(255) NOT NULL, CHANGE uuid typeId VARCHAR(255) NOT NULL;
ALTER TABLE fo_dynamics ADD idUsersCreator INT DEFAULT NULL, ADD idUsersChanger INT DEFAULT NULL;
ALTER TABLE fo_dynamics ADD CONSTRAINT FK_EC8AF030DBF11E1D FOREIGN KEY (idUsersCreator) REFERENCES se_users (id) ON DELETE SET NULL;
ALTER TABLE fo_dynamics ADD CONSTRAINT FK_EC8AF03030D07CD5 FOREIGN KEY (idUsersChanger) REFERENCES se_users (id) ON DELETE SET NULL;
CREATE INDEX IDX_EC8AF030DBF11E1D ON fo_dynamics (idUsersCreator);
CREATE INDEX IDX_EC8AF03030D07CD5 ON fo_dynamics (idUsersChanger);
ALTER TABLE fo_dynamics ADD typeName VARCHAR(255) DEFAULT NULL;
UPDATE `fo_dynamics` SET `type` = 'page' WHERE `type` = '';With the compatibility to use the form bundle in articles it is needed to define the type in the xml definition.
before
<property name="form" type="form_select">
<meta>
<title lang="de">Formular</title>
<title lang="en">Form</title>
</meta>
</property>after
<property name="form" type="form_select">
<meta>
<title lang="de">Formular</title>
<title lang="en">Form</title>
</meta>
<params>
<param name="type" value="page" />
</params>
</property>Change app/config/config.yml the dynamic_lists configuration need to be updated.
before:
sulu_form:
dynamic_lists:
content:
default:
property: formafter:
sulu_form:
dynamic_lists:
content:
default:
template: default
property: form
type: pageThe bundle is under heavy development so check the changes of the following link when you did overwrite or extend the sulu form bundle: https://github.com/sulu/suluformbundle/compare/0.1.0...0.2.0
Handling static forms this way is deprecated and will be removed in one of the next releases.
- The
Sulu\Bundle\FormBundle\Provider\DynamicProvideris deprecated and will be removed in one of the next releases use the config above. - Handling static forms the current way is deprecated and will be removed in one of the next releases.
- The
Sulu\Bundle\FormBundle\Event\DynFormSavedEvent::getFormSelectfunction is deprecated usgetDatainstead. - The
Sulu\Bundle\FormBundle\Form\Builder::buildFormis deprecated and will be removed in one of the next releases. - The
Sulu\Bundle\FormBundle\Form\Builder::createFormis deprecated and will be removed in one of the next releases. - The
Sulu\Bundle\FormBundle\Form\Builder::loadFormEntityis deprecated and will be removed in one of the next releases. - The
Sulu\Bundle\FormBundle\Form\Builder::createFormTypeis deprecated and will be removed in one of the next releases. - The
Sulu\Bundle\FormBundle\Form\Builder::loadFormEntityis deprecated and will be removed in one of the next releases. - The
Sulu\Bundle\FormBundle\Form\Builder::getDefaultsis deprecated and will be removed in one of the next releases. - The
Sulu\Bundle\FormBundle\Form\Builder::getWebspaceKeyis deprecated and will be removed in one of the next releases. - The
Sulu\Bundle\FormBundle\Form\Handleris deprecated and will be removed in one of the next releases.