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

CommentFileSizeAuthor
#7 3391867-7.patch863 bytesmarthinal
#2 3391867-2.patch717 bytesmarthinal
Command icon 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

marthinal created an issue. See original summary.

marthinal’s picture

StatusFileSize
new717 bytes

And here is the patch

marthinal’s picture

Issue summary: View changes
marthinal’s picture

Issue summary: View changes
jwilson3’s picture

Thanks @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?

jwilson3’s picture

Status: Needs review » Needs work
marthinal’s picture

StatusFileSize
new863 bytes

Thanks for reviewing @jwilson3. Okay, in that case we can try something like this.

marthinal’s picture

Status: Needs work » Needs review
jwilson3’s picture

Thanks @marthinal!

I feel more comfortable committing a patch like this. Fundamentally, I think this needs additional testing to truly confirm several things:

  1. We still don't have a clear picture why this hook was added so many years ago, and whether it could be safely removed. We must figure out if there is codepath where we need both hooks (eg. because the second doesn't get executed). One approach would be to just remove the first hook (as the patch in #2 does) and let the community upgrade and report back if more issues are found. This is one way to ensure the open source advances, but OTOH it seems very imprudent approach, with over 1000+ installs of the module it could end up breaking many sites, which seems more harmful and self-serving than helpful.
  2. We need to verify whether str_contains null parameter warning always happens in all cases of file uploads or if this ONLY affects the CKEditor 5 uploads. Having this insight will help indicate whether this might be a larger upstream Drupal core issue to report. We can use a step debugger outside CKEditor 5 on normal file upload fields on nodes, media entities, and perhaps in theme settings > logo/favicon field and the user picture field, in order to test this.

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.

  • jwilson3 committed 661e9adb on 1.1.x
    Issue #3391867 by marthinal, jwilson3: Deprecated function Error Message...
jwilson3’s picture

Status: Needs review » Fixed

I 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

Status: Fixed » Closed (fixed)

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