Feature #101909
closedMake it possible to activate / deactive packages (extensions) from Feature toggles
Added by Stig Nørgaard Færch about 1 year ago. Updated 4 months ago.
0%
Description
We have extension A and the new extension B. In extension A we have added som feature toggles on code that uses extension B.
Currently on our testing site we activate the featuretoggle to test things, but manually have to add the extension B package from composer, breaking our deploy setup.
Also we might want to test the new feature on only one of multiple Production/Live instances of the same TYPO3 solution, which also presents the same problem.
It would be nice if we could add extension B to the main branch and have it activated through the feature toggle.
Updated by Stig Nørgaard Færch about 1 year ago
- Tracker changed from Bug to Feature
- TYPO3 Version deleted (
11)
Updated by Stig Nørgaard Færch about 1 year ago
Just experimented a bit with the PackageManager and got something working, though of course not tested thoroughly, and it may or maybe not be a viable solution:
\TYPO3\CMS\Core\Package\PackageManager::getActivePackages
public function getActivePackages()
{
if (empty($this->activePackages)) {
if (!empty($this->packageStatesConfiguration['packages'])) {
foreach ($this->packageStatesConfiguration['packages'] as $packageKey => $packageConfig) {
$addAsActivePackage = true;
if($GLOBALS['TYPO3_CONF_VARS']['SYS']['enableExtensionByFeatureToggle'][$packageKey] ?? false) {
$addAsActivePackage = GeneralUtility::makeInstance(Features::class)->isFeatureEnabled($GLOBALS['TYPO3_CONF_VARS']['SYS']['enableExtensionByFeatureToggle'][$packageKey]);
}
if($addAsActivePackage) $this->activePackages[$packageKey] = $this->getPackage($packageKey);
}
}
}
return $this->activePackages;
}
So I my additionalConfiguration.php file, I would of course have my feature toggle settings and this new one:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['enableExtensionByFeatureToggle']['news'] = 'myFeatureName';
Updated by Stig Nørgaard Færch about 1 year ago
As some points out on Slack. My suggestion to a solution might bring big trouble as patching getActivePackages for runtime extensions might introduce a lot of DI-cache and other TYPO3-cache issues...
For my example, one suggests me make anything in the extension B gated from the feature toggle as well. That could be a lot of conditions all over. Another point is, that this might be a 3rd party extension, and not a in house extension. So that would require to hack the extension instead.
Updated by Helmut Hummel 5 months ago
We got rid of runtimeActivatedPackages not long ago, because it caused a lot of headaches. we should not re-introduce it again.
Instead of adding hacks to manipulate installed packages on runtime, typo3 should introduce more fine geraintes control over resources these packages provide.
Updated by Helmut Hummel 5 months ago
@Stig Nørgaard Færch Can you elaborate your use case more? I'm sure we can find a clean solution to what you need in regards to feature toggles.
- What kind of resources / configuration does extension B provide?
- How do they (resources / configuration) interfere with extension A or the system, when extension B is merely activated.
- What do you currently use as feature toggle? TYPO3_CONF_VARS?
Updated by Stig Nørgaard Færch 5 months ago
Helmut Hummel wrote in #note-7:
@Stig Nørgaard Færch Can you elaborate your use case more? I'm sure we can find a clean solution to what you need in regards to feature toggles.
There would be different cases -
Case 1: Extension A = The main configuration/template extension. Extension B: A new extension introducing a new major feature (fx a newsletter function), could contain any possible TYPO3 resource and configuration.
Case 2: Extension B = An extension containing a major feature (News etc). Extension B: A backend module is added. New fields are added.
Sometimes ExtensionManagementUtility::isLoaded('some_extenion_name') would be used to determine if something should be activated or not.
- What kind of resources / configuration does extension B provide?
- TCA
- TypoScript (constants and setup)
- Page and User TS
- Service.yaml/php
- Fluid templates (sometimes overriding something)
- Language files (sometimes overriding)
- All these could be automatically activated (ExtensionManagementUtility::addPageTSConfig, addUserTSConfig, addTypoScriptSetup etc)
- How do they (resources / configuration) interfere with extension A or the system, when extension B is merely activated.
For example:
- New fields popping up in the backend
- Fluid templates overridden
- New plugins or content elements available
- Some content being manipulated by hook or eventlistener
- TS loaded which could do all sorts of things.
- PageTS or UserTS loaded which could do something to backend (new content element wizard etc)
- What do you currently use as feature toggle? TYPO3_CONF_VARS?
The standard TYPO3 api for feature toggles:
https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/Configuration/FeatureToggles.html
Updated by Helmut Hummel 5 months ago
Thanks for your reply.
There would be different cases -
Case 1: Extension A = The main configuration/template extension. Extension B: A new extension introducing a new major feature (fx a newsletter function), could contain any possible TYPO3 resource and configuration.
I invite you to not (only) focus on features being encapsulated in exactly one (new) extension.
More often than not, features need to be added to one or more existing extensions.
If you ask yourself, how you would then need to apply feature toggles, you are closer to what I am suggesting.
Case 2: Extension B = An extension containing a major feature (News etc). Extension B: A backend module is added. New fields are added.
Sometimes ExtensionManagementUtility::isLoaded('some_extenion_name') would be used to determine if something should be activated or not.
I don't understand how any of this is related.
- TCA
that's all php code. you can add feature checks in the code.
- TypoScript (constants and setup)
- Page and User TS
There are multiple ways those are added. They are never added automatically. Depending on how they are added, the way feature toggle are checked can differ, but it should be possible
- Service.yaml/php
PHP see above. yaml could be tricky. But similar to classes being loadable, when a package is required, side effects from that need to be accepted, or workaround can be found.
- Fluid templates (sometimes overriding something)
Same as ts no fluid template is loaded / overrides automatically
- Language files (sometimes overriding)
Same as Fluid
- All these could be automatically activated (ExtensionManagementUtility::addPageTSConfig, addUserTSConfig, addTypoScriptSetup etc)
That is php code hat can branch according to feature toggles.
- How do they (resources / configuration) interfere with extension A or the system, when extension B is merely activated.
For example:
- New fields popping up in the backend
- Fluid templates overridden
- New plugins or content elements available
- Some content being manipulated by hook or eventlistener
- TS loaded which could do all sorts of things.
- PageTS or UserTS loaded which could do something to backend (new content element wizard etc)
see above
- What do you currently use as feature toggle? TYPO3_CONF_VARS?
The standard TYPO3 api for feature toggles:
https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/Configuration/FeatureToggles.html
So PHP code can be covered, which covers most of the use cases you mentioned. Some minor things need to be added, like recently a view helper that checks for feature toggles.
If what I have written seems too much effort and you want to stick to put features into extensions, that's fine.
It should be doable with any deployment strategy, to execute a single composer require call only on specified systems. This will then also work for code, that does feature checks with class_exists, which always fails when a package is required by composer
Updated by Georg Ringer 4 months ago
- Status changed from Needs Feedback to Closed
Hey Stig,
I am closing this issue as we won't implement such toggles and as pointed out by Helmut, there are plenty of options how this can be achieved already