first commit
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* Autoloader
|
||||
*
|
||||
* This file is part of Grav MediaEmbed plugin.
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 3 licenses, see LICENSE.
|
||||
* http://benjamin-regler.de/license/
|
||||
*/
|
||||
|
||||
namespace Grav\Plugin\MediaEmbed;
|
||||
|
||||
/**
|
||||
* Autoloader
|
||||
*/
|
||||
class Autoloader
|
||||
{
|
||||
protected $routes = [];
|
||||
|
||||
public function __construct($routes = [])
|
||||
{
|
||||
|
||||
// Set routes for autoloading
|
||||
if (!is_array($routes) || count($routes) == 0) {
|
||||
$routes = [__NAMESPACE__ => __DIR__];
|
||||
}
|
||||
|
||||
$this->route($routes);
|
||||
}
|
||||
|
||||
public function route($var = null, $reset = true)
|
||||
{
|
||||
if ($var !== null && is_array($var)) {
|
||||
if ($reset) {
|
||||
$this->routes = [];
|
||||
}
|
||||
|
||||
// Setup routes
|
||||
foreach ($var as $prefix => $path) {
|
||||
if (false !== strrpos($prefix, '\\')) {
|
||||
// Prefix is a namespaced path
|
||||
$prefix = rtrim($prefix, '_\\') . '\\';
|
||||
} else {
|
||||
// Prefix contain underscores
|
||||
$prefix = rtrim($prefix, '_') . '_';
|
||||
}
|
||||
|
||||
$this->routes[$prefix] = rtrim($path, '/\\') . '/';
|
||||
}
|
||||
}
|
||||
|
||||
return $this->routes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload classes
|
||||
*
|
||||
* @param string $class Class name
|
||||
*
|
||||
* @return mixed false FALSE if unable to load $class; Class name if
|
||||
* $class is successfully loaded
|
||||
*/
|
||||
public function autoload($class)
|
||||
{
|
||||
foreach ($this->routes as $prefix => $path) {
|
||||
// Only load classes of MediaEmbed plugin
|
||||
if (false !== strpos($class, $prefix)) {
|
||||
// Remove prefix from class
|
||||
$class = substr($class, strlen($prefix));
|
||||
|
||||
// Replace namespace tokens to directory separators
|
||||
$file = $path . preg_replace('#\\\|_(?!.+\\\)#', '/', $class) . '.php';
|
||||
|
||||
// Load class
|
||||
if (stream_resolve_include_path($file)) {
|
||||
return include_once($file);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'autoload'), false, $prepend);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'autoload'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,497 @@
|
||||
<?php
|
||||
/**
|
||||
* MediaEmbed
|
||||
*
|
||||
* This file is part of Grav MediaEmbed plugin.
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 3 licenses, see LICENSE.
|
||||
* http://benjamin-regler.de/license/
|
||||
*/
|
||||
|
||||
namespace Grav\Plugin\MediaEmbed;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\GravTrait;
|
||||
use Grav\Plugin\MediaEmbed\Service;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
|
||||
/**
|
||||
* MediaEmbed
|
||||
*
|
||||
* Helper class to embed several media sites (e.g. YouTube, Vimeo,
|
||||
* Soundcloud) by only providing the URL to the medium.
|
||||
*/
|
||||
class MediaEmbed
|
||||
{
|
||||
/**
|
||||
* @var MediaEmbed
|
||||
*/
|
||||
use GravTrait;
|
||||
|
||||
/** ---------------------------
|
||||
* Private/protected properties
|
||||
* ----------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* A unique identifier
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* A key-valued array used for hashing math formulas of a page
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hashes;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $assets = [];
|
||||
|
||||
/**
|
||||
* @var Grav\Plugin\MediaEmbed\Service
|
||||
*/
|
||||
protected $service;
|
||||
|
||||
/** -------------
|
||||
* Public methods
|
||||
* --------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param [type] $config [description]
|
||||
*/
|
||||
public function __construct($config)
|
||||
{
|
||||
// Initialize Service class
|
||||
$this->service = new Service();
|
||||
$this->config = $config;
|
||||
$this->hashes = [];
|
||||
|
||||
$services = $this->config->get('plugins.mediaembed.services', []);
|
||||
foreach ($services as $name => $config) {
|
||||
if (!$config['enabled']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Load providers in directory "services"
|
||||
$class = __NAMESPACE__ . "\\Services\\$name";
|
||||
if (!class_exists($class)) {
|
||||
// Fallback to a more generic one
|
||||
$type = isset($config['type']) ? $config['type'] : '';
|
||||
$class = __NAMESPACE__."\\OEmbed\\OEmbed".ucfirst($type);
|
||||
}
|
||||
|
||||
// Populate config
|
||||
$config['media'] = $this->config->get('plugins.mediaembed.media', []);
|
||||
$config['name'] = $name;
|
||||
|
||||
if (class_exists($class)) {
|
||||
// Load ServiceProvider
|
||||
$provider = new $class($config);
|
||||
|
||||
// Register ServiceProvider
|
||||
$this->service->register($provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets and sets the identifier for hashing.
|
||||
*
|
||||
* @param string $var the identifier
|
||||
*
|
||||
* @return string the identifier
|
||||
*/
|
||||
public function id($var = null)
|
||||
{
|
||||
if ($var !== null) {
|
||||
$this->id = $var;
|
||||
}
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function prepare($content, $id = '')
|
||||
{
|
||||
// Set unique identifier based on page content
|
||||
$this->id(md5(time() . $id . md5($content)));
|
||||
|
||||
// Reset class hashes before processing
|
||||
$this->reset();
|
||||
|
||||
$regex = "~
|
||||
( # wrap whole match in $1
|
||||
!\\[
|
||||
(?P<alt>.*?) # alt text = $2
|
||||
\\]
|
||||
\\( # literal paren
|
||||
[ \\t]*
|
||||
<?(?P<src>\S+?)>? # src url = $3
|
||||
[ \\t]*
|
||||
( # $4
|
||||
(['\"]) # quote char = $5
|
||||
(?<title>.*?) # title = $6
|
||||
\\5 # matching quote
|
||||
[ \\t]*
|
||||
)? # title is optional
|
||||
\\)
|
||||
)
|
||||
~xs";
|
||||
|
||||
// Replace all mediaembed links by a (unique) hash
|
||||
$content = preg_replace_callback($regex, function($matches) {
|
||||
// Get the url and parse it
|
||||
$url = parse_url(htmlspecialchars_decode($matches[3]));
|
||||
|
||||
// If there is no host set but there is a path, the file is local
|
||||
if (!isset($url['host']) && isset($url['path'])) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
if (!isset($matches['title'])) {
|
||||
$matches['title'] = '';
|
||||
}
|
||||
|
||||
return $this->hash($matches[0], $matches);
|
||||
}, $content);
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function process($content, $config = [])
|
||||
{
|
||||
/** @var Twig $twig */
|
||||
$twig = self::getGrav()['twig'];
|
||||
|
||||
// Initialize unique per-page counter
|
||||
$uid = 1;
|
||||
|
||||
// '~(<p>)?\s*<a[^>]*href\s*=\s*([\'"])(?P<href>.*?)\2[^>]*>(?P<code>.*?)</a>\s*(?(1)(</p>))~i',
|
||||
|
||||
// Get all <a> tags and extract "href" attribute
|
||||
$content = preg_replace_callback(
|
||||
'~mediaembed::([0-9a-z]+)::([0-9]+)::M~i',
|
||||
function($match) use ($twig, &$uid, $config) {
|
||||
list($embed, $data) = $this->hashes[$match[0]];
|
||||
|
||||
// Check if a service for a specific domain is registered
|
||||
if ($this->service->match($data['src'])) {
|
||||
$mediaembed = [
|
||||
'uid' => $uid++,
|
||||
'service' => null,
|
||||
'config' => $config,
|
||||
|
||||
'raw' => [
|
||||
'alt' => $data['alt'],
|
||||
'title' => $data['title'],
|
||||
'src' => html_entity_decode($data['src']),
|
||||
],
|
||||
|
||||
'success' => true,
|
||||
'message' => '',
|
||||
];
|
||||
|
||||
// Load and get data of OEmbed Media Service
|
||||
try {
|
||||
$provider = $this->service->embed($data['src']);
|
||||
} catch (\Exception $e) {
|
||||
$mediaembed['message'] = $e->getMessage();
|
||||
$mediaembed['success'] = false;
|
||||
}
|
||||
|
||||
// Setup variables for embedding OEmbed Media Service
|
||||
if ($mediaembed['success']) {
|
||||
// Get assets/options of current provider
|
||||
$assets = $provider->onTwigTemplateVariables(
|
||||
new Event(['service' => $this->service, 'mediaembed' => $this])
|
||||
);
|
||||
|
||||
// Assets are passed by value as an array
|
||||
if (is_array($assets)) {
|
||||
$this->addAssets($assets);
|
||||
}
|
||||
|
||||
// Add OEmbed Service to variables
|
||||
$mediaembed['service'] = $provider;
|
||||
|
||||
// TODO: Cache contents from thumbnail and url
|
||||
}
|
||||
|
||||
// Embed OEmbed Media
|
||||
$vars = ['mediaembed' => $mediaembed];
|
||||
$template = 'partials/mediaembed' . TEMPLATE_EXT;
|
||||
$embed = $twig->processTemplate($template, $vars);
|
||||
} else {
|
||||
$text = (strlen($data['alt']) > 0) ? $data['alt'] : $data['src'];
|
||||
|
||||
// If display link or img
|
||||
$link = $config->get('link');
|
||||
if($link == true) {
|
||||
$attributes = [
|
||||
'href' => $data['src'],
|
||||
'title' => $data['title'],
|
||||
];
|
||||
|
||||
$format = '<a%s>%s</a>';
|
||||
|
||||
} else {
|
||||
$attributes = [
|
||||
'src' => $data['src'],
|
||||
'title' => $data['title'],
|
||||
'alt' => $data['alt'],
|
||||
];
|
||||
|
||||
$format = '<img%s>';
|
||||
|
||||
}
|
||||
|
||||
foreach ($attributes as $key => $value) {
|
||||
if (strlen($value) == 0) {
|
||||
unset($attributes[$key]);
|
||||
} else {
|
||||
$value = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
|
||||
$attributes[$key] = $key . '="' . $value . '"';
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = $attributes ? ' ' . implode(' ', $attributes) : '';
|
||||
|
||||
// Transform embed media to link or img for compatibility
|
||||
$embed = sprintf($format, $attributes, $text);
|
||||
|
||||
}
|
||||
|
||||
return $embed;
|
||||
}, $content);
|
||||
|
||||
$this->reset();
|
||||
// Write content back to page
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires an event with optional parameters.
|
||||
*
|
||||
* @param string $eventName The name of the event.
|
||||
* @param Event $event Optional parameter to be passed to the
|
||||
* called methods.
|
||||
* @return Event
|
||||
*/
|
||||
public function fireEvent($eventName, Event $event = null)
|
||||
{
|
||||
// Dispatch event; just propagate it to service class
|
||||
return $this->service->call($eventName, $event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get assets of loaded media services.
|
||||
*
|
||||
* @param boolean $reset Toggle whether to reset assets after retrieving
|
||||
* or not.
|
||||
*/
|
||||
public function getAssets($reset = true)
|
||||
{
|
||||
$assets = $this->assets;
|
||||
if ($reset) {
|
||||
$this->assets = [];
|
||||
}
|
||||
|
||||
return $assets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add assets to the queue of MediaEmbed plugin
|
||||
*
|
||||
* @param array $assets An array of assets to add.
|
||||
* @param boolean $append Append assets to array or reset assets.
|
||||
*/
|
||||
public function addAssets($assets, $append = true)
|
||||
{
|
||||
// Append or reset assets
|
||||
if (!$append) {
|
||||
$this->assets = [];
|
||||
}
|
||||
|
||||
// Wrap non-array assets in an array
|
||||
if (!is_array($assets)) {
|
||||
$assets = array($assets);
|
||||
}
|
||||
|
||||
// Merge assets
|
||||
$assets = array_merge($this->assets, $assets);
|
||||
|
||||
// Remove duplicates
|
||||
$this->assets = array_keys(array_flip($assets));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add assets to the queue of MediaEmbed plugin
|
||||
*
|
||||
* Alias for `addAssets`
|
||||
*
|
||||
* @param array $assets An array of assets to add.
|
||||
* @param boolean $append Append assets to array or reset assets.
|
||||
*/
|
||||
public function add($assets, $append = true)
|
||||
{
|
||||
return $this->addAssets($assets, $append);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add assets to the queue of MediaEmbed plugin
|
||||
*
|
||||
* Alias for `addAssets`
|
||||
*
|
||||
* @param array $assets An array of assets to add.
|
||||
* @param boolean $append Append assets to array or reset assets.
|
||||
*/
|
||||
public function addCss($assets, $append = true)
|
||||
{
|
||||
return $this->addAssets($assets, $append);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add assets to the queue of MediaEmbed plugin
|
||||
*
|
||||
* Alias for `addAssets`
|
||||
*
|
||||
* @param array $assets An array of assets to add.
|
||||
* @param boolean $append Append assets to array or reset assets.
|
||||
*/
|
||||
public function addJs($assets, $append = true)
|
||||
{
|
||||
return $this->addAssets($assets, $append);
|
||||
}
|
||||
|
||||
/** -------------------------------
|
||||
* Private/protected helper methods
|
||||
* --------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get cached media or media with key.
|
||||
*
|
||||
* @param string $key The key to load from the cache.
|
||||
* @return mixed The media content.
|
||||
*/
|
||||
protected function getCachedMedia($key)
|
||||
{
|
||||
/** @var Cache $cache */
|
||||
$cache = $grav['cache'];
|
||||
|
||||
// Check, if cache should be used or not
|
||||
if ($this->config->get('cache.enabled')) {
|
||||
// Get cache id and try to fetch data
|
||||
$cache_id = md5('mediaembed' . $key . $cache->getKey());
|
||||
$data = $cache->fetch($cache_id);
|
||||
|
||||
if ((false === $data) || (time() > $data['expire'])) {
|
||||
// Pack and provide data with a time stamp.
|
||||
$data = array(
|
||||
'content' => $this->service->embed($key),
|
||||
'expire' => time() + $this->config->get('cache.lifetime'),
|
||||
);
|
||||
$cache->save($cache_id, $data);
|
||||
}
|
||||
|
||||
// Return data contents
|
||||
$content = $data['content'];
|
||||
} else {
|
||||
// Just call callback and return result
|
||||
$content = $this->service->embed($key);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
protected function parseUrl($url)
|
||||
{
|
||||
if (!filter_var($url, FILTER_VALIDATE_URL)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Parse URL
|
||||
$url = html_entity_decode($url, ENT_COMPAT | ENT_HTML401, 'UTF-8');
|
||||
$parts = parse_url($url);
|
||||
$parts['url'] = $url;
|
||||
|
||||
// Get top-level domain from URL
|
||||
$parts['domain'] = isset($parts['host']) ? $parts['host'] : '';
|
||||
if ( preg_match('~(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$~i', $parts['domain'], $match) ) {
|
||||
$parts['domain'] = $match['domain'];
|
||||
}
|
||||
|
||||
if (isset($parts['query'])) {
|
||||
parse_str(urldecode($parts['query']), $parts['query']);
|
||||
}
|
||||
$parts['query'] = [];
|
||||
|
||||
return $parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset MathJax class
|
||||
*/
|
||||
protected function reset()
|
||||
{
|
||||
$this->hashes = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash a given text.
|
||||
*
|
||||
* Called whenever a tag must be hashed when a function insert an
|
||||
* atomic element in the text stream. Passing $text to through this
|
||||
* function gives a unique text-token which will be reverted back when
|
||||
* calling unhash.
|
||||
*
|
||||
* @param string $text The text to be hashed
|
||||
* @param string $type The type (category) the text should be saved
|
||||
*
|
||||
* @return string Return a unique text-token which will be
|
||||
* reverted back when calling unhash.
|
||||
*/
|
||||
protected function hash($text, $data = [])
|
||||
{
|
||||
static $counter = 0;
|
||||
|
||||
// Swap back any tag hash found in $text so we do not have to `unhash`
|
||||
// multiple times at the end.
|
||||
$text = $this->unhash($text);
|
||||
|
||||
// Then hash the block
|
||||
$key = implode('::', array('mediaembed', $this->id, ++$counter, 'M'));
|
||||
$this->hashes[$key] = [$text, $data];
|
||||
|
||||
// String that will replace the tag
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap back in all the tags hashed by hash.
|
||||
*
|
||||
* @param string $text The text to be un-hashed
|
||||
*
|
||||
* @return string A text containing no hash inside
|
||||
*/
|
||||
protected function unhash($text)
|
||||
{
|
||||
$text = preg_replace_callback(
|
||||
'~mediaembed::([0-9a-z]+)::([0-9]+)::M~i', function($atches) {
|
||||
return $this->hashes[$matches[0]][0];
|
||||
}, $text);
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,494 @@
|
||||
<?php
|
||||
/**
|
||||
* OEmbed
|
||||
*
|
||||
* This file is part of Grav MediaEmbed plugin.
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 3 licenses, see LICENSE.
|
||||
* http://benjamin-regler.de/license/
|
||||
*/
|
||||
|
||||
namespace Grav\Plugin\MediaEmbed\OEmbed;
|
||||
|
||||
use Grav\Common\GravTrait;
|
||||
use Grav\Common\Data\Data;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
|
||||
/**
|
||||
* OEmbed
|
||||
*/
|
||||
class OEmbed implements OEmbedInterface
|
||||
{
|
||||
use GravTrait;
|
||||
|
||||
/**
|
||||
* @var \Grav\Common\Data\Data
|
||||
*/
|
||||
protected $base_config;
|
||||
|
||||
/**
|
||||
* @var \Grav\Common\Data\Data
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $embedCode = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $attributes;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $params;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $oembed;
|
||||
|
||||
protected $protocol;
|
||||
|
||||
/** -------------
|
||||
* Public methods
|
||||
* --------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct(array $config = [])
|
||||
{
|
||||
$this->base_config = $this->config = new Data($config);
|
||||
|
||||
$schemes = $this->base_config->get('schemes', []);
|
||||
if (!is_array($schemes)) {
|
||||
$schemes = [$schemes];
|
||||
}
|
||||
|
||||
foreach ($schemes as $index => $scheme) {
|
||||
$scheme = preg_quote($scheme);
|
||||
|
||||
$schemes[$index] = preg_replace_callback('~((?:\\\\\*){1,2})(.[^\\\\]?|$)~',
|
||||
function($match) {
|
||||
// Remove control characters
|
||||
$separator = preg_replace('~[^\p{L}]~i', '', $match[2]);
|
||||
$star = strlen(str_replace('\\', '', $match[1]));
|
||||
|
||||
if (ctype_alnum($separator)) {
|
||||
$replace = '.*?';
|
||||
} else {
|
||||
$separator = (strlen($separator) == 0) ? substr($match[2], -1) : $separator;
|
||||
$replace = (strlen($match[2]) > 0) ? "[^$separator ]+" : '[^\"\&\?\. ]+';
|
||||
}
|
||||
|
||||
// Wrap one star result in parenthesis
|
||||
$replace = ($star > 1) ? $replace : "($replace)";
|
||||
return $replace . $match[2];
|
||||
}, $scheme);
|
||||
}
|
||||
$this->base_config->set('schemes', $schemes);
|
||||
}
|
||||
|
||||
public function init($embedCode, $config = [])
|
||||
{
|
||||
$this->reset();
|
||||
|
||||
// Normalize URL to embed
|
||||
$url = $this->parseUrl($embedCode);
|
||||
$this->embedCode = $this->canonicalize($embedCode);
|
||||
$this->oembed = new Data((array) $this->getOEmbed());
|
||||
|
||||
// Get media attributes and object parameters
|
||||
$attributes = [
|
||||
'width'=> $this->oembed->get('width', 0),
|
||||
'height' => $this->oembed->get('height', 0),
|
||||
'protocol' => ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://",
|
||||
];
|
||||
|
||||
// $this->config->merge($config);
|
||||
// $attributes = $this->config->get('media', []);
|
||||
$params = array_replace_recursive($this->config->get('params', []), $url['query']);
|
||||
|
||||
// Copy media attributes from object parameters
|
||||
$attr_keys = ['width', 'height', 'adjust', 'preview', 'responsive'];
|
||||
foreach ($attr_keys as $key) {
|
||||
if (isset($params[$key])) {
|
||||
$attributes[$key] = $params[$key];
|
||||
unset($params[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
// Set media attributes and object parameters
|
||||
$this->attributes($attributes);
|
||||
$this->params($params);
|
||||
}
|
||||
|
||||
public function canonicalize($embedCode)
|
||||
{
|
||||
$schemes = $this->config->get('schemes', []);
|
||||
foreach ($schemes as $scheme) {
|
||||
preg_match("~$scheme~i", $embedCode, $matches);
|
||||
if ($matches && $this->validId(end($matches))) {
|
||||
return end($matches);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a media id is valid.
|
||||
*
|
||||
* @param string $id Id to check against the oembed stream.
|
||||
*
|
||||
* @return boolean TRUE if id is valid, FALSE otherwise. Throws errors
|
||||
* on invalid ids.
|
||||
*/
|
||||
protected function validId($id)
|
||||
{
|
||||
$endpoint = $this->config->get('endpoint', '');
|
||||
$endpoint = $this->format($endpoint, ['{:id}' => $id]);
|
||||
|
||||
if (!$id || !$endpoint) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = \Requests::head($endpoint);
|
||||
// If a head request fails, try to send a get request
|
||||
if ($response->status_code != 200) {
|
||||
$response = \Requests::get($endpoint);
|
||||
}
|
||||
|
||||
if ( $response->status_code == 401 ) {
|
||||
throw new \Exception('Embedding has been disabled for this media.');
|
||||
} elseif ( $response->status_code == 404 ) {
|
||||
throw new \Exception('The media ID was not found.');
|
||||
} elseif ( $response->status_code == 501 ) {
|
||||
throw new \Exception('Media informations can not be retrieved.');
|
||||
} elseif ( $response->status_code != 200 ) {
|
||||
throw new \Exception('The media ID is invalid or the media was deleted.');
|
||||
} elseif (!$response->success) {
|
||||
$response->throw_for_status();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
// Reset values
|
||||
$this->embedCode = '';
|
||||
$this->oembed = null;
|
||||
|
||||
$this->attributes([], true);
|
||||
$this->params([], true);
|
||||
|
||||
$this->config = new Data($this->base_config->toArray());
|
||||
}
|
||||
|
||||
public function id()
|
||||
{
|
||||
return $this->embedCode;
|
||||
}
|
||||
|
||||
public function slug()
|
||||
{
|
||||
$slug = strtolower($this->name()) . '://' . $this->id();
|
||||
return $slug;
|
||||
}
|
||||
|
||||
public function name()
|
||||
{
|
||||
$name = get_class($this);
|
||||
$name = substr($name, strrpos($name, '\\') + 1);
|
||||
|
||||
if ($this->embedCode) {
|
||||
$name = $this->config->get('name', $name);
|
||||
if (mb_strlen($name) == 0 && $this->oembed) {
|
||||
$this->oembed->get('provider_name', '');
|
||||
}
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
public function title()
|
||||
{
|
||||
$title = '';
|
||||
if ($this->oembed) {
|
||||
$title = $this->oembed->get('title', '');
|
||||
}
|
||||
return $title;
|
||||
}
|
||||
|
||||
public function description()
|
||||
{
|
||||
$description = '';
|
||||
if ($this->oembed) {
|
||||
$description = $this->oembed->get('description', '');
|
||||
}
|
||||
return $description;
|
||||
}
|
||||
|
||||
public function url()
|
||||
{
|
||||
$url = '';
|
||||
if ($this->embedCode && $this->oembed) {
|
||||
$url = $this->format($this->config->get('url', ''), ['{:url}' => '']);
|
||||
if (strlen($url) == 0) {
|
||||
$url = $this->oembed->get('url', $url);
|
||||
} else {
|
||||
$protocol = isset($this->attributes['protocol']) ? $this->attributes['protocol'] : '//';
|
||||
$url = $protocol . $url;
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function website()
|
||||
{
|
||||
$website = '';
|
||||
if ($this->oembed) {
|
||||
$website = $this->oembed->get('provider_url', '');
|
||||
}
|
||||
return $website;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a png img
|
||||
*
|
||||
* @param array $stub or string $alias
|
||||
* @return Resource or null if not available
|
||||
*/
|
||||
public function icon() {
|
||||
$icon = '';
|
||||
|
||||
$endpoint = '';
|
||||
if ($this->oembed) {
|
||||
$endpoint = $this->format($this->config->get('endpoint', ''));
|
||||
}
|
||||
|
||||
if (!$endpoint) {
|
||||
return $icon;
|
||||
}
|
||||
|
||||
$pieces = parse_url($endpoint);
|
||||
$url = $pieces['host'];
|
||||
|
||||
// Grab favicon from Google cache
|
||||
$icon = 'http://www.google.com/s2/favicons?domain=';
|
||||
$icon .= urlencode($url);
|
||||
|
||||
return $icon;
|
||||
}
|
||||
|
||||
public function thumbnail()
|
||||
{
|
||||
$thumbnail = '';
|
||||
if ($this->oembed) {
|
||||
$thumbnail = $this->oembed->get('thumbnail_url', '');
|
||||
}
|
||||
return $thumbnail;
|
||||
}
|
||||
|
||||
public function type()
|
||||
{
|
||||
$type = $this->config->get('type', 'generic');
|
||||
if ($type === 'generic' && $this->embedCode && $this->oembed) {
|
||||
$type = $this->oembed->get('type', $type);
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
public function author($key = 'name')
|
||||
{
|
||||
$author = '';
|
||||
if ($this->embedCode && $this->oembed) {
|
||||
$author = $this->oembed->get('author_' . strtolower($key), '');
|
||||
}
|
||||
return $author;
|
||||
}
|
||||
|
||||
public function attributes($var = null, $reset = false)
|
||||
{
|
||||
if ($var !== null) {
|
||||
if ($reset) {
|
||||
$this->attributes = $var;
|
||||
} else {
|
||||
$this->attributes = array_replace_recursive($this->attributes, $var);
|
||||
}
|
||||
}
|
||||
if (!is_array($this->attributes)) {
|
||||
$this->attributes = [];
|
||||
}
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
public function params($var = null, $reset = false)
|
||||
{
|
||||
if ($var !== null) {
|
||||
if ($reset) {
|
||||
$this->params = $var;
|
||||
} else {
|
||||
$this->params = array_replace_recursive($this->params, $var);
|
||||
}
|
||||
}
|
||||
if (!is_array($this->params)) {
|
||||
$this->params = [];
|
||||
}
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
public function getEmbedCode($params = [])
|
||||
{
|
||||
$params = array_replace_recursive($this->params(), $params);
|
||||
$url = $this->url();
|
||||
|
||||
$query = http_build_query($params);
|
||||
if (mb_strlen($query) > 0) {
|
||||
$query = (false === strpos($url, '?') ? '?' : '&') . $query;
|
||||
}
|
||||
return $url . $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about the media. See http://www.oembed.com/.
|
||||
*
|
||||
* @return
|
||||
* If oEmbed information is available, an array containing 'title', 'type',
|
||||
* 'url', and other information as specified by the oEmbed standard.
|
||||
* Otherwise, NULL.
|
||||
*/
|
||||
public function getOEmbed()
|
||||
{
|
||||
if ($this->oembed) {
|
||||
return $this->oembed;
|
||||
}
|
||||
|
||||
$endpoint = $this->format($this->config->get('endpoint', ''));
|
||||
if (!$endpoint) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$response = \Requests::get($endpoint);
|
||||
if (!$response->success) {
|
||||
$response->throw_for_status();
|
||||
}
|
||||
|
||||
return json_decode($response->body, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the domain(s) of this media resource
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDomains()
|
||||
{
|
||||
// Get domains of media resources
|
||||
$schemes = $this->base_config->get('schemes', []);
|
||||
|
||||
// Ensure domains are of type array
|
||||
if (!is_array($schemes)) {
|
||||
$schemes = [$schemes];
|
||||
}
|
||||
|
||||
$domains = [];
|
||||
foreach ($schemes as $scheme) {
|
||||
// Trick: extract domains from scheme attributes
|
||||
$domain = parse_url(str_replace('\.', '.', "http://$scheme"), PHP_URL_HOST);
|
||||
|
||||
// Take out the www. in front of domain
|
||||
$domains[] = preg_replace("/^www\./", '', $domain);
|
||||
}
|
||||
|
||||
// Faster alternative to PHP’s array unique function
|
||||
return array_keys(array_flip($domains));
|
||||
}
|
||||
|
||||
public function onTwigTemplateVariables(Event $event)
|
||||
{
|
||||
$mediaembed = $event['mediaembed'];
|
||||
foreach ($this->config->get('assets', []) as $asset) {
|
||||
if (is_string($asset) && strlen($asset) > 0) {
|
||||
$mediaembed->add($asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience wrapper for `echo $ServiceProvider`
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getEmbedCode();
|
||||
}
|
||||
|
||||
/** -------------------------------
|
||||
* Private/protected helper methods
|
||||
* --------------------------------
|
||||
*/
|
||||
|
||||
protected function format($string, $params = [])
|
||||
{
|
||||
$keys = ['id', 'name', 'url'];
|
||||
foreach ($keys as $key) {
|
||||
if (!isset($params["{:$key}"])) {
|
||||
$params["{:$key}"] = $this->{$key}();
|
||||
}
|
||||
}
|
||||
$params += [
|
||||
'{:canonical}' => $this->config->get('canonical', ''),
|
||||
];
|
||||
|
||||
// Format URL placeholder with params
|
||||
$keys = ['{:url}', '{:canonical}'];
|
||||
foreach ($keys as $key) {
|
||||
$params[$key] = urlencode(str_ireplace(
|
||||
array_keys($params), $params, $params[$key])
|
||||
);
|
||||
}
|
||||
|
||||
// Replace OEmbed calls with response
|
||||
$string = preg_replace_callback('~\{\:oembed(?:\.(?=\w))([\.\w_]+)?\}~i',
|
||||
function($match) {
|
||||
$ombed = $this->getOEmbed();
|
||||
return $oembed ? $oembed->get($match[1], '') : $match[0];
|
||||
}, $string);
|
||||
|
||||
return str_ireplace(array_keys($params), $params, $string);
|
||||
}
|
||||
|
||||
protected function parseUrl($url)
|
||||
{
|
||||
if (!filter_var($url, FILTER_VALIDATE_URL)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Parse URL
|
||||
$url = html_entity_decode($url, ENT_COMPAT | ENT_HTML401, 'UTF-8');
|
||||
$parts = parse_url($url);
|
||||
$parts['url'] = $url;
|
||||
|
||||
// Get top-level domain from URL
|
||||
$parts['domain'] = isset($parts['host']) ? $parts['host'] : '';
|
||||
if ( preg_match('~(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$~i', $parts['domain'], $match) ) {
|
||||
$parts['domain'] = $match['domain'];
|
||||
}
|
||||
|
||||
if (isset($parts['query'])) {
|
||||
parse_str(urldecode($parts['query']), $parts['query']);
|
||||
} else {
|
||||
$parts['query'] = [];
|
||||
}
|
||||
|
||||
return $parts;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
/**
|
||||
* OEmbedInterface
|
||||
*
|
||||
* This file is part of Grav MediaEmbed plugin.
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 3 licenses, see LICENSE.
|
||||
* http://benjamin-regler.de/license/
|
||||
*/
|
||||
|
||||
namespace Grav\Plugin\MediaEmbed\OEmbed;
|
||||
|
||||
/**
|
||||
* OEmbedInterface
|
||||
*/
|
||||
interface OEmbedInterface
|
||||
{
|
||||
/**
|
||||
* Initialize service.
|
||||
*/
|
||||
public function init($embedCode, $config = []);
|
||||
|
||||
/**
|
||||
* Reset service.
|
||||
*/
|
||||
public function reset();
|
||||
|
||||
/**
|
||||
* Extract and normalize id from embed code.
|
||||
*
|
||||
* @param string $embedCode The embed code to be canonicalized
|
||||
* @return string Returns the canonicalized embed code,
|
||||
* usually an id.
|
||||
*/
|
||||
public function canonicalize($embedCode);
|
||||
|
||||
/**
|
||||
* Returns the unique id of a media resource.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function id();
|
||||
|
||||
/**
|
||||
* Returns the host as slugged string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function slug();
|
||||
|
||||
/**
|
||||
* Returns the name of this media.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function name();
|
||||
|
||||
/**
|
||||
* Returns the title of this media.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function title();
|
||||
|
||||
/**
|
||||
* Returns the description of this media.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function description();
|
||||
|
||||
/**
|
||||
* The URL of this media
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url();
|
||||
|
||||
/**
|
||||
* The website where this media come from.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function website();
|
||||
|
||||
/**
|
||||
* Gets the thumbnail of the media and its dimensions.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function thumbnail();
|
||||
|
||||
/**
|
||||
* Returns the type of this media.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function type();
|
||||
|
||||
/**
|
||||
* Gets the author and informations about him from the media.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function author($key = 'name');
|
||||
|
||||
/**
|
||||
* Gets or sets object attributes about the media
|
||||
*
|
||||
* @param bool $var Media attributes
|
||||
*
|
||||
* @return array Returns object attributes about the media i.e.
|
||||
* width, height and so on.
|
||||
*/
|
||||
public function attributes($var = [], $reset = false);
|
||||
|
||||
/**
|
||||
* Gets or sets object parameter about the media
|
||||
*
|
||||
* @param bool $var Media parameter.
|
||||
*
|
||||
* @return array Returns the object parameter about the media i.e.
|
||||
* additional parameter for the request
|
||||
*/
|
||||
public function params($var = [], $reset = false);
|
||||
|
||||
/**
|
||||
* Returns the final HTML code for display.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEmbedCode($params = []);
|
||||
|
||||
/**
|
||||
* Returns information about the media. See http://www.oembed.com/.
|
||||
*
|
||||
* @return
|
||||
* If oEmbed information is available, an array containing 'title', 'type',
|
||||
* 'url', and other information as specified by the oEmbed standard.
|
||||
* Otherwise, NULL.
|
||||
*/
|
||||
public function getOEmbed();
|
||||
|
||||
/**
|
||||
* Returns the accepted domains of this media resource
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDomains();
|
||||
|
||||
/**
|
||||
* Special Template events fired by Grav\Plugin\MediaEmbed\Service.
|
||||
*/
|
||||
// public function onTwigTemplatePaths();
|
||||
// public function onTwigTemplateVariables(Event $event);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* OEmbedLink
|
||||
*
|
||||
* This file is part of Grav MediaEmbed plugin.
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 3 licenses, see LICENSE.
|
||||
* http://benjamin-regler.de/license/
|
||||
*/
|
||||
|
||||
namespace Grav\Plugin\MediaEmbed\OEmbed;
|
||||
|
||||
use Grav\Plugin\MediaEmbed\OEmbed\OEmbed;
|
||||
|
||||
/**
|
||||
* OEmbedLink
|
||||
*
|
||||
* Responses of this type allow a provider to return any generic embed
|
||||
* data (such as title and author_name), without providing either the
|
||||
* url or html parameters. The consumer may then link to the resource,
|
||||
* using the URL specified in the original request.
|
||||
*/
|
||||
class OEmbedLink extends OEmbed
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* OEmbedPhoto
|
||||
*
|
||||
* This file is part of Grav MediaEmbed plugin.
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 3 licenses, see LICENSE.
|
||||
* http://benjamin-regler.de/license/
|
||||
*/
|
||||
|
||||
namespace Grav\Plugin\MediaEmbed\OEmbed;
|
||||
|
||||
use Grav\Plugin\MediaEmbed\OEmbed\OEmbed;
|
||||
|
||||
/**
|
||||
* OEmbedPhoto
|
||||
*
|
||||
* This type is used for representing static photos. The following
|
||||
* parameters are defined:
|
||||
*
|
||||
* url (required)
|
||||
* The source URL of the image. Consumers should be able to insert
|
||||
* this URL into an <img> element. Only HTTP and HTTPS URLs are valid.
|
||||
*
|
||||
* width (required)
|
||||
* The width in pixels of the image specified in the url parameter.
|
||||
*
|
||||
* height (required)
|
||||
* The height in pixels of the image specified in the url parameter.
|
||||
*
|
||||
* Responses of this type must obey the maxwidth and maxheight request
|
||||
* parameter.
|
||||
*/
|
||||
class OEmbedPhoto extends OEmbed
|
||||
{
|
||||
public function getOEmbed()
|
||||
{
|
||||
$oembed = parent::getOEmbed();
|
||||
|
||||
if ($this->embedCode && $this->oembed) {
|
||||
$width = $this->oembed->get('width');
|
||||
$height = $this->oembed->get('height');
|
||||
$this->attributes(['width' => $width, 'height' => $height]);
|
||||
}
|
||||
|
||||
return $oembed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* OEmbedRich
|
||||
*
|
||||
* This file is part of Grav MediaEmbed plugin.
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 3 licenses, see LICENSE.
|
||||
* http://benjamin-regler.de/license/
|
||||
*/
|
||||
|
||||
namespace Grav\Plugin\MediaEmbed\OEmbed;
|
||||
|
||||
use Grav\Plugin\MediaEmbed\OEmbed\OEmbed;
|
||||
|
||||
/**
|
||||
* OEmbedRich
|
||||
*
|
||||
* This type is used for rich HTML content that does not fall under one
|
||||
* of the other categories. The following parameters are defined:
|
||||
*
|
||||
* html (required)
|
||||
* The HTML required to display the resource. The HTML should have no
|
||||
* padding or margins. Consumers may wish to load the HTML in an
|
||||
* off-domain iframe to avoid XSS vulnerabilities. The markup should
|
||||
* be valid XHTML 1.0 Basic.
|
||||
*
|
||||
* width (required)
|
||||
* The width in pixels required to display the HTML.
|
||||
*
|
||||
* height (required)
|
||||
* The height in pixels required to display the HTML.
|
||||
*
|
||||
* Responses of this type must obey the maxwidth and maxheight request
|
||||
* parameters.
|
||||
*/
|
||||
class OEmbedRich extends OEmbed
|
||||
{
|
||||
public function getOEmbed()
|
||||
{
|
||||
$oembed = parent::getOEmbed();
|
||||
|
||||
$sizes = ['width', 'height'];
|
||||
foreach ($sizes as $key) {
|
||||
$size = isset($oembed[$key]) ? $oembed[$key] : 0;
|
||||
if (!preg_match('~^\d+$~', $size)) {
|
||||
$oembed[$key] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return $oembed;
|
||||
}
|
||||
|
||||
public function getEmbedCode($params = [])
|
||||
{
|
||||
$embed = parent::getEmbedCode($params);
|
||||
if ($this->embedCode && $this->oembed) {
|
||||
$embed = $this->oembed->get('html', '');
|
||||
}
|
||||
|
||||
return $embed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* OEmbedVideo
|
||||
*
|
||||
* This file is part of Grav MediaEmbed plugin.
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 3 licenses, see LICENSE.
|
||||
* http://benjamin-regler.de/license/
|
||||
*/
|
||||
|
||||
namespace Grav\Plugin\MediaEmbed\OEmbed;
|
||||
|
||||
use Grav\Plugin\MediaEmbed\OEmbed\OEmbed;
|
||||
|
||||
/**
|
||||
* OEmbedVideo
|
||||
*
|
||||
* This type is used for representing playable videos. The following
|
||||
* parameters are defined:
|
||||
*
|
||||
* html (required)
|
||||
* The HTML required to embed a video player. The HTML should have
|
||||
* no padding or margins. Consumers may wish to load the HTML in an
|
||||
* off-domain iframe to avoid XSS vulnerabilities.
|
||||
*
|
||||
* width (required)
|
||||
* The width in pixels required to display the HTML.
|
||||
*
|
||||
* height (required)
|
||||
* The height in pixels required to display the HTML.
|
||||
*
|
||||
* Responses of this type must obey the maxwidth and maxheight request
|
||||
* parameters. If a provider wishes the consumer to just provide a
|
||||
* thumbnail, rather than an embeddable player, they should instead
|
||||
* return a photo response type.
|
||||
*/
|
||||
class OEmbedVideo extends OEmbed
|
||||
{
|
||||
public function getOEmbed()
|
||||
{
|
||||
$oembed = parent::getOEmbed();
|
||||
|
||||
if ($this->embedCode && $this->oembed) {
|
||||
$width = $this->oembed->get('width');
|
||||
$height = $this->oembed->get('height');
|
||||
$this->attributes(['width' => $width, 'height' => $height]);
|
||||
}
|
||||
|
||||
return $oembed;
|
||||
}
|
||||
|
||||
public function getEmbedCode($params = [])
|
||||
{
|
||||
$embed = parent::getEmbedCode($params);
|
||||
if (mb_strlen($embed) == 0 && $this->embedCode && $this->oembed) {
|
||||
$embed = $this->oembed->get('html', '');
|
||||
}
|
||||
|
||||
return $embed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/**
|
||||
* ProviderInterface
|
||||
*
|
||||
* This file is part of Grav MediaEmbed plugin.
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 3 licenses, see LICENSE.
|
||||
* http://benjamin-regler.de/license/
|
||||
*/
|
||||
|
||||
namespace Grav\Plugin\MediaEmbed;
|
||||
|
||||
/**
|
||||
* ProviderInterface
|
||||
*/
|
||||
interface ProviderInterface
|
||||
{
|
||||
/**
|
||||
* Initialize service.
|
||||
*/
|
||||
public function init($embedCode);
|
||||
|
||||
/**
|
||||
* Reset service.
|
||||
*/
|
||||
public function reset();
|
||||
|
||||
/**
|
||||
* Extract and normalize id from embed code.
|
||||
*
|
||||
* @param string $embedCode The embed code to be canonicalized
|
||||
* @return string Returns the canonicalized embed code,
|
||||
* usually an id.
|
||||
*/
|
||||
public function canonicalize($embedCode);
|
||||
|
||||
/**
|
||||
* Returns the unique id of a media resource.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function id();
|
||||
|
||||
/**
|
||||
* Returns the host as slugged string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function slug();
|
||||
|
||||
/**
|
||||
* Returns the name of this media.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function name();
|
||||
|
||||
/**
|
||||
* Returns the type of this media.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function type();
|
||||
|
||||
|
||||
/**
|
||||
* Gets or sets object attributes about the media
|
||||
*
|
||||
* @param bool $var Media attributes
|
||||
*
|
||||
* @return array Returns object attributes about the media i.e.
|
||||
* width, height and so on.
|
||||
*/
|
||||
public function attributes($var = []);
|
||||
|
||||
/**
|
||||
* Gets or sets object parameter about the media
|
||||
*
|
||||
* @param bool $var Media parameter.
|
||||
*
|
||||
* @return array Returns the object parameter about the media i.e.
|
||||
* additional parameter for the request
|
||||
*/
|
||||
public function params($var = []);
|
||||
|
||||
/**
|
||||
* Returns the final HTML code for display.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEmbedCode();
|
||||
|
||||
/**
|
||||
* Returns information about the media. See http://www.oembed.com/.
|
||||
*
|
||||
* @return
|
||||
* If oEmbed information is available, an array containing 'title', 'type',
|
||||
* 'url', and other information as specified by the oEmbed standard.
|
||||
* Otherwise, NULL.
|
||||
*/
|
||||
public function getOEmbed();
|
||||
|
||||
/**
|
||||
* Returns the accepted domains of this media resource
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDomains();
|
||||
|
||||
/**
|
||||
* Special Template events fired by Grav\Plugin\MediaEmbed\Service.
|
||||
*/
|
||||
// public function onTwigTemplatePaths();
|
||||
// public function onTwigTemplateVariables(Event $event);
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
<?php
|
||||
/**
|
||||
* Service
|
||||
*
|
||||
* This file is part of Grav MediaEmbed plugin.
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 3 licenses, see LICENSE.
|
||||
* http://benjamin-regler.de/license/
|
||||
*/
|
||||
|
||||
namespace Grav\Plugin\MediaEmbed;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\GravTrait;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
|
||||
/**
|
||||
* Service
|
||||
*/
|
||||
class Service
|
||||
{
|
||||
/**
|
||||
* @var Service
|
||||
*/
|
||||
use GravTrait;
|
||||
|
||||
/** ---------------------------
|
||||
* Private/protected properties
|
||||
* ----------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* @var Grav\Plugin\MediaEmbed\ServiceProvider
|
||||
*/
|
||||
protected $services = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $domains;
|
||||
|
||||
/** -------------
|
||||
* Public methods
|
||||
* --------------
|
||||
*/
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// Fire event
|
||||
self::getGrav()->fireEvent('onMediaEmbed', new Event(['service' => $this]));
|
||||
}
|
||||
|
||||
public function call($method, $params = [])
|
||||
{
|
||||
$result = [];
|
||||
foreach ($this->services as $key => $service) {
|
||||
if (method_exists($service['provider'], $method)) {
|
||||
$data = call_user_method_array([$service['provider'], $method], $params);
|
||||
if ($data) {
|
||||
$result[] = $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function match($url, $embedCode = null)
|
||||
{
|
||||
$embed_key = 'embed';
|
||||
if ($embedCode && (strtolower($embedCode) !== $embed_key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parts = $this->parseUrl($url);
|
||||
if ($parts['host'] == $embed_key) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isset($this->domains[$parts['host']]);
|
||||
}
|
||||
|
||||
public function embed($embedCode, $options = [])
|
||||
{
|
||||
if (!$this->match($embedCode)) {
|
||||
throw new \Exception('Unknown embed code "' . htmlspecialchars($embedCode) . '".');
|
||||
}
|
||||
|
||||
// Extract domain from embed code
|
||||
$domain = strtolower($this->parseUrl($embedCode)['host']);
|
||||
$key = $this->domains[$domain];
|
||||
|
||||
// Call OEmbed service provider
|
||||
$provider = $this->services[$key]['provider'];
|
||||
$provider->init($embedCode, $options);
|
||||
|
||||
// Return initialized provider
|
||||
return $provider;
|
||||
|
||||
// // Get type of media
|
||||
// $type = ucfirst($provider->type());
|
||||
|
||||
// // Get the default properties of the response class
|
||||
// $class = __NAMESPACE__ . "\\Response\\{$type}Response";
|
||||
|
||||
// // Repopulate properties
|
||||
// $vars = [
|
||||
// 'raw' => $embedCode,
|
||||
// 'options' => $provider->attributes(),
|
||||
// 'url' => $provider->getEmbedCode(,
|
||||
// ] + get_class_vars($class);
|
||||
|
||||
// // Enrich properties with media resource informations
|
||||
// foreach ($vars as $key => $value) {
|
||||
// if (!$value) {
|
||||
// $vars[$key] = $provider->{$key}();
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Create response
|
||||
// $response = new $class($vars);
|
||||
|
||||
// return [$provider, $response];
|
||||
|
||||
// try {
|
||||
// // Call ServiceProvider
|
||||
// $provider->init($embedCode);
|
||||
|
||||
// $embed += array(
|
||||
// // Get unique id of video
|
||||
// 'id' => $provider->canonicalize($embedCode),
|
||||
|
||||
// // Templates are stored in the templates/partials folder
|
||||
// 'assets' => $provider->getAssets(),
|
||||
// 'template' => $provider->getTemplatePaths(),
|
||||
// 'variables' => $provider->getTemplateVariables(),
|
||||
|
||||
// // Store embed status of ServiceProvider call
|
||||
// 'success' => true,
|
||||
// 'message' => '',
|
||||
// );
|
||||
// } catch (\Exception $e) {
|
||||
// $embed['success'] = false;
|
||||
// $embed['message'] = $e->getMessage();
|
||||
// }
|
||||
// }
|
||||
|
||||
// return $embed;
|
||||
}
|
||||
|
||||
public function getDomains()
|
||||
{
|
||||
$allDomains = [];
|
||||
foreach ($this->services as $key => $service) {
|
||||
$allDomains[] = $service['domains'];
|
||||
}
|
||||
|
||||
// Flatten multidimensional array of domains
|
||||
$domains = [];
|
||||
array_walk($allDomains, function($domain) use (&$domains) {
|
||||
$domains[] = $domain;
|
||||
});
|
||||
|
||||
// Return unique array of domains
|
||||
return array_unique($domains);
|
||||
}
|
||||
|
||||
public function getProviders()
|
||||
{
|
||||
// Get providers sorted by priority
|
||||
$classes = $this->collectProviders(function($key, $service) {
|
||||
return true;
|
||||
}, true, 'class');
|
||||
|
||||
// Replace names with provider classes
|
||||
$providers = [];
|
||||
foreach ($classes as $class) {
|
||||
$name = substr($class, strrpos($class, '\\') + 1);
|
||||
$provider = $this->services[$class]['provider'];
|
||||
|
||||
if ( isset($providers[$name]) ) {
|
||||
$providers[$name] = array($providers[$name], $provider);
|
||||
} else {
|
||||
$providers[$name][] = $provider;
|
||||
}
|
||||
}
|
||||
|
||||
return $providers;
|
||||
}
|
||||
|
||||
public function getProviderByName($name, $all = false)
|
||||
{
|
||||
$providers = $this->collectProviders(
|
||||
function($key, $service) use ($name) {
|
||||
return preg_match("~^$name$~i", $service['name']);
|
||||
}, $all);
|
||||
|
||||
return $providers;
|
||||
}
|
||||
|
||||
public function getProviderByDomain($domain, $all = false)
|
||||
{
|
||||
$providers = $this->collectProviders(
|
||||
function($key, $service) use ($domain) {
|
||||
return in_array($domain, $service['domains']);
|
||||
}, $all);
|
||||
|
||||
return $providers;
|
||||
}
|
||||
|
||||
public function register($provider, $priority = 0)
|
||||
{
|
||||
if ($provider instanceof \Grav\Plugin\MediaEmbed\OEmbed\OEmbed) {
|
||||
$key = md5(spl_object_hash($provider));
|
||||
$domains = $provider->getDomains();
|
||||
|
||||
$this->services[$key] = array(
|
||||
'priority' => $priority,
|
||||
'domains' => $domains,
|
||||
'provider' => $provider,
|
||||
'name' => $provider->name(),
|
||||
'class' => $key,
|
||||
);
|
||||
|
||||
foreach ($domains as $domain) {
|
||||
if (!isset($this->domains[$domain]) || ($priority > $this->services[$domain]['priority'])) {
|
||||
$this->domains[$domain] = $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function unregister($provider)
|
||||
{
|
||||
if ($provider instanceof \Grav\Plugin\MediaEmbed\OEmbed\OEmbed) {
|
||||
$key = md5(spl_object_hash($provider));
|
||||
if (isset($this->services[$key])) {
|
||||
$domains = $this->services[$key]['domains'];
|
||||
unset($this->services[$key]);
|
||||
|
||||
// Unset and repopulate domain keys, if possible
|
||||
foreach ($domains as $domain) {
|
||||
if ($provider = $this->getProviderByDomain($domain)) {
|
||||
$this->domains[$domain] = get_class($provider);
|
||||
} else {
|
||||
unset($this->domains[$domain]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function collectProviders($callback, $all, $id = 'provider')
|
||||
{
|
||||
$services = [];
|
||||
foreach ($this->services as $key => $service) {
|
||||
if ($callback($key, $service)) {
|
||||
$services[] = $service;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort providers based on priority
|
||||
uasort($services, function ($a, $b) {
|
||||
// Priority is first sort criterion
|
||||
$cmp = $a['priority'] - $b['priority'];
|
||||
|
||||
// Text string is second criterion (in case of two equal priorities)
|
||||
if ( $cmp == 0 ) {
|
||||
$cmp = strnatcmp($a['name'], $b['name']);
|
||||
}
|
||||
|
||||
return $cmp;
|
||||
});
|
||||
|
||||
// Strip additional service informations
|
||||
$providers = array_map(function($service) use ($id) {
|
||||
return $service[$id];
|
||||
}, $services);
|
||||
|
||||
if (count($providers)) {
|
||||
// Return providers
|
||||
return ($all ? $providers : $providers[0]);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/** -------------------------------
|
||||
* Private/protected helper methods
|
||||
* --------------------------------
|
||||
*/
|
||||
|
||||
protected function parseUrl($url)
|
||||
{
|
||||
if (!filter_var($url, FILTER_VALIDATE_URL)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Parse URL
|
||||
$url = html_entity_decode($url, ENT_COMPAT | ENT_HTML401, 'UTF-8');
|
||||
$parts = parse_url($url);
|
||||
$parts['url'] = $url;
|
||||
$parts['host'] = preg_replace("/^www\./", '', $parts['host']);
|
||||
|
||||
// Get top-level domain from URL
|
||||
$parts['domain'] = isset($parts['host']) ? $parts['host'] : '';
|
||||
if ( preg_match('~(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$~i', $parts['domain'], $match) ) {
|
||||
$parts['domain'] = $match['domain'];
|
||||
}
|
||||
|
||||
if (isset($parts['query'])) {
|
||||
parse_str(urldecode($parts['query']), $parts['query']);
|
||||
}
|
||||
$parts['query'] = [];
|
||||
|
||||
return $parts;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
/**
|
||||
* ServiceProvider
|
||||
*
|
||||
* This file is part of Grav MediaEmbed plugin.
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 3 licenses, see LICENSE.
|
||||
* http://benjamin-regler.de/license/
|
||||
*/
|
||||
|
||||
namespace Grav\Plugin\MediaEmbed;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\GravTrait;
|
||||
use Grav\Common\Data\Data;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
|
||||
/**
|
||||
* ServiceProvider
|
||||
*/
|
||||
abstract class ServiceProvider implements ProviderInterface
|
||||
{
|
||||
use GravTrait;
|
||||
/**
|
||||
* @var \Grav\Common\Data\Data
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $embedCode = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $attributes;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $params;
|
||||
|
||||
/** -------------
|
||||
* Public methods
|
||||
* --------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct(array $config = [])
|
||||
{
|
||||
$this->config = new Data($config);
|
||||
}
|
||||
|
||||
public function init($embedCode)
|
||||
{
|
||||
$this->reset();
|
||||
|
||||
// Normalize URL to embed
|
||||
$this->embedCode = $this->canonicalize($embedCode);
|
||||
$url = $this->parseUrl($embedCode);
|
||||
|
||||
// Get media attributes and object parameters
|
||||
$attributes = $this->config->get('media', []);
|
||||
$params = array_replace_recursive($this->config->get('params', []), $url['query']);
|
||||
|
||||
// Copy media attributes from object parameters
|
||||
$attr_keys = ['width', 'height', 'crop', 'preview', 'responsive'];
|
||||
foreach ($attr_keys as $key) {
|
||||
if (isset($params[$key])) {
|
||||
$attributes[$key] = $params[$key];
|
||||
unset($params[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
// Set media attributes and object parameters
|
||||
$this->attributes($attributes);
|
||||
$this->params($params);
|
||||
}
|
||||
|
||||
public function reset() {
|
||||
// Reset values
|
||||
$this->embedCode = '';
|
||||
|
||||
$this->attributes([]);
|
||||
$this->params([]);
|
||||
}
|
||||
|
||||
public function id()
|
||||
{
|
||||
return $this->embedCode;
|
||||
}
|
||||
|
||||
public function slug()
|
||||
{
|
||||
$slug = strtolower($this->name()) . '://' . $this->id();
|
||||
return $slug;
|
||||
}
|
||||
|
||||
public function name()
|
||||
{
|
||||
$name = $this->config->get('name', get_class($this));
|
||||
return substr($name, strrpos($name, '\\') + 1);
|
||||
}
|
||||
|
||||
public function type()
|
||||
{
|
||||
return $this->config->get('type', 'unknown');
|
||||
}
|
||||
|
||||
public function thumbnail() {
|
||||
$thumbnails = $this->config->get('thumbnail', []);
|
||||
if (is_string($thumbnails)) {
|
||||
$thumbnails = [$thumbnails];
|
||||
}
|
||||
|
||||
$url = '';
|
||||
foreach ($thumbnails as $thumbnail) {
|
||||
$thumbnail = $this->format($thumbnail);
|
||||
if (substr(get_headers($thumbnail)[0], -6) == '200 OK') {
|
||||
$url = $thumbnail;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function attributes($var = null)
|
||||
{
|
||||
if ($var !== null) {
|
||||
$this->attributes = $var;
|
||||
}
|
||||
if (!is_array($this->attributes)) {
|
||||
$this->attributes = [];
|
||||
}
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
public function params($var = null)
|
||||
{
|
||||
if ($var !== null) {
|
||||
$this->params = $var;
|
||||
}
|
||||
if (!is_array($this->params)) {
|
||||
$this->params = [];
|
||||
}
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the domain(s) of this media resource
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
// public function getDomains()
|
||||
// {
|
||||
// return [];
|
||||
// }
|
||||
|
||||
public function onTwigTemplateVariables(Event $event)
|
||||
{
|
||||
$mediaembed = $event['mediaembed'];
|
||||
foreach ($this->config->get('assets', []) as $asset) {
|
||||
$mediaembed->add($asset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience wrapper for `echo $ServiceProvider`
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString() {
|
||||
return $this->getEmbedCode();
|
||||
}
|
||||
|
||||
/** -------------------------------
|
||||
* Private/protected helper methods
|
||||
* --------------------------------
|
||||
*/
|
||||
|
||||
protected function format($string, $params = [])
|
||||
{
|
||||
$params += [
|
||||
'{:id}' => $this->id(),
|
||||
'{:name}' => $this->name(),
|
||||
'{:url}' => urlencode($this->config->get('website', '')),
|
||||
];
|
||||
|
||||
// Format URL placeholder with params
|
||||
$params['{:url}'] = urlencode(str_ireplace(array_keys($params), $params, $params['{:url}']));
|
||||
|
||||
$string = preg_replace_callback('~\{\:oembed(?:\.(?=\w))([\.\w_]+)?\}~i',
|
||||
function($match) {
|
||||
static $oembed;
|
||||
|
||||
if (is_null($oembed)) {
|
||||
$oembed = new Data($this->getOEmbed());
|
||||
}
|
||||
|
||||
return $oembed->get($match[1], '');
|
||||
}, $string);
|
||||
|
||||
return str_ireplace(array_keys($params), $params, $string);
|
||||
}
|
||||
|
||||
protected function parseUrl($url)
|
||||
{
|
||||
if (!filter_var($url, FILTER_VALIDATE_URL)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Parse URL
|
||||
$url = html_entity_decode($url, ENT_COMPAT | ENT_HTML401, 'UTF-8');
|
||||
$parts = parse_url($url);
|
||||
$parts['url'] = $url;
|
||||
|
||||
// Get top-level domain from URL
|
||||
$parts['domain'] = isset($parts['host']) ? $parts['host'] : '';
|
||||
if ( preg_match('~(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$~i', $parts['domain'], $match) ) {
|
||||
$parts['domain'] = $match['domain'];
|
||||
}
|
||||
|
||||
if (isset($parts['query'])) {
|
||||
parse_str(urldecode($parts['query']), $parts['query']);
|
||||
}
|
||||
$parts['query'] = [];
|
||||
|
||||
return $parts;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* GitHub
|
||||
*
|
||||
* This file is part of Grav MediaEmbed plugin.
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 3 licenses, see LICENSE.
|
||||
* http://benjamin-regler.de/license/
|
||||
*/
|
||||
|
||||
namespace Grav\Plugin\MediaEmbed\Services;
|
||||
|
||||
use Grav\Common\Debugger;
|
||||
use Grav\Plugin\MediaEmbed\OEmbed\OEmbedRich;
|
||||
|
||||
/**
|
||||
* GitHub
|
||||
*/
|
||||
class GitHub extends OEmbedRich
|
||||
{
|
||||
|
||||
public function getOEmbed()
|
||||
{
|
||||
if ($this->oembed) {
|
||||
return $this->oembed;
|
||||
}
|
||||
|
||||
$endpoint = $this->format($this->config->get('endpoint', ''));
|
||||
|
||||
if (!$endpoint) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$response = \Requests::get($endpoint);
|
||||
if (!$response->success) {
|
||||
$response->throw_for_status();
|
||||
}
|
||||
|
||||
$json = json_decode($response->body, true);
|
||||
|
||||
$this->oembed = [
|
||||
'type' => 'rich',
|
||||
'title' => $json['files'],
|
||||
'description' => $json['description'],
|
||||
'author_name' => $json['owner'],
|
||||
'author_url' => 'https://github.com/' . $json['owner'],
|
||||
'provider' => 'GitHub',
|
||||
'provider_url' => 'https://gist.github.com/',
|
||||
'url' => 'https://gist.github.com/' . $this->embedCode,
|
||||
'html' => $json['div'],
|
||||
];
|
||||
|
||||
$this->config->join('assets', [$json['stylesheet']]);
|
||||
return $this->oembed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* Slides.com
|
||||
*
|
||||
* This file is part of Grav MediaEmbed plugin.
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 3 licenses, see LICENSE.
|
||||
* http://benjamin-regler.de/license/
|
||||
*/
|
||||
|
||||
namespace Grav\Plugin\MediaEmbed\Services;
|
||||
|
||||
use Grav\Plugin\MediaEmbed\OEmbed\OEmbedRich;
|
||||
|
||||
/**
|
||||
* Slides
|
||||
*/
|
||||
class Slides extends OEmbedRich
|
||||
{
|
||||
public function getOEmbed()
|
||||
{
|
||||
if ($this->oembed) {
|
||||
return $this->oembed;
|
||||
}
|
||||
|
||||
$endpoint = $this->format($this->config->get('endpoint', ''));
|
||||
if (!$endpoint) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Extract owner from embed code
|
||||
list($owner, $id) = explode('/', $this->embedCode, 2);
|
||||
|
||||
// Fake response
|
||||
$this->oembed = [
|
||||
'type' => 'rich',
|
||||
'title' => '',
|
||||
'description' => '',
|
||||
'author_name' => $owner,
|
||||
'author_url' => 'http://slides.com/'.$owner,
|
||||
'provider' => 'Slides',
|
||||
'provider_url' => 'http://slides.com',
|
||||
'url' => 'http://slides.com/'.$this->embedCode,
|
||||
'html' => '<iframe src="//slides.com/'.rtrim($this->embedCode, '/').'/embed" width="576" height="420" scrolling="no" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>',
|
||||
'width' => 576,
|
||||
'height' => 420,
|
||||
];
|
||||
|
||||
return $this->oembed;
|
||||
}
|
||||
|
||||
public function getEmbedCode($params = [])
|
||||
{
|
||||
$embed = parent::getEmbedCode($params);
|
||||
if ($this->embedCode && $this->oembed) {
|
||||
// Inject parameters directly into HTML OEmbed attribute
|
||||
$query = http_build_query($this->params());
|
||||
$url = $this->attributes['protocol'].'slides.com/'.rtrim($this->embedCode, '/').'/embed';
|
||||
if (mb_strlen($query) > 0) {
|
||||
$url .= (false === strpos($url, '?') ? '?' : '&') . $query;
|
||||
}
|
||||
|
||||
// Get width and height
|
||||
$width = $this->attributes['width'];
|
||||
$height = $this->attributes['height'];
|
||||
|
||||
$embed = '<iframe src="'.$url.'" width="'.$width.'" height="'.$height.'" scrolling="no" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
|
||||
}
|
||||
|
||||
return $embed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* Twitter
|
||||
*
|
||||
* This file is part of Grav MediaEmbed plugin.
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 3 licenses, see LICENSE.
|
||||
* http://benjamin-regler.de/license/
|
||||
*/
|
||||
|
||||
namespace Grav\Plugin\MediaEmbed\Services;
|
||||
|
||||
use Grav\Plugin\MediaEmbed\OEmbed\OEmbedRich;
|
||||
|
||||
/**
|
||||
* Twitter
|
||||
*/
|
||||
class Twitter extends OEmbedRich
|
||||
{
|
||||
|
||||
public function getOEmbed()
|
||||
{
|
||||
if ($this->oembed) {
|
||||
return $this->oembed;
|
||||
}
|
||||
|
||||
$endpoint = $this->format($this->config->get('endpoint', ''));
|
||||
if (!$endpoint) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$response = \Requests::get($endpoint);
|
||||
if (!$response->success) {
|
||||
$response->throw_for_status();
|
||||
}
|
||||
|
||||
$json = json_decode($response->body, true);
|
||||
|
||||
$this->oembed = [
|
||||
'type' => 'rich',
|
||||
'author_name' => $json['author_name'],
|
||||
'author_url' => 'https://twitter.com/' . $json['author_name'],
|
||||
'provider_name' => 'Twitter',
|
||||
'provider_url' => 'https://twitter.com/',
|
||||
'url' => 'https://www.twitter.com/' . $this->embedCode,
|
||||
'html' => $json['html'],
|
||||
];
|
||||
|
||||
return $this->oembed;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user