From 571907c8a367f633ac2a9751a5caf477b5fd980c Mon Sep 17 00:00:00 2001 From: Florian Sydekum Date: Tue, 21 Apr 2020 16:40:03 +0200 Subject: [PATCH 1/4] Added proposal for configuration provisioning --- .../provisioning/configuration.md | 93 ++++++++++++++++++ .../provisioning/module-structure.jpg | Bin 0 -> 26390 bytes 2 files changed, 93 insertions(+) create mode 100644 design-documents/provisioning/configuration.md create mode 100644 design-documents/provisioning/module-structure.jpg diff --git a/design-documents/provisioning/configuration.md b/design-documents/provisioning/configuration.md new file mode 100644 index 000000000..1c1ba9c4a --- /dev/null +++ b/design-documents/provisioning/configuration.md @@ -0,0 +1,93 @@ +## Configuration Provisioning + +### Overview + +When you start a new Magento project there are similar initial tasks to set up configuration including websites, stores, tax, store configuration, attributes and more. This leads to the following known problems: + +* Boilerplate Code in data patches (copied from Google, DevDocs, StackOverflow, other projects, maybe poorly adjusted) +* Update and Delete operations are tedious and complex as you have to manage relations and identification inside data patches (i.e. store code vs. autoincrement id) +* Installation from scratch with scope level configuration inside `config.php` is not possible if you rely on it in data patches + +There should be a declarative schema approach to provision a new instance with all necessary configuration to run. It is related to the existing delcarative database schema but manages configuration data like: + +* Websites +* Stores +* Store Groups +* System configuration +* Attribtues +* Attribute Sets +* Attribute Groups +* Tax + +This is at least the most basic configuration. The design approach aims to leverage the extensibility so that more configuration entities can be included in the list above. + +**Additional feature:** There should also be an export functionality which generates declarative schema files for an existing Magento instance which includes all configuration. This feature would be priority 2 as it is more important to import them first via declarative schema. + +### Design + +#### Module structure + +The main dataflow and import functionality is provided by a core module. It controls the workflow and provides generic functionality for all configuration modules. On top of that there is a module for every configuration entity (website, store, tax...) which uses the core module to import and export the data. + +![module-structure](module-structure.jpg) + +The core module provides: + +* CLI Commands: Imports and exports single configuration entities +* Backend GUI: Offers functionality to export configuration via admin interface +* Import / Export workflow: Abstract definition of the workflow +* Serialize / Input / Output: Read- and write adapter, offers merge logic for declarative files and offers `maintained` flag logic + +#### Provisioning sequence + +The usual behavior for installing from scratch or upgrading is the following: + +`bin/magento setup:install` + +* Declarative Schema (DB) +* Install Schema +* Upgrade Schema +* Recurring Schema +* Install Data +* Upgrade Data +* Recurring Data +* app:config:import + +`bin/magento setup:upgrade` + +* Declarative Schema (DB) +* Install Schema +* Upgrade Schema +* Recurring Schema +* Install Data +* Upgrade Data +* Recurring Data +* app:config:import + +The configuration provisioning core logic should be executed as one of the last recurring data scripts. As alternative the execution sequence mentioned above can be changed so that it runs directly after recurring data and before config import. + +The reason for this is that also registered themes (inside a recurring data script) can still be used by the provisioning logic. This would be obsolete if theme registration is part of configuration provisioning. + +#### Data structure + +As already mentioned the data structure is related to the existing database declarative schema. Every module can define such a XML file for a configuration type. All configuration files for the same type would be merged to one big logical structure. Therefore every configuration type module should at least support merge logic. This is done individually as for example websites are merged differently than attributes. + +Therefore a virtual type of `Magento\Framework\Config\Reader\Filesystem` will be defined which has a ` Magento\Framework\Config\ConverterInterface` which is responsible for merging the XML files. + +On top of that every configuration type module defines a `maintained` flag which basically defines if the configuration can be overriden by a user or not. If it is set to `yes` the configuration provisioning will always override the values, independently if it was changed or not. + +#### Change or delete configuration + +Changing or deleting configuration is a challenging task, especially for all the relations and true identifier of an entity (i.e. store code vs. autoincrement id). Every configuration type module should therefore define the identifier on its own, dependent on which configuration type it supports. + +Changes can then be done via the identifier and the `maintained` flag. + +Deletions must be done explicit similar how you explicitly deactivate a plugin with `disabled = true`. This allows for proper merging of the XML files. + +#### Extension Points and Scenarios + +Once the core provisioning logic and module is set up including the main workflow, we can adapt legacy code to the new functionality. For example registering themes is done via a recurring patch which we can easily adapt to the new configuration provisioning logic. + +### Prototype or Proof of Concept + +tbd. diff --git a/design-documents/provisioning/module-structure.jpg b/design-documents/provisioning/module-structure.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ba188c7642c3e7b5c6b74e6ea165b5b8a273907d GIT binary patch literal 26390 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 z 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

OTE@iC>bll4hq_*%Ao~EbUhN z{d$*b`_Uj*yBW=FyP+aOyI6f#JP$dE|4^2uA%x1Bm(17k{ApaQBzbKpNLyPc|8>2* zSEb&;js6ELx7C)tAnEdN|A{F0UE>#P0w4(kYUmfu+jr9z# z4Z>Cc)HVbt+dYJLD8I9OZ#yb|AN@=1Z~G^=E;h}5#iiWz%U!9gtKDvBj~r)R?e^p^ z&d2`(=)YX|w#^@O;x8Va?YF^gd;EXHLnH=$Zm}oax{AUpgo)Q8St(s{kv;E!oA+|L zFhf|@m34`NVj97MD<#8*dSy9clI6DX%kpdRg&e=GQrlVk=8@=+ta$DnW_1%j?|Fuf z1pf4LQFSq5HcFj!hb%klQ`$hLxx?j8cLUmII%UdEtvzF16l?kNij9YLeCSKg4+Nvh1UHq1|$ruc;9fNQn`eME9gUMT!&07)q*V2 z6IC7p1bFoulPre|aihs&b0R}jOF5_&M)D4$anw!AGNZuKC@4@n0mzk1)tykg>8kz> zU@9brcrW3z>D`O7mNG;WYuU@l~EmHYp?P(TheuiE#4DbQK@Q@G{OE0FT5_ zpJ`?(fXYQJl9{=zdx3U=Si0cbNBO@Xo&P4G{|+|9<&TK}mMZ#3*>L|t=sw$ztpiDq zVk<(Mt{INW4=N^<%@6yvNtT?u*X-%ThNB0hn-wsUt-%A!30T&(*H`~@G4g*n@E;ER z>l_g1c~fUlGk>nl*Cfkl)zD@=W{F=WW*jKImp)lUh5nzZ3r#jsk1CYq z1Op24Im7_^kc1{4JQX4D5g9 J!Dj!z2>{yxNVot1 literal 0 HcmV?d00001 From 03e4347d86df4430dfeb16db6e6fe604ad77f87d Mon Sep 17 00:00:00 2001 From: Florian Sydekum Date: Fri, 3 Jul 2020 14:28:16 +0200 Subject: [PATCH 2/4] Updated proposal with further information and detailed examples --- .../provisioning/configuration.md | 173 +++++++++++++++++- 1 file changed, 169 insertions(+), 4 deletions(-) diff --git a/design-documents/provisioning/configuration.md b/design-documents/provisioning/configuration.md index 1c1ba9c4a..39f94eb3b 100644 --- a/design-documents/provisioning/configuration.md +++ b/design-documents/provisioning/configuration.md @@ -40,6 +40,23 @@ The core module provides: #### Provisioning sequence +There are entities which can be declared on project scope and entities which can be declared on module scope. All project declarations belong into `app/etc`. Basically everything which can be declared on module scope can also be declared on project scope and will be overwritten by the project scope as it enforces the rules project wide and also can change module introduced entities. + +**Project declarations:** + +* Attribute Sets/Attribute Groups +* Attributes +* Websites/Stores/Store Groups +* System configuration (basically the config.xml functionality will be used for this) +* Tax +* future entities can be added... + +**Module declarations:** + +* Attributes +* System configuration (basically the config.xml functionality will be used for this) +* Tax + The usual behavior for installing from scratch or upgrading is the following: `bin/magento setup:install` @@ -64,9 +81,19 @@ The usual behavior for installing from scratch or upgrading is the following: * Recurring Data * app:config:import -The configuration provisioning core logic should be executed as one of the last recurring data scripts. As alternative the execution sequence mentioned above can be changed so that it runs directly after recurring data and before config import. +There is a dependency tree during installation like the following: + +* Declarative Schema +* Schema Patches +* Recurring Schema Scripts +* Websites => Store Groups => Stores +* System Configuration +* Attributes => Attribute Sets / Attribute Groups +* Tax +* Data Patches +* Recurring Data Scripts +* app:config:import -The reason for this is that also registered themes (inside a recurring data script) can still be used by the provisioning logic. This would be obsolete if theme registration is part of configuration provisioning. #### Data structure @@ -74,16 +101,154 @@ As already mentioned the data structure is related to the existing database decl Therefore a virtual type of `Magento\Framework\Config\Reader\Filesystem` will be defined which has a ` Magento\Framework\Config\ConverterInterface` which is responsible for merging the XML files. -On top of that every configuration type module defines a `maintained` flag which basically defines if the configuration can be overriden by a user or not. If it is set to `yes` the configuration provisioning will always override the values, independently if it was changed or not. +There is also a field `is_mutable` which defines if the declared data can be changed by the admin. The following explains the behavior: + +* `is_mutable` is not defined: + * new entity is installed + * checkbox is unchecked + * admin can change the entity (after checking the checkbox) + * won't overwrite admin side manual created entities until checkbox is unchecked +* `is_mutable = false`: + * new entity is installed + * checkbox does not exist + * admin can't change the entity + * will overwrite admin side manual created entities + +#### Example: Attribute behavior + - "**is_mutable**" flag is checkbox at the attribute grid and at attribute edit page + - Attributes which created from Admin panel is not maintainable by xml (no dumping, "**is_mutable**" flag is not shown but has true value in database) until xml with the same attribute code will be created and "**is_mutable**" will be unchecked + - "**is_mutable**" flag is responsible for defining maintenance responsibilities: + - **true** responsibility on Admin panel side switchable from admin + - **false** responsibility on code side switchable from admin + - **locked** - responsibility on code side and not switchable from admin +``` + + + + + /> + + +``` +## Created by XML +- Default `"is_mutable"=false` and this property is optional for attribute xml node +- Fully managed by admin panel +- If xml with the same attribute code will be created - it will take over all responsibilities to a code side and will be then managed like attribute created by XML declaration + +| is_mutable in XML-> | `is_mutable` not defined | `is_mutable="false"` | +| ------------------------- | --------------------------------- | -------------------- | +| DB value for `is_mutable` | true/false (default false) | locked | +| checkbox | unchecked | not existing | +| checkbox changeable | true | not existing | +| save btn | disabled (until checkbox checked) | disabled | +| delete btn | disabled (until checkbox checked) | disabled | +| data patch changes | can apply | will be overwritten | + + +## Created by admin (xml declaration doesn't exists): +- Fully managed by admin panel +- If xml with the same attribute code will be created - it will take over all responsibilities to a code side and will be then managed like attribute created by XML declaration + +* DB value for `is_mutable`: true +* checkbox: hidden +* checkbox changeable: false +* save btn: enabled +* delete btn: enabled +* data patch changes: can apply + +#### Example: Store Scopes behavior +We can define a `stores.xml` file on project scope like the following: + +```xml + + + + + + + + + + + + + + + + +``` #### Change or delete configuration Changing or deleting configuration is a challenging task, especially for all the relations and true identifier of an entity (i.e. store code vs. autoincrement id). Every configuration type module should therefore define the identifier on its own, dependent on which configuration type it supports. -Changes can then be done via the identifier and the `maintained` flag. +Example: Create and update store: +- The store/website/store group is identified by its code +- All other data than the code can be changed => will lead to an update +- If the code has to change: delete entity and create new one Deletions must be done explicit similar how you explicitly deactivate a plugin with `disabled = true`. This allows for proper merging of the XML files. +Example Delete store: +- A `deleted=true` flag should be provided +```xml + +``` + #### Extension Points and Scenarios Once the core provisioning logic and module is set up including the main workflow, we can adapt legacy code to the new functionality. For example registering themes is done via a recurring patch which we can easily adapt to the new configuration provisioning logic. From f73f22072295263a883db20442797cd738a5a866 Mon Sep 17 00:00:00 2001 From: Donald Booth Date: Thu, 9 Jul 2020 08:54:14 -0500 Subject: [PATCH 3/4] Editorial pass --- .../provisioning/configuration.md | 75 +++++++++++-------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/design-documents/provisioning/configuration.md b/design-documents/provisioning/configuration.md index 39f94eb3b..456096711 100644 --- a/design-documents/provisioning/configuration.md +++ b/design-documents/provisioning/configuration.md @@ -2,13 +2,13 @@ ### Overview -When you start a new Magento project there are similar initial tasks to set up configuration including websites, stores, tax, store configuration, attributes and more. This leads to the following known problems: +When starting a new Magento project, there are initial tasks to set up: websites, stores, tax, store configuration, attributes and more. This often leads to the following problems: -* Boilerplate Code in data patches (copied from Google, DevDocs, StackOverflow, other projects, maybe poorly adjusted) -* Update and Delete operations are tedious and complex as you have to manage relations and identification inside data patches (i.e. store code vs. autoincrement id) -* Installation from scratch with scope level configuration inside `config.php` is not possible if you rely on it in data patches +* Boilerplate code in data patches: code copied from Google, DevDocs, StackOverflow or other projects. +* Update and Delete operations are tedious and complex. You must manage relations and identification inside data patches (i.e. store code vs. autoincrement id) +* Installation from scratch, with scope level configuration inside `config.php`, is not possible if you rely on data patches -There should be a declarative schema approach to provision a new instance with all necessary configuration to run. It is related to the existing delcarative database schema but manages configuration data like: +Consider a declarative schema approach to provisioning a new instance, with all the necessary configuration set. It is related to the existing delcarative database schema, but manages configuration data such as: * Websites * Stores @@ -19,42 +19,42 @@ There should be a declarative schema approach to provision a new instance with a * Attribute Groups * Tax -This is at least the most basic configuration. The design approach aims to leverage the extensibility so that more configuration entities can be included in the list above. +This is the most basic configuration. This design approach aims to leverage extensibility so more configuration entities can be included in the list above. -**Additional feature:** There should also be an export functionality which generates declarative schema files for an existing Magento instance which includes all configuration. This feature would be priority 2 as it is more important to import them first via declarative schema. +**Additional feature:** There should also be 'export' functionality, which generates declarative schema files for an existing Magento instance,including all configurations. This feature would be priority 2, as it is more important to import them first via a declarative schema. ### Design #### Module structure -The main dataflow and import functionality is provided by a core module. It controls the workflow and provides generic functionality for all configuration modules. On top of that there is a module for every configuration entity (website, store, tax...) which uses the core module to import and export the data. +The main dataflow and import functionality is provided by a core module. It controls the workflow and provides generic functionality for all configuration modules. On top of that, there is a module for every configuration entity (website, store, tax...), which uses the core module to import and export the data. ![module-structure](module-structure.jpg) The core module provides: * CLI Commands: Imports and exports single configuration entities -* Backend GUI: Offers functionality to export configuration via admin interface +* Backend GUI: Offers functionality to export configurations via the admin interface * Import / Export workflow: Abstract definition of the workflow -* Serialize / Input / Output: Read- and write adapter, offers merge logic for declarative files and offers `maintained` flag logic +* Serialize / Input / Output: Read- and write adapter, offers merge logic for declarative files and provides the `maintained` flag logic #### Provisioning sequence -There are entities which can be declared on project scope and entities which can be declared on module scope. All project declarations belong into `app/etc`. Basically everything which can be declared on module scope can also be declared on project scope and will be overwritten by the project scope as it enforces the rules project wide and also can change module introduced entities. +There are entities which can be declared on the project scope and entities which can be declared on the module scope. All project declarations go into `app/etc`. Basically everything which can be declared on the module scope can also be declared on the project scope and will be overwritten by the project scope, as it enforces the rules project-wide and also can change module-introduced entities. **Project declarations:** * Attribute Sets/Attribute Groups * Attributes * Websites/Stores/Store Groups -* System configuration (basically the config.xml functionality will be used for this) +* System configuration (the config.xml functionality is used for this) * Tax * future entities can be added... **Module declarations:** * Attributes -* System configuration (basically the config.xml functionality will be used for this) +* System configuration (the config.xml functionality is used for this) * Tax The usual behavior for installing from scratch or upgrading is the following: @@ -81,7 +81,7 @@ The usual behavior for installing from scratch or upgrading is the following: * Recurring Data * app:config:import -There is a dependency tree during installation like the following: +There is a dependency tree during installation: * Declarative Schema * Schema Patches @@ -97,30 +97,32 @@ There is a dependency tree during installation like the following: #### Data structure -As already mentioned the data structure is related to the existing database declarative schema. Every module can define such a XML file for a configuration type. All configuration files for the same type would be merged to one big logical structure. Therefore every configuration type module should at least support merge logic. This is done individually as for example websites are merged differently than attributes. +As already mentioned, the data structure is related to the existing database declarative schema. Every module can define a XML file for a particular configuration type. All configuration files for the same type would be merged to a single logical structure. Therefore every configuration type module should at least support merge logic. This is done individually, as for example, websites are merged differently than attributes. -Therefore a virtual type of `Magento\Framework\Config\Reader\Filesystem` will be defined which has a ` Magento\Framework\Config\ConverterInterface` which is responsible for merging the XML files. +Therefore, a virtual type of `Magento\Framework\Config\Reader\Filesystem` will be defined, which has a ` Magento\Framework\Config\ConverterInterface` which is responsible for merging the XML files. -There is also a field `is_mutable` which defines if the declared data can be changed by the admin. The following explains the behavior: +There is also a field `is_mutable`, which defines if the declared data can be changed by the admin. * `is_mutable` is not defined: * new entity is installed * checkbox is unchecked * admin can change the entity (after checking the checkbox) - * won't overwrite admin side manual created entities until checkbox is unchecked + * will not overwrite the admin-side, manually-created entities until the checkbox is unchecked * `is_mutable = false`: * new entity is installed * checkbox does not exist - * admin can't change the entity - * will overwrite admin side manual created entities + * admin cannot change the entity + * will overwrite admin-side, manually-created entities #### Example: Attribute behavior - - "**is_mutable**" flag is checkbox at the attribute grid and at attribute edit page - - Attributes which created from Admin panel is not maintainable by xml (no dumping, "**is_mutable**" flag is not shown but has true value in database) until xml with the same attribute code will be created and "**is_mutable**" will be unchecked + + - "**is_mutable**" flag is a checkbox on the attribute grid and on the attribute edit page + - Attributes which are created from the admin panel are not maintainable by xml (no dumping, "**is_mutable**" flag is not shown but has a true value in database) until xml with the same attribute code is created and "**is_mutable**" will be unchecked - "**is_mutable**" flag is responsible for defining maintenance responsibilities: - - **true** responsibility on Admin panel side switchable from admin - - **false** responsibility on code side switchable from admin - - **locked** - responsibility on code side and not switchable from admin + - **true** responsibility is on the admin panel side, switchable from the admin + - **false** responsibility is on the code side, switchable from the admin + - **locked** - responsibility is on the code side and is not switchable from the admin + ```