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!
|
||||
"$action"
|
||||
);
|
||||
$this->extend('updateLink', $link);
|
||||
$this->extend('updateLink', $link, $action);
|
||||
return $link;
|
||||
}
|
||||
|
||||
|
@ -465,7 +465,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
* @return string
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public function getAbsoluteLiveLink($includeStageEqualsLive = true) {
|
||||
$oldStage = Versioned::current_stage();
|
||||
$oldMode = Versioned::get_reading_mode();
|
||||
Versioned::reading_stage('Live');
|
||||
$live = Versioned::get_one_by_stage('SiteTree', 'Live', array(
|
||||
'"SiteTree"."ID"' => $this->ID
|
||||
@ -556,7 +559,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
$link = null;
|
||||
}
|
||||
|
||||
Versioned::reading_stage($oldStage);
|
||||
Versioned::set_reading_mode($oldMode);
|
||||
return $link;
|
||||
}
|
||||
|
||||
@ -2429,7 +2432,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
|
||||
$this->invokeWithExtensions('onBeforeUnpublish', $this);
|
||||
|
||||
$origStage = Versioned::current_stage();
|
||||
$origMode = Versioned::get_reading_mode();
|
||||
Versioned::reading_stage('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();
|
||||
}
|
||||
Versioned::reading_stage($origStage);
|
||||
Versioned::set_reading_mode($origMode);
|
||||
|
||||
// Unpublish any published virtual pages
|
||||
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);
|
||||
}
|
||||
|
||||
$oldStage = Versioned::current_stage();
|
||||
$oldMode = Versioned::get_reading_mode();
|
||||
Versioned::reading_stage('Stage');
|
||||
$this->forceChange();
|
||||
$this->write();
|
||||
@ -2534,7 +2537,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
$page->write();
|
||||
}
|
||||
|
||||
Versioned::reading_stage($oldStage);
|
||||
Versioned::set_reading_mode($oldMode);
|
||||
|
||||
$this->invokeWithExtensions('onAfterRestoreToStage', $this);
|
||||
|
||||
|
@ -110,7 +110,7 @@ class SiteTreeFileExtension extends DataExtension {
|
||||
// site does its thing
|
||||
$brokenPageIDs = $this->owner->BackLinkTracking()->column("ID");
|
||||
if($brokenPageIDs) {
|
||||
$origStage = Versioned::current_stage();
|
||||
$origMode = Versioned::get_reading_mode();
|
||||
|
||||
// This will syncLinkTracking on draft
|
||||
Versioned::reading_stage('Stage');
|
||||
@ -124,7 +124,7 @@ class SiteTreeFileExtension extends DataExtension {
|
||||
$brokenPage->write();
|
||||
}
|
||||
|
||||
Versioned::reading_stage($origStage);
|
||||
Versioned::set_reading_mode($origMode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,16 +7,21 @@ class ContentControllerTest extends FunctionalTest {
|
||||
|
||||
protected static $fixture_file = 'ContentControllerTest.yml';
|
||||
|
||||
protected static $use_draft_site = 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
|
||||
*/
|
||||
|
||||
public function testNestedPages() {
|
||||
RootURLController::reset();
|
||||
$this->useDraftSite(true);
|
||||
Config::inst()->update('SiteTree', 'nested_urls', true);
|
||||
|
||||
$this->assertEquals('Home Page', $this->get('/')->getBody());
|
||||
@ -52,7 +57,7 @@ class ContentControllerTest extends FunctionalTest {
|
||||
*/
|
||||
public function testChildrenOf() {
|
||||
$controller = new ContentController();
|
||||
|
||||
$this->useDraftSite(true);
|
||||
Config::inst()->update('SiteTree', 'nested_urls', true);
|
||||
|
||||
$this->assertEquals(1, $controller->ChildrenOf('/')->Count());
|
||||
@ -70,6 +75,7 @@ class ContentControllerTest extends FunctionalTest {
|
||||
|
||||
public function testDeepNestedURLs() {
|
||||
Config::inst()->update('SiteTree', 'nested_urls', true);
|
||||
$this->useDraftSite(true);
|
||||
|
||||
$page = new Page();
|
||||
$page->URLSegment = 'base-page';
|
||||
@ -126,7 +132,7 @@ class ContentControllerTest extends FunctionalTest {
|
||||
|
||||
$this->assertContains(
|
||||
sprintf('<a href="%s">Testlink</a>', $linkedPage->Link()),
|
||||
$this->get($page->RelativeLink())->getBody(),
|
||||
$this->get($page->Link())->getBody(),
|
||||
'"sitetree_link" shortcodes get parsed properly'
|
||||
);
|
||||
}
|
||||
|
@ -2,47 +2,58 @@
|
||||
|
||||
class RedirectorPageTest extends FunctionalTest {
|
||||
protected static $fixture_file = 'RedirectorPageTest.yml';
|
||||
protected static $use_draft_site = true;
|
||||
|
||||
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() {
|
||||
/* For good redirectors, the final destination URL will be returned */
|
||||
$this->assertEquals("http://www.google.com", $this->objFromFixture('RedirectorPage','goodexternal')->Link());
|
||||
$this->assertEquals(Director::baseURL() . "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')->redirectionLink());
|
||||
$this->assertEquals("/redirection-dest/", $this->objFromFixture('RedirectorPage','goodinternal')->Link());
|
||||
}
|
||||
|
||||
public function testEmptyRedirectors() {
|
||||
/* If a redirector page is misconfigured, then its link method will just return the usual URLSegment-generated value */
|
||||
$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 */
|
||||
$content = $this->get(Director::makeRelative($page1->Link()))->getBody();
|
||||
$content = $this->get($page1->Link())->getBody();
|
||||
$this->assertContains('message-setupWithoutRedirect', $content);
|
||||
|
||||
/* This also applies for internal links */
|
||||
$page2 = $this->objFromFixture('RedirectorPage','badinternal');
|
||||
$this->assertEquals(Director::baseURL() . 'bad-internal/', $page2->Link());
|
||||
$content = $this->get(Director::makeRelative($page2->Link()))->getBody();
|
||||
$this->assertEquals('/bad-internal/', $page2->Link());
|
||||
$content = $this->get($page2->Link())->getBody();
|
||||
$this->assertContains('message-setupWithoutRedirect', $content);
|
||||
}
|
||||
|
||||
public function testReflexiveAndTransitiveInternalRedirectors() {
|
||||
/* 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');
|
||||
$this->assertEquals(Director::baseURL() . 'reflexive/', $page->Link());
|
||||
$content = $this->get(Director::makeRelative($page->Link()))->getBody();
|
||||
$this->assertEquals('/reflexive/', $page->Link());
|
||||
$content = $this->get($page->Link())->getBody();
|
||||
$this->assertContains('message-setupWithoutRedirect', $content);
|
||||
|
||||
/* 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 */
|
||||
$page = $this->objFromFixture('RedirectorPage', 'transitive');
|
||||
$this->assertEquals(Director::baseURL() . 'good-internal/', $page->Link());
|
||||
$this->assertEquals('/good-internal/', $page->Link());
|
||||
|
||||
$this->autoFollowRedirection = false;
|
||||
$response = $this->get(Director::makeRelative($page->Link()));
|
||||
$this->assertEquals(Director::baseURL() . "redirection-dest/", $response->getHeader("Location"));
|
||||
$response = $this->get($page->Link());
|
||||
$this->assertEquals("/redirection-dest/", $response->getHeader("Location"));
|
||||
}
|
||||
|
||||
public function testExternalURLGetsPrefixIfNotSet() {
|
||||
|
@ -34,10 +34,10 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
||||
}
|
||||
|
||||
$response = $this->get($page->URLSegment . '?stage=Live');
|
||||
$this->assertEquals($response->getStatusCode(), '404');
|
||||
$this->assertEquals(404, $response->getStatusCode());
|
||||
|
||||
$response = $this->get($page->URLSegment . '?stage=');
|
||||
$this->assertEquals($response->getStatusCode(), '404');
|
||||
$this->assertEquals(404, $response->getStatusCode());
|
||||
|
||||
// should be prompted for a login
|
||||
try {
|
||||
@ -45,7 +45,7 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
||||
} catch(SS_HTTPResponse_Exception $responseException) {
|
||||
$response = $responseException->getResponse();
|
||||
}
|
||||
$this->assertEquals($response->getStatusCode(), '302');
|
||||
$this->assertEquals(302, $response->getStatusCode());
|
||||
$this->assertContains(
|
||||
Config::inst()->get('Security', 'login_url'),
|
||||
$response->getHeader('Location')
|
||||
@ -54,13 +54,16 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
||||
$this->logInWithPermission('ADMIN');
|
||||
|
||||
$response = $this->get($page->URLSegment . '?stage=Live');
|
||||
$this->assertEquals($response->getStatusCode(), '404');
|
||||
|
||||
$response = $this->get($page->URLSegment . '?stage=Stage');
|
||||
$this->assertEquals($response->getStatusCode(), '200');
|
||||
$this->assertEquals(404, $response->getStatusCode());
|
||||
|
||||
$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() {
|
||||
|
Loading…
Reference in New Issue
Block a user