FIX: Minor functional alterations and CI improvements
FIX: PSR-2 codebase. Formatting via phpcbf FIX: rendering bug in allchanges FIX: update .gitattributes to not export codecov's config file FIX: Update SiteTree_versions to the ss4 equivalent SiteTree_Versions
This commit is contained in:
parent
17cf3d7487
commit
67e112fd12
|
@ -4,3 +4,4 @@
|
||||||
/.gitignore export-ignore
|
/.gitignore export-ignore
|
||||||
/.travis.yml export-ignore
|
/.travis.yml export-ignore
|
||||||
/.scrutinizer.yml export-ignore
|
/.scrutinizer.yml export-ignore
|
||||||
|
/codecov.yml export-ignore
|
||||||
|
|
|
@ -22,7 +22,6 @@ before_script:
|
||||||
|
|
||||||
# Install composer dependencies
|
# Install composer dependencies
|
||||||
- composer validate
|
- composer validate
|
||||||
- composer require --no-update silverstripe/recipe-core:1.0.x-dev
|
|
||||||
- if [[ $DB == PGSQL ]]; then composer require --no-update silverstripe/postgresql 2.0.x-dev; fi
|
- if [[ $DB == PGSQL ]]; then composer require --no-update silverstripe/postgresql 2.0.x-dev; fi
|
||||||
- composer install --prefer-dist --no-interaction --no-progress --no-suggest --optimize-autoloader --verbose --profile
|
- composer install --prefer-dist --no-interaction --no-progress --no-suggest --optimize-autoloader --verbose --profile
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
],
|
],
|
||||||
"require":
|
"require":
|
||||||
{
|
{
|
||||||
"silverstripe/recipe-cms": "^1"
|
"silverstripe/cms": "^4",
|
||||||
|
"silverstripe/versioned": "^1",
|
||||||
|
"silverstripe/siteconfig": "^4"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^5.7",
|
"phpunit/phpunit": "^5.7",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<phpunit bootstrap="vendor/silverstripe/framework/tests/bootstrap.php" colors="true">
|
<phpunit bootstrap="vendor/silverstripe/cms/tests/bootstrap.php" colors="true">
|
||||||
<testsuite name="Default">
|
<testsuite name="Default">
|
||||||
<directory>tests/</directory>
|
<directory>tests/</directory>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
|
|
|
@ -2,16 +2,13 @@
|
||||||
|
|
||||||
namespace SilverStripe\VersionFeed\Filters;
|
namespace SilverStripe\VersionFeed\Filters;
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\Core\Config\Config;
|
use SilverStripe\Core\Config\Config;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caches results of a callback
|
* Caches results of a callback
|
||||||
*/
|
*/
|
||||||
class CachedContentFilter extends ContentFilter {
|
class CachedContentFilter extends ContentFilter
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable caching
|
* Enable caching
|
||||||
|
@ -21,7 +18,8 @@ class CachedContentFilter extends ContentFilter {
|
||||||
*/
|
*/
|
||||||
private static $cache_enabled = true;
|
private static $cache_enabled = true;
|
||||||
|
|
||||||
public function getContent($key, $callback) {
|
public function getContent($key, $callback)
|
||||||
|
{
|
||||||
$cache = $this->getCache();
|
$cache = $this->getCache();
|
||||||
|
|
||||||
// Return cached value if available
|
// Return cached value if available
|
||||||
|
@ -29,7 +27,9 @@ class CachedContentFilter extends ContentFilter {
|
||||||
$result = (isset($_GET['flush']) || !$cacheEnabled)
|
$result = (isset($_GET['flush']) || !$cacheEnabled)
|
||||||
? null
|
? null
|
||||||
: $cache->get($key);
|
: $cache->get($key);
|
||||||
if($result) return $result;
|
if ($result) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
// Fallback to generate result
|
// Fallback to generate result
|
||||||
$result = parent::getContent($key, $callback);
|
$result = parent::getContent($key, $callback);
|
||||||
|
|
|
@ -7,13 +7,12 @@ use SilverStripe\Core\Config\Configurable;
|
||||||
use Psr\SimpleCache\CacheInterface;
|
use Psr\SimpleCache\CacheInterface;
|
||||||
use SilverStripe\Core\Injector\Injector;
|
use SilverStripe\Core\Injector\Injector;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conditionally executes a given callback, attempting to return the desired results
|
* Conditionally executes a given callback, attempting to return the desired results
|
||||||
* of its execution.
|
* of its execution.
|
||||||
*/
|
*/
|
||||||
abstract class ContentFilter {
|
abstract class ContentFilter
|
||||||
|
{
|
||||||
|
|
||||||
use Configurable;
|
use Configurable;
|
||||||
|
|
||||||
|
@ -32,7 +31,8 @@ abstract class ContentFilter {
|
||||||
*/
|
*/
|
||||||
private static $cache_lifetime = 300;
|
private static $cache_lifetime = 300;
|
||||||
|
|
||||||
public function __construct($nestedContentFilter = null) {
|
public function __construct($nestedContentFilter = null)
|
||||||
|
{
|
||||||
$this->nestedContentFilter = $nestedContentFilter;
|
$this->nestedContentFilter = $nestedContentFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,8 @@ abstract class ContentFilter {
|
||||||
*
|
*
|
||||||
* @return Zend_Cache_Frontend
|
* @return Zend_Cache_Frontend
|
||||||
*/
|
*/
|
||||||
protected function getCache() {
|
protected function getCache()
|
||||||
|
{
|
||||||
return Injector::inst()->get(
|
return Injector::inst()->get(
|
||||||
CacheInterface::class . '.VersionFeedController'
|
CacheInterface::class . '.VersionFeedController'
|
||||||
);
|
);
|
||||||
|
@ -54,7 +55,8 @@ abstract class ContentFilter {
|
||||||
* @param callable $callback Callback for evaluating the content
|
* @param callable $callback Callback for evaluating the content
|
||||||
* @return mixed Result of $callback()
|
* @return mixed Result of $callback()
|
||||||
*/
|
*/
|
||||||
public function getContent($key, $callback) {
|
public function getContent($key, $callback)
|
||||||
|
{
|
||||||
if ($this->nestedContentFilter) {
|
if ($this->nestedContentFilter) {
|
||||||
return $this->nestedContentFilter->getContent($key, $callback);
|
return $this->nestedContentFilter->getContent($key, $callback);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,20 +2,15 @@
|
||||||
|
|
||||||
namespace SilverStripe\VersionFeed\Filters;
|
namespace SilverStripe\VersionFeed\Filters;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\Core\Config\Config;
|
use SilverStripe\Core\Config\Config;
|
||||||
use SilverStripe\Control\Controller;
|
use SilverStripe\Control\Controller;
|
||||||
use SilverStripe\Control\HTTPResponse_Exception;
|
use SilverStripe\Control\HTTPResponse_Exception;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides rate limiting of execution of a callback
|
* Provides rate limiting of execution of a callback
|
||||||
*/
|
*/
|
||||||
class RateLimitFilter extends ContentFilter {
|
class RateLimitFilter extends ContentFilter
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Time duration (in second) to allow for generation of cached results. Requests to
|
* Time duration (in second) to allow for generation of cached results. Requests to
|
||||||
|
@ -66,7 +61,8 @@ class RateLimitFilter extends ContentFilter {
|
||||||
* @param string $itemkey Input key
|
* @param string $itemkey Input key
|
||||||
* @return string Result key
|
* @return string Result key
|
||||||
*/
|
*/
|
||||||
protected function getCacheKey($itemkey) {
|
protected function getCacheKey($itemkey)
|
||||||
|
{
|
||||||
$key = self::CACHE_PREFIX;
|
$key = self::CACHE_PREFIX;
|
||||||
|
|
||||||
// Add global identifier
|
// Add global identifier
|
||||||
|
@ -84,7 +80,8 @@ class RateLimitFilter extends ContentFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getContent($key, $callback) {
|
public function getContent($key, $callback)
|
||||||
|
{
|
||||||
// Bypass rate limiting if flushing, or timeout isn't set
|
// Bypass rate limiting if flushing, or timeout isn't set
|
||||||
$timeout = $this->config()->get('lock_timeout');
|
$timeout = $this->config()->get('lock_timeout');
|
||||||
if (isset($_GET['flush']) || !$timeout) {
|
if (isset($_GET['flush']) || !$timeout) {
|
||||||
|
|
|
@ -13,7 +13,8 @@ use SilverStripe\Forms\LiteralField;
|
||||||
use SilverStripe\SiteConfig\SiteConfig;
|
use SilverStripe\SiteConfig\SiteConfig;
|
||||||
use SilverStripe\CMS\Model\SiteTreeExtension;
|
use SilverStripe\CMS\Model\SiteTreeExtension;
|
||||||
|
|
||||||
class VersionFeed extends SiteTreeExtension {
|
class VersionFeed extends SiteTreeExtension
|
||||||
|
{
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'PublicHistory' => 'Boolean(true)'
|
'PublicHistory' => 'Boolean(true)'
|
||||||
|
@ -23,7 +24,8 @@ class VersionFeed extends SiteTreeExtension {
|
||||||
'PublicHistory' => true
|
'PublicHistory' => true
|
||||||
);
|
);
|
||||||
|
|
||||||
public function updateFieldLabels(&$labels) {
|
public function updateFieldLabels(&$labels)
|
||||||
|
{
|
||||||
$labels['PublicHistory'] = _t('RSSHistory.LABEL', 'Make history public');
|
$labels['PublicHistory'] = _t('RSSHistory.LABEL', 'Make history public');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,10 +69,11 @@ class VersionFeed extends SiteTreeExtension {
|
||||||
*
|
*
|
||||||
* @returns ArrayList List of cleaned records.
|
* @returns ArrayList List of cleaned records.
|
||||||
*/
|
*/
|
||||||
public function getDiffList($highestVersion = null, $limit = 100) {
|
public function getDiffList($highestVersion = null, $limit = 100)
|
||||||
|
{
|
||||||
// This can leak secured content if it was protected via inherited setting.
|
// This can leak secured content if it was protected via inherited setting.
|
||||||
// For now the users will need to be aware about this shortcoming.
|
// For now the users will need to be aware about this shortcoming.
|
||||||
$offset = $highestVersion ? "AND \"SiteTree_versions\".\"Version\"<='".(int)$highestVersion."'" : '';
|
$offset = $highestVersion ? "AND \"SiteTree_Versions\".\"Version\"<='".(int)$highestVersion."'" : '';
|
||||||
// Get just enough elements for diffing. We need one more than desired to have something to compare to.
|
// Get just enough elements for diffing. We need one more than desired to have something to compare to.
|
||||||
$qLimit = (int)$limit + 1;
|
$qLimit = (int)$limit + 1;
|
||||||
$versions = $this->owner->allVersions(
|
$versions = $this->owner->allVersions(
|
||||||
|
@ -88,7 +91,6 @@ class VersionFeed extends SiteTreeExtension {
|
||||||
|
|
||||||
// Check if we have something to compare with.
|
// Check if we have something to compare with.
|
||||||
if (isset($previous)) {
|
if (isset($previous)) {
|
||||||
|
|
||||||
// Produce the diff fields for use in the template.
|
// Produce the diff fields for use in the template.
|
||||||
if ($version->Title != $previous->Title) {
|
if ($version->Title != $previous->Title) {
|
||||||
$diffTitle = Diff::compareHTML($version->Title, $previous->Title);
|
$diffTitle = Diff::compareHTML($version->Title, $previous->Title);
|
||||||
|
@ -146,7 +148,8 @@ class VersionFeed extends SiteTreeExtension {
|
||||||
*
|
*
|
||||||
* @returns DataObject Object with relevant fields diffed.
|
* @returns DataObject Object with relevant fields diffed.
|
||||||
*/
|
*/
|
||||||
public function getDiff() {
|
public function getDiff()
|
||||||
|
{
|
||||||
$changes = $this->getDiffList($this->owner->Version, 1);
|
$changes = $this->getDiffList($this->owner->Version, 1);
|
||||||
if ($changes && $changes->Count()) {
|
if ($changes && $changes->Count()) {
|
||||||
return $changes->First();
|
return $changes->First();
|
||||||
|
@ -166,20 +169,24 @@ class VersionFeed extends SiteTreeExtension {
|
||||||
*
|
*
|
||||||
* @returns ArrayList List of cleaned records.
|
* @returns ArrayList List of cleaned records.
|
||||||
*/
|
*/
|
||||||
public function getDiffedChanges($highestVersion = null, $fullHistory = true, $limit = 100) {
|
public function getDiffedChanges($highestVersion = null, $fullHistory = true, $limit = 100)
|
||||||
|
{
|
||||||
return $this->getDiffList(
|
return $this->getDiffList(
|
||||||
$highestVersion,
|
$highestVersion,
|
||||||
$fullHistory ? $limit : 1
|
$fullHistory ? $limit : 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateSettingsFields(FieldList $fields) {
|
public function updateSettingsFields(FieldList $fields)
|
||||||
if(!Config::inst()->get(get_class(), 'changes_enabled')) return;
|
{
|
||||||
|
if (!Config::inst()->get(get_class(), 'changes_enabled')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Add public history field.
|
// Add public history field.
|
||||||
$fields->addFieldToTab('Root.Settings', $publicHistory = new FieldGroup(
|
$fields->addFieldToTab('Root.Settings', $publicHistory = new FieldGroup(
|
||||||
new CheckboxField('PublicHistory', $this->owner->fieldLabel('PublicHistory')
|
new CheckboxField('PublicHistory', $this->owner->fieldLabel('PublicHistory'))
|
||||||
)));
|
));
|
||||||
|
|
||||||
$warning = _t(
|
$warning = _t(
|
||||||
'VersionFeed.Warning',
|
'VersionFeed.Warning',
|
||||||
|
@ -201,7 +208,8 @@ class VersionFeed extends SiteTreeExtension {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSiteRSSLink() {
|
public function getSiteRSSLink()
|
||||||
|
{
|
||||||
// TODO: This link should be from the homepage, not this page.
|
// TODO: This link should be from the homepage, not this page.
|
||||||
if (Config::inst()->get(get_class(), 'allchanges_enabled')
|
if (Config::inst()->get(get_class(), 'allchanges_enabled')
|
||||||
&& SiteConfig::current_site_config()->AllChangesEnabled
|
&& SiteConfig::current_site_config()->AllChangesEnabled
|
||||||
|
@ -210,7 +218,8 @@ class VersionFeed extends SiteTreeExtension {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDefaultRSSLink() {
|
public function getDefaultRSSLink()
|
||||||
|
{
|
||||||
if (Config::inst()->get(get_class(), 'changes_enabled') && $this->owner->PublicHistory) {
|
if (Config::inst()->get(get_class(), 'changes_enabled') && $this->owner->PublicHistory) {
|
||||||
return $this->owner->Link('changes');
|
return $this->owner->Link('changes');
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,8 @@ use SilverStripe\View\Requirements;
|
||||||
use SilverStripe\Core\Extension;
|
use SilverStripe\Core\Extension;
|
||||||
use SilverStripe\VersionFeed\Filters\ContentFilter;
|
use SilverStripe\VersionFeed\Filters\ContentFilter;
|
||||||
|
|
||||||
class VersionFeedController extends Extension {
|
class VersionFeedController extends Extension
|
||||||
|
{
|
||||||
|
|
||||||
private static $allowed_actions = array(
|
private static $allowed_actions = array(
|
||||||
'changes',
|
'changes',
|
||||||
|
@ -35,7 +36,8 @@ class VersionFeedController extends Extension {
|
||||||
*
|
*
|
||||||
* @param ContentFilter $contentFilter
|
* @param ContentFilter $contentFilter
|
||||||
*/
|
*/
|
||||||
public function setContentFilter(ContentFilter $contentFilter) {
|
public function setContentFilter(ContentFilter $contentFilter)
|
||||||
|
{
|
||||||
$this->contentFilter = $contentFilter;
|
$this->contentFilter = $contentFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +48,8 @@ class VersionFeedController extends Extension {
|
||||||
* @param callable $callback Callback for evaluating the content
|
* @param callable $callback Callback for evaluating the content
|
||||||
* @return mixed Result of $callback()
|
* @return mixed Result of $callback()
|
||||||
*/
|
*/
|
||||||
protected function filterContent($key, $callback) {
|
protected function filterContent($key, $callback)
|
||||||
|
{
|
||||||
if ($this->contentFilter) {
|
if ($this->contentFilter) {
|
||||||
return $this->contentFilter->getContent($key, $callback);
|
return $this->contentFilter->getContent($key, $callback);
|
||||||
} else {
|
} else {
|
||||||
|
@ -54,7 +57,8 @@ class VersionFeedController extends Extension {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onAfterInit() {
|
public function onAfterInit()
|
||||||
|
{
|
||||||
$this->linkToPageRSSFeed();
|
$this->linkToPageRSSFeed();
|
||||||
$this->linkToAllSiteRSSFeed();
|
$this->linkToAllSiteRSSFeed();
|
||||||
}
|
}
|
||||||
|
@ -62,7 +66,8 @@ class VersionFeedController extends Extension {
|
||||||
/**
|
/**
|
||||||
* Get page-specific changes in a RSS feed.
|
* Get page-specific changes in a RSS feed.
|
||||||
*/
|
*/
|
||||||
public function changes() {
|
public function changes()
|
||||||
|
{
|
||||||
// Check viewability of changes
|
// Check viewability of changes
|
||||||
if (!Config::inst()->get(VersionFeed::class, 'changes_enabled')
|
if (!Config::inst()->get(VersionFeed::class, 'changes_enabled')
|
||||||
|| !$this->owner->PublicHistory
|
|| !$this->owner->PublicHistory
|
||||||
|
@ -88,7 +93,8 @@ class VersionFeedController extends Extension {
|
||||||
/**
|
/**
|
||||||
* Get all changes from the site in a RSS feed.
|
* Get all changes from the site in a RSS feed.
|
||||||
*/
|
*/
|
||||||
public function allchanges() {
|
public function allchanges()
|
||||||
|
{
|
||||||
// Check viewability of allchanges
|
// Check viewability of allchanges
|
||||||
if (!Config::inst()->get(VersionFeed::class, 'allchanges_enabled')
|
if (!Config::inst()->get(VersionFeed::class, 'allchanges_enabled')
|
||||||
|| !SiteConfig::current_site_config()->AllChangesEnabled
|
|| !SiteConfig::current_site_config()->AllChangesEnabled
|
||||||
|
@ -98,18 +104,16 @@ class VersionFeedController extends Extension {
|
||||||
|
|
||||||
$limit = (int)Config::inst()->get(VersionFeed::class, 'allchanges_limit');
|
$limit = (int)Config::inst()->get(VersionFeed::class, 'allchanges_limit');
|
||||||
$latestChanges = DB::query('
|
$latestChanges = DB::query('
|
||||||
SELECT * FROM "SiteTree_versions"
|
SELECT * FROM "SiteTree_Versions"
|
||||||
WHERE "WasPublished" = \'1\'
|
WHERE "WasPublished" = \'1\'
|
||||||
AND "CanViewType" IN (\'Anyone\', \'Inherit\')
|
AND "CanViewType" IN (\'Anyone\', \'Inherit\')
|
||||||
AND "ShowInSearch" = 1
|
AND "ShowInSearch" = 1
|
||||||
AND ("PublicHistory" IS NULL OR "PublicHistory" = \'1\')
|
AND ("PublicHistory" IS NULL OR "PublicHistory" = \'1\')
|
||||||
ORDER BY "LastEdited" DESC LIMIT ' . $limit
|
ORDER BY "LastEdited" DESC LIMIT ' . $limit);
|
||||||
);
|
|
||||||
$lastChange = $latestChanges->record();
|
$lastChange = $latestChanges->record();
|
||||||
$latestChanges->rewind();
|
$latestChanges->rewind();
|
||||||
|
|
||||||
if ($lastChange) {
|
if ($lastChange) {
|
||||||
|
|
||||||
// Cache the diffs to remove DOS possibility.
|
// Cache the diffs to remove DOS possibility.
|
||||||
$key = 'allchanges'
|
$key = 'allchanges'
|
||||||
. preg_replace('#[^a-zA-Z0-9_]#', '', $lastChange['LastEdited'])
|
. preg_replace('#[^a-zA-Z0-9_]#', '', $lastChange['LastEdited'])
|
||||||
|
@ -118,7 +122,6 @@ class VersionFeedController extends Extension {
|
||||||
$changeList = new ArrayList();
|
$changeList = new ArrayList();
|
||||||
$canView = array();
|
$canView = array();
|
||||||
foreach ($latestChanges as $record) {
|
foreach ($latestChanges as $record) {
|
||||||
|
|
||||||
// Check if the page should be visible.
|
// Check if the page should be visible.
|
||||||
// WARNING: although we are providing historical details, we check the current configuration.
|
// WARNING: although we are providing historical details, we check the current configuration.
|
||||||
$id = $record['RecordID'];
|
$id = $record['RecordID'];
|
||||||
|
@ -126,10 +129,12 @@ class VersionFeedController extends Extension {
|
||||||
$page = SiteTree::get()->byID($id);
|
$page = SiteTree::get()->byID($id);
|
||||||
$canView[$id] = $page && $page->canView(new Member());
|
$canView[$id] = $page && $page->canView(new Member());
|
||||||
}
|
}
|
||||||
if (!$canView[$id]) continue;
|
if (!$canView[$id]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the diff to the previous version.
|
// Get the diff to the previous version.
|
||||||
$version = new Versioned_Version($record);
|
$version = SiteTree::create($record);
|
||||||
if ($diff = $version->getDiff()) {
|
if ($diff = $version->getDiff()) {
|
||||||
$changeList->push($diff);
|
$changeList->push($diff);
|
||||||
}
|
}
|
||||||
|
@ -142,7 +147,8 @@ class VersionFeedController extends Extension {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Produce output
|
// Produce output
|
||||||
$rss = new RSSFeed($changeList, $this->owner->request->getURL(), $this->linkToAllSitesRSSFeedTitle(), '', 'Title', '', null);
|
$url = $this->owner->getRequest()->getURL();
|
||||||
|
$rss = new RSSFeed($changeList, $url, $this->linkToAllSitesRSSFeedTitle(), '', 'Title', '', null);
|
||||||
$rss->setTemplate('Page_allchanges_rss');
|
$rss->setTemplate('Page_allchanges_rss');
|
||||||
return $rss->outputToBrowser();
|
return $rss->outputToBrowser();
|
||||||
}
|
}
|
||||||
|
@ -150,7 +156,8 @@ class VersionFeedController extends Extension {
|
||||||
/**
|
/**
|
||||||
* Generates and embeds the RSS header link for the page-specific version rss feed
|
* Generates and embeds the RSS header link for the page-specific version rss feed
|
||||||
*/
|
*/
|
||||||
public function linkToPageRSSFeed() {
|
public function linkToPageRSSFeed()
|
||||||
|
{
|
||||||
if (!Config::inst()->get(VersionFeed::class, 'changes_enabled') || !$this->owner->PublicHistory) {
|
if (!Config::inst()->get(VersionFeed::class, 'changes_enabled') || !$this->owner->PublicHistory) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -167,7 +174,8 @@ class VersionFeedController extends Extension {
|
||||||
/**
|
/**
|
||||||
* Generates and embeds the RSS header link for the global version rss feed
|
* Generates and embeds the RSS header link for the global version rss feed
|
||||||
*/
|
*/
|
||||||
public function linkToAllSiteRSSFeed() {
|
public function linkToAllSiteRSSFeed()
|
||||||
|
{
|
||||||
if (!Config::inst()->get(VersionFeed::class, 'allchanges_enabled')
|
if (!Config::inst()->get(VersionFeed::class, 'allchanges_enabled')
|
||||||
|| !SiteConfig::current_site_config()->AllChangesEnabled
|
|| !SiteConfig::current_site_config()->AllChangesEnabled
|
||||||
) {
|
) {
|
||||||
|
@ -180,10 +188,12 @@ class VersionFeedController extends Extension {
|
||||||
|
|
||||||
Requirements::insertHeadTags(
|
Requirements::insertHeadTags(
|
||||||
'<link rel="alternate" type="application/rss+xml" title="' . $title .
|
'<link rel="alternate" type="application/rss+xml" title="' . $title .
|
||||||
'" href="' . $url . '" />');
|
'" href="' . $url . '" />'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function linkToAllSitesRSSFeedTitle() {
|
public function linkToAllSitesRSSFeedTitle()
|
||||||
|
{
|
||||||
return sprintf(_t('RSSHistory.SITEFEEDTITLE', 'Updates to %s'), SiteConfig::current_site_config()->Title);
|
return sprintf(_t('RSSHistory.SITEFEEDTITLE', 'Updates to %s'), SiteConfig::current_site_config()->Title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,6 @@
|
||||||
|
|
||||||
namespace SilverStripe\VersionFeed;
|
namespace SilverStripe\VersionFeed;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
use SilverStripe\Core\Config\Config;
|
use SilverStripe\Core\Config\Config;
|
||||||
use SilverStripe\VersionFeed\VersionFeed;
|
use SilverStripe\VersionFeed\VersionFeed;
|
||||||
|
@ -14,12 +9,11 @@ use SilverStripe\Forms\CheckboxField;
|
||||||
use SilverStripe\Forms\FieldGroup;
|
use SilverStripe\Forms\FieldGroup;
|
||||||
use SilverStripe\ORM\DataExtension;
|
use SilverStripe\ORM\DataExtension;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows global configuration of all changes
|
* Allows global configuration of all changes
|
||||||
*/
|
*/
|
||||||
class VersionFeedSiteConfig extends DataExtension {
|
class VersionFeedSiteConfig extends DataExtension
|
||||||
|
{
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'AllChangesEnabled' => 'Boolean(true)'
|
'AllChangesEnabled' => 'Boolean(true)'
|
||||||
|
@ -29,14 +23,19 @@ class VersionFeedSiteConfig extends DataExtension {
|
||||||
'AllChangesEnabled' => true
|
'AllChangesEnabled' => true
|
||||||
);
|
);
|
||||||
|
|
||||||
public function updateFieldLabels(&$labels) {
|
public function updateFieldLabels(&$labels)
|
||||||
|
{
|
||||||
$labels['AllChangesEnabled'] = _t('VersionFeedSiteConfig.ALLCHANGESLABEL', 'Make global changes feed public');
|
$labels['AllChangesEnabled'] = _t('VersionFeedSiteConfig.ALLCHANGESLABEL', 'Make global changes feed public');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateCMSFields(FieldList $fields) {
|
public function updateCMSFields(FieldList $fields)
|
||||||
if(!Config::inst()->get(VersionFeed::class, 'allchanges_enabled')) return;
|
{
|
||||||
|
if (!Config::inst()->get(VersionFeed::class, 'allchanges_enabled')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$fields->addFieldToTab('Root.Access',
|
$fields->addFieldToTab(
|
||||||
|
'Root.Access',
|
||||||
FieldGroup::create(new CheckboxField('AllChangesEnabled', $this->owner->fieldLabel('AllChangesEnabled')))
|
FieldGroup::create(new CheckboxField('AllChangesEnabled', $this->owner->fieldLabel('AllChangesEnabled')))
|
||||||
->setTitle(_t('VersionFeedSiteConfig.ALLCHANGES', 'All page changes'))
|
->setTitle(_t('VersionFeedSiteConfig.ALLCHANGES', 'All page changes'))
|
||||||
->setDescription(_t(
|
->setDescription(_t(
|
||||||
|
|
|
@ -17,8 +17,8 @@ use SilverStripe\Dev\FunctionalTest;
|
||||||
use SilverStripe\Control\Director;
|
use SilverStripe\Control\Director;
|
||||||
use Psr\SimpleCache\CacheInterface;
|
use Psr\SimpleCache\CacheInterface;
|
||||||
|
|
||||||
|
class VersionFeedFunctionalTest extends FunctionalTest
|
||||||
class VersionFeedFunctionalTest extends FunctionalTest {
|
{
|
||||||
protected $usesDatabase = true;
|
protected $usesDatabase = true;
|
||||||
|
|
||||||
protected $baseURI = 'http://www.fakesite.test';
|
protected $baseURI = 'http://www.fakesite.test';
|
||||||
|
@ -30,7 +30,8 @@ class VersionFeedFunctionalTest extends FunctionalTest {
|
||||||
|
|
||||||
protected $userIP;
|
protected $userIP;
|
||||||
|
|
||||||
protected function setUp() {
|
protected function setUp()
|
||||||
|
{
|
||||||
Director::config()->set('alternate_base_url', $this->baseURI);
|
Director::config()->set('alternate_base_url', $this->baseURI);
|
||||||
|
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
@ -54,7 +55,8 @@ class VersionFeedFunctionalTest extends FunctionalTest {
|
||||||
Config::modify()->set(RateLimitFilter::class, 'lock_cooldown', false);
|
Config::modify()->set(RateLimitFilter::class, 'lock_cooldown', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tearDown() {
|
public function tearDown()
|
||||||
|
{
|
||||||
Director::config()->set('alternate_base_url', null);
|
Director::config()->set('alternate_base_url', null);
|
||||||
|
|
||||||
$_SERVER['REMOTE_ADDR'] = $this->userIP;
|
$_SERVER['REMOTE_ADDR'] = $this->userIP;
|
||||||
|
@ -62,7 +64,8 @@ class VersionFeedFunctionalTest extends FunctionalTest {
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPublicHistory() {
|
public function testPublicHistory()
|
||||||
|
{
|
||||||
$page = $this->createPageWithChanges(array('PublicHistory' => false));
|
$page = $this->createPageWithChanges(array('PublicHistory' => false));
|
||||||
|
|
||||||
$response = $this->get($page->RelativeLink('changes'));
|
$response = $this->get($page->RelativeLink('changes'));
|
||||||
|
@ -86,7 +89,8 @@ class VersionFeedFunctionalTest extends FunctionalTest {
|
||||||
$this->assertTrue((bool)$xml->channel->item);
|
$this->assertTrue((bool)$xml->channel->item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRateLimiting() {
|
public function testRateLimiting()
|
||||||
|
{
|
||||||
// Re-enable locking just for this test
|
// Re-enable locking just for this test
|
||||||
Config::modify()->set(RateLimitFilter::class, 'lock_timeout', 20);
|
Config::modify()->set(RateLimitFilter::class, 'lock_timeout', 20);
|
||||||
Config::modify()->set(CachedContentFilter::class, 'cache_enabled', true);
|
Config::modify()->set(CachedContentFilter::class, 'cache_enabled', true);
|
||||||
|
@ -145,37 +149,46 @@ class VersionFeedFunctionalTest extends FunctionalTest {
|
||||||
Config::modify()->set(CachedContentFilter::class, 'cache_enabled', false);
|
Config::modify()->set(CachedContentFilter::class, 'cache_enabled', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testContainsChangesForPageOnly() {
|
public function testContainsChangesForPageOnly()
|
||||||
|
{
|
||||||
$page1 = $this->createPageWithChanges(array('Title' => 'Page1'));
|
$page1 = $this->createPageWithChanges(array('Title' => 'Page1'));
|
||||||
$page2 = $this->createPageWithChanges(array('Title' => 'Page2'));
|
$page2 = $this->createPageWithChanges(array('Title' => 'Page2'));
|
||||||
|
|
||||||
$response = $this->get($page1->RelativeLink('changes'));
|
$response = $this->get($page1->RelativeLink('changes'));
|
||||||
$xml = simplexml_load_string($response->getBody());
|
$xml = simplexml_load_string($response->getBody());
|
||||||
$titles = array_map(function($item) {return (string)$item->title;}, $xml->xpath('//item'));
|
$titles = array_map(function ($item) {
|
||||||
|
return (string)$item->title;
|
||||||
|
}, $xml->xpath('//item'));
|
||||||
// TODO Unclear if this should contain the original version
|
// TODO Unclear if this should contain the original version
|
||||||
$this->assertContains('Changed: Page1', $titles);
|
$this->assertContains('Changed: Page1', $titles);
|
||||||
$this->assertNotContains('Changed: Page2', $titles);
|
$this->assertNotContains('Changed: Page2', $titles);
|
||||||
|
|
||||||
$response = $this->get($page2->RelativeLink('changes'));
|
$response = $this->get($page2->RelativeLink('changes'));
|
||||||
$xml = simplexml_load_string($response->getBody());
|
$xml = simplexml_load_string($response->getBody());
|
||||||
$titles = array_map(function($item) {return (string)$item->title;}, $xml->xpath('//item'));
|
$titles = array_map(function ($item) {
|
||||||
|
return (string)$item->title;
|
||||||
|
}, $xml->xpath('//item'));
|
||||||
// TODO Unclear if this should contain the original version
|
// TODO Unclear if this should contain the original version
|
||||||
$this->assertNotContains('Changed: Page1', $titles);
|
$this->assertNotContains('Changed: Page1', $titles);
|
||||||
$this->assertContains('Changed: Page2', $titles);
|
$this->assertContains('Changed: Page2', $titles);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testContainsAllChangesForAllPages() {
|
public function testContainsAllChangesForAllPages()
|
||||||
|
{
|
||||||
$page1 = $this->createPageWithChanges(array('Title' => 'Page1'));
|
$page1 = $this->createPageWithChanges(array('Title' => 'Page1'));
|
||||||
$page2 = $this->createPageWithChanges(array('Title' => 'Page2'));
|
$page2 = $this->createPageWithChanges(array('Title' => 'Page2'));
|
||||||
|
|
||||||
$response = $this->get($page1->RelativeLink('allchanges'));
|
$response = $this->get($page1->RelativeLink('allchanges'));
|
||||||
$xml = simplexml_load_string($response->getBody());
|
$xml = simplexml_load_string($response->getBody());
|
||||||
$titles = array_map(function($item) {return (string)$item->title;}, $xml->xpath('//item'));
|
$titles = array_map(function ($item) {
|
||||||
|
return (string)$item->title;
|
||||||
|
}, $xml->xpath('//item'));
|
||||||
$this->assertContains('Page1', $titles);
|
$this->assertContains('Page1', $titles);
|
||||||
$this->assertContains('Page2', $titles);
|
$this->assertContains('Page2', $titles);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createPageWithChanges($seed = null) {
|
protected function createPageWithChanges($seed = null)
|
||||||
|
{
|
||||||
$page = new Page();
|
$page = new Page();
|
||||||
|
|
||||||
$seed = array_merge(array(
|
$seed = array_merge(array(
|
||||||
|
@ -212,7 +225,8 @@ class VersionFeedFunctionalTest extends FunctionalTest {
|
||||||
/**
|
/**
|
||||||
* Tests response code for globally disabled feedss
|
* Tests response code for globally disabled feedss
|
||||||
*/
|
*/
|
||||||
public function testFeedViewability() {
|
public function testFeedViewability()
|
||||||
|
{
|
||||||
|
|
||||||
// Nested loop through each configuration
|
// Nested loop through each configuration
|
||||||
foreach (array(true, false) as $publicHistory_Page) {
|
foreach (array(true, false) as $publicHistory_Page) {
|
||||||
|
@ -241,6 +255,4 @@ class VersionFeedFunctionalTest extends FunctionalTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace SilverStripe\VersionFeed\Tests;
|
namespace SilverStripe\VersionFeed\Tests;
|
||||||
|
|
||||||
|
|
||||||
use Page;
|
use Page;
|
||||||
use SilverStripe\VersionFeed\VersionFeed;
|
use SilverStripe\VersionFeed\VersionFeed;
|
||||||
use SilverStripe\VersionFeed\VersionFeedController;
|
use SilverStripe\VersionFeed\VersionFeedController;
|
||||||
|
@ -10,8 +9,8 @@ use SilverStripe\Dev\SapphireTest;
|
||||||
use SilverStripe\CMS\Model\SiteTree;
|
use SilverStripe\CMS\Model\SiteTree;
|
||||||
use SilverStripe\CMS\Controllers\ContentController;
|
use SilverStripe\CMS\Controllers\ContentController;
|
||||||
|
|
||||||
|
class VersionFeedTest extends SapphireTest
|
||||||
class VersionFeedTest extends SapphireTest {
|
{
|
||||||
|
|
||||||
protected $usesDatabase = true;
|
protected $usesDatabase = true;
|
||||||
|
|
||||||
|
@ -24,15 +23,18 @@ class VersionFeedTest extends SapphireTest {
|
||||||
'SiteTree' => ['Translatable']
|
'SiteTree' => ['Translatable']
|
||||||
];
|
];
|
||||||
|
|
||||||
public function testDiffedChangesExcludesRestrictedItems() {
|
public function testDiffedChangesExcludesRestrictedItems()
|
||||||
|
{
|
||||||
$this->markTestIncomplete();
|
$this->markTestIncomplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDiffedChangesIncludesFullHistory() {
|
public function testDiffedChangesIncludesFullHistory()
|
||||||
|
{
|
||||||
$this->markTestIncomplete();
|
$this->markTestIncomplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDiffedChangesTitle() {
|
public function testDiffedChangesTitle()
|
||||||
|
{
|
||||||
$page = new Page(['Title' => 'My Title']);
|
$page = new Page(['Title' => 'My Title']);
|
||||||
$page->write();
|
$page->write();
|
||||||
$page->publish('Stage', 'Live');
|
$page->publish('Stage', 'Live');
|
||||||
|
@ -61,5 +63,4 @@ class VersionFeedTest extends SapphireTest {
|
||||||
'Ignores unpublished title changes'
|
'Ignores unpublished title changes'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue