actionDownload for my download link

can anyone give me an example of actionDownload method for my download link? i seek for the best practice of that :D

what user will download? csv file, generated pdf, some model info, file or something else. Your question is too generic, so better reformulate it, or you will not get any answers.

thanks for your reply, Ivica :D

i am a newbie. i have a download method from my senior programmer. but i think this is not best way. this is the action:


public function actionDownloadFiles($id)

	{

		$material = Materials::model()->findByPk($id);

		$src = "files/material/".$material->id.".pdf";

		if(@file_exists($src)) {

			$path_parts = @pathinfo($src);

			//$mime = $this->__get_mime($path_parts['extension']);

			header('Content-Description: File Transfer');

			header('Content-Type: application/octet-stream');

			//header('Content-Type: '.$mime);

			header('Content-Disposition: attachment; filename='.basename($src));

			header('Content-Transfer-Encoding: binary');

			header('Expires: 0');

			header('Cache-Control: must-revalidate, post-check=0, pre-check=0');

			header('Pragma: public');

			header('Content-Length: ' . filesize($src));

			ob_clean();

			flush();

			readfile($src);

		} else {

			header("HTTP/1.0 404 Not Found");

			exit();

		}


	}

now i want to know what is the best practice for the same process

that’s an actionDownloadFiles in controller right? and then how about the link in view? Any help would be greatly appreciated.

Hi, I advice you to create an action in your controller. In this action you must have your http header like :




public function actionDownloadFile($id,$file_field,$file_name)

  {

    $model=$this->loadModel($id);

    header('Pragma: public');

    header('Expires: 0');

    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');

    header('Content-Transfer-Encoding: binary');

    //header('Content-length: 1665');

    header('Content-Type: text/html');

    header('Content-Disposition: attachment; filename='.$file_name);

              

    echo stream_get_contents($model->$file_field,-1,0);     

  }



then in your echo, you put your file. For example, my file is in database so I give the model field which contains the binary file. If the file is in on server you can use php simply function to print it.

In parameter I have id, file_field, and file_name, you can adapte it depending on what you want to do exactly.

the way/link to call this action is like :




/your/ii/app/yourModelName/downloadFile?id=my_id&file_field=my_file_field&file_name=my_file_name



or in your column part of your CDetailsView something like :




array('name'=>'column_name','type'=>'raw',

      'value'=>function($data) {return CHtml::link('name_of_the_link',

        array('yourModelName/downloadFile',

          'id'=>$data->id,

          'file_name'=>'name_of_the_file_which_will_be_downloaded',

          'file_field'=>'the_file_field_name_in_model'));}),



or in your CGridView column part:




array(

      'class' => 'CButtonColumn',

      'template'=>'{download}',

      'buttons'=>array(

      'download'=>array(

      'label'=>'download',

      'url'=>'"downloadFile?id=".$data->id."&file_field=the_file_field_name_in_model&file_name=name_of_the_file_which_will_be_downloaded"',

      'imageUrl'=>"/your_yii_app/images/an_image.png",

    )))



The best thing to do is to put this function in a global controller, like "MyController" in order to all controllers can benefit of that.

Do you want to develop "Export" record type functionality?

I mean that when click on Download link at that time all records will be save into CSV file like that??

thanks Zugluk for your answer.i will try it first…but can i ask you about file_name?




...file_name=name_of_the_file_which_will_be_downloaded



which that called file_name?because the file in file_field is too many.sorry if i make a mistake ;D

In my example,

file_name will be the name which will be given to the file that the user will download. "the_file_downloaded.txt" for example.

file_field is the column database name which contains the file in bytea format for me… blob in mysql I guess or binaries format.