Skip to content

Commit

Permalink
Update to support Laravel 5
Browse files Browse the repository at this point in the history
  • Loading branch information
jeroennoten committed Sep 2, 2015
1 parent 95b252c commit 6656d3d
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 144 deletions.
38 changes: 20 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#### For Laravel 4, use the [1.0 branch](https://github.com/JeroenNoten/Laravel-Prerender/tree/1.0)

Laravel Prerender [![Build Status](https://travis-ci.org/JeroenNoten/Laravel-Prerender.svg?branch=master)](https://travis-ci.org/JeroenNoten/Laravel-Prerender)
===========================

Expand All @@ -12,29 +14,25 @@ Prerender adheres to google's `_escaped_fragment_` proposal, which we recommend

## Installation

Require this package in your composer.json and run composer update (or run `composer require nutsweb/laravel-prerender:dev-master` directly):

"nutsweb/laravel-prerender": "dev-master"
Require this package run: `composer require nutsweb/laravel-prerender`

After updating composer, add the ServiceProvider to the providers array in app/config/app.php.
After installing, add the ServiceProvider to the providers array in app/config/app.php.

'Nutsweb\LaravelPrerender\LaravelPrerenderServiceProvider',

Publish the configuration file.
If you want to make use of the prerender.io service, add the following to your `.env` file:

PRERENDER_TOKEN=yoursecrettoken

If you are using a self-hosted service, add the server address in the `.env` file.

$ php artisan config:publish nutsweb/laravel-prerender
PRERENDER_URL=http://example.com

If you want to make use of the prerender.io service, fill in your token in the configuration file.

// config.php
'prerender_token' => 'YOUR-TOKEN',

If you are using a self-hosted service, change the server address in the configuration file.
You can disable the service by adding the following to your `.env` file:

// config.php
'prerender_url' => 'http://example.com',
PRERENDER_ENABLE=false

By default, the service is disabled for `local` environments. If you want, you can change this in `config/packages/nutsweb/laravel-prerender/local/config.php`.
This may be useful for your local development environment.

## How it works
1. The middleware checks to make sure we should show a prerendered page
Expand All @@ -47,6 +45,10 @@ By default, the service is disabled for `local` environments. If you want, you c

# Customization

To customize the whitelist and the blacklist, you first have to publish the configuration file:

$ php artisan vendor:publish

### Whitelist

Whitelist paths or patterns. You can use asterix syntax, or regular expressions (without start and end markers).
Expand All @@ -55,7 +57,7 @@ An empty array means that all URIs will pass this filter.
Note that this is the full request URI, so including starting slash and query parameter string.

```php
// config.php:
// prerender.php:
'whitelist' => [
'/frontend/*' // only prerender pages starting with '/frontend/'
],
Expand All @@ -68,8 +70,8 @@ If a blacklist is supplied, all url's will be prerendered except ones containing
By default, a set of asset extentions are included (this is actually only necessary when you dynamically provide assets via routes).
Note that this is the full request URI, so including starting slash and query parameter string.

```js
// config.php:
```php
// prerender.php:
'blacklist' => [
'/api/*' // do not prerender pages starting with '/api/'
],
Expand Down
11 changes: 6 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
}
],
"require": {
"php": ">=5.4.0",
"illuminate/support": "4.2.*",
"guzzlehttp/guzzle": "~4.0"
"php": ">=5.5.9",
"illuminate/support": "~5.0.14|~5.1",
"guzzlehttp/guzzle": "^6.0",
"symfony/psr-http-message-bridge": "^0.2.0"
},
"autoload": {
"psr-0": {
"Nutsweb\\LaravelPrerender": "src/"
"psr-4": {
"Nutsweb\\LaravelPrerender\\": "src/"
}
},
"minimum-stability": "stable"
Expand Down
6 changes: 3 additions & 3 deletions src/config/config.php → config/prerender.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
|
*/

'enable' => true,
'enable' => env('PRERENDER_ENABLE', true),

/*
|--------------------------------------------------------------------------
Expand All @@ -25,7 +25,7 @@
|
*/

'prerender_url' => 'https://service.prerender.io',
'prerender_url' => env('PRERENDER_URL', 'https://service.prerender.io'),

/*
|--------------------------------------------------------------------------
Expand All @@ -38,7 +38,7 @@
|
*/

'prerender_token' => '',
'prerender_token' => env('PRERENDER_TOKEN'),

/*
|--------------------------------------------------------------------------
Expand Down
48 changes: 48 additions & 0 deletions src/LaravelPrerenderServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php namespace Nutsweb\LaravelPrerender;

use App;
use GuzzleHttp\Client;
use Illuminate\Foundation\Http\Kernel;
use Illuminate\Support\ServiceProvider;

class LaravelPrerenderServiceProvider extends ServiceProvider
{

/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;

protected $package = 'nutsweb/laravel-prerender';

/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
$this->publishes([
__DIR__ . '/../config/prerender.php' => config_path('prerender.php')
], 'config');

if ($this->app['config']->get('prerender.enable')) {
/** @var Kernel $kernel */
$kernel = $this->app['Illuminate\Contracts\Http\Kernel'];
$kernel->pushMiddleware(PrerenderMiddleware::class);
}
}

/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->mergeConfigFrom(__DIR__ . '/../config/prerender.php', 'prerender');
}

}
58 changes: 0 additions & 58 deletions src/Nutsweb/LaravelPrerender/LaravelPrerenderServiceProvider.php

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,27 @@
namespace Nutsweb\LaravelPrerender;


use GuzzleHttp\Client as GuzzleClient;
use Closure;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Message\Response as GuzzleResponse;
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Illuminate\Contracts\Foundation\Application;
use GuzzleHttp\Client as Guzzle;
use Psr\Http\Message\ResponseInterface;
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
use Symfony\Component\HttpFoundation\Response;

class PrerenderMiddleware implements HttpKernelInterface
class PrerenderMiddleware
{
/**
* The application instance (implements the HttpKernelInterface)
* The application instance
*
* @var HttpKernelInterface
* @var Application
*/
private $app;

/**
* The Guzzle Client that sends GET requests to the prerender server
* This client must take care of the base URL by itself
*
* @var GuzzleClient
* @var Guzzle
*/
private $client;

Expand Down Expand Up @@ -56,40 +56,43 @@ class PrerenderMiddleware implements HttpKernelInterface
*/
private $blacklist;

/**
* Base URI to make the prerender requests
*
* @var string
*/
private $prerenderUri;

/**
* Creates a new PrerenderMiddleware instance
*
* @param HttpKernelInterface $app
* @param GuzzleClient $client
* @param $prerenderToken
* @param array $crawlerUserAgents
* @param array $whitelist
* @param array $blacklist
* @param Application $app
* @param Guzzle $client
*/
public function __construct(HttpKernelInterface $app,
GuzzleClient $client,
$prerenderToken,
array $crawlerUserAgents,
array $whitelist,
array $blacklist)
public function __construct(Application $app, Guzzle $client)
{
$this->app = $app;
$this->client = $client;
$this->crawlerUserAgents = $crawlerUserAgents;
$this->prerenderToken = $prerenderToken;
$this->whitelist = $whitelist;
$this->blacklist = $blacklist;

$config = $app['config']->get('prerender');

$this->prerenderUri = $config['prerender_url'];
$this->crawlerUserAgents = $config['crawler_user_agents'];
$this->prerenderToken = $config['prerender_token'];
$this->whitelist = $config['whitelist'];
$this->blacklist = $config['blacklist'];
}

/**
* Handles a request and prerender if it should, otherwise call the next middleware.
*
* @param SymfonyRequest $request
* @param int $type
* @param bool $catch
* @return SymfonyResponse
* @param $request
* @param Closure $next
* @return Response
* @internal param int $type
* @internal param bool $catch
*/
public function handle(SymfonyRequest $request, $type = self::MASTER_REQUEST, $catch = true)
public function handle($request, Closure $next)
{
if ($this->shouldShowPrerenderedPage($request)) {
$prerenderedResponse = $this->getPrerenderedPageResponse($request);
Expand All @@ -98,16 +101,16 @@ public function handle(SymfonyRequest $request, $type = self::MASTER_REQUEST, $c
}
}

return $this->app->handle($request, $type, $catch);
return $next($request);
}

/**
* Returns whether the request must be prerendered.
*
* @param SymfonyRequest $request
* @param $request
* @return bool
*/
private function shouldShowPrerenderedPage(SymfonyRequest $request)
private function shouldShowPrerenderedPage($request)
{
$userAgent = strtolower($request->server->get('HTTP_USER_AGENT'));
$bufferAgent = $request->server->get('X-BUFFERBOT');
Expand Down Expand Up @@ -157,10 +160,10 @@ private function shouldShowPrerenderedPage(SymfonyRequest $request)
/**
* Prerender the page and return the Guzzle Response
*
* @param SymfonyRequest $request
* @param $request
* @return null|void
*/
private function getPrerenderedPageResponse(SymfonyRequest $request)
private function getPrerenderedPageResponse($request)
{
$headers = [
'User-Agent' => $request->server->get('HTTP_USER_AGENT'),
Expand All @@ -171,7 +174,8 @@ private function getPrerenderedPageResponse(SymfonyRequest $request)

try {
// Return the Guzzle Response
return $this->client->get('/' . urlencode($request->getUri()), compact('headers'));
$originalUri = $request->getUri();
return $this->client->get($this->prerenderUri . '/' . urlencode($originalUri), compact('headers'));
} catch (RequestException $exception) {
// In case of an exception, we only throw the exception if we are in debug mode. Otherwise,
// we return null and the handle() method will just pass the request to the next middleware
Expand All @@ -186,15 +190,12 @@ private function getPrerenderedPageResponse(SymfonyRequest $request)
/**
* Convert a Guzzle Response to a Symfony Response
*
* @param GuzzleResponse $prerenderedResponse
* @return SymfonyResponse
* @param ResponseInterface $prerenderedResponse
* @return Response
*/
private function buildSymfonyResponseFromGuzzleResponse(GuzzleResponse $prerenderedResponse)
private function buildSymfonyResponseFromGuzzleResponse(ResponseInterface $prerenderedResponse)
{
$body = $prerenderedResponse->getBody();
$statusCode = $prerenderedResponse->getStatusCode();
$headers = $prerenderedResponse->getHeaders();
return new SymfonyResponse($body, $statusCode, $headers);
return (new HttpFoundationFactory)->createResponse($prerenderedResponse);
}

/**
Expand Down
Loading

0 comments on commit 6656d3d

Please sign in to comment.