TASK: Update TYPO3 to 9.5 LTS, add outlook, add routing, add ignore
validation
This commit is contained in:
parent
89b63c3f43
commit
3701a4e492
7
CodeExamples/.gitignore
vendored
7
CodeExamples/.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
/private/
|
||||
/public/
|
||||
/vendor/
|
||||
/public
|
||||
/vendor
|
||||
/app/*
|
||||
!/app/typo3conf/sites/default/config.yaml
|
||||
|
|
39
CodeExamples/app/typo3conf/sites/default/config.yaml
Normal file
39
CodeExamples/app/typo3conf/sites/default/config.yaml
Normal file
|
@ -0,0 +1,39 @@
|
|||
rootPageId: 1
|
||||
base: /
|
||||
baseVariants: {}
|
||||
languages:
|
||||
-
|
||||
title: English
|
||||
enabled: true
|
||||
languageId: '0'
|
||||
base: /
|
||||
typo3Language: default
|
||||
locale: en_US.utf8
|
||||
iso-639-1: en
|
||||
navigationTitle: English
|
||||
hreflang: en-US
|
||||
direction: ''
|
||||
flag: global
|
||||
errorHandling: {}
|
||||
routes: {}
|
||||
routeEnhancers:
|
||||
ExamplePlugin:
|
||||
type: Extbase
|
||||
extension: ExampleExtension
|
||||
plugin: Address
|
||||
defaultController: 'Address::index'
|
||||
routes:
|
||||
-
|
||||
routePath: '/edit/{address}'
|
||||
_controller: 'Address::edit'
|
||||
_arguments:
|
||||
'address': 'address'
|
||||
-
|
||||
routePath: '/update'
|
||||
_controller: 'Address::update'
|
||||
aspects:
|
||||
address:
|
||||
type: PersistedPatternMapper
|
||||
tableName: 'tx_exampleextension_domain_model_address'
|
||||
routeFieldPattern: '^(?P<company_name>.+)-(?P<uid>\d+)$'
|
||||
routeFieldResult: '{company_name}-{uid}'
|
|
@ -13,27 +13,29 @@
|
|||
"description": "Example TYPO3 installation for workshop",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"helhum/typo3-console": "^4.9.3 || ^5.2",
|
||||
"helhum/typo3-console": "^5.5.5",
|
||||
"helhum/typo3-secure-web": "^0.2.7",
|
||||
"typo3-console/composer-auto-commands": "^0.2.0",
|
||||
"typo3/cms-about": "^8.7.17",
|
||||
"typo3/cms-belog": "^8.7.17",
|
||||
"typo3/cms-beuser": "^8.7.17",
|
||||
"typo3/cms-fluid-styled-content": "^8.7.17",
|
||||
"typo3/cms-info": "^8.7.17",
|
||||
"typo3/cms-info-pagetsconfig": "^8.7.17",
|
||||
"typo3/cms-rte-ckeditor": "^8.7.17",
|
||||
"typo3/cms-setup": "^8.7.17",
|
||||
"typo3/cms-t3editor": "^8.7.17",
|
||||
"typo3/cms-tstemplate": "^8.7.17",
|
||||
"typo3/cms-core": "^9.5.0",
|
||||
"typo3/cms-about": "*",
|
||||
"typo3/cms-belog": "*",
|
||||
"typo3/cms-beuser": "*",
|
||||
"typo3/cms-fluid-styled-content": "*",
|
||||
"typo3/cms-info": "*",
|
||||
"typo3/cms-info-pagetsconfig": "*",
|
||||
"typo3/cms-rte-ckeditor": "*",
|
||||
"typo3/cms-setup": "*",
|
||||
"typo3/cms-t3editor": "*",
|
||||
"typo3/cms-tstemplate": "*",
|
||||
"workshop/example-extension": "@dev"
|
||||
},
|
||||
"require-dev": {
|
||||
"typo3/cms-lowlevel": "^8.7.17"
|
||||
"typo3/cms-lowlevel": "*"
|
||||
},
|
||||
"extra": {
|
||||
"typo3/cms": {
|
||||
"root-dir": "private",
|
||||
"app-dir": "app",
|
||||
"root-dir": "app",
|
||||
"web-dir": "public"
|
||||
},
|
||||
"helhum/typo3-console": {
|
||||
|
|
1923
CodeExamples/composer.lock
generated
1923
CodeExamples/composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -42,6 +42,9 @@ class AddressController extends ActionController
|
|||
$this->view->assign('addresses', $this->addressRepository->findAll());
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignorevalidation $address
|
||||
*/
|
||||
public function editAction(Address $address)
|
||||
{
|
||||
$this->view->assign('address', $address);
|
||||
|
|
|
@ -27,6 +27,7 @@ class Address extends AbstractEntity
|
|||
{
|
||||
/**
|
||||
* @var string
|
||||
* @validate NotEmpty
|
||||
*/
|
||||
protected $companyName;
|
||||
|
||||
|
@ -42,6 +43,7 @@ class Address extends AbstractEntity
|
|||
|
||||
/**
|
||||
* @var string
|
||||
* @validate RegularExpression(regularExpression = '/^[0-9]{5}$/')
|
||||
*/
|
||||
protected $zip;
|
||||
|
||||
|
|
|
@ -22,6 +22,14 @@
|
|||
<trans-unit id="labels.country" xml:space="preserve">
|
||||
<source>Country</source>
|
||||
</trans-unit>
|
||||
|
||||
<!-- Form Validation -->
|
||||
<trans-unit id="error.address.companyName.1221560718" xml:space="preserve">
|
||||
<source>Please provide a company name.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="error.address.zip.1221565130" xml:space="preserve">
|
||||
<source>Please provide a valid ZIP consisting of 5 digits.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
</label>
|
||||
<br>
|
||||
<f:form.textfield property="{propertyName}" id="{propertyName}" />
|
||||
{f:render(section: 'FieldErrors', arguments: {
|
||||
propertyPath: 'address.{propertyName}'
|
||||
})}
|
||||
<br>
|
||||
</p>
|
||||
</f:for>
|
||||
|
@ -22,3 +25,13 @@
|
|||
<br>
|
||||
<f:form.submit value="Update" />
|
||||
</f:form>
|
||||
|
||||
<f:section name="FieldErrors">
|
||||
<f:form.validationResults for="{propertyPath}">
|
||||
<f:for each="{validationResults.flattenedErrors}" as="errors">
|
||||
<f:for each="{errors}" as="error">
|
||||
{f:translate(id: 'error.{propertyPath}.{error.code}', default: error.code)}
|
||||
</f:for>
|
||||
</f:for>
|
||||
</f:form.validationResults>
|
||||
</f:section>
|
||||
|
|
|
@ -13,5 +13,8 @@
|
|||
"psr-4": {
|
||||
"Workshop\\ExampleExtension\\": "Classes"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"typo3/cms-core": "*"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,8 @@ See :ref:`t3coreapi:extension-files-locations` in TYPO3 Core API Reference.
|
|||
Further resources
|
||||
-----------------
|
||||
|
||||
* https://extensions.typo3.org/about-extension-repository/what-are-extensions/
|
||||
|
||||
* :ref:`t3coreapi:extension-architecture` in TYPO3 Core API Reference.
|
||||
|
||||
* :ref:`t3coreapi:extension-files-locations` in TYPO3 Core API Reference.
|
||||
|
|
19
Documentation/source/Outlook.rst
Normal file
19
Documentation/source/Outlook.rst
Normal file
|
@ -0,0 +1,19 @@
|
|||
Outlook
|
||||
=======
|
||||
|
||||
If we have some time left, we can take a deeper look at some of these topics.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:numbered:
|
||||
|
||||
Outlook/Routing
|
||||
Outlook/Dependency-Injection
|
||||
Outlook/Automated-Testing
|
||||
Outlook/Property-Mapper
|
||||
Outlook/Coding-Guideline
|
||||
Outlook/Command-Controllers
|
||||
Outlook/Backend-Modules
|
||||
Outlook/Fluid/Custom-ViewHelper
|
||||
Outlook/Fluid/Concepts-of-Models
|
||||
Outlook/Configuration/Mapping-DB
|
6
Documentation/source/Outlook/Automated-Testing.rst
Normal file
6
Documentation/source/Outlook/Automated-Testing.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
Automated Testing
|
||||
=================
|
||||
|
||||
See:
|
||||
|
||||
* https://github.com/DanielSiepmann/testing-talk/
|
6
Documentation/source/Outlook/Backend-Modules.rst
Normal file
6
Documentation/source/Outlook/Backend-Modules.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
Backend Modules
|
||||
===============
|
||||
|
||||
See:
|
||||
|
||||
* https://docs.typo3.org/typo3cms/ExtbaseFluidBook/10-Outlook/2-Backend-modules.html
|
2
Documentation/source/Outlook/Coding-Guideline.rst
Normal file
2
Documentation/source/Outlook/Coding-Guideline.rst
Normal file
|
@ -0,0 +1,2 @@
|
|||
Coding Guideline
|
||||
================
|
6
Documentation/source/Outlook/Command-Controllers.rst
Normal file
6
Documentation/source/Outlook/Command-Controllers.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
Command Controllers
|
||||
===================
|
||||
|
||||
See:
|
||||
|
||||
* https://docs.typo3.org/typo3cms/ExtbaseFluidBook/10-Outlook/3-Command-controllers.html
|
|
@ -0,0 +1,6 @@
|
|||
Configuration Mapping DB
|
||||
========================
|
||||
|
||||
See:
|
||||
|
||||
* https://docs.typo3.org/typo3cms/ExtbaseFluidBook/b-ExtbaseReference/Index.html#persistence
|
8
Documentation/source/Outlook/Dependency-Injection.rst
Normal file
8
Documentation/source/Outlook/Dependency-Injection.rst
Normal file
|
@ -0,0 +1,8 @@
|
|||
Dependency Injection
|
||||
====================
|
||||
|
||||
See:
|
||||
|
||||
* https://daniel-siepmann.de/Posts/2017/2017-08-17-typo3-injection.html
|
||||
|
||||
* https://daniel-siepmann.de/Posts/Migrated/2015-10-20-extbase-inject-settings.html
|
|
@ -0,0 +1,2 @@
|
|||
Fluid - Concepts of Models
|
||||
==========================
|
6
Documentation/source/Outlook/Fluid/Custom-ViewHelper.rst
Normal file
6
Documentation/source/Outlook/Fluid/Custom-ViewHelper.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
Fluid - Custom ViewHelper
|
||||
=========================
|
||||
|
||||
See:
|
||||
|
||||
* https://docs.typo3.org/typo3cms/ExtbaseFluidBook/8-Fluid/8-developing-a-custom-viewhelper.html
|
8
Documentation/source/Outlook/Property-Mapper.rst
Normal file
8
Documentation/source/Outlook/Property-Mapper.rst
Normal file
|
@ -0,0 +1,8 @@
|
|||
Property Mapper
|
||||
===============
|
||||
|
||||
See:
|
||||
|
||||
* https://docs.typo3.org/typo3cms/ExtbaseFluidBook/10-Outlook/4-Property-mapping.html
|
||||
|
||||
* https://github.com/DanielSiepmann/extbase-the-good-parts/blob/master/Tests/Unit/PropertyMappingTest.php
|
38
Documentation/source/Outlook/Routing.rst
Normal file
38
Documentation/source/Outlook/Routing.rst
Normal file
|
@ -0,0 +1,38 @@
|
|||
Routing
|
||||
=======
|
||||
|
||||
This section is related to TYPO3 v9.5.0 LTS, which introduces routing into the TYPO3
|
||||
core.
|
||||
|
||||
See: https://docs.typo3.org/typo3cms/extensions/core/latest/Changelog/9.5/Feature-86365-RoutingEnhancersAndAspects.html
|
||||
|
||||
An example for the example extension looks like:
|
||||
|
||||
.. code-block:: yaml
|
||||
:linenos:
|
||||
|
||||
routeEnhancers:
|
||||
ExamplePlugin:
|
||||
type: Extbase
|
||||
extension: ExampleExtension
|
||||
plugin: Address
|
||||
defaultController: 'Address::index'
|
||||
routes:
|
||||
-
|
||||
routePath: '/edit/{address}'
|
||||
_controller: 'Address::edit'
|
||||
_arguments:
|
||||
'address': 'address'
|
||||
-
|
||||
routePath: '/update'
|
||||
_controller: 'Address::update'
|
||||
aspects:
|
||||
address:
|
||||
type: PersistedPatternMapper
|
||||
tableName: 'tx_exampleextension_domain_model_address'
|
||||
routeFieldPattern: '^(?P<company_name>.+)-(?P<uid>\d+)$'
|
||||
routeFieldResult: '{company_name}-{uid}'
|
||||
|
||||
This defines two routed, one for edit and one for update. Also there is no cHash in
|
||||
URls due to the configuration. The address is replaced by company name and uid within
|
||||
the url.
|
|
@ -172,3 +172,119 @@ Validation
|
|||
|
||||
Prevent invalid data.
|
||||
|
||||
Up till now, the user could provide any text into any property. There was no
|
||||
validation whether a zip is actual valid.
|
||||
|
||||
Adding this is done within either the model, or the controller.
|
||||
|
||||
Within Controller
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Sparely used, this makes sense if you do not use models at all or use the same model
|
||||
with different validation rules.
|
||||
|
||||
The process is the same as within a model, just the annotations are added to the
|
||||
PHPDoc of the corresponding action.
|
||||
|
||||
We will not cover this, instead we use validation within model.
|
||||
|
||||
Within Model
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Each property already has a type annotation::
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
||||
By adding one, or multiple, ``@validate`` annotations, these properties get
|
||||
validated::
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @validate NotEmpty
|
||||
*/
|
||||
|
||||
Extbase provides some validators our of the box, all available within ``typo3/sysext/extbase/Classes/Validation/Validator``:
|
||||
|
||||
* AlphanumericValidator
|
||||
* EmailAddressValidator
|
||||
* NotEmptyValidator
|
||||
* NumberRangeValidator
|
||||
* RawValidator
|
||||
* RegularExpressionValidator
|
||||
* StringLengthValidator
|
||||
* TextValidator
|
||||
|
||||
Also validators for PHP Type like ``String`` or ``DateTime`` are provided which are
|
||||
auto added based on ``@var`` annotation.
|
||||
|
||||
Let's say a zip only consists of integers and is exactly 5 integers long, like in
|
||||
Germany. One or more leading 0 are allowed, we therefore will not use the PHP type
|
||||
``integer`` but ``string``. A possible validation might look like::
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @validate RegularExpression(regularExpression = '/^[0-9]{5}$/')
|
||||
*/
|
||||
protected $zip;
|
||||
|
||||
Display validation errors
|
||||
-------------------------
|
||||
|
||||
Nearly finished, we can no longer save invalid records. Still the user does not get
|
||||
any information about what's wrong. Fluid by default will add the css class
|
||||
``f3-form-error`` to all inputs with an error. So one could style this css class:
|
||||
|
||||
.. code-block:: css
|
||||
|
||||
.f3-form-error {
|
||||
border: solid 5px #cd2323;
|
||||
}
|
||||
|
||||
This way at least it's clear which fields fail, but not why. We therefore use another
|
||||
ViewHelper to add the validation errors to each field. As we have to add the same
|
||||
markup for each field, we will put it into a section for re-use. On larger projects
|
||||
this might be a Partial:
|
||||
|
||||
.. code-block:: html
|
||||
:linenos:
|
||||
|
||||
<f:section name="FieldErrors">
|
||||
<f:form.validationResults for="{propertyPath}">
|
||||
<f:for each="{validationResults.flattenedErrors}" as="errors">
|
||||
<f:for each="{errors}" as="error">
|
||||
<li>{error.code}: {error}</li>
|
||||
</f:for>
|
||||
</f:for>
|
||||
</f:form.validationResults>
|
||||
</f:section>
|
||||
|
||||
This section can be used like:
|
||||
|
||||
.. code-block:: html
|
||||
:linenos:
|
||||
|
||||
<f:form.textfield property="companyName" />
|
||||
{f:render(section: 'FieldErrors', arguments: {
|
||||
propertyPath: 'address.companyName'
|
||||
})}
|
||||
|
||||
Handling existing invalid records
|
||||
---------------------------------
|
||||
|
||||
In some circumstances your system might have an invalid record. Right now it's not
|
||||
possible to edit this record with `editAction` as Extbase will validate the record.
|
||||
|
||||
Therefore the `@ignorevalidation` annotation can be added to the action::
|
||||
|
||||
/**
|
||||
* @ignorevalidation $address
|
||||
*/
|
||||
public function editAction(Address $address)
|
||||
{
|
||||
$this->view->assign('address', $address);
|
||||
}
|
||||
|
||||
This way Extbase will ignore raised validation issues and we are ready to go to edit
|
||||
the record.
|
||||
|
|
|
@ -39,3 +39,4 @@ build custom extensions:
|
|||
Configuration
|
||||
CustomRecords
|
||||
UpdatingRecords
|
||||
Outlook
|
||||
|
|
Loading…
Reference in a new issue