Skip to content

OEL-4511: Update to Drupal 11.3.x.#541

Open
tibi2303 wants to merge 5 commits into1.xfrom
OEL-4511
Open

OEL-4511: Update to Drupal 11.3.x.#541
tibi2303 wants to merge 5 commits into1.xfrom
OEL-4511

Conversation

@tibi2303
Copy link
Contributor

@tibi2303 tibi2303 commented Mar 3, 2026

Jira issue(s):

Copy link
Contributor

@donquixote donquixote left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

* 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';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That local variable seems unnecessary.

Comment on lines +31 to +32
$service_id = 'Drupal\Core\Extension\ThemeSettingsProvider';
$settings_provider = \Drupal::service($service_id);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and then use class import

use Drupal\Core\Extension\ThemeSettingsProvider;
Suggested change
$service_id = 'Drupal\Core\Extension\ThemeSettingsProvider';
$settings_provider = \Drupal::service($service_id);
$settings_provider = \Drupal::service(ThemeSettingsProvider::class);

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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why call_user_func?

Suggested change
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.

Comment on lines +31 to +33
$service_id = 'Drupal\Core\Extension\ThemeSettingsProvider';
$settings_provider = \Drupal::service($service_id);
return \call_user_func([$settings_provider, 'getSetting'], $setting, $theme);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you don't need the local var for the service:

Suggested change
$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.

Comment on lines +36 to +37
$legacy_getter = 'theme_get_setting';
return \call_user_func($legacy_getter, $setting, $theme);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$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.

'#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),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'#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?

Suggested change
'#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().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)


$legacy_getter = 'theme_get_setting';
return \call_user_func($legacy_getter, $setting, $theme);
}
Copy link
Contributor

@donquixote donquixote Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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(...),
    );

*/
function _oe_bootstrap_theme_get_setting(string $setting): mixed {
return ThemeSettings::get($setting, 'oe_bootstrap_theme');
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this function, instead of calling the static method directly?

Comment on lines +42 to +44
static function () use ($setting, $theme): mixed {
return \theme_get_setting($setting, $theme);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can simplify with fn (). Also use trailing comma on last arg.

Suggested change
static function () use ($setting, $theme): mixed {
return \theme_get_setting($setting, $theme);
}
fn () =>\theme_get_setting($setting, $theme),

(and same for the other one)

Comment on lines +34 to +41
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.');
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

\Drupal::VERSION,
self::THEME_SETTINGS_PROVIDER_VERSION,
fn () => \Drupal::service(ThemeSettingsProvider::class)->getSetting($setting, $theme),
fn () =>\theme_get_setting($setting, $theme),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a whitespace here.
And the \ backslash is debatable, we typically don't add it.

Suggested change
fn () =>\theme_get_setting($setting, $theme),
fn () => theme_get_setting($setting, $theme),

$extra_suggestions[] = 'views_view_table__bootstrap';

$responsive = theme_get_setting('bootstrap_tables.responsive');
$responsive = DrupalCompatibility::themeGetSetting('bootstrap_tables.responsive', 'oe_bootstrap_theme');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Suggested change
$responsive = DrupalCompatibility::themeGetSetting('bootstrap_tables.responsive', 'oe_bootstrap_theme');
$responsive = DrupalCompatibility::themeGetSetting('bootstrap_tables.responsive');

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

*/
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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are still passing the theme name?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return (bool) (DrupalCompatibility::themeGetSetting(self::PREFIX . $name, self::THEME) ?? TRUE);
return (bool) (DrupalCompatibility::themeGetSetting(self::PREFIX . $name) ?? TRUE);

* The theme where backward compatibility settings are stored.
*/
private const THEME = 'oe_bootstrap_theme';

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should not be needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

'#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'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'#default_value' => DrupalCompatibility::themeGetSetting('bootstrap_tables.enable', 'oe_bootstrap_theme'),
'#default_value' => DrupalCompatibility::themeGetSetting('bootstrap_tables.enable'),

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

],
'#empty_option' => t('Never'),
'#default_value' => theme_get_setting('bootstrap_tables.responsive') ?? '',
'#default_value' => DrupalCompatibility::themeGetSetting('bootstrap_tables.responsive', 'oe_bootstrap_theme') ?? '',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'#default_value' => DrupalCompatibility::themeGetSetting('bootstrap_tables.responsive', 'oe_bootstrap_theme') ?? '',
'#default_value' => DrupalCompatibility::themeGetSetting('bootstrap_tables.responsive') ?? '',

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

'#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'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
'#default_value' => DrupalCompatibility::themeGetSetting('bootstrap_tables.enable'),

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compare how core themes do it, e.g. olivero/theme-settings.php

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants