Score:0

Programatically reorder referenced entities by field

es flag
gr8

I have a content type Speaker that uses an Event content type as reference. The Event has a start date and time field. There can be any number of events that a speaker speaks at, when visiting the speaker page, the events are not ordered by date, they are ordered by id. How do I programmatically change this?

I am able to get the field value and sort them by date, but I am not able to set them back to the variable.

Related Drupal API Link

use \Drupal\Component\Utility\SortArray;


function mytheme_preprocess_node__speaker_page(&$variables) {
  $node = $variables['node'];
  $entity_ids = [];
  if ($node) {
    if (isset($node->field_events)) {
      $items = $node->field_events; //entity reference
      $unsorted=array();
      foreach ($items as $item) {
        $target_id = $item->target_id;
        $field_event = $item->entity;
        //creating a new unsorted array with the target id and event date, this is used for sorting
        array_push($unsorted, array('target_id' => $target_id, 'event_date' => strtotime($field_event->field_date_of_event->value)));
      }
      //sorting
      usort($unsorted, function ($a, $b) {
        return SortArray::sortByKeyInt($a, $b, 'event_date');
      });
      //sorted ids
      $new_entity_ids = array_column($unsorted, 'target_id');

      $items_new = \Drupal\node\Entity\Node::loadMultiple($new_entity_ids);
      $variables['node']->field_events = $items_new; //this doesn't work
      //$variables['node']->set($field_name)->referencedEntities(); 
    }
  }
}
Kevin avatar
in flag
You still have to change the order in the render array for this to have an effect on the output.
Kevin avatar
in flag
Wouldn't it be easier to drop this logic into a field formatter?
Jaypan avatar
de flag
That's where I would do it.
es flag
gr8
thanks @Kevin sorry I am kind of new to this, from what I understand, I will need to create a custom field formatter that sorts the referenced entities by event date and then set that field formatter for the referenced entities field in the display of the speaker content type, am I right? Wouldn't that be a longer and a time consuming way to do it? I was trying to do a quicker way since it is just a sort.
Kevin avatar
in flag
The problem is you don't really want to deal with render array manipulation here, and the moment you want to show this field anywhere else, you will have to do the code again in another place. Field Formatters are re-usable.
es flag
gr8
Makes sense, thanks @Kevin
4uk4 avatar
cn flag
Similar discussion about manipulating the referenced entity list in a field formatter including a code example: https://drupal.stackexchange.com/questions/294728/filter-the-list-of-entities-referenced-by-entity-reference-revisions-field
4uk4 avatar
cn flag
For a no-code solution you can use https://www.drupal.org/project/eva
es flag
gr8
yes, I am creating a field formatter, thanks @4k4
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.