Problem/Motivation
This issue was originally brought into focus when PHP 8.1 was introduced.
Error message when enabling modules:
Deprecated function: mb_strtolower(): Passing null to parameter #1 ($string) of type string is deprecated in Drupal\Core\Config\Entity\Query\Condition->compile() (line 39 of core/lib/Drupal/Core/Config/Entity/Query/Condition.php).
Drupal\Core\Config\Entity\Query\Condition->compile(Array) (Line: 85)
Drupal\Core\Config\Entity\Query\Query->execute() (Line: 301)
Drupal\Core\Config\Entity\ConfigEntityBase->preSave(Object) (Line: 124)
Drupal\language\Entity\ConfigurableLanguage->preSave(Object) (Line: 562)
Drupal\Core\Entity\EntityStorageBase->doPreSave(Object) (Line: 517)
Drupal\Core\Entity\EntityStorageBase->save(Object) (Line: 253)
Drupal\Core\Config\Entity\ConfigEntityStorage->save(Object) (Line: 339)
Drupal\Core\Entity\EntityBase->save() (Line: 607)
Drupal\Core\Config\Entity\ConfigEntityBase->save() (Line: 392)
Drupal\Core\Config\ConfigInstaller->createConfiguration('', Array) (Line: 99)
Drupal\features\FeaturesConfigInstaller->createConfiguration('', Array) (Line: 152)
Drupal\Core\Config\ConfigInstaller->installDefaultConfig('module', 'ldp_translation') (Line: 327)
Drupal\Core\Extension\ModuleInstaller->install(Array, 1) (Line: 83)
Drupal\Core\ProxyClass\Extension\ModuleInstaller->install(Array) (Line: 175)
Drupal\system\Form\ModulesListConfirmForm->submitForm(Array, Object)
call_user_func_array(Array, Array) (Line: 114)
... snippedSteps to reproduce
Using a supported version of PHP such as 8.1/8.2/8.3/8.4
Enable some custom or contrib module that has configs to install and the config somehow results in a null uuid. After the module is enabled, the error message will be displayed.
RELATED ISSUES LINKED:
- #3312252: Unique Field Ajax php 8.1 - Deprecated functions mb_strtolower and addcslashes
- #3374182: Deprecated mb_strtolower triggered from layout_builder PHP 8.1
- #3301692: mb_strtolower(): Passing null to parameter #1 ($string) of type string is deprecated with PHP 8.1
- #3369127: 'filter.format.' . WebformHtmlEditor::DEFAULT_FILTER_FORMAT missing UUID
- #3408809: Fix PHP 8.2+ Drupal Core issues by resolving deprecated function occurrences involving the passing of null
Release notes snippet
Make core more resilient to null uuids when using recent versions of PHP
We have a proven tests only failure.
The solution passes the new test.
| Comment | File | Size | Author |
|---|---|---|---|
| #67 | 3302838-67.patch | 6.84 KB | jlockhart |
| #62 | 3302838-61.patch | 713 bytes | hfernandes |
| #25 | 3302838-25.patch | 811 bytes | joegraduate |
| #13 | 3302838-13.patch | 809 bytes | catch |
| #11 | 3302838.patch | 808 bytes | catch |
Issue fork drupal-3302838
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
Comment #2
ciprian.stavovei commentedComment #3
fagoI'm not convinced that we should turn NULL into "" here.
It seems to me the better fix would be to exclude the NULL case from mbstring in the if like
> elseif (!is_bool($condition['value']) && isset($condition['value']))
?
Comment #4
ravi.shankar commentedMade changes as per comment #3, please review.
Comment #5
ciprian.stavovei commentedAdded another patch to set the condition value to NULL when no condition is met so that the final result stays the same as before.
Comment #6
fago+ elseif (!is_bool($condition['value']) && isset($condition['value'])) {
$condition['value'] = mb_strtolower($condition['value']);
}
+ else {
+ $condition['value'] = NULL;
+ }
this fails if the value is bool. but when $condition['value'] is already NULL it's not necessary to assign it, so just keeping $condition['value'] and having no else {} part should be fine then?
Comment #7
ciprian.stavovei commentedThat's right. It should be disregarded.
Comment #8
fagoPatch of #7 seems to be wrong if value is FALSE.
Actually, I think patch #4 is correct. if no massaging of the value is necessary, no else {} clause is necessary. Right?
Comment #9
ciprian.stavovei commentedYes, patch #4 is the correct one. In comment #7 I hid patch #5 because it is not correct.
Comment #10
fagoagreed, so #4 is the right fix. I verified it solves the issue as well, so all good then.
Comment #11
catchIt looks a little odd to me to check isset() after is_bool(), what about this?
Comment #12
ravi.shankar commentedSetting back to needs work as patch #11 fails.
Comment #13
catchWhoops this time without the syntax error.
Comment #14
ericdsd commentedThanks, #13 fixed the issue on 9.4.5.
Comment #15
heni_deepak commented#13 fixed my issue on 9.5.0-dev
but I have faced issues after adding
TypeError: mb_strtolower(): Argument #1 ($string) must be of type string, array given in mb_strtolower() (line 174 of core/lib/Drupal/Core/Config/Entity/Query/Condition.php).
$block_ids = \Drupal::entityQuery('block')->condition('third_party_settings', Null, '<>')->execute();Comment #16
jungleRe #15 try
$block_ids = \Drupal::entityQuery('block')->condition('third_party_settings', 'IS NOT NULL')->execute();instead?#13 fixed testPostUpdateTaxonomyIndexFilterMultipleVocabularies() in the patch in comment #212 of issue #2784233: Allow multiple vocabularies in the taxonomy filter
+1
#13 looks good to me.
Comment #17
jungle#3301692: mb_strtolower(): Passing null to parameter #1 ($string) of type string is deprecated with PHP 8.1 is a duplicate of this?
Comment #18
alexpottWhen we had these errors while prepping for PHP 8 we tracked them back to the caller. This error is pointing something else being amiss and not as expected.
Comment #19
jungle>#13 fixed testPostUpdateTaxonomyIndexFilterMultipleVocabularies() in the patch in comment #212 of issue #2784233: Allow multiple vocabularies in the taxonomy filter
FYI, found that it's the view for testing in which the `uuid` is missing, the patch here is no more required.
Judged by the issue summary, the deprecated message was raised while installing a non-core module: `ldp_translation`, per @alexpott's comment, is this a won't fix? Setting back to NR for opinions.
Comment #20
smustgrave commentedClosed as a duplicate https://www.drupal.org/project/drupal/issues/3301692#comment-14802752 moving over credit.
Comment #21
extexan commentedAlthough the patch in #13 fixed the error for me, while stepping through in debug, I noticed the array_map in line 36 is running against this value:
When value is not an array, the elseif at line 38 is checking is_bool(), and skipping the mb_strtolower() if it is. Should it be skipped in line 36 as well?
Comment #23
smustgrave commentedHave to be in agreement with @jungle in #19. Seems this patch was just covering a symptom but the cause has been fixed.
If anyone disagrees please reopen with an explanation why.
Thanks!
Comment #24
heddnI wonder if closing won't fix is quite what we want to do? Could we complain more loudly or do something to help track down these issues? I regularly see these warnings in test runs and its a bear to figure out where the null is coming from. Being more loud in our logging of the source would be really nice.
Comment #25
joegraduateWe're seeing these warnings show up in various contexts when using exported configuration entities provided by custom modules in
config/installdirectories that do not have UUIDs. It looks like theDrupal\Core\Config\Entity\ConfigEntityBase::preSave()method usesDrupal\Core\Entity\EntityBase::uuid()when creating query conditions which returnsNULLif a UUID doesn't exist.The attached patch changes those NULL values into empty strings in
Drupal\Core\Config\Entity\ConfigEntityBase::preSave()to prevent them from getting passed as query condition values.Comment #26
smustgrave commentedThe issue summary should be updated with the new proposed solution.
Will also require a test case to show the problem.
Comment #28
joseph.olstadGot this notice/warning in D10 using php 8.1 when switching text format from ckeditor5 to ckeditor4
patch 25 resolves the issue.
Comment #29
lucian.ilea commentedHi!
I confirm that #13 fixed the issue for me on Drupal 9.5.9 with php 8.1.
Thank you!
Comment #30
heddnPart of why this is becoming an issue, more and more is because of #3369127: 'filter.format.' . WebformHtmlEditor::DEFAULT_FILTER_FORMAT missing UUID.
Comment #33
Ajeet Tiwari commentedkindly review the patch.
Comment #34
smustgrave commentedStill needs tests and issue summary update
Comment #35
suryabhi commentedPlease review the Patch
Comment #36
suryabhi commentedAdded a new patch. Fixing build issue. Please review
Comment #37
suryabhi commentedComment #38
mrinalini9 commentedRerolled patch #36, please review it.
Thanks!
Comment #39
smustgrave commentedThank you for the interest but please read the tags. Previously tagged for issue summary update and tests.
Also the MR is on the correct branch and should continue there.
Comment #40
joseph.olstad"Needs tests"
Comment #41
suryabhi commentedComment #42
smustgrave commentedStill needs a test.
Comment #43
BBaptiste commentedMerge request !4263 fixed my issue on Drupal 10.1.2 (PHP 8.1.14 / MySQL 5.7.29)
Thanks.
Comment #44
bjc2265 commentedI've been unable to reproduce this by enabling modules. Attempted several contrib modules (including ckeditor 4 and 5) in fresh Drupal 10.1.x install.
Comment #45
joseph.olstad@bjc2265, are you using PHP 8.0 or PHP 8.1+ ?
This fix is for PHP 8.1+
Comment #46
bjc2265 commentedUsing PHP 8.1.8 and Drupal 10.1.4
Just to confirm: message should appear in GUI after going to Extend tab, selecting a module that changes configuration (such as Configuration Translation or Content Translation) and clicking Install? Because doing that on fresh install I'm not seeing error in logs or as alert.
Comment #48
prabuela commentedComment #49
prabuela commentedComment #50
eiriksmI don't know how to do test only patches with gitlab. I also was not able to "claim" push access to the fork
Anyway. Here is a test only patch, please feel free to add to the fork
Comment #51
smustgrave commentedIf you click "Get push access" there's an option on the pipeline https://git.drupalcode.org/issue/drupal-3302838/-/pipelines/56031
There you can click "Test-only feature"
Current MR appears to have test failures.
Was previously tagged for issue summary too as some sections appear to be missing.
Comment #52
eiriksmI did click the "get push access" and have done so many times before as well. But some hiccup today probably? Tried again now, and now it works :)
Let me try to rebase and get the test only thing in there as well, never tried that before.
Leaving on NW for the issue summary part
Comment #53
smustgrave commentedNow will say there's a bug/feature being worked out where if the MR is opened by a core committer, even getting push access you can't run the test-only feature or rerun any tests.
Comment #54
eiriksmright. was probably just a hiccup I guess, since both work now.
Link to test-only run: https://git.drupalcode.org/issue/drupal-3302838/-/jobs/799034
Comment #55
smustgrave commentedRemoving tests tag
Comment #56
joseph.olstadComment #57
joseph.olstadupdated issue summary
Comment #58
joseph.olstadComment #59
alexpottAs per #18 this is fixing the symptom and not the cause. If a config entity is missing a UUID then a module is doing something wrong. The configuration is not valid.
Comment #62
hfernandes commentedI am adding another related issue as the solutions are the same.
I'm updating the MR to include the
is_stringvalidation since the functionmb_strtolowerexpects a string as parameter.Comment #63
smustgrave commentedAppears to have test failures.
Comment #65
eric_a commentedAdding a related contrib issue, from CAPTCHA module.
From #3497314-6: Tests are failing for Drupal 11.1:
Comment #66
rajab natshahComment #67
jlockhartJust adding a new patch from the latest MR.