API Ability to globally enable / disable RSS feeds via config / siteconfig

This commit is contained in:
Damian Mooyman 2014-05-14 16:14:15 +12:00
parent a3c4c52faf
commit 094e3190df
8 changed files with 150 additions and 18 deletions

View File

@ -10,6 +10,9 @@ Injector:
SiteTree:
extensions:
- VersionFeed
SiteConfig:
extensions:
- VersionFeedSiteConfig
ContentController:
extensions:
- VersionFeed_Controller

View File

@ -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');
}
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
* Allows global configuration of all changes
*/
class VersionFeedSiteConfig extends DataExtension {
private static $db = array(
'AllChangesEnabled' => '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."
))
);
}
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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

View File

@ -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<br>accessible may result in publicising all historical changes on these pages too. Please review<br>this section''s "Public history" settings to ascertain only intended information is disclosed.'
VersionFeedSiteConfig:
ALLCHANGES: 'All page changes'
ALLCHANGESLABEL: 'Make global changes feed public'

View File

@ -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());
}
}
}
}
}
}