Issue / Need

I am doing a migration deriver, which creates a derivative for each active domain, and uses the default configuration, or the domain overriden one if there is one. What i am doing now, is creating manually the configuration id for each domain, and then try to load them individually.

Proposed change / improvement

The "domain.config.overrider" could have a method to be able to load configuration overrides across all domains, not only the active one. Also, it would also be useful to change the method getDomainConfigMethod to public.

Issue fork domain-3409936

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

guiu.rocafort.ferrer created an issue. See original summary.

guiu.rocafort.ferrer’s picture

Status: Active » Needs review

Change the status to needs review.

agentrickard’s picture

I wonder about how we might do this. We do something similar with languages.

* If a language/domain specific config exists, use it.
* Else use the domain config for all languages under that domain.

I wonder if we could just allow prefixes to ignore the domain id portion of the config.

  protected function getDomainConfigName($name, DomainInterface $domain) {
    return [
      'langcode' => 'domain.config.' . $domain->id() . '.' . $this->language->getId() . '.' . $name,
      'domain' => 'domain.config.' . $domain->id() . '.' . $name,
      'langcode-global' => 'domain.config.' . $this->language->getId() . '.' . $name,
      'global' => 'domain.config.' . $name,
    ];
  }

And then we would cascade through in that order, where now we just loop through the first two.

guiu.rocafort.ferrer’s picture

"I wonder if we could just allow prefixes to ignore the domain id portion of the config". I don't think this is possible.

As i see it, the fact that the domain and the language come before the configuration name makes it a bit difficult to retrieve a particular configuration name for all domains. If the configuration names had the format domain.config.{name}.{domain}.{langcode}, then it could be possible to load all overrides for a configuration using the prefix domain.config.{name}, but i guess this might be a big change in the domain_config module...

In this commit ( https://git.drupalcode.org/issue/domain-3409936/-/commit/c82f391bea0e657... ) i added a method that retrieves all domains, and checks the overrides for a particular configuration in all of them. I expanded the method functionality to include language overrides in this one ( https://git.drupalcode.org/issue/domain-3409936/-/commit/341c4227254c684... ).

I don't see how this could be done without loading and iterating over the domains, and in each one, iterating through the languages.

agentrickard’s picture

Category: Feature request » Support request
Status: Needs review » Active
I don't see how this could be done without loading and iterating over the domains, and in each one, iterating through the languages.

We do this by loading the config name first and then checking to see if a matching config file exists. That is, we loop through config names, not domains. So it sounds like what you are looking to do is counter to that logic.

But I am struggling to understand the use-case here.

You want to find all the overrides for each domain -- not at runtime, but during a migration action?

I suspect that what you are doing is a special case that is better handled in the migration code (through a custom service) rather than ported back to the module.

My advice is to use a service decorator to extend / alter the domain_config.overrider service to do what you need within the context of your migration.

Otherwise, we should propose an entirely new service that we could call in order to do this type of operation, because what you are doing -- if I understand correctly -- is not what this service is built for.

In an ideal world, we would use Config Collections (#3060758: Investigate using config collections), but that is a larger task, given that the collection system is largely undocumented.

guiu.rocafort.ferrer’s picture

I think i didn't set my point properly, so i will try again:

Generic issue: I have a specific configuration X. I want to know all the domains that override that specific configuration.

Particular use case: In this specific example i am exposing, i have a configuration that stores some credentials to an external rest api, which i use to import the contents via a migration. Each domain has a different endpoint url, and different credentials. so, i use a deriver to automatically generate a different migration for each domain that has this configuration overriden.

Potential use cases: I can think of some use cases for this, for example cron tasks that perform different actions according to each defined domain overriden configuration.

What i am doing now: I am loading all the domains, and iterating over them, then i call getDomainConfigName for each one, and then check if that configuration name is present or not.

I hope this time i was able to define more clearly the scope of the issue.

agentrickard’s picture

Generic issue:
I have a specific configuration X. I want to know all the domains that override that specific configuration.

Yes, this is great and very clear.

I still think that this request is totally separate from what the domain_config.overrider service is for, so this patch is not valid as written.

domain_config.overrider is an event handler, not a stand-along service. It responds to the `config.factory.override` event, which is normally part of a request bootstrap. It's also tightly coupled to the DomainNegotiator (see initiateContext()), which is request-dependent.

So the overrider service is contextual to the current request in a way that your external migration likely is not. So we would need a new service that would allow that lookup to be more efficient. In versions < Drupal 8. we did something like this inside hook_cron() to account for such use-cases, but I don't think that would work here.

The "best" way to do that is likely to refactor to use config collections, which are supposed to register overrides similar to your use-case, but I don't have time for that.

For the short term, I can see a domain.config.collection service to run this calculation for you, then cache the output for efficiency.

guiu.rocafort.ferrer’s picture

Thanks for the clarification,

I failed to see that this service is not the right place to add this functionality due to the tight coupling with the DomainNegotiator.
Because the use of config collections issue is going to take some time, i agree with adding a new service "domain.config.collection" for this. Later, this service can be reused to perform some operations with the config collections once that is in place.

I will find some time to do this at some point today.

guiu.rocafort.ferrer’s picture

Status: Active » Needs review

I added a new service domain_config.collection ( to be coherent with the module name and the rest of the services ), and added the function there. To avoid repeating code, i made the getDomainConfigName method static, so it can be used from the new service without duplicating the code. I also added a Functional test for the service method.

For some reason i cannot create a merge request for the branch i created, not sure what i should do about that...

guiu.rocafort.ferrer’s picture

Priority: Normal » Major

Changing the issue status to Major as per issue priorities

guiu.rocafort.ferrer’s picture

Assigned: guiu.rocafort.ferrer » Unassigned
guiu.rocafort.ferrer’s picture

Priority: Major » Critical

Changing the issue status to Crital as per issue priorities

agentrickard’s picture

Category: Support request » Feature request
Priority: Critical » Normal
Status: Needs review » Needs work

MR is out of date.

guiu.rocafort.ferrer’s picture

Status: Needs work » Needs review

MR have been updated.

agentrickard’s picture

Status: Needs review » Needs work

Nitpick: The comment "Return config overrides across all ( or ony active ) domains." has unwanted spacing around the ().

Question:

Adding the $language as an argument to getDomainConfigName() is an API change -- though so it making it public and static.

Perhaps we should make a public static wrapper that uses the new arguments without editing the existing method? At the least $language should = NULL by default?

A good test for the approach would be to rewrite the now redundant code in Drupal\domain_config_ui\Config\Config, which does this:

  /**
   * Get the domain config name.
   */
  protected function getDomainConfigName() {
    // Return selected config name.
    return $this->domainConfigUIManager->getSelectedConfigName($this->name);
  }

And that calls Drupal\domain_config_ui\DomainConfigUIManager::getSelectedConfigName

  /**
   * {@inheritdoc}
   */
  public function getSelectedConfigName($name, $omit_language = FALSE) {
    if ($domain_id = $this->getSelectedDomainId()) {
      $prefix = "domain.config.{$domain_id}.";
      if (!$omit_language && $langcode = $this->getSelectedLanguageId()) {
        $prefix .= "{$langcode}.";
      }
      return $prefix . $name;
    }
    return $name;
  }

Though that may not be worth it, since the DomainConfigUIManager uses ids and not objects.

mably’s picture

We might have some name conflict with this issue: #3060758: Investigate using config collections

MR needs to be rebased.

guiu.rocafort.ferrer’s picture

Status: Needs work » Needs review

Hello, i made a new branch because i kind of messed up doing the merge in the original one... sorry about that.

I tried to take a new approach, where i created an auxiliary method in the module file and then it can be called from the new service and the existing overriding one. Since the new method getConfigNamesByDomainAndLanguage only really calling the new method, i thought it would be ok to remove it, since i think it has not been included in any release yet so we are not really doing any API changes from the existing ones.

We could also add it back, but i don't really see the point of it.

mably’s picture

Status: Needs review » Needs work

Made some comments in the MR.

"We must avoid using non object-oriented code as much as possible."

Made that method public static so it can be called from everywhere.

You should avoid using the name "ConfigCollection" as it will be needed when we will switch to using the core config collections.

mably changed the visibility of the branch 3409936-allow-to-load to hidden.

guiu.rocafort.ferrer’s picture

Status: Needs work » Needs review

Changed the class name to DomainConfigUtilities to avoid future conflicts when using config collections.
Added back the method getConfigNamesByDomainAndLanguage as a static method in the class.

mably’s picture

Status: Needs review » Needs work

Comments in MR.

guiu.rocafort.ferrer’s picture

Status: Needs work » Needs review

Should be ready for review now.

mably changed the visibility of the branch 2.0.x to hidden.

mably’s picture

Status: Needs review » Fixed

Have been included in the first beta release of the new Domain Extras module.

mably’s picture

This will need an update to be compatible with the new 3.x version.

guiu.rocafort.ferrer’s picture

Version: 2.0.x-dev » 3.x-dev
Assigned: Unassigned » guiu.rocafort.ferrer
Status: Fixed » Needs work

Targeting now version 3.x-dev using config collections, setting as needs work.

guiu.rocafort.ferrer changed the visibility of the branch 3.x to hidden.

mably’s picture

Assigned: guiu.rocafort.ferrer » Unassigned
Status: Needs work » Closed (won't fix)

@guiu.rocafort.ferrer a new issue should be created on the Domain Extras module page where the previous MR has been merged.

Marking as "Won't fix" as it should be fixed in the Domain Extras module's code.

Just created a new 3.x development branch there.

Now that this issue is closed, please review the contribution record.

As a contributor, attribute any organization helped you, or if you volunteered your own time.

Maintainers, please credit people who helped resolve this issue.

mably’s picture

New issue created in the Domain Extras module: #3544885: Upgrade loadAllDomainOverrides for Domain 3.x compatibility

@guiu.rocafort.ferrer could you have a look at the MR there?