Presmerovani pomoci Redirect map
- Wizzard256
- Člen | 18
Zdravim,
rad bych se zeptal zda nevite o nejakem jednoduchem reseni jak resit redirecty ze starych URL, rekneme ze mam dlouhy seznam starych a novych url, na ktere bych potreboval presmerovat, napr.:
$redirectMap = [
'/?abc[x1]=123&def[x2]=456' => '/landing-page-1',
'/?abc[x1]=789&def[x2]=012' => '/landing-page-2',
...
];
nevidim zda by se toto dalo vyresit pomoci routy, a prepisovani na cilovy tvar
[
'presenter' => 'Homepage',
'action' => 'default'
]
neni zadouci.
Otazka tedy je:
- kam toto reseni zakomponovat v nette
- lze nejak propojit s route, aby redirecty byli videt v tracy v seznamu rout?
Diky
- Wizzard256
- Člen | 18
Zdravím,
@Felix Děkuji za návrh, bohužel toto není řešení pomocí Nette, ačkoliv je rychlejší, nedrží se tím kód na jednom místě
rád bych se podělil o své řešení, snad to někomu pomůže:
<?php
use Nette\Application\IRouter;
class RouteUrl extends \Nette\Application\Routers\Route //implements IRouter
{
private $redirectMap = [];
private $matchedItem;
/**
* new RouteUrl('link1', 'link2');
* new RouteUrl([
* 'link1' => 'link2',
* ...
* ]);
*
* @param type $sourceUrl
* @param type $destinationUrl
* @throws Nette\InvalidArgumentException
*/
public function __construct($sourceUrl, $destinationUrl = null)
{
if (is_array($sourceUrl)) {
$this->redirectMap = $sourceUrl;
} else {
if (!$destinationUrl) {
throw new Nette\InvalidArgumentException('Invalid parameters');
}
$this->redirectMap[$sourceUrl] = $destinationUrl;
}
}
public function constructUrl(\Nette\Application\Request $appRequest, \Nette\Http\Url $refUrl)
{
return null;
}
public function getMask()
{
// pro tracy
if (count($this->redirectMap) == 1) {
return key($this->redirectMap);
} else {
return $this->matchedItem;
}
}
public function getDefaults()
{
// pro tracy
return [
'presenter' => 'System:Redirect',
];
}
public function match(\Nette\Http\IRequest $httpRequest)
{
if (!isset($_SERVER['REQUEST_URI'])) {
return null;
}
$requestUri = $_SERVER['REQUEST_URI']; // /test/def/?abraka
$scriptPath = $httpRequest->getUrl()->getScriptPath(); // /test/
$relativeUri = preg_replace('/^' . preg_quote($scriptPath, '/') . '/', '', $requestUri); // def/?abraka
foreach ($this->redirectMap as $matchSourceUrl => $matchDestinationUrl) {
if ($matchSourceUrl == $relativeUri) {
$presenter = 'System:Redirect';
$this->matchedItem = $relativeUri;
return new \Nette\Application\Request(
$presenter,
$httpRequest->getMethod(),
[
'destinationUrl' => urlencode($httpRequest->getUrl()->getBaseUrl() . $matchDestinationUrl),
],
$httpRequest->getPost(),
$httpRequest->getFiles(),
[\Nette\Application\Request::SECURED => $httpRequest->isSecured()]
);
}
}
}
}
dále přidat presenter pro přesměrování:
<?php
namespace SystemModule;
class RedirectPresenter extends \Nette\Application\UI\Presenter
{
public function actionDefault()
{
if (!isset($this->request->parameters['destinationUrl'])) {
throw new \Exception('Missing redirect parameter');
}
$destinationUrl = urldecode($this->request->parameters['destinationUrl']);
$this->redirectUrl($destinationUrl, \Nette\Http\IResponse::S301_MOVED_PERMANENTLY);
$this->terminate();
}
}
v RouterFactory pak stačí
// old URLs
$this->router[] = new RouteUrl('?abc%5Bdef%5D=xyz', 'landing-page-1');
výsledek je potom vidět v Tracy baru
- CZechBoY
- Člen | 3608
To je šílený…
Na co dělat vlastní router když to v pohodě zvládne klasická Route?
Pro starý url je v dokumentaci uveden parametr Route::ONE_WAY, který bys měl
pooužít v kombinaci s Route třídou.
Takže RouterFactory by vypadala nějak takhle
class RouterFactory
{
public static function createRouter(): IRouter
{
$router = new RouteList();
$router[] = new Route('/?abc[x1]=123&def[x2]=456', [
'presenter' => 'LandingPage',
'action' => 'default',
'id' => 1,
], Route::ONE_WAY);
}
}
- Wizzard256
- Člen | 18
to ale neakceptuje vstup jak jsem psal:
$redirectMap = [
'/?abc[x1]=123&def[x2]=456' => '/landing-page-1',
'/?abc[x1]=789&def[x2]=012' => '/landing-page-2',
...
];
tvým řešením by se musely všechny cílové URL přepsat do tvaru
[
'presenter' => 'LandingPage',
'action' => 'default',
'id' => 1,
]
včetně ručního dohledávání všech parametrů presenter, action a id