Image from database not found - php

I have a problem with my project; the problem is the uploaded image to the database is not found and is not displaying on the page.
Galleries upload error
And these are the scripts.
gallery.blade.php
#foreach ($galleryImages as $galleryImage)
<div class="gallery-card">
<a href="detailed-gallery.html">
<img src="{{ asset('storage/' . $galleryImage->image_path) }}">
</a>
<p>{{ $galleryImage->title }}</p>
</div>
#endforeach
AppController.php
public function gallery()
{
$setting = \App\Setting::first();
$galleryImages = Gallery::all();
return view('gallery', compact('setting', 'galleryImages'));
}
GalleryController.php
public function store(Request $request)
{
$data = $request->validate([
'title' => 'required',
'image_path' => 'required|image',
]);
Gallery::create(array_merge($data, ['image_path' => $data['image_path']->store('uploads/attachments', 'public')]));
return redirect()->route('galleries.index');
}
There are no errors on my friend's laptop, and they don't show on the page; what is it that the different OS affects? My friend is using Windows, and I'm using Ubuntu Linux; what's the solution?

Related

Retrieving image from database and showing it Laravel

I am making a web application in the Laravel Framework. I have written code that saves a image in the database.
Code for saving a image in the database (code in my controller):
public function store(Request $request)
{
$request->validate([
'title' => 'required',
'description' => 'required',
'category_id' => 'required',
]);
$user = request()->user();
$assortment = $user->assortments()->create($request->all());
if($request->hasFile('image') && $request->file('image')->isValid()) {
if($request->hasFile('image') && $request->file('image')->isValid()) {
//dd($request->image->store('images', 'public'));
$assortment->image_path = $request->image->store('images', 'public');
$assortment->save();
//Check what the Storage::url() generates
//dd(Storage::disk('public')->url($assortment->fresh()->image_path));
}
else {
abort(500, "Image not valid");
}
}
if ($request->wantsJson()) {
return response([], 204);
}
return redirect()->route('assortments.show', $assortment->slug)
->with('success','Verzameling is succesvol aangemaakt.');
}
I want my image to be retrieved from my database in the view but I do not know how to go about doing this. I tried things like:
<img src="/images/{{ $imageVariableName }}"> Variables and path are changed
The view I am trying to make my image be retrieved and shown:
<div class="mt-10">
<ul class="md:grid md:grid-cols-2 md:gap-x-8 md:gap-y-10">
#foreach ($assortment->itemCategories as $category)
<li>
<a href="{{ route('categories.show', [$assortment->slug, $category->id]) }}">
<div class="flex px-4 py-5 bg-white shadow overflow-hidden sm:rounded-md sm:px-6">
<div class="flex-shrink-0">
<div class="flex items-center justify-center h-12 w-12 rounded-md bg-indigo-500 text-white">
<!-- Heroicon name: globe-alt -->
</div>
</div>
<div class="ml-4">
<h4 class="text-lg leading-6 font-medium text-gray-900">{{ $category->name }}</h4>
</div>
</div>
</a>
</li>
#endforeach
</ul>
</div>
Anyone know how I go about doing this?
EDIT
I also tried:
<img src="{{ Storage::disk('public')->url($assortment->image_path) }}">
But it also returned no image. Just returned:
I inspected the image and it returned the following link:
http://localhost/storage/tmp/phpSX2W3G
EDIT
I know now the problem has to do with my upload controller. The file should not be stored at a temporary path: /storage//tmp/phpL1ZVcx
EDIT 2
The storage link appears to be broken. Get this in my public/storage:
Greetings,
Parsa
you can use
<img src={{Storage::url($assortment->img)}} />
EDIT:
I found out your problem, the problem not in the display but actually in your upload code
if ($request->hasFile('image')) {
$image = $request->file('image'); //request the file
$fileName = md5($image->getClientOriginalName() . microtime()) . '.' . $image->getClientOriginalExtension(); //use md5 for security reasons and get the extension.
$image->storeAs('', $fileName, 'public'); //store the file in the public folder disk.
$assortment->image_path = $fileName;
$assortment->save();
}
should become, because $filename just a temporary upload file it will be delete later, the actual upload path will be return by storeAs
if ($request->hasFile('image')) {
$image = $request->file('image'); //request the file
$fileName = md5($image->getClientOriginalName() . microtime()) . '.' . $image->getClientOriginalExtension(); //use md5 for security reasons and get the extension.
$assortment->image_path = $image->storeAs('', $fileName, 'public'); //store the file in the public folder disk.
$assortment->save();
}
EDIT2: if you are using nginx you need to remove these line
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
}
You can try the below:
Have included comments in the code with dd() statements to debug - uncomment the dd() statements if you don't get it working to check.
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required',
'description' => 'required',
'category_id' => 'required',
]);
$user = request()->user();
if(!$user) {
abort(401, 'Unauthenticated');
}
$assortment = $user->assortments()->create($validated);
if($request->hasFile('image') && $request->file('image')->isValid()) {
//dd($request->image->store('images', 'public'));
$assortment->image_path = $request->image->store('images', 'public');
$assortment->save();
//Check what the Storage::url() generates
//dd(Storage::disk('public')->url($assortment->fresh()->image_path));
} else {
abort(422, "Image not valid");
}
if ($request->wantsJson()) {
return response([], 204);
}
return redirect()->route('assortments.show', $assortment->slug)
->with('success','Verzameling is succesvol aangemaakt.');
}
Verify that you have a public disk configured in the config\filesystems.php, something like
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL') . '/storage',
'visibility' => 'public',
],
//And links specified for symlinking when php artisan storage:link is run
'links' => [
public_path('storage') => storage_path('app/public'),
],
Then run
php artisan storage:link
and check in the public folder that there exists a symlinked storage folder
Then in your blade view, you can use
<img src="{{ Storage::disk('public')->url($assortment->image_path) }}" />
//OR
<img src="/storage/{{ $assortment->image_path }}" />
Controller:
if ($request->hasFile('image')) {
$image = $request->file('image');
$assortment->image_path = $image->store('', 'public');
$assortment->save();
}
NB: Laravel by default will create a unique name for a file and manage extension for you - dependent on your use case you may not need to make this filename yourself.
Artisan Command
php artisan storage:link
Generates the correct symlinks for your public storage.
Template
{{ Storage::url($assortment->image_path) }}
Those three things together should work.
Try
<img src="{{ url('storage/images/'.$assortment->image_path) }}"/>
Try a much simplified version:
if ($request->hasFile('image')) {
$path = $request->file('image')->storePublicly('images'); // Store file in public disk & return path
$assortment->image_path = $path; // If you want filename only, use basename($path)
$assortment->save();
}
After that, you can use Storage::disk('public')->url($assortment->image_path) in your view. Using getClientOriginalExtension() and getClientOriginalExtension() probably isn't a good idea since it's not considered a safe value (source). Laravel's store method saves the file and returns the hashed filename with path for you so you don't have to worry about all that :)
Make sure storage symlink is created:
php artisan storage:link
Also make sure post_max_size and upload_max_filesize in your php.ini are set with sufficient amount.

always return null while uploading file to laravel 7

I'm having an issue while uploading file to laravel either its pdf or image always return to null
This is the View
{!! Form::open(['action' => 'TransactionInController#store', 'method' => 'POST', 'autocomplete' => 'off',
'class' => 'form-horizontal', 'enctype' => 'multipart/form-data']) !!}
<div class="row">
{{ Form::label('Device Document', '', ['class' => 'col-sm-2 col-form-label']) }}
<div class="col-sm-7">
{{ Form::file('device_document') }}
<p style="color: red;">#error('device_document') {{ $message }} #enderror</p>
</div>
</div>
{!! Form::close() !!}
and this is the Controller i use
public function store(Request $request)
{
$this->validate($request, [
'device_document' => 'nullable|max:8192|mimes:pdf'
]);
$transactionsin = new TransactionIn;
$imageName = $request->input('device_document');
$request->image->move(public_path('document-image'), $imageName);
$transactionsin->save();
return redirect('/transactionsin');
}
i know its been asked before and i already try several way to upload file this error.
This is the error message i get while running the code
Call to a member function move() on null
but if i change the code in controller into something more simple like this
public function store(Request $request)
{
$this->validate($request, [
'device_document' => 'nullable|max:8192|mimes:pdf'
]);
$transactionsin = new TransactionIn;
$transactionsin->device_document = $request->input('device_document');
$transactionsin->save();
return redirect('/transactionsin');
}
it will not return any error message but it will saved as null in the database.
Use $request->file('device_document') instead of input method to catch a file.
If you would like to get original name of the uploaded file, you may do so using the getClientOriginalName() method
Try this :
public function store(Request $request)
{
$this->validate($request, [
'device_document' => 'nullable|max:8192|mimes:pdf'
]);
$transactionsin = new TransactionIn;
$imageName = $request->file('device_document');
$imageName->move(public_path('document-image'), $imageName->getClientOriginalName());
$transactionsin->device_document = $request->file('device_document')->getClientOriginalName();
$transactionsin->save();
return redirect('/transactionsin');
}
See the official documentation here
you can access file using file() method not input method and after upload image to get image path using asset() function like this below code
$transactionsin = new TransactionIn;
$image= $request->file('device_condition');
//upload imaage
$image->move(public_path('document-image'), $image->getClientOriginalExtension());
//asset() function use store path
$transactionsin->device_document = asset('document-image/'.$image->getClientOriginalExtension());
$transactionsin->save();

How to view files in laravel 5.7 (use multiple file upload code) and how to edit them

I am upload multiple file in laravel 5.7 files are uploaded in database but i am enable to view on admin panel and how to edit these files .How to display these images on admin panel and how to edit these files . Here is my code given below:
This is my controller to upload file
public function addProduct(Request $request)
{
if($request->isMethod('get'))
{
return view('admin.product.add-product');
}
if($request->isMethod('post'))
{
$this->validate($request,[
'product_name' => 'required|max:40',
'price' => 'required',
'product_type' => 'required',
'quantity' => 'required',
'description' => 'required',
'image' => 'required',
'image.*' => 'image|mimes:jpeg,png,jpg,gif,svg'
]);
$product = new Product();
$product->product_name = $request->product_name;
$product->price = $request->price;
$product->product_type = $request->product_type;
$product->quantity = $request->quantity;
$product->description = $request->description;
//image upoad code
//return $request->all();
if($request->hasfile('image'))
{
// return $request->image;
foreach($request->file('image') as $images)
{
//var_dump($images);
$name=$images->getClientOriginalName();
$images->move(public_path().'/images/', $name);
$data[] = $name;
}
}
$product->image=json_encode($data);
$product->save();
return redirect('admin/product-management');
}
}
Code to view file on admin panel is:
#foreach ($product as $products)
#php $images = json_decode($product->image,true);
#endphp
#if(is_array($images) && !empty($images))
#foreach ($images as $image)
<img src="{{ url('public/images/'.$images) }}"/>
#endforeach
#endif
#endforeach
i upload files to public/images folder. How to edit and display images on admin panel.
in database images are stored as
["download.jpeg","download.png","download (2).jpeg"]
You can try like this:
#foreach ($products as $product)
#php $images = json_decode($product->image,true);
#endphp
#if(is_array($images) && !empty($images))
#foreach ($images as $image)
<img src="{{ asset('images/'.$image) }}"/>
#endforeach
#endif
#endforeach
Here i removed url function and use asset function , asset make complete url for public directory
just remove the public keyword from image path and check again
#foreach ($product as $products)
#php $images = json_decode($product->image,true);
#endphp
#if(is_array($images) && !empty($images))
#foreach ($images as $image)
<img src="{{ url('images/'.$image) }}"/>
#endforeach
#endif
#endforeach
I also removed 's' from {{ url('images/'.$image) }}

Display image from storage in view

I have a form with multiple fields which stores information including an image upload. There is also an edit view:
Route::PUT('/link/{link}', function (Request $request, Link $link) {
$request->validate([
'name' => 'required|max:255',
'title' => 'required|max:255',
'cell' => 'required|max:255',
'tel' => 'required|max:255',
'email' => 'required|max:255',
'website' => 'required|url|max:255',
'location' => 'required|max:255',
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
$img = $request->file('image');
$newfilename = $request->name;
$img->move(public_path("/uploads"), $newfilename);
$link->update($request->all());
return redirect('/');
});
The initial submit and edit works fine along with changing the image file name and storing it in the uploads folder.
The path generated being:
public/uploads/exampleFileName.jpg
The problem here is when it comes to displaying the image in the home view. The code below generates a 404 not found with an additional /tmp/ path which I have no idea about where it comes from.
Code in home view:
#foreach ($links as $link)
<div class="link-box">
<h5 class="off-white-txt">Card [# {{ $link->id }}]</h5>
<h5 class="off-white-txt"><span class="pool-blue-txt">Name: </span>{{ $link->name }}</h5>
<h5 class="off-white-txt"><span class="pool-blue-txt">Title: </span>{{ $link->title }}</h5>
<h5 class="off-white-txt"><span class="pool-blue-txt">Cell: </span>{{ $link->cell }}</h5>
<h5 class="off-white-txt"><span class="pool-blue-txt">Tel: </span>{{ $link->tel }}</h5>
<h5 class="off-white-txt"><span class="pool-blue-txt">Email: </span>{{ $link->email }}</h5>
<h5 class="off-white-txt"><span class="pool-blue-txt">Website: </span>{{ $link->website }}</h5>
<h5 class="off-white-txt"><span class="pool-blue-txt">Location: </span>{{ $link->location }}</h5>
<img src="{{url('uploads'.$link->image) }}" class="off-white-txt">
</div>
The error message in the console:
GET http://192.168.10.10/uploads/tmp/phpdtnTcw 404 (Not Found)
My question is the following; How could I edit my code to point to the correct path and display the image?
Thank you in advance.
if you are using storage folder to save images then you should use Storage::url
make sure to run command php artisan storage:link
<img src="{{ Storage::url($link->image) }}" class="off-white-txt">
The temporary path you are getting is from the image itself.
Why? Because you are not setting the image new path after moving the image, so the image is stored inside a temp storage.
To simplify it, you have indeed saved the image under public folder, but the image path is still in the temp storage. This is where the image resides. This temp storage is the default path for every UploadedFile object
You need to explicitly set it's path on the Link object, like so:
$link->image = 'my new path';
$link->save();
I think it is because you cannot access the uploads folder from the view.
I would suggest to create a controller that will get your image in the uploads folder and send a image Response. Something like this :
public function showImage($image)
{
if (!Storage::exists($image->name)) {
return false;
}
$file = Storage::get($image->name);
$type = Storage::mimeType($image->name);
$response = Response::make($file, 200)->header("Content-Type", $type);
return $response;
}
Then you just have to call the right route that points to your controller method :
<img src="{{ route('getMyImage', $image) }}" />
This way you can protect easily the files in your uploads folder (for exemple : put middleware or user control functions ...). Otherwise you can do the php artisan storage:link command
These are all valid points although the setup of my framework didn't play well with the suggestions. I have implemented a workaround for now.
This is the updated code in the web controller:
Route::post('/submit', function (Request $request) {
$data = $request->validate([
'name' => 'required|max:255',
'title' => 'required|max:255',
'cell' => 'required|max:255',
'tel' => 'required|max:255',
'email' => 'required|max:255',
'website' => 'required|url|max:255',
'location' => 'required|max:255',
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
$img = $request->file('image');
// Storage::disk('public')->put('uploads', $img);
$newfilename = $request->name;
$img->move(public_path("/uploads"), $newfilename);
$link = tap(new App\Link($data))->save();
return redirect('/');
});
This is the updated view code:
<img src="/uploads/{{ $link->name }}" class="user-img">
Thank you very much for all the help!

why do I get preg_replace() error when submitting a post form in Laravel?

I have built a simple application laravel 4. I have scaffolding setup for adding posts which seems to be working fine. I have setup Stapler and image uploading package. When I setup to use single image uploads its pretty good and it works a charm. I recently looked at the docs here
It states that you can do multiple uploads so I went about doing it as explained in the docs. Here are my coded pages:
Post.php model:
<?php
class Post extends Eloquent {
use Codesleeve\Stapler\Stapler;
protected $guarded = array();
// A user has many profile pictures.
public function galleryImages(){
return $this->hasMany('GalleryImage');
}
public static $rules = array(
'title' => 'required',
'body' => 'required'
);
public function __construct(array $attributes = array()) {
$this->hasAttachedFile('picture', [
'styles' => [
'thumbnail' => '100x100',
'large' => '300x300'
],
// 'url' => '/system/:attachment/:id_partition/:style/:filename',
'default_url' => '/:attachment/:style/missing.jpg'
]);
parent::__construct($attributes);
}
}
PostsController.php
/**
* Store a newly created resource in storage.
*
* #return Response
*/
public function store()
{
$input = Input::all();
$validation = Validator::make($input, Post::$rules);
if ($validation->passes())
{
$this->post->create($input);
return Redirect::route('posts.index');
}
$post = Post::create(['picture' => Input::file('picture')]);
foreach(Input::file('photos') as $photo)
{
$galleryImage = new GalleryImage();
$galleryImage->photo = $photo;
$user->galleryImages()->save($galleryImage);
}
return Redirect::route('posts.create')
->withInput()
->withErrors($validation)
->with('message', 'There were validation errors.');
}
This has save functions and other functions inside it too.
GalleryImage.php gallery image model to use in the post controller
<?php
class GalleryImage extends Eloquent {
protected $guarded = array();
public static $rules = array();
public function __construct(array $attributes = array()) {
$this->hasAttachedFile('photo', [
'styles' => [
'thumbnail' => '300x300#'
]
]);
parent::__construct($attributes);
}
// A gallery image belongs to a post.
public function post(){
return $this->belongsTo('Post');
}
}
My create.blade.php template to post the post itself
#extends('layouts.scaffold')
#section('main')
<h1>Create Post</h1>
{{ Form::open(array('route' => 'posts.store', 'files' => true)) }}
<ul>
<li>
{{ Form::label('title', 'Title:') }}
{{ Form::text('title') }}
</li>
<li>
{{ Form::label('body', 'Body:') }}
{{ Form::textarea('body') }}
</li>
<li>
{{ Form::file('picture') }}
</li>
<li>
{{ Form::file( 'photo[]', ['multiple' => true] ) }}
</li>
<li>
{{ Form::submit('Submit', array('class' => 'btn btn-info')) }}
</ul>
{{ Form::close() }}
#if ($errors->any())
<ul>
{{ implode('', $errors->all('<li class="error">:message</li>')) }}
</ul>
#endif
#stop
When I post the form with a single images attached its fine and saves to the db and it works a treat but when I save it with multiple image uploads I get this error:
ErrorException
preg_replace(): Parameter mismatch, pattern is a string while replacement is an array
The full stack trace is here in my gist of the files
Can anyone point out to me why this error happens. From my research its creating a multidimensional array that needs flattening I think but I am unsure if this is true.
I have been banging my head against a brick wall with this for ages.
Problem is when your submitting multiple images it becomes an array of pictures instead of a single string. So its trying to save an array to the database instead of a string which its expecting. If you make it so your photo variable is a json_encoded array of pictures then you should be able to save them.
Hope this helps.

Categories