How to reuse functions using services

Hello. I have made a function that I need to call from two different observers, and both in the created and update methods (I have to call it 4 times). I have tried to have one only function in an functions file and call it from the 4 different places, but I have not succeded. It is just a 10 line function, but there must be a better way to do this either than repeating the code 4 times. Any ideas of how to call a function which is in an external FUNCTIONS CUSTOM FILE from inside the observers? I understand that inside the same Observer I can use: $this->nameOfFunction() But how to call that from an outer file?
Solution:
Sounds like you need a service class or a helper class.
Jump to solution
2 Replies
Solution
awcodes
awcodes4mo ago
Sounds like you need a service class or a helper class.
Albert Lens
Albert Lens3mo ago
Perfect approach. Thank you. I created a Service and it is working perfectly. I'll give my example just for if it helps someone in the future: Created file (Media is what I want to change): app\Services\MediaService.php That file is:
<?php
namespace App\Services;
use App\Models\Pago;
use App\Models\User;
use App\Models\Media;
use App\Models\Expediente;

class MediaService {
public function recalculaMediaNumExp()
{
$mediaExpedientes=Media::where('model_type','App\Models\Expediente')->get();
foreach ($mediaExpedientes as $mediaExpediente) {
$num = $mediaExpediente->model_id;
$expediente = Expediente::find($num);
$mediaExpediente->numExp = $expediente->numExp;
$mediaExpediente->save();
}

$mediaPagos=Media::where('model_type','App\Models\Pago')->get();
foreach ($mediaPagos as $mediaPago) {
$num = $mediaPago->model_id;
$pago = Pago::find($num);
$mediaPago->numExp = $pago->expediente->numExp;
$mediaPago->save();
}
}
}
<?php
namespace App\Services;
use App\Models\Pago;
use App\Models\User;
use App\Models\Media;
use App\Models\Expediente;

class MediaService {
public function recalculaMediaNumExp()
{
$mediaExpedientes=Media::where('model_type','App\Models\Expediente')->get();
foreach ($mediaExpedientes as $mediaExpediente) {
$num = $mediaExpediente->model_id;
$expediente = Expediente::find($num);
$mediaExpediente->numExp = $expediente->numExp;
$mediaExpediente->save();
}

$mediaPagos=Media::where('model_type','App\Models\Pago')->get();
foreach ($mediaPagos as $mediaPago) {
$num = $mediaPago->model_id;
$pago = Pago::find($num);
$mediaPago->numExp = $pago->expediente->numExp;
$mediaPago->save();
}
}
}
Then, when I need to call that function called recalculaMediaNumExp() I do this: Added the use at the beginning like this:
use App\Services\MediaService;
use App\Services\MediaService;
call the function like this:
public function created(Pago $pago): void
{
(new MediaService())->recalculaMediaNumExp();
}
public function created(Pago $pago): void
{
(new MediaService())->recalculaMediaNumExp();
}
Being careful to consider: 1 - In my case I need no parameters to be passed 2 - As this function is : void, no return is needed/possible 3 - If the function inside which you are calling the recalculaMediaNumExp() is not void you must use return:
return (new MediaService())->recalculaMediaNumExp();
return (new MediaService())->recalculaMediaNumExp();
This is the perfect approach, I think, because if I need to update some parts of the function I will do it in one place only. I will change the title to -> How to reuse functions using services Although I understand this is a Laravel issue and not specifically Filament. Thanks again.