Merge pull request #991 from tractorcow/pulls/3.1-canview-orphaned

BUG Fix orphaned pages reporting they can be viewed
This commit is contained in:
Will Rossiter 2014-04-07 09:02:06 -07:00
commit f40de3b1a7
2 changed files with 77 additions and 0 deletions

View File

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

View File

@ -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);
}
}
/**#@+