- Issue created by @Quentin Massez
- Status changed to Needs review
10 months ago 3:54pm 15 February 2024 - π«π·France Quentin Massez
Update, I still have infinite loop with my patch because of the entity->getFields(). We dont need to load all fields because we juste need fields name to get caption on it.
Since the last time, i saw that there is a function _image_field_caption_get_image_field_names to get the image field name, it's called in hook entity update and should also be called in hook entity storage load.Here is the new patch.
- First commit to issue fork.
- πΊπ¦Ukraine Foxy-vikvik
On Drupal 9.3 works fine and fixed the main issue related to the infinity loop. I had infinity loop when generate Sitemaps using module Simple SiteMaps.
- πΊπ¦Ukraine Foxy-vikvik
The best option is to remove hook_entity_storage_load and replace with the custom logic. It has bad impact on the sit performace.
- π©πͺGermany Bruno2
In Drupal 10 (with more than 8k nodes), every page that uses hook_entity_storage_load runs infinite loops. Therefore /admin/content is not available. Cron cannot finish its run and nodes cannot be deleted via the Drupal API. The patches don't help, so it must be limeted to the current node, without load all entities. I dont think that hook_entity_storage_load is the best hook to set or get the values for this field.
- π©πͺGermany Bruno2
Ok, here is a small fix up, please check for the values. I tested it only a little bit:
Rewrite function to get display the values on edit nodes:
function _image_field_caption_widget_process($element, &$form_state, $form) { $entity = NULL; $form_object = $form_state->getFormObject(); if ($form_object instanceof EntityFormInterface) { $entity = $form_object->getEntity(); } if (!$entity) { return $element; } // Get caption from storage $caption = \Drupal::service('image_field_caption.storage')->getCaption( $entity->getEntityTypeId(), $entity->bundle(), $element['#field_name'], $entity->id(), $entity->getRevisionId(), $entity->language()->getId(), $element['#delta'] ); // Add the caption field to the widget $element['image_field_caption'] = [ '#type' => 'text_format', '#title' => t('Caption'), '#default_value' => $caption['caption'] ?? '', '#format' => $caption['caption_format'] ?? 'plain_text', '#weight' => 10, '#required' => $element['#caption_field_required'], '#access' => (bool) $element['#value']['fids'], '#element_validate' => $element['#caption_field_required'] ? ['_image_field_caption_validate_required'] : [], ]; return $element; }
Delete the whole function:
function image_entity_storage_load_field_caption(array $entities, $entity_type_id) {}
And insert this for it:
function image_field_caption_preprocess_field(&$variables) { // Only process image fields if ($variables['element']['#field_type'] !== 'image') { return; } $entity = $variables['element']['#object']; $field_name = $variables['element']['#field_name']; $entity_type = $entity->getEntityTypeId(); $bundle = $entity->bundle(); $entity_id = $entity->id(); $revision_id = $entity->getRevisionId(); $langcode = $entity->language()->getId(); foreach ($variables['items'] as $delta => &$item) { if (!isset($item['content']['#item'])) { continue; } // Get caption using the actual storage service method $caption = \Drupal::service('image_field_caption.storage') ->getCaption( $entity_type, $bundle, $field_name, $entity_id, $revision_id, $langcode, $delta ); if (!empty($caption['caption'])) { $item['content']['caption'] = [ '#type' => 'markup', '#markup' => $caption['caption'], '#format' => $caption['caption_format'], '#weight' => 10, ]; } } }
image_field_caption_entity_insert and image_field_caption_entity_update should also be handled in the widget.
** * Implements hook_form_FORM_ID_alter() */ function MODULE_NAME_form_FORM_ID_alter(&$form, $form_state, $form_id) { $form['submit']['#submit'][] = 'custom_submit_function'; } function custom_submit_function($form, $form_state) { .... }