Score:0

Is possible to find the "original" route while executing code from a widget?

br flag

I'm on D9.

I've a node edit form with a media field using the media library widget.

When a new media is added I'd need to run some custom code to replace one token, of the media path location, depending on the value of the node itself.

However, the route available with \Drupal::routeMatch() is media_library.ui and there is no node object available

I suppose this is correct, as the code is execute during the request "inside the media library widget".

Thus, i'm trying to find if is possibile somehow to get the "main\original" request from in that moment and the relative node object or if it is impossible. In the latter case, do you have idea if that objective is somehow possible?

apaderno avatar
us flag
To make the question helpful to future readers, you should show the code you are using and make clear which hook you are using and which form you are trying to alter. The question seems about a node edit form, but then it says that `\Drupal::routeMatch()` returns `'media_library.ui'`, which isn't the route for a node edit form.
apaderno avatar
us flag
I guess that what described would be possible when the field widget is using AJAX.
Giuseppe avatar
br flag
@apaderno for now I haven't yet a defined code to show, I'm debugging directly inside `token_tokens` because I'm trying to see if this patch is working https://www.drupal.org/project/token/issues/919760 with my use case. As I said, the route is not the one of the node edit form, because the code "runs" during the media insert, which is inside the "media widget modal"
Score:2
us flag

To alter a widget form, Drupal invokes these hooks.

In both the cases, you can get the node to which the field using the Media library widget is attached using with code similar to the following one.

if ($context['widget']->getPluginId() == 'media_library_widget') {
  $field_definition = $context['items']->getFieldDefinition();
  if ($field_definition->getTargetEntityTypeId() == 'node') {
    $node = $context['items']->getEntity();
    // Use $node.
  }
}

If you are instead trying to alter the value of a token when it's used for that widget, that isn't possible, since the hook to alter the tokens (hook_tokens_alter()) only knows for which entity type the token is requested ($context['type']) and for which entity object ($context['data'][$context['type']]).

Score:0
cn flag

Here is my code which does a similar job - extracting the node from the entity browser parameters (However I am not sure which media path location are you going to change).

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function my_module_form_entity_browser_media_entity_browser_modal_form_alter(&$form, FormStateInterface $form_state) {
  // @todo Move that code to ClassResolver.
  /** @var \Drupal\entity_browser\Form\EntityBrowserForm $form_object */
  $form_object = $form_state->getFormObject();
  $eb = $form_object->getEntityBrowser();
  $eb_params = $eb->getAdditionalWidgetParameters();
  if (!isset($eb_params["path_parts"][1]) || !isset($eb_params["path_parts"][2])) {
    return;
  }

  if (!is_numeric($eb_params["path_parts"][2])) {
    return;
  }

  $params = [];
  try {
    $params = Url::fromUserInput(implode('/', $eb_params["path_parts"]))->getRouteParameters();
  }
  catch (Exception $exception) {
    Drupal::messenger()->addError($exception->getMessage());
  }

  $node = NULL;
  if (isset($params['node'])) {
    $node = Node::load($params['node']);
  }

  $group = NULL;
  if (isset($params['group'])) {
    $group = Group::load($params['group']);
  }

  if (empty($node) && empty($group)) {
    return;
  }

  $labels = [];
  $group_links = [];
  $group_urls = [];
  $gids = [];
  $gid = NULL;
  $form['#attributes']['data-parent_node'] = NULL;

  switch (!$node ? 'group' : 'node') {
    case 'group':
      $gid = $group->id();
      break;
    case 'node':
      $group_contents = GroupContent::loadByEntity($node);
      foreach ($group_contents as $group_content) {
        $group = $group_content->getGroup();
        $gids[] = $group->id();
        $labels[] = $group->label();
        $group_urls[] = $group->toUrl()->toString();
        $group_links[] = $group->toLink($group->label())->toString();
      }

      $form['#attributes']['data-parent_node'] = $node->id();

      $gid = reset($gids);
      break;
  }

  $form['#attributes']['data-parent_group_names'] = json_encode($labels);
  $form['#attributes']['data-parent_group_urls'] = json_encode($group_urls);
  $form['#attributes']['data-parent_group_links'] = json_encode($group_links);
  $form['#attributes']['data-parent_group_ids'] = json_encode($gids);
  $form['#attributes']['data-parent_group_id'] = $gid;
}
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.