mirror of
https://github.com/silverstripe/silverstripe-cms
synced 2024-10-22 08:05:56 +02:00
ENHANCEMENT Backport versioned querystring fix (#2153)
* Backport versioned querystring fix * Fix versioned state reset * Fix up tests * Fix permissions test * Linting
This commit is contained in:
parent
7cc4ce7895
commit
dfdaac48ca
@ -188,7 +188,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
|||||||
'/', // trailing slash needed if $action is null!
|
'/', // trailing slash needed if $action is null!
|
||||||
"$action"
|
"$action"
|
||||||
);
|
);
|
||||||
$this->extend('updateLink', $link);
|
$this->extend('updateLink', $link, $action);
|
||||||
return $link;
|
return $link;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,7 +465,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function Link($action = null) {
|
public function Link($action = null) {
|
||||||
return Controller::join_links(Director::baseURL(), $this->RelativeLink($action));
|
$relativeLink = $this->RelativeLink($action);
|
||||||
|
$link = Controller::join_links(Director::baseURL(), $relativeLink);
|
||||||
|
$this->extend('updateLink', $link, $action, $relativeLink);
|
||||||
|
return $link;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -542,7 +545,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getAbsoluteLiveLink($includeStageEqualsLive = true) {
|
public function getAbsoluteLiveLink($includeStageEqualsLive = true) {
|
||||||
$oldStage = Versioned::current_stage();
|
$oldMode = Versioned::get_reading_mode();
|
||||||
Versioned::reading_stage('Live');
|
Versioned::reading_stage('Live');
|
||||||
$live = Versioned::get_one_by_stage('SiteTree', 'Live', array(
|
$live = Versioned::get_one_by_stage('SiteTree', 'Live', array(
|
||||||
'"SiteTree"."ID"' => $this->ID
|
'"SiteTree"."ID"' => $this->ID
|
||||||
@ -556,7 +559,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
$link = null;
|
$link = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Versioned::reading_stage($oldStage);
|
Versioned::set_reading_mode($oldMode);
|
||||||
return $link;
|
return $link;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2429,7 +2432,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
|
|
||||||
$this->invokeWithExtensions('onBeforeUnpublish', $this);
|
$this->invokeWithExtensions('onBeforeUnpublish', $this);
|
||||||
|
|
||||||
$origStage = Versioned::current_stage();
|
$origMode = Versioned::get_reading_mode();
|
||||||
Versioned::reading_stage('Live');
|
Versioned::reading_stage('Live');
|
||||||
|
|
||||||
// We should only unpublish virtualpages that exist on live
|
// We should only unpublish virtualpages that exist on live
|
||||||
@ -2445,7 +2448,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
// $page->write() calls syncLinkTracking, which does all the hard work for us.
|
// $page->write() calls syncLinkTracking, which does all the hard work for us.
|
||||||
$page->write();
|
$page->write();
|
||||||
}
|
}
|
||||||
Versioned::reading_stage($origStage);
|
Versioned::set_reading_mode($origMode);
|
||||||
|
|
||||||
// Unpublish any published virtual pages
|
// Unpublish any published virtual pages
|
||||||
if ($virtualPages) foreach($virtualPages as $vp) $vp->doUnpublish();
|
if ($virtualPages) foreach($virtualPages as $vp) $vp->doUnpublish();
|
||||||
@ -2521,7 +2524,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
if(method_exists($conn, 'allowPrimaryKeyEditing')) $conn->allowPrimaryKeyEditing('SiteTree', false);
|
if(method_exists($conn, 'allowPrimaryKeyEditing')) $conn->allowPrimaryKeyEditing('SiteTree', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
$oldStage = Versioned::current_stage();
|
$oldMode = Versioned::get_reading_mode();
|
||||||
Versioned::reading_stage('Stage');
|
Versioned::reading_stage('Stage');
|
||||||
$this->forceChange();
|
$this->forceChange();
|
||||||
$this->write();
|
$this->write();
|
||||||
@ -2534,7 +2537,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
$page->write();
|
$page->write();
|
||||||
}
|
}
|
||||||
|
|
||||||
Versioned::reading_stage($oldStage);
|
Versioned::set_reading_mode($oldMode);
|
||||||
|
|
||||||
$this->invokeWithExtensions('onAfterRestoreToStage', $this);
|
$this->invokeWithExtensions('onAfterRestoreToStage', $this);
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ class SiteTreeFileExtension extends DataExtension {
|
|||||||
SiteTreeFileExtension::BackLinkTracking() have been deprecated.
|
SiteTreeFileExtension::BackLinkTracking() have been deprecated.
|
||||||
Please manipluate the returned list directly.', Deprecation::SCOPE_GLOBAL);
|
Please manipluate the returned list directly.', Deprecation::SCOPE_GLOBAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(class_exists("Subsite")){
|
if(class_exists("Subsite")){
|
||||||
$rememberSubsiteFilter = Subsite::$disable_subsite_filter;
|
$rememberSubsiteFilter = Subsite::$disable_subsite_filter;
|
||||||
Subsite::disable_subsite_filter(true);
|
Subsite::disable_subsite_filter(true);
|
||||||
@ -71,7 +71,7 @@ class SiteTreeFileExtension extends DataExtension {
|
|||||||
SiteTreeFileExtension::BackLinkTracking() have been deprecated.
|
SiteTreeFileExtension::BackLinkTracking() have been deprecated.
|
||||||
Please manipluate the returned list directly.', Deprecation::SCOPE_GLOBAL);
|
Please manipluate the returned list directly.', Deprecation::SCOPE_GLOBAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
$links = $this->owner->getManyManyComponents('BackLinkTracking');
|
$links = $this->owner->getManyManyComponents('BackLinkTracking');
|
||||||
if($this->owner->ID) {
|
if($this->owner->ID) {
|
||||||
$links = $links
|
$links = $links
|
||||||
@ -80,14 +80,14 @@ class SiteTreeFileExtension extends DataExtension {
|
|||||||
->limit($limit);
|
->limit($limit);
|
||||||
}
|
}
|
||||||
$this->owner->extend('updateBackLinkTracking', $links);
|
$this->owner->extend('updateBackLinkTracking', $links);
|
||||||
|
|
||||||
if(class_exists("Subsite")){
|
if(class_exists("Subsite")){
|
||||||
Subsite::disable_subsite_filter($rememberSubsiteFilter);
|
Subsite::disable_subsite_filter($rememberSubsiteFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $links;
|
return $links;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @todo Unnecessary shortcut for AssetTableField, coupled with cms module.
|
* @todo Unnecessary shortcut for AssetTableField, coupled with cms module.
|
||||||
*
|
*
|
||||||
@ -101,7 +101,7 @@ class SiteTreeFileExtension extends DataExtension {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates link tracking.
|
* Updates link tracking.
|
||||||
*/
|
*/
|
||||||
@ -110,7 +110,7 @@ class SiteTreeFileExtension extends DataExtension {
|
|||||||
// site does its thing
|
// site does its thing
|
||||||
$brokenPageIDs = $this->owner->BackLinkTracking()->column("ID");
|
$brokenPageIDs = $this->owner->BackLinkTracking()->column("ID");
|
||||||
if($brokenPageIDs) {
|
if($brokenPageIDs) {
|
||||||
$origStage = Versioned::current_stage();
|
$origMode = Versioned::get_reading_mode();
|
||||||
|
|
||||||
// This will syncLinkTracking on draft
|
// This will syncLinkTracking on draft
|
||||||
Versioned::reading_stage('Stage');
|
Versioned::reading_stage('Stage');
|
||||||
@ -124,10 +124,10 @@ class SiteTreeFileExtension extends DataExtension {
|
|||||||
$brokenPage->write();
|
$brokenPage->write();
|
||||||
}
|
}
|
||||||
|
|
||||||
Versioned::reading_stage($origStage);
|
Versioned::set_reading_mode($origMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rewrite links to the $old file to now point to the $new file.
|
* Rewrite links to the $old file to now point to the $new file.
|
||||||
*
|
*
|
||||||
@ -138,15 +138,15 @@ class SiteTreeFileExtension extends DataExtension {
|
|||||||
*/
|
*/
|
||||||
public function updateLinks($old, $new) {
|
public function updateLinks($old, $new) {
|
||||||
if(class_exists('Subsite')) Subsite::disable_subsite_filter(true);
|
if(class_exists('Subsite')) Subsite::disable_subsite_filter(true);
|
||||||
|
|
||||||
$pages = $this->owner->BackLinkTracking();
|
$pages = $this->owner->BackLinkTracking();
|
||||||
|
|
||||||
$summary = "";
|
$summary = "";
|
||||||
if($pages) {
|
if($pages) {
|
||||||
foreach($pages as $page) $page->rewriteFileURL($old,$new);
|
foreach($pages as $page) $page->rewriteFileURL($old,$new);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(class_exists('Subsite')) Subsite::disable_subsite_filter(false);
|
if(class_exists('Subsite')) Subsite::disable_subsite_filter(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,16 +7,21 @@ class ContentControllerTest extends FunctionalTest {
|
|||||||
|
|
||||||
protected static $fixture_file = 'ContentControllerTest.yml';
|
protected static $fixture_file = 'ContentControllerTest.yml';
|
||||||
|
|
||||||
protected static $use_draft_site = true;
|
|
||||||
|
|
||||||
protected static $disable_themes = true;
|
protected static $disable_themes = true;
|
||||||
|
|
||||||
|
public function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
Config::inst()->update('Director', 'alternate_base_url', '/');
|
||||||
|
$this->useDraftSite(false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that nested pages, basic actions, and nested/non-nested URL switching works properly
|
* Test that nested pages, basic actions, and nested/non-nested URL switching works properly
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public function testNestedPages() {
|
public function testNestedPages() {
|
||||||
RootURLController::reset();
|
RootURLController::reset();
|
||||||
|
$this->useDraftSite(true);
|
||||||
Config::inst()->update('SiteTree', 'nested_urls', true);
|
Config::inst()->update('SiteTree', 'nested_urls', true);
|
||||||
|
|
||||||
$this->assertEquals('Home Page', $this->get('/')->getBody());
|
$this->assertEquals('Home Page', $this->get('/')->getBody());
|
||||||
@ -52,7 +57,7 @@ class ContentControllerTest extends FunctionalTest {
|
|||||||
*/
|
*/
|
||||||
public function testChildrenOf() {
|
public function testChildrenOf() {
|
||||||
$controller = new ContentController();
|
$controller = new ContentController();
|
||||||
|
$this->useDraftSite(true);
|
||||||
Config::inst()->update('SiteTree', 'nested_urls', true);
|
Config::inst()->update('SiteTree', 'nested_urls', true);
|
||||||
|
|
||||||
$this->assertEquals(1, $controller->ChildrenOf('/')->Count());
|
$this->assertEquals(1, $controller->ChildrenOf('/')->Count());
|
||||||
@ -70,6 +75,7 @@ class ContentControllerTest extends FunctionalTest {
|
|||||||
|
|
||||||
public function testDeepNestedURLs() {
|
public function testDeepNestedURLs() {
|
||||||
Config::inst()->update('SiteTree', 'nested_urls', true);
|
Config::inst()->update('SiteTree', 'nested_urls', true);
|
||||||
|
$this->useDraftSite(true);
|
||||||
|
|
||||||
$page = new Page();
|
$page = new Page();
|
||||||
$page->URLSegment = 'base-page';
|
$page->URLSegment = 'base-page';
|
||||||
@ -126,7 +132,7 @@ class ContentControllerTest extends FunctionalTest {
|
|||||||
|
|
||||||
$this->assertContains(
|
$this->assertContains(
|
||||||
sprintf('<a href="%s">Testlink</a>', $linkedPage->Link()),
|
sprintf('<a href="%s">Testlink</a>', $linkedPage->Link()),
|
||||||
$this->get($page->RelativeLink())->getBody(),
|
$this->get($page->Link())->getBody(),
|
||||||
'"sitetree_link" shortcodes get parsed properly'
|
'"sitetree_link" shortcodes get parsed properly'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,47 +2,58 @@
|
|||||||
|
|
||||||
class RedirectorPageTest extends FunctionalTest {
|
class RedirectorPageTest extends FunctionalTest {
|
||||||
protected static $fixture_file = 'RedirectorPageTest.yml';
|
protected static $fixture_file = 'RedirectorPageTest.yml';
|
||||||
protected static $use_draft_site = true;
|
|
||||||
protected $autoFollowRedirection = false;
|
protected $autoFollowRedirection = false;
|
||||||
|
|
||||||
|
public function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
$this->useDraftSite(false);
|
||||||
|
$this->logInWithPermission('ADMIN');
|
||||||
|
foreach (SiteTree::get() as $page) {
|
||||||
|
$page->doPublish();
|
||||||
|
}
|
||||||
|
Config::inst()->update('Director', 'alternate_base_url', '/');
|
||||||
|
}
|
||||||
|
|
||||||
public function testGoodRedirectors() {
|
public function testGoodRedirectors() {
|
||||||
/* For good redirectors, the final destination URL will be returned */
|
/* For good redirectors, the final destination URL will be returned */
|
||||||
$this->assertEquals("http://www.google.com", $this->objFromFixture('RedirectorPage','goodexternal')->Link());
|
$this->assertEquals("http://www.google.com", $this->objFromFixture('RedirectorPage','goodexternal')->Link());
|
||||||
$this->assertEquals(Director::baseURL() . "redirection-dest/", $this->objFromFixture('RedirectorPage','goodinternal')->redirectionLink());
|
$this->assertEquals("/redirection-dest/", $this->objFromFixture('RedirectorPage','goodinternal')->redirectionLink());
|
||||||
$this->assertEquals(Director::baseURL() . "redirection-dest/", $this->objFromFixture('RedirectorPage','goodinternal')->Link());
|
$this->assertEquals("/redirection-dest/", $this->objFromFixture('RedirectorPage','goodinternal')->Link());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testEmptyRedirectors() {
|
public function testEmptyRedirectors() {
|
||||||
/* If a redirector page is misconfigured, then its link method will just return the usual URLSegment-generated value */
|
/* If a redirector page is misconfigured, then its link method will just return the usual URLSegment-generated value */
|
||||||
$page1 = $this->objFromFixture('RedirectorPage','badexternal');
|
$page1 = $this->objFromFixture('RedirectorPage','badexternal');
|
||||||
$this->assertEquals(Director::baseURL() . 'bad-external/', $page1->Link());
|
$this->assertEquals('/bad-external/', $page1->Link());
|
||||||
|
|
||||||
/* An error message will be shown if you visit it */
|
/* An error message will be shown if you visit it */
|
||||||
$content = $this->get(Director::makeRelative($page1->Link()))->getBody();
|
$content = $this->get($page1->Link())->getBody();
|
||||||
$this->assertContains('message-setupWithoutRedirect', $content);
|
$this->assertContains('message-setupWithoutRedirect', $content);
|
||||||
|
|
||||||
/* This also applies for internal links */
|
/* This also applies for internal links */
|
||||||
$page2 = $this->objFromFixture('RedirectorPage','badinternal');
|
$page2 = $this->objFromFixture('RedirectorPage','badinternal');
|
||||||
$this->assertEquals(Director::baseURL() . 'bad-internal/', $page2->Link());
|
$this->assertEquals('/bad-internal/', $page2->Link());
|
||||||
$content = $this->get(Director::makeRelative($page2->Link()))->getBody();
|
$content = $this->get($page2->Link())->getBody();
|
||||||
$this->assertContains('message-setupWithoutRedirect', $content);
|
$this->assertContains('message-setupWithoutRedirect', $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testReflexiveAndTransitiveInternalRedirectors() {
|
public function testReflexiveAndTransitiveInternalRedirectors() {
|
||||||
/* Reflexive redirectors are those that point to themselves. They should behave the same as an empty redirector */
|
/* Reflexive redirectors are those that point to themselves. They should behave the same as an empty redirector */
|
||||||
|
/** @var RedirectorPage $page */
|
||||||
$page = $this->objFromFixture('RedirectorPage','reflexive');
|
$page = $this->objFromFixture('RedirectorPage','reflexive');
|
||||||
$this->assertEquals(Director::baseURL() . 'reflexive/', $page->Link());
|
$this->assertEquals('/reflexive/', $page->Link());
|
||||||
$content = $this->get(Director::makeRelative($page->Link()))->getBody();
|
$content = $this->get($page->Link())->getBody();
|
||||||
$this->assertContains('message-setupWithoutRedirect', $content);
|
$this->assertContains('message-setupWithoutRedirect', $content);
|
||||||
|
|
||||||
/* Transitive redirectors are those that point to another redirector page. They should send people to the URLSegment
|
/* Transitive redirectors are those that point to another redirector page. They should send people to the URLSegment
|
||||||
* of the destination page - the middle-stop, so to speak. That should redirect to the final destination */
|
* of the destination page - the middle-stop, so to speak. That should redirect to the final destination */
|
||||||
$page = $this->objFromFixture('RedirectorPage','transitive');
|
$page = $this->objFromFixture('RedirectorPage', 'transitive');
|
||||||
$this->assertEquals(Director::baseURL() . 'good-internal/', $page->Link());
|
$this->assertEquals('/good-internal/', $page->Link());
|
||||||
|
|
||||||
$this->autoFollowRedirection = false;
|
$this->autoFollowRedirection = false;
|
||||||
$response = $this->get(Director::makeRelative($page->Link()));
|
$response = $this->get($page->Link());
|
||||||
$this->assertEquals(Director::baseURL() . "redirection-dest/", $response->getHeader("Location"));
|
$this->assertEquals("/redirection-dest/", $response->getHeader("Location"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testExternalURLGetsPrefixIfNotSet() {
|
public function testExternalURLGetsPrefixIfNotSet() {
|
||||||
|
@ -8,61 +8,64 @@
|
|||||||
*/
|
*/
|
||||||
class SiteTreePermissionsTest extends FunctionalTest {
|
class SiteTreePermissionsTest extends FunctionalTest {
|
||||||
protected static $fixture_file = "SiteTreePermissionsTest.yml";
|
protected static $fixture_file = "SiteTreePermissionsTest.yml";
|
||||||
|
|
||||||
protected $illegalExtensions = array(
|
protected $illegalExtensions = array(
|
||||||
'SiteTree' => array('SiteTreeSubsites')
|
'SiteTree' => array('SiteTreeSubsites')
|
||||||
);
|
);
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->useDraftSite();
|
$this->useDraftSite();
|
||||||
|
|
||||||
// we're testing HTTP status codes before being redirected to login forms
|
// we're testing HTTP status codes before being redirected to login forms
|
||||||
$this->autoFollowRedirection = false;
|
$this->autoFollowRedirection = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function testAccessingStageWithBlankStage() {
|
public function testAccessingStageWithBlankStage() {
|
||||||
$this->useDraftSite(false);
|
$this->useDraftSite(false);
|
||||||
$this->autoFollowRedirection = false;
|
$this->autoFollowRedirection = false;
|
||||||
|
|
||||||
$page = $this->objFromFixture('Page', 'draftOnlyPage');
|
$page = $this->objFromFixture('Page', 'draftOnlyPage');
|
||||||
|
|
||||||
if($member = Member::currentUser()) {
|
if($member = Member::currentUser()) {
|
||||||
$member->logOut();
|
$member->logOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $this->get($page->URLSegment . '?stage=Live');
|
$response = $this->get($page->URLSegment . '?stage=Live');
|
||||||
$this->assertEquals($response->getStatusCode(), '404');
|
$this->assertEquals(404, $response->getStatusCode());
|
||||||
|
|
||||||
$response = $this->get($page->URLSegment . '?stage=');
|
$response = $this->get($page->URLSegment . '?stage=');
|
||||||
$this->assertEquals($response->getStatusCode(), '404');
|
$this->assertEquals(404, $response->getStatusCode());
|
||||||
|
|
||||||
// should be prompted for a login
|
// should be prompted for a login
|
||||||
try {
|
try {
|
||||||
$response = $this->get($page->URLSegment . '?stage=Stage');
|
$response = $this->get($page->URLSegment . '?stage=Stage');
|
||||||
} catch(SS_HTTPResponse_Exception $responseException) {
|
} catch(SS_HTTPResponse_Exception $responseException) {
|
||||||
$response = $responseException->getResponse();
|
$response = $responseException->getResponse();
|
||||||
}
|
}
|
||||||
$this->assertEquals($response->getStatusCode(), '302');
|
$this->assertEquals(302, $response->getStatusCode());
|
||||||
$this->assertContains(
|
$this->assertContains(
|
||||||
Config::inst()->get('Security', 'login_url'),
|
Config::inst()->get('Security', 'login_url'),
|
||||||
$response->getHeader('Location')
|
$response->getHeader('Location')
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->logInWithPermission('ADMIN');
|
$this->logInWithPermission('ADMIN');
|
||||||
|
|
||||||
$response = $this->get($page->URLSegment . '?stage=Live');
|
$response = $this->get($page->URLSegment . '?stage=Live');
|
||||||
$this->assertEquals($response->getStatusCode(), '404');
|
$this->assertEquals(404, $response->getStatusCode());
|
||||||
|
|
||||||
$response = $this->get($page->URLSegment . '?stage=Stage');
|
|
||||||
$this->assertEquals($response->getStatusCode(), '200');
|
|
||||||
|
|
||||||
$response = $this->get($page->URLSegment . '?stage=');
|
$response = $this->get($page->URLSegment . '?stage=');
|
||||||
$this->assertEquals($response->getStatusCode(), '404');
|
$this->assertEquals(404, $response->getStatusCode());
|
||||||
|
|
||||||
|
$response = $this->get($page->URLSegment . '?stage=Stage');
|
||||||
|
$this->assertEquals(200, $response->getStatusCode());
|
||||||
|
|
||||||
|
$response = $this->get($page->URLSegment . '?stage=');
|
||||||
|
$this->assertEquals(200, $response->getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPermissionCheckingWorksOnDeletedPages() {
|
public function testPermissionCheckingWorksOnDeletedPages() {
|
||||||
// Set up fixture - a published page deleted from draft
|
// Set up fixture - a published page deleted from draft
|
||||||
$this->logInWithPermission("ADMIN");
|
$this->logInWithPermission("ADMIN");
|
||||||
@ -77,18 +80,18 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
// subadmin has edit rights on that page
|
// subadmin has edit rights on that page
|
||||||
$member = $this->objFromFixture('Member','subadmin');
|
$member = $this->objFromFixture('Member','subadmin');
|
||||||
$member->logIn();
|
$member->logIn();
|
||||||
|
|
||||||
// Test can_edit_multiple
|
// Test can_edit_multiple
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
array($pageID => true),
|
array($pageID => true),
|
||||||
SiteTree::can_edit_multiple(array($pageID), $member->ID)
|
SiteTree::can_edit_multiple(array($pageID), $member->ID)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Test canEdit
|
// Test canEdit
|
||||||
$member->logIn();
|
$member->logIn();
|
||||||
$this->assertTrue($page->canEdit());
|
$this->assertTrue($page->canEdit());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPermissionCheckingWorksOnUnpublishedPages() {
|
public function testPermissionCheckingWorksOnUnpublishedPages() {
|
||||||
// Set up fixture - an unpublished page
|
// Set up fixture - an unpublished page
|
||||||
$this->logInWithPermission("ADMIN");
|
$this->logInWithPermission("ADMIN");
|
||||||
@ -125,7 +128,7 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
// subadmin had edit rights on that page, but now it's gone
|
// subadmin had edit rights on that page, but now it's gone
|
||||||
$member = $this->objFromFixture('Member','subadmin');
|
$member = $this->objFromFixture('Member','subadmin');
|
||||||
$member->logIn();
|
$member->logIn();
|
||||||
|
|
||||||
$this->assertFalse($page->canEdit());
|
$this->assertFalse($page->canEdit());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,19 +145,19 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
|
|
||||||
$editor = $this->objFromFixture('Member', 'editor');
|
$editor = $this->objFromFixture('Member', 'editor');
|
||||||
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
||||||
|
|
||||||
$this->assertTrue($page->canViewStage('Live', $websiteuser));
|
$this->assertTrue($page->canViewStage('Live', $websiteuser));
|
||||||
$this->assertFalse($page->canViewStage('Stage', $websiteuser));
|
$this->assertFalse($page->canViewStage('Stage', $websiteuser));
|
||||||
|
|
||||||
$this->assertTrue($page->canViewStage('Live', $editor));
|
$this->assertTrue($page->canViewStage('Live', $editor));
|
||||||
$this->assertTrue($page->canViewStage('Stage', $editor));
|
$this->assertTrue($page->canViewStage('Stage', $editor));
|
||||||
|
|
||||||
$this->useDraftSite();
|
$this->useDraftSite();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAccessTabOnlyDisplaysWithGrantAccessPermissions() {
|
public function testAccessTabOnlyDisplaysWithGrantAccessPermissions() {
|
||||||
$page = $this->objFromFixture('Page', 'standardpage');
|
$page = $this->objFromFixture('Page', 'standardpage');
|
||||||
|
|
||||||
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||||
$this->session()->inst_set('loggedInAs', $subadminuser->ID);
|
$this->session()->inst_set('loggedInAs', $subadminuser->ID);
|
||||||
$fields = $page->getSettingsFields();
|
$fields = $page->getSettingsFields();
|
||||||
@ -166,7 +169,7 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
$fields->dataFieldByName('CanEditType')->isReadonly(),
|
$fields->dataFieldByName('CanEditType')->isReadonly(),
|
||||||
'Users with SITETREE_GRANT_ACCESS permission can change "edit" permissions in cms fields'
|
'Users with SITETREE_GRANT_ACCESS permission can change "edit" permissions in cms fields'
|
||||||
);
|
);
|
||||||
|
|
||||||
$editoruser = $this->objFromFixture('Member', 'editor');
|
$editoruser = $this->objFromFixture('Member', 'editor');
|
||||||
$this->session()->inst_set('loggedInAs', $editoruser->ID);
|
$this->session()->inst_set('loggedInAs', $editoruser->ID);
|
||||||
$fields = $page->getSettingsFields();
|
$fields = $page->getSettingsFields();
|
||||||
@ -178,13 +181,13 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
$fields->dataFieldByName('CanEditType')->isReadonly(),
|
$fields->dataFieldByName('CanEditType')->isReadonly(),
|
||||||
'Users without SITETREE_GRANT_ACCESS permission cannot change "edit" permissions in cms fields'
|
'Users without SITETREE_GRANT_ACCESS permission cannot change "edit" permissions in cms fields'
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->session()->inst_set('loggedInAs', null);
|
$this->session()->inst_set('loggedInAs', null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRestrictedViewLoggedInUsers() {
|
public function testRestrictedViewLoggedInUsers() {
|
||||||
$page = $this->objFromFixture('Page', 'restrictedViewLoggedInUsers');
|
$page = $this->objFromFixture('Page', 'restrictedViewLoggedInUsers');
|
||||||
|
|
||||||
// unauthenticated users
|
// unauthenticated users
|
||||||
$this->assertFalse(
|
$this->assertFalse(
|
||||||
$page->canView(FALSE),
|
$page->canView(FALSE),
|
||||||
@ -197,7 +200,7 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
302,
|
302,
|
||||||
'Unauthenticated members cant view a page marked as "Viewable for any logged in users"'
|
'Unauthenticated members cant view a page marked as "Viewable for any logged in users"'
|
||||||
);
|
);
|
||||||
|
|
||||||
// website users
|
// website users
|
||||||
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
||||||
$this->assertTrue(
|
$this->assertTrue(
|
||||||
@ -213,10 +216,10 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
);
|
);
|
||||||
$this->session()->inst_set('loggedInAs', null);
|
$this->session()->inst_set('loggedInAs', null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRestrictedViewOnlyTheseUsers() {
|
public function testRestrictedViewOnlyTheseUsers() {
|
||||||
$page = $this->objFromFixture('Page', 'restrictedViewOnlyWebsiteUsers');
|
$page = $this->objFromFixture('Page', 'restrictedViewOnlyWebsiteUsers');
|
||||||
|
|
||||||
// unauthenticcated users
|
// unauthenticcated users
|
||||||
$this->assertFalse(
|
$this->assertFalse(
|
||||||
$page->canView(FALSE),
|
$page->canView(FALSE),
|
||||||
@ -229,7 +232,7 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
302,
|
302,
|
||||||
'Unauthenticated members cant view a page marked as "Viewable by these groups"'
|
'Unauthenticated members cant view a page marked as "Viewable by these groups"'
|
||||||
);
|
);
|
||||||
|
|
||||||
// subadmin users
|
// subadmin users
|
||||||
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||||
$this->assertFalse(
|
$this->assertFalse(
|
||||||
@ -244,7 +247,7 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
'Authenticated members cant view a page marked as "Viewable by these groups" if theyre not in the listed groups'
|
'Authenticated members cant view a page marked as "Viewable by these groups" if theyre not in the listed groups'
|
||||||
);
|
);
|
||||||
$this->session()->inst_set('loggedInAs', null);
|
$this->session()->inst_set('loggedInAs', null);
|
||||||
|
|
||||||
// website users
|
// website users
|
||||||
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
||||||
$this->assertTrue(
|
$this->assertTrue(
|
||||||
@ -260,16 +263,16 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
);
|
);
|
||||||
$this->session()->inst_set('loggedInAs', null);
|
$this->session()->inst_set('loggedInAs', null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRestrictedEditLoggedInUsers() {
|
public function testRestrictedEditLoggedInUsers() {
|
||||||
$page = $this->objFromFixture('Page', 'restrictedEditLoggedInUsers');
|
$page = $this->objFromFixture('Page', 'restrictedEditLoggedInUsers');
|
||||||
|
|
||||||
// unauthenticcated users
|
// unauthenticcated users
|
||||||
$this->assertFalse(
|
$this->assertFalse(
|
||||||
$page->canEdit(FALSE),
|
$page->canEdit(FALSE),
|
||||||
'Unauthenticated members cant edit a page marked as "Editable by logged in users"'
|
'Unauthenticated members cant edit a page marked as "Editable by logged in users"'
|
||||||
);
|
);
|
||||||
|
|
||||||
// website users
|
// website users
|
||||||
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
||||||
$websiteuser->logIn();
|
$websiteuser->logIn();
|
||||||
@ -277,7 +280,7 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
$page->canEdit($websiteuser),
|
$page->canEdit($websiteuser),
|
||||||
'Authenticated members cant edit a page marked as "Editable by logged in users" if they dont have cms permissions'
|
'Authenticated members cant edit a page marked as "Editable by logged in users" if they dont have cms permissions'
|
||||||
);
|
);
|
||||||
|
|
||||||
// subadmin users
|
// subadmin users
|
||||||
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||||
$this->assertTrue(
|
$this->assertTrue(
|
||||||
@ -285,23 +288,23 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
'Authenticated members can edit a page marked as "Editable by logged in users" if they have cms permissions and belong to any of these groups'
|
'Authenticated members can edit a page marked as "Editable by logged in users" if they have cms permissions and belong to any of these groups'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRestrictedEditOnlySubadminGroup() {
|
public function testRestrictedEditOnlySubadminGroup() {
|
||||||
$page = $this->objFromFixture('Page', 'restrictedEditOnlySubadminGroup');
|
$page = $this->objFromFixture('Page', 'restrictedEditOnlySubadminGroup');
|
||||||
|
|
||||||
// unauthenticated users
|
// unauthenticated users
|
||||||
$this->assertFalse(
|
$this->assertFalse(
|
||||||
$page->canEdit(FALSE),
|
$page->canEdit(FALSE),
|
||||||
'Unauthenticated members cant edit a page marked as "Editable by these groups"'
|
'Unauthenticated members cant edit a page marked as "Editable by these groups"'
|
||||||
);
|
);
|
||||||
|
|
||||||
// subadmin users
|
// subadmin users
|
||||||
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||||
$this->assertTrue(
|
$this->assertTrue(
|
||||||
$page->canEdit($subadminuser),
|
$page->canEdit($subadminuser),
|
||||||
'Authenticated members can view a page marked as "Editable by these groups" if theyre in the listed groups'
|
'Authenticated members can view a page marked as "Editable by these groups" if theyre in the listed groups'
|
||||||
);
|
);
|
||||||
|
|
||||||
// website users
|
// website users
|
||||||
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
||||||
$this->assertFalse(
|
$this->assertFalse(
|
||||||
@ -309,11 +312,11 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
'Authenticated members cant edit a page marked as "Editable by these groups" if theyre not in the listed groups'
|
'Authenticated members cant edit a page marked as "Editable by these groups" if theyre not in the listed groups'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRestrictedViewInheritance() {
|
public function testRestrictedViewInheritance() {
|
||||||
$parentPage = $this->objFromFixture('Page', 'parent_restrictedViewOnlySubadminGroup');
|
$parentPage = $this->objFromFixture('Page', 'parent_restrictedViewOnlySubadminGroup');
|
||||||
$childPage = $this->objFromFixture('Page', 'child_restrictedViewOnlySubadminGroup');
|
$childPage = $this->objFromFixture('Page', 'child_restrictedViewOnlySubadminGroup');
|
||||||
|
|
||||||
// unauthenticated users
|
// unauthenticated users
|
||||||
$this->assertFalse(
|
$this->assertFalse(
|
||||||
$childPage->canView(FALSE),
|
$childPage->canView(FALSE),
|
||||||
@ -326,7 +329,7 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
302,
|
302,
|
||||||
'Unauthenticated members cant view a page marked as "Viewable by these groups" by inherited permission'
|
'Unauthenticated members cant view a page marked as "Viewable by these groups" by inherited permission'
|
||||||
);
|
);
|
||||||
|
|
||||||
// subadmin users
|
// subadmin users
|
||||||
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||||
$this->assertTrue(
|
$this->assertTrue(
|
||||||
@ -342,17 +345,17 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
);
|
);
|
||||||
$this->session()->inst_set('loggedInAs', null);
|
$this->session()->inst_set('loggedInAs', null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRestrictedEditInheritance() {
|
public function testRestrictedEditInheritance() {
|
||||||
$parentPage = $this->objFromFixture('Page', 'parent_restrictedEditOnlySubadminGroup');
|
$parentPage = $this->objFromFixture('Page', 'parent_restrictedEditOnlySubadminGroup');
|
||||||
$childPage = $this->objFromFixture('Page', 'child_restrictedEditOnlySubadminGroup');
|
$childPage = $this->objFromFixture('Page', 'child_restrictedEditOnlySubadminGroup');
|
||||||
|
|
||||||
// unauthenticated users
|
// unauthenticated users
|
||||||
$this->assertFalse(
|
$this->assertFalse(
|
||||||
$childPage->canEdit(FALSE),
|
$childPage->canEdit(FALSE),
|
||||||
'Unauthenticated members cant edit a page marked as "Editable by these groups" by inherited permission'
|
'Unauthenticated members cant edit a page marked as "Editable by these groups" by inherited permission'
|
||||||
);
|
);
|
||||||
|
|
||||||
// subadmin users
|
// subadmin users
|
||||||
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||||
$this->assertTrue(
|
$this->assertTrue(
|
||||||
@ -360,11 +363,11 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
'Authenticated members can edit a page marked as "Editable by these groups" if theyre in the listed groups by inherited permission'
|
'Authenticated members can edit a page marked as "Editable by these groups" if theyre in the listed groups by inherited permission'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDeleteRestrictedChild() {
|
public function testDeleteRestrictedChild() {
|
||||||
$parentPage = $this->objFromFixture('Page', 'deleteTestParentPage');
|
$parentPage = $this->objFromFixture('Page', 'deleteTestParentPage');
|
||||||
$childPage = $this->objFromFixture('Page', 'deleteTestChildPage');
|
$childPage = $this->objFromFixture('Page', 'deleteTestChildPage');
|
||||||
|
|
||||||
// unauthenticated users
|
// unauthenticated users
|
||||||
$this->assertFalse(
|
$this->assertFalse(
|
||||||
$parentPage->canDelete(FALSE),
|
$parentPage->canDelete(FALSE),
|
||||||
@ -375,13 +378,13 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
'Unauthenticated members cant delete a child page marked as "Editable by these groups"'
|
'Unauthenticated members cant delete a child page marked as "Editable by these groups"'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRestrictedEditLoggedInUsersDeletedFromStage() {
|
public function testRestrictedEditLoggedInUsersDeletedFromStage() {
|
||||||
$page = $this->objFromFixture('Page', 'restrictedEditLoggedInUsers');
|
$page = $this->objFromFixture('Page', 'restrictedEditLoggedInUsers');
|
||||||
$pageID = $page->ID;
|
$pageID = $page->ID;
|
||||||
|
|
||||||
$this->logInWithPermission("ADMIN");
|
$this->logInWithPermission("ADMIN");
|
||||||
|
|
||||||
$page->doPublish();
|
$page->doPublish();
|
||||||
$page->deleteFromStage('Stage');
|
$page->deleteFromStage('Stage');
|
||||||
|
|
||||||
@ -402,40 +405,40 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
$siteconfig = $this->objFromFixture('SiteConfig', 'default');
|
$siteconfig = $this->objFromFixture('SiteConfig', 'default');
|
||||||
$editor = $this->objFromFixture('Member', 'editor');
|
$editor = $this->objFromFixture('Member', 'editor');
|
||||||
$editorGroup = $this->objFromFixture('Group', 'editorgroup');
|
$editorGroup = $this->objFromFixture('Group', 'editorgroup');
|
||||||
|
|
||||||
$siteconfig->CanViewType = 'Anyone';
|
$siteconfig->CanViewType = 'Anyone';
|
||||||
$siteconfig->write();
|
$siteconfig->write();
|
||||||
$this->assertTrue($page->canView(FALSE), 'Anyone can view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to LoggedInUsers');
|
$this->assertTrue($page->canView(FALSE), 'Anyone can view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to LoggedInUsers');
|
||||||
|
|
||||||
$siteconfig->CanViewType = 'LoggedInUsers';
|
$siteconfig->CanViewType = 'LoggedInUsers';
|
||||||
$siteconfig->write();
|
$siteconfig->write();
|
||||||
$this->assertFalse($page->canView(FALSE), 'Anonymous can\'t view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to LoggedInUsers');
|
$this->assertFalse($page->canView(FALSE), 'Anonymous can\'t view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to LoggedInUsers');
|
||||||
|
|
||||||
$siteconfig->CanViewType = 'LoggedInUsers';
|
$siteconfig->CanViewType = 'LoggedInUsers';
|
||||||
$siteconfig->write();
|
$siteconfig->write();
|
||||||
$this->assertTrue($page->canView($editor), 'Users can view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to LoggedInUsers');
|
$this->assertTrue($page->canView($editor), 'Users can view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to LoggedInUsers');
|
||||||
|
|
||||||
$siteconfig->CanViewType = 'OnlyTheseUsers';
|
$siteconfig->CanViewType = 'OnlyTheseUsers';
|
||||||
$siteconfig->ViewerGroups()->add($editorGroup);
|
$siteconfig->ViewerGroups()->add($editorGroup);
|
||||||
$siteconfig->write();
|
$siteconfig->write();
|
||||||
$this->assertTrue($page->canView($editor), 'Editors can view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to OnlyTheseUsers');
|
$this->assertTrue($page->canView($editor), 'Editors can view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to OnlyTheseUsers');
|
||||||
$this->assertFalse($page->canView(FALSE), 'Anonymous can\'t view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to OnlyTheseUsers');
|
$this->assertFalse($page->canView(FALSE), 'Anonymous can\'t view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to OnlyTheseUsers');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInheritCanEditFromSiteConfig() {
|
public function testInheritCanEditFromSiteConfig() {
|
||||||
$page = $this->objFromFixture('Page', 'inheritWithNoParent');
|
$page = $this->objFromFixture('Page', 'inheritWithNoParent');
|
||||||
$siteconfig = $this->objFromFixture('SiteConfig', 'default');
|
$siteconfig = $this->objFromFixture('SiteConfig', 'default');
|
||||||
$editor = $this->objFromFixture('Member', 'editor');
|
$editor = $this->objFromFixture('Member', 'editor');
|
||||||
$user = $this->objFromFixture('Member', 'websiteuser');
|
$user = $this->objFromFixture('Member', 'websiteuser');
|
||||||
$editorGroup = $this->objFromFixture('Group', 'editorgroup');
|
$editorGroup = $this->objFromFixture('Group', 'editorgroup');
|
||||||
|
|
||||||
$siteconfig->CanEditType = 'LoggedInUsers';
|
$siteconfig->CanEditType = 'LoggedInUsers';
|
||||||
$siteconfig->write();
|
$siteconfig->write();
|
||||||
|
|
||||||
$this->assertFalse($page->canEdit(FALSE), 'Anonymous can\'t edit a page when set to inherit from the SiteConfig, and SiteConfig has canEdit set to LoggedInUsers');
|
$this->assertFalse($page->canEdit(FALSE), 'Anonymous can\'t edit a page when set to inherit from the SiteConfig, and SiteConfig has canEdit set to LoggedInUsers');
|
||||||
$this->session()->inst_set('loggedInAs', $editor->ID);
|
$this->session()->inst_set('loggedInAs', $editor->ID);
|
||||||
$this->assertTrue($page->canEdit(), 'Users can edit a page when set to inherit from the SiteConfig, and SiteConfig has canEdit set to LoggedInUsers');
|
$this->assertTrue($page->canEdit(), 'Users can edit a page when set to inherit from the SiteConfig, and SiteConfig has canEdit set to LoggedInUsers');
|
||||||
|
|
||||||
$siteconfig->CanEditType = 'OnlyTheseUsers';
|
$siteconfig->CanEditType = 'OnlyTheseUsers';
|
||||||
$siteconfig->EditorGroups()->add($editorGroup);
|
$siteconfig->EditorGroups()->add($editorGroup);
|
||||||
$siteconfig->write();
|
$siteconfig->write();
|
||||||
|
Loading…
Reference in New Issue
Block a user