From 7304acb17138d136f24e106b22ef3f5713aee4ec Mon Sep 17 00:00:00 2001 From: Steve Boyd Date: Wed, 12 Aug 2020 12:14:05 +1200 Subject: [PATCH] NEW Cache embed shortcodes --- _config/cache.yml | 5 ++ .../Shortcodes/EmbedShortcodeProvider.php | 77 +++++++++++++++++-- .../Shortcodes/EmbedShortcodeProviderTest.php | 29 +++++++ 3 files changed, 105 insertions(+), 6 deletions(-) diff --git a/_config/cache.yml b/_config/cache.yml index 14d65fcea..2372735a9 100644 --- a/_config/cache.yml +++ b/_config/cache.yml @@ -37,3 +37,8 @@ SilverStripe\Core\Injector\Injector: factory: SilverStripe\Core\Cache\CacheFactory constructor: namespace: 'DatabaseAdapterRegistry' + Psr\SimpleCache\CacheInterface.EmbedShortcodeProvider: + factory: SilverStripe\Core\Cache\CacheFactory + constructor: + namespace: 'EmbedShortcodeProvider' + defaultLifetime: 86400 diff --git a/src/View/Shortcodes/EmbedShortcodeProvider.php b/src/View/Shortcodes/EmbedShortcodeProvider.php index f19529337..8f1cf1929 100644 --- a/src/View/Shortcodes/EmbedShortcodeProvider.php +++ b/src/View/Shortcodes/EmbedShortcodeProvider.php @@ -3,7 +3,11 @@ namespace SilverStripe\View\Shortcodes; use Embed\Http\DispatcherInterface; +use League\Flysystem\Exception; +use Psr\SimpleCache\CacheInterface; +use Psr\SimpleCache\InvalidArgumentException; use SilverStripe\Core\Convert; +use SilverStripe\Core\Extensible; use SilverStripe\Core\Injector\Injector; use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\FieldType\DBField; @@ -13,7 +17,6 @@ use SilverStripe\View\Embed\EmbedResource; use SilverStripe\View\HTML; use SilverStripe\View\Parsers\ShortcodeHandler; use Embed\Adapters\Adapter; -use Embed\Embed; use Embed\Exceptions\InvalidUrlException; use SilverStripe\View\Parsers\ShortcodeParser; use SilverStripe\Control\Director; @@ -59,6 +62,16 @@ class EmbedShortcodeProvider implements ShortcodeHandler 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 $serviceArguments = []; if (!empty($arguments['width'])) { @@ -113,13 +126,19 @@ class EmbedShortcodeProvider implements ShortcodeHandler // Convert embed object into HTML if ($embed && $embed instanceof Adapter) { $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) { } } - - // Fallback to link to service - return static::linkEmbed($arguments, $serviceURL, $serviceURL); + return $result; } /** @@ -242,4 +261,50 @@ class EmbedShortcodeProvider implements ShortcodeHandler 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; + } } diff --git a/tests/php/View/Shortcodes/EmbedShortcodeProviderTest.php b/tests/php/View/Shortcodes/EmbedShortcodeProviderTest.php index 379970c68..b7d38eb1a 100644 --- a/tests/php/View/Shortcodes/EmbedShortcodeProviderTest.php +++ b/tests/php/View/Shortcodes/EmbedShortcodeProviderTest.php @@ -2,6 +2,8 @@ namespace SilverStripe\View\Tests\Shortcodes; +use Psr\SimpleCache\CacheInterface; +use SilverStripe\View\Parsers\ShortcodeParser; use SilverStripe\View\Shortcodes\EmbedShortcodeProvider; use SilverStripe\Dev\SapphireTest; @@ -119,4 +121,31 @@ EOS ] ); } + + public function testFlushCachedShortcodes() + { + /** @var CacheInterface $cache */ + $url = 'http://www.test-service.com/abc123'; + $content = '

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]

'; + $embedHtml = '