how to validate image dimension before insert into database in laravel - validation

Iam new in laravel .im trying to validate dimensions of image .i want dimensions minimum(width=100,height=50).iam using validation code in controller.php is here
'galimg'=>'required|max:200kb|DimensionMin(300,300)|Mimes:jpeg,jpg,gif,png
,pneg'
but DimensionMin(300,300) is not work....i think custom validation rule is possible ..but i dont know how to use it ?and where ? this is my controller.php code
public function getgallery()
{
$validate=Validator::make(Input::all(),array(
'galname'=>'required|max:20',
'galimg'=>'required|max:400kb|Dimensionmin(300,300)|Mimes:jpeg,jpg,gif,png
,pneg'));
if($validate->fails())
{ return Redirect::route('getgallery')
->withErrors($validate)->withInput(); }
else
{ $max_image = 3;
if(ForumGallery::all()->count() < $max_image)
{ $file=Input::file('galimg');
$filename=$file->getClientOriginalName();
$file->move('uploads',$filename);
ForumGallery::create(['galname'=>Input::get('galname'),
'galimg'=>$filename]);
return Redirect::route('addgallery');
}
else
{return Redirect::route('gallery')
->with('success','Max Image Upload Reached!');
} }}

you can use this code
function getImgSize(imgSrc) {
var newImg = new Image();
newImg.onload = function() {
var height = newImg.height;
var width = newImg.width;
alert ('The image size is '+width+'*'+height);
}
newImg.src = imgSrc; // this must be done AFTER setting onload
}`
Here you get Image height and width compare it with your required dimention.
refer http://tiku.io/questions/4060613/how-to-validate-image-size-and-dimensions-before-saving-image-in-database

$v = Validator::make($data, array(
'email' => 'required|email',
'games' => 'required|numeric',
));
Assume you have some other fields to validate as well. Put them in $v.
Now you need to add custom validation rules.
$v->sometimes('galimg', 'required', function($input)
{
//psudo code, here validate your image
if($input.length >= 300) return false;
return true;
});
Put image-related manipulation into the function.
Hope this helps.
$validate=Validator::make(Input::all(),array(
'galname'=>'required|max:20',
'galimg'=>'required|max:400kb|Mimes:jpeg,jpg,gif,png
,pneg'));
$validate->sometimes('galimg', 'required', function($input)
{
//psudo code, here validate your image
return imagesx($input) > 300 && imagesy($input) > 300;
});

You can use this awesome library for detecting your image dimension here
afte done installing you can use it in your controller like this one :
$validate=Validator::make(Input::all(),array(
'galname'=>'required|max:20',
'galimg'=>'required|mimes:jpeg,jpg,gif,png,pneg|image_size:1200,800'));
the rules should be 1200 wide and 800 tall or width = 1200 and height = 800
Note : the dimension is in pixels
hope it helps.

Related

Laravel: How to validate multiple size rules on same file based on mime-type

Hello great people of SO!
I hope you all have a good day
I want to validate uploaded file based on their mime type
if file is an image, maximum size is 2Mb
if file is a video, maximum size is 500Mb
Atm, this is my code snippet
public function upload(Request $request) {
$request->validate([
'file.*' => ['required', 'file', 'mimes:jpg,jpeg,png,mp4', 'max:2048'] // 2 Mb for images / photos, *but how to put maximum size for video?*
]);
...
}
As you can see, I put: max:2048, which is maximum size for an image
I want to allow users, to upload video up to 500Mb
UPDATE
I can separate each file type based on their mimes on JavaScript
// Example: (Some snippet from my code)
var files = Array.prototype.slice.call(event.target.files)
$formData = new FormData
files.forEach((f, i) => {
var fType = f.type.lowerCase()
// or if you want to get file ext,
// use this: f.name.substr(f.name.lastIndexOf('.') + 1, f.name[length - 1])
// 'example_image.jpeg' > 'jpeg'
// 'example_video.mp4' > 'mp4'
// Here, we can validate the files
// Example:
// You can use regex here, but I prefer to use an array of string, so for future update, if I ever want to 'whitelist' new ext, I can easily add them to this array
if (['image/jpeg', 'image/jpg', 'image/png'].indexOf(fType) !== -1) {
// File is an image with format: jpe?g / png
if ((f.size / 1024) < 2048) {
// Image size is less than 2Mb, valid
$formData.append(['image[' + i + ']', f); // f is the file, see forEach above
}
}
if (['video/mp4'].indexOf(fType) !== -1) {
// File is a video
if ((f.size / 1024) < 512000) {
// Video size is less than 500 Mb, valid
$formData.append(['video[' + i + ']'), f);
}
}
// else: error (file is not an image / video)
... // XHR upload call
})
Then, on server side, for validation
// I can separate the uploaded files
public function upload(Request $request) {
// OBVIOUSLY 'this is NOT the best way to do it'
$request->validate([
'image.*' => ['file', 'mimes:jpg,jpeg,png', 'max:2048'],
'video.*' => ['file', 'mimes:mp4', 'max:512000']
]);
..
}
If you want to know which index the error is:
// *NOTE* I'm using Vue & Axios here
Object.entries(exc.response.data.errors).forEach(([e, m]) => {
// Error response would be:
// image.0 => ['error message']
// ...
// video.3 => ['error message']
var errorIndex = parseInt(e.split('.')[1])
// image.0 > ["image", "0"]
errorMsg = m[0]
// Since we stored all previous selected files in an array
console.log(`Error in file index: ${errorIndex}, file name: ${this.upload.files[errorIndex].name}`)
console.log(`Error message: ${errorMsg}`)
// Error in file index [X], file name: hello_there.mp4
// Error: video.X size cannot be more than ... kilobytes (500Mb)
})
But the thing is, I want to do it only with Laravel way
Q: How to put maximum size for video?
Thanks in advance
you can validate based on file mime type like below psudo-code:
public function upload(Request $request) {
$rules = [];
$image_max_size = 1024 * 2;
$video_max_size = 1024 * 500;
foreach($request->file('file') as $index => $file){
if(in_array($file->getMimeType(), ['image/jpg', 'image/jpeg', 'image/png']) {
$rules["file.$index"] = ["max:$image_max_size"];
} else if (in_array($file->getMimeType(), ['video/mp4']){
$rules["file.$index"] = ["max:$video_max_size"];
} else {
// Always non-validating => returns error
$rules["file.$index"] = ['bail', 'mimes:jpg,jpeg,png,mp4'];
}
}
$request->validate($rules);
...
}
I had similar problem and make that solved using this approach.
try this =>
public function upload(Request $request) {
$request->validate([
'file.*' => ['required', 'file', 'mimes:jpg,jpeg,png', 'max:2048'],
'file.mp4' => ['required', 'file', 'mimes:mp4', 'max:512000'] // 500 Mb for video/
]);
}

Laravel Backpack Image Upload Issue

I m trying to upload images in Laravel Backpack. I had added field in my Controller:
$this->crud->addfield([
'label' => "Logo",
'name' => "logo",
'type' => 'image',
'upload'=> true,
'crop' => true, // set to true to allow cropping, false to disable
'aspect_ratio' => 1, // ommit or set to 0 to allow any aspect ratio
//'disk' => 'public', // in case you need to show images from a different disk
'prefix' => 'uploads/college/' // in case your db value is only the file name (no path), you can use this to prepend your path to the image src (in HTML), before it's shown to the user;
]);
Here is my Model:
protected $fillable = ['name','description','logo','location','establised_at'];
// protected $hidden = [];
// protected $dates = [];
public function setImageAttribute($value)
{
$attribute_name = "logo";
$disk = "public";
$destination_path = "/uploads";
// if the image was erased
if ($value==null) {
// delete the image from disk
\Storage::disk($disk)->delete($this->{$attribute_name});
// set null in the database column
$this->attributes[$attribute_name] = null;
}
// if a base64 was sent, store it in the db
if (starts_with($value, 'data:image'))
{
// 0. Make the image
$image = \Image::make($value)->encode('jpg', 90);
// 1. Generate a filename.
$filename = md5($value.time()).'.jpg';
// 2. Store the image on disk.
\Storage::disk($disk)->put($destination_path.'/'.$filename, $image->stream());
// 3. Save the path to the database
$this->attributes[$attribute_name] = $destination_path.'/'.$filename;
}
}
It's trying to save the base64 data in database but I don't want to do so.
It would be great help if anyone solve it. Thank You!
I've tried the code shown in docs and it works.
I think your problem is the mutator function name. To define a mutator you have to define a method in your model like set{attribute_name}Attribute.
In your case, your mutator function is setImageAttribute then it is looking for an attribute called image.
I think that if you change this code:
public function setImageAttribute($value)
{
with this
public function setLogoAttribute($value)
{
it will work
you miss a step:
like in doc
\Storage::disk($disk)->delete($this->{$attribute_name});
$public_destination_path = Str::replaceFirst('public/', '', $destination_path);
$this->attributes[$attribute_name] = $public_destination_path.'/'.$filename;

How to upload multiple images with base64 in laravel & vue-js

I have been trying to upload multiple images with base64 but it uploads only the second one.
and Is there any easy way to upload images in larvel-vueJS instead of base 64.
this is the Vue-js method:
updateIMG(e){
// console.log('uploaded');
let file = e.target.files[0]
let reader = new FileReader();
if(file['size'] < 9111775){
reader.onloadend = (file) => {
this.landingform.logo = reader.result;
this.landingform.landingBg = reader.result;
}
reader.readAsDataURL(file)
}else {
swal.fire({
icon: 'error',
title: 'Oops...',
text: 'You are uploading a large fiel!',
footer: 'You are authorized to upload files less than 10MB.'
})
}
the method called like this:
<input type="file" #change="updateIMG" name="logo" class="form-input">
and this is my controller:
public function updateLanding(Request $request)
{
$landnginIMG = LandingImage::whereIn('id', [1]);
if ($request->logo){
$name = time().'.' . explode('/', explode(':', substr($request->logo, 0,
strpos($request->logo, ';')))[1])[1];
\Image::make($request->logo)->save(public_path('img/landing/').$name);
$request->merge(['logo' => $name]);
};
if ($request->landingBg){
$bgname = time().'.' . explode('/', explode(':', substr($request->landingBg, 0,
strpos($request->landingBg, ';')))[1])[1];
\Image::make($request->landingBg)->save(public_path('img/landing/').$bgname);
$request->merge(['landingBg' => $bgname]);
};
$landnginIMG->update([
'logo'=> $request ['logo'],
'landingBg'=> $request ['landingBg'],
]);
return ['message' => 'all is done'];
}
There are a few factors your must follow.
First
Your form should let you select multiple files
Second
Your JavaScript must handle all of those files when selected. Check this line of your code.
// console.log('uploaded');
let file = e.target.files[0]
let reader = new FileReader();
e.target.files[0] is taking the first file. You should loop and go through all files.
let files = e.target.files;
Now, use JavaScript foreach loop and convert each file to base64 and store them on array. Then, send that array to sever.
On the server, do the same. You will receive an array so you should loop through each and convert it back to image and save it.
Thanks.
Pls check if this helps:
Vuejs example of multiple image upload https://picupload.netlify.app/
VueJS code repo https://github.com/manojkmishra/dw_take5
Concerned File- https://github.com/manojkmishra/dw_take5/blob/master/src/components/ImageUploader.vue
PHP[Laravel] part is behind firewall so upload submission will not work outside intranet. Here is the controller function code
public function imagesupload(Request $request){
if (count($request->images)) {
foreach ($request->images as $image) {
$image->store('images');
}
}
return response()->json(["message" => "Done"]);
}

Youtube video in laravel

I'm using Laravel Video Embed(https://github.com/Merujan99/laravel-video-embed) so i can get the embeded code from a youtube url.It works just fine but i want to know is there any possibility to change the width and height properties of the embeded video in the view ?
my code in the controller:
public static function getvideo($id)
{
$url = Blog::where('id',$id)->value('video_link');
return LaravelVideoEmbed::parse($url);
}
my view:
<div>
{!!App\Http\Controllers\HomeController::getvideo($blog->id)!!}
</div>
You can pass attributes to the embed like so:
$params = [];
$attributes = [
'height' => 100px,
'width' => 200px,
];
LaravelVideoEmbed::parse($url, ['YouTube'], $params, $attributes)
Which will work dynamically.

Magento: Custom attributes option's new value field

I want to add a custom field in Attribute option in Manage Attribute Options menu in admin. Like value column beside the position column in admin. I have attached an image.
What I have done ... (Magento 1.8)
created a new field in eav_attribute_option table named value after sort_order filed.
changed magento\app\design\adminhtml\default\default\template\eav\attribute\options.phtml this file to show the Value column beside the Position column.
changed getOptionValues() method in this file magento\app\code\core\Mage\Eav\Block\Adminhtml\Attribute\Edit\Options\Abstract.php to get data for my custom value column from database and show in admin side. It shows the default value of db in admin form.
But when I want to save from admin panel the data doesn’t save in db.
I've been trying to find the model or controller that actually handles writing into the database to make sure my new field saves too.
Any help would be appreciated.
(I'd post an image to make you understand, but I can't since I need 10 points to be able to do it.)
Got it!
Update: Mage/Eav/Model/Resource/Entity/Attribute.php
in function: _saveOption(Mage_Core_Model_Abstract $object)
change:
$sortOrder = !empty($option[’order’][$optionId]) ? $option[’order’][$optionId] : 0;
if (!$intOptionId) {
$data = array(
‘attribute_id’ => $object->getId(),
‘sort_order’ => $sortOrder,
);
$adapter->insert($optionTable, $data);
$intOptionId = $adapter->lastInsertId($optionTable);
} else {
$data = array(’sort_order’ => $sortOrder);
$where = array(’option_id =?’ => $intOptionId);
$adapter->update($optionTable, $data, $where);
}
for this:
$sortOrder = !empty($option[’order’][$optionId]) ? $option[’order’][$optionId] : 0;
$yourAttribute = (isset($option[’your_attr_field’]) && !empty($option[’your_attr_field’][$optionId])) ? $option[’your_attr_field’][$optionId] : ‘’;
if (!$intOptionId) {
$data = array(
‘attribute_id’ => $object->getId(),
‘sort_order’ => $sortOrder,
‘your_attr_field’ => $yourAttribute
);
$adapter->insert($optionTable, $data);
$intOptionId = $adapter->lastInsertId($optionTable);
} else {
$data = array(’sort_order’ => $sortOrder, ‘your_attr_field’ => $yourAttribute);
$where = array(’option_id =?’ => $intOptionId);
$adapter->update($optionTable, $data, $where);
}
I could use some help in making all this changes 'the Magento way'

Resources