function BigPipe::getPlaceholderOrder

Same name and namespace in other branches
  1. 8.9.x core/modules/big_pipe/src/Render/BigPipe.php \Drupal\big_pipe\Render\BigPipe::getPlaceholderOrder()
  2. 10 core/modules/big_pipe/src/Render/BigPipe.php \Drupal\big_pipe\Render\BigPipe::getPlaceholderOrder()
  3. 11.x core/modules/big_pipe/src/Render/BigPipe.php \Drupal\big_pipe\Render\BigPipe::getPlaceholderOrder()

Gets the BigPipe placeholder order.

Determines the order in which BigPipe placeholders must be replaced.

Parameters

string $html: HTML markup.

array $placeholders: Associative array; the BigPipe placeholders. Keys are the BigPipe placeholder IDs.

Return value

array Indexed array; the order in which the BigPipe placeholders must be sent. Values are the BigPipe placeholder IDs. Note that only unique placeholders are kept: if the same placeholder occurs multiple times, we only keep the first occurrence.

1 call to BigPipe::getPlaceholderOrder()
BigPipe::sendContent in core/modules/big_pipe/src/Render/BigPipe.php
Sends an HTML response in chunks using the BigPipe technique.

File

core/modules/big_pipe/src/Render/BigPipe.php, line 713

Class

BigPipe
Service for sending an HTML response in chunks (to get faster page loads).

Namespace

Drupal\big_pipe\Render

Code

protected function getPlaceholderOrder($html, $placeholders) {
    $fragments = explode('<span data-big-pipe-placeholder-id="', $html);
    array_shift($fragments);
    $placeholder_ids = [];
    foreach ($fragments as $fragment) {
        $t = explode('"></span>', $fragment, 2);
        $placeholder_id = $t[0];
        $placeholder_ids[] = $placeholder_id;
    }
    $placeholder_ids = array_unique($placeholder_ids);
    // The 'status messages' placeholder needs to be special cased, because it
    // depends on global state that can be modified when other placeholders are
    // being rendered: any code can add messages to render.
    // This violates the principle that each lazy builder must be able to render
    // itself in isolation, and therefore in any order. However, we cannot
    // change the way \Drupal\Core\Messenger\MessengerInterface::addMessage()
    // works in the Drupal 8 cycle. So we have to accommodate its special needs.
    // Allowing placeholders to be rendered in a particular order (in this case:
    // last) would violate this isolation principle. Thus a monopoly is granted
    // to this one special case, with this hard-coded solution.
    // @see \Drupal\Core\Render\Element\StatusMessages
    // @see \Drupal\Core\Render\Renderer::replacePlaceholders()
    // @see https://www.drupal.org/node/2712935#comment-11368923
    $message_placeholder_ids = [];
    foreach ($placeholders as $placeholder_id => $placeholder_element) {
        if (isset($placeholder_element['#lazy_builder']) && $placeholder_element['#lazy_builder'][0] === 'Drupal\\Core\\Render\\Element\\StatusMessages::renderMessages') {
            $message_placeholder_ids[] = $placeholder_id;
        }
    }
    // Return placeholder IDs in DOM order, but with the 'status messages'
    // placeholders at the end, if they are present.
    $ordered_placeholder_ids = array_merge(array_diff($placeholder_ids, $message_placeholder_ids), array_intersect($placeholder_ids, $message_placeholder_ids));
    return $ordered_placeholder_ids;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.