How to override Auth::attempt($array) in Laravel - laravel-5

Currently Auth::attempt($array) will return Boolean, Is there any way to override the default laravel functionality.
That it should return some value instead of Boolean.

Related

Creating a Laravel attribute (accessor) on model but unable to access model properties

Here's my code:
protected function expires(): Attribute
{
if ($this->started_at) {
$expiry = $this->started_at->addDays(20);
}
return Attribute::make(
get: fn () => $expiry ?? null
);
}
Running this code gives me an ErrorException with the message Undefined property: Models\Job::$started_at
I have found that I can work around this error by accessing the property through $this->attributes['started_at'] as follows:
protected function expires(): Attribute
{
if ($this->attributes['started_at']) {
$expiry = Carbon::parse($this->attributes['started_at'])->addDays(20);
}
return Attribute::make(
get: fn () => $expiry ?? null
);
}
However, this code feels a little inefficient because I'm manually using Carbon to parse the property back into a Carbon object. But if I do a dd($this->started_at) right before the if statement, it's already been cast to a Carbon object by Laravel and I'd really just like to use this object to make my code as clean as in the first example above.
I'd like to know the reason why $this->started_at is apparently available as a Carbon object in this context but somehow not usable (an undefined property) in the way I'm using it, and also I would like to know if there is another way to go about achieving my goal?
you can add custom attributes with
public function getExpireAttribute()
{
if ($this->started_at) {
$this->started_at->addDays(20);
}
return $this->started_at;
}
now you can access expire attribute like other, with
$model->expire
to make Eloquent casts dates to Carbon for you, add attribute to casts:
protected $casts = [
'started_at' => 'datetime',
];
The reason you are getting an "Undefined property" error when trying to access $this->started_at in your accessor method is because Laravel's model accessor methods are executed before the model attributes are hydrated.
This means that when your expires() method is executed, the started_at attribute may not have been set yet, and thus accessing it directly on the model instance will result in an "Undefined property" error.
One way to work around this is to use the getAttribute method provided by Laravel's Model class. This method allows you to retrieve the value of an attribute, even if it has not been set yet. Here's an updated version of your expires() method that uses getAttribute:
use Carbon\Carbon;
protected function getExpiresAttribute(): ?Carbon
{
$startedAt = $this->getAttribute('started_at');
if ($startedAt) {
return $startedAt->addDays(20);
}
return null;
}
In this version, we are using the getAttribute method to retrieve the value of the started_at attribute, even if it has not been set yet. We then use Carbon to manipulate the date, and return the result.
Note that we are using the getExpiresAttribute method instead of the expires method, because Laravel automatically maps get{AttributeName}Attribute method calls to corresponding attribute accessors. So, in this case, calling
$model->expires
will automatically execute the getExpiresAttribute method.
With this approach, you can use the started_at property directly in your code, and it will be automatically cast to a Carbon object by Laravel, without the need to manually parse it with Carbon.
Hope this helps.

How to optionally call mutator in lumen

i use mutator in my model to encrypt id:
public function getIdAttribute($value)
{
return encrypt($value);
}
but I want the default value to be the original value of the id and call the mutator when needed. is that possible?
If you want to be able to call the original value, and sometimes the encrypted value why don't you just add an extra function to your model ?
You won't use a mutator since you want to be able to grab the original value, but you can add an extra function like this in your model which you will be able to call when you want to receive encrypted value.
public function encryptedId()
{
return encrypt($this->id);
}
Or am I missing something?
You can using getRawOriginal() to get original value in lumen:
for example:
$model = Model::find('model_id');
return $model->getRawOriginal('column_name'));

Whats the laravel way to convert boolean string to bool?

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

Backpack V4 modifying field before store

In 3.6 version of backpack I can change an attribute value before storing it.
I have this code
If ($request->description == "") {
$request->description="User has not entered any description";
}
$redirect_location = parent::storeCrud($request);
What can I do to get the same in V4? I'm reading this guide but I can't make it to work.
This is what I'm trying in V4
public function store(PedidoRequest $request)
{
Log::debug('testing...');
If ($request->description == "") {
$request->description="User has not entered any description";
}
$redirect_location = $this->traitStore();
return $redirect_location;
}
The Request object in Laravel, Illuminate\Http\Request, doesn't have the ability to set the inputs via the properties like that, no __set method ($request->description = '...' does not set an input named description). You would have to merge the inputs into the request or use the array syntax to do that:
$request->merge(['description' => '...']);
// or
$request['description'] = '...';
But since backpack seems to have abstracted things apparently you aren't controlling anything in your controller methods you could try this:
$this->crud->request->request->add(['description'=> '...']);
Potentially:
$this->request->merge(['description' => '...']);
That would be assuming some trait the Controller uses is using the Fields trait.

Is there a way to add a phone authentication to the default laravel auth scaffolding

Please is there a way to add phone number authentication to the default laravel auth scaffolding?
In LoginController add this method
// for laravel v5.4+
public function username()
{
return 'phone_number'; // HERE WRITE YOUR FIELD NAME
}
// for older laravel versions
protected function getCredentials(Request $request)
{
return $request->only('field_email', 'field_passwd');
}
This will override your default trait's (AuthenticatesUsers) method for getting the custom username for Authentication.
Also don't forget to make that field in migration as "unique" like this:
$table->string('phone_number')->unique(); // HERE WRITE YOUR FIELD NAME
This will optimize your DB structure and speed up your auth system.

Resources