diff --git a/code/Model/SiteTree.php b/code/Model/SiteTree.php index ea189770..7424253c 100755 --- a/code/Model/SiteTree.php +++ b/code/Model/SiteTree.php @@ -70,6 +70,7 @@ use SilverStripe\View\ArrayData; use SilverStripe\View\HTML; use SilverStripe\View\Parsers\ShortcodeParser; use SilverStripe\View\Parsers\URLSegmentFilter; +use SilverStripe\View\Shortcodes\EmbedShortcodeProvider; use SilverStripe\View\SSViewer; /** @@ -1607,6 +1608,24 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi if ($oneChangedFields && !array_diff($changedFields, $fieldsIgnoredByVersioning)) { $this->setNextWriteWithoutVersion(true); } + + // Flush cached [embed] shortcodes + // Flush on both DRAFT and LIVE because VersionedCacheAdapter has separate caches for both + // Clear both caches at once for the scenario where a CMS-author updates a remote resource + // on a 3rd party service and the url for the resource stays the same. Either saving or publishing + // the page will clear both caches. This allow a CMS-author to clear the live cache by only + // saving the draft page and not publishing any changes they may not want live yet. + $parser = ShortcodeParser::get('default'); + foreach ([Versioned::DRAFT, Versioned::LIVE] as $stage) { + Versioned::withVersionedMode(function () use ($parser, $stage) { + Versioned::set_reading_mode("Stage.$stage"); + // $this->Content may be null on brand new SiteTree objects + if (!$this->Content) { + return; + } + EmbedShortcodeProvider::flushCachedShortcodes($parser, $this->Content); + }); + } } /** diff --git a/tests/php/Model/SiteTreeTest.php b/tests/php/Model/SiteTreeTest.php index 384df5a4..f3b04557 100644 --- a/tests/php/Model/SiteTreeTest.php +++ b/tests/php/Model/SiteTreeTest.php @@ -4,6 +4,7 @@ namespace SilverStripe\CMS\Tests\Model; use LogicException; use Page; +use Psr\SimpleCache\CacheInterface; use ReflectionMethod; use SilverStripe\CMS\Model\RedirectorPage; use SilverStripe\CMS\Model\SiteTree; @@ -30,6 +31,7 @@ use SilverStripe\Versioned\Versioned; use SilverStripe\View\Parsers\Diff; use SilverStripe\View\Parsers\ShortcodeParser; use SilverStripe\View\Parsers\URLSegmentFilter; +use SilverStripe\View\Shortcodes\EmbedShortcodeProvider; use TractorCow\Fluent\Extension\FluentSiteTreeExtension; use const RESOURCES_DIR; @@ -1691,4 +1693,44 @@ class SiteTreeTest extends SapphireTest $pages = $record->DependentPages(); $this->assertCount(0, $pages, 'Unsaved pages should have no dependent pages'); } + + public function testOnBeforeWriteClearsEmbedShortcodeCache() + { + /** @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 = '