ehsanquddusi's avatar

Error in Eloquent Pagination outside Laravel

I am using Illuminate/database package outside Laravel with my CodeIgniter setup. The initialization is done using Capsule class like this

use Illuminate\Database\Capsule\Manager as CapsuleManager;
use Illuminate\Events\Dispatcher;
use Illuminate\Container\Container;

class Capsule extends CapsuleManager
{
public function __construct()
{
    parent::__construct();

    require_once __DIR__.'/../config/database.php';
    $db = (object) $db['default'];

    $this->addConnection(array(
        'driver'    => 'mysql',
        'host'      => $db->hostname,
        'database'  => $db->database,
        'username'  => $db->username,
        'password'  => $db->password,
        'charset'   => $db->char_set,
        'collation' => $db->dbcollat,
        'prefix'    => $db->dbprefix,
    ));

    $this->setEventDispatcher(new Dispatcher(new Container));

    // Make this Capsule instance available globally via static methods... (optional)
    $this->setAsGlobal();

    // Setup the Eloquent ORM... (optional; unless you've used setEventDispatcher())
    $this->bootEloquent();
}
}

I had it running on illuminate/database 5.2. Recently I updated it to illuminate/database 5.5. My Eloquent paginate() has stopped working. The links() method on eloquent collection gives following error.

    Call to a member function make() on null

With a stack trace to

    return new HtmlString(static::viewFactory()->make($view ?: static::$defaultView, array_merge($data, [

in

     vendor\illuminate\pagination\LengthAwarePaginator.php on Line 90

The issue lies with viewFactoryResolver() as it can't resolve the view class.

I am using following code to initialize the paginator class.

Paginator::currentPathResolver(function() use ($path) { 
    return site_url($path);
});
$page = Input::get('page');
Paginator::currentPageResolver(function() use($page) { 
    return $page;
});

My composer.json file has following dependencies for eloquent.

"illuminate/database": "5.5",
"illuminate/events": "5.5",
"illuminate/pagination": "5.5",
"doctrine/dbal": "~2.6",

Any help in this regard will be appreciated.

0 likes
8 replies
ehsanquddusi's avatar

@jlrdw - I have updated my question with composer.json eloquent dependency. Please have a look.

jlrdw's avatar

@ehsanquddusi I once had an older project that used illuminate database. However I used a different paginator. I just had to provide the stylesheet (css) for the links.

Example, old code no longer used:

    public function index() {
         Session::set('owner', '1');
         $petsearch = (isset($_REQUEST['psch']) <> '' ? $_REQUEST['psch'] : "");
        Session::set('petsearch', $petsearch);
        $petrows = $this->Pet->petCount($petsearch);
        Session::set('petrows', $petrows);
        $pages = new HelpersPaginator('5', 'p');
        Session::set('petpage', $pages->getInstance());
        $pages->setTotal($petrows);
        $data['pageLinks'] = $pages->pageLinks('?', '&psch=' . $petsearch);
        $data['title'] = 'pet';
        $data['pets'] = $this->Pet->getPets($pages->getLimit2(), $pages->getPerpage(), $petsearch);
        $this->view->renderTemplate('header', $data);
        $this->view->render('pet/index', $data);
        $this->view->renderTemplate('footer', $data);
    }

And in view

echo '<td>' . $data['pageLinks'] . '</td>';

But with some tweaking the paginator works also in asp.net razor, and in java jsp.

I used this https://github.com/nova-framework/framework/blob/2.2/app/Helpers/Paginator.php

But the one I now used I modified some.

If interested I will post my current paginator and a css file that works in laravel and yii2.

Also, if CI is like laravel, did you delete all possible cache and dump autoload.

spekkionu's avatar

The laravel pagination has a dependency on the laravel view renderer so if you aren't using blade you wont be able to use the $pagination->links()method and will instead have to write your own pagination html using the given data.

jlrdw's avatar

That's why I used a different paginator. Illuminate database works great but I had trouble with paginator.

For the one I use it needs a count first so I have a method

public function petCount($petsearch = "") {
$petsearch = $petsearch . "%";
        return db::table('pets')
                    ->where('petname', 'like', $petsearch)
                     ->count();
}

and the getPets call to model

    public function getPets($offset = "", $rowsperpage = "", $petsearch = "") {
        //$pagingQuery = "LIMIT {$offset}, {$rowsperpage}";  //old code not used
        $petsearch = $petsearch . "%";
        return db::table('pets')
                        ->where('petname', 'like', $petsearch)
                        ->orderBy('petname', 'asc')
                        ->skip($offset)->take($rowsperpage)->get();
    }

where offset comes from the paginator but

->skip($offset)->take($rowsperpage)->get();

the actual skip and take is part of eloquent and querybuilder.

jlrdw's avatar

I was curious myself and attempted to use lengthaware paginator outside laravel. I couldn't never get the

$data->links();
or
$data->render();

to work in a view. I figure the most important part is the skip and take, i.e.,

$pets = db::table('pets')       
                       ->skip($offset)->take($perpage)->get();

So I figure just make own links as needed, a quick example: Controller:

    public function index() {
        if (isset($_REQUEST['page'])) {
            $page = $_REQUEST['page'];
        } else {
            $page = "1";
        }

        $perpage = "3";
        $offset = ($page - 1) * $perpage;
        $krows = db::select('select COUNT(petid) as count from dc_pets');
        $numrows = $krows[0]->count;
        
        $t1 = "b";  // just a test querystring
        $pets = db::table('pets')       
                       ->skip($offset)->take($perpage)->get();
        
        $params = ['page'=>$page, 't1'=>$t1];
        
        $this->view->renderTemplate('header', $data);
        $this->view->makeView('pet/index2', compact('pets', 'params'));
        $this->view->renderTemplate('footer', $data);
    }

View

<?php
// top of view with foreach, etc not shown
// just custom link, a quick test
$pageno = $params[page][0];
$t1 = $params[t1][0];
?>
///////then
<?php $pageno = $page + 1; ?>
<a href="<?= DIR; ?>pet/index?page=<?= $pageno; ?>&t1=<?= $t1; ?>">next</a>

DIR is just a constant for root here.

I even got normal ->paginate(5) to work, but never got the links to work.

So for me illuminate database works great outside of laravel, just not the pagination.

I tested version 5.5 of everything.

If anyone has done pagination outside of laravel, with extra parameters, please show here how you did it to help others. Not in this duscussion, but in guides, make a new topic.

Also, this was old code I tested with. Since then my thought was:

If having to load many laravel packages to make things work, I may as well just use laravel anyway, so I did.

eugenefvdm's avatar

Hi @ehsanquddusi ,

Did you ever resolve this issue? I'm also trying to use the Paginator outside of Laravel and having a view factory resolver issue.

Out of interest, I'm using blade standalone as well: https://github.com/EFTEC/BladeOne

If I could initialize the view factory I'm sure I could proceed.

Please or to participate in this conversation.