ServiceProvider.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <?php
  2. /**
  3. * ServiceProvider
  4. *
  5. * This file is part of Grav MediaEmbed plugin.
  6. *
  7. * Dual licensed under the MIT or GPL Version 3 licenses, see LICENSE.
  8. * http://benjamin-regler.de/license/
  9. */
  10. namespace Grav\Plugin\MediaEmbed;
  11. use Grav\Common\Grav;
  12. use Grav\Common\GravTrait;
  13. use Grav\Common\Data\Data;
  14. use RocketTheme\Toolbox\Event\Event;
  15. /**
  16. * ServiceProvider
  17. */
  18. abstract class ServiceProvider implements ProviderInterface
  19. {
  20. use GravTrait;
  21. /**
  22. * @var \Grav\Common\Data\Data
  23. */
  24. protected $config;
  25. /**
  26. * @var string
  27. */
  28. protected $embedCode = '';
  29. /**
  30. * @var array
  31. */
  32. protected $attributes;
  33. /**
  34. * @var array
  35. */
  36. protected $params;
  37. /** -------------
  38. * Public methods
  39. * --------------
  40. */
  41. /**
  42. * Constructor.
  43. */
  44. public function __construct(array $config = [])
  45. {
  46. $this->config = new Data($config);
  47. }
  48. public function init($embedCode)
  49. {
  50. $this->reset();
  51. // Normalize URL to embed
  52. $this->embedCode = $this->canonicalize($embedCode);
  53. $url = $this->parseUrl($embedCode);
  54. // Get media attributes and object parameters
  55. $attributes = $this->config->get('media', []);
  56. $params = array_replace_recursive($this->config->get('params', []), $url['query']);
  57. // Copy media attributes from object parameters
  58. $attr_keys = ['width', 'height', 'crop', 'preview', 'responsive'];
  59. foreach ($attr_keys as $key) {
  60. if (isset($params[$key])) {
  61. $attributes[$key] = $params[$key];
  62. unset($params[$key]);
  63. }
  64. }
  65. // Set media attributes and object parameters
  66. $this->attributes($attributes);
  67. $this->params($params);
  68. }
  69. public function reset() {
  70. // Reset values
  71. $this->embedCode = '';
  72. $this->attributes([]);
  73. $this->params([]);
  74. }
  75. public function id()
  76. {
  77. return $this->embedCode;
  78. }
  79. public function slug()
  80. {
  81. $slug = strtolower($this->name()) . '://' . $this->id();
  82. return $slug;
  83. }
  84. public function name()
  85. {
  86. $name = $this->config->get('name', get_class($this));
  87. return substr($name, strrpos($name, '\\') + 1);
  88. }
  89. public function type()
  90. {
  91. return $this->config->get('type', 'unknown');
  92. }
  93. public function thumbnail() {
  94. $thumbnails = $this->config->get('thumbnail', []);
  95. if (is_string($thumbnails)) {
  96. $thumbnails = [$thumbnails];
  97. }
  98. $url = '';
  99. foreach ($thumbnails as $thumbnail) {
  100. $thumbnail = $this->format($thumbnail);
  101. if (substr(get_headers($thumbnail)[0], -6) == '200 OK') {
  102. $url = $thumbnail;
  103. break;
  104. }
  105. }
  106. return $url;
  107. }
  108. public function attributes($var = null)
  109. {
  110. if ($var !== null) {
  111. $this->attributes = $var;
  112. }
  113. if (!is_array($this->attributes)) {
  114. $this->attributes = [];
  115. }
  116. return $this->attributes;
  117. }
  118. public function params($var = null)
  119. {
  120. if ($var !== null) {
  121. $this->params = $var;
  122. }
  123. if (!is_array($this->params)) {
  124. $this->params = [];
  125. }
  126. return $this->params;
  127. }
  128. /**
  129. * Return the domain(s) of this media resource
  130. *
  131. * @return string
  132. */
  133. // public function getDomains()
  134. // {
  135. // return [];
  136. // }
  137. public function onTwigTemplateVariables(Event $event)
  138. {
  139. $mediaembed = $event['mediaembed'];
  140. foreach ($this->config->get('assets', []) as $asset) {
  141. $mediaembed->add($asset);
  142. }
  143. }
  144. /**
  145. * Convenience wrapper for `echo $ServiceProvider`
  146. *
  147. * @return string
  148. */
  149. public function __toString() {
  150. return $this->getEmbedCode();
  151. }
  152. /** -------------------------------
  153. * Private/protected helper methods
  154. * --------------------------------
  155. */
  156. protected function format($string, $params = [])
  157. {
  158. $params += [
  159. '{:id}' => $this->id(),
  160. '{:name}' => $this->name(),
  161. '{:url}' => urlencode($this->config->get('website', '')),
  162. ];
  163. // Format URL placeholder with params
  164. $params['{:url}'] = urlencode(str_ireplace(array_keys($params), $params, $params['{:url}']));
  165. $string = preg_replace_callback('~\{\:oembed(?:\.(?=\w))([\.\w_]+)?\}~i',
  166. function($match) {
  167. static $oembed;
  168. if (is_null($oembed)) {
  169. $oembed = new Data($this->getOEmbed());
  170. }
  171. return $oembed->get($match[1], '');
  172. }, $string);
  173. return str_ireplace(array_keys($params), $params, $string);
  174. }
  175. protected function parseUrl($url)
  176. {
  177. if (!filter_var($url, FILTER_VALIDATE_URL)) {
  178. return [];
  179. }
  180. // Parse URL
  181. $url = html_entity_decode($url, ENT_COMPAT | ENT_HTML401, 'UTF-8');
  182. $parts = parse_url($url);
  183. $parts['url'] = $url;
  184. // Get top-level domain from URL
  185. $parts['domain'] = isset($parts['host']) ? $parts['host'] : '';
  186. if ( preg_match('~(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$~i', $parts['domain'], $match) ) {
  187. $parts['domain'] = $match['domain'];
  188. }
  189. if (isset($parts['query'])) {
  190. parse_str(urldecode($parts['query']), $parts['query']);
  191. }
  192. $parts['query'] = [];
  193. return $parts;
  194. }
  195. }