Problem/Motivation
When navigating to /admin/structure/salesforce/mappings/manage/{mapping}, the following fatal error is thrown:
Error: Call to a member function render() on string in Drupal\salesforce_mapping_ui\Form\SalesforceMappingFormCrudBase->Drupal\salesforce_mapping_ui\Form\{closure}() (line 527 of modules/contrib/salesforce/modules/salesforce_mapping_ui/src/Form/SalesforceMappingFormCrudBase.php).
uasort(Array, Object) (Line: 526)
Drupal\salesforce_mapping_ui\Form\SalesforceMappingFormCrudBase->getEntityTypeOptions() (Line: 114)
Drupal\salesforce_mapping_ui\Form\SalesforceMappingFormCrudBase->buildForm(Array, Object)
call_user_func_array(Array, Array) (Line: 536)
Drupal\Core\Form\FormBuilder->retrieveForm('salesforce_mapping_edit_form', Object) (Line: 284)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 73)
Drupal\Core\Controller\FormController->getContentResult(Object, Object) (Line: 39)
Drupal\layout_builder\Controller\LayoutBuilderHtmlEntityFormController->getContentResult(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 638)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 121)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 181)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 76)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 53)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 28)
Drupal\Core\StackMiddleware\ContentLength->handle(Object, 1, 1) (Line: 263)
Drupal\shield\ShieldMiddleware->bypass(Object, 1, 1) (Line: 148)
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: 36)
Drupal\Core\StackMiddleware\AjaxPageState->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object, 1, 1) (Line: 741)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
This has been observed in particular when using modules like
ECK β
(Entity Construction Kit), which can cause entity labels to be stored simply as strings rather than TranslatableMarkup.
Steps to reproduce
1. Install and enable ECK contrib module.
2. Create a custom entity type using ECK (e.g., βMy Custom Entityβ).
3. Configure a Salesforce Mapping to map data to this ECK-based entity type.
4. Visit `/admin/structure/salesforce/mappings/manage/{mapping}`.
5. Receive fatal error: "Call to a member function render() on string".
Proposed resolution
Instead of calling $a->render() directly in `SalesforceMappingFormCrudBase::getEntityTypeOptions()`, cast both label objects to strings before comparing. This will handle both string and TranslatableMarkup:
// Old code:
return strcmp($a->render(), $b->render());
// New code:
return strcmp((string) $a, (string) $b);
This ensures the comparison works uniformly for both strings and TranslatableMarkup objects, preventing the fatal error.