Redirect custom rules

Hi,

I got a lot (about 150) of links like this:


<a href="download.php?product=product-cl">CL</a>

I did a mistake using this method to manage the file downlaoding.

Now I want to repair it avoiding to edit more than 150 files so I want to use urlManager to redirect url like this to be managed with a controller; for example ProductController.php::actionDownload().

I just know that I must edit ./config/main.php but what are the rules to be written to manage urls like these and redirect them to a controller/action ?

Thank you sooo much!

Just some hints to get you going:

Adding these rules:




'product/download/<product:\w+>' => 'product/download',// option 1

'download/<product:\w+>' => 'product/download',// option 2



Would generate urls like:




Yii::app()->createUrl('product/download',array('product'=>'my-product'));


//with option 1 you'd get:

/product/download/product/my-product


//with option 2 you'd get:

/download/product/my-product



Both options would redirect to download() action inside product controller:




public function actionDownload($product)

{

   echo $product;

}



Now having all that set, in the old download method(the one handling url like: download.php?product=product-cl ), you’d do a permanent redirect to the new download method from within the product controller, smth like:




$this->redirect(array('product/download','product'=>$_GET['product']),true,301);


//rest of the old code here can be moved in the actionDownload from product controller.



Hope it helps :)

Thank you so much twisted1919!

Anyway I want to make the stuff clear to understand better what you suggested me.

Now my links are like I wrote before:


<a href="download.php?product=product-cl">CL</a>

The download.php file is in the root of the project:




<?php

//Yii::import('application.extensions.forcedownload.*');

require_once("./protected/extensions/forcedownload/forcedownload.php");


$filename=$_GET["product"];




if($filename == "product-cl") $filepath = "./protected/download/cl.pdf";

//here there's a long list of 150 products





$fparts = pathinfo($filepath);

$safename = $filename;

          

$myfd = new forcedownload();

$myfd->setSafename($safename);

$myfd->setFilename($filepath);

$myfd->output();            


?>



Now I want that these links pasted above, will be get automatically by a ProductController that will check for the product through actionDownload() (and I think actionDownload() will contain the list of if statement for the right file) without modifying all the view pages that show the product to the users: they will stay with the <a>…</a> link.

The problem is that the rule must work with “download.php?product=” because I can’t modify all the links: how can I do this?

Will be the links taken automatically and automatically passed to actionDownload() ?

Thank you, thank you, thank you!

Sorry for this late reply, i was kind of busy :)

Back to your issue, modify the file download.php like:




<?php

$filename=isset($_GET["product"])?$_GET["product"]:null;          

header('HTTP/1.1 301 Moved Permanently');

header("Location:/product/download/".$filename);

exit;

?>



Add this rule to your url rules:




'download/<product:\w+>' => 'product/download',



Now, in the product controller, have:




public function actionDownload($product)

{

   Yii::import('application.extensions.forcedownload.*');

   if($product== "product-cl") $filepath = "./protected/download/cl.pdf";

   //here there's a long list of 150 products





   $fparts = pathinfo($filepath);

   $safename = $filename;

          

   $myfd = new forcedownload();

   $myfd->setSafename($safename);

   $myfd->setFilename($filepath);

   $myfd->output();     

}



All the above code will work with your current link format, meaning that when somebody will access a url like:

download.php?product=product-cl it will be taken to the download.php file, this file will add a header to let the browser know the resource has been permanently moved and will redirect the user to your new url for download: /download/product-cl.

Once this new url is requested, it is handled by Yii and will basically download the file.

All the above is for backward compatibility, from the moment you make these changes, you will generate any new download url using: Yii::app()->createUrl(‘product/download’,array(‘product’=>$name));

Just to make it clear, you will still have your old download urls in the website (download.php?product=1234) but that file will exists there only for compatibility reasons and in the future, when you get rid of the products which directly links to that file, you can safely remove the file too and only use the new Yii download method.

Hope it was clear enough.

if you have configuration of path-style urls without script name (requires simple htaccess) - then every request not pointing to existing file will be passed to front controller (index.php).

In this case you can simply delete download.php file (move its logic to controller/action) and add routing rule:

‘download\.php’ => ‘product/download’,

this should route every request to ‘download.php’ file to your action. get params should be passed by default.

hope this helps :)