- Truncate descriptions
Activity
- Edited by totten
If I'm reading correctly, you're suggesting that we keep the
Component
s basically as-is but provide the facade ofExtension
-style management (so that they can participate in the dependency-graph). This gives some management benefits without the technical cost of reorganizing the code or changing the lifecycle of the MySQL data/entities. Very interesting.There are important differences between
Component
s andModule-Extension
s -- you might summarize the difference as "lightweight activation" vs "heavyweight activation". Compare:- For
Component
s (lightweight activation - supported by large system):- Most artifacts (PHP classes, MySQL schema, default data, Smarty templates, APIv3 entities, HTTP routes) are always registered (regardless of whether the
Component
is active). - When activating/deactivating a
Component
, you do not require a script to setup system-level artifacts. You just change a lightweight setting. - The activation is tracked as a
Setting
(enable_components
). This means that everyDomain
stores a separate list ofComponent
s. It also means thatcivicrm.settings.php
can statically or dynamically compute the list of components.
- Most artifacts (PHP classes, MySQL schema, default data, Smarty templates, APIv3 entities, HTTP routes) are always registered (regardless of whether the
- For
Module-Extension
s (heavyweight activation - combing several smaller systems):- Most artifacts (PHP classes, MySQL schema, default data, Smarty templates, APIv3 entities, HTTP routes) are only registered if the extension is active.
- When activating/deactivating a
Module-Extension
, you must run a script to setup system-level artifacts. - The activation is tracked via
civicrm_extension
. This is a system-wide table.
Some questions and gut feelings:
- Extracting
civigrant
was hard because it was changing the lifecycle+activation for so many artifacts. - Is it important to allow
enable_components
to vary per-domain or to be customized incivicrm.settings.php
? I doubt it. But it's really a question for multisite users. - If we want to treat
Component
s as a special kind ofExtension
(for dependency-management purposes), then we should no longer supportenable_components
as aSetting
.- I'm OK with some limited facade for 80%-compatibility, but functionality will be lost -- no per-domain and no
$civicrm_setting
. My brain would explode if twoDomain
s could have different perspectives on the "extension dependency graph".
- I'm OK with some limited facade for 80%-compatibility, but functionality will be lost -- no per-domain and no
- Would the extension name
civicrm
convey "Common/Shared/Base/Core" or "Default/Overarching/Profile"? I think that's an important distinction. If they're blended into one name, then you get a cyclic dependency (civicrm
depends onsearch_kit
, andsearch_kit
depends oncivicrm
==> What?!) Based on the current pseudo-extensioncivicrm
, I would usecivicrm
for "Common/Shared/Base/Core" and develop a separate construct for "Default/Overarching/Profile". - There are a few ways to do stub extensions for each component. My gut says that a "Component-Extension" approach would give us the more wiggle-room for weird edge-cases, and a "Module-Extension" approach would encourage more unplanned/incremental/drive-by patches. But that's just a gut feeling.
<!-- COMPONENT-EXTENSION: Components are a type of extension --> <extension key="civievent" type="component"> <name>CiviEvent</name> <component>CiviEvent</component> <!-- Tip: CRM_Extension_Manager_Component will manage enable/disable. --> <!-- MODULE-EXTENSION: Components are empty module-extensions w/common lifecycle --> <extension key="civievent" type="module"> <name>CiviEvent</name> <upgrader>CRM_Extension_Upgrader_Component</upgrader> <!-- MODULE-EXTENSION: Components are empty module-extensions w/common lifecycle --> <extension key="civievent" type="module"> <name>CiviEvent</name> <mixins> <mixin>component@1.0.0</mixin> </mixin>
- For
- Edited by colemanw
Thanks @totten, you articulated the differences between components and extensions well. To your questions/comments:
- I think the lessons from CiviGrant were that
- The hardest part was migrating the sql installer and structural data (option groups, etc).
- Moving (most of) the php code was straightforward.
- But some of it wasn't (particularly code that expects to be tied to a component, like reports and advanced search panes).
- Therefore, a gradual code migration is best (I'm taking inspiration here from @eileen's approach of creating hidden extensions that you can drag-n-drop php classes into from core at a leisurely pace).
- The easiest part was creating a stub extension. That's why I think this is a good place to start, and still a good thing to do even if we never get around to migrating all components into self-contained extensions.
- Oof you blindsided me with the "per-domain" component activation. I had no idea that was a thing, but my hot take is that it's unnecessary. Given the "heavy" nature of components (they're really always there whether you enable them or not) I see no benefit to disabling them per-domain. IMO we just need to take it into account during the migration process and be sure to turn on a component-extension if the corresponding component was enabled on any domain.
- Agreed, the setting should be axed, the multi-domain functionality lost to the ages, and a facade could help the transition.
- I'm not sure I understand your point about cyclic dependencies. It would be redundant to declare any extension as dependent on
civicrm
(like declaring a Wordpress plugin as dependent on Wordpress). But I think making CiviCRM dependant onsearch_kit
is useful (and part of the motivation for this proposal). - As clever as it would be to add an extension
type=component
I worry that might be overcomplicating things (as that new type would need special support throughout the ExtensionManager system), and I also think it's steering us slightly in the wrong direction. I think the end goal should be to turn every component into a fully self-contained module extension. Sure, we might never fully achieve that goal, but it's IMO the right direction to aim for. And hey, we did it once and survived the ordeal (and even learned a few things along the way), so it's not a totally unrealistic goal.
- I think the lessons from CiviGrant were that
If I am reading correctly, you are suggesting creating a 'fake' civicrm core extension to indicate that SearchKit is a required dependency of core.
It seems to me this is already implemented, but the other way around, as the info.xml for SearchKit states:
<?xml version="1.0"?> <extension key="org.civicrm.search_kit" type="module"> <file>search_kit</file> <name>SearchKit</name> [...] <tags> <tag>mgmt:required</tag> </tags> [...]
This seems to fully address 'Motivation 1' as described above.
'Motivation 2' seems to stem from the same need but related to an individual component rather than core. So you would need to express that an extension is required for a certain component of CiviCRM.
Could we use the same paradigm, and add other mgmt tags that would indicate this (ex: mgmt:required_civievent). These extensions would then automatically be installed when the corresponding component is enabled.
Thanks @cividesk you're correct about motivation 1. I've edited the issue description to reflect the fact that it's been solved and isn't relevant to this issue anymore. The second motivation was actually to be able to package Afforms and SearchKit displays within components, which I think is the best rationale for this proposal. I think what you're talking about would also be a benefit we'd get for free, which is that extensions would finally be able to declare dependencies on components, e.g.
<requires><ext>civievent</ext></requires>
. I've added that as motivation 3. Another reason for going down this path is that it will be the start of a slow transition away from components entirely (I've put that as motivation 4).Here is a PR to add the extensions: https://github.com/civicrm/civicrm-core/pull/26036
- A deleted user
First of all, moving more and more Core code into extensions seems a very good thing.
Unfortunately, we just discovered this after a class naming collision occurred when updating to CiviCRM 5.63 with our extension systopia/de.systopia.campaign (Campaign Manager) installed.
I guess we're way too late to the party for another round of finding unique names for Core component extensions ...
Seems there will be much more "reserved" namespaces with Core moving functionality into extensions. Will there be documentation about that?
Also, please consider making those additions public a bit more noisily, e. g. in a special dev-digest or by informing maintainers of things in Universe, which I think Campaign Manager has long been part of.
Ooooh, the collision is on
CRM_Campaign_ExtensionUtil
because both extensions declare<civix><namespace>CRM/Campaign</namespace></civix>
.One could soften the error a little bit by putting a guard around the
class
declaration, e.g.if (!class_exists('CRM_Campaign_ExtensionUtil')) { class CRM_Campaign_ExtensionUtil { ... } }
That would prevent hard-crashes. (I'd be +1 on updating the template and core-ext so that the problem-scenario is recoverable.) But realistically, one ext or the other needs to change the
<namespace>
and then search/replace theuse
statements.-use CRM_Campaign_ExtensionUtil as E; +use CRM_CampaignManager_ExtensionUtil as E;
(I don't think there are any other clashes. In theory,
CRM_Campaign_Upgrader
could be a conflict-point, but I don't think it's likely since all thecivi_*
stubs are using a special<upgrader>CRM_Extension_Upgrader_Component</upgrader>
.)- Edited by totten
I mean... if we really wanted drop-in compat with the published versions of
de.systopia.campaign
, then one could:- Update
civix
to support an XML flag to override this particular name:<civix> <utilClass>CRM_Campaign_OtherExtensionUtil</utilClass> </civix>
- Add this flag to
ext/civi_*/info.xml
and regenext/civi_*/*.php
.- (AFAICS, the
civi_*
aren't using theE::*
helpers... probably because they're stub-extensions...)
- (AFAICS, the
- Update
See https://github.com/systopia/de.systopia.campaign/pull/111 for a starting point on renaming our namespace.