This is a follow-up from #2633870-9: Revisit defaults for third party settings where pfrenssen suggested

We should at some point in the future take all the constants out of the global space, and put them in a class, so we don't pollute the global space, and can use them like this: SchedulerApi::MY_CONSTANT

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jonathan1055 created an issue. See original summary.

jonathan1055’s picture

Status: Active » Postponed
jonathan1055’s picture

Status: Postponed » Active

Unpostponing now that #2633870: Revisit defaults for third party settings is done. However, it is not an urgent issue, and can be left until more important things are finished.

legovaer’s picture

Assigned: Unassigned » legovaer
legovaer’s picture

Instead of creating a class with constants, I'd suggest to use the configuration API.

legovaer’s picture

Status: Active » Needs review
FileSize
33.58 KB

As I suggested, instead of creating a new Class for these constants, I moved them to our settings as this is the best practice. I also did some other minor changes, here's an overview:

  • Moved all constants defined on scheduler.module to config/install/scheduler.settings.yml
  • Injected the ConfigFactory inside the SchedulerAdminForm
  • Introduced a new helper method SchedulerArdminForm::setting($key) and SchedulerManager::setting($key) which loads $key from the settings file.
  • Updated a codeblock in SchedulerManager::publish() as the reference to both the Exceptions was incorrect.

Status: Needs review » Needs work

The last submitted patch, 6: 2682579-remove-constants-6.patch, failed testing.

legovaer’s picture

Status: Needs work » Needs review
FileSize
35.28 KB
1.61 KB

Added the schema definitions for the new settings.

legovaer’s picture

Anyone who has some time to review this?

jonathan1055’s picture

Good idea to use the existing .schema and .settings.yml files, that's tidier than a separate class. I applied the existing patch manually in parts after adjusting for recent commits. Looks good in general. I made a few changes:

  1. Fixed typo 'default_publish_require' to 'default_publish_required' in scheduler.admin.inc function _scheduler_form_node_type_form_alter()
  2. Fixed typo 'default_publush_revision' to 'default_publish_revision' in schedulerManager.php function publish()
  3. Moved the new items in settings.yml and schema.yml into alphabetical order to match the existing items
  4. In .module scheduler_form_node_form_alter() used $config->get instead of \Drupal::config('scheduler.settings')->get for 'default_expand_fieldset' and 'default_time'
  5. Likewise in scheduler_node_preave() for 'date_format'
  6. in .rules.inc, split the code over two lines for 'default_publish_enable' to match what you did for 'default_unpublish_enable', which improves readability.

New patch and interdiff attached.

I have three questions:
a. Even with the two mis-typed config items there is no runtime error and the tests passed. I guess this is because NULL was returned which has the same effect as the FALSE default value. Is there a way to make this more strict and to fail if trying to get a non-existent name?

b. What is difference between \Drupal::config('scheduler.settings'); as used in most places and $this->configFactory->get('scheduler.settings') as used in SchedulerManager.php?

c. To make the schema and settings .yml files take effect I had to uninstall and re-install the module. This is tedious as it loses all Scheduler settings and data. How can we help our users to do this more smoothly? i.e. what is the better way to replace the loaded configuration with new values to match the .yml files. I guess we could suggest Configuration Inspector as that looks like you may be able to import a .yml file. But there should be an equivalent of 'empty cache' for config so that value are refreshed from the external files.

legovaer’s picture

Thank you for your updates / fixes on this issue!

Here are my remarks on your questions;
a: The test doesn't fail because we don't test if these configuration variables are explicitly set. As you say, by default Drupal will return NULL if the configuration parameter doesn't exist. If we want to make sure that our tests fail as soon as we did some "weird" changes inside the configuration files, we will need to check each configuration parameter inside our unit tests. This can be done quite easily by looping through all our defined configuration paramaters (hard coded of course) and see if they don't return NULL when we try to load them via the configuration API. This will ensure us that our tests will fail as soon as we have some typos or other issues with these parameters.

b: This is a very good example of dependency injection (see https://www.drupal.org/node/2133171). In the SchedulerManager service, we are injecting the ConfigFactory so that we don't need to load the static class. As the ConfigFactory is probably already loaded by other (core) modules, PHP will consume less memory in order to load this class. This is because the class is already loaded inside the memory of the server. As you can see in scheduler.services.yml, we add @config.factory as an argument. If you take a look at core.services.yml you will find a service config.factory using the class Drupal\Core\Config\ConfigFactory. This is the class we are injecting inside our own custom class.
Now that we developed our own service called scheduler.manager, other services can make use of our service by adding @sheduler.manager as an argument in their *.services.yml file. When they do so, they will be able to make use of all our methods without instantiating the class from scratch. Dependency Injection is a design pattern used in various programming languages. More information on that can be found on WikiPedia.
The difference is minimal. \Drupal::config('scheduler.settings'); will actually try to load the service (container) if it is already existing. If it's not existing yet, it will factor a new service and load it into the memory. You can see this in /core/lib/Drupal.php:341. The best practice here is to use Dependency Injection.

c: I can't give you a clear answer on that (yet). I'd suggest that we create a new issue and discuss it over there as this will impact our end users.

jonathan1055’s picture

Thank you for the excellent answers - particularly to (b), which really helps my understanding.

For (a) the tests you propose will check that we have not accidentally messed up the settings.yml and schema.yml files, which is worth it. But I don't see how this can check the specific problem of a typo in a code change patch such as in #8 above. Maybe we can write a test which parses all the source code files to get a unique list of the calls to \Drupal::config('scheduler.settings') and configFactory->get('scheduler.settings') and then tests each of these for a non-NULL return value?

For (c) I have raised issue #2731587: Refresh schema and config settings after upgrading to new version

Back to this actual issue. I think is souds like you are happy with my changes in #10. If so, please mark this RTBC and I will commit it.

legovaer’s picture

Status: Needs review » Reviewed & tested by the community

Looks all good to me, RTBC!

  • jonathan1055 committed 9dc08b2 on 8.x-1.x authored by legovaer
    Issue #2682579 by legovaer, jonathan1055: Move constants out of global...
jonathan1055’s picture

Title: Move constants out of global space into class » Move constants out of global space into settings and schema
Assigned: legovaer » Unassigned
Status: Reviewed & tested by the community » Fixed

Thanks for your effort on this issue, much appreciated.

Did you have any thoughts on my reply to (a) in #12 above, regarding how to trap typos when getting config settings?

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.