I am trying to edit/update my image upload but I am getting "Call to a member function getClientOriginalExtension() on a non-object" error. please help
My controller:
public function update(Request $request, $id)
{
$lnkupdate=Request::all();
$links=Links::findorFail($id);
$file = Input::file('image');
$random_name = str_random(8);
$destinationPath = 'albums/';
$extension = $file->getClientOriginalExtension();
$filename=$random_name.'_link_logo.'.$extension;
$uploadSuccess = Input::file('image')->move($destinationPath, $filename);
ConsularGen::update(array(
'name'=>Input::get('name'),
'link' => Input::get('link'),
'image' => $filename,
));
}
View:
{!!Form::model($links,['method'=>'PATCH','action'=>['LinksController#update',$links->id]])!!}
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="form-group">
<label for="image">Select a logo</label>
{!!Form::file('image')!!}
</div>
<div class="form-goup">
{!!Form::label('name','Name')!!}
{!!Form::text('name',null,['class'=>'form-control'])!!}
</div>
<div class="form-goup">
{!!Form::label('link','Link')!!}
{!!Form::text('link',null,['class'=>'form-control'])!!}
</div>
<div class="form-group">
<button type="submit" class="btnbtn-default">Add</button>
</div>
{!!Form::close()!!}
Route:
Route::patch('admin/links/{id}/update','LinksController#update');
Uploading files requires the html form to specify enctype="multipart/form-data". If you don't have this, the file will not be uploaded, Input::file('image') will return null, and you'll get the error you're seeing.
The Laravel Form builder will add this to your form if you tell it that it needs to handle files. Add 'files' => true to your array in the form:
{!! Form::model($links, ['method'=>'PATCH', 'files' => true, 'action'=>['LinksController#update', $links->id]]) !!}
Once this is fixed, you'll also get this error if you don't actually select a file to be uploaded. You should wrap your file handing inside a check to hasFile. Something like:
public function update(Request $request, $id)
{
$lnkupdate=Request::all();
if (Input::hasFile('image')) {
$links=Links::findorFail($id);
$file = Input::file('image');
$random_name = str_random(8);
$destinationPath = 'albums/';
$extension = $file->getClientOriginalExtension();
$filename=$random_name.'_link_logo.'.$extension;
$uploadSuccess = Input::file('image')->move($destinationPath, $filename);
ConsularGen::update(array(
'name'=>Input::get('name'),
'link' => Input::get('link'),
'image' => $filename,
));
} else {
echo 'no file uploaded. oops.';
}
}
Your file has not uploaded successfully.
you are trying to run getClientOriginalExtension() on a null file thats's why you are getting this error
Related
I am trying to update an image and other data in a database, but when I update only text data, the image value becomes null or empty.
<form action="/admin/settings/why-us/update/{{$data->id}}" enctype="multipart/form-data" method="POST">
#csrf
<input type="text" class="form-control" name="title" value="{{$data->title}}">
<input type="file" class="form-control" value="{{$data->image}}" name="image">
<button type="submit" class="btn btn-success py-2 px-4 text-white">Update changes</button>
</form>
This a controller
public function updateWhyusPageSetting(Request $request,$id)
{
$title = $request->input('title');
$image = $image = $request->file('image');
dd($image);
if($request->hasFile('image')) {
$image = $request->file('image');
$filename = $image->getClientOriginalName();
$image->move(public_path('/frontend/images/'), $filename);
$image_upload = $request->file('image')->getClientOriginalName();
}
DB::table('features')
->where('id', $id)
->update([
'title' => $title,
'image' => $image_upload
]);
\Session::flash('flash_message', __('Why us data updated'));
\Session::flash('flash_type', 'success');
return redirect()->back();
}
When I input only the title, left out the image, and tried to dump using dd($image);, I got a null value.
When updating the image, it's getting updated very well database.
Now, my question is, how do I make sure the value is captured in the input file <input type="file" class="form-control" value="{{$data->image}}" name="image"> so that when I update other data, it also sends the image value. NB: value="{{$data->image}}" IS NOT capturing the data from database
Try this code
public function updateWhyusPageSetting(Request $request,$id){
$data = [];
$data['title'] = $request->input('title');
if($request->hasFile('image')) {
$image = $request->file('image');
$image->move(public_path('/frontend/images/'),$imageName = $image->hashName()); //hashName() will generate image name with extension
$data['image'] = $imageName; // here if user uploads an image, it will add to data array then add to DB.
}
DB::table('features')
->where('id', $id)
->update($data); // if a user uploaded an image will add. if not, a previous image will not change
\Session::flash('flash_message', __('Why us data updated'));
\Session::flash('flash_type', 'success');
return redirect()->back();
}
Please note you should delete the old images if you don't need anymore
you can use this to delete an old image if you want
(new Filesystem())->delete("full/path/with/image/name.jpg");
I'm trying to upload image-file from frontend in OctoberCMS
I have a model Person and relation:
public $attachOne = [
'photo' => 'System\Models\File'
];
In php-block with upload form:
public function onUploadImage() {
$person = Person::where('id', '=', $this->param('id'))->first();
$person->photo = \Input::file('avatar');
$person->save();
}
And my template:
<form method="POST" action="/persons/person/{{person.id}}" accept-charset="UTF-8" enctype="multipart/form-data">
<input type="hidden" name="_handler" value="onUploadImage">
<input type="file" name="avatar" id="avatar" />
{{ form_token() }}
{{ form_sessionKey() }}
<button type="submit" data-attach-loading>Upload</button>
After submit it saves to DB only path 'http://my-site/storage/app/uploads/public/' and does not upload any files to filesystem. It seems like there are no some permissions, but I can easily upload images from backend.
Where is my error?
You must get the UploadedFile from the request and store it to one of the configured disks. And store the path to the image in the database.
Assume storage/app/public/images is the directory where the uploaded images should be stored.
public function onUploadImage() {
if(request()->hasFile('avatar') && request()->file('avatar')->isValid()) {
$file = request()->file('avatar');
$filename = $file->getClientOriginalName();
$person = Person::where('id', '=', $this->param('id'))->first();
$person->photo = $file->storeAs('images', $filename)
$person->save();
}
}
Here is the solution.
if(request()->hasFile('avatar') && request()->file('avatar')->isValid()) {
$file = new System\Models\File;
$file->data = Input::file('avatar');
$file->is_public = true;
$file->save();
$person = Person::where('id', '=', $this->param('id'))->first();
$person->photo()->add($file);
$person->save();
}
I am a beginner in laravel. i need to upload an image and that image needs to saved in the database but it is not working Could somebody take a look at my logic and see where I'm going wrong?
StudentController.php
public function store(Request $request)
{
$this->validateRequest();
// Handle File Upload
if($request->hasFile('cover_image')){
// Get filename with the extension
$filenameWithExt = $request->file('cover_image')->getClientOriginalName();
// Get just filename
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
// Get just ext
$extension = $request->file('cover_image')->getClientOriginalExtension();
// Filename to store
$fileNameToStore= $filename.'_'.time().'.'.$extension;
// Upload Image
$path = $request->file('cover_image')->storeAs('public/cover_images', $fileNameToStore);
} else {
$fileNameToStore = 'noimage.jpg';
}
dd( $fileNameToStore);
$student = new student();
$student->cover_image = $fileNameToStore;
$student->save();
return redirect()->route('show')->with('response', 'Registered Successfully');
}
when dd( $fileNameToStore); it is giving the result as "noimage.jpg"
create.blade.php
#extends('layouts.app')
#section('content')
<div class="container">
{!! Form::open(['url' => 'student','method' => 'get', 'enctype' => 'multipart/form-data'])!!}
<div class="form-group">
{{Form::file('cover_image')}}
</div>
<button type="submit" class="btn btn-primary">Submit</button>
{!! Form::close() !!}
</div>
#endsection
I need to validate my image array as an image and specific image file extensions only. but my request validation to image WONT ALLOW me to use inser nullable values
For example I will add a content and dont want to add images. then the image should contain null that is why i need to have request validation as nullable. But in my experience null value is not allowed and it gives me error why? help me please
here is the error.
Undefined variable: promotion
here is my CONTROLLER
public function store(Request $request)
{
$this->validate($request, [
'promotion_image' => 'image|nullable|max:1999'
]);
if ($request->has('promotion_image'))
{
//Handle File Upload
$promotion = [];
foreach ($request->file('promotion_image') as $key => $file)
{
// Get FileName
$filenameWithExt = $file->getClientOriginalName();
//Get just filename
$filename = pathinfo( $filenameWithExt, PATHINFO_FILENAME);
//Get just extension
$extension = $file->getClientOriginalExtension();
//Filename to Store
$fileNameToStore = $filename.'_'.time().'.'.$extension;
//Upload Image
$path = $file->storeAs('public/promotion_images',$fileNameToStore);
array_push($promotion, $fileNameToStore);
}
$fileNameToStore = serialize($promotion);
}
else
{
$fileNameToStore='noimage.jpg';
}
if (count($promotion)) {
$implodedPromotion = implode(' , ', $promotion);
$promotionImage = new Promotion;
$promotionImage->promotion_image = $implodedPromotion;
$promotionImage->save();
return redirect('/admin/airlineplus/promotions')->with('success', 'Image Inserted');
}
return redirect('/admin/airlineplus/promotions')->with('error', 'Something went wrong.');
}
here is my VIEW
{!! Form::open(['action'=>'Admin\PromotionsController#store', 'method' => 'POST','enctype'=>'multipart/form-data', 'name' => 'add_name', 'id' => 'add_name']) !!}
<div class="form-group">
<div class="table-responsive">
<table class="table table-bordered" id="dynamic_field">
<tr>
<td> {{ Form::file('promotion_image[]')}}</td>
<td>{{ Form::button('', ['class' => 'btn btn-success fa fa-plus-circle', 'id'=>'add','name'=>'add', 'style'=>'font-size:15px;']) }}</td>
</tr>
</table>
{{Form::submit('submit', ['class'=>'btn btn-primary', 'name'=>'submit'])}}
</div>
</div>
{!! Form::close() !!}
You need to declare $promotion = [] above if ($request->has('promotion_image')), not inside of it.
So:
public function store(Request $request)
{
$this->validate($request, [
'promotion_image' => 'image|nullable|max:1999'
]);
$promotion = [];
if ($request->has('promotion_image'))
{
//Handle File Upload
That is because your selecting file other than image in your form. See the following to restrict user to only upload images.
<input accept=".png, .jpg, jpeg" name="files[]" type="file" multiple>
Not sure but try once
'promotion_image' => 'nullable|mimes:jpeg,jpg,png,gif|max:1999'
I'm building a Laravel 5.4 application that let's you upload an image to each registered entry. I was using the intervention image package but realized I needed a way to enable image cropping and rotation (iphone images are rotated when uploaded for some reason), so I decided to use the jquery plugin Slim Cropper. I've added the necessary files to my code but can't succesfully upload an image.
Slim Cropper offers two ways to upload an image: through a regular form which gives me the "TokenMismatchException in VerifyCsrfToken.php (line 68)" after submitting, and an ajax form that simply shows a "cannot upload" message. I've tried both ways with different changes but can't get it to work. All my classes/controllers check for authentication, and I have tried sending the csrf token every way I could think of, all show the same error.
UPDATE: As per the suggestions in the comments, I've moved csrf token right after <form>, I've updated the input file names to match those from the example and attempted to debug through middleware with no error messages whatsoever. The TokenMismatchException error is no longer an issue, but once the form is submitted I get the error Constant expression contains invalid operations in Slim.php (line 106) for public static function saveFile($data, $name, $path = public_path('/uploads/mascotas-img/'), $uid = true). Still have no fix for this.
Here's the code:
Routes
Route::post('/mascotas/avatar', 'PetsController#avatar');
Pets Controller
use App\Slim;
public function avatar(Request $request)
{
if ( $request->avatar )
{
// Pass Slim's getImages the name of your file input, and since we only care about one image, postfix it with the first array key
$image = Slim::getImages('avatar')[0];
$mascota_num = $image['meta']->petId;
// Grab the ouput data (data modified after Slim has done its thing)
if ( isset($image['output']['data']) )
{
// Original file name
$name = $image['output']['name'];
//$name = $request->input('mascota_num');
// Base64 of the image
$data = $image['output']['data'];
// Server path
$path = public_path('/uploads/mascotas-img/');
// Save the file to the server
$file = Slim::saveFile($data, $name, $path);
// Get the absolute web path to the image
$imagePath = public_path('/uploads/mascotas-img/' . $file['name']);
DB::table('mascotas')
->where('num',$mascota_num)
->update(['foto' => $imagePath]);
//$mascota->foto = $imagePath;
//$mascota->save();
}
}
return redirect()->back()->with('success', "User's profile picture has been updated!");
}
Slim Class
namespace App;
abstract class SlimStatus {
const Failure = 'failure';
const Success = 'success';
}
class Slim {
public static function getImages($inputName = 'slim') {
$values = Slim::getPostData($inputName);
// test for errors
if ($values === false) {
return false;
}
// determine if contains multiple input values, if is singular, put in array
$data = array();
if (!is_array($values)) {
$values = array($values);
}
// handle all posted fields
foreach ($values as $value) {
$inputValue = Slim::parseInput($value);
if ($inputValue) {
array_push($data, $inputValue);
}
}
// return the data collected from the fields
return $data;
}
// $value should be in JSON format
private static function parseInput($value) {
// if no json received, exit, don't handle empty input values.
if (empty($value)) {return null;}
// The data is posted as a JSON String so to be used it needs to be deserialized first
$data = json_decode($value);
// shortcut
$input = null;
$actions = null;
$output = null;
$meta = null;
if (isset ($data->input)) {
$inputData = isset($data->input->image) ? Slim::getBase64Data($data->input->image) : null;
$input = array(
'data' => $inputData,
'name' => $data->input->name,
'type' => $data->input->type,
'size' => $data->input->size,
'width' => $data->input->width,
'height' => $data->input->height,
);
}
if (isset($data->output)) {
$outputData = isset($data->output->image) ? Slim::getBase64Data($data->output->image) : null;
$output = array(
'data' => $outputData,
'width' => $data->output->width,
'height' => $data->output->height
);
}
if (isset($data->actions)) {
$actions = array(
'crop' => $data->actions->crop ? array(
'x' => $data->actions->crop->x,
'y' => $data->actions->crop->y,
'width' => $data->actions->crop->width,
'height' => $data->actions->crop->height,
'type' => $data->actions->crop->type
) : null,
'size' => $data->actions->size ? array(
'width' => $data->actions->size->width,
'height' => $data->actions->size->height
) : null
);
}
if (isset($data->meta)) {
$meta = $data->meta;
}
// We've sanitized the base64data and will now return the clean file object
return array(
'input' => $input,
'output' => $output,
'actions' => $actions,
'meta' => $meta
);
}
// $path should have trailing slash
public static function saveFile($data, $name, $path = public_path('/uploads/mascotas-img/'), $uid = true) {
// Add trailing slash if omitted
if (substr($path, -1) !== '/') {
$path .= '/';
}
// Test if directory already exists
if(!is_dir($path)){
mkdir($path, 0755);
}
// Let's put a unique id in front of the filename so we don't accidentally overwrite older files
if ($uid) {
$name = uniqid() . '_' . $name;
}
$path = $path . $name;
// store the file
Slim::save($data, $path);
// return the files new name and location
return array(
'name' => $name,
'path' => $path
);
}
public static function outputJSON($status, $fileName = null, $filePath = null) {
header('Content-Type: application/json');
if ($status !== SlimStatus::Success) {
echo json_encode(array('status' => $status));
return;
}
echo json_encode(
array(
'status' => $status,
'name' => $fileName,
'path' => $filePath
)
);
}
/**
* Gets the posted data from the POST or FILES object. If was using Slim to upload it will be in POST (as posted with hidden field) if not enhanced with Slim it'll be in FILES.
* #param $inputName
* #return array|bool
*/
private static function getPostData($inputName) {
$values = array();
if (isset($_POST[$inputName])) {
$values = $_POST[$inputName];
}
else if (isset($_FILES[$inputName])) {
// Slim was not used to upload this file
return false;
}
return $values;
}
/**
* Saves the data to a given location
* #param $data
* #param $path
*/
private static function save($data, $path) {
file_put_contents($path, $data);
}
/**
* Strips the "data:image..." part of the base64 data string so PHP can save the string as a file
* #param $data
* #return string
*/
private static function getBase64Data($data) {
return base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $data));
}
}
Picture submit form (tokenmismatch error)
<form action="{{ url('mascotas/avatar') }}" method="post" enctype="multipart/form-data">
<div class="modal-body">
<div class="slim" data-label="Agregar imagen aquí" data-size="400, 400" data-ratio="1:1" data-meta-pet-id="{{ $mascota->num }}">
#if ( $mascota->foto )
<img src="{{ url('/uploads/mascotas-img/'.$mascota->foto) }}" />
#endif
<input type="file" name="avatar" required />
{{ csrf_field() }}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-red">Cambiar Foto</button>
</div>
</form>
Alternate submit form (error message)
<div class="modal-body">
<div class="slim" data-label="Agregar imagen aquí" data-size="400, 400" data-ratio="1:1" data-service="{{ url('mascotas/avatar') }}" data-meta-pet-id="{{ $mascota->num }}">
#if ( $mascota->foto )
<img src="{{ url('/uploads/mascotas-img/'.$mascota->foto) }}" />
#endif
<input type="file" name="avatar" />
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-red">Cambiar Foto</button>
</div>
Slim image cropper website with examples http://slimimagecropper.com/
My original upload form through laravel image intervetion, this works with no problems at upload, but would very much like to replace with one of the above.
<form enctype="multipart/form-data" action="{{ url('mascotas/foto') }}" method="POST">
<div class="modal-body">
<img class="mascota-avatar" src="{{ url('/uploads/mascotas-img/'.$mascota->foto) }}">
<div class="clearfix"></div>
<input type="file" name="foto">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="mascota_num" value="{{ $mascota->num }}">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-red">Cambiar Foto</button>
</div>
</form>
Thanks for any help!
You should include the {{ csrf_field() }} on each of your forms, for the Ajax one, you could send the token as header.