Link.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. <?php
  2. /**
  3. * @package Grav\Common\Page
  4. *
  5. * @copyright Copyright (c) 2015 - 2023 Trilby Media, LLC. All rights reserved.
  6. * @license MIT License; see LICENSE file for details.
  7. */
  8. namespace Grav\Common\Page\Medium;
  9. use BadMethodCallException;
  10. use Grav\Common\Media\Interfaces\MediaLinkInterface;
  11. use Grav\Common\Media\Interfaces\MediaObjectInterface;
  12. use RuntimeException;
  13. use function call_user_func_array;
  14. use function get_class;
  15. use function is_array;
  16. use function is_callable;
  17. /**
  18. * Class Link
  19. * @package Grav\Common\Page\Medium
  20. */
  21. class Link implements RenderableInterface, MediaLinkInterface
  22. {
  23. use ParsedownHtmlTrait;
  24. /** @var array */
  25. protected $attributes = [];
  26. /** @var MediaObjectInterface|MediaLinkInterface */
  27. protected $source;
  28. /**
  29. * Construct.
  30. * @param array $attributes
  31. * @param MediaObjectInterface $medium
  32. */
  33. public function __construct(array $attributes, MediaObjectInterface $medium)
  34. {
  35. $this->attributes = $attributes;
  36. $source = $medium->reset()->thumbnail('auto')->display('thumbnail');
  37. if (!$source instanceof MediaObjectInterface) {
  38. throw new RuntimeException('Media has no thumbnail set');
  39. }
  40. $source->set('linked', true);
  41. $this->source = $source;
  42. }
  43. /**
  44. * Get an element (is array) that can be rendered by the Parsedown engine
  45. *
  46. * @param string|null $title
  47. * @param string|null $alt
  48. * @param string|null $class
  49. * @param string|null $id
  50. * @param bool $reset
  51. * @return array
  52. */
  53. public function parsedownElement($title = null, $alt = null, $class = null, $id = null, $reset = true)
  54. {
  55. $innerElement = $this->source->parsedownElement($title, $alt, $class, $id, $reset);
  56. return [
  57. 'name' => 'a',
  58. 'attributes' => $this->attributes,
  59. 'handler' => is_array($innerElement) ? 'element' : 'line',
  60. 'text' => $innerElement
  61. ];
  62. }
  63. /**
  64. * Forward the call to the source element
  65. *
  66. * @param string $method
  67. * @param mixed $args
  68. * @return mixed
  69. */
  70. #[\ReturnTypeWillChange]
  71. public function __call($method, $args)
  72. {
  73. $object = $this->source;
  74. $callable = [$object, $method];
  75. if (!is_callable($callable)) {
  76. throw new BadMethodCallException(get_class($object) . '::' . $method . '() not found.');
  77. }
  78. $object = call_user_func_array($callable, $args);
  79. if (!$object instanceof MediaLinkInterface) {
  80. // Don't start nesting links, if user has multiple link calls in his
  81. // actions, we will drop the previous links.
  82. return $this;
  83. }
  84. $this->source = $object;
  85. return $object;
  86. }
  87. }