mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
parent
5cace7c693
commit
20fac04637
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
ShortcodeParser::get('default')
|
ShortcodeParser::get('default')
|
||||||
->register('file_link', array('File', 'handle_shortcode'))
|
->register('file_link', array('File', 'handle_shortcode'))
|
||||||
->register('embed', array('Oembed', 'handle_shortcode'))
|
->register('embed', array('SilverStripe\Forms\HtmlEditor\EmbedShortcodeProvider', 'handle_shortcode'))
|
||||||
->register('image', array('Image', 'handle_shortcode'));
|
->register('image', array('Image', 'handle_shortcode'));
|
||||||
|
|
||||||
// Shortcode parser which only regenerates shortcodes
|
// Shortcode parser which only regenerates shortcodes
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
name: Oembed
|
|
||||||
---
|
|
||||||
Oembed:
|
|
||||||
providers:
|
|
||||||
'http://*.youtube.com/watch*':
|
|
||||||
http: 'http://www.youtube.com/oembed/'
|
|
||||||
https: 'https://www.youtube.com/oembed/?scheme=https'
|
|
||||||
'https://*.youtube.com/watch*':
|
|
||||||
http: 'http://www.youtube.com/oembed/'
|
|
||||||
https: 'https://www.youtube.com/oembed/?scheme=https'
|
|
||||||
'http://*.youtu.be/*':
|
|
||||||
http: 'http://www.youtube.com/oembed/'
|
|
||||||
https: 'https://www.youtube.com/oembed/?scheme=https'
|
|
||||||
'https://youtu.be/*':
|
|
||||||
http: 'http://www.youtube.com/oembed/'
|
|
||||||
https: 'https://www.youtube.com/oembed/?scheme=https'
|
|
||||||
'http://*.flickr.com/*':
|
|
||||||
'http://www.flickr.com/services/oembed/'
|
|
||||||
'http://*.viddler.com/*':
|
|
||||||
'http://lab.viddler.com/services/oembed/'
|
|
||||||
'http://*.revision3.com/*':
|
|
||||||
'http://revision3.com/api/oembed/'
|
|
||||||
'http://*.hulu.com/watch/*':
|
|
||||||
'http://www.hulu.com/api/oembed.json'
|
|
||||||
'http://*.vimeo.com/*':
|
|
||||||
http: 'http://vimeo.com/api/oembed.json'
|
|
||||||
https: 'https://vimeo.com/api/oembed.json'
|
|
||||||
'https://*.vimeo.com/*':
|
|
||||||
http: 'http://vimeo.com/api/oembed.json'
|
|
||||||
https: 'https://vimeo.com/api/oembed.json'
|
|
||||||
'http://twitter.com/*':
|
|
||||||
http: 'https://api.twitter.com/1/statuses/oembed.json'
|
|
||||||
https: 'https://api.twitter.com/1/statuses/oembed.json'
|
|
||||||
'https://twitter.com/*':
|
|
||||||
http: 'https://api.twitter.com/1/statuses/oembed.json'
|
|
||||||
https: 'https://api.twitter.com/1/statuses/oembed.json'
|
|
||||||
autodiscover:
|
|
||||||
true
|
|
||||||
enabled:
|
|
||||||
true
|
|
@ -1397,7 +1397,7 @@ $.entwine('ss', function($) {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert an oembed object tag into the content.
|
* Insert an Embed object tag into the content.
|
||||||
* Requires the 'media' plugin for serialization of tags into <img> placeholders.
|
* Requires the 'media' plugin for serialization of tags into <img> placeholders.
|
||||||
*/
|
*/
|
||||||
$('form.htmleditorfield-mediaform .ss-htmleditorfield-file.embed').entwine({
|
$('form.htmleditorfield-mediaform .ss-htmleditorfield-file.embed').entwine({
|
||||||
|
@ -20,8 +20,9 @@
|
|||||||
"composer/installers": "~1.0",
|
"composer/installers": "~1.0",
|
||||||
"monolog/monolog": "~1.11",
|
"monolog/monolog": "~1.11",
|
||||||
"league/flysystem": "~1.0.12",
|
"league/flysystem": "~1.0.12",
|
||||||
"symfony/yaml": "~2.7"
|
"symfony/yaml": "~2.7",
|
||||||
},
|
"embed/embed": "^2.6"
|
||||||
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/PHPUnit": "~4.8"
|
"phpunit/PHPUnit": "~4.8"
|
||||||
},
|
},
|
||||||
|
@ -281,6 +281,14 @@ E.g.
|
|||||||
'mysite/js/src/main.js',
|
'mysite/js/src/main.js',
|
||||||
'mysite/js/src/functions.js'
|
'mysite/js/src/functions.js'
|
||||||
]]);
|
]]);
|
||||||
|
|
||||||
|
### RestfulService
|
||||||
|
|
||||||
|
* `RestfulService` has been removed. Use Guzzle instead. See Upgrading notes.
|
||||||
|
|
||||||
|
### Oembed
|
||||||
|
|
||||||
|
* Our self-maintained `Oembed` implementation has been removed, in favour of introducing [oscarotero/Embed](https://github.com/oscarotero/Embed) as a dependency.
|
||||||
|
|
||||||
|
|
||||||
## Upgrading
|
## Upgrading
|
||||||
@ -822,3 +830,18 @@ Will become:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Note that string references to SS_Datetime passed to injector, or used in config values, will still work, and will refer to the updated class names.
|
Note that string references to SS_Datetime passed to injector, or used in config values, will still work, and will refer to the updated class names.
|
||||||
|
|
||||||
|
### Upgrading from deprecated RestfulService
|
||||||
|
|
||||||
|
Install Guzzle to get an API consuming library.
|
||||||
|
`composer require guzzlehttp/guzzle` or add `guzzlehttp/guzzle: "^6.0"` to your composer.json.
|
||||||
|
|
||||||
|
For information on how to use Guzzle, please see the extensive [Guzzle documentation](http://docs.guzzlephp.org/en/latest/)
|
||||||
|
|
||||||
|
In case you want to keep using RestfulService, you can use `Firesphere/silverstripe-restfulservice`, but it is unmaintained and deprecated.
|
||||||
|
|
||||||
|
### Upgrading from deprecated Oembed
|
||||||
|
|
||||||
|
Instead of Oembed, the framework now relies on [oscarotero/Embed](https://github.com/oscarotero/Embed) to handle getting the shortcode-data for embedding.
|
||||||
|
|
||||||
|
If you have custom embedding-code relying on Oembed, please refer to the documentation provided by oscarotero.
|
||||||
|
77
forms/htmleditor/EmbedShortcodeProvider.php
Normal file
77
forms/htmleditor/EmbedShortcodeProvider.php
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Forms\HtmlEditor;
|
||||||
|
|
||||||
|
use Embed\Adapters\Adapter;
|
||||||
|
use Embed\Embed;
|
||||||
|
use ShortcodeHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class EmbedShortcodeProvider
|
||||||
|
*
|
||||||
|
* Provider for the [embed] shortcode tag used by the embedding service
|
||||||
|
* in the HTML Editor field.
|
||||||
|
* Provides the html needed for the frontend and the editor field itself.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @package SilverStripe\Forms\HtmlEditor
|
||||||
|
*/
|
||||||
|
class EmbedShortcodeProvider implements ShortcodeHandler
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of shortcodes provided by this handler
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function get_shortcodes()
|
||||||
|
{
|
||||||
|
return array('embed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Embed shortcode parser from Oembed. This is a temporary workaround.
|
||||||
|
* Oembed class has been replaced with the Embed external service.
|
||||||
|
*
|
||||||
|
* @param $arguments
|
||||||
|
* @param $content
|
||||||
|
* @param $parser
|
||||||
|
* @param $shortcode
|
||||||
|
* @param array $extra
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function handle_shortcode($arguments, $content, $parser, $shortcode, $extra = array()) {
|
||||||
|
$embed = Embed::create($content, $arguments);
|
||||||
|
if($embed && $embed instanceof \Embed\Adapters\Adapter) {
|
||||||
|
return self::embedForTemplate($embed);
|
||||||
|
} else {
|
||||||
|
return '<a href="' . $content . '">' . $content . '</a>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Adapter $embed
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function embedForTemplate($embed)
|
||||||
|
{
|
||||||
|
switch ($embed->type) {
|
||||||
|
case 'video':
|
||||||
|
case 'rich':
|
||||||
|
if ($embed->extraClass) {
|
||||||
|
return "<div class='media $embed->extraClass'>$embed->code</div>";
|
||||||
|
} else {
|
||||||
|
return "<div class='media'>$embed->code</div>";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'link':
|
||||||
|
return '<a class="' . $embed->extraClass . '" href="' . $embed->origin . '">' . $embed->title . '</a>';
|
||||||
|
break;
|
||||||
|
case 'photo':
|
||||||
|
return "<img src='$embed->url' width='$embed->width' height='$embed->height' class='$embed->extraClass' />";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
use Embed\Adapters\AdapterInterface;
|
||||||
|
use Embed\Embed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A TinyMCE-powered WYSIWYG HTML editor field with image and link insertion and tracking capabilities. Editor fields
|
* A TinyMCE-powered WYSIWYG HTML editor field with image and link insertion and tracking capabilities. Editor fields
|
||||||
* are created from <textarea> tags, which are then converted with JavaScript.
|
* are created from <textarea> tags, which are then converted with JavaScript.
|
||||||
@ -523,8 +526,8 @@ class HTMLEditorField_Toolbar extends RequestHandler {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instanciate file wrapper and get fields based on its type
|
// Instantiate file wrapper and get fields based on its type
|
||||||
// Check if appCategory is an image and exists on the local system, otherwise use oEmbed to refference a
|
// Check if appCategory is an image and exists on the local system, otherwise use Embed to reference a
|
||||||
// remote image
|
// remote image
|
||||||
$fileCategory = $this->getFileCategory($url, $file);
|
$fileCategory = $this->getFileCategory($url, $file);
|
||||||
switch($fileCategory) {
|
switch($fileCategory) {
|
||||||
@ -541,11 +544,11 @@ class HTMLEditorField_Toolbar extends RequestHandler {
|
|||||||
if($file) {
|
if($file) {
|
||||||
throw $this->getErrorFor(_t(
|
throw $this->getErrorFor(_t(
|
||||||
"HTMLEditorField_Toolbar.ERROR_OEMBED_REMOTE",
|
"HTMLEditorField_Toolbar.ERROR_OEMBED_REMOTE",
|
||||||
"Oembed is only compatible with remote files"
|
"Embed is only compatible with remote files"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Other files should fallback to oembed
|
// Other files should fallback to embed
|
||||||
$fileWrapper = new HTMLEditorField_Embed($url, $file);
|
$fileWrapper = new HTMLEditorField_Embed($url, $file);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1031,9 +1034,9 @@ abstract class HTMLEditorField_File extends ViewableData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulation of an oembed tag, linking to an external media source.
|
* Encapsulation of an embed tag, linking to an external media source.
|
||||||
*
|
*
|
||||||
* @see Oembed
|
* @see Embed
|
||||||
* @package forms
|
* @package forms
|
||||||
* @subpackage fields-formattedinput
|
* @subpackage fields-formattedinput
|
||||||
*/
|
*/
|
||||||
@ -1045,16 +1048,16 @@ class HTMLEditorField_Embed extends HTMLEditorField_File {
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Oembed result
|
* Embed result
|
||||||
*
|
*
|
||||||
* @var Oembed_Result
|
* @var Embed
|
||||||
*/
|
*/
|
||||||
protected $oembed;
|
protected $embed;
|
||||||
|
|
||||||
public function __construct($url, File $file = null) {
|
public function __construct($url, File $file = null) {
|
||||||
parent::__construct($url, $file);
|
parent::__construct($url, $file);
|
||||||
$this->oembed = Oembed::get_oembed_from_url($url);
|
$this->embed = Embed::create($url);
|
||||||
if(!$this->oembed) {
|
if(!$this->embed) {
|
||||||
$controller = Controller::curr();
|
$controller = Controller::curr();
|
||||||
$response = $controller->getResponse();
|
$response = $controller->getResponse();
|
||||||
$response->addHeader('X-Status',
|
$response->addHeader('X-Status',
|
||||||
@ -1093,32 +1096,32 @@ class HTMLEditorField_Embed extends HTMLEditorField_File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get width of this oembed
|
* Get width of this Embed
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getWidth() {
|
public function getWidth() {
|
||||||
return $this->oembed->Width ?: 100;
|
return $this->embed->width ?: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get height of this oembed
|
* Get height of this Embed
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getHeight() {
|
public function getHeight() {
|
||||||
return $this->oembed->Height ?: 100;
|
return $this->embed->height ?: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPreviewURL() {
|
public function getPreviewURL() {
|
||||||
// Use thumbnail url
|
// Use thumbnail url
|
||||||
if(!empty($this->oembed->thumbnail_url)) {
|
if($this->embed->image) {
|
||||||
return $this->oembed->thumbnail_url;
|
return $this->embed->image;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use direct image type
|
// Use direct image type
|
||||||
if($this->getType() == 'photo' && !empty($this->Oembed->url)) {
|
if($this->getType() == 'photo' && !empty($this->embed->url)) {
|
||||||
return $this->Oembed->url;
|
return $this->embed->url;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default media
|
// Default media
|
||||||
@ -1126,32 +1129,37 @@ class HTMLEditorField_Embed extends HTMLEditorField_File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getName() {
|
public function getName() {
|
||||||
if(isset($this->oembed->title)) {
|
if($this->embed->title) {
|
||||||
return $this->oembed->title;
|
return $this->embed->title;
|
||||||
} else {
|
} else {
|
||||||
return parent::getName();
|
return parent::getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get OEmbed type
|
* Get Embed type
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getType() {
|
public function getType() {
|
||||||
return $this->oembed->type;
|
return $this->embed->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get filetype
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function getFileType() {
|
public function getFileType() {
|
||||||
return $this->getType()
|
return $this->getType()
|
||||||
?: parent::getFileType();
|
?: parent::getFileType();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Oembed_Result
|
* @return AdapterInterface
|
||||||
*/
|
*/
|
||||||
public function getOembed() {
|
public function getEmbed() {
|
||||||
return $this->oembed;
|
return $this->embed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function appCategory() {
|
public function appCategory() {
|
||||||
@ -1159,12 +1167,12 @@ class HTMLEditorField_Embed extends HTMLEditorField_File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Info for this oembed
|
* Info for this Embed
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getInfo() {
|
public function getInfo() {
|
||||||
return $this->oembed->info;
|
return $this->embed->info;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,428 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Format of the Oembed config. Autodiscover allows discovery of all URLs.
|
|
||||||
*
|
|
||||||
* Endpoint set to true means autodiscovery for this specific provider is
|
|
||||||
* allowed (even if autodiscovery in general has been disabled).
|
|
||||||
*
|
|
||||||
* <code>
|
|
||||||
*
|
|
||||||
* name: Oembed
|
|
||||||
* ---
|
|
||||||
* Oembed:
|
|
||||||
* providers:
|
|
||||||
* 'http://*.youtube.com/watch*':
|
|
||||||
* 'http://www.youtube.com/oembed/'
|
|
||||||
* autodiscover:
|
|
||||||
* true
|
|
||||||
* </code>
|
|
||||||
*
|
|
||||||
* @package framework
|
|
||||||
* @subpackage oembed
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Oembed implements ShortcodeHandler {
|
|
||||||
|
|
||||||
public static function is_enabled() {
|
|
||||||
return Config::inst()->get('Oembed', 'enabled');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the autodiscover setting from the config.
|
|
||||||
*/
|
|
||||||
public static function get_autodiscover() {
|
|
||||||
return Config::inst()->get('Oembed', 'autodiscover');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets providers from config.
|
|
||||||
*/
|
|
||||||
public static function get_providers() {
|
|
||||||
return Config::inst()->get('Oembed', 'providers');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an endpoint (a base Oembed URL) from first matching provider.
|
|
||||||
*
|
|
||||||
* @param $url Human-readable URL.
|
|
||||||
* @returns string/bool URL of an endpoint, or false if no matching provider exists.
|
|
||||||
*/
|
|
||||||
protected static function find_endpoint($url) {
|
|
||||||
foreach(self::get_providers() as $scheme=>$endpoint) {
|
|
||||||
if(self::matches_scheme($url, $scheme)) {
|
|
||||||
$protocol = Director::is_https() ? 'https' : 'http';
|
|
||||||
|
|
||||||
if (is_array($endpoint)) {
|
|
||||||
if (array_key_exists($protocol, $endpoint)) $endpoint = $endpoint[$protocol];
|
|
||||||
else $endpoint = reset($endpoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $endpoint;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the URL if it matches against the scheme (pattern).
|
|
||||||
*
|
|
||||||
* @param $url Human-readable URL to be checked.
|
|
||||||
* @param $scheme Pattern to be matched against.
|
|
||||||
* @returns bool Whether the pattern matches or not.
|
|
||||||
*/
|
|
||||||
protected static function matches_scheme($url, $scheme) {
|
|
||||||
$urlInfo = parse_url($url);
|
|
||||||
$schemeInfo = parse_url($scheme);
|
|
||||||
|
|
||||||
foreach($schemeInfo as $k=>$v) {
|
|
||||||
if(!array_key_exists($k, $urlInfo)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(strpos($v, '*') !== false) {
|
|
||||||
$v = preg_quote($v, '/');
|
|
||||||
$v = str_replace('\*', '.*', $v);
|
|
||||||
if($k == 'host') {
|
|
||||||
$v = str_replace('*\.', '*', $v);
|
|
||||||
}
|
|
||||||
if(!preg_match('/' . $v . '/', $urlInfo[$k])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} elseif(strcasecmp($urlInfo[$k], $v)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs a HTTP request to the URL and scans the response for resource links
|
|
||||||
* that mention oembed in their type.
|
|
||||||
*
|
|
||||||
* @param $url Human readable URL.
|
|
||||||
* @returns string/bool Oembed URL, or false.
|
|
||||||
*/
|
|
||||||
protected static function autodiscover_from_url($url)
|
|
||||||
{
|
|
||||||
$timeout = 5;
|
|
||||||
$sapphireInfo = new SapphireInfo();
|
|
||||||
$useragent = 'SilverStripe/' . $sapphireInfo->Version();
|
|
||||||
$curlRequest = curl_init();
|
|
||||||
curl_setopt_array(
|
|
||||||
$curlRequest,
|
|
||||||
array(
|
|
||||||
CURLOPT_URL => $url,
|
|
||||||
CURLOPT_RETURNTRANSFER => 1,
|
|
||||||
CURLOPT_USERAGENT => $useragent,
|
|
||||||
CURLOPT_CONNECTTIMEOUT => $timeout,
|
|
||||||
CURLOPT_FOLLOWLOCATION => 1,
|
|
||||||
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
$response = curl_exec($curlRequest);
|
|
||||||
$headers = curl_getinfo($curlRequest);
|
|
||||||
if(!$response || $headers['http_code'] !== 200) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$body = $response;
|
|
||||||
return static::autodiscover_from_body($body);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a response body, determine if there is an autodiscover url
|
|
||||||
*
|
|
||||||
* @param string $body
|
|
||||||
* @return bool|string
|
|
||||||
*/
|
|
||||||
public static function autodiscover_from_body($body) {
|
|
||||||
// Look within the body for an oembed link.
|
|
||||||
$pcreOmbed = '#<link[^>]+?(?:href=[\'"](?<first>[^\'"]+?)[\'"][^>]+?)'
|
|
||||||
. '?type=["\']application/json\+oembed["\']'
|
|
||||||
. '(?:[^>]+?href=[\'"](?<second>[^\'"]+?)[\'"])?#';
|
|
||||||
|
|
||||||
if(preg_match_all($pcreOmbed, $body, $matches, PREG_SET_ORDER)) {
|
|
||||||
$match = $matches[0];
|
|
||||||
if(!empty($match['second'])) {
|
|
||||||
return html_entity_decode($match['second']);
|
|
||||||
}
|
|
||||||
if(!empty($match['first'])) {
|
|
||||||
return html_entity_decode($match['first']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes the human-readable URL of an embeddable resource and converts it into an
|
|
||||||
* Oembed_Result descriptor (which contains a full Oembed resource URL).
|
|
||||||
*
|
|
||||||
* @param $url Human-readable URL
|
|
||||||
* @param $type ?
|
|
||||||
* @param $options array Options to be used for constructing the resulting descriptor.
|
|
||||||
* @returns Oembed_Result/bool An Oembed descriptor, or false
|
|
||||||
*/
|
|
||||||
public static function get_oembed_from_url($url, $type = false, array $options = array()) {
|
|
||||||
if(!self::is_enabled()) return false;
|
|
||||||
|
|
||||||
// Find or build the Oembed URL.
|
|
||||||
$endpoint = self::find_endpoint($url);
|
|
||||||
$oembedUrl = false;
|
|
||||||
if(!$endpoint) {
|
|
||||||
if(self::get_autodiscover()) {
|
|
||||||
$oembedUrl = self::autodiscover_from_url($url);
|
|
||||||
}
|
|
||||||
} elseif($endpoint === true) {
|
|
||||||
$oembedUrl = self::autodiscover_from_url($url);
|
|
||||||
} else {
|
|
||||||
// Build the url manually - we gave all needed information.
|
|
||||||
$oembedUrl = Controller::join_links($endpoint, '?format=json&url=' . rawurlencode($url));
|
|
||||||
}
|
|
||||||
|
|
||||||
// If autodescovery failed the resource might be a direct link to a file
|
|
||||||
if(!$oembedUrl) {
|
|
||||||
if(File::get_app_category(File::get_file_extension($url)) == "image") {
|
|
||||||
return new Oembed_Result($url, $url, $type, $options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if($oembedUrl) {
|
|
||||||
// Inject the options into the Oembed URL.
|
|
||||||
if($options) {
|
|
||||||
if(isset($options['width']) && !isset($options['maxwidth'])) {
|
|
||||||
$options['maxwidth'] = $options['width'];
|
|
||||||
}
|
|
||||||
if(isset($options['height']) && !isset($options['maxheight'])) {
|
|
||||||
$options['maxheight'] = $options['height'];
|
|
||||||
}
|
|
||||||
$oembedUrl = Controller::join_links($oembedUrl, '?' . http_build_query($options, '', '&'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Oembed_Result($oembedUrl, $url, $type, $options);
|
|
||||||
}
|
|
||||||
|
|
||||||
// No matching Oembed resource found.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function get_shortcodes() {
|
|
||||||
return 'embed';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function handle_shortcode($arguments, $content, $parser, $shortcode, $extra = array()) {
|
|
||||||
if(isset($arguments['type'])) {
|
|
||||||
$type = $arguments['type'];
|
|
||||||
unset($arguments['type']);
|
|
||||||
} else {
|
|
||||||
$type = false;
|
|
||||||
}
|
|
||||||
$oembed = self::get_oembed_from_url($content, $type, $arguments);
|
|
||||||
if($oembed && $oembed->exists()) {
|
|
||||||
return $oembed->forTemplate();
|
|
||||||
} else {
|
|
||||||
return '<a href="' . $content . '">' . $content . '</a>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property string $Type Oembed type
|
|
||||||
* @property string $Title Title
|
|
||||||
* @property string $URL URL to asset
|
|
||||||
* @property string $Provider_URL Url for provider
|
|
||||||
* @property int $Width
|
|
||||||
* @property int $Height
|
|
||||||
* @property string $Info Descriptive text for this oembed
|
|
||||||
*
|
|
||||||
* @package framework
|
|
||||||
* @subpackage oembed
|
|
||||||
*/
|
|
||||||
class Oembed_Result extends ViewableData {
|
|
||||||
/**
|
|
||||||
* JSON data fetched from the Oembed URL.
|
|
||||||
* This data is accessed dynamically by getField and hasField.
|
|
||||||
*/
|
|
||||||
protected $data = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Human readable URL
|
|
||||||
*/
|
|
||||||
protected $origin = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ?
|
|
||||||
*/
|
|
||||||
protected $type = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Oembed URL
|
|
||||||
*/
|
|
||||||
protected $url;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class to be injected into the resulting HTML element.
|
|
||||||
*/
|
|
||||||
protected $extraClass;
|
|
||||||
|
|
||||||
private static $casting = array(
|
|
||||||
'html' => 'HTMLText',
|
|
||||||
);
|
|
||||||
|
|
||||||
public function __construct($url, $origin = false, $type = false, array $options = array()) {
|
|
||||||
$this->url = $url;
|
|
||||||
$this->origin = $origin;
|
|
||||||
$this->type = $type;
|
|
||||||
|
|
||||||
if(isset($options['class'])) {
|
|
||||||
$this->extraClass = $options['class'];
|
|
||||||
}
|
|
||||||
if($options) {
|
|
||||||
if(isset($options['width'])) {
|
|
||||||
$this->Width = $options['width'];
|
|
||||||
}
|
|
||||||
if(isset($options['height'])) {
|
|
||||||
$this->Height = $options['height'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getOembedURL() {
|
|
||||||
return $this->url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches the JSON data from the Oembed URL (cached).
|
|
||||||
* Only sets the internal variable.
|
|
||||||
*/
|
|
||||||
protected function loadData() {
|
|
||||||
if($this->data !== false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$timeout = 5;
|
|
||||||
$sapphireInfo = new SapphireInfo();
|
|
||||||
$useragent = 'SilverStripe/' . $sapphireInfo->Version();
|
|
||||||
$curlRequest = curl_init();
|
|
||||||
curl_setopt_array(
|
|
||||||
$curlRequest,
|
|
||||||
array(
|
|
||||||
CURLOPT_URL => $this->url,
|
|
||||||
CURLOPT_RETURNTRANSFER => 1,
|
|
||||||
CURLOPT_USERAGENT => $useragent,
|
|
||||||
CURLOPT_CONNECTTIMEOUT => $timeout,
|
|
||||||
CURLOPT_FOLLOWLOCATION => 1,
|
|
||||||
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
$response = curl_exec($curlRequest);
|
|
||||||
$headers = curl_getinfo($curlRequest);
|
|
||||||
if(!$response || $headers['http_code'] !== 200) {
|
|
||||||
$this->data = array();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$body = $response;
|
|
||||||
$data = json_decode($body, true);
|
|
||||||
if(!$data) {
|
|
||||||
// if the response is no valid JSON we might have received a binary stream to an image
|
|
||||||
$data = array();
|
|
||||||
if (!function_exists('imagecreatefromstring')) {
|
|
||||||
throw new LogicException('imagecreatefromstring function does not exist - Please make sure GD is installed');
|
|
||||||
}
|
|
||||||
$image = imagecreatefromstring($body);
|
|
||||||
if($image !== FALSE) {
|
|
||||||
preg_match("/^(http:\/\/)?([^\/]+)/i", $this->url, $matches);
|
|
||||||
$protocoll = $matches[1];
|
|
||||||
$host = $matches[2];
|
|
||||||
$data['type'] = "photo";
|
|
||||||
$data['title'] = basename($this->url) . " ($host)";
|
|
||||||
$data['url'] = $this->url;
|
|
||||||
$data['provider_url'] = $protocoll.$host;
|
|
||||||
$data['width'] = imagesx($image);
|
|
||||||
$data['height'] = imagesy($image);
|
|
||||||
$data['info'] = _t('UploadField.HOTLINKINFO',
|
|
||||||
'Info: This image will be hotlinked. Please ensure you have permissions from the'
|
|
||||||
. ' original site creator to do so.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert all keys to lowercase
|
|
||||||
$data = array_change_key_case($data, CASE_LOWER);
|
|
||||||
|
|
||||||
// Check if we can guess thumbnail
|
|
||||||
if(empty($data['thumbnail_url']) && $thumbnail = $this->findThumbnail($data)) {
|
|
||||||
$data['thumbnail_url'] = $thumbnail;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Purge everything if the type does not match.
|
|
||||||
if($this->type && $this->type != $data['type']) {
|
|
||||||
$data = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->data = $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find thumbnail if omitted from data
|
|
||||||
*
|
|
||||||
* @param array $data
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function findThumbnail($data) {
|
|
||||||
if(!empty($data['thumbnail_url'])) {
|
|
||||||
return $data['thumbnail_url'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hack in facebook graph thumbnail
|
|
||||||
if(!empty($data['provider_name']) && $data['provider_name'] === 'Facebook') {
|
|
||||||
$id = preg_replace("/.*\\/(\\d+?)\\/?($|\\?.*)/", "$1", $data["url"]);
|
|
||||||
return "https://graph.facebook.com/{$id}/picture";
|
|
||||||
}
|
|
||||||
|
|
||||||
// no thumbnail found
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap the check for looking into Oembed JSON within $this->data.
|
|
||||||
*/
|
|
||||||
public function hasField($field) {
|
|
||||||
$this->loadData();
|
|
||||||
return array_key_exists(strtolower($field), $this->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap the field calls to fetch data from Oembed JSON (within $this->data)
|
|
||||||
*/
|
|
||||||
public function getField($field) {
|
|
||||||
$field = strtolower($field);
|
|
||||||
if($this->hasField($field)) {
|
|
||||||
return $this->data[$field];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function forTemplate() {
|
|
||||||
$this->loadData();
|
|
||||||
switch($this->Type) {
|
|
||||||
case 'video':
|
|
||||||
case 'rich':
|
|
||||||
if($this->extraClass) {
|
|
||||||
return "<div class='media $this->extraClass'>$this->HTML</div>";
|
|
||||||
} else {
|
|
||||||
return "<div class='media'>$this->HTML</div>";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'link':
|
|
||||||
return '<a class="' . $this->extraClass . '" href="' . $this->origin . '">' . $this->Title . '</a>';
|
|
||||||
break;
|
|
||||||
case 'photo':
|
|
||||||
return "<img src='$this->URL' width='$this->Width' height='$this->Height' class='$this->extraClass' />";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function exists() {
|
|
||||||
$this->loadData();
|
|
||||||
return count($this->data) > 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple parser that allows you to map BBCode-like "shortcodes" to an arbitrary callback.
|
* A simple parser that allows you to map BBCode-like "shortcodes" to an arbitrary callback.
|
||||||
* It is a simple regex based parser that allows you to replace simple bbcode-like tags
|
* It is a simple regex based parser that allows you to replace simple bbcode-like tags
|
||||||
@ -121,14 +122,17 @@ class ShortcodeParser extends Object {
|
|||||||
/**
|
/**
|
||||||
* Return the text to insert in place of a shoprtcode.
|
* Return the text to insert in place of a shoprtcode.
|
||||||
* Behaviour in the case of missing shortcodes depends on the setting of ShortcodeParser::$error_behavior.
|
* Behaviour in the case of missing shortcodes depends on the setting of ShortcodeParser::$error_behavior.
|
||||||
* @param $tag A map containing the the following keys:
|
*
|
||||||
|
* @param array $tag A map containing the the following keys:
|
||||||
* - 'open': The name of the tag
|
* - 'open': The name of the tag
|
||||||
* - 'attrs': Attributes of the tag
|
* - 'attrs': Attributes of the tag
|
||||||
* - 'content': Content of the tag
|
* - 'content': Content of the tag
|
||||||
* @param $extra Extra-meta data
|
* @param array $extra Extra-meta data
|
||||||
* @param $isHTMLAllowed A boolean indicating whether it's okay to insert HTML tags into the result
|
* @param boolean $isHTMLAllowed A boolean indicating whether it's okay to insert HTML tags into the result
|
||||||
|
*
|
||||||
|
* @return bool|mixed|string
|
||||||
*/
|
*/
|
||||||
function getShortcodeReplacementText($tag, $extra = array(), $isHTMLAllowed = true) {
|
public function getShortcodeReplacementText($tag, $extra = array(), $isHTMLAllowed = true) {
|
||||||
$content = $this->callShortcode($tag['open'], $tag['attrs'], $tag['content'], $extra);
|
$content = $this->callShortcode($tag['open'], $tag['attrs'], $tag['content'], $extra);
|
||||||
|
|
||||||
// Missing tag
|
// Missing tag
|
||||||
@ -157,7 +161,8 @@ class ShortcodeParser extends Object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function insertAfter($new, $after) {
|
protected function insertAfter($new, $after) {
|
||||||
$parent = $after->parentNode; $next = $after->nextSibling;
|
$parent = $after->parentNode;
|
||||||
|
$next = $after->nextSibling;
|
||||||
|
|
||||||
if ($next) {
|
if ($next) {
|
||||||
$parent->insertBefore($new, $next);
|
$parent->insertBefore($new, $next);
|
||||||
@ -182,6 +187,9 @@ class ShortcodeParser extends Object {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected static $marker_class = '--ss-shortcode-marker';
|
protected static $marker_class = '--ss-shortcode-marker';
|
||||||
|
|
||||||
protected static $block_level_elements = array(
|
protected static $block_level_elements = array(
|
||||||
@ -612,4 +620,5 @@ class ShortcodeParser extends Object {
|
|||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
59
tests/forms/EmbedShortcodeProviderTest.php
Normal file
59
tests/forms/EmbedShortcodeProviderTest.php
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
use Embed\Adapters\Webpage;
|
||||||
|
use Embed\Embed;
|
||||||
|
use SilverStripe\Forms\HtmlEditor\EmbedShortcodeProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class EmbedShortcodeProviderTest
|
||||||
|
*
|
||||||
|
* Because Embed/Embed does not have a mockup, the tests have to run against a live environment.
|
||||||
|
* I've tried to fix it by serializing the data to a file, but to no avail.
|
||||||
|
* Any improvements on not having to call external resources are welcome.
|
||||||
|
*/
|
||||||
|
class EmbedShortcodeProviderTest extends SapphireTest
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string test youtube. The SilverStripe Platform promotion by UncleCheese
|
||||||
|
*/
|
||||||
|
protected static $test_youtube = 'https://www.youtube.com/watch?v=dM15HfUYwF0';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string test Soundcloud. One of my favorite bands, Delain, Suckerpunch.
|
||||||
|
*/
|
||||||
|
protected static $test_soundcloud = 'http://soundcloud.com/napalmrecords/delain-suckerpunch';
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
return parent::setUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testYoutube()
|
||||||
|
{
|
||||||
|
/** @var Webpage $result */
|
||||||
|
$result = Embed::create(self::$test_youtube, array());
|
||||||
|
self::assertEquals($result->providerName, 'YouTube');
|
||||||
|
$embedded = EmbedShortcodeProvider::embedForTemplate($result);
|
||||||
|
self::assertContains("<div class='media'", $embedded);
|
||||||
|
self::assertContains('iframe', $embedded);
|
||||||
|
self::assertContains('youtube.com', $embedded);
|
||||||
|
self::assertContains('embed', $embedded);
|
||||||
|
self::assertContains('dM15HfUYwF0', $embedded);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSoundcloud()
|
||||||
|
{
|
||||||
|
/** @var Webpage $result */
|
||||||
|
$result = Embed::create(self::$test_soundcloud, array());
|
||||||
|
self::assertEquals($result->providerName, 'SoundCloud');
|
||||||
|
$embedded = EmbedShortcodeProvider::embedForTemplate($result);
|
||||||
|
self::assertContains("<div class='media'", $embedded);
|
||||||
|
self::assertContains('iframe', $embedded);
|
||||||
|
self::assertContains('soundcloud.com', $embedded);
|
||||||
|
self::assertContains('player', $embedded);
|
||||||
|
self::assertContains('tracks%2F242518079', $embedded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,153 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class OembedTest extends SapphireTest {
|
|
||||||
public function testGetOembedFromUrl() {
|
|
||||||
Config::inst()->update('Oembed', 'providers', array(
|
|
||||||
'http://*.silverstripe.com/watch*'=>'http://www.silverstripe.com/oembed/'
|
|
||||||
));
|
|
||||||
$escapedEndpointURL = urlencode("http://www.silverstripe.com/oembed/");
|
|
||||||
|
|
||||||
// Test with valid URL
|
|
||||||
$result = Oembed::get_oembed_from_url('http://www.silverstripe.com/watch12345');
|
|
||||||
$this->assertTrue($result!=false);
|
|
||||||
$this->assertEquals($result->getOembedURL(),
|
|
||||||
'http://www.silverstripe.com/oembed/?format=json&url='.urlencode('http://www.silverstripe.com/watch12345'),
|
|
||||||
'Triggers on matching URL');
|
|
||||||
|
|
||||||
// Test without www.
|
|
||||||
$result = Oembed::get_oembed_from_url('http://silverstripe.com/watch12345');
|
|
||||||
$this->assertTrue($result!=false);
|
|
||||||
$this->assertEquals($result->getOembedURL(),
|
|
||||||
'http://www.silverstripe.com/oembed/?format=json&url='.urlencode('http://silverstripe.com/watch12345'),
|
|
||||||
'Triggers on matching URL without www');
|
|
||||||
|
|
||||||
// Test if options make their way to the URL
|
|
||||||
$result = Oembed::get_oembed_from_url('http://www.silverstripe.com/watch12345', false, array('foo'=>'bar'));
|
|
||||||
$this->assertTrue($result!=false);
|
|
||||||
$this->assertEquals($result->getOembedURL(), 'http://www.silverstripe.com/oembed/?format=json&url='
|
|
||||||
. urlencode('http://www.silverstripe.com/watch12345').'&foo=bar',
|
|
||||||
'Includes options');
|
|
||||||
|
|
||||||
// Test magic.
|
|
||||||
$result = Oembed::get_oembed_from_url('http://www.silverstripe.com/watch12345', false,
|
|
||||||
array('height'=>'foo', 'width'=>'bar'));
|
|
||||||
$this->assertTrue($result!=false);
|
|
||||||
$urlParts = parse_url($result->getOembedURL());
|
|
||||||
parse_str($urlParts['query'], $query);
|
|
||||||
$this->assertEquals($query['maxheight'], 'foo', 'Magically creates maxheight option');
|
|
||||||
$this->assertEquals($query['maxwidth'], 'bar', 'Magically creates maxwidth option');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testAutodiscover() {
|
|
||||||
// Test href after type tag
|
|
||||||
$body = <<<EOS
|
|
||||||
<title id="pageTitle">Some content</title>
|
|
||||||
<link rel="search" type="application/opensearchdescription+xml" href="/osd.xml" title="Facebook" />
|
|
||||||
<link
|
|
||||||
rel="alternate" type="application/json+oembed"
|
|
||||||
href="https://www.facebook.com/plugins/post/oembed.json/?url=https%3A%2F%2Fwww.facebook.com%2Fsomeusername%2Fposts%2F10209305859558135"
|
|
||||||
title="My post"
|
|
||||||
/>
|
|
||||||
EOS;
|
|
||||||
$this->assertEquals(
|
|
||||||
'https://www.facebook.com/plugins/post/oembed.json/?url=https%3A%2F%2Fwww.facebook.com%2Fsomeusername%2Fposts%2F10209305859558135',
|
|
||||||
Oembed::autodiscover_from_body($body)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Test href before the type tag
|
|
||||||
$body2 = <<<EOS
|
|
||||||
<title id="pageTitle">Some content</title>
|
|
||||||
<link rel="search" type="application/opensearchdescription+xml" href="/osd.xml" title="Facebook" />
|
|
||||||
<link
|
|
||||||
href="https://www.facebook.com/plugins/post/oembed.json/?url=https%3A%2F%2Fwww.facebook.com%2Fsomeusername%2Fposts%2F10209305859558135"
|
|
||||||
rel="alternate" type="application/json+oembed"
|
|
||||||
|
|
||||||
title="My post"
|
|
||||||
/>
|
|
||||||
EOS;
|
|
||||||
$this->assertEquals(
|
|
||||||
'https://www.facebook.com/plugins/post/oembed.json/?url=https%3A%2F%2Fwww.facebook.com%2Fsomeusername%2Fposts%2F10209305859558135',
|
|
||||||
Oembed::autodiscover_from_body($body2)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testFindThumbnail()
|
|
||||||
{
|
|
||||||
$data = array(
|
|
||||||
"author_name"=> "Some User",
|
|
||||||
"author_url"=> null,
|
|
||||||
"provider_url" => "https://www.facebook.com",
|
|
||||||
"provider_name" => "Facebook",
|
|
||||||
"success" => true,
|
|
||||||
"height" => null,
|
|
||||||
"html" => "<div />",
|
|
||||||
"type" => "rich",
|
|
||||||
"version" => "1.0",
|
|
||||||
"url" => "https://www.facebook.com/someuser/posts/6465132161654421654",
|
|
||||||
"width" => 552
|
|
||||||
);
|
|
||||||
|
|
||||||
// Test facebook url
|
|
||||||
$result = new Oembed_Result('https://www.facebook.com/someuser/posts/6465132161654421654');
|
|
||||||
$this->assertEquals(
|
|
||||||
"https://graph.facebook.com/6465132161654421654/picture",
|
|
||||||
$result->findThumbnail($data)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Test respect existing url
|
|
||||||
$data['thumbnail_url'] = 'http://www.silverstripe.com/picture.jpg';
|
|
||||||
$this->assertEquals(
|
|
||||||
"http://www.silverstripe.com/picture.jpg",
|
|
||||||
$result->findThumbnail($data)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testRequestProtocolReflectedInGetOembedFromUrl() {
|
|
||||||
Config::inst()->update('Oembed', 'providers', array(
|
|
||||||
'http://*.silverstripe.com/watch*'=> array(
|
|
||||||
'http' => 'http://www.silverstripe.com/oembed/',
|
|
||||||
'https' => 'https://www.silverstripe.com/oembed/?scheme=https',
|
|
||||||
),
|
|
||||||
'https://*.silverstripe.com/watch*'=> array(
|
|
||||||
'http' => 'http://www.silverstripe.com/oembed/',
|
|
||||||
'https' => 'https://www.silverstripe.com/oembed/?scheme=https',
|
|
||||||
)
|
|
||||||
));
|
|
||||||
|
|
||||||
Config::inst()->update('Director', 'alternate_protocol', 'http');
|
|
||||||
|
|
||||||
foreach(array('http', 'https') as $protocol) {
|
|
||||||
$url = $protocol.'://www.silverstripe.com/watch12345';
|
|
||||||
$result = Oembed::get_oembed_from_url($url);
|
|
||||||
|
|
||||||
$this->assertInstanceOf('Oembed_Result', $result);
|
|
||||||
$this->assertEquals($result->getOembedURL(),
|
|
||||||
'http://www.silverstripe.com/oembed/?format=json&url='.urlencode($url),
|
|
||||||
'Returns http based URLs when request is over http, regardless of source URL');
|
|
||||||
}
|
|
||||||
|
|
||||||
Config::inst()->update('Director', 'alternate_protocol', 'https');
|
|
||||||
|
|
||||||
foreach(array('http', 'https') as $protocol) {
|
|
||||||
$url = $protocol.'://www.silverstripe.com/watch12345';
|
|
||||||
$result = Oembed::get_oembed_from_url($url);
|
|
||||||
|
|
||||||
$this->assertInstanceOf('Oembed_Result', $result);
|
|
||||||
$this->assertEquals($result->getOembedURL(),
|
|
||||||
'https://www.silverstripe.com/oembed/?scheme=https&format=json&url='.urlencode($url),
|
|
||||||
'Returns https based URLs when request is over https, regardless of source URL');
|
|
||||||
}
|
|
||||||
|
|
||||||
Config::inst()->update('Director', 'alternate_protocol', 'foo');
|
|
||||||
|
|
||||||
foreach(array('http', 'https') as $protocol) {
|
|
||||||
$url = $protocol.'://www.silverstripe.com/watch12345';
|
|
||||||
$result = Oembed::get_oembed_from_url($url);
|
|
||||||
|
|
||||||
$this->assertInstanceOf('Oembed_Result', $result);
|
|
||||||
$this->assertEquals($result->getOembedURL(),
|
|
||||||
'http://www.silverstripe.com/oembed/?format=json&url='.urlencode($url),
|
|
||||||
'When request protocol doesn\'t have specific handler, fall back to first option');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user