Laravel excel export using laravel excel killing server - php

I am trying to export an excel file, or a simple csv using laravel excel library but for some reason anything I do with the laravel excel library completly kills the server. Here is me calling the endpoint from postman
and this is what my code looks like in the controller
public function exportPurchases(Request $request)
{
$query = QueryBuilder::for(Purchase::class)
->with(['customer', 'productCategory'])
->allowedFilters(
[
AllowedFilter::partial('product_no')->ignore(['']),
AllowedFilter::partial('model_no')->ignore(['']),
AllowedFilter::partial('serial_no')->ignore(['']),
AllowedFilter::partial('productCategory.name')->ignore(['']),
AllowedFilter::scope('date_of_purchase_lte')->ignore(['']),
AllowedFilter::scope('date_of_purchase_gte')->ignore(['']),
AllowedFilter::partial('customer.first_name')->ignore(['']),
AllowedFilter::partial('customer.surname')->ignore(['']),
AllowedFilter::partial('customer.mobile')->ignore(['']),
AllowedFilter::partial('customer.email')->ignore(['']),
AllowedFilter::partial('customer.town')->ignore(['']),
AllowedFilter::partial('customer.region')->ignore(['']),
AllowedFilter::partial('dealer.name')->ignore(['']),
]);
Excel::store(new PurchaseExport($query), 'purchases.csv', 'public');
return [];
}
It does not matter if I do Excel::store or Excel::download, the result is the same, I have gb extension enabled, infact on another project running on the very same php server I am able to generate and download excel files.

I figured out my mistake, in the purchase exports on the headings function I had a self referencing function as I had a private array property called headings I was supposed to return there instead of calling it as a function.
public function headings(): array
{
return $this->headings();
}
correct was
public function headings(): array
{
return $this->headings;
}

Related

Method App\Http\Controllers\CD4Controller::importcd4 does not exist. Facing this error

I want to upload excel file to database table CD4 and I am facing issue this method can't find.
Route::get('importcd4',[CD4Controller::class, 'importcd4'])->name('importcd4');
Here is controller function:
public function importcd4(){
Excel::import(new CD4, request()->file('file')->store('files'));
return redirect()->route('cd4.index')->with('success');
}
}
Need solution for that and I want to know why it's showing this error to me.

Laravel: DOMPDF error when trying to get PDF

I've been trying to get the PDF of a view using DOMPDF with a table full of ingredients populated from a database table.
I created a function in my Controller:
public function createPDF() {
// retreive all records from db
$data = Ingredients::all();
// share data to view
view()->share('ingredients', $data);
$pdf = PDF::loadView('printableingredientslist', $data);
// download PDF file with download method
return $pdf->download('printableingredientslist.pdf');
}
And the route in web.php is defined as:
Route::get('/printpreviewingredients/pdf', [MealPlanDisplayController::class, 'createPDF']);
However, I keep getting this error:
fopen(D:\mealplan\storage\fonts//nunito_normal_46b9b3b48cc3ddbae60da82f1c1c5d29.ufm):
failed to open stream: No such file or directory
It must be something to do with the 'printableingredientslist' as when I replaced it with a plain view page with simple text that worked. I am struggling to see how there's a path issue however, as printableingredientslist.blade.php is simply under the views folder. What can the issue be? I am using tailwind.css, could that be a problem?
setOptions method to use default font.For example like below
public function pdf()
{
$pdf = \PDF::loadView('contact')->setOptions(['defaultFont' => 'sans-serif']);
return $pdf->download('invoice.pdf');
}
or
Create the directory fonts in storage directory
Ref: https://github.com/barryvdh/laravel-dompdf/issues/724
Ref:https://github.com/barryvdh/laravel-dompdf/issues/176
Ref:https://github.com/barryvdh/laravel-dompdf/issues/269

Livewire encountered corrupt data when trying to hydrate the … component

I am getting the following error and am a bit lost on it:
Livewire encountered corrupt data when trying to hydrate the …
component. Ensure that the [name, id, data] of the Livewire component
wasn’t tampered with between requests
Situation is as follows: Livewire 2.x, Laravel 7.x, Component Controller fetches data from 3 MySQL Stored Procedures and processes it. Component Blade is a pretty basic blade with foreach loop. I am using the wire:init feature so that the component is not blocking the page load. It contains a custom-built pagination. When switching to the second page of data, this error occurs. It did not error out while on Livewire 1.x.
Has anyone any idea on how to tackle this problem? The error itself does not speak much to me. Any additional info required?
Thank you in advance, appreciate any help!
In my case the solution was to make a public property protected and pass it to the blade manually, so it was excluded from Livewire's auto-handling under the hood.
To troubleshoot this open the vendor/livewire/livewire/src/ComponentChecksumManager.php file and add var_dump($stringForHashing); on line 19, just before the return statement. Then you can see the data that is being hashed and compare it to the previous hashed data to find the discrepancies.
After I did this I was able to identify the numeric keys that javascript was re-arranging and come up with an adequate fix.
One thing to note is that some json formatters will re-order numeric keys also, so it's better to compare the json without formatting it or format it manually.
Edit:
Using var_dump can interfere with the functionality on some pages, so writing the data to a file might be a better option:
file_put_contents('/path/to/log.txt', $stringForHashing . "\n\n", FILE_APPEND);
For what it worth, our issue was a very large integer, larger than what javascript can handle through Number.MAX_SAFE_INTEGER.
We filled a bug report here: https://github.com/livewire/livewire/discussions/4788 (livewire 2.10.4).
So, no solution for the bug itself when using too large integer. If you want to treat your value as a real integer you’re in no luck for now, but maybe casting to string could work for you. (and/or do your computations on the php side – with protected property – if it’s doable in your case).
That being said, the real cause of our problem was an uuid casted to int because we did not filled the protected $keyType = 'string'; of our laravel model (https://laravel.com/docs/9.x/eloquent#primary-keys)!
i run following command then it solved
php artisan optimize
So I was getting the same error, this one:
Livewire encountered corrupt data when trying to hydrate the [component] component. Ensure that the [name, id, data] of the Livewire component wasn't tampered with between requests.
After trying the accepted answer and reading this long issue thread on Livewire's Github, I played around with passing data to the view in different ways. I'm sharing it here to help someone else with the same use case issue.
I found the following change, where an url I was previous passing I just got in the view instead, made it go away. From:
// Class
class MyComponent extends Component
{
public Shop $shop;
public Address $address;
public string $action;
// rules etc
public function mount(Shop $shop)
{
if ($shop->address()->exists()) {
$this->address = $shop->address;
$this->form_action = route('merchant.shop.address.update');
} else {
$this->address = Address::make();
$this->form_action = route('address.store');
}
}
// view
<div>
<form method="post" action="{{ $action }}">
#csrf
to:
// class
class MyComponent extends Component
{
public Shop $shop;
public Address $address;
// rules etc
public function mount(Shop $shop)
{
$this->address = $shop->address()->exists() ? $shop->address : Address::make();
}
// view
<div>
<form method="post" action="{{ $shop->address()->exists() ? route('merchant.shop.address.update') : route('address.store') }}">
In my case, I had a couple of public variables and not all of them were being passed in from the parent view. After reading Markus' answer. I went and added the mount method to my livewire class and passed in the variables I was inheriting from the parent and it worked. I am using Livewire 2.3
This had the error
class MyView extends Component
{
public $fromParent, $local;
public function render()
{
return view('livewire.my-view');
}
}
Adding mount fixed it
class MyView extends Component
{
public $fromParent, $localVariable1, localVariable2;
public function mount($fromParent)
{
$this->fromParent = $fromParent;
}
public function render()
{
return view('livewire.my-view');
}
}
In my case the problem came from a database query and the resulting collection.
This query (the meaning of the variables is not important)
DB::table('progress_trackings')
->select('user_id')
->whereIn('user_id', $users->pluck('id'))
->where('object_id', $activity->id)
->where('event', $type)
->get()
->keyBy('user_id');
Produced this output:
Illuminate\Support\Collection {#2427
all: [
454 => {#2279
+"user_id": 454,
},
528 => {#441
+"user_id": 528,
},
531 => {#2368
+"user_id": 531,
},
],
The query was triggered by a button in the blade file.
Clicking the button 2 or 3 times resulted in the hydration error.
In the Livewire docs it is explained that array keys sometimes can cause problems: https://laravel-livewire.com/docs/2.x/troubleshooting
So I tried to make a plain array out of the db query result. Since I only needed the keys, this worked:
DB::table('progress_trackings')
->select('user_id')
->whereIn('user_id', $users->pluck('id'))
->where('object_id', $activity->id)
->where('event', $type)
->get()
->keyBy('user_id')
->keys()->toArray(); // ADDED THIS
Now the result is:
[
454,
528,
531,
]
Which solved the hydration error.
Addition to what others suggested above also this might happen if you have a collection which uses groupBy() might be the cause for this issue,
To fix this use protected $attribute in your component instead of public then pass $attribute to the component view.
protected $attribute;
public function mount($attribute){
$this->attribute = $attribute;
}
...........
public function render()
{
return view('livewire.view-here',['attribute'=>$attribute]);
}
I did this and it worked for me:
php artisan config:cache
php artisan config:clear
In my case it was image accessor for API i was trying to get full link image for API in model this is my mistake
public function getImageAttribute($value)
{
return $value ? url(Storage::url($value)) : '';
}
This cause me Livewire encountered corrupt data..
the solution in my case was
public function getImageAttribute($value)
{
if (Str::contains(Request()->route()->getPrefix(), 'api')) {
return $value ? url(Storage::url($value)) : '';
}
return $value;
}
In my case, I had the affected livewire component in another component.
//livewire component
<x-layouts.content-nosidebar title="false">
<div class="verification section-padding">
</div>
</x-layouts.content-nosidebar>
I removed the livewire component into its own file and I stopped getting the error.
//livewire component
<div class="verification section-padding">
</div>
Its looking, like there are some public variables that have been either set or unset (value-filled or blank by your code) using any Livewire Hook method.
Please check those and fix them, these values are not set or unset properly during the lifecycle hook method call, I also have faced this issue and fixed it.
In my case, in the updated hook method, I have changed
This
$this->{'selectGroup.'.$value} = false;
To
$this->selectGroup[$value] = false;
Worked well for me, I hope it would make sense.
I successfully fixed this by downgrading from php8 to php7.4
My project was running fine on Production, however for some reason I kept getting the "corrupt data when trying to hydrate" locally which used php8
I tried a ton of things, but eventually downgrading was the 1 thing that worked. Not sure what the difference is but try that.
I use custom class properties a lot, so in my case it was a hydration problem.
Even when any of the upstream classes is not implementing Wireable interface, you'll get the exception.
Even for enum, which was in my case.
Component
public Notifications $notifications;
public function mount()
{
$this->notifications = new Notifications([
new Notification(Type::Slack);
]);
}
Notifications class
class Notifications implements Wireable
{
public function toLivewire(): array
{
// convert to array
}
public function fromLivewire($value): self
{
// convert from array to Notifications
}
}
Notifications class
class Notification implements Wireable
{
public function toLivewire(): array
{
// convert to array
}
public function fromLivewire($value): self
{
// convert from array to Notification
}
}
Implementing enum solved my problem
I frankly didn't know that enums can implement interfaces.
enum Type: int implements Wireable
{
case Slack = 1;
case Teams = 2;
public function toLivewire(): int
{
return $this->value;
}
public static function fromLivewire($value): Type
{
return self::from($value);
}
}
Hope that helps.
In my case, the Livewire component was referencing a model that had a custom attribute which was calculated using Carbon::now()
So that attribute had a different value every time the component tried to hyrdrate, and therefore was "corrupted".
I faced this error, when I added an array of a Value Object into the livewire component.
It was a very simple value object class like this:
class Foo {
public string $name;
public string $data;
}
After several hours of struggling, it became clear that solution was simply adding a $id property to the Foo class:
class Foo {
public string $id; // a unique id
public string $name;
public string $data;
}
By adding $id, livewire now can keep state of a collection of objects.
I solved it by putting livewire scripts #livewireScripts inside page header
<head>
<meta charset="utf-8" />
#livewireStyles
#livewireScripts
</head>

Laravel GET image as file along with other data

I have an Ionic application that communicates with my Laravel api. I'm trying to get the product details and image from the api and display that data in my Ionic app. I have the images stored on the local disk and also have a db table that contains the path name for each image. But when the Ionic app gets this data back, it just gets a json object that contains the mainImage with a path to the local disk, which of course, I can't use as an img src. My question is, how do I pass the mainImage as a file rather than a json object?
Here is my Laravel function:
public function api_get_non_disliked_for_user($categoryId)
{
$allProducts = Product::with('mainImage')
->where('subSubCategoryId', "=", $categoryId)->orderBy('title')->get();
return $allProducts;
}
In Product Model:
public function mainImage(){
return $this->hasOne('App\MainImage', 'productId');
}
In MainImage Model:
public function product(){
return $this->belongsTo('App\Product', 'productId');
}
The API should provide the url to the image, not the image file, specially when using Ionic as the front end, because then you just use the url in your html markup and the image will get downloaded automatically.

url mapping in code igniter

I'm writing a PHP application using codeigniter framework. I'm trying to add a tool to download the data in the page as a .csv format file. I have the code to the server side, but I'm having trouble handling the URL mapping for the "Download" Controller.
in /controllers/ I have a controller called "Download", which is has a function called 'exportCSV', which receives a json object that is decoded and used to create the file. So, I'm trying to send a JavaScript array through 'post' to that method, but I'm having trouble handling the URL mapping.
here is my javascript call ...
function download(){
$.post('index.php/download/exportCSV', {input : dataForDownload.toString()},
function(answer){
alert(answer);
}
);
}
POST to index.php/download/exportcsv. CI doesn't much like Mixed Case controllers.
If you have a download controller, it should look like this:
class Download extends CI_Controller
{
function _construct()
{
parent::_construct();
}
function exportcsv()
{
if($this->input->post())
{
// Something was POSTed, continue
// process input
} else {
// Catch error if no POST
}
}
}
If you're getting a 404, your application might not be set up correctly. Check routes.php and your base_url.
I also recommend the CodeIgniter user guide. It's full of good information:
http://codeigniter.com/user_guide/overview/appflow.html
http://codeigniter.com/user_guide/overview/mvc.html

Categories