Conversation
donquixote
left a comment
There was a problem hiding this comment.
some feedback.
I am still undecided if it would be acceptable to simply accept or suppress the deprecated calls. I am trying to find the discussion in drupal.org where this was mentioned.
theme-settings.php
Outdated
| * Implements hook_form_system_theme_settings_alter(). | ||
| */ | ||
| function oe_bootstrap_theme_form_system_theme_settings_alter(&$form, FormStateInterface $form_state) { | ||
| $theme_name = 'oe_bootstrap_theme'; |
There was a problem hiding this comment.
That local variable seems unnecessary.
src/ThemeSettings.php
Outdated
| $service_id = 'Drupal\Core\Extension\ThemeSettingsProvider'; | ||
| $settings_provider = \Drupal::service($service_id); |
There was a problem hiding this comment.
| $service_id = 'Drupal\Core\Extension\ThemeSettingsProvider'; | |
| $settings_provider = \Drupal::service($service_id); | |
| $settings_provider = \Drupal::service(Drupal\Core\Extension\ThemeSettingsProvider::class); |
- no need for local var
- use ::class so that static analysis sees the class name.
There was a problem hiding this comment.
and then use class import
use Drupal\Core\Extension\ThemeSettingsProvider;| $service_id = 'Drupal\Core\Extension\ThemeSettingsProvider'; | |
| $settings_provider = \Drupal::service($service_id); | |
| $settings_provider = \Drupal::service(ThemeSettingsProvider::class); |
src/ThemeSettings.php
Outdated
| if (version_compare(\Drupal::VERSION, self::THEME_SETTINGS_PROVIDER_VERSION, '>=')) { | ||
| $service_id = 'Drupal\Core\Extension\ThemeSettingsProvider'; | ||
| $settings_provider = \Drupal::service($service_id); | ||
| return \call_user_func([$settings_provider, 'getSetting'], $setting, $theme); |
There was a problem hiding this comment.
why call_user_func?
| return \call_user_func([$settings_provider, 'getSetting'], $setting, $theme); | |
| return $settings_provider->getSetting($setting, $theme); |
If you are concerned about static analysis, you can put a /** @var */ doc on the service.
src/ThemeSettings.php
Outdated
| $service_id = 'Drupal\Core\Extension\ThemeSettingsProvider'; | ||
| $settings_provider = \Drupal::service($service_id); | ||
| return \call_user_func([$settings_provider, 'getSetting'], $setting, $theme); |
There was a problem hiding this comment.
if you don't need the local var for the service:
| $service_id = 'Drupal\Core\Extension\ThemeSettingsProvider'; | |
| $settings_provider = \Drupal::service($service_id); | |
| return \call_user_func([$settings_provider, 'getSetting'], $setting, $theme); | |
| return \Drupal::service(ThemeSettingsProvider::class)->getSetting($setting, $theme); |
The local var for the service is useful only if you want to put a /** @var */ doc.
src/ThemeSettings.php
Outdated
| $legacy_getter = 'theme_get_setting'; | ||
| return \call_user_func($legacy_getter, $setting, $theme); |
There was a problem hiding this comment.
| $legacy_getter = 'theme_get_setting'; | |
| return \call_user_func($legacy_getter, $setting, $theme); | |
| // phpcs:ignore <deprecation code> | |
| return theme_get_setting($setting, $theme); |
not sure how that phpcs line needs to look like or if you need it at all.
theme-settings.php
Outdated
| '#title' => t('Style all tables using Bootstrap.'), | ||
| '#description' => t('Applies Bootstrap classes to all tables rendered using this theme. Note that some table instances (such as calendars) might not render correctly when Bootstrap is applied to them.'), | ||
| '#default_value' => theme_get_setting('bootstrap_tables.enable'), | ||
| '#default_value' => ThemeSettings::get('bootstrap_tables.enable', $theme_name), |
There was a problem hiding this comment.
| '#default_value' => ThemeSettings::get('bootstrap_tables.enable', $theme_name), | |
| '#default_value' => ThemeSettings::get('bootstrap_tables.enable', 'oe_bootstrap_theme'), |
But do you even need to pass the theme name at all?
Shouldn't it work without that?
| '#default_value' => ThemeSettings::get('bootstrap_tables.enable', $theme_name), | |
| '#default_value' => ThemeSettings::get('bootstrap_tables.enable'), |
This also helps to support overriding the setting in a subtheme, which I think was the goal of theme_get_setting().
src/ThemeSettings.php
Outdated
There was a problem hiding this comment.
Alternatively we could name this class DrupalCompatibility and the method themeGetSetting(), this was suggested by AI :)
The point would be to add more like this in the future.
it's a bit confusing with the existing class BackwardCompatibility, which is meant not to support old Drupal versions but to solve another kind of problem (not sure how that should work)
src/ThemeSettings.php
Outdated
|
|
||
| $legacy_getter = 'theme_get_setting'; | ||
| return \call_user_func($legacy_getter, $setting, $theme); | ||
| } |
There was a problem hiding this comment.
Actually, something better!
https://www.drupal.org/node/3379306
Can you try this?
use Drupal\Component\Utility\DeprecationHelper;
[...]
return DeprecationHelper::backwardsCompatibleCall(
\Drupal::VERSION,
'11.3',
\Drupal::service(ThemeSettingsProvider::class)->getSetting(...),
theme_get_setting(...),
);
oe_bootstrap_theme.theme
Outdated
| */ | ||
| function _oe_bootstrap_theme_get_setting(string $setting): mixed { | ||
| return ThemeSettings::get($setting, 'oe_bootstrap_theme'); | ||
| } |
There was a problem hiding this comment.
Why this function, instead of calling the static method directly?
src/DrupalCompatibility.php
Outdated
| static function () use ($setting, $theme): mixed { | ||
| return \theme_get_setting($setting, $theme); | ||
| } |
There was a problem hiding this comment.
we can simplify with fn (). Also use trailing comma on last arg.
| static function () use ($setting, $theme): mixed { | |
| return \theme_get_setting($setting, $theme); | |
| } | |
| fn () =>\theme_get_setting($setting, $theme), |
(and same for the other one)
src/DrupalCompatibility.php
Outdated
| static function () use ($setting, $theme): mixed { | ||
| $settings_provider = \Drupal::service('Drupal\Core\Extension\ThemeSettingsProvider'); | ||
| if (is_object($settings_provider) && method_exists($settings_provider, 'getSetting')) { | ||
| return $settings_provider->getSetting($setting, $theme); | ||
| } | ||
|
|
||
| throw new \RuntimeException('ThemeSettingsProvider::getSetting() is not available.'); | ||
| }, |
There was a problem hiding this comment.
No need for all the defensive code.
If we have the correct Drupal version, it will just work. The service won't surprisingly be something we did not expect.
If it is, we will get some kind of error and we will know.
Also always use ::class, not string literal with quotes for a class name. This way an IDE can do "Find usages" etc.
| static function () use ($setting, $theme): mixed { | |
| $settings_provider = \Drupal::service('Drupal\Core\Extension\ThemeSettingsProvider'); | |
| if (is_object($settings_provider) && method_exists($settings_provider, 'getSetting')) { | |
| return $settings_provider->getSetting($setting, $theme); | |
| } | |
| throw new \RuntimeException('ThemeSettingsProvider::getSetting() is not available.'); | |
| }, | |
| fn () => \Drupal::service(ThemeSettingsProvider::class)->getSetting($setting, $theme), |
If there is any problem with phpcs or phpstan when running a different core version, we suppress.
There was a problem hiding this comment.
As a general note: Defensive code is more important when we deal with user data, or with anything that could have different values or states for reasons we do not control.
src/DrupalCompatibility.php
Outdated
| \Drupal::VERSION, | ||
| self::THEME_SETTINGS_PROVIDER_VERSION, | ||
| fn () => \Drupal::service(ThemeSettingsProvider::class)->getSetting($setting, $theme), | ||
| fn () =>\theme_get_setting($setting, $theme), |
There was a problem hiding this comment.
We need a whitespace here.
And the \ backslash is debatable, we typically don't add it.
| fn () =>\theme_get_setting($setting, $theme), | |
| fn () => theme_get_setting($setting, $theme), |
oe_bootstrap_theme.theme
Outdated
| $extra_suggestions[] = 'views_view_table__bootstrap'; | ||
|
|
||
| $responsive = theme_get_setting('bootstrap_tables.responsive'); | ||
| $responsive = DrupalCompatibility::themeGetSetting('bootstrap_tables.responsive', 'oe_bootstrap_theme'); |
There was a problem hiding this comment.
Again, why pass the theme name?
I assume we want the following to work:
- You enable oe_whitelabel, which is a subtheme of oe_bootstrap_theme.
- In oe_whitelabel, you have the same config options available (and more).
- Setting values are stored separately for oe_whitelabel and oe_bootstrap_theme.
- When this function is called while in oe_whitelabel, we want the setting value from oe_whitelabel to be used.
| $responsive = DrupalCompatibility::themeGetSetting('bootstrap_tables.responsive', 'oe_bootstrap_theme'); | |
| $responsive = DrupalCompatibility::themeGetSetting('bootstrap_tables.responsive'); |
There was a problem hiding this comment.
I don't fully remember if this is how these theme settings work, please try it out.
But there is a reason why until now we did not pass along the theme name.
src/BackwardCompatibility.php
Outdated
| */ | ||
| public static function getSetting(string $name): bool { | ||
| return theme_get_setting(self::PREFIX . $name) ?? TRUE; | ||
| return (bool) (DrupalCompatibility::themeGetSetting(self::PREFIX . $name, self::THEME) ?? TRUE); |
There was a problem hiding this comment.
We are still passing the theme name?
There was a problem hiding this comment.
| return (bool) (DrupalCompatibility::themeGetSetting(self::PREFIX . $name, self::THEME) ?? TRUE); | |
| return (bool) (DrupalCompatibility::themeGetSetting(self::PREFIX . $name) ?? TRUE); |
src/BackwardCompatibility.php
Outdated
| * The theme where backward compatibility settings are stored. | ||
| */ | ||
| private const THEME = 'oe_bootstrap_theme'; | ||
|
|
theme-settings.php
Outdated
| '#title' => t('Style all tables using Bootstrap.'), | ||
| '#description' => t('Applies Bootstrap classes to all tables rendered using this theme. Note that some table instances (such as calendars) might not render correctly when Bootstrap is applied to them.'), | ||
| '#default_value' => theme_get_setting('bootstrap_tables.enable'), | ||
| '#default_value' => DrupalCompatibility::themeGetSetting('bootstrap_tables.enable', 'oe_bootstrap_theme'), |
There was a problem hiding this comment.
| '#default_value' => DrupalCompatibility::themeGetSetting('bootstrap_tables.enable', 'oe_bootstrap_theme'), | |
| '#default_value' => DrupalCompatibility::themeGetSetting('bootstrap_tables.enable'), |
theme-settings.php
Outdated
| ], | ||
| '#empty_option' => t('Never'), | ||
| '#default_value' => theme_get_setting('bootstrap_tables.responsive') ?? '', | ||
| '#default_value' => DrupalCompatibility::themeGetSetting('bootstrap_tables.responsive', 'oe_bootstrap_theme') ?? '', |
There was a problem hiding this comment.
| '#default_value' => DrupalCompatibility::themeGetSetting('bootstrap_tables.responsive', 'oe_bootstrap_theme') ?? '', | |
| '#default_value' => DrupalCompatibility::themeGetSetting('bootstrap_tables.responsive') ?? '', |
theme-settings.php
Outdated
| '#title' => t('Style all tables using Bootstrap.'), | ||
| '#description' => t('Applies Bootstrap classes to all tables rendered using this theme. Note that some table instances (such as calendars) might not render correctly when Bootstrap is applied to them.'), | ||
| '#default_value' => theme_get_setting('bootstrap_tables.enable'), | ||
| '#default_value' => DrupalCompatibility::themeGetSetting('bootstrap_tables.enable'), |
There was a problem hiding this comment.
It seems we need to remove this line for correct behavior. Drupal ConfigFormBase will auto fill the setting. To be confirmed if this works in Drupal 10, I think it should.
| '#default_value' => DrupalCompatibility::themeGetSetting('bootstrap_tables.enable'), |
There was a problem hiding this comment.
Compare how core themes do it, e.g. olivero/theme-settings.php
Jira issue(s):