Initial commit

This commit is contained in:
Robert Curry 2012-11-26 13:22:30 +13:00
commit d9dd9311d0
6 changed files with 213 additions and 0 deletions

0
.gitignore vendored Normal file
View File

29
README.md Normal file
View File

@ -0,0 +1,29 @@
# Version Feed
## Overview
The module creates an RSS feed on each page with their change history, as well as one for the entire site.
## Requirements
* SilverStripe 3.0+
## Installation
Install with composer by running:
composer require silverstripe/versionfeed:*
in the root of your SilverStripe project.
Or just clone/download the git repository into a subfolder (usually called "versionfeed") of your SilverStripe project.
## Usage
### Accessing RSS feeds
The extensions will automatically add links to the RSS feeds, accessible by the actions 'changes' and 'allchanges'. You will encounter problems if you have functions called the same name on any controller.
### Enabling / disabling
You can enable or disable the feed on a per-page basis by interacting with the checkbox on the Settings tab of each page.

4
_config.php Normal file
View File

@ -0,0 +1,4 @@
<?php
Object::add_extension('SiteTree', 'VersionFeed');
Object::add_extension('ContentController', 'VersionFeed_Controller');

94
code/VersionFeed.php Normal file
View File

@ -0,0 +1,94 @@
<?php
class VersionFeed extends SiteTreeExtension {
static $db = array(
'PublicHistory' => 'Boolean'
);
static $defaults = array(
'PublicHistory' => true
);
/**
* Compile a list of changes to the current page, excluding non-published and explicitly secured versions.
*
* @param int $highestVersion Top version number to consider.
* @param boolean $fullHistory Whether to get the full change history or just the previous version.
*
* @returns ArrayList List of cleaned records.
*/
public function getDiffedChanges($highestVersion = null, $fullHistory = true) {
// This can leak secured content if it was protected via inherited setting.
// For now the users will need to be aware about this shortcoming.
$offset = $highestVersion ? "AND \"SiteTree_versions\".\"Version\"<='".(int)$highestVersion."'" : '';
$limit = $fullHistory ? null : 2;
$versions = $this->owner->allVersions("\"WasPublished\"='1' AND \"CanViewType\" IN ('Anyone', 'Inherit') $offset", "\"LastEdited\" DESC", $limit);
// Process the list to add the comparisons.
$changeList = new ArrayList();
$previous = null;
$count = 0;
foreach ($versions as $version) {
$changed = false;
if (isset($previous)) {
// We have something to compare with.
$diff = $this->owner->compareVersions($version->Version, $previous->Version);
// Produce the diff fields for use in the template.
if ($version->Title != $previous->Title) {
$version->DiffTitle = new HTMLText();
$version->DiffTitle->setValue(
sprintf(
'<div><em>%s</em>' . $diff->Title . '</div>',
_t('RSSHistory.TITLECHANGED', 'Title has changed:')
)
);
$changed = true;
}
if ($version->Content != $previous->Content) {
$version->DiffContent = new HTMLText();
$version->DiffContent->setValue('<div>'.$diff->obj('Content')->forTemplate().'</div>');
$changed = true;
}
}
// Omit the versions that haven't been visibly changed (only takes the above fields into consideration).
if ($changed) {
$changeList->push($version);
$count++;
}
// Store the last version for comparison.
$previous = $version;
}
if ($fullHistory && $previous) {
$first = clone($previous);
$first->DiffContent = new HTMLText();
$first->DiffContent->setValue('<div>' . $first->obj('Content')->forTemplate() . '</div>');
$changeList->push($first);
}
return $changeList;
}
public function updateSettingsFields(FieldList $fields) {
// Add public history field.
$fields->addFieldToTab('Root.Settings', $publicHistory = new FieldGroup(
new CheckboxField('PublicHistory', $this->owner->fieldLabel(_t(
'RSSHistory.LABEL',
'Publish public RSS feed containing every published version of this page.'))
)));
$publicHistory->setTitle($this->owner->fieldLabel('Public history'));
}
public function getSiteRSSLink() {
// TODO: This link should be from the homepage, not this page.
return $this->owner->Link('allchanges');
}
public function getDefaultRSSLink() {
if ($this->owner->PublicHistory) return $this->owner->Link('changes');
}
}

View File

@ -0,0 +1,68 @@
<?php
class VersionFeed_Controller extends Extension {
static $allowed_actions = array(
'changes',
'allchanges'
);
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->linkToAllSiteRSSFeed();
return $this;
}
/**
* Get page-specific changes in a RSS feed.
*/
function changes() {
if(!$this->owner->PublicHistory) throw new SS_HTTPResponse_Exception('Page history not viewable', 404);;
// 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->setTemplate('Page_changes_rss');
return $rss->outputToBrowser();
}
/**
* 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());
}
// Produce output
$rss = new RSSFeed($changeList, $this->owner->request->getURL(), $this->linkToAllSitesRSSFeedTitle(), '', 'Title', '', null);
$rss->setTemplate('Page_allchanges_rss');
return $rss->outputToBrowser();
}
function linkToAllSiteRSSFeed() {
// RSS feed to all-site changes.
RSSFeed::linkToFeed($this->owner->getSiteRSSLink(), $this->linkToAllSitesRSSFeedTitle());
}
function linkToAllSitesRSSFeedTitle() {
return sprintf(_t('RSSHistory.SITEFEEDTITLE', 'Updates to %s'), SiteConfig::current_site_config()->Title);
}
}

18
composer.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "silverstripe/versionfeed",
"description": "Adds RSS feeds of content changes to SilverStripe",
"type": "silverstripe-module",
"keywords": ["silverstripe", "rss", "feed"],
"license": "BSD-3-Clause",
"authors": [
{
"name": "Robert Curry",
"email": "robert@silverstripe.com"
}
],
"require":
{
"silverstripe/framework": "3.*",
"silverstripe/cms": "3.*"
}
}