diff --git a/code/controllers/CMSMain.php b/code/controllers/CMSMain.php
index 817bf398..a36008c9 100644
--- a/code/controllers/CMSMain.php
+++ b/code/controllers/CMSMain.php
@@ -1369,7 +1369,9 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
if(($id = $this->urlParams['ID']) && is_numeric($id)) {
$page = DataObject::get_by_id("SiteTree", $id);
- if($page && (!$page->canEdit() || !$page->canCreate())) return Security::permissionFailure($this);
+ if($page && (!$page->canEdit() || !$page->canCreate(null, array('Parent' => $page->Parent())))) {
+ return Security::permissionFailure($this);
+ }
if(!$page || !$page->ID) throw new SS_HTTPResponse_Exception("Bad record ID #$id", 404);
$newPage = $page->duplicate();
@@ -1405,7 +1407,9 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
increase_time_limit_to();
if(($id = $this->urlParams['ID']) && is_numeric($id)) {
$page = DataObject::get_by_id("SiteTree", $id);
- if($page && (!$page->canEdit() || !$page->canCreate())) return Security::permissionFailure($this);
+ if($page && (!$page->canEdit() || !$page->canCreate(null, array('Parent' => $page->Parent())))) {
+ return Security::permissionFailure($this);
+ }
if(!$page || !$page->ID) throw new SS_HTTPResponse_Exception("Bad record ID #$id", 404);
$newPage = $page->duplicateWithChildren();
diff --git a/code/model/RedirectorPage.php b/code/model/RedirectorPage.php
index c9ec3270..34c0a148 100644
--- a/code/model/RedirectorPage.php
+++ b/code/model/RedirectorPage.php
@@ -165,7 +165,8 @@ class RedirectorPage_Controller extends Page_Controller {
public function init() {
parent::init();
- if($link = $this->redirectionLink()) {
+ // Check we don't already have a redirect code set
+ if(!$this->getResponse()->isFinished() && $link = $this->redirectionLink()) {
$this->redirect($link, 301);
return;
}
diff --git a/code/reports/BrokenLinksReport.php b/code/reports/BrokenLinksReport.php
index 447c9abf..6dc1d2c0 100644
--- a/code/reports/BrokenLinksReport.php
+++ b/code/reports/BrokenLinksReport.php
@@ -80,7 +80,7 @@ class BrokenLinksReport extends SS_Report {
return $returnSet;
}
public function columns() {
- if(isset($_REQUEST['CheckSite']) && $_REQUEST['CheckSite'] == 'Draft') {
+ if(isset($_REQUEST['filters']['CheckSite']) && $_REQUEST['filters']['CheckSite'] == 'Draft') {
$dateTitle = _t('BrokenLinksReport.ColumnDateLastModified', 'Date last modified');
} else {
$dateTitle = _t('BrokenLinksReport.ColumnDateLastPublished', 'Date last published');
@@ -91,7 +91,7 @@ class BrokenLinksReport extends SS_Report {
"Title" => array(
"title" => _t('BrokenLinksReport.PageName', 'Page name'),
'formatting' => function($value, $item) use ($linkBase) {
- return sprintf('%s',
+ return sprintf('%s',
Controller::join_links($linkBase, $item->ID),
_t('BrokenLinksReport.HoverTitleEditPage', 'Edit page'),
$value
diff --git a/tests/behat/features/insert-an-image.feature b/tests/behat/features/insert-an-image.feature
index 146eace0..bc1883e9 100644
--- a/tests/behat/features/insert-an-image.feature
+++ b/tests/behat/features/insert-an-image.feature
@@ -17,12 +17,12 @@ Feature: Insert an image into a page
Then I should see "Choose files to upload..."
When I press the "From the web" button
- And I fill in "RemoteURL" with "http://www.silverstripe.com/themes/sscom/images/silverstripe_logo_web.png"
+ And I fill in "RemoteURL" with "http://www.silverstripe.org/themes/ssv3/img/ss_logo.png"
And I press the "Add url" button
- Then I should see "silverstripe_logo_web.png (www.silverstripe.com)" in the ".ss-assetuploadfield span.name" element
+ Then I should see "ss_logo.png (www.silverstripe.org)" in the ".ss-assetuploadfield span.name" element
When I press the "Insert" button
- Then the "Content" HTML field should contain "silverstripe_logo_web.png"
+ Then the "Content" HTML field should contain "ss_logo.png"
# Required to avoid "unsaved changed" browser dialog
Then I press the "Save draft" button
diff --git a/tests/model/RedirectorPageTest.php b/tests/model/RedirectorPageTest.php
index 5e036a16..6d4d29d7 100644
--- a/tests/model/RedirectorPageTest.php
+++ b/tests/model/RedirectorPageTest.php
@@ -3,6 +3,7 @@
class RedirectorPageTest extends FunctionalTest {
protected static $fixture_file = 'RedirectorPageTest.yml';
protected static $use_draft_site = true;
+ protected $autoFollowRedirection = false;
public function testGoodRedirectors() {
/* For good redirectors, the final destination URL will be returned */
@@ -64,4 +65,27 @@ class RedirectorPageTest extends FunctionalTest {
$protocolRelative->write();
$this->assertEquals('//mydomain.com', $protocolRelative->ExternalURL);
}
+
+ /**
+ * Test that we can trigger a redirection before RedirectorPage_Controller::init() is called
+ */
+ public function testRedirectRespectsFinishedResponse() {
+ $page = $this->objFromFixture('RedirectorPage', 'goodinternal');
+ RedirectorPage_Controller::add_extension('RedirectorPageTest_RedirectExtension');
+
+ $response = $this->get($page->regularLink());
+ $this->assertEquals(302, $response->getStatusCode());
+ $this->assertEquals('/foo', $response->getHeader('Location'));
+
+ RedirectorPage_Controller::remove_extension('RedirectorPageTest_RedirectExtension');
+ }
+
+}
+
+class RedirectorPageTest_RedirectExtension extends Extension implements TestOnly {
+
+ public function onBeforeInit() {
+ $this->owner->redirect('/foo');
+ }
+
}
diff --git a/tests/reports/CmsReportsTest.php b/tests/reports/CmsReportsTest.php
index 657fc274..25b14c83 100644
--- a/tests/reports/CmsReportsTest.php
+++ b/tests/reports/CmsReportsTest.php
@@ -24,6 +24,31 @@ class CmsReportsTest extends SapphireTest {
DB::query("UPDATE \"SiteTree\" SET \"Created\"='2009-01-01 00:00:00', \"LastEdited\"='".date('Y-m-d H:i:s', $beforeThreshold)."' WHERE \"ID\"='".$before->ID."'");
}
+ /**
+ * ASSERT whether a report is returning the correct results, based on a broken "draft" and/or "published" page.
+ *
+ * @parameter ss_report
+ * @parameter boolean
+ * @parameter boolean
+ */
+
+ public function isReportBroken($report, $isDraftBroken, $isPublishedBroken) {
+
+ $class = get_class($report);
+
+ // ASSERT that the "draft" report is returning the correct results.
+
+ $results = count($report->sourceRecords(array())) > 0;
+ $isDraftBroken ? $this->assertTrue($results, "{$class} has NOT returned the correct DRAFT results, as NO pages were found.") : $this->assertFalse($results, "{$class} has NOT returned the correct DRAFT results, as pages were found.");
+
+ // ASSERT that the "published" report is returning the correct results.
+
+ $results = count($report->sourceRecords(array(
+ 'OnLive' => 1
+ ))) > 0;
+ $isPublishedBroken ? $this->assertTrue($results, "{$class} has NOT returned the correct PUBLISHED results, as NO pages were found.") : $this->assertFalse($results, "{$class} has NOT returned the correct PUBLISHED results, as pages were found.");
+ }
+
public function testRecentlyEdited() {
SS_Datetime::set_mock_now('31-06-2009 00:00:00');
@@ -39,4 +64,265 @@ class CmsReportsTest extends SapphireTest {
SS_DateTime::clear_mock_now();
}
+
+ /**
+ * Test the broken links side report.
+ */
+
+ public function testBrokenLinks() {
+
+ // Create a "draft" page with a broken link.
+
+ $page = Page::create();
+ $page->Content = "This is a broken link.";
+ $page->writeToStage('Stage');
+
+ // Retrieve the broken links side report.
+
+ $reports = SS_Report::get_reports();
+ $brokenLinksReport = null;
+ foreach($reports as $report) {
+ if($report instanceof SideReport_BrokenLinks) {
+ $brokenLinksReport = $report;
+ break;
+ }
+ }
+
+ // Determine that the report exists, otherwise it has been excluded.
+
+ if($brokenLinksReport) {
+
+ // ASSERT that the "draft" report has detected the page having a broken link.
+ // ASSERT that the "published" report has NOT detected the page having a broken link, as the page has not been "published" yet.
+
+ $this->isReportBroken($brokenLinksReport, true, false);
+
+ // Make sure the page is now "published".
+
+ $page->writeToStage('Live');
+
+ // ASSERT that the "draft" report has detected the page having a broken link.
+ // ASSERT that the "published" report has detected the page having a broken link.
+
+ $this->isReportBroken($brokenLinksReport, true, true);
+
+ // Correct the "draft" broken link.
+
+ $page->Content = str_replace('987654321', $page->ID, $page->Content);
+ $page->writeToStage('Stage');
+
+ // ASSERT that the "draft" report has NOT detected the page having a broken link.
+ // ASSERT that the "published" report has detected the page having a broken link, as the previous content remains "published".
+
+ $this->isReportBroken($brokenLinksReport, false, true);
+
+ // Make sure the change has now been "published".
+
+ $page->writeToStage('Live');
+
+ // ASSERT that the "draft" report has NOT detected the page having a broken link.
+ // ASSERT that the "published" report has NOT detected the page having a broken link.
+
+ $this->isReportBroken($brokenLinksReport, false, false);
+ }
+ }
+
+ /**
+ * Test the broken files side report.
+ */
+
+ public function testBrokenFiles() {
+
+ // Create a "draft" page with a broken file.
+
+ $page = Page::create();
+ $page->Content = "This is a broken file.";
+ $page->writeToStage('Stage');
+
+ // Retrieve the broken files side report.
+
+ $reports = SS_Report::get_reports();
+ $brokenFilesReport = null;
+ foreach($reports as $report) {
+ if($report instanceof SideReport_BrokenFiles) {
+ $brokenFilesReport = $report;
+ break;
+ }
+ }
+
+ // Determine that the report exists, otherwise it has been excluded.
+
+ if($brokenFilesReport) {
+
+ // ASSERT that the "draft" report has detected the page having a broken file.
+ // ASSERT that the "published" report has NOT detected the page having a broken file, as the page has not been "published" yet.
+
+ $this->isReportBroken($brokenFilesReport, true, false);
+
+ // Make sure the page is now "published".
+
+ $page->writeToStage('Live');
+
+ // ASSERT that the "draft" report has detected the page having a broken file.
+ // ASSERT that the "published" report has detected the page having a broken file.
+
+ $this->isReportBroken($brokenFilesReport, true, true);
+
+ // Correct the "draft" broken file.
+
+ $file = File::create();
+ $file->Filename = 'name.pdf';
+ $file->write();
+ $page->Content = str_replace('987654321', $file->ID, $page->Content);
+ $page->writeToStage('Stage');
+
+ // ASSERT that the "draft" report has NOT detected the page having a broken file.
+ // ASSERT that the "published" report has detected the page having a broken file, as the previous content remains "published".
+
+ $this->isReportBroken($brokenFilesReport, false, true);
+
+ // Make sure the change has now been "published".
+
+ $page->writeToStage('Live');
+
+ // ASSERT that the "draft" report has NOT detected the page having a broken file.
+ // ASSERT that the "published" report has NOT detected the page having a broken file.
+
+ $this->isReportBroken($brokenFilesReport, false, false);
+ }
+ }
+
+ /**
+ * Test the broken virtual pages side report.
+ */
+
+ public function testBrokenVirtualPages() {
+
+ // Create a "draft" virtual page with a broken link.
+
+ $page = VirtualPage::create();
+ $page->CopyContentFromID = 987654321;
+ $page->writeToStage('Stage');
+
+ // Retrieve the broken virtual pages side report.
+
+ $reports = SS_Report::get_reports();
+ $brokenVirtualPagesReport = null;
+ foreach($reports as $report) {
+ if($report instanceof SideReport_BrokenVirtualPages) {
+ $brokenVirtualPagesReport = $report;
+ break;
+ }
+ }
+
+ // Determine that the report exists, otherwise it has been excluded.
+
+ if($brokenVirtualPagesReport) {
+
+ // ASSERT that the "draft" report has detected the page having a broken link.
+ // ASSERT that the "published" report has NOT detected the page having a broken link, as the page has not been "published" yet.
+
+ $this->isReportBroken($brokenVirtualPagesReport, true, false);
+
+ // Make sure the page is now "published".
+
+ $page->writeToStage('Live');
+
+ // ASSERT that the "draft" report has detected the page having a broken link.
+ // ASSERT that the "published" report has detected the page having a broken link.
+
+ $this->isReportBroken($brokenVirtualPagesReport, true, true);
+
+ // Correct the "draft" broken link.
+
+ $contentPage = Page::create();
+ $contentPage->Content = 'This is some content.';
+ $contentPage->writeToStage('Stage');
+ $contentPage->writeToStage('Live');
+ $page->CopyContentFromID = $contentPage->ID;
+ $page->writeToStage('Stage');
+
+ // ASSERT that the "draft" report has NOT detected the page having a broken link.
+ // ASSERT that the "published" report has detected the page having a broken link, as the previous content remains "published".
+
+ $this->isReportBroken($brokenVirtualPagesReport, false, true);
+
+ // Make sure the change has now been "published".
+
+ $page->writeToStage('Live');
+
+ // ASSERT that the "draft" report has NOT detected the page having a broken link.
+ // ASSERT that the "published" report has NOT detected the page having a broken link.
+
+ $this->isReportBroken($brokenVirtualPagesReport, false, false);
+ }
+ }
+
+ /**
+ * Test the broken redirector pages side report.
+ */
+
+ public function testBrokenRedirectorPages() {
+
+ // Create a "draft" redirector page with a broken link.
+
+ $page = RedirectorPage::create();
+ $page->RedirectionType = 'Internal';
+ $page->LinkToID = 987654321;
+ $page->writeToStage('Stage');
+
+ // Retrieve the broken redirector pages side report.
+
+ $reports = SS_Report::get_reports();
+ $brokenRedirectorPagesReport = null;
+ foreach($reports as $report) {
+ if($report instanceof SideReport_BrokenRedirectorPages) {
+ $brokenRedirectorPagesReport = $report;
+ break;
+ }
+ }
+
+ // Determine that the report exists, otherwise it has been excluded.
+
+ if($brokenRedirectorPagesReport) {
+
+ // ASSERT that the "draft" report has detected the page having a broken link.
+ // ASSERT that the "published" report has NOT detected the page having a broken link, as the page has not been "published" yet.
+
+ $this->isReportBroken($brokenRedirectorPagesReport, true, false);
+
+ // Make sure the page is now "published".
+
+ $page->writeToStage('Live');
+
+ // ASSERT that the "draft" report has detected the page having a broken link.
+ // ASSERT that the "published" report has detected the page having a broken link.
+
+ $this->isReportBroken($brokenRedirectorPagesReport, true, true);
+
+ // Correct the "draft" broken link.
+
+ $contentPage = Page::create();
+ $contentPage->Content = 'This is some content.';
+ $contentPage->writeToStage('Stage');
+ $contentPage->writeToStage('Live');
+ $page->LinkToID = $contentPage->ID;
+ $page->writeToStage('Stage');
+
+ // ASSERT that the "draft" report has NOT detected the page having a broken link.
+ // ASSERT that the "published" report has detected the page having a broken link, as the previous content remains "published".
+
+ $this->isReportBroken($brokenRedirectorPagesReport, false, true);
+
+ // Make sure the change has now been "published".
+
+ $page->writeToStage('Live');
+
+ // ASSERT that the "draft" report has NOT detected the page having a broken link.
+ // ASSERT that the "published" report has NOT detected the page having a broken link.
+
+ $this->isReportBroken($brokenRedirectorPagesReport, false, false);
+ }
+ }
+
}