Multiple file upload and validation - laravel

I want to allow multiple files upload, so I did this in my view:
{{ Form::file('files[]', array('multiple'=>true)); }}
it works, but I can't validate it. For testing purposes I've created this rule:
'files' => 'required|mimes:png,jpg,jpeg'
but it doesn't work, it always says the mime type is incorrect, I also tried it with png.
Can anyone help me please? I also tried to remove the [] from the file input name.
Could be the problem that laravel doesn't support multiple files at validation?
Thanks

I had the same problem, i got the solution by editing the code of the request handler.
public function rules()
{
$rules = [];
$nbr = count($this->file('field_name')) - 1;
foreach(range(0, $nbr) as $index) {
$rules['field_name.' . $index] = 'required|mimes:jpeg,jpg,png';
}
return $rules;
}

Related

Importing generated csv from Laravel into Google Sheets

I'm trying to import an automatically generated csv into Google Sheets using this as cell value:
=importData("https://example.com/reports/some-report")
When I try importData on a static file on the server everything works as expected (like =importData("https://example.com/storage/some-static-report.csv") )
..but when I generate the file on the fly () I get a #N/A in the cell; "Resource at url not found." error.
This is the Laravel code to generate the csv:
public function downloadReportsAsCSV(Request $request) {
$list = [];
$list[] = ['timestamp', 'id', 'value'];
// ... fill the list with data here
$callback = function() use ($list) {
$out = fopen('php://output', 'w+');
// Write CSV lines
foreach ($list as $line) {
fputcsv($out, $line);
}
fclose($out);
};
$name = 'somereport.csv';
$headers = [
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment; filename='. $name,
];
return response()->stream($callback, 200, $headers);
}
The route to this method is public so authentication is not a problem in this case.
When I call https://example.com/reports/some-report in a browser it downloads the file (as somereport.csv), but somehow Google Sheeds can't handle it the way I expect it to.
Any ideas on how to make this work?
It seems to be working after all, it's just that Google Sheets apparently needed quit some time before updating the field (at least a couple of minutes).
If anyone has any idea how to trigger Google Sheets to update the data immediately I'd sure like to know.

Validating Image Uploads

Yo! I am working on a form where I attach some image.
Form:
{{ Form::file('attachments[]', array('multiple')) }}
Validation:
$this->validate($response, array(
'attachments' => 'required | mimes:jpeg,jpg,png',
));
I have also tried 'image' as validator rule but whenever I post the form with jpg image I get back errors:
The attachments must be a file of type: jpeg, jpg, png.
Working with Laravel 5.3
Since you defined an input name of attachments[], attachments will be an array containing your file. If you only need to upload one file, you might want to rename your input name to be attachments, without the [] (or attachment would make more sense in that case). If you need to be able to upload multiple, you can build an iterator inside your Request-extending class that returns a set of rules covering each entry inside attachments[]
protected function attachments()
{
$rules = [];
$postedValues = $this->request->get('attachments');
if(null == $postedValues) {
return $rules;
}
// Let's create some rules!
foreach($postedValues as $index => $value) {
$rules["attachments.$index"] = 'required|mimes:jpeg,jpg,png';
}
/* Let's imagine we've uploaded 2 images. $rules would look like this:
[
'attachments.0' => 'required|mimes:jpeg,jpg,png',
'attachments.1' => 'required|mimes:jpeg,jpg,png'
];
*/
return $rules;
}
Then, you can just call that function inside rules() to merge the array returned from attachments with any other rules you might want to specify for that request:
public function rules()
{
return array_merge($this->attachments(), [
// Create any additional rules for your request here...
]);
}
If you do not yet have a dedicated Request-extending class for your form, you can create one with the artisan cli by entering: php artisan make:request MyRequestName. A new request class will be created inside app\Http\Requests. That is the file where you would put the code above in. Next, you may just typehint this class inside the function signature of your controller endpoint:
public function myControllerEndpoint(MyRequestName $request)
{
// Do your logic... (if your code gets here, all rules inside MyRequestName are met, yay!)
}

Laravel password recovery template

I have the following code which sends a passowrds recovery mail:
public function recovery(Request $request)
{
$validator = Validator::make($request->only('email'), [
'email' => 'required'
]);
if($validator->fails()) {
throw new ValidationHttpException($validator->errors()->all());
}
$response = Password::sendResetLink($request->only('email'), function (Message $message) {
$message->subject(Config::get('boilerplate.recovery_email_subject'));
});
switch ($response) {
case Password::RESET_LINK_SENT:
return $this->response->noContent();
case Password::INVALID_USER:
return $this->response->errorNotFound();
}
}
Which I found out uses the following template: resources/views/auth/emails/password.php
which is an empty file.
How I can access the token from this template?
Isn't there any built-in view to use from laravel?
The function in your questions doesn't return a view.
Also, I'm unfamiliar with that path to the view that is in your question. Which version of Laravel are you using?
Anyhow, you can get the reset token from the DB, just like any other value in the DB. E.g. from a controller that is returning a view:
$user = User::find(Auth::id());
$remeber_token = $user->remember_token;
return view('to_your_view.blade.php', compact('remember_token');
And then in the view file:
{{ $remember_token }}
This will output it, no need to use echo or anything.
But, again, the function you pasted into your question is not a function that is returning a view, so I'm not sure where to tell you to put the above code.
As for your questoin about Laravel having an in-built view for 'this', in Laravel 5.3, at least, the view I assume you want will be within `resources/views/auth/passwords/'.

Image validation not working If using ajaxForm

I tried googling and saw other questions posted at this forum but could not find any solution for my issue. I am using Jquery ajaxForm method to submit form. My form contains one file field too in the form that can be used to upload a picture. I have defined the validation in my model. But the issue is even i am uploading a correct jpg file, still i am getting error message that
Argument 1 passed to Illuminate\\Validation\\Factory::make() must be of the type array, object given.
Javascript Code
$('#create_form').ajaxForm({
dataType:'JSON',
success: function(response){
alert(response);
}
}).submit();
Controllder Code
if ($file = Input::file('picture')) {
$validator = Validator::make($file, User::$file_rules);
if ($validator->fails()) {
$messages = $validator->messages();
foreach ($messages->all(':message') as $message) {
echo $message; exit;
}
return Response::json(array('message'=>$response, 'status'=>'failure'));
} else {
// do rest
}
}
Model Code
public static $file_rules = array(
'picture' => 'required|max:2048|mimes:jpeg,jpg,bmp,png,gif'
);
POST Request
I know that my validation defined in the model expects an array. But by passing $file in the validator, an object is passed. Then i changed the code like:
$validator = Validator::make(array('picture' => $file->getClientOriginalName()), User::$file_rules);
Now i am getting error:
The picture must be a file of type: jpg, JPEG, png,gif.
The problem is you pass file object directly to validate. Validator::make() method takes all four parameters as array. Moreover, you need to pass the whole file object as value so that Validator can validate mime type, size, etc. That's why your code should be like that.
$input = array('picture' => Input::file('picture'));
$validator = Validator::make($input, User::$file_rules);
if ($validator->fails()) {
$messages = $validator->messages();
foreach ($messages->all(':message') as $message) {
echo $message; exit;
}
return Response::json(array('message'=>$response, 'status'=>'failure'));
} else {
// do rest
}
Hope it will be useful for you.
Try rule like this.
$rules = array(
'picture' => 'image|mimes:jpeg,jpg,bmp,png,gif'
);
or try removing 'mimes'

Yii validation with file upload failing

I'm having what looks to me some strange behaviour within Yii.
I have a simple file upload, that takes a name and the file itself.
If I just submit the form with no name or file I can bypass the validation (i.e - My controller action is called and is trying to process the uploaded file) I think my rules() are setup accordingly to stop this. These are my relevant rules:
public function rules() {
return array(
array('name file', 'required', 'message' => 'This field is required'),
array('file', 'file', 'on' => 'insert', 'allowEmpty' => false, 'safe'=>true,
'maxSize'=> 512000,
'maxFiles'=> 1,
'mimeTypes' => 'application/msword, text/plain',
'tooLarge'=> 'file cannot be larger than 500KB.',
'wrongMimeType'=> 'Format must be: .doc .txt'
),
I specified that the file is required and also within the file array that allowEmpty should be false. So what am I doing wrong here?
Thanks in advance for any help
Controller
public function actionCreate() {
$model = new File;
if (isset($_POST['File'])) {
$model->setAttributes($_POST['File']);
// Set file
$model->file = CUploadedFile::getInstance($model,'file');
// Set directory
$dest = Yii::getPathOfAlias('application.uploads');
$model->tmp_name = time();
$model->date_added = new CDbExpression('NOW()');
$model->file_type = $model->file->type;
$model->file_size = $model->file->size;
$model->extension = $model->file->extensionName;
if ($model->save()) {
$model->file->saveAs(($dest . '/' . $model->tmp_name . '.' . $model->file->extensionName));
Yii::app()->user->setFlash('success','<strong>Success!</strong> Your file has been uploaded');
}
}
$this->render('create', array( 'model' => $model));
}
For one you're missing a , in your first rule between name and file. Then you say:
I can bypass the validation (i.e - My controller action is called ...
From that i assume you use AJAX validation and expect the upload to fail. But you can't do AJAX validation on file uploads with CActiveForm.
So if you fix the typo above, you'll at least get AJAX validation for the name attribute.
You should maybe also remove the 'on'=>'insert' scenario. And you don't need the 'safe'=>true because you don't do massive assignment with the $model->file attribute.
For me I found that if I validate before I process the uploaded file it worked. Wasn't quite sure why I had to do that as I thought the save() method automatically called the validate() method
Validation will be performed before saving the record. If the validation fails, the record will not be saved. You can call getErrors() to retrieve the validation errors.
Updated code
public function actionCreate() {
$model = new File;
if (isset($_POST['File'])) {
$model->setAttributes($_POST['File']);
if($model->validate()){ // add in validation call
// Set file
$model->file = CUploadedFile::getInstance($model,'file');
// Set directory
$dest = Yii::getPathOfAlias('application.uploads');
$model->tmp_name = time();
$model->date_added = new CDbExpression('NOW()');
$model->file_type = $model->file->type;
$model->file_size = $model->file->size;
$model->extension = $model->file->extensionName;
if ($model->save()) {
$model->file->saveAs(($dest . '/' . $model->tmp_name . '.' . $model->file->extensionName));
Yii::app()->user->setFlash('success','<strong>Success!</strong> Your file has been uploaded');
}
}
}
$this->render('create', array( 'model' => $model));
}
Hope that helps anyone, thanks to #Michael Härtl too

Resources