Viewing of PDF present in code - Yii - pdf

I have placed a PDF file in folder /protected/uploads. I want to view this file on click of hyperlink. But i am facing the error and the PDF is not being displayed.
Error
Error 404<br/>
Unable to resolve the request "uploads/viewPdf".
Here is what i have done to view the file.
main.php
'urlManager'=>array(
'urlFormat'=>'path',
'rules'=>array(
'uploads/<filename:[a-zA-Z]+\.pdf>' => 'Upload/viewPdf',
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
),
),
UploadController
class UploadController extends Controller
{
public function actionIndex()
{
$this->render('index');
}
public function actionViewPdf()
{
$filename = $_GET['filename'] . '.pdf';
$filepath = '/uploads/Tutorial' . $filename;
if(file_exists($filepath))
{
// Set up PDF headers
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($filepath));
header('Accept-Ranges: bytes');
// Render the file
readfile($filepath);
}
else
{
// PDF doesn't exist so throw an error or something
}
}
}
and the link in the form. I would like to mention here is that the form belong to other controller not the upload controller
_form
echo CHtml::link(
'pdf',
Yii::app()->createUrl('/uploads/viewPdf', array('filename' => 'Tutorial')) ,
array('class'=>'btnPrint btn btn-danger','target'=>'_blank'));

echo CHtml::link(
'pdf',
Yii::app()->createUrl('/uploads/viewPdf', array('filename' => 'Tutorial')) ,
array('class'=>'btnPrint btn btn-danger','target'=>'_blank'));
You do NOT have a controller called uploads, you do have one called upload, this is the problem. Also I believe you should not use the first / when using create url. Try using
echo CHtml::link(
'pdf',
Yii::app()->createUrl('upload/viewPdf', array('filename' => 'Tutorial')) ,
array('class'=>'btnPrint btn btn-danger','target'=>'_blank'));
One more thing, I am not sure that the file resolves to the correct path when creating
$filepath = '/uploads/Tutorial' . $filename;
The controller is in a folder, why would /uploads/ go to the correct folder from there? Try using a full path, or detect the path with dirname(FILE) and take it from there.
Just to also make sure. You create a link that will look something like this:
/uploads/Tutorial.pdf this will get resolved to /protected/uploads/TutorialTutorial.pdf, is that the functionality you want?

Most of what Mihai said is true and should be fixed. In addition try changing your controller to include the $filename as a required parameter. This will throw a 404 if $filename is not present in the url.
public function actionViewPdf($filename){
$filename .= '.pdf';
...
}

Related

RenderPartial from Modules for index.php

I'm trying to call a view in my modules/moduleName/views/ab/_temp from my index.php file. but cant seem to get it to work.
in my side controller i have this
public function actionIndex()
{
$model=new Ab;
$this->render('index',array(
'model'=>$model
));
}
in my views/site/index.php
<?php $this->renderPartial('//modulesName/views/ab/_temp', array('model'=>$model)); ?>
i'm getting this error
include(Ab.php): failed to open stream: No such file or directory
If your controller is not inside the module you should import the path to your main.php file:
'import'=>array(
...,
'application.modules.moduleName.*',
'application.modules.moduleName.models.*',
),

View PDF in Yii

I have PDF stored in a folder, now i want to view it via link on my form page. How will i do it using Yii framework.
echo CHtml::link(
'pdf',
Yii::app()->createUrl('/uploads/Tutorial.pdf') ,
array('class'=>'button','target'=>'_blank'));
The error i am receiving mentioned below, i have also tried by including uploads in allow of controller.
Error
Error 404
Unable to resolve the request "uploads/Tutorial.pdf".
I am using mPDF to generate PDF but i don't know how to view an already generated PDF using Yii.
You need several more things to make this work. You may have already done some of this and not pasted it but here goes...
I'm assuming you've set up your site to use clean URLs with .htaccess by following this tutorial. Now you can add:
in config/main.php, urlMananger section you need a route to a controller class and action method. This tells Yii which controller to use when you go to the URL /uploads/Tutorial.pdf
'urlManager'=>array(
'urlFormat'=>'path',
'showScriptName'=>false,
'rules'=>array(
'uploads/<filename:[a-zA-Z]+\.pdf>' => 'upload/viewPdf', // actionViewPdf Method in UploadController class
// ... all your other rules
),
),
And a controller class, and a method with the same name as in your route above (prepended with action):
class UploadController extends Controller
{
// Put the usual Yii access control stuff here or whatever...
public function actionViewPdf()
{
$filename = $_GET['filename'] . '.pdf';
$filepath = '/path/to/your/pdfs/' . $filename;
if(file_exists($filepath))
{
// Set up PDF headers
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($filepath));
header('Accept-Ranges: bytes');
// Render the file
readfile($filepath);
}
else
{
// PDF doesn't exist so throw an error or something
}
}
}
Then you should be able to use
echo CHtml::link(
'pdf',
Yii::app()->createUrl('/uploads/viewPdf', array('filename' => 'Tutorial')) ,
array('class'=>'button','target'=>'_blank'));
Hope that's helpful.
Well.... are you sure that the uploads folder is available on the server and it is in a location that is link friendly? Yii does not pass everything through it's index.php file, if a file already exists then it just used it like it is. That is why you can access the files in your images or css folder without having a controller for it.
If you are using the normal Yii structure then you should have your "uploads" folder next to your protected folder.
If your uploads folder is not in a web accessible location, use what JamesG told you to. The only change I would to is to the pattern, it only matches letters, you might have other chars in the name too.
Do not add ".pdf" to your link:
Yii::app()->createUrl('/uploads/Tutorial')
in PHP you can print your pdf like this (must be in the actionTutorial):
$mPDF = Yii::app()->ePdf->mpdf();
$mPDF->WriteHTML($this->render('tutorial', array(), true));
$mPDF->Output();
The tutorial is a simply html page that should be rendered into your pdf.
Here you can find the doku to the mpdf Yii extension

Yii - Ajax Get based on drop down selection

I am trying to display the price based on the selection of product from a drop down.
View contains:
<?php $form=$this->beginWidget('bootstrap.widgets.TbActiveForm', array(
'id'=>'plan-form',
'enableAjaxValidation'=>true,
)); ?>
<?php echo $form->dropDownListRow($model, 'plan_id',
$planList, array('id'=>'planid', 'prompt'=>'Select Plan',
'ajax' => array('type'=>'GET',
'url'=> Yii::app()->createUrl('mbr/plan/ajaxGetPrice'),
'update'=>'#price'))); ?>
<div id="price">0.00</div>
<?php $this->endWidget(); ?>
Action:
public function actionAjaxGetPrice()
{
Yii::log("Within AjaxGetPrice");
if (Yii::app()->request->isAjaxRequest)
Yii::log("ajax request");
else
Yii::log("regular request");
//$plan=Plan::model()->findByPk((int) $_GET['plan_id']);
//Yii::log(serializ($plan));
// echo $plan->price;
echo "10";
Yii::app()->end();
}
It is not updating the price. Its not calling the action at all. I looked at the suggestions found in Yiiframework and here and tried those and still no luck.
when I add this to the view
<?php
echo CHtml::ajaxLink(
"Get Price",
Yii::app()->createUrl('mbr/plan/ajaxgetprice'),
array( // ajaxOptions
'type' => 'GET',
'update' => '#price'),
array( //htmlOptions
'href' => Yii::app()->createUrl('mbr/plan/ajaxgetprice')
)
);
?>
I get the response when I click on the link, but it renders a separate page with value "10". I have URLFormat = Path.
What am I doing wrong? Any pointers?
You can also try this as shown
<?php echo CHtml::dropDownList('categories','',
$category,
array('ajax'=>array('type'=>'POST','url'=>CController::createUrl('yourController/GetId'),'update' =>'#data'))
);?>
yourController action
public function actionGetId(){
echo 10;
}
And the div
<div id="data">0.00</div>
I'm not really sure how to do this the Yii way but the following javascript should be useful.
$("#yourdropdownidhere").change(function(){
$.ajax({
url: 'your url here', //(dynamically generated by product item)
type: "get",
success: ajaxSuccessHandler
});
});
function ajaxSuccessHandler(obj) {
$('#price').html(obj);
}
I also suggest sending a JSON object as the response for AJAX requests, so it will have an actual structure. A great blog post on this to check out would be Fully ajax website with Yii
I had the same problem and solved it on the controller that renders the view. If you are using renderPartial assure that the processOutput() option is set to TRUE, otherwise Yii will not attach any Javascript.
If you use render instead of renderPartial it also works.

CCaptcha displaying no image yii

I have a user registration form, in which I am trying to display a Captcha image by using Yii widget CCaptcha, however my image link appears broken,
Controller file:
public function actions()
{
return array(
// captcha action renders the CAPTCHA image displayed on the contact page
'captcha'=>array(
'class'=>'CCaptchaAction',
'backColor'=>0xFFFFFF,
),
);
}
Model File:
public function rules()
{
return array( array('verifyCode','captcha','allowEmpty'=>!CCaptcha::checkRequirements(),'on'=>'insert'),
);
}
And view file:
<?php if(CCaptcha::checkRequirements()): ?>
<div class="row">
<?php echo $form->labelEx($model,'verifyCode'); ?>
<div>
<?php $this->widget('CCaptcha'); ?>
<?php echo $form->textField($model,'verifyCode'); ?>
</div>
<div class="hint">Please enter the letters as shown.
<br/>Letters are not case-sensitive.</div>
<?php echo $form->error($model,'verifyCode'); ?>
</div>
<?php endif; ?>
As a answer provided somewhere I also tried giving the access rules in my controller file as
public function accessRules()
{
return array(
array('allow',
'actions' => array('captcha'),
'users' => array('*'),
),
);
}
But nothing seems to be working.
The problem was with the controller file,it should have been,
public function accessRules()
{
return array(
array('allow',
'actions'=>array('create', 'captcha'),
'users'=>array('*'),
),
}
whereas I had mentioned the action for captcha at the end, which I figured out is not allowed in Yii. All the allow actions for * should be together.
Yii captcha will create a png image. A possible explanation for the broken image link would be a missing GD extension or imagick extension, which can be identified by the presence of the following text in your error.log:
call to undefined function imagecreatetruecolor
For details and fix see "call to undefined function imagecreatetruecolor" error in PHP & pChart

show uploaded image yii

I am new to php and yii. I have a file field in my form to upload images. I use the following code to upload the image using file field.
Code in View:
<?php echo $form->fileField($model,'logo', array('class'=>'input-file')); ?>
<img src="<?php
echo Yii::app()->request->baseUrl.'/protected/uploads/sitelogo/'.$savedvalues['varLogo'];
?>" width="50" height="50" />
<?php echo $form->hiddenField($model,'hiddenfile',
array('value'=>$savedvalues['varLogo'])); ?>
code in controller:
$randnum = rand(0,100);
$home->varLogo = $randnum.$model->logo;
$file= Yii::app()->getBasePath().'/uploads/sitelogo/'.$randnum.$model->logo;
$model->logo->saveAs($file);
The images are uploading fine now. I have saved the uploaded images in protected\uploads\ folder. I am trying to show the uploaded image in edit image section. But the image doesn't display. It Shows failed to load the given url in firebug.
How can i correct this issue?
protected folder is protected for some reason - nobody can access it
if you want to access your pictures move them to public folder (or public/uploaded)
here is .htaccess content for protected
deny from all
EDIT:
of course you can put your files into protected folder(or make uploaded folder not accessible too) if you want some ACL for your users, and then check access, read and output file by your script(class)
in view:
<img src="<?php
echo Yii::app()->request->baseUrl.'/image.php?url=protected/uploads/sitelogo/'.$savedvalues['varLogo'];
?>" width="50" height="50" />
in your controller or class:
if (Yii::app()->session['user_can_access_files']) {
header('Content-Type: image/jpeg');
readfile($_GET['url']);
} else {
Yii::app()->user->loginRequired();
}
Caveat: I'm a total yii noob, so take this w/ a grain of salt :)
I took a similar approach, but have user-specific folders & added a MIME type check.
I upload files in a similar way, then view them with this in the view:
echo '<embed src="/tim_0.5/index.php/files/Getdatafile/' . $modelid . '" width=100% height=400>';
And from my controller I have:
public function actionGetdatafile($id)
{
$model=$this->loadModel($id);
$imgpath = $model->user_id . '/' . $model->filename;
$file=Yii::app()->getBasePath().'/datafiles/'.$imgpath;
if (file_exists($file))
{
$img=getimagesize($file);
header('Content-Type: '.$img['mime']);
readfile($file);
exit;
} else {
echo 'File not found!';
}
}
<b><?php echo CHtml::encode($data->getAttributeLabel('binaryfile')); ?>:</b>
<?php echo CHtml::image(Yii::app()->request->baseUrl.'/upload/'.$data->fileName); ?>
<br />
filename is name of your file which you have stored in upload folder in root directory.
(Yii::app()->request->baseUrl.'/upload/' point to your upload folder which is in your root directory
Hope it works....