mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #9639 from creative-commoners/pulls/4/embed-performance
NEW Cache embed shortcodes
This commit is contained in:
commit
9aa2642d03
@ -37,3 +37,8 @@ SilverStripe\Core\Injector\Injector:
|
|||||||
factory: SilverStripe\Core\Cache\CacheFactory
|
factory: SilverStripe\Core\Cache\CacheFactory
|
||||||
constructor:
|
constructor:
|
||||||
namespace: 'DatabaseAdapterRegistry'
|
namespace: 'DatabaseAdapterRegistry'
|
||||||
|
Psr\SimpleCache\CacheInterface.EmbedShortcodeProvider:
|
||||||
|
factory: SilverStripe\Core\Cache\CacheFactory
|
||||||
|
constructor:
|
||||||
|
namespace: 'EmbedShortcodeProvider'
|
||||||
|
defaultLifetime: 86400
|
||||||
|
@ -3,7 +3,11 @@
|
|||||||
namespace SilverStripe\View\Shortcodes;
|
namespace SilverStripe\View\Shortcodes;
|
||||||
|
|
||||||
use Embed\Http\DispatcherInterface;
|
use Embed\Http\DispatcherInterface;
|
||||||
|
use League\Flysystem\Exception;
|
||||||
|
use Psr\SimpleCache\CacheInterface;
|
||||||
|
use Psr\SimpleCache\InvalidArgumentException;
|
||||||
use SilverStripe\Core\Convert;
|
use SilverStripe\Core\Convert;
|
||||||
|
use SilverStripe\Core\Extensible;
|
||||||
use SilverStripe\Core\Injector\Injector;
|
use SilverStripe\Core\Injector\Injector;
|
||||||
use SilverStripe\ORM\ArrayList;
|
use SilverStripe\ORM\ArrayList;
|
||||||
use SilverStripe\ORM\FieldType\DBField;
|
use SilverStripe\ORM\FieldType\DBField;
|
||||||
@ -13,7 +17,6 @@ use SilverStripe\View\Embed\EmbedResource;
|
|||||||
use SilverStripe\View\HTML;
|
use SilverStripe\View\HTML;
|
||||||
use SilverStripe\View\Parsers\ShortcodeHandler;
|
use SilverStripe\View\Parsers\ShortcodeHandler;
|
||||||
use Embed\Adapters\Adapter;
|
use Embed\Adapters\Adapter;
|
||||||
use Embed\Embed;
|
|
||||||
use Embed\Exceptions\InvalidUrlException;
|
use Embed\Exceptions\InvalidUrlException;
|
||||||
use SilverStripe\View\Parsers\ShortcodeParser;
|
use SilverStripe\View\Parsers\ShortcodeParser;
|
||||||
use SilverStripe\Control\Director;
|
use SilverStripe\Control\Director;
|
||||||
@ -59,6 +62,16 @@ class EmbedShortcodeProvider implements ShortcodeHandler
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to use cached result
|
||||||
|
$cache = static::getCache();
|
||||||
|
$key = static::deriveCacheKey($serviceURL);
|
||||||
|
try {
|
||||||
|
if ($cache->has($key)) {
|
||||||
|
return $cache->get($key);
|
||||||
|
}
|
||||||
|
} catch (InvalidArgumentException $e) {
|
||||||
|
}
|
||||||
|
|
||||||
// See https://github.com/oscarotero/Embed#example-with-all-options for service arguments
|
// See https://github.com/oscarotero/Embed#example-with-all-options for service arguments
|
||||||
$serviceArguments = [];
|
$serviceArguments = [];
|
||||||
if (!empty($arguments['width'])) {
|
if (!empty($arguments['width'])) {
|
||||||
@ -113,13 +126,19 @@ class EmbedShortcodeProvider implements ShortcodeHandler
|
|||||||
// Convert embed object into HTML
|
// Convert embed object into HTML
|
||||||
if ($embed && $embed instanceof Adapter) {
|
if ($embed && $embed instanceof Adapter) {
|
||||||
$result = static::embedForTemplate($embed, $arguments);
|
$result = static::embedForTemplate($embed, $arguments);
|
||||||
if ($result) {
|
}
|
||||||
return $result;
|
// Fallback to link to service
|
||||||
|
if (!$result) {
|
||||||
|
$result = static::linkEmbed($arguments, $serviceURL, $serviceURL);
|
||||||
|
}
|
||||||
|
// Cache result
|
||||||
|
if ($result) {
|
||||||
|
try {
|
||||||
|
$cache->set($key, $result);
|
||||||
|
} catch (InvalidArgumentException $e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return $result;
|
||||||
// Fallback to link to service
|
|
||||||
return static::linkEmbed($arguments, $serviceURL, $serviceURL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -242,4 +261,50 @@ class EmbedShortcodeProvider implements ShortcodeHandler
|
|||||||
|
|
||||||
return $attributes;
|
return $attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ShortcodeParser $parser
|
||||||
|
* @param string $content
|
||||||
|
*/
|
||||||
|
public static function flushCachedShortcodes(ShortcodeParser $parser, string $content): void
|
||||||
|
{
|
||||||
|
$cache = static::getCache();
|
||||||
|
$tags = $parser->extractTags($content);
|
||||||
|
foreach ($tags as $tag) {
|
||||||
|
if (!isset($tag['open']) || $tag['open'] != 'embed') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$url = $tag['content'] ?? $tag['attrs']['url'] ?? null;
|
||||||
|
if (!$url) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$key = static::deriveCacheKey($url);
|
||||||
|
try {
|
||||||
|
if (!$cache->has($key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$cache->delete($key);
|
||||||
|
} catch (InvalidArgumentException $e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return CacheInterface
|
||||||
|
*/
|
||||||
|
private static function getCache(): CacheInterface
|
||||||
|
{
|
||||||
|
return Injector::inst()->get(CacheInterface::class . '.EmbedShortcodeProvider');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $url
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function deriveCacheKey(string $url): string
|
||||||
|
{
|
||||||
|
$key = 'embed-shortcode-' . preg_replace('/[^a-zA-Z0-9\-]/', '', $url);
|
||||||
|
return $key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace SilverStripe\View\Tests\Shortcodes;
|
namespace SilverStripe\View\Tests\Shortcodes;
|
||||||
|
|
||||||
|
use Psr\SimpleCache\CacheInterface;
|
||||||
|
use SilverStripe\View\Parsers\ShortcodeParser;
|
||||||
use SilverStripe\View\Shortcodes\EmbedShortcodeProvider;
|
use SilverStripe\View\Shortcodes\EmbedShortcodeProvider;
|
||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
|
|
||||||
@ -119,4 +121,31 @@ EOS
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testFlushCachedShortcodes()
|
||||||
|
{
|
||||||
|
/** @var CacheInterface $cache */
|
||||||
|
$url = 'http://www.test-service.com/abc123';
|
||||||
|
$content = '<p>Some content with an [embed url="' . $url . '" thumbnail="https://example.com/mythumb.jpg" ' .
|
||||||
|
'class="leftAlone ss-htmleditorfield-file embed" width="480" height="270"]' . $url . '[/embed]</p>';
|
||||||
|
$embedHtml = '<iframe myattr="something" />';
|
||||||
|
$parser = ShortcodeParser::get('default');
|
||||||
|
|
||||||
|
// use reflection to access private methods
|
||||||
|
$provider = new EmbedShortcodeProvider();
|
||||||
|
$reflector = new \ReflectionClass(EmbedShortcodeProvider::class);
|
||||||
|
$method = $reflector->getMethod('getCache');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
$cache = $method->invokeArgs($provider, []);
|
||||||
|
$method = $reflector->getMethod('deriveCacheKey');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
$key = $method->invokeArgs($provider, [$url]);
|
||||||
|
|
||||||
|
// assertions
|
||||||
|
$this->assertEquals('embed-shortcode-httpwwwtest-servicecomabc123', $key);
|
||||||
|
$cache->set($key, $embedHtml);
|
||||||
|
$this->assertTrue($cache->has($key));
|
||||||
|
EmbedShortcodeProvider::flushCachedShortcodes($parser, $content);
|
||||||
|
$this->assertFalse($cache->has($key));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user