Framework: [5.2] Pagination links do not use forced root url

Created on 9 Sep 2016  路  7Comments  路  Source: laravel/framework

  • Laravel Version: 5.2.45
  • PHP Version: 5.6.24
  • Database Driver & Version: mysql Ver 14.14 Distrib 5.5.51, for Linux (x86_64) using readline 5.1

    Description:

After forcing HTTPS and base URL of the application:

URL::forceSchema('https'); // Force HTTPS
URL::forceRootUrl(Config::get('app.url')); // Set the base URL of the application

, all observable links are adjusted except for the links produced by $LengthAwarePaginator->links()

Steps To Reproduce:

  1. Force HTTPS and base URL of the application in AppServiceProvider.
  2. Create a paginated resource in a Controller and pass it to a View.
  3. Output the pagination buttons to navigate the paginated content in your view using $var->links()

Most helpful comment

Just put this code into AppServiceProvider in boot function.

\Illuminate\Pagination\AbstractPaginator::currentPathResolver(function () {
            /** @var \Illuminate\Routing\UrlGenerator $url */
           $url = app('url');
           return $url->current();
        });

All 7 comments

Unfortunately fixing this in a clean way would be considered a breaking change, the this is that the path these URLs use is built very early in the request, before any of your custom code is run, at this point the application won't know about your forced schema rule.

I suggest that you use a custom Presenter and adjust the links accordingly.

If you think there's a clean way to fix this in 5.2 please open a PR, otherwise I think a custom presenter is the way to go :)

@themsaid Thanks for the explanation and useful suggestion :)

Even though it's not backward compatible, wouldn't it be possible to leave it open as a feature request for upcoming versions?
We are now on Laravel 5.5 and this is still an issue. Seems weird to not support forceRootUrl in this case.

Agreed ... seems obvious that this is a bug and I don't understand the 'breaking change' idea. I think what you mean is it will be a lot of work to move the generation of these links downstream in the request without introducing bugs or regressions.

EDIT: since I'm not using a presenter here (JSON api) I had to override PaginatedResourceResponse to inject the correct URL into the paginators. Then I had to have all my resource collections use this override. Makes me sad:

   /**
     * PaginatedResourceResponse constructor.
     * @param $resource
     */
    public function __construct( $resource )
    {
        parent::__construct( $resource );
        // framework bug workaround
        // force the links to adhere to our \Url::forceRootUrl()
        // @see https://github.com/laravel/framework/issues/15361
        $this->resource->resource->withPath( \URL::current() );
    }

Just put this code into AppServiceProvider in boot function.

\Illuminate\Pagination\AbstractPaginator::currentPathResolver(function () {
            /** @var \Illuminate\Routing\UrlGenerator $url */
           $url = app('url');
           return $url->current();
        });

In your AppServiceProvider::boot method you can add the following to force https on everything including pagination links

$this->app['request']->server->set('HTTPS','on');

You can go further to do something like this

if($this->app->environment('production'))
{
   $this->app['request']->server->set('HTTPS','on');
}

@themsaid I know this is an old issue, but do you think changing this:

Paginator::currentPathResolver(function () {
    return $this->app['request']->url();
});

to this:

Paginator::currentPathResolver(function () {
    return $this->app['url']->current();
});

inside PaginationServiceProvider would be a clean way to solve the issue?

If you think there's a clean way to fix this in 5.2 please open a PR, otherwise I think a custom presenter is the way to go :)

Was this page helpful?
0 / 5 - 0 ratings