addAttachments example

return $meta;
  }

  /** * {@inheritdoc} */
  public function addCacheableDependency($other_object) {
    parent::addCacheableDependency($other_object);

    if ($other_object instanceof AttachmentsInterface) {
      $this->addAttachments($other_object->getAttachments());
    }

    return $this;
  }

  /** * Merges two attachments arrays (which live under the '#attached' key). * * The values under the 'drupalSettings' key are merged in a special way, to * match the behavior of: * * @code * jQuery.extend(true, {}, $settings_items[0], $settings_items[1], ...) * @endcode * * This means integer indices are preserved just like string indices are, * rather than re-indexed as is common in PHP array merging. * * Example: * @code * function module1_page_attachments(&$page) { * $page['a']['#attached']['drupalSettings']['foo'] = ['a', 'b', 'c']; * } * function module2_page_attachments(&$page) { * $page['#attached']['drupalSettings']['foo'] = ['d']; * } * // When the page is rendered after the above code, and the browser runs the * // resulting <SCRIPT> tags, the value of drupalSettings.foo is * // ['d', 'b', 'c'], not ['a', 'b', 'c', 'd']. * @endcode * * By following jQuery.extend() merge logic rather than common PHP array merge * logic, the following are ensured: * - Attaching JavaScript settings is idempotent: attaching the same settings * twice does not change the output sent to the browser. * - If pieces of the page are rendered in separate PHP requests and the * returned settings are merged by JavaScript, the resulting settings are * the same as if rendered in one PHP request and merged by PHP. * * @param array $a * An attachments array. * @param array $b * Another attachments array. * * @return array * The merged attachments array. */
$twig = new Environment($loader[
      'debug' => TRUE,
      'cache' => FALSE,
      'autoescape' => 'html',
      'optimizations' => 0,
    ]);

    $twig->addExtension($this->systemUnderTest);
    $link = new GeneratedLink();
    $link->setGeneratedLink('<a href="http://example.com"></a>');
    $link->addCacheTags(['foo']);
    $link->addAttachments(['library' => ['system/base']]);

    $this->renderer->expects($this->atLeastOnce())
      ->method('render')
      ->with([
        "#cache" => [
          "contexts" => [],
          "tags" => ["foo"],
          "max-age" => -1,
        ],
        "#attached" => ['library' => ['system/base']],
      ]);
    
$mail->setSubject($mailData['subject']);

        $mail->setFrom($mailData['fromMail']$mailData['fromName']);
        $mail->addTo($mailData['to']);

        if ($mailData['isHtml']) {
            $mail->setBodyHtml($mailData['bodyHtml']);
        } else {
            $mail->setBodyText($mailData['bodyText']);
        }
        $mail = $this->addAttachments($mail$orderId$mailData['attachments']);

        $mail->setAssociation(LogEntryBuilder::ORDER_ID_ASSOCIATION, $orderId);

        $this->get('modules')->Order()->sendStatusMail($mail);

        $this->View()->assign([
            'success' => true,
            'data' => $data,
        ]);
    }

    

class FilterTestAssets extends FilterBase {

  /** * {@inheritdoc} */
  public function process($text$langcode) {
    $result = new FilterProcessResult($text);
    $result->addAttachments([
      'library' => [
        'filter/caption',
      ],
    ]);
    return $result;
  }

}

  public function testAddAttachments(BubbleableMetadata $initial$attachments, BubbleableMetadata $expected) {
    $test = $initial;
    $test->addAttachments($attachments);
    $this->assertEquals($expected$test);
  }

  /** * Provides test data for testAddAttachments(). */
  public function providerTestAddAttachments() {
    return [
      [new BubbleableMetadata()[]new BubbleableMetadata()],
      [new BubbleableMetadata()['library' => ['core/foo']](new BubbleableMetadata())->setAttachments(['library' => ['core/foo']])],
      [(new BubbleableMetadata())->setAttachments(['library' => ['core/foo']])['library' => ['core/bar']](new BubbleableMetadata())->setAttachments(['library' => ['core/foo', 'core/bar']])],
    ];

  public function createPlaceholder($callback, array $args) {
    // Generate placeholder markup.     // @see \Drupal\Core\Render\PlaceholderGenerator::createPlaceholder()     $arguments = UrlHelper::buildQuery($args);
    $token = Crypt::hashBase64(serialize([$callback$args]));
    $placeholder_markup = '<drupal-filter-placeholder callback="' . Html::escape($callback) . '" arguments="' . Html::escape($arguments) . '" token="' . Html::escape($token) . '"></drupal-filter-placeholder>';

    // Add the placeholder attachment.     $this->addAttachments([
      'placeholders' => [
        $placeholder_markup => [
          '#lazy_builder' => [$callback$args],
        ],
      ],
    ]);

    // Return the placeholder markup, so that the filter wanting to use a     // placeholder can actually insert the placeholder markup where it needs the     // placeholder to be replaced.     return $placeholder_markup;
  }
->addCacheableDependency(CacheableMetadata::createFromRenderArray($element));

      // Modules and themes implementing hook_media_oembed_iframe_preprocess()       // can add additional #cache and #attachments to a render array. If this       // occurs, the render context won't be empty, and we need to ensure the       // added metadata is bubbled up to the response.       // @see \Drupal\Core\Theme\ThemeManager::render()       if (!$context->isEmpty()) {
        $bubbleable_metadata = $context->pop();
        assert($bubbleable_metadata instanceof BubbleableMetadata);
        $response->addCacheableDependency($bubbleable_metadata);
        $response->addAttachments($bubbleable_metadata->getAttachments());
      }
    }
    catch (ResourceException $e) {
      // Prevent the response from being cached.       $response->setMaxAge(0);

      // The oEmbed system makes heavy use of exception wrapping, so log the       // entire exception chain to help with troubleshooting.       do {
        // @todo Log additional information from ResourceException, to help with         // debugging, in https://www.drupal.org/project/drupal/issues/2972846.
/** @var \Drupal\Core\Render\BubbleableMetadata $early_rendering_bubbleable_metadata */
      $early_rendering_bubbleable_metadata = $context->pop();

      // If a render array or AjaxResponse is returned by the controller, merge       // the "lost" bubbleable metadata.       if (is_array($response)) {
        BubbleableMetadata::createFromRenderArray($response)
          ->merge($early_rendering_bubbleable_metadata)
          ->applyTo($response);
      }
      elseif ($response instanceof AjaxResponse) {
        $response->addAttachments($early_rendering_bubbleable_metadata->getAttachments());
        // @todo Make AjaxResponse cacheable in         // https://www.drupal.org/node/956186. Meanwhile, allow contrib         // subclasses to be.         if ($response instanceof CacheableResponseInterface) {
          $response->addCacheableDependency($early_rendering_bubbleable_metadata);
        }
      }
      // If a non-Ajax Response or domain object is returned and it cares about       // attachments or cacheability, then throw an exception: early rendering       // is not permitted in that case. It is the developer's responsibility       // to not use early rendering.
foreach ($updated_nodes as $updated_node) {
          // Import the updated node from the new DOMDocument into the original           // one, importing also the child nodes of the updated node.           $updated_node = $dom->importNode($updated_node, TRUE);
          $node->parentNode->insertBefore($updated_node$node);
        }
        // Finally, remove the original data-caption node.         $node->parentNode->removeChild($node);
      }

      $result->setProcessedText(Html::serialize($dom))
        ->addAttachments([
          'library' => [
            'filter/caption',
          ],
        ]);
    }

    return $result;
  }

  /** * {@inheritdoc} */

      $url = Url::fromRoute($element['#autocomplete_route_name']$parameters$options)->toString(TRUE);
      /** @var \Drupal\Core\Access\AccessManagerInterface $access_manager */
      $access_manager = \Drupal::service('access_manager');
      $access = $access_manager->checkNamedRoute($element['#autocomplete_route_name']$parameters, \Drupal::currentUser(), TRUE);
    }

    if ($access) {
      $metadata = BubbleableMetadata::createFromRenderArray($element);
      if ($access->isAllowed()) {
        $element['#attributes']['class'][] = 'form-autocomplete';
        $metadata->addAttachments(['library' => ['core/drupal.autocomplete']]);
        // Provide a data attribute for the JavaScript behavior to bind to.         $element['#attributes']['data-autocomplete-path'] = $url->getGeneratedUrl();
        $metadata = $metadata->merge($url);
      }
      $metadata
        ->merge(BubbleableMetadata::createFromObject($access))
        ->applyTo($element);
    }

    return $element;
  }

}
$this->expectException(\Exception::class);
    theme_render_and_autoescape(new NonPrintable());
  }

  /** * Ensure cache metadata is bubbled when using theme_render_and_autoescape(). */
  public function testBubblingMetadata() {
    $link = new GeneratedLink();
    $link->setGeneratedLink('<a href="http://example.com"></a>');
    $link->addCacheTags(['foo']);
    $link->addAttachments(['library' => ['system/base']]);

    $context = new RenderContext();
    // Use a closure here since we need to render with a render context.     $theme_render_and_autoescape = function D) use ($link) {
      return theme_render_and_autoescape($link);
    };
    /** @var \Drupal\Core\Render\RendererInterface $renderer */
    $renderer = \Drupal::service('renderer');
    $output = $renderer->executeInRenderContext($context$theme_render_and_autoescape);
    $this->assertEquals('<a href="http://example.com"></a>', $output);
    /** @var \Drupal\Core\Render\BubbleableMetadata $metadata */
    
else {
        // Generate a placeholder and a render array to replace it.         $placeholder = Crypt::hashBase64($path);
        $placeholder_render_array = [
          '#lazy_builder' => ['route_processor_csrf:renderPlaceholderCsrfToken', [$path]],
        ];

        // Instead of setting an actual CSRF token as the query string, we set         // the placeholder, which will be replaced at the very last moment. This         // ensures links with CSRF tokens don't break cacheability.         $parameters['token'] = $placeholder;
        $bubbleable_metadata->addAttachments(['placeholders' => [$placeholder => $placeholder_render_array]]);
      }
    }
  }

  /** * #lazy_builder callback; gets a CSRF token for the given path. * * @param string $path * The path to get a CSRF token for. * * @return array * A renderable array representing the CSRF token. */
Home | Imprint | This part of the site doesn't use cookies.