From b4a1aa4537fc1a771c590fc552b5ddc635138e4f Mon Sep 17 00:00:00 2001 From: Russell Michell Date: Wed, 12 Mar 2014 09:42:10 +1300 Subject: [PATCH 1/2] FIX Fixes #965. Allow user date-settings to show on GridField Page admin - Relies on framework PR #2961. --- code/controllers/CMSMain.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/CMSMain.php b/code/controllers/CMSMain.php index 913e7247..170f2398 100644 --- a/code/controllers/CMSMain.php +++ b/code/controllers/CMSMain.php @@ -754,7 +754,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr $columns->setDisplayFields($fields); $columns->setFieldCasting(array( 'Created' => 'Datetime->Ago', - 'LastEdited' => 'Datetime->Ago', + 'LastEdited' => 'Datetime->FormatFromSettings', 'getTreeTitle' => 'HTMLText' )); From 3204ab5af35796ef5aa28331b821bea1549a4c2d Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Mon, 7 Apr 2014 12:21:57 +1200 Subject: [PATCH 2/2] BUG Fix orphaned pages reporting they can be viewed --- code/model/SiteTree.php | 19 ++++++++++++ tests/model/SiteTreeTest.php | 58 ++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/code/model/SiteTree.php b/code/model/SiteTree.php index f539ac94..25a97baa 100644 --- a/code/model/SiteTree.php +++ b/code/model/SiteTree.php @@ -586,6 +586,22 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid ); } + /** + * Check if the parent of this page has been removed (or made otherwise unavailable), and + * is still referenced by this child. Any such orphaned page may still require access via + * the cms, but should not be shown as accessible to external users. + * + * @return bool + */ + public function isOrphaned() { + // Always false for root pages + if(empty($this->ParentID)) return false; + + // Parent must exist and not be an orphan itself + $parent = $this->Parent(); + return !$parent || !$parent->exists() || $parent->isOrphaned(); + } + /** * Return "link" or "current" depending on if this is the {@link SiteTree::isCurrent()} current page. * @@ -885,6 +901,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid // check to make sure this version is the live version and so can be viewed if (Versioned::get_versionnumber_by_stage($this->class, 'Live', $this->ID) != $this->Version) return false; } + + // Orphaned pages (in the current stage) are unavailable, except for admins via the CMS + if($this->isOrphaned()) return false; // Standard mechanism for accepting permission changes from extensions $extended = $this->extendedCan('canView', $member); diff --git a/tests/model/SiteTreeTest.php b/tests/model/SiteTreeTest.php index 4736fd5a..e4e8d4ce 100644 --- a/tests/model/SiteTreeTest.php +++ b/tests/model/SiteTreeTest.php @@ -944,6 +944,64 @@ class SiteTreeTest extends SapphireTest { Config::inst()->update('SiteTree', 'meta_generator', $generator); } + /** + * Test that orphaned pages are handled correctly + */ + public function testOrphanedPages() { + $origStage = Versioned::get_reading_mode(); + + // Setup user who can view draft content, but lacks cms permission. + // To users such as this, orphaned pages should be inaccessible. canView for these pages is only + // necessary for admin / cms users, who require this permission to edit / rearrange these pages. + $permission = new Permission(); + $permission->Code = 'VIEW_DRAFT_CONTENT'; + $group = new Group(array('Title' => 'Staging Users')); + $group->write(); + $group->Permissions()->add($permission); + $member = new Member(); + $member->Email = 'someguy@example.com'; + $member->write(); + $member->Groups()->add($group); + + // both pages are viewable in stage + Versioned::reading_stage('Stage'); + $about = $this->objFromFixture('Page', 'about'); + $staff = $this->objFromFixture('Page', 'staff'); + $this->assertFalse($about->isOrphaned()); + $this->assertFalse($staff->isOrphaned()); + $this->assertTrue($about->canView($member)); + $this->assertTrue($staff->canView($member)); + + // Publishing only the child page to live should orphan the live record, but not the staging one + $staff->publish('Stage', 'Live'); + $this->assertFalse($staff->isOrphaned()); + $this->assertTrue($staff->canView($member)); + Versioned::reading_stage('Live'); + $staff = $this->objFromFixture('Page', 'staff'); // Live copy of page + $this->assertTrue($staff->isOrphaned()); // because parent isn't published + $this->assertFalse($staff->canView($member)); + + // Publishing the parent page should restore visibility + Versioned::reading_stage('Stage'); + $about = $this->objFromFixture('Page', 'about'); + $about->publish('Stage', 'Live'); + Versioned::reading_stage('Live'); + $staff = $this->objFromFixture('Page', 'staff'); + $this->assertFalse($staff->isOrphaned()); + $this->assertTrue($staff->canView($member)); + + // Removing staging page should not prevent live page being visible + $about->deleteFromStage('Stage'); + $staff->deleteFromStage('Stage'); + $staff = $this->objFromFixture('Page', 'staff'); + $this->assertFalse($staff->isOrphaned()); + $this->assertTrue($staff->canView($member)); + + // Cleanup + Versioned::set_reading_mode($origStage); + + } + } /**#@+