Yii Url Manager Help. Please

Hi guys,

I want to write some rule in the URLmanager and achieve the following goal:


'WEBROOT/uploads/avatar/1/xunkown.jpg'  => 'WEBROOT/site/download?path=/avatar/1/xunkown.jpg&filename=xunkown.jpg'

I want this effect for all files underneath the uploads folder…

Is there a way to do so? The first part is simply the location of the file. I understand that the filename part could be potentially hard. If that’s the case, at least we can redirect the URL to


WEBROOT/site/download?path=/avatar/1/xunkown.jpg

?

I’ve been testing for hours with no luck :frowning:

Thanks so much for your help.

Hi jzhong05, welcome to the forum.

So you want the user to access the file ‘WEBROOT/upload/avatar/1/xunknown.jpg’ by the url of ‘WEBROOT/site/download?path=/avatar/1/xunknown.jpg’, right? Then I think what you have to do is just to write actionDownload method in siteController. There seems to be nothing to do with the url manager.




public function actionDownload($path, $filename)

{

    $filePath = Yii::getPathOfAliad('webroot') . '/upload' . $path;

    Yii::app()->request->sendFile($filename, file_get_contents($filePath));

}



Hi,

Thanks for your help. But that’s not what i want. I have lots of static links have format like “WEBROOT/upload/avatar/1/xunknown.jpg” now and everytime user click the download link, they just open directly instead of being downloaded. So I wrote a download action and now I need to make sure everytime user click the link like “WEBROOT/upload/avatar/1/xunknown.jpg”, they actually go to “WEBROOT/site/download?path=/avatar/1/xunknown.jpg”, so the code in the actionDownload could run.

Thanks :slight_smile:

So you click on ‘upload’ and you go to ‘download’? If the link is hard coded as above, then ‘/avatar/1/xunknown.jpg’ is the ONLY img they will see, with the description given so far.

In order to ‘see’ an img, it HAS to be sent (ie; downloaded) to your computer.

A simple answer to what you have said and what has been writen might be the following:

In the site controller




public function actionDownload($path) {

   $this->redirect('site/upload', 'path'=>$path;

}


public function actionUpload($path) {

   //Send it

}



Other questions would be:

  • Why ‘hard-code’ the links?

  • What happens when you move the site from dev machine to production?

  • What does ‘WEBROOT’ mean in relation to the site root? You’re telling us that under the site root directory, you have a subdirectory called ‘WEBROOT’.

  • In "WEBROOT/upload/avatar/1/xunknown.jpg", what does the 1 represent?

I would refactor your links to use:

  • <a href="<php echo Yii::app()->baseUrl.’/upload/avatar/’.Yii::app()->user->id.’/’.<image name here>.’"’; ?>

When you finally send the img, I have seen a way of using the php header() to reply like a .php file IS a .jpg file.

I’m not trying to put you down in any way, it’s just that what you are discribing you want/need to do seems a little strange. However, if there is a good reason then let’s figure out how to do what you wnat :)

Could you show us your view code for the avatar image and its download link? How do you construct <img> and <a> tags?

Hi,

The download link right now is simply a link to the image like <a href="Websitelink/uploads/../../someimage.jpg">Image name</a>

So if the user clicks the link now, they just open the image directly. I wrote an action in my controller so i want the server send them the image so they can actually download it directly. That’s why I need to actually open the download link when users click the image href link. And I think we can do that in URLManager in .htaccess?

Thanks,

Well, please show us the exact code that you use for that link.

Do you literally have those links as ‘static’ ‘hard-coded’ strings?

Hi, we are a forum that user can post stuff. so I can’t go through thousands of thousands of posts and revise all those uploaded files links…

The exact code I use for that link is simply <a href="filePath">filename</a>

I just want the effect that when user click that file link, it actually goes to a send file action link…

like this: domain/site/download?path=/avatar/1/xunkown.jpg&filename=xunkown.jpg

Hi, thanks for your help,

we are a forum that user can post stuff. so I can’t go through thousands of thousands of posts and revise all those uploaded files links…

The exact code I use for that link is simply <a href="filePath">filename</a>

I just want the effect that when user click that file link, it actually goes to a send file action link…

like this: domain/site/download?path=/avatar/1/xunkown.jpg&filename=xunkown.jpg

I don’t get you.

This is not what I mean by code, it’s just an output.

What data do you have for the avatar image in the database? Isn’t it just a string that represents a jpeg file name like “unknown.jpg”?

I think you are constructing the link in your code, retrieving the file name from the db, like:




$fileName = $data->avatar_file_name;

$filePath = Yii::getPathOfAliad('webroot') . '/upload' . $fileName;

echo CHtml::link($fileName, $filePath);



That’s what I have in the code. I don’t output the image from the database. The wysiwyg editor simply print out the image path.

So I simply want to redirect that output link to the download link I want.

Well, I thought that it will be the easiest way to reconsider the way you create the download link.

Probably you can tweak .htaccess and url rules to route ‘WEBROOT/uploads/1/avatar/some.jpg’ to ‘WEBROOT/site/download?path=1/avatar/some.jpg’. But I think it will bring you another bigger problem.

You have ‘WEBROOT/uploads/1/avatar/some.jpg’ for ‘href’ attribute of <a> tag of the download link. But I guess you have to set the same url (‘WEBROOT/uploads/1/avatar/some.jpg’) as ‘src’ attribute of <img> tag somewhere else in your forum page. Am I right? Then you will not want both of them to be routed to ‘WEBROOT/site/download?path=1/avatar/some.jpg’.

Yes you are right…I never thought of this…

It’s just i’m using redactor now…


$array = array(

	'filelink' => Yii::app()->request->hostInfo."/uploads/questions/".$model->owner_id."/".$date.$filename,

	'filename' => $_FILES['file']['name']

);


echo stripslashes(json_encode($array));

That’s like what they do now… I really don’t know how can I make it different…have you ever used redactor before?

thanks so much for your help.