Spatie Media Library not generating jpeg for videos - laravel

OK, so Lets start with code
App\Models\User
public function registerMediaConversions(Media $media = null): void
{
$this
->addMediaConversion('thumb')
->width(368)
->height(232)
->extractVideoFrameAtSecond(1)
->performOnCollections('stories')
->nonQueued();
}
media-library.php
'ffmpeg_path' => env('FFMPEG_PATH', '/usr/local/bin/ffmpeg'),
'ffprobe_path' => env('FFPROBE_PATH', '/usr/local/bin/ffprobe'),
Test Route
Route::get('test', function() {
$video = new \Spatie\MediaLibrary\Conversions\ImageGenerators\Video();
echo $video->convert('demo.mov');
});
StoryController.php (snip)
$model = Auth::user();
//if request is a video
if($request->hasFile('video') && $request->file('video')->isValid()){
$media = $model->addMediaFromRequest('video')
->toMediaCollection('stories');
}
When the video is uploaded, it is added to the library successfully. The issue is no thumbnail is being generated based on the model information. When I use the test route, it does generate the thumbnail successfully. I am not sure what I am missing but after 8 hours I am starting to wonder if this is a bug or if there is more troubleshooting I can do.
Nothing is showing up in the laravel.log, nothing is showing up on the frontend, nothing is showing up out of the ordinary in Telescope so I am at a loss.

Related

Laravel Spatie Media Library Pro and Activity Log

I am having issues wrapping my head around integrating these 2 products together. I am dealing with how to make the following work.
User uploads 1-10 images via Spatie Media Library Pro (Headless)
Form Request is sent to the backend function
Images are stored (in this case moved) and conversion of image is completed
Log all photos into a batch to be retrieved later
There are a number of ways I have tried, however, the issue is the only way I have figured out how to log the images is as a single entry in the log without a batch ID. This is because when the data is run via media library, its done one by one and I cannot figure out where to start and end the batch so that its stored as expected.
I am not sure what code to share, happy to share anything though. Here is the basics of what I can think would help
PhotosController.php
public function store(Request $request)
{
//store photos using Spatie Media Library
$user = Auth::user();
$user
->addFromMediaLibraryRequest($request->media)
->withCustomProperties('tags')
// ->withResponsiveImages()
->toMediaCollection('user_photos');
session()->flash('flash.banner', 'Photos Uploaded!');
session()->flash('flash.bannerStyle', 'success');
return Redirect::route('dashboard');
}
Listeners/MediaLogger.php
public function handle(MediaHasBeenAdded $event)
{
$media = $event->media;
if ($media->collection_name == 'user_stories') {
return;
}
$user = Auth::user();
$path = $media->getPath();
LogBatch::startBatch();
activity()->causedBy($user)
->performedOn($user)
->event('new_photo')
->withProperties(['photo' => $path])
->log('uploaded new media!');
LogBatch::endBatch();
}
Any help would be forever grateful, Thanks!

Replace Old image with new image in laravel

CONTROLLER
public function updateproduct(Request $request, $id)
{
// dd($request->all());
$request->validate([
'name'=>'required',
'description'=>'required',
'price'=>'required|numeric',
'quantity'=>'required|numeric',
]);
$product = Product::where('id', $id)->first();
if(is_null($product)) {
$product = new Product();
}
$product->name=$request->name;
$product->description=$request->description;
$product->price=$request->price;
$product->quantity=$request->quantity;
if($request->hasfile('images')){
$existingimages = Image::where(['product_id'=> $product->id, 'source'=> 1])->get();
if($existingimages->count() > 0)
foreach($existingimages as $existingimage) {
$filename = public_path().'files/'.$existingimage->name;
if(file_exists($filename)){
unlink($filename);
$existingimage->delete();
}
}
foreach($request->file('images') as $file){
$name = rand(1,9999).'.'.$file->getClientOriginalName().$file->getClientOriginalExtension();
if($file->move(public_path().'/files/', $name)){
$updateImage = Image::firstWhere('product_id', $product->id);
$updateImage->images = $name;
$updateImage->source = 1;
$updateImage->save();
}
}
}
Please check updated question. Request you to correct me if I wrong. Right now it only updates 1 image and other images remains same. please help me with this.
Your code is somewhat confusing, I'm afraid.
Your request appears to allow for multiple images to be uploaded. Here :
if(file_exists($imagePath)){
unlink($imagePath);
}
you look like you're trying to delete any images that already exist, but when you store upload images you're assigning them a random name (which Laravel can already handle for you, by the way, so there's no need to do it yourself) so you're unlikely to be actually deleting them because there'll likely be no file at that location anyway.
Nowhere does your code actually delete any existing images from the database. Essentially what you want to do is :
If the upload has images, retrieve all the existing images for that product.
Delete the physical files for those existing images.
Delete the database entries for those existing images.
Upload your new images and save their details to the database.
Translating that into code means :
if($request->hasfile('images')){
// Delete any existing image files and database entries.
$existingimages = Image::where('product_id', $product->id)->get();
if($existingimages->count() > 0)
foreach($existingimages as $existingimage) {
$filename = public_path().'files/'.$existingimage->name;
unlink($filename);
$existingimage->delete();
}
}
// Carry on with your upload
}
It adds new images because you are using the Image::create method. If I understood correctly, you want to modify the images of your products in the image table.
Try to modify your code like :
$updateImage = Image::firstWhere('product_id', $product->id);
$updateImage->images = $name;
$updateImage->source = 1;
$updateImage->save();

barryvdh/laravel-dompdf renders blank web page

I'm upgrading from Laravel 7 to 8 and would like to switch to barryvdh/laravel-dompdf for PDF generation. I was using niklasravnsborg/laravel-pdf up until now, but since that package doesn't support Laravel 8, I need to switch. So I am in the processing of altering my existing code to use barryvdh/laravel-dompdf, but I'm running into an issue.
This is my (simplified) controller:
public function update(Request $request) {
$invoice = Invoice::find($request->invoice_id);
if(isset($request->export) AND $request->export == 1) {
$this->exportInvoice($invoice, $request);
}
}
This exportInvoice function is in the same controller file.
I'm using this to generate a test PDF:
$pdf = App::make('dompdf.wrapper');
$pdf->loadHTML('<h1>Test</h1>');
return $pdf->stream();
Now I've managed to narrow down the issue to the place in my code where the PDF generation fails.
If I put the PDF generation code in the if statement in the update function above, then I get the expected result: a simple PDF file.
However, as soon as I move this piece of code to the exportInvoice function, I get a simple blank web page.
I've been googling around, but I was unable to find similar issues.
I've tried putting all my code together in the update function and guess what ... This works as expected. It's as if I'm doing something wrong with the subfunctions, but I can't figure out what.
Does anybody see what I'm doing wrong?
From your update() method, this will stream a PDF back to the browser:
return $pdf->stream();
But from a exportInvoice(), called by the update() method, that will just return the stream back to the update() method. If you don't do anything with it there, it won't reach the browser. You need to return the response returned from exportInvoice().
public function update(Request $request) {
$invoice = Invoice::find($request->invoice_id);
if(isset($request->export) AND $request->export == 1) {
// Note we need to *return* the response to the browser
return $this->exportInvoice($invoice, $request);
}
}
public function exportInvoice($invoice, $request) {
$pdf = App::make('dompdf.wrapper');
$pdf->loadHTML('<h1>Test</h1>');
return $pdf->stream();
}

is there any possibility to display image from public folder in Laravel controller?

this function returns only one image. but I want to show all images which are stored in this folder. can anyone help me?
My controller
public function index()
{
$get=Resturant::all(['id','name','image']);
foreach ($get as $image) {
$path =public_path().'/Images/Resturants/'.$image->image;
$file= File::get($path);
$type= File::mimeType($path);
$response= Response::make($file, 200);
$response->header("Content-Type",$type);
return $response;
}
}
You don't need to be trying to return a file response, since your web server itself can handle serving files in the public folder. Also you wouldn't be trying to return multiple files (somehow) in the response. You can just return an array of the URLs to the files and let what ever is consuming this make the requests to get these files by URL. This would simplify your controller method quite a bit:
return Resturant::pluck('image')
->map(fn ($i) => asset('Images/Resturants/'. $i));
PHP 8 here, but its pretty simple, just have to make URLs from each image.
If you want to have the names to go along with this you can adjust pluck to use a column for the index:
...pluck('image', 'name')...

Laravel production error using Guzzle HTTP to get URL status code

I am running into an issue where I'm getting the following error in my laravel.log file.
[2020-12-20 13:43:43] production.ERROR: URI must be a string or UriInterface
However my code works in development, which is super weird. I'm trying to figure out why this isn't working and i'm just really at a loss and no amount of googling or searching here has answered my question as to why in development vs production this error is occuring.
Heres my function:
/**
* Returns the user avatar or the placeholder avatar
* depending on the Discord Status Code
*
* #param \App\Models\Auth\User $user
* #return \Illuminate\Http\RedirectResponse|mixed|string
*/
public static function getUserAvatar(\App\Models\Auth\User $user) {
$client = new Client();
try {
$response = $client->head($user->avatar);
} catch(BadResponseException $e) {
return "https://dummyimage.com/128x128/888ea8/ebedf2.png?text=No+Image+Found";
}
if($response->getStatusCode() == 200) {
return $user->avatar;
} else {
return "https://dummyimage.com/128x128/888ea8/ebedf2.png?text=No+Image+Found";
}
}
The main functionality is this... whenever a User logs in, their avatar updates from discord (using socialite as the login provider). However if the user changes their avatar in discord, but hasn't logged into our site in a while, that avatar link will just go dead as discord no longer wants to serve it. So the avatar link returns a 404 code. I'm basically just trying to handle this 404 code and not display a broken image on the site. Rather it just be a placeholder image instead.
Edit: When i die and dump on $user->avatar I get the following result:
I've also tried the following as well to no avail:
$response = $client->request('GET', (string) $user->avatar, ['allow_redirects' => false, 'verify' => false]);
Thanks.

Resources