diff --git a/_config/versionfeed.yml b/_config/versionfeed.yml index e6e99eb..d775357 100644 --- a/_config/versionfeed.yml +++ b/_config/versionfeed.yml @@ -10,6 +10,9 @@ Injector: SiteTree: extensions: - VersionFeed +SiteConfig: + extensions: + - VersionFeedSiteConfig ContentController: extensions: - VersionFeed_Controller diff --git a/code/VersionFeed.php b/code/VersionFeed.php index 4004192..ce5ee3e 100644 --- a/code/VersionFeed.php +++ b/code/VersionFeed.php @@ -13,6 +13,22 @@ class VersionFeed extends SiteTreeExtension { public function updateFieldLabels(&$labels) { $labels['PublicHistory'] = _t('RSSHistory.LABEL', 'Make history public'); } + + /** + * Enable the allchanges feed + * + * @config + * @var bool + */ + private static $allchanges_enabled = true; + + /** + * Enables RSS feed for page-specific changes + * + * @config + * @var bool + */ + private static $changes_enabled = true; /** * Compile a list of changes to the current page, excluding non-published and explicitly secured versions. @@ -84,6 +100,8 @@ class VersionFeed extends SiteTreeExtension { } public function updateSettingsFields(FieldList $fields) { + if(!Config::inst()->get(get_class(), 'changes_enabled')) return; + // Add public history field. $fields->addFieldToTab('Root.Settings', $publicHistory = new FieldGroup( new CheckboxField('PublicHistory', $this->owner->fieldLabel('PublicHistory') @@ -111,10 +129,16 @@ class VersionFeed extends SiteTreeExtension { public function getSiteRSSLink() { // TODO: This link should be from the homepage, not this page. - return $this->owner->Link('allchanges'); + if(Config::inst()->get(get_class(), 'allchanges_enabled') + && SiteConfig::current_site_config()->AllChangesEnabled + ) { + return $this->owner->Link('allchanges'); + } } public function getDefaultRSSLink() { - if ($this->owner->PublicHistory) return $this->owner->Link('changes'); + if(Config::inst()->get(get_class(), 'changes_enabled') && $this->owner->PublicHistory) { + return $this->owner->Link('changes'); + } } } diff --git a/code/VersionFeedSiteConfig.php b/code/VersionFeedSiteConfig.php new file mode 100644 index 0000000..2320bc5 --- /dev/null +++ b/code/VersionFeedSiteConfig.php @@ -0,0 +1,33 @@ + 'Boolean(true)' + ); + + private static $defaults = array( + 'AllChangesEnabled' => true + ); + + public function updateFieldLabels(&$labels) { + $labels['AllChangesEnabled'] = _t('VersionFeedSiteConfig.ALLCHANGESLABEL', 'Make global changes feed public'); + } + + public function updateCMSFields(\FieldList $fields) { + if(!Config::inst()->get('VersionFeed', 'allchanges_enabled')) return; + + $fields->addFieldToTab('Root.Access', + FieldGroup::create(new CheckboxField('AllChangesEnabled', $this->owner->fieldLabel('AllChangesEnabled'))) + ->setTitle(_t('VersionFeedSiteConfig.ALLCHANGES', 'All page changes')) + ->setDescription(_t( + 'VersionFeed.Warning', + "Publicising the history will also disclose the changes that have at the time been protected " . + "from the public view." + )) + ); + } +} diff --git a/code/VersionFeed_Controller.php b/code/VersionFeed_Controller.php index e39b476..68e0768 100644 --- a/code/VersionFeed_Controller.php +++ b/code/VersionFeed_Controller.php @@ -39,26 +39,18 @@ class VersionFeed_Controller extends Extension { } public function onAfterInit() { - // RSS feed for per-page changes. - if ($this->owner->PublicHistory) { - RSSFeed::linkToFeed($this->owner->Link() . 'changes', - sprintf( - _t('RSSHistory.SINGLEPAGEFEEDTITLE', 'Updates to %s page'), - $this->owner->Title - ) - ); - } - + $this->linkToPageRSSFeed(); $this->linkToAllSiteRSSFeed(); - - return $this; } /** * Get page-specific changes in a RSS feed. */ public function changes() { - if(!$this->owner->PublicHistory) throw new SS_HTTPResponse_Exception('Page history not viewable', 404); + // Check viewability of changes + if(!Config::inst()->get('VersionFeed', 'changes_enabled') || !$this->owner->PublicHistory) { + return $this->owner->httpError(404, 'Page history not viewable'); + } // Cache the diffs to remove DOS possibility. $target = $this->owner; @@ -78,6 +70,12 @@ class VersionFeed_Controller extends Extension { * Get all changes from the site in a RSS feed. */ public function allchanges() { + // Check viewability of allchanges + if(!Config::inst()->get('VersionFeed', 'allchanges_enabled') + || !SiteConfig::current_site_config()->AllChangesEnabled + ) { + return $this->owner->httpError(404, 'Global history not viewable'); + } $latestChanges = DB::query(' SELECT * FROM "SiteTree_versions" @@ -127,8 +125,34 @@ class VersionFeed_Controller extends Extension { $rss->setTemplate('Page_allchanges_rss'); return $rss->outputToBrowser(); } + + /** + * Generates and embeds the RSS header link for the page-specific version rss feed + */ + public function linkToPageRSSFeed() { + if (!Config::inst()->get('VersionFeed', 'changes_enabled') || !$this->owner->PublicHistory) { + return; + } + + RSSFeed::linkToFeed( + $this->owner->Link('changes'), + sprintf( + _t('RSSHistory.SINGLEPAGEFEEDTITLE', 'Updates to %s page'), + $this->owner->Title + ) + ); + } - function linkToAllSiteRSSFeed() { + /** + * Generates and embeds the RSS header link for the global version rss feed + */ + public function linkToAllSiteRSSFeed() { + if(!Config::inst()->get('VersionFeed', 'allchanges_enabled') + || !SiteConfig::current_site_config()->AllChangesEnabled + ) { + return; + } + // RSS feed to all-site changes. $title = Convert::raw2xml($this->linkToAllSitesRSSFeedTitle()); $url = $this->owner->getSiteRSSLink(); @@ -138,7 +162,7 @@ class VersionFeed_Controller extends Extension { '" href="' . $url . '" />'); } - function linkToAllSitesRSSFeedTitle() { + public function linkToAllSitesRSSFeedTitle() { return sprintf(_t('RSSHistory.SITEFEEDTITLE', 'Updates to %s'), SiteConfig::current_site_config()->Title); } } diff --git a/docs/en/developer.md b/docs/en/developer.md index 5d4ee74..1d9fa82 100644 --- a/docs/en/developer.md +++ b/docs/en/developer.md @@ -7,6 +7,15 @@ Creating functions called `changes` or `allchanges` on any of your page types or controllers will cause confusion with the extensions defined on the extension. +### Enabling / Disabling + +The `allchanges` feed can be disabled by setting the `VersionFeed.allchanges_enabled` config to false. + +Likewise, the `changes` feed for each page can be globally disabled by setting the `VersionFeed.changes_enabled` +config to false. If this left true, then each page can still be individually disabled by unchecking the +'Make History Public' checkbox in the CMS under page settings. +See [user documentation on enabling / disabling](user.md#enabling--disabling). + ### Default RSS action Templates can offer a "Subscribe" link with a link to the most relevant RSS feed. This will default to the changes feed diff --git a/docs/en/user.md b/docs/en/user.md index 2331f4d..9d27c52 100644 --- a/docs/en/user.md +++ b/docs/en/user.md @@ -17,6 +17,9 @@ You can enable or disable the feed on a per-page basis by checking or unchecking Settings tab of each page. If a page has the Public History option, unchecked, it will not appear in the allchanges feed. +The allchanges feed can also be disabled by unchecking the "All page changes" checkbox in the "Settings" +section in the cms. + #### Privacy A page's history will be completely visible when it has public history enabled, even if some updates were made when it diff --git a/lang/en.yml b/lang/en.yml index 9f96f8f..d68d03b 100644 --- a/lang/en.yml +++ b/lang/en.yml @@ -7,3 +7,6 @@ en: VersionFeed: Warning: 'Publicising the history will also disclose the changes that have at the time been protected from the public view.' Warning2: 'Changing access settings in such a way that this page or pages under it become publicly
accessible may result in publicising all historical changes on these pages too. Please review
this section''s "Public history" settings to ascertain only intended information is disclosed.' + VersionFeedSiteConfig: + ALLCHANGES: 'All page changes' + ALLCHANGESLABEL: 'Make global changes feed public' diff --git a/tests/VersionFeedFunctionalTest.php b/tests/VersionFeedFunctionalTest.php index 1f40f50..736fc99 100644 --- a/tests/VersionFeedFunctionalTest.php +++ b/tests/VersionFeedFunctionalTest.php @@ -178,5 +178,38 @@ class VersionFeedFunctionalTest extends FunctionalTest { return $page; } + + /** + * Tests response code for globally disabled feedss + */ + public function testFeedViewability() { + $siteConfig = SiteConfig::current_site_config(); + + // Nested loop through each configuration + foreach(array(true, false) as $publicHistory_Page) { + $page = $this->createPageWithChanges(array('PublicHistory' => $publicHistory_Page, 'Title' => 'Page')); + + // Test requests to 'changes' action + foreach(array(true, false) as $publicHistory_Config) { + Config::inst()->update('VersionFeed', 'changes_enabled', $publicHistory_Config); + $expectedResponse = $publicHistory_Page && $publicHistory_Config ? 200 : 404; + $response = $this->get($page->RelativeLink('changes')); + $this->assertEquals($expectedResponse, $response->getStatusCode()); + } + + // Test requests to 'allchanges' action on each page + foreach(array(true, false) as $allChanges_Config) { + foreach(array(true, false) as $allChanges_SiteConfig) { + Config::inst()->update('VersionFeed', 'allchanges_enabled', $allChanges_Config); + $siteConfig->AllChangesEnabled = $allChanges_SiteConfig; + $siteConfig->write(); + + $expectedResponse = $allChanges_Config && $allChanges_SiteConfig ? 200 : 404; + $response = $this->get($page->RelativeLink('allchanges')); + $this->assertEquals($expectedResponse, $response->getStatusCode()); + } + } + } + } -} \ No newline at end of file +}