Excerpts.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <?php
  2. /**
  3. * @package Grav\Common\Helpers
  4. *
  5. * @copyright Copyright (C) 2015 - 2020 Trilby Media, LLC. All rights reserved.
  6. * @license MIT License; see LICENSE file for details.
  7. */
  8. namespace Grav\Common\Helpers;
  9. use Grav\Common\Page\Interfaces\PageInterface;
  10. use Grav\Common\Page\Markdown\Excerpts as ExcerptsObject;
  11. use Grav\Common\Page\Medium\Medium;
  12. class Excerpts
  13. {
  14. /**
  15. * Process Grav image media URL from HTML tag
  16. *
  17. * @param string $html HTML tag e.g. `<img src="image.jpg" />`
  18. * @param PageInterface|null $page Page, defaults to the current page object
  19. * @return string Returns final HTML string
  20. */
  21. public static function processImageHtml($html, PageInterface $page = null)
  22. {
  23. $excerpt = static::getExcerptFromHtml($html, 'img');
  24. $original_src = $excerpt['element']['attributes']['src'];
  25. $excerpt['element']['attributes']['href'] = $original_src;
  26. $excerpt = static::processLinkExcerpt($excerpt, $page, 'image');
  27. $excerpt['element']['attributes']['src'] = $excerpt['element']['attributes']['href'];
  28. unset($excerpt['element']['attributes']['href']);
  29. $excerpt = static::processImageExcerpt($excerpt, $page);
  30. $excerpt['element']['attributes']['data-src'] = $original_src;
  31. $html = static::getHtmlFromExcerpt($excerpt);
  32. return $html;
  33. }
  34. /**
  35. * Process Grav page link URL from HTML tag
  36. *
  37. * @param string $html HTML tag e.g. `<a href="../foo">Page Link</a>`
  38. * @param PageInterface|null $page Page, defaults to the current page object
  39. * @return string Returns final HTML string
  40. */
  41. public static function processLinkHtml($html, PageInterface $page = null)
  42. {
  43. $excerpt = static::getExcerptFromHtml($html, 'a');
  44. $original_href = $excerpt['element']['attributes']['href'];
  45. $excerpt = static::processLinkExcerpt($excerpt, $page, 'link');
  46. $excerpt['element']['attributes']['data-href'] = $original_href;
  47. $html = static::getHtmlFromExcerpt($excerpt);
  48. return $html;
  49. }
  50. /**
  51. * Get an Excerpt array from a chunk of HTML
  52. *
  53. * @param string $html Chunk of HTML
  54. * @param string $tag A tag, for example `img`
  55. * @return array|null returns nested array excerpt
  56. */
  57. public static function getExcerptFromHtml($html, $tag)
  58. {
  59. $doc = new \DOMDocument('1.0', 'UTF-8');
  60. $internalErrors = libxml_use_internal_errors(true);
  61. $doc->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
  62. libxml_use_internal_errors($internalErrors);
  63. $elements = $doc->getElementsByTagName($tag);
  64. $excerpt = null;
  65. $inner = [];
  66. /** @var \DOMElement $element */
  67. foreach ($elements as $element) {
  68. $attributes = [];
  69. foreach ($element->attributes as $name => $value) {
  70. $attributes[$name] = $value->value;
  71. }
  72. $excerpt = [
  73. 'element' => [
  74. 'name' => $element->tagName,
  75. 'attributes' => $attributes
  76. ]
  77. ];
  78. foreach ($element->childNodes as $node) {
  79. $inner[] = $doc->saveHTML($node);
  80. }
  81. $excerpt = array_merge_recursive($excerpt, ['element' => ['text' => implode('', $inner)]]);
  82. }
  83. return $excerpt;
  84. }
  85. /**
  86. * Rebuild HTML tag from an excerpt array
  87. *
  88. * @param array $excerpt
  89. * @return string
  90. */
  91. public static function getHtmlFromExcerpt($excerpt)
  92. {
  93. $element = $excerpt['element'];
  94. $html = '<'.$element['name'];
  95. if (isset($element['attributes'])) {
  96. foreach ($element['attributes'] as $name => $value) {
  97. if ($value === null) {
  98. continue;
  99. }
  100. $html .= ' '.$name.'="'.$value.'"';
  101. }
  102. }
  103. if (isset($element['text'])) {
  104. $html .= '>';
  105. $html .= is_array($element['text']) ? static::getHtmlFromExcerpt(['element' => $element['text']]) : $element['text'];
  106. $html .= '</'.$element['name'].'>';
  107. } else {
  108. $html .= ' />';
  109. }
  110. return $html;
  111. }
  112. /**
  113. * Process a Link excerpt
  114. *
  115. * @param array $excerpt
  116. * @param PageInterface|null $page Page, defaults to the current page object
  117. * @param string $type
  118. * @return mixed
  119. */
  120. public static function processLinkExcerpt($excerpt, PageInterface $page = null, $type = 'link')
  121. {
  122. $excerpts = new ExcerptsObject($page);
  123. return $excerpts->processLinkExcerpt($excerpt, $type);
  124. }
  125. /**
  126. * Process an image excerpt
  127. *
  128. * @param array $excerpt
  129. * @param PageInterface|null $page Page, defaults to the current page object
  130. * @return array
  131. */
  132. public static function processImageExcerpt(array $excerpt, PageInterface $page = null)
  133. {
  134. $excerpts = new ExcerptsObject($page);
  135. return $excerpts->processImageExcerpt($excerpt);
  136. }
  137. /**
  138. * Process media actions
  139. *
  140. * @param Medium $medium
  141. * @param string|array $url
  142. * @param PageInterface|null $page Page, defaults to the current page object
  143. * @return Medium
  144. */
  145. public static function processMediaActions($medium, $url, PageInterface $page = null)
  146. {
  147. $excerpts = new ExcerptsObject($page);
  148. return $excerpts->processMediaActions($medium, $url);
  149. }
  150. }