Troubleshooting's post
How to use select2 with livewireLaravel

How to use select2 with livewireLaravel
We can resolve this issue by using a livewire javascript hook.
Here is my screen with select2 before livewire component rendering.

And when the livewire component is refreshed means re-render the select2 style is gone ☹️

How to Fix it ?? 🤔
document.addEventListener('livewire:load', function (event) { window.livewire.hook('afterDomUpdate', () => { $('#select2ID').select2(); }); });
livewire:load is listening events when livewire component is load and we can add our code within it.
And now when your livewire component is refreshed your select2 style will be still there as we are again applying it.
Other Livewire Posts :
Use Laravel Debugbar's measure function to optimize application performanceLaravel

Use Laravel Debugbar's measure function to optimize application performanceLaravel
Laravel Debugbar is a great package to debug laravel applications while development. But it's not just limited to debugging. You can use it to optimize the performance of your app a lot as well. Like,
- number of models loaded in a memory
- number of queries fired with timing
- memory used and more.
In short, we can have a complete view of what's going on in each request.
But the less known and use feature it gives is the Timeline tab. Where you can see how much time is taken for each request. And more than that, how much time Laravel took to boot up and how much time our other code has taken. Check the below screenshot.
Recently we came to the case, where one of our consultation clients' CRM application was taking too much time on the first load. Their developers were not able to spot a problem. They checked queries and other stuff which looked completely good. so we were not sure where the time has been spent by the application.
That's were debugbar came to rescue us. We used its measure function facility by which we can measure the time spent in each of the function wherever we want to use. It gives simply two functions startMeasure
and stopMeasure
to measure the time spent between these two statements.
so we can put startMeasure
in the staring of function and put stopMeasure
at the end of the function which will render something like this in the timeline tab.
public function searchClients($department)
{
\Debugbar::startMeasure("searchClients");
// logic here
\Debugbar::stopMeasure("searchClients");
return $result;
}
Once we put this, we get a time that searchClients
is taking. Check the screenshot below,
Hope this can help you to figure out what piece of code is taking the time and you can optimize it.
Happy Optimizing :)
How to remove public path from URL in Laravel ApplicationLaravel

How to remove public path from URL in Laravel ApplicationLaravel
While hosting on the Laravel project on cPanel, the traditional problem that lots of developers get is, /public
path is appended to the URL. Because in most cases, we put a project directly into the public_html
folder, so public_html
is our root for the website and that's where our laravel application is also placed.
But to run the Laravel application, we need to point our domain root to the public
folder of the laravel. It is possible to do with cPanel but you need to go through some steps which are not known by most of the people and also the tedious process.
So to make it simple, what you can do is, there is a way we can do it via .htaccess
file in our root folder.
We can copy .htaccess
file from our public
folder and then make modifications to it to work with the direct root folder and route every request to the public
folder.
Here is the final .htaccess
file,
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization MemberHeader
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Remove public URL from the path
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(.*)$ /public/$1 [L,QSA]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
By adding the above file to the root folder we can use laravel project without the public path. Check out the following two lines:
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(.*)$ /public/$1 [L,QSA]
These two lines make magic and our application will work without public
path in URL.
Custom path generation in Spatie Media Library while multi-tenantLaravel

Custom path generation in Spatie Media Library while multi-tenantLaravel
Recently we use Spatie laravel-multitenancy package in our of our client's CRM project along with spatie/laravel-medialibrary.
The default behavior of the media library package is, it generates a folder for each media with its ID in our configured disk, like a public folder or s3 or whatever disk we configured.
This works really great when you are dealing with a single-tenant application. But while using multi-tenant, you got a media table in each of your tenant databases. so this pattern simply doesn't work. Because then you will end up having multiple media files under the same folder from different tenants.
So what we want to do is, instead of having a structure like,
public
-- media
---- 1
------ file.jpg
---- 2
------ file.jpg
...
What we want to achieve is, we want to have a folder structure where media of every tenant will be in a separate folder with tenant unique id,
public
-- media
---- abcd1234 // tenant1 Id
------ 1
-------- file.jpg
------ 2
-------- file.jpg
---- efgh5678 // tenant2 Id
------ 1
-------- file.jpg
------ 2
-------- file.jpg
...
Spatie Media library is very configurable out of the box where you can write your own media library path generator. That is documented very well over here: https://docs.spatie.be/laravel-medialibrary/v8/advanced-usage/using-a-custom-directory-structure
So what we did is, we wrote our own Path Generator, which can store files into tenants folder. Here is how it looks like,
<?php
namespace App\MediaLibrary;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
use Spatie\MediaLibrary\Support\PathGenerator\DefaultPathGenerator;
class InfyCRMMediaPathGenerator extends DefaultPathGenerator
{
/*
* Get a unique base path for the given media.
*/
protected function getBasePath(Media $media): string
{
$currentTenant = app('currentTenant');
return $currentTenant->unique_id.DIRECTORY_SEPARATOR.$media->getKey();
}
}
What we did here is, we just simply extended the Spatie\MediaLibrary\Support\PathGenerator\DefaultPathGenerator
of Media Library and override the function getBasePath
. We attached the prefix of the tenant's unique_id
to the path. so instead of 1/file.png
, it will return abcd1234/1/file.png
.
All you need to make sure is, whenever you are uploading a media, your application should be tenant aware. Otherwise, it will not able to get the current tenant.
Hope this helps while using spatie media library along with spatie multi-tenant.
Even if you are not using a spatie multi-tenant, still you can create your own PathGenerator and use it your own way to have a media structure you want.
DateTimeLocal with LaravelCollective Model BindingLaravel

DateTimeLocal with LaravelCollective Model BindingLaravel
Last week, we were working on one project where we were using LaravelCollective for generating our form. LaravelCollective is a really awesome package and reduces lots of efforts, specifically for automatically binding old inputs to our forms.
Problem
With LaravelColletive when we pass null
as a second value, it tried to get old inputs if available and inject them. But for some reason, it was not working with datetimelocal
.
datetimelocal
need a date in Y-m-d\TH:i
Format. When I went into the code of FormBuilder.php, it’s already managing that and tries to convert date into that format if you have passed DateTime
object.
So it was completely working fine while creating a record when you do not have any value.
But I have the same form which was used at both the time of Create and Update. And I was passing null
into value field at both of the time and LaravelCollective injects it automatically from model or old inputs if there is some error. Something like following,
<div class="form-group col-sm-6">
{!! Form::label('due_date', 'Due Date:') !!}
{!! Form::datetimeLocal('due_date', null, ['class' => 'form-control']) !!}
</div>
So, Due date will be automatically placed from the model. It’s working fine with all other fields except datetimelocal
.
Solution
The reason behind that is, the value is retrieved from model due_date field, but it comes in Carbon instance and when it converts to a date string, it’s converted into default format which is Y-m-d h:i:s
. So it will not work for datetimelocal
input since it requires Y-m-d\TH:i
format.
So as a solution, what change we did is, instead of passing null
value, we first check, if the model is there then pass the value directly to the input. Something like,
<div class="form-group col-sm-6">
{!! Form::label('due_date', 'Due Date:') !!}
{!! Form::datetimeLocal('due_date', (isset($task)) ? $task->due_date : null, ['class' => 'form-control']) !!}
</div>
So, I will check if I have passed the model $task
to the view and then I will pass a due_date value to input. So FormBuilder will convert it to the proper format and it will get displayed into an input.
Now, when we save the form, it will also return date into Y-m-d\TH:i
format, so again we need to convert it to the proper format. For that, we created a mutate attribute for due_date
in my Task Model.
public function setDueDateAttribute($value)
{
$this->attributes['due_date'] = Carbon::parse($value);
}
And that’s it. Our datetimelocal
input gets working. I have seen lots of issues on stackoverflow for it. So hope it may help someone.