Problem/Motivation
Deprecated function Error Message when using CKEeditor5 to upload images.
Steps to reproduce
I ran into this error when saving a node. I had just uploaded an image (in this case a gif) and put in a caption with a link and bolded text. These changes were made successfully despite the error.
Deprecated function: str_contains(): Passing null to parameter #1 ($haystack) of type string is deprecated in Drupal\Component\Transliteration\PhpTransliteration->transliterate() (line 135 of core/lib/Drupal/Component/Transliteration/PhpTransliteration.php).
Drupal\Component\Transliteration\PhpTransliteration->transliterate(NULL, 'en', '_') (Line: 57)
Drupal\filename_transliteration\FilenamePostprocessor->process(NULL) (Line: 17)
filename_transliteration_file_field_values_init(Object)
call_user_func_array(Object, Array) (Line: 409)
Drupal\Core\Extension\ModuleHandler->Drupal\Core\Extension\{closure}(Object, 'filename_transliteration') (Line: 388)
Drupal\Core\Extension\ModuleHandler->invokeAllWith('file_field_values_init', Object) (Line: 416)
Drupal\Core\Extension\ModuleHandler->invokeAll('file_field_values_init', Array) (Line: 215)
Drupal\Core\Entity\EntityStorageBase->invokeHook('field_values_init', Object) (Line: 900)
Drupal\Core\Entity\ContentEntityStorageBase->invokeHook('field_values_init', Object) (Line: 283)
Drupal\Core\Entity\ContentEntityStorageBase->initFieldValues(Object, Array) (Line: 129)
Drupal\Core\Entity\ContentEntityStorageBase->doCreate(Array) (Line: 94)
Drupal\Core\Entity\ContentEntityStorageBase->create(Array) (Line: 1139)
Drupal\Core\Entity\ContentEntityBase::create(Array) (Line: 171)
Drupal\ckeditor5\Controller\CKEditor5ImageController->upload(Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 617)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 182)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 76)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 270)
Drupal\shield\ShieldMiddleware->bypass(Object, 1, 1) (Line: 137)
Drupal\shield\ShieldMiddleware->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object, 1, 1) (Line: 704)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Deprecated function: mb_convert_encoding(): Passing null to parameter #1 ($string) of type array|string is deprecated in Drupal\Component\Transliteration\PhpTransliteration->transliterate() (line 142 of core/lib/Drupal/Component/Transliteration/PhpTransliteration.php).
Drupal\Component\Transliteration\PhpTransliteration->transliterate(NULL, 'en', '_') (Line: 57)
Drupal\filename_transliteration\FilenamePostprocessor->process(NULL) (Line: 17)
filename_transliteration_file_field_values_init(Object)
call_user_func_array(Object, Array) (Line: 409)
Drupal\Core\Extension\ModuleHandler->Drupal\Core\Extension\{closure}(Object, 'filename_transliteration') (Line: 388)
Drupal\Core\Extension\ModuleHandler->invokeAllWith('file_field_values_init', Object) (Line: 416)
Drupal\Core\Extension\ModuleHandler->invokeAll('file_field_values_init', Array) (Line: 215)
Drupal\Core\Entity\EntityStorageBase->invokeHook('field_values_init', Object) (Line: 900)
Drupal\Core\Entity\ContentEntityStorageBase->invokeHook('field_values_init', Object) (Line: 283)
Drupal\Core\Entity\ContentEntityStorageBase->initFieldValues(Object, Array) (Line: 129)
Drupal\Core\Entity\ContentEntityStorageBase->doCreate(Array) (Line: 94)
Drupal\Core\Entity\ContentEntityStorageBase->create(Array) (Line: 1139)
Drupal\Core\Entity\ContentEntityBase::create(Array) (Line: 171)
Drupal\ckeditor5\Controller\CKEditor5ImageController->upload(Object)
Proposed resolution
The contrib module filename_transliteration is building the filename when initializing the entity and the value is null at that point. Then we also have a hook_presave to do basically the same.
From a functional perspective, these hooks are doing different things:
The first is modifying the filename upon entity initialization.
The second is ensuring that before the file entity is saved, if its name has been changed (or will conflict with another file), it gets a new unique name and updates the related URI.
I see some redundancy from the perspective of transliterating the filename twice (once during initialization and once during pre-save). To avoid this issue we can remove the first hook.
Remaining tasks
User interface changes
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| #7 | 3391867-7.patch | 863 bytes | marthinal |
| #2 | 3391867-2.patch | 717 bytes | marthinal |
Issue fork filename_transliteration-3391867
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
marthinal commentedAnd here is the patch
Comment #3
marthinal commentedComment #4
marthinal commentedComment #5
jwilson3Thanks @Jose.
Honestly, I'm a little nervous about removing the hook even if it appears to be executed twice during the various hook phases of uploading a file.
I'm nervous mainly because I wrote the module >6 years ago and there are no code comments that indicate why both transliterations are required but its possible that certain scenarios follow different code paths, that would break backward compatibility if removed.
Is there another approach that we can use to the underlying issue to avoid executing when a value is null?
Comment #6
jwilson3Comment #7
marthinal commentedThanks for reviewing @jwilson3. Okay, in that case we can try something like this.
Comment #8
marthinal commentedComment #9
jwilson3Thanks @marthinal!
I feel more comfortable committing a patch like this. Fundamentally, I think this needs additional testing to truly confirm several things:
For now, I think I'd like to leave this issue open in NR for more time in case others come here and have a chance to lend a hand with more debugging, use cases, and insights. Thanks again.
Comment #12
jwilson3I decided to go ahead and commit this. The approach in #7 is safe. I expanded it to also work with the other function, for consistency and safety.
This will be included in the final release 1.2.0