mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
FEATURE: Refactored RootURLController to allow nested home pages.
MINOR: Deprecated RootURLController::get_homepage_urlsegment() in favour of get_homepage_link(). MINOR: Updated SiteTree->RelativeLink() to return a link to the site root for the home page. From: Andrew Short <andrewjshort@gmail.com> git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@88496 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
f29eceecff
commit
ad7194cc40
@ -1,117 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* This controller handles what happens when you visit the root URL.
|
||||
*
|
||||
* @package sapphire
|
||||
* @subpackage control
|
||||
*/
|
||||
class RootURLController extends Controller {
|
||||
|
||||
/**
|
||||
* @var boolean $is_at_root
|
||||
* @var bool
|
||||
*/
|
||||
protected static $is_at_root = false;
|
||||
|
||||
/**
|
||||
* @var string $default_homepage_urlsegment Defines which URLSegment value on a {@link SiteTree} object
|
||||
* is regarded as the correct "homepage" if the requested URI doesn't contain
|
||||
* an explicit segment. E.g. http://mysite.com should show http://mysite.com/home.
|
||||
* @var string
|
||||
*/
|
||||
protected static $default_homepage_urlsegment = 'home';
|
||||
protected static $default_homepage_link = 'home';
|
||||
|
||||
public function handleRequest($request) {
|
||||
self::$is_at_root = true;
|
||||
$this->pushCurrent();
|
||||
|
||||
$this->init();
|
||||
|
||||
// If the basic database hasn't been created, then build it.
|
||||
if(!DB::isActive() || !ClassInfo::hasTable('SiteTree')) {
|
||||
$this->response = new HTTPResponse();
|
||||
$this->redirect("dev/build?returnURL=");
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
$controller = new ModelAsController();
|
||||
$request = new HTTPRequest("GET", self::get_homepage_urlsegment().'/', $request->getVars(), $request->postVars());
|
||||
$request->match('$URLSegment//$Action', true);
|
||||
|
||||
$result = $controller->handleRequest($request);
|
||||
|
||||
$this->popCurrent();
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the URL segment for the current HTTP_HOST value
|
||||
*
|
||||
* @param string $locale
|
||||
* Get the full form (e.g. /home/) relative link to the home page for the current HTTP_HOST value. Note that the
|
||||
* link is trimmed of leading and trailing slashes before returning to ensure consistency.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static function get_homepage_urlsegment() {
|
||||
$urlSegment = '';
|
||||
|
||||
$homePageOBJ = null;
|
||||
|
||||
$host = $_SERVER['HTTP_HOST'];
|
||||
$host = str_replace('www.','',$host);
|
||||
public static function get_homepage_link() {
|
||||
$host = str_replace('www.', null, $_SERVER['HTTP_HOST']);
|
||||
$SQL_host = Convert::raw2sql($host);
|
||||
|
||||
$homePageOBJs = DataObject::get("SiteTree", "\"HomepageForDomain\" LIKE '%$SQL_host%'");
|
||||
if($homePageOBJs) foreach($homePageOBJs as $candidateObj) {
|
||||
if(preg_match('/(,|^) *' . preg_quote($host) . ' *(,|$)/', $candidateObj->HomepageForDomain)) {
|
||||
$homePageOBJ = $candidateObj;
|
||||
break;
|
||||
$candidates = DataObject::get('SiteTree', "\"HomepageForDomain\" LIKE '%$SQL_host%'");
|
||||
|
||||
if($candidates) foreach($candidates as $candidate) {
|
||||
if(preg_match('/(,|^) *' . preg_quote($host) . ' *(,|$)/', $candidate->HomepageForDomain)) {
|
||||
return trim($candidate->RelativeLink(true), '/');
|
||||
}
|
||||
}
|
||||
|
||||
if(singleton('SiteTree')->hasExtension('Translatable') && !$homePageOBJ) {
|
||||
$urlSegment = Translatable::get_homepage_urlsegment_by_locale(Translatable::get_current_locale());
|
||||
} elseif($homePageOBJ) {
|
||||
$urlSegment = $homePageOBJ->URLSegment;
|
||||
if(Object::has_extension('SiteTree', 'Translatable')) {
|
||||
if($link = Translatable::get_homepage_link_by_locale(Translatable::get_current_locale())) return $link;
|
||||
}
|
||||
|
||||
return ($urlSegment) ? $urlSegment : self::get_default_homepage_urlsegment();
|
||||
|
||||
return self::get_default_homepage_link();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if we're currently on the root page and should be redirecting to the root
|
||||
* Doesn't take into account actions, post vars, or get vars.
|
||||
* Gets the link that denotes the homepage if there is not one explicitly defined for this HTTP_HOST value.
|
||||
*
|
||||
* @param SiteTree $currentPage
|
||||
* @return boolean
|
||||
* @return string
|
||||
*/
|
||||
static function should_be_on_root(SiteTree $currentPage) {
|
||||
if(self::$is_at_root) return false;
|
||||
|
||||
if(!$currentPage->HomepageForDomain
|
||||
&& $currentPage->URLSegment != self::get_default_homepage_urlsegment()) return false;
|
||||
|
||||
$matchesHomepageSegment = (self::get_homepage_urlsegment() == $currentPage->URLSegment);
|
||||
// Don't redirect translated homepage segments,
|
||||
// as the redirection target '/' will show the default locale
|
||||
// instead of the translation.
|
||||
$isTranslatedHomepage = (
|
||||
singleton('SiteTree')->hasExtension('Translatable')
|
||||
&& $currentPage->Locale
|
||||
&& $currentPage->Locale != Translatable::default_locale()
|
||||
);
|
||||
if($matchesHomepageSegment && !$isTranslatedHomepage) return true;
|
||||
public static function get_default_homepage_link() {
|
||||
return self::$default_homepage_link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if a request to a certain page should be redirected to the site root (i.e. if the page acts as the
|
||||
* home page).
|
||||
*
|
||||
* @param SiteTree $page
|
||||
* @return bool
|
||||
*/
|
||||
public static function should_be_on_root(SiteTree $page) {
|
||||
if(!self::$is_at_root && self::get_homepage_link() == trim($page->RelativeLink(true), '/')) {
|
||||
return !(
|
||||
$page->hasExtension('Translatable') && $page->Locale && $page->Locale != Translatable::default_locale()
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the (untranslated) hardcoded URL segment that will
|
||||
* show when the website is accessed without a URL segment (http://mysite.com/).
|
||||
* It is also the base for any redirections to '/' for the homepage,
|
||||
* see {@link should_be_on_root()}.
|
||||
*
|
||||
* @return string
|
||||
* @deprecated 2.4 Use {@link RootURLController::get_homepage_link()}
|
||||
*/
|
||||
static function get_default_homepage_urlsegment() {
|
||||
return self::$default_homepage_urlsegment;
|
||||
public static function get_homepage_urlsegment() {
|
||||
user_error (
|
||||
'RootURLController::get_homepage_urlsegment() is deprecated, please use get_homepage_link()', E_USER_NOTICE
|
||||
);
|
||||
|
||||
return self::get_homepage_link();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param HTTPRequest $request
|
||||
* @return HTTPResponse
|
||||
*/
|
||||
public function handleRequest(HTTPRequest $request) {
|
||||
self::$is_at_root = true;
|
||||
|
||||
$this->pushCurrent();
|
||||
$this->init();
|
||||
|
||||
if(!DB::isActive() || !ClassInfo::hasTable('SiteTree')) {
|
||||
$this->response = new HTTPResponse();
|
||||
$this->response->redirect('dev/build/?returnURL=');
|
||||
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
$request = new HTTPRequest (
|
||||
$request->httpMethod(), self::get_homepage_link() . '/', $request->getVars(), $request->postVars()
|
||||
);
|
||||
$request->match('$URLSegment//$Action', true);
|
||||
|
||||
$controller = new ModelAsController();
|
||||
$result = $controller->handleRequest($request);
|
||||
|
||||
$this->popCurrent();
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -244,7 +244,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
if(trim($link, '/')) {
|
||||
$link = trim(Director::makeRelative($link), '/');
|
||||
} else {
|
||||
$link = RootURLController::get_homepage_urlsegment();
|
||||
$link = RootURLController::get_homepage_link();
|
||||
}
|
||||
|
||||
$parts = Convert::raw2sql(preg_split('|/+|', $link));
|
||||
@ -379,19 +379,32 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
/**
|
||||
* Return the link for this {@link SiteTree} object relative to the SilverStripe root.
|
||||
*
|
||||
* By default, it this page is the current home page, and there is no action specified then this will return a link
|
||||
* to the root of the site. However, if you set the $action parameter to TRUE then the link will not be rewritten
|
||||
* and returned in its full form.
|
||||
*
|
||||
* @uses RootURLController::get_homepage_link()
|
||||
* @param string $action
|
||||
* @return string
|
||||
*/
|
||||
public function RelativeLink($action = null) {
|
||||
$action = str_replace('&', '&', $action);
|
||||
|
||||
if($this->ParentID && self::nested_urls()) {
|
||||
$base = $this->Parent()->RelativeLink($this->URLSegment);
|
||||
} else {
|
||||
$base = $this->URLSegment;
|
||||
}
|
||||
|
||||
return "$base/$action";
|
||||
if(!$action && $base == RootURLController::get_homepage_link()) {
|
||||
$base = null;
|
||||
}
|
||||
|
||||
if(is_string($action)) {
|
||||
$action = str_replace('&', '&', $action);
|
||||
} elseif($action === true) {
|
||||
$action = null;
|
||||
}
|
||||
|
||||
return Controller::join_links($base, '/', $action);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1219,28 +1219,21 @@ class Translatable extends DataObjectDecorator implements PermissionProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a URLSegment value for a homepage in another language.
|
||||
* The value is inferred by finding the homepage in default language
|
||||
* (as identified by RootURLController::$default_homepage_urlsegment).
|
||||
* Returns NULL if no translated page can be found.
|
||||
*
|
||||
* @param string $locale
|
||||
* @return string|boolean URLSegment (e.g. "home")
|
||||
* @todo
|
||||
*/
|
||||
public static function get_homepage_link_by_locale($locale) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 2.4 Use {@link Translatable::get_homepage_link_by_locale()}
|
||||
*/
|
||||
static function get_homepage_urlsegment_by_locale($locale) {
|
||||
$origHomepageObj = Translatable::get_one_by_locale(
|
||||
'SiteTree',
|
||||
Translatable::default_locale(),
|
||||
sprintf('"URLSegment" = \'%s\'', RootURLController::get_default_homepage_urlsegment())
|
||||
user_error (
|
||||
'Translatable::get_homepage_urlsegment_by_locale() is deprecated, please use get_homepage_link_by_locale()',
|
||||
E_USER_NOTICE
|
||||
);
|
||||
if($origHomepageObj) {
|
||||
$translatedHomepageObj = $origHomepageObj->getTranslation($locale);
|
||||
if($translatedHomepageObj) {
|
||||
return $translatedHomepageObj->URLSegment;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return self::get_homepage_link_by_locale($locale);
|
||||
}
|
||||
|
||||
/**
|
||||
|
24
tests/control/RootURLControllerTest.php
Normal file → Executable file
24
tests/control/RootURLControllerTest.php
Normal file → Executable file
@ -39,11 +39,33 @@ class RootURLControllerTest extends SapphireTest {
|
||||
$_SERVER['HTTP_HOST'] = $domain;
|
||||
$this->assertEquals(
|
||||
$urlSegment,
|
||||
RootURLController::get_homepage_urlsegment(Translatable::default_locale()),
|
||||
RootURLController::get_homepage_link(),
|
||||
"Testing $domain matches $urlSegment"
|
||||
);
|
||||
}
|
||||
|
||||
$_SERVER['HTTP_HOST'] = $originalHost;
|
||||
}
|
||||
|
||||
public function testGetHomepageLink() {
|
||||
$default = $this->objFromFixture('Page', 'home');
|
||||
$nested = $this->objFromFixture('Page', 'nested');
|
||||
|
||||
SiteTree::disable_nested_urls();
|
||||
$this->assertEquals('home', RootURLController::get_homepage_link());
|
||||
SiteTree::enable_nested_urls();
|
||||
$this->assertEquals('home', RootURLController::get_homepage_link());
|
||||
|
||||
$nested->HomepageForDomain = str_replace('www.', null, $_SERVER['HTTP_HOST']);
|
||||
$nested->write();
|
||||
|
||||
SiteTree::disable_nested_urls();
|
||||
$this->assertEquals('nested-home', RootURLController::get_homepage_link());
|
||||
SiteTree::enable_nested_urls();
|
||||
$this->assertEquals('home/nested-home', RootURLController::get_homepage_link());
|
||||
|
||||
$nested->HomepageForDomain = null;
|
||||
$nested->write();
|
||||
}
|
||||
|
||||
}
|
3
tests/control/RootURLControllerTest.yml
Normal file → Executable file
3
tests/control/RootURLControllerTest.yml
Normal file → Executable file
@ -1,6 +1,9 @@
|
||||
Page:
|
||||
home:
|
||||
Title: Home
|
||||
nested:
|
||||
Title: Nested Home
|
||||
Parent: =>Page.home
|
||||
page1:
|
||||
Title: First Page
|
||||
URLSegment: page1
|
||||
|
4
tests/model/TranslatableTest.php
Normal file → Executable file
4
tests/model/TranslatableTest.php
Normal file → Executable file
@ -652,7 +652,7 @@ class TranslatableTest extends FunctionalTest {
|
||||
// test with translatable
|
||||
Translatable::set_current_locale('de_DE');
|
||||
$this->assertEquals(
|
||||
RootURLController::get_homepage_urlsegment(),
|
||||
RootURLController::get_homepage_link(),
|
||||
'heim',
|
||||
'Homepage with different URLSegment in non-default language is found'
|
||||
);
|
||||
@ -893,4 +893,4 @@ class TranslatableTest_Page extends Page implements TestOnly {
|
||||
}
|
||||
|
||||
DataObject::add_extension('TranslatableTest_DataObject', 'TranslatableTest_Decorator');
|
||||
?>
|
||||
?>
|
||||
|
Loading…
Reference in New Issue
Block a user