boot function is not firing up on model - laravel-5

class WalletHistory extends ABModel
{
protected static function boot() {
echo 'boot';exit;
parent::boot();
}
}
For above code, I have written some code in boot function in model and it is not firing up.

Normally the creating method should be called within boot():
public static function boot() {
parent::boot();
static::creating(function ($model) {
$model->foo = 'bar';
});
}
And The static boot() method is automatically run whenever a model is instantiated. So here boot method will be called before creating the model i.e. : Model::create();
Hope it helps. For more information may need to see your code.

Related

How do I do the type-hint 'automatic injection' custom class laravel

Below is the EmailNotifier Class
class EmailNotifier
{
public function notify()
{
echo 'Sending payment notification via email' ;
}
}
Below is my AppServiceProvider
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
}
public function register()
{
$this->app->make(App\EmailNotifier::class); // resolve the EmailNotifier Class
}
}
Below is billing class
class Billing
{
protected $notifier;
public function __construct(EmailNotifier $notifier)
{
$this->notifier = $notifier;
}
public function pay()
{
// Process the bill payment
$this->notifier->notify();
}
}
and in my controller I did
$data = new Billing(1);
As you can see I already resolve the EmailNotifier Class at the AppServiceProvider Class but when I call that like the code above, it throws an error said 'must be an instance of EmailNotifier'
and based on the laravel documentation, it's stated that :
you may "type-hint" the dependency in the constructor of a class that
is resolved by the container (for the automatic injection)
how do I achieve automatic injection for the type-hint in laravel ?
Use $data = resolve(Billing::class); instead of $data = new Billing(1); and you can remove $this->app->make(App\EmailNotifier::class); // resolve the EmailNotifier Class from service provider's register method.

Laravel: use extended controller or Traits or something else?

To maintain my Laravel application and save myself from a lot of duplicate code I have made the following solution:
BaseController
class BaseController extends Controller
{
public function get($id){
return $this->baseService->get($id);
}
public function getAll(){
return $this->baseService->getAll();
}
}
BaseService
class BaseService
{
protected $model;
public function __construct($model){
$this->model = $model;
}
public function get($id){
return response()->json($this->model->where('id', $id)->first());
}
public function getAll()
{
return $this->model->get();
}
}
MyController
class MyController extends BaseController
{
protected $model;
protected $baseService;
public function __construct(){
$this->model= new Model();
$this->baseService = new BaseService($this->model);
}
/**
* This controller has all the functionality from BaseController now
*/
}
What I'm wondering if this is a good method. Should I stick with this or should I use a different approach? I've heard about Traits but not sure if they are doing the same thing. It's Laravel 5.5 I'm using.
Yes, traits are used to move methods out of a controller regularly. A good example that the Laravel framework uses is the ThrottlesLogin trait. Take a look at https://github.com/laravel/framework/blob/5.5/src/Illuminate/Foundation/Auth/ThrottlesLogins.php#L20
to see how the methods are moved outside of a controller but can be still accessed by importing the trait using the use keyword.
While traits would work for your use case I wouldn't use them here for the functionality you are looking for. I would use the repository pattern. It would better separate your code and make it more reusable.
Take a look at https://bosnadev.com/2015/03/07/using-repository-pattern-in-laravel-5/ for more information on the repository pattern. Basically, you would separate your code into a separate repository and use Laravel's built in IoC to inject the repository into your controller.
MyController
class MyController extends Controller
{
protected $repo;
public function __construct(MyRepository $myRepository)
{
$this->repo = $myRepository;
}
public function index()
{
$myStuff = $this->repo->all();
}
// you can also inject the repository directly in the controller
// actions.
// look at https://laravel.com/docs/5.5/controllers#dependency-injection-and-controllers
public function other(MyRepository $repo)
{
$myStuff = $repo->all();
}
}
This is the perfect use case for a Trait. Traits are intended for reusable functions. They're super simple to implement, and won't take more than a few minutes to change what you have.
Here is a great article on them: https://www.conetix.com.au/blog/simple-guide-using-traits-laravel-5

Declare value ONCE to use in multiple controller methods - Laravel 5.2

I currently have to declare my Stripe api key in every controller method that will make an api call to Stripe. For example
public function __construct()
{
\Stripe\Stripe::setApiKey(env('STRIPE_KEY'));
}
public function addCard()
{
Stripe::setApiKey(env('STRIPE_KEY'));
}
public function updateCard()
{
Stripe::setApiKey(env('STRIPE_KEY'));
}
public function deleteCard()
{
Stripe::setApiKey(env('STRIPE_KEY'));
}
This is getting very annoying as I have more than 10 methods that are doing this. My question is, is there a way i can declare the key somewhere ONCE and not have to call it in every controller method?
Yep, I'd do it in your AppServiceProvider. You'll find this at app/Providers/AppServiceProvider.php.
Stick it in the register method:
public function register()
{
Stripe::setApiKey(env('STRIPE_KEY'));
}
That will run during bootstrap for every request.
Alternatively you could set this in the constructor for your Controller. This would cause it to run for all actions in this one controller only.
class PaymentController extends Controller {
public function __construct() {
Stripe::setApiKey(env('STRIPE_KEY'));
}
public function addCard() {
...
I'd argue this is less desirable, your service providers should primarily be responsible for wiring up your dependencies. Up to you.

Aggregate injections in Laravel

I have a class to build a report about course registration in Laravel. Following is my class:
class Report {
protected $user;
protected $course;
protected $registration;
public function __construct(User $user, Course $course, Registration $registration) {
$this->user = $user;
$this->course = $course;
$this->registration = $registration;
}
public function build() {
// build report
}
}
Laravel will auto inject the instance of User, Course and Registration Models into Report.
If I need more other Model classes that should be used to build the report, I will need to add more arguments to the constructor of Report.
class Report {
protected $user;
protected $course;
protected $registration;
public function __construct(User $user, Course $course, Registration $registration, Another1 $another1, Another2 $another2, ... ) {
$this->user = $user;
$this->course = $course;
$this->registration = $registration;
}
public function build() {
// build report
}
}
Is this a correct way ?
Does have any other way to aggregate those classes that will be used in the Report class ? Should I use Facade Pattern to refactor it ?
Any help is appreciated.
If you really need that many Model injections it seems highly likely that you need to refactor your code and re-consider how a Report class is constructed.
Instead of Models, learn more about Repositories.
I recommend you also learn more regarding the Single Responsibility principle.
wiki
Since Laravel will inject new instances of these classes, you can consider doing this instead:
public function __construct()
{
$this->createInstances();
}
protected function createInstances()
{
$this->user = new User;
$this->course = new Course;
$this->registration = new Registration;
...
}
EDIT:
Or this to resolve any dependencies of these classes:
protected function createInstances()
{
$this->user = $this->app->make('User');
$this->course = $this->app->make('Course');
$this->registration = $this->app->make('Registration');
...
}

Calling other controller methods from a controller failed in Codeigniter

I want to call upload_controllers methods in admin controller. I've attached my code here. But its not working. Rather its shows Unable to locate the specified class: Session.php
class Admin_controller extends CI_Controller {
public function __construct() {
parent::__construct();
this->load->helper('url');
}
function index(){
require_once(APPPATH.'controllers/uploads_controller.php');
$testObj = new uploads_Controller();
$testObj->index();
}
}

Resources