You are here

public function HtmlLink::parseEntitiesFromText in Entity Usage 8.3

Same name and namespace in other branches
  1. 8.2 src/Plugin/EntityUsage/Track/HtmlLink.php \Drupal\entity_usage\Plugin\EntityUsage\Track\HtmlLink::parseEntitiesFromText()

Parse an HTML snippet looking for embedded entities.

Parameters

string $text: The partial (X)HTML snippet to load. Invalid markup will be corrected on import.

Return value

array An array of all embedded entities found, where keys are the uuids and the values are the entity types.

Overrides EmbedTrackInterface::parseEntitiesFromText

File

src/Plugin/EntityUsage/Track/HtmlLink.php, line 92

Class

HtmlLink
Tracks usage of entities referenced from regular HTML Links.

Namespace

Drupal\entity_usage\Plugin\EntityUsage\Track

Code

public function parseEntitiesFromText($text) {
  $dom = Html::load($text);
  $xpath = new \DOMXPath($dom);
  $entities = [];

  // Loop trough all the <a> elements that don't have the LinkIt attributes.
  $xpath_query = "//a[@href != '']";
  foreach ($xpath
    ->query($xpath_query) as $element) {

    /** @var \DOMElement $element */
    try {

      // Get the href value of the <a> element.
      $href = $element
        ->getAttribute('href');

      // Strip off the scheme and host, so we only get the path.
      $site_domains = $this->config
        ->get('site_domains') ?: [];
      foreach ($site_domains as $site_domain) {
        $host_pattern = '{^https?://' . str_replace('.', '\\.', $site_domain) . '/}';
        if (\preg_match($host_pattern, $href)) {
          $href = preg_replace($host_pattern, '/', $href);
          break;
        }
      }
      $target_type = $target_id = NULL;

      // Check if the href links to an entity.
      $url = $this->pathValidator
        ->getUrlIfValidWithoutAccessCheck($href);
      if ($url && $url
        ->isRouted() && preg_match('/^entity\\./', $url
        ->getRouteName())) {

        // Ge the target entity type and ID.
        $route_parameters = $url
          ->getRouteParameters();
        $target_type = array_keys($route_parameters)[0];
        $target_id = $route_parameters[$target_type];
      }
      elseif (\preg_match('{^/?' . $this->publicFileDirectory . '/}', $href)) {

        // Check if we can map the link to a public file.
        $file_uri = preg_replace('{^/?' . $this->publicFileDirectory . '/}', 'public://', urldecode($href));
        $files = $this->entityTypeManager
          ->getStorage('file')
          ->loadByProperties([
          'uri' => $file_uri,
        ]);
        if ($files) {

          // File entity found.
          $target_type = 'file';
          $target_id = array_keys($files)[0];
        }
      }
      if ($target_type && $target_id) {
        $entity = $this->entityTypeManager
          ->getStorage($target_type)
          ->load($target_id);
        if ($entity) {
          if ($element
            ->hasAttribute('data-entity-uuid')) {

            // Normally the Linkit plugin handles when a element has this
            // attribute, but sometimes users may change the HREF manually and
            // leave behind the wrong UUID.
            $data_uuid = $element
              ->getAttribute('data-entity-uuid');

            // If the UUID is the same as found in HREF, then skip it because
            // it's LinkIt's job to register this usage.
            if ($data_uuid == $entity
              ->uuid()) {
              continue;
            }
          }
          $entities[$entity
            ->uuid()] = $target_type;
        }
      }
    } catch (\Exception $e) {

      // Do nothing.
    }
  }
  return $entities;
}