my model code:
public $image;
return array(
array('filename', 'required'),
array('image', 'file', 'types'=>''),
array('filename', 'length', 'max'=>11),
array('id, filename', 'safe', 'on'=>'search'),
);
my view code:
<?php echo CHtml::activeFileField($model, 'image'); ?>
my controller code:
$model = new TblUpload;
$model->attributes=$_POST['TblUpload'];
$img = CUploadedFile::getInstance($model,'image');
if($img->saveAs(Yii::app()->basePath.'/../images/'.$img))
{
$model->filename = $img;
$model->save(false);
}
}
$this->render('uploadfile',array('model'=>$model));
}
hi friends using this code i am able to upload all types of files like images and documents, but i am unable to upload videos.... i have changed my php.ini file max_upload_size also...
In your form view, have you set the enctype for the form?
$form = $this->beginWidget(
'CActiveForm', array(
'id' => 'my-form',
'htmlOptions' => array(
'enctype' => 'multipart/form-data'
),
)
);
It could also possibly be the path to the folder you are trying to upload to doesn't exists or is incorrect. Try using getcwd(), eg:
$model->my_image->saveAs(getcwd()."/uploads/myfile.jpg");
This is most likely the problem, your path in your code above is:
if($img->saveAs(Yii::app()->basePath.'/../images/'.$img))
The basepath and followed by the ../ probably wrong unless you areally are trying to upload in the directory before your root?
Finally i sorted out how to upload images...
Here is my controller code.....
public function actionUploadfile()
{
$model = new TblUpload;
if(isset($_POST['TblUpload']))
{
$model->image=CUploadedFile::getInstance($model,'image');
if($model->save())
{
$model->image->saveAs('/wamp/www/fileupload/images/'.$fileName);
}*/
$model->attributes=$_POST['TblUpload'];
$img = CUploadedFile::getInstance($model,'image');
if($img->saveAs(Yii::app()->basePath.'/../images/'.$img))
{
$model->filename = $img;
$model->save(false);
}
}
$this->render('uploadfile',array('model'=>$model));
}
this was the place i got mistaken... but now i am using uploadify extension to upload all kinds of files and edited it to be used for multiple upload at a time
Related
In yii2 project I have my own file structure setup. Anything uploaded will get saved as a file type. I can get the file dimensions using the file uploaded in the temp folder by yii2. Using those dimensions I set my own width and height and compare them. If the height and width is more than what I have declared It has display an error message in the form. Which I am unable to do it.
My Active Form
<div class="company-form">
<?php
$form = ActiveForm::begin([
'action'=>['company/logo', 'id'=>$model->company_id],
'validateOnSubmit' => true,
'options' =>
['enctype' => 'multipart/form-data','class' => 'disable-submit-buttons','id'=> 'companyLogoForm'],
'fieldConfig' => [
'template' => "<div class=\"row\">
<div class=\"col-xs-6 margin-top-8\">{label}</div>\n<div class=\"col-xs-6 text-right\">{hint}</div>
\n<div class=\"col-xs-12 \">{input}</div>
</div>",
],
]); ?>
<?= $form->errorSummary($model, $options = ['header'=>'','class'=>'pull-left']); ?>
<?= $form->field($model, 'company_name')->hiddenInput(['maxlength' => true])->label(false) ?>
<?= $form->field($file, 'file')->fileInput([])->label(Yii::t('app', 'Attach Logo'),['class'=> 'margin-top-8']) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Save') : Yii::t('app', 'Save'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary','data' => ['disabled-text' => 'Please Wait']]) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
My Controller Action
public function actionLogo($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$file = new File;
$file->load(Yii::$app->request->post());
$a = UploadedFile::getInstance($file,'file');
$size = getimagesize($a->tempName);
$maxWidth = 500;
$maxHeight = 500;
if ($size[0] > $maxWidth || $size[1] > $maxHeight)
{
$model->addError('file', $error = 'Error Message');
if($model->hasErrors()){
return ActiveForm::validate($model);
}
}
$file->file = UploadedFile::getInstance($file,'file');
$file->file_name = $file->file->name;
$file->file_user = Yii::$app->user->id;
$file->file_type = 1;
if($file->save()){
$file->file_path = Files::getFilePath($file->file_id);
$validDir = $file->file->createFileDir($file->file_path, $file->file_id);
if($validDir){
$file->file->saveAs($file->file_path, false);
if($file->save()){
$model->company_file = $file->file_id;
$model->save();
return $this->redirect(['index']);
}
}
}
}
}
How do I add error message in the controller and pass that to display on my form on the modal box.
Note: my form is displayed on the modal box.
Thank you!!
You should handle the file processing in your model - or even better, create a specific UploadForm model for this purpose.
In that case you can use File Validation or a custom validator to set errors during model validation.
The built-in yii\validators\FileValidator gives you plenty pf validation rules out of the box.
This is actually pretty well explained in the documentation: Uploading Files
See also the documentation for FileValidator
Example for validating an uploaded image file:
namespace app\models;
use yii\base\Model;
use yii\web\UploadedFile;
class UploadForm extends Model
{
/**
* #var UploadedFile
*/
public $imageFile;
public function rules()
{
return [
[['imageFile'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg'],
];
}
public function upload()
{
if ($this->validate()) {
$this->imageFile->saveAs('uploads/' . $this->imageFile->baseName . '.' . $this->imageFile->extension);
return true;
} else {
return false;
}
}
}
Try this validation rule
['imageFile', 'image', 'minWidth' => 250, 'maxWidth' => 250,'minHeight' => 250, 'maxHeight' => 250, 'extensions' => 'jpg, gif, png', 'maxSize' => 1024 * 1024 * 2],
I am using
$this->widget(
'CMultiFileUpload',
array(
'model' => $model,
'attribute' => 'Image',
'accept' => 'jpg|gif|png|doc|docx|pdf',
'denied' => 'Only doc,docx,pdf and txt are allowed',
'max' => 4,
'remove' => '[x]',
'duplicate'=>'Already Selected',
)
);
for upload multiple images , i save all images into database.But i want to download that saved image.
public function uploadMultifile ($model, $attr, $path)
{
/*
* path when uploads folder is on site root.
* $path='/uploads/doc/'
*/
if ($sfile = CUploadedFile::getInstances($model, $attr)) {
foreach ($sfile as $i => $file) {
$fileName = "{$sfile[$i]}";
$formatName=time() . $i . '_' . $fileName;
$file->saveAs(Yii::app()->basePath . '/' . $formatName);
$ffile[$i] = $formatName;
}
return ($ffile);
}
}
I want to provide link to image and download automatically.
echo CHtml::link($data->image);
Any help appreciated.
I tried
public function actionDownloadImage()
{
$model = $this->loadModel($_GET['id']);
$fileDir = Yii::app()->basePath.'/Img/';
Yii::app()
->request
->sendFile(
$model->image,
file_get_contents($fileDir.$model->image),
$model->image
);
}
but give error..
You haven't defined folder path to save image in uploadMultifile() action. So you can't get your desired images from "Img" named folder. You have to make following changes in uploadMultifile() action:
public function uploadMultifile ($model, $attr, $path)
{
/*
* path when uploads folder is on site root.
* $path='/uploads/doc/'
*/
if ($sfile = CUploadedFile::getInstances($model, $attr)) {
foreach ($sfile as $i => $file) {
$fileName = "{$sfile[$i]}";
$formatName=time() . $i . '_' . $fileName;
$file->saveAs(Yii::app()->basePath . '/Img/' . $formatName); // specify folder path where you have to save image
$ffile[$i] = $formatName;
}
return ($ffile);
}
}
Hope this helps.
I am using TbActiveForm. I want upload multiple file at a time, Please help me.Thanks
In your TbActiveForm you have to use a widget for multiple file upload. You could write it yourself or use widget like CMultiFileUpload.
Here is reference for CMultiFileUpload.
Example for view:
<?php
$this->widget('CMultiFileUpload', array(
'model'=>$model,
'attribute'=>'photos',
'accept'=>'jpg|gif|png',
'options'=>array(),
'denied'=>'File is not allowed',
'max'=>10, // max 10 files
));
?>
Example for controller:
public function actionCreate()
{
$model = new Photo;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
$type = isset($_GET['type']) ? $_GET['type'] : 'post';
if (isset($_POST['Photo'])) {
$model->attributes = $_POST['Photo'];
$photos = CUploadedFile::getInstancesByName('photos');
// proceed if the images have been set
if (isset($photos) && count($photos) > 0) {
// go through each uploaded image
foreach ($photos as $image => $pic) {
echo $pic->name.'<br />';
if ($pic->saveAs(Yii::getPathOfAlias('webroot').'/photos/path/'.$pic->name)) {
// add it to the main model now
$img_add = new Photo();
$img_add->filename = $pic->name; //it might be $img_add->name for you, filename is just what I chose to call it in my model
$img_add->topic_id = $model->id; // this links your picture model to the main model (like your user, or profile model)
$img_add->save(); // DONE
}
else{
echo 'Cannot upload!'
}
}
}
if ($model->save())
$this->redirect(array('update', 'id' => $model->id));
}
$this->render('create', array(
'model' => $model,
));
}
Source reference.
I want to UPDATE record without losing the File that i have uploaded. Below is my create action.
public function actionCreate()
{
$model = new Page;
if (isset($_POST['Page']))
{
$model->attributes = $_POST['Page'];
$model->filename = CUploadedFile::getInstance($model, 'filename');
if ($model->save())
{
if ($model->filename !== null)
{
$dest = Yii::getPathOfAlias('application.uploads');
$model->filename->saveAs($dest . '/' . $model->filename->name);
$model->save();
}
$this->redirect(array('view', 'id' => $model->id));
}
}
$this->render('create', array(
'model' => $model,
));
}
In yii, update method is designed to update the values that you are posting from your form. It will not update all Model properties.
For suppose, your Page model has 4 model properties, assume all are mandatory.
title
description
keywords
image
Since you don't want to update image field, you can make it non mandatory field by setting scenario for image field in your Page model rules.
class Page extends CActiveRecord
{
/*
Coding
*/
public function rules()
{
return array(
array('title, description,keywords', 'required'),
array('image', 'file', 'types'=>'jpg, png'),
array('image', 'required', 'on' => 'insert'),
// => You need image field to be entered on Create, not on Update
.................
}
}
So, Show file input in your form on Create, Hide on Update action so that image field won't submit.
//Your page form
<?php if($model->isNewRecord):?>
echo $form->labelEx($model, 'image');
echo $form->fileField($model, 'image');
echo $form->error($model, 'image');
<?php endif;?>
Since your are using Yii-2 you can use skippOnEmpty validator for the same.
I need to redirect a user to an error page (view/error/403.phtml) from within the Module.php of a module called Admin when a user is not allowed to access the specific resource. I have been searching for a solution to this, but so far had no success. The best I found was this question, the accepted answer to which doesn't work for me (and I currently cannot add comments to the linked question because I don't have the required reputation level) - the page is displayed as if there is no redirect at all and the user is allowed to access it. I have tried to replace the redirecting code with a simple die; to test if the isAllowed() is working properly, and it correctly shows a blank page, so the problem lies in the redirection itself.
Relevant code in Module.php is:
public function onBootstrap(MvcEvent $e)
{
$this->initAcl($e);
$eventManager = $e->getApplication()->getEventManager();
$eventManager->attach('route', array($this, 'checkAcl'));
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
}
public function checkAcl(MvcEvent $e)
{
// ...
if (!$this->acl->isAllowed($userRole, $controller, $privilege))
{
$response = $e->getResponse();
$response->setHeaders($response->getHeaders()->addHeaderLine('Location', $e->getRequest()->getBaseurl() . '/error/403'));
$response->setStatusCode(403);
$response->sendHeaders();
}
// ...
}
module.config.php
'view_manager' => array(
'display_exceptions' => true,
'exception_template' => 'error/403',
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/admin_layout.phtml',
'error/403' => __DIR__ . '/../view/error/403.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
'Admin' => __DIR__ . '/../view',
),
'strategies' => array(
'ViewJsonStrategy',
),
),
If I add the line
throw new \Exception($translator->translate('Access denied'));
after the code for redirection, I do get redirected to URL http://[servername]/error/403, but the contents of the page is, instead of my custom 403.phtml, a styled (with layout) 404 error page, stating that "The requested URL could not be matched by routing."
A better way to achieve what you want is to trigger a dispatch.error event in your checkAcl function rather than trying to do a redirect. You can then handle this event and display the 403 page.
To trigger the event:
if (!$this->acl->isAllowed($userRole, $controller, $privilege))
{
$app = $e->getTarget();
$route = $e->getRouteMatch();
$e->setError('ACL_ACCESS_DENIED') // Pick your own value, would be better to use a const
->setParam('route', $route->getMatchedRouteName());
$app->getEventManager()->trigger('dispatch.error', $e);
}
Then in your onBootstrap add a listener for the dispatch.error event:
use Zend\Mvc\MvcEvent;
...
$eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, <any callable>, -999);
In your callback for dispatch.error event you just attached to:
$error = $event->getError();
if (empty($error) || $error != "ACL_ACCESS_DENIED") {
return;
}
$result = $event->getResult();
if ($result instanceof StdResponse) {
return;
}
$baseModel = new ViewModel();
$baseModel->setTemplate('layout/layout');
$model = new ViewModel();
$model->setTemplate('error/403');
$baseModel->addChild($model);
$baseModel->setTerminal(true);
$event->setViewModel($baseModel);
$response = $event->getResponse();
$response->setStatusCode(403);
$event->setResponse($response);
$event->setResult($baseModel);
return false;