diff --git a/_config.php b/_config.php
index f18ff31..36ccb11 100644
--- a/_config.php
+++ b/_config.php
@@ -2,3 +2,6 @@
SiteTree::add_extension('VersionFeed');
ContentController::add_extension('VersionFeed_Controller');
+
+// Set the cache lifetime to 5 mins.
+SS_Cache::set_cache_lifetime('VersionFeed_Controller', 5*60);
diff --git a/code/VersionFeed.php b/code/VersionFeed.php
index 693fcd5..1dafb95 100644
--- a/code/VersionFeed.php
+++ b/code/VersionFeed.php
@@ -51,6 +51,9 @@ class VersionFeed extends SiteTreeExtension {
$version->DiffContent->setValue('
'.$diff->obj('Content')->forTemplate().'
');
$changed = true;
}
+
+ // Copy the link so it can be cached by SS_Cache.
+ $version->GeneratedLink = $version->AbsoluteLink();
}
// Omit the versions that haven't been visibly changed (only takes the above fields into consideration).
@@ -93,4 +96,4 @@ class VersionFeed extends SiteTreeExtension {
public function getDefaultRSSLink() {
if ($this->owner->PublicHistory) return $this->owner->Link('changes');
}
-}
\ No newline at end of file
+}
diff --git a/code/VersionFeed_Controller.php b/code/VersionFeed_Controller.php
index 2fb1c07..08d4a71 100644
--- a/code/VersionFeed_Controller.php
+++ b/code/VersionFeed_Controller.php
@@ -29,9 +29,19 @@ class VersionFeed_Controller extends Extension {
function changes() {
if(!$this->owner->PublicHistory) throw new SS_HTTPResponse_Exception('Page history not viewable', 404);;
+ // Cache the diffs, otherwise it will take 5secs to generate 100 diffs which could lead to DOS.
+ $cache = SS_Cache::factory('VersionFeed_Controller');
+ $cache->setOption('automatic_serialization', true);
+ $key = 'changes' . $this->owner->Version;
+ $entries = $cache->load($key);
+ if(!$entries) {
+ $entries = $this->owner->getDiffedChanges();
+ $cache->save($entries, $key);
+ }
+
// Generate the output.
$title = sprintf(_t('RSSHistory.SINGLEPAGEFEEDTITLE', 'Updates to %s page'), $this->owner->Title);
- $rss = new RSSFeed($this->owner->getDiffedChanges(), $this->owner->request->getURL(), $title, '', 'Title', '', null);
+ $rss = new RSSFeed($entries, $this->owner->request->getURL(), $title, '', 'Title', '', null);
$rss->setTemplate('Page_changes_rss');
return $rss->outputToBrowser();
}
@@ -40,15 +50,33 @@ class VersionFeed_Controller extends Extension {
* Get all changes from the site in a RSS feed.
*/
function allchanges() {
- // Fetch the latest changes on the entire site.
- $latestChanges = DB::query('SELECT * FROM "SiteTree_versions" WHERE "WasPublished"=\'1\' AND "CanViewType" IN (\'Anyone\', \'Inherit\') AND "ShowInSearch"=1 AND ("PublicHistory" IS NULL OR "PublicHistory" = \'1\') ORDER BY "LastEdited" DESC LIMIT 20');
- $changeList = new ArrayList();
- foreach ($latestChanges as $record) {
- // Get the diff to the previous version.
- $version = new Versioned_Version($record);
- $changes = $version->getDiffedChanges($version->Version, false);
- if ($changes && $changes->Count()) $changeList->push($changes->First());
+ $latestChanges = DB::query('SELECT * FROM "SiteTree_versions" WHERE "WasPublished"=\'1\' AND "CanViewType" IN (\'Anyone\', \'Inherit\') AND "ShowInSearch"=1 AND ("PublicHistory" IS NULL OR "PublicHistory" = \'1\') ORDER BY "LastEdited" DESC LIMIT 20');
+ $lastChange = $latestChanges->record();
+ $latestChanges->rewind();
+
+ if ($lastChange) {
+
+ // Cache the diffs, otherwise it will take 5secs to generate 100 diffs which could lead to DOS.
+ $cache = SS_Cache::factory('VersionFeed_Controller');
+ $cache->setOption('automatic_serialization', true);
+ $key = 'allchanges' . preg_replace('#[^a-zA-Z0-9_]#', '', $lastChange['LastEdited']);
+
+ $changeList = $cache->load($key);
+ if(!$changeList) {
+
+ $changeList = new ArrayList();
+
+ foreach ($latestChanges as $record) {
+ // Get the diff to the previous version.
+ $version = new Versioned_Version($record);
+ $changes = $version->getDiffedChanges($version->Version, false);
+ if ($changes && $changes->Count()) $changeList->push($changes->First());
+ }
+
+ $cache->save($changeList, $key);
+ }
+
}
// Produce output
@@ -65,4 +93,4 @@ class VersionFeed_Controller extends Extension {
function linkToAllSitesRSSFeedTitle() {
return sprintf(_t('RSSHistory.SITEFEEDTITLE', 'Updates to %s'), SiteConfig::current_site_config()->Title);
}
-}
\ No newline at end of file
+}