NEW Shift Embeddable and EmbedResource from asset-admin, lazy load Embed to allow injected dependencies (#8194)

This commit is contained in:
Robbie Averill 2018-06-20 11:40:28 +12:00 committed by Aaron Carlino
parent cfc3b851e7
commit 7d90a14f37
6 changed files with 282 additions and 2 deletions

View File

@ -988,7 +988,7 @@ warnings:
'HTMLEditorField_Toolbar':
message: 'replaced With SilverStripe\Admin\ModalController'
'HTMLEditorField_Embed':
message: 'replaced with SilverStripe\AssetAdmin\Model\EmbedResource'
message: 'replaced with SilverStripe\View\Embed\EmbedResource'
'HTMLEditorField_File':
message: 'Removed'
'HTMLEditorField_Flash':

6
_config/oembed.yml Normal file
View File

@ -0,0 +1,6 @@
---
Name: coreoembed
---
SilverStripe\Core\Injector\Injector:
SilverStripe\View\Embed\Embeddable:
class: SilverStripe\View\Embed\EmbedResource

View File

@ -0,0 +1,147 @@
<?php
namespace SilverStripe\View\Embed;
use Embed\Adapters\Adapter;
use Embed\Embed;
use Embed\Http\DispatcherInterface;
use SilverStripe\Core\Manifest\ModuleResourceLoader;
/**
* Encapsulation of an embed tag, linking to an external media source.
*
* @see Embed
*/
class EmbedResource implements Embeddable
{
/**
* Embed result
*
* @var Adapter
*/
protected $embed;
/**
* @var string
*/
protected $url;
/**
* @var array
*/
protected $options;
/**
* @var DispatcherInterface
*/
protected $dispatcher;
/**
* @param string @url
*/
public function __construct($url)
{
$this->url = $url;
}
public function getWidth()
{
return $this->getEmbed()->getWidth() ?: 100;
}
public function getHeight()
{
return $this->getEmbed()->getHeight() ?: 100;
}
public function getPreviewURL()
{
// Use thumbnail url
if ($this->getEmbed()->image) {
return $this->getEmbed()->image;
}
// Use direct image type
if ($this->getType() === 'photo' && !empty($this->getEmbed()->url)) {
return $this->getEmbed()->url;
}
// Default media
return ModuleResourceLoader::resourceURL(
'silverstripe/asset-admin:client/dist/images/icon_file.png'
);
}
/**
* Get human readable name for this resource
*
* @return string
*/
public function getName()
{
if ($this->getEmbed()->title) {
return $this->getEmbed()->title;
}
return preg_replace('/\?.*/', '', basename($this->getEmbed()->getUrl()));
}
public function getType()
{
return $this->getEmbed()->type;
}
public function validate()
{
return !empty($this->getEmbed()->code);
}
/**
* @param array $options
* @return $this
*/
public function setOptions(array $options)
{
$this->options = $options;
return $this;
}
/**
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* @param DispatcherInterface $dispatcher
* @return $this
*/
public function setDispatcher(DispatcherInterface $dispatcher)
{
$this->dispatcher = $dispatcher;
return $this;
}
/**
* @return DispatcherInterface
*/
public function getDispatcher()
{
return $this->dispatcher;
}
/**
* Returns a bootstrapped Embed object
*
* @return Adapter
*/
public function getEmbed()
{
if (!$this->embed) {
$this->embed = Embed::create($this->url, $this->getOptions(), $this->getDispatcher());
}
return $this->embed;
}
}

View File

@ -0,0 +1,53 @@
<?php
namespace SilverStripe\View\Embed;
/**
* Abstract interface for an embeddable resource
*
* @see EmbedResource
*/
interface Embeddable
{
/**
* Get width of this Embed
*
* @return int
*/
public function getWidth();
/**
* Get height of this Embed
*
* @return int
*/
public function getHeight();
/**
* Get preview url
*
* @return string
*/
public function getPreviewURL();
/**
* Get human readable name for this resource
*
* @return string
*/
public function getName();
/**
* Get Embed type
*
* @return string
*/
public function getType();
/**
* Validate this resource
*
* @return bool
*/
public function validate();
}

View File

@ -4,6 +4,8 @@ namespace SilverStripe\View\Shortcodes;
use SilverStripe\Core\Convert;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\View\Embed\Embeddable;
use SilverStripe\View\Embed\EmbedResource;
use SilverStripe\View\HTML;
use SilverStripe\View\Parsers\ShortcodeHandler;
use Embed\Adapters\Adapter;
@ -60,6 +62,12 @@ class EmbedShortcodeProvider implements ShortcodeHandler
$serviceArguments['min_image_height'] = $arguments['height'];
}
/** @var EmbedResource $embed */
$embed = Injector::inst()->create(Embeddable::class, $serviceURL);
if (!empty($serviceArguments)) {
$embed->setOptions(array_merge($serviceArguments, (array) $embed->getOptions()));
}
// Allow resolver to be mocked
$dispatcher = null;
if (isset($extra['resolver'])) {
@ -68,10 +76,11 @@ class EmbedShortcodeProvider implements ShortcodeHandler
$serviceURL,
$extra['resolver']['config']
);
$embed->setDispatcher($dispatcher);
}
// Process embed
$embed = Embed::create($serviceURL, $serviceArguments, $dispatcher);
$embed = $embed->getEmbed();
// Convert embed object into HTML
if ($embed && $embed instanceof Adapter) {

View File

@ -0,0 +1,65 @@
<?php
namespace SilverStripe\View\Tests\Embed;
use Embed\Adapters\Adapter;
use Embed\Http\DispatcherInterface;
use Embed\Http\Response;
use Embed\Http\Url;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\View\Embed\EmbedResource;
class EmbedResourceTest extends SapphireTest
{
public function testGetEmbed()
{
$dispatcherMock = $this->createMock(DispatcherInterface::class);
$dispatcherMock->expects($this->atLeastOnce())->method('dispatch')->willReturn($this->mockResponse());
/** @var EmbedResource $embed */
$embed = Injector::inst()->create(EmbedResource::class, 'https://www.youtube.com/watch?v=iRXJXaLV0n4');
$this->assertEmpty($embed->getOptions());
$this->assertEmpty($embed->getDispatcher());
$embed->setOptions(['foo' => 'bar']);
$embed->setDispatcher($dispatcherMock);
$adapter = $embed->getEmbed();
$this->assertInstanceOf(Adapter::class, $adapter);
$this->assertSame('Try to stay SERIOUS -The most popular CAT videos', $adapter->getTitle());
}
/**
* Generate a mock Response object suitable for Embed
*
* @return Response
*/
private function mockResponse()
{
$url = Url::create('https://www.youtube.com/watch?v=iRXJXaLV0n4');
return new Response(
$url,
$url,
200,
'application/json',
json_encode([
'author_url' => 'https://www.youtube.com/channel/UCR2KG2dK1tAkwZZjm7rAiSg',
'thumbnail_width' => 480,
'title' => 'Try to stay SERIOUS -The most popular CAT videos',
'width' => 480,
'provider_name' => 'YouTube',
'author_name' => 'Tiger Funnies',
'height' => 270,
'version' => '1.0',
'type' => 'video',
// phpcs:ignore
'html' => '<iframe width="480" height="270" src="https://www.youtube.com/embed/iRXJXaLV0n4?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>',
'provider_url' => 'https://www.youtube.com/',
'thumbnail_height' => 360,
'thumbnail_url' => 'https://i.ytimg.com/vi/iRXJXaLV0n4/hqdefault.jpg',
]),
[]
);
}
}