• 11
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

name Punditsdkoslkdosdkoskdo

How to replace the Laravel Builder class

I want to replace the Laravels builder class with my own that's extending from it. I thought it would be as simple as matter of App::bind but it seems that does not work. Where should I place the binding and what is the proper way to do that in Laravel?

This is what I have tried:

my Builder:

    use Illuminate\Database\Eloquent\Builder as BaseBuilder;
    class Builder  extends  BaseBuilder
    {

        /**
         * Find a model by its primary key.
         *
         * @param  mixed  $id
         * @param  array  $columns
         * @return \Illuminate\Database\Eloquent\Model|static|null
         */
        public function find($id, $columns = array('*'))
        {
            Event::fire('before.find', array($this));
            $result = parent::find($id, $columns);
            Event::fire('after.find', array($this));
            return $result;
        }
    }

And next I tried to register the binding in bootstrap/start.php file like this :

$app->bind('Illuminate\\Database\\Eloquent\\Builder', 'MyNameSpace\\Database\\Eloquent\\Builder');
return $app;

Illuminate\Database\Eloquent\Builder class is an internal class and as such it is not dependency injected into the Illuminate\Database\Eloquent\Model class, but kind of hard coded there.

To do what you want to do, I would extend the Illuminate\Database\Eloquent\Model to MyNamespace\Database\Eloquent\Model class and override newEloquentBuilder function.

public function newEloquentBuilder($query)
{
   return new MyNamespace\Database\Eloquent\Builder($query);
}

Then alias MyNamespace\Database\Eloquent\Model to Eloquent at the aliases in app/config/app.php

  • 11
Reply Report

The answer above doesn't exactly work for laravel > 5 so I done some digging and I found this!

https://github.com/laravel/framework/blob/5.2/src/Illuminate/Database/Eloquent/Model.php#L1868

use this instead!

protected function newBaseQueryBuilder()
{
    $conn = $this->getConnection();
    $grammar = $conn->getQueryGrammar();
    return new QueryBuilder($conn, $grammar, $conn->getPostProcessor());
}
  • 3
Reply Report

Both of the answers are correct in some way. You have to decide what your goal is.

Change Eloquent Builder

For example, if you want to add a new method only for eloquent models (eg. something like scopes, but maybe a little more advanced so it’s not possible in a scope)

Create a new Class extending the Eloquent Builder, for Example CustomEloquentBuilder.

use Illuminate\Database\Eloquent\Builder;


class CustomEloquentBuilder extends Builder 
{

    public function myMethod()
    {
        // some method things
    }

}

Create a Custom Model and overwrite the method newEloquentBuilder

use Namespace\Of\CustomEloquentBuilder;
use Illuminate\Database\Eloquent\Model;


class CustomModel extends Model
{

    public function newEloquentBuilder($query)
    {
        return new CustomEloquentBuilder($query);
    }

}

Change Database Query Builder

For example to modify the where-clause for all database accesses

Create a new Class extending the Database Builder, for Example CustomQueryBuilder.

use Illuminate\Database\Query\Builder;


class CustomQueryBuilder extends Builder 
{

    public function myMethod()
    {
        // some method things
    }

}

Create a Custom Model and overwrite the method newBaseQueryBuilder

use Namespace\Of\CustomQueryBuilder;
use Illuminate\Database\Eloquent\Model;


class CustomModel extends Model
{

    protected function newBaseQueryBuilder()
    {
        $connection = $this->getConnection();

        return new CustomQueryBuilder(
            $connection, $connection->getQueryGrammar(), $connection->getPostProcessor()
        );
    }

}

Laravel Version: 5.5 / this code is untestet

  • 2
Reply Report

Warm tip !!!

This article is reproduced from Stack Exchange / Stack Overflow, please click

Trending Tags

Related Questions