useful for say, laravel components, where often text can be handed by mistake e.g.
<x-mything render="false"/>
this will be string "false" and
if("false"){
// is truthy
}
the php way to handle this is here
https://stackoverflow.com/a/15075609/533426
is there a laravel way to do it?
the answer:
do
<x-mything :render="false"/>
is not the answer I'm looking for. I'm looking for a laravel way to cast string to boolean like in the linked post
if(!filter_var($render, FILTER_VALIDATE_BOOLEAN)) {
// is falsy
}
Encapsulate this in a string macro. In the AppServiceProvider boot method add;
use Illuminate\Support\Str;
public function boot()
{
Str::macro('isFalsy', function ($str) {
return !filter_var($str, FILTER_VALIDATE_BOOLEAN);
});
}
now in code Str::isFalsy($render) or in Laravel 9 str($render)->isFalsy()
or swap the logic and create an isTruthy() macro
Related
good day, I am using Tucker-Eric/EloquentFilter Laravel.
I want to filter it by relationship using Models
I want to automate it, instead of using the following:
public function users($users)
{
// dd($users);
return $this->r('users', $users);
}
public function user($user)
{
// dd($user);
return $this->r('user', $user);
}
public function owner($owner)
{
// dd($owner);
return $this->r('owner', $owner);
}
I want to make it one function that based on the relationship
so that I want to add another relationship on the model I don't need anymore to add another function.
Thanks!
We specifically stayed away from the type of implicit functionality you're looking for and opted for explicit filter methods to avoid security issues if/when new relations/properties were added to a model they wouldn't implicitly be available to filter against.
With that, what you're looking for isn't recommended because of the security concerns above but it can still exist if you implement it.
It sounds like the setup method would be the best place to implement it since it would be called first every time ->filter() is called.
public function setup()
{
foreach($this->input() as $key => $val) {
if($this->getModel()->$key() instanceof \Illuminate\Database\Eloquent\Relations\Relation) {
// Your logic here
}
}
}
I have created new component using php artisan make:component Test.
Now, when creating that component, if I try to pass one word variable everything works fine (<x-test :testID="'test'"). But when I try passing it as multi word, separating words by using underscore (<x-test :test_id="'test'"), I am facing next error:
Unresolvable dependency resolving [Parameter #0 [ <required> $test_id ]] in class App\View\Components\Test
And that class looks like this:
class Test extends Component
{
public $test_id;
public function __construct($test_id)
{
$this->test_id = $test_id;
}
public function render()
{
return view('components.test');
}
}
Is this normal behaviour and is it even allowed to use underscore when creating variables inside components?
Livewire components do not support the classical __construct constructor. Instead you better use the mount() method.
Furthermore you should work with public properties like this
public $test_id;
public function mount()
{
// properly initialize the var
$this->test_id = 0;
}
and reference (see Data Binding) it in your view with
<x-test wire.model="test_id"/>
I generally would always go for camelCase naming, f. ex. testId. This is definately fully supported in Livewire (see docs).
Some general hint about naming variables
What you describe with one word and multi word variable is named
camel case, f. ex. myVariableName, Wikipedia
snake case, f. ex. my_variable_name, Wikipedia
Update for comment component
class Comments extends Component
{
public int $postId;
public function mount()
{
$this->postId = 0;
}
public function render()
{
$comments = Comments::where('post_id', $this->postId)->get();
return view('post.list', [
'comments' => $comments,
]);
}
}
In your views you can use something like this.
<x-comments :postId="$post->id"/>
You don't need to inject it into the mount method. Just use the public property.
I face the same issue. I can't pass in :dd_array="$dd_color" to an anonymous blade component, but passing it like :ddArray="$dd_color" works fine.
When using custom keys Laravel forces us with scoping, for example, I have a route to getting a country and a post
api/countries/{country:slug}/posts/{post:slug}
but I can't get that using slug key because it doesn't have a relation with country, and in this case, I want to handle scope myself and I don't need implicitly scope binding, but I get an error (Call to undefined method App\Country::posts() ).
so because of that I cant using this Laravel feature. is there a way to turn the implicitly scope binding off?
If the posts are not related to the countries, it may not make sense to nest them in the URI?
But, nonetheless, to answer your question, you need to do one of two things:
Instead of setting {country:slug}, just use {country} and then override getKeyRouteName() function on your Country and Post models.
Alternatively, especially if you want to use the ID elsewhere, use explicit model binding.
To use a slug without custom keys in the routes file
class Post
{
[...]
public function getRouteKeyName()
{
return 'slug';
}
}
To use explicit route model binding
Add the following to the boot() method of your RouteServiceProvider:
public function boot()
{
parent::boot();
Route::bind('post', function ($value) {
return App\Post::where('slug', $value)->firstOrFail();
});
}
As we know in Laravel 5.2 Route::controller() and Route::controllers() method was deprecated but it was very handy for reducing the number of routes. I was able to write simple route like this Route::controller('admin/invoice','InvoiceController'). With this simple one route, I can manage all things related to making invoice related work by a controller.
class InvoiceController extends Controller{
public function getInvoices(){ }
public function getInvoiceDetails(){ }
public function postStoreInvoice(){ }
public function postUpdateInvoice(){ }
public function postStoreInvoiceDetails(){ }
public function postupdateInvoiceDetails(){ }
public function postDeleteInvoice(){ }
public function postDeleteInvoiceDetails(){ }
....
}
but unfortunately this Route::controller() and Route::controllers() no longer available laravel version > 5.1. An option available Route::resource() but it has a limited number of the route. The laravel route is Macroable, there is an option to extend the route features like
Illuminate\Routing\Router::macro('controller', function ($routes) {
// implementation
});
Is there anyone who implements Route::controller() and Route::controllers() method for Laravel 5.8, 6 ? or suggest any way.
You can use Route::resource() or Route::resources().
Example:
Route::resource('books', 'BookController');
this will assumes you have
class BookController extends Controller {
// to list resources.
public function index();
// to show create form.
public function create();
// to store resource in database.
public function store();
// to show single resource.
public function show();
// to show edit form.
public function edit();
// to edit and then store the modified resource in database.
public function update();
// to delete a resource from database.
public function destroy();
}
You should read https://laravel.com/docs/master/controllers#resource-controllers for more information.
Edit
Implicit controllers was removed in version 5.2 for some reason.
If you come from the CodeIgniter world, then you may have warm and fuzzy
feelings for implicit routing. You know, where the URI matches up to
the controller method that will be called. You might even want this
for your Laravel development (which Laravel can do).
Though it might seem useful at first to simply call
Route::controller('admin', 'AdminController') and then declare all of
your desired routes from the controller, there are a number of
setbacks to this. Think about how you would, when using implicit routing,
leverage named routes, or create nested resources, or even do
something as simple as rename your controller class without affecting
your URI design.
No, when it comes to implicit routing, just say no.
source: https://laracasts.com/lessons/say-no-to-implicit-routing
However if you want this functionality you can use this package:
Laravel Routes Publisher or Laravel Advanced Route
I have some simple logic in my Controller. But I often use it in other method. Here is an example.
In my controller.
public function method1()
{
if(isset(Auth::user()->showroom->name)){
$showroomName = Auth::user()->showroom->name;
}else{
$showroomName = "Belum Ada Izin";
}
return view('method1view', compact('showroomName'));
}
public function method2()
{
if(isset(Auth::user()->showroom->name)){
$showroomName = Auth::user()->showroom->name;
}else{
$showroomName = "Belum Ada Izin";
}
return view('method2view', compact('showroomName'));
}
... so on
How I can follow DRY principle in my case?
Any help will be appreciated.
Thanks in advance.
For cleaner and shorter syntax, use data_get helper:
data_get(Auth::user(), 'showroom.name', 'your default value');
This in most cases comes handy, but not always is the best way.
However, in your example it seems, that maybe in fact you'd like to simply share this variable across your views - use share or a View Composer described in the docs.
In your Showroom model you could include the following function:
public function getNameAttribute($value)
{
return isset($value) ? $value : 'Belum Ada Izin';
}
That's assuming you want that behavior everywhere showroom->name is used. If not, make the function getNameWithDefaultAttribute, check $this->name in the body, and reference it in the controller like Auth::user()->showroom->name_with_default