mirror of
https://github.com/silverstripe/silverstripe-reports
synced 2024-10-22 09:05:53 +00:00
Refactor old page redirector into an extension
This commit is contained in:
parent
35a84e4eae
commit
f972466880
@ -22,6 +22,8 @@ class ContentController extends Controller {
|
|||||||
|
|
||||||
protected $dataRecord;
|
protected $dataRecord;
|
||||||
|
|
||||||
|
private static $extensions = array('OldPageRedirector');
|
||||||
|
|
||||||
private static $allowed_actions = array(
|
private static $allowed_actions = array(
|
||||||
'successfullyinstalled',
|
'successfullyinstalled',
|
||||||
'deleteinstallfiles', // secured through custom code
|
'deleteinstallfiles', // secured through custom code
|
||||||
@ -168,31 +170,6 @@ class ContentController extends Controller {
|
|||||||
'URLSegment' => rawurlencode($action)
|
'URLSegment' => rawurlencode($action)
|
||||||
))->first();
|
))->first();
|
||||||
if(class_exists('Translatable')) Translatable::enable_locale_filter();
|
if(class_exists('Translatable')) Translatable::enable_locale_filter();
|
||||||
|
|
||||||
// if we can't find a page with this URLSegment try to find one that used to have
|
|
||||||
// that URLSegment but changed. See ModelAsController->getNestedController() for similiar logic.
|
|
||||||
if(!$child){
|
|
||||||
$child = ModelAsController::find_old_page($action,$this->ID);
|
|
||||||
if($child){
|
|
||||||
$response = new SS_HTTPResponse();
|
|
||||||
$params = $request->getVars();
|
|
||||||
if(isset($params['url'])) unset($params['url']);
|
|
||||||
$response->redirect(
|
|
||||||
Controller::join_links(
|
|
||||||
$child->Link(
|
|
||||||
Controller::join_links(
|
|
||||||
$request->param('ID'), // 'ID' is the new 'URLSegment', everything shifts up one position
|
|
||||||
$request->param('OtherID')
|
|
||||||
)
|
|
||||||
),
|
|
||||||
// Needs to be in separate join links to avoid urlencoding
|
|
||||||
($params) ? '?' . http_build_query($params) : null
|
|
||||||
),
|
|
||||||
301
|
|
||||||
);
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// we found a page with this URLSegment.
|
// we found a page with this URLSegment.
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
* @subpackage control
|
* @subpackage control
|
||||||
*/
|
*/
|
||||||
class ModelAsController extends Controller implements NestedController {
|
class ModelAsController extends Controller implements NestedController {
|
||||||
|
private static $extensions = array('OldPageRedirector');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the appropriate {@link ContentController} for handling a {@link SiteTree} object, link it to the object and
|
* Get the appropriate {@link ContentController} for handling a {@link SiteTree} object, link it to the object and
|
||||||
@ -108,31 +109,6 @@ class ModelAsController extends Controller implements NestedController {
|
|||||||
if(class_exists('Translatable')) Translatable::enable_locale_filter();
|
if(class_exists('Translatable')) Translatable::enable_locale_filter();
|
||||||
|
|
||||||
if(!$sitetree) {
|
if(!$sitetree) {
|
||||||
// If a root page has been renamed, redirect to the new location.
|
|
||||||
// See ContentController->handleRequest() for similiar logic.
|
|
||||||
$redirect = self::find_old_page($URLSegment);
|
|
||||||
if($redirect) {
|
|
||||||
$params = $request->getVars();
|
|
||||||
if(isset($params['url'])) unset($params['url']);
|
|
||||||
$this->response = new SS_HTTPResponse();
|
|
||||||
$this->response->redirect(
|
|
||||||
Controller::join_links(
|
|
||||||
$redirect->Link(
|
|
||||||
Controller::join_links(
|
|
||||||
$request->param('Action'),
|
|
||||||
$request->param('ID'),
|
|
||||||
$request->param('OtherID')
|
|
||||||
)
|
|
||||||
),
|
|
||||||
// Needs to be in separate join links to avoid urlencoding
|
|
||||||
($params) ? '?' . http_build_query($params) : null
|
|
||||||
),
|
|
||||||
301
|
|
||||||
);
|
|
||||||
|
|
||||||
return $this->response;
|
|
||||||
}
|
|
||||||
|
|
||||||
$response = ErrorPage::response_for(404);
|
$response = ErrorPage::response_for(404);
|
||||||
$this->httpError(404, $response ? $response : 'The requested page could not be found.');
|
$this->httpError(404, $response ? $response : 'The requested page could not be found.');
|
||||||
}
|
}
|
||||||
@ -148,45 +124,18 @@ class ModelAsController extends Controller implements NestedController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @deprecated 3.2 Use OldPageRedirector::find_old_page instead
|
||||||
|
*
|
||||||
* @param string $URLSegment A subset of the url. i.e in /home/contact/ home and contact are URLSegment.
|
* @param string $URLSegment A subset of the url. i.e in /home/contact/ home and contact are URLSegment.
|
||||||
* @param int $parentID The ID of the parent of the page the URLSegment belongs to.
|
* @param int $parentID The ID of the parent of the page the URLSegment belongs to.
|
||||||
* @return SiteTree
|
* @return SiteTree
|
||||||
*/
|
*/
|
||||||
static public function find_old_page($URLSegment,$parentID = 0, $ignoreNestedURLs = false) {
|
static public function find_old_page($URLSegment, $parent = null, $ignoreNestedURLs = false) {
|
||||||
|
Deprecation::notice('3.2', 'Use OldPageRedirector::find_old_page instead');
|
||||||
$useParentIDFilter = SiteTree::config()->nested_urls && $parentID;
|
if ($parent) {
|
||||||
|
$parent = SiteTree::get()->byId($parent);
|
||||||
// First look for a non-nested page that has a unique URLSegment and can be redirected to.
|
|
||||||
if(SiteTree::config()->nested_urls) {
|
|
||||||
$pages = SiteTree::get()->filter("URLSegment", rawurlencode($URLSegment));
|
|
||||||
if($useParentIDFilter) {
|
|
||||||
$pages = $pages->filter("ParentID", (int)$parentID);
|
|
||||||
}
|
}
|
||||||
|
$url = OldPageRedirector::find_old_page(array($URLSegment), $parent);
|
||||||
if($pages && $pages->Count() == 1 && ($page = $pages->First())) {
|
return SiteTree::get_by_link($url);
|
||||||
$parent = $page->ParentID ? $page->Parent() : $page;
|
|
||||||
if($parent->isPublished()) return $page;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Get an old version of a page that has been renamed.
|
|
||||||
$URLSegmentSQL = Convert::raw2sql(rawurlencode($URLSegment));
|
|
||||||
$query = new SQLQuery (
|
|
||||||
'"RecordID"',
|
|
||||||
'"SiteTree_versions"',
|
|
||||||
"\"URLSegment\" = '$URLSegmentSQL' AND \"WasPublished\" = 1" . ($useParentIDFilter ? ' AND "ParentID" = ' . (int)$parentID : ''),
|
|
||||||
'"LastEdited" DESC',
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
1
|
|
||||||
);
|
|
||||||
$record = $query->execute()->first();
|
|
||||||
|
|
||||||
if($record && ($oldPage = DataObject::get_by_id('SiteTree', $record['RecordID']))) {
|
|
||||||
$oldParent = $oldPage->ParentID ? $oldPage->Parent() : $oldPage;
|
|
||||||
// Run the page through an extra filter to ensure that all extensions are applied.
|
|
||||||
if(SiteTree::get_by_link($oldPage->RelativeLink()) && $oldParent->isPublished()) return $oldPage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
91
code/controllers/OldPageRedirector.php
Normal file
91
code/controllers/OldPageRedirector.php
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class OldPageRedirector extends Extension {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On every URL that generates a 404, we'll capture it here and see if we can
|
||||||
|
* find an old URL that it should be redirecting to.
|
||||||
|
*
|
||||||
|
* @param SS_HTTPResponse $request The request object
|
||||||
|
*/
|
||||||
|
public function onBeforeHTTPError404($request) {
|
||||||
|
// Build up the request parameters
|
||||||
|
$params = array_filter(array_values($request->allParams()), function($v) { return ($v !== NULL); });
|
||||||
|
|
||||||
|
$getvars = $request->getVars();
|
||||||
|
unset($getvars['url']);
|
||||||
|
|
||||||
|
$page = self::find_old_page($params);
|
||||||
|
|
||||||
|
if ($page) {
|
||||||
|
$res = new SS_HTTPResponse();
|
||||||
|
$res->redirect(
|
||||||
|
Controller::join_links(
|
||||||
|
$page,
|
||||||
|
($getvars) ? '?' . http_build_query($getvars) : null
|
||||||
|
), 301);
|
||||||
|
throw new SS_HTTPResponse_Exception($res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to find an old/renamed page from some given the URL as an array
|
||||||
|
*
|
||||||
|
* @param array $params The array of URL, e.g. /foo/bar as array('foo', 'bar')
|
||||||
|
* @param SiteTree $parent The current parent in the recursive flow
|
||||||
|
* @param boolean $redirect Whether we've found an old page worthy of a redirect
|
||||||
|
*
|
||||||
|
* @return string|boolean False, or the new URL
|
||||||
|
*/
|
||||||
|
static public function find_old_page($params, $parent = null, $redirect = false) {
|
||||||
|
$URL = Convert::raw2sql(array_shift($params));
|
||||||
|
if (empty($URL)) { return false; }
|
||||||
|
if ($parent) {
|
||||||
|
$page = SiteTree::get()->filter(array('ParentID' => $parent->ID, 'URLSegment' => $URL))->First();
|
||||||
|
} else {
|
||||||
|
$page = SiteTree::get()->filter(array('URLSegment' => $URL))->First();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$page) {
|
||||||
|
// If we haven't found a candidate, lets resort to finding an old page with this URL segment
|
||||||
|
// TODO: Rewrite using ORM syntax
|
||||||
|
$query = new SQLQuery (
|
||||||
|
'"RecordID"',
|
||||||
|
'"SiteTree_versions"',
|
||||||
|
"\"URLSegment\" = '$URL' AND \"WasPublished\" = 1" . ($parent ? ' AND "ParentID" = ' . $parent->ID : ''),
|
||||||
|
'"LastEdited" DESC',
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
$record = $query->execute()->first();
|
||||||
|
if ($record) {
|
||||||
|
$page = SiteTree::get()->byID($record['RecordID']);
|
||||||
|
$redirect = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($page && $page->canView()) {
|
||||||
|
if (count($params)) {
|
||||||
|
// We have to go deeper!
|
||||||
|
$ret = self::find_old_page($params, $page, $redirect);
|
||||||
|
if ($ret) {
|
||||||
|
// A valid child page was found! We can return it
|
||||||
|
return $ret;
|
||||||
|
} else {
|
||||||
|
// No valid page found.
|
||||||
|
if ($redirect) {
|
||||||
|
// If we had some redirect to be done, lets do it. imagine /foo/action -> /bar/action, we still want this redirect to happen if action isn't a page
|
||||||
|
return $page->Link() . implode('/', $params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We've found the final, end all, page.
|
||||||
|
return $page->Link();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user