Yii: Keep files uploaded after validation fail? - php

If I upload a file with YII and another rule fails, then the user has to pick the file again. What is the easiest way to avoid this?
For example, I have a rule that the title must be 20 characters at most. The user types in 21 letters. He chooses a file to upload. When the user is returned to the page, the file is no longer there and he must choose it again, and effectively upload it again. This is very frustrating, especially now when the user will be required to upload up to ten files.
I know Drupal works like this. If you upload and other rules fail, the files appear as screenshots when you return to the form. How can I get the same functionality on YII?
UPDATE
If I could get that requirement covered with this extension and not require that the user presses start upload, I would be home free

The original plugin that xupload wraps, there is an additional callback option you could use: .done().
In the xupload wiki, the way to access those additional options would be this way:
<?php
$this->widget('xupload.XUpload', array(
// ... other attributes
'options' => array(
//This is the submit callback that will gather
//the additional data corresponding to the current file
'submit' => "js:function (e, data) {
var inputs = data.context.find(':input');
data.formData = inputs.serializeArray();
return true;
}"
),
));
?>
Source
You could probably just change the submit part to done, and let that save the URL/path of the uploaded file to a temporary hidden field, and move your validation to that hidden field instead, so the user does not have to re-upload a file again.
I moved away from this plugin to the coco uploader as it was easier to implement.

You could enable client side validation and AJAX validation. So your regular attributes will be validated before the form is sent and the file gets uploaded.

You can do it with session.
In your controller
// Here I have taken Users as model. you should replace it as your need.
$model=new Users;
if(isset($_POST['Users']))
{
$model->attributes=$_POST['Users'];
//save file in session if User has actually selected a file and there weren't any errors.
if(isset($_FILES['Users']) && $_FILES['Users']['error']['image'] == 0){
Yii::app()->session['image'] = $_FILES['Users'];
}
if(isset(Yii::app()->session['image']) && !empty(Yii::app()->session['image'])){
$model->image = Yii::app()->session['image'];
$model->image = CUploadedFile::getInstance($model,'image');
}
if($model->save())
{
if(!empty($model->image)){
$model->image->saveAs(Yii::app()->basePath.'/images/'.time()."_".$model->image->name);
unset(Yii::app()->session['image']);
//File has successfully been uploaded.
}
// redirect to other page.
}
}
else{
// remember to unset the session variable if it's a get request.
unset(Yii::app()->session['image']);
}
And in your view file
//Your form fields
//This is to show user that he has already selected a file. You could do it in more sofisticated way.
if(isset(Yii::app()->session['image']) && !empty(Yii::app()->session['image'])) {
echo "<label>".Yii::app()->session['image']['name']['image']."</label><br>";
}
//File uplaod field.
//More form Fields.
Hope that helps.

Related

How to upload default picture if user delete the picture?

So, i want to make if user click the delete button the picture profile will be user.jpg (this is default picture).
enter image description here
here is my controller :
public function update()
{
$fileimg = $this->request->getFile('img');
$oldimg= $this->request->getVar('oldimage');
$defaultimg= $this->request->getVar('defaultimage');
if ($fileimg == 'user.jpg') {
$uploadImg = $defaultimg;
}
if ($fileimg->getError() == 4) {
$uploadImg= $oldimg;
} else {
$uploadImg = $fileimg->getRandomName();
$fileimg->move('img/', $uploadImg);
if ($oldimg != 'user.jpg') {
unlink('img/' . $oldimg);
}
}
When i click delete button image the image will be user.jpg and then i click button upload but the image wont change to user.jpg, but always showing the old picture.
sorry for bad english.
How about think like this:
Default picture is not a data which user is willingly save to database. It's rather a placeholder. Thinking further, it can be handled in the views. If user profile picture is not set or exists, show default picture. To prevent typing manually you can make it a global data or a config value or a constant. But the key is it is a placeholder, not a data.
Happy coding...
Write the image name in a database somewhere, usually in the user profile table. It will make your life much easier, and you'll be able to access it all the time. Then in your model, you'll be able to see if there is no image and return the default image.
I am not sure what your getRandomName() is doing, but some hash function (sha1, md5...) are good enough for creating a file name to avoid possible name collisions.

How to validate a form and uploaded file seperate in the same method

I'm trying to understand uploading files in laravel for a project I'm working on.
Sadly I failed when trying to achieve what I had in mind.
When a form is submitted you get to a site where all your inputs are displayed so you can check them again. So the form data has already been validated to this point.
On this site is also an input button to upload a file.
This means that both will go through the same controller method to be displayed after the validation is successful.
Problem here is that, even though the validation of the form works perfectly, I don't know how to validate the file.
Here you can see the store-method:
public function store(ValidateFormData $request, ValidateUploadedFile $requestFile, $param = '')
{
$validated = $request->validated();
$formData = $request->all();
if ($requestFile->hasFile('file')) {
$file = $requestFile->file('file');
// call to $requestFile/validate the uploaded file
}
return view('/validation', compact('formData'));
}
EDIT
I just need the file to be a pdf/postscript file and successfully uploaded.
This is the rule I have in ValidateUploadedFile:
public function rules()
{
return [
'datei' => 'required|file|mimes:pdf,ps',
];
}
I really hope someone can help me.
Please do not link any of the Laravel documentation, believe me, I've seen way to many sites about this topic but still don't quite get it.

Something wrong with Codeigniter Callback validation

So I am creating a web app, it has this upload form where you can upload android APKs, this part of upload form is specifically for uploading a revised version of the old APK(In others words new version of the application).
So I am doing all this in PHP, using CodeIgniter 2.x
Since user is uploading a new version of old Application, I want the website to make sure the application being uploaded for this old application by user has same package name (Android Package file name) e.g com.example.something
When the file upload is initiated, the file is parsed and the package name is put into the database, and a random generated hash of this file is stored in the session data as 'new_app_hash', the random hash of old file is in hidden input field called 'app_id'.
Now coming to the code:
My controller has this in place to do the callback thing for app_id, and compare its information with 'new_app_hash' which is in the session.
So, this callback is mainly for getting row information where the hash is 'app_id' and 'new_app_hash' in my database table, then compare the package names.
$app_id = $this->input->post('app_id',TRUE);
if($app_id!='0'){ //only if app_id is not 0, else I dont want this to happen
$this->form_validation->set_rules('app_id','New Package','required|callback_packagerevname');
}
Model function used in callback:
public function check_checkpackagerevname($app_id,$sessionhash){
if($app_id!='0'){
$old_package = $this->getPackageInfo($app_id);
$new_package = $this->getPackageInfo($sessionhash);
if($old_package['package_name']==$new_package['package_name']){
///ok fine they are same, return true.
return TRUE;
}else{
return FALSE;
}
}else{
return TRUE;
}
}
GetPackageInfo():
public function getPackageInfo($hash){
$this->db->select('*');
$this->db->from('appstore_packages');
$this->db->where('hash',$hash);
$query = $this->db->get();
return $query->row_array();
}
My callback is as follows:
function callback_packagerevname($app_id){
$sessionAppHash = $this->session->userdata('new_hash_app');
$checking = $this->storeM->check_checkpackagerevname($app_id,$sessionAppHash);
if($checking==TRUE){
return TRUE;
}else{
$this->form_validation->set_message('packagerevname','The uploaded APK must have same package name as the parent app that you are trying to upload.');
return FALSE; ////// new apk doesnt have same package name.
}
}
I have tried checking if the form_validation rule is working, when i add some other sort of rule like greater_than[0] it does show me errors, but the callback doesn't work when form is submitted, though the callback function seems to work fine, when i visit it directly from the URL, with the 'new_app_hash' set in the session and putting app_id in URL, it does return true or false accordingly.
What could be wrong?
P.S If the question is a little confusing please comment, I am working on the project for like past 12 hours continuously, so I am a little you know. :P
Edit: Ok it seems 12 hours really had it on me.
Thanks to praveen, I had named the callback method wrongly,
instead of :
function callback_packagerevname($app_id){
}
It obviously should have been:
function packagerevname($app_id){
}
You dont need callback_functionname as callback event just remove callback_ and will work fine...
function packagerevname()
{
$app_id = $this->input->post('app_id');
//so on....
}
you can use set flash data
/* $this->form_validation->set_message('checkpackagerevname',
'The uploaded APK must have same package name as the parent app that you are trying to upload.'); */
$this->session->set_flashdata('checkpackagerevname',
'The uploaded APK must have same package name as the parent app that you are trying to upload.');
and can print
echo $this->session->flashdata('checkpackagerevname');
for more visit
https://ellislab.com/codeigniter/user-guide/libraries/sessions.html

Determining if a file was submitted with codeigniter

I basically have an edit profile page that along with other fields has a option to upload a picture. Now the problem I have is determining wether or not they submitted a file or left it blank(default).
My current code:
if($this->input->post('user_pic') === FALSE)
{
//Don't do anything.
} else {
//Proccess upload.
}
The form is done correctly with multi-part and all, and other values do update, so I am assuming that this exact code that isn't working.
The problem is that even if I do submit a file it remains just like it was, or another words doesn't do anything. Am I doing this wrong?
you can check so: if(isset($_FILES['user_pic']))
CodeIgniter method:
$this->load->library('upload');
if ($this->upload->do_upload('user_pic'))
//good
else
//errors display $this->upload->display_errors()
CodeIgniter File Uploading Class

Zend Framework - Validating contents of upload (secondary validation)

I'm currently having users upload a MS Word Document where I am checking a version within the XML. The controller currently checks isValid() and then hits a library that does the parsing and extraction (since word is an archive). Now since it's technically "valid" already, I need to check the validity again through the library. What is the best course of action in Zend Framework for this?
Cheers from Kohana Land ;)
I think I understand what you are looking for.
You are currently calling is valid against the form, your file passes the form validation (correct size, extension ...) now you need to unpack the file and validate the contents.
I'm going to assume you already have the code to validate the contents and just want to understand how that might be used in the controller.'
public function anyAction() {
$form = new Form();
//test for $_POST
if ($this->getRequest()->isPost(){
//Test form for validity
if ($form->isValid($this->getRequest()->getPost()){
//will receive file upload (unless disabled in element) and filter form values,
//based on filters attached to the elements.
$data = $form->getValues();
//placeholder for whatever code is required to validate contents of file
$validateFile = new MyFileValidator();
//test for valid file contents
if ($validateFile->isValid($data['file']){
//Do some Stuff
}
//if file contents is not valid, display form and populate values with unfiltered values
$form->populate($this->getRequest()->getPost());
}
//if form is not valid, it should stay populated and display element errors
}
//if not post send form to view
$this->view->form = $form;
}
This example should provide the basic controller workflow for this type of problem. I hope it addresses your question.

Categories