|
<?php |
|
|
|
namespace App\Http\Middleware; |
|
|
|
use Closure; |
|
use App\Services\Cache\ActionCacheManager; |
|
use Symfony\Component\HttpFoundation\ResponseHeaderBag; |
|
|
|
/** |
|
* Middleware that will cache controller action responses |
|
*/ |
|
class ActionCache |
|
{ |
|
protected $cacheManager; |
|
|
|
/** |
|
* Injects the class dependencies |
|
* @param ActionCacheManager $cacheManager To manage the cached actions. |
|
*/ |
|
public function __construct(ActionCacheManager $cacheManager) |
|
{ |
|
$this->cacheManager = $cacheManager; |
|
} |
|
|
|
/** |
|
* Run the request middleware. |
|
* |
|
* @param \Illuminate\Http\Request $request |
|
* @param \Closure $next |
|
* |
|
* @return mixed |
|
*/ |
|
public function handle($request, Closure $next) |
|
{ |
|
$path = $request->path(); |
|
|
|
if ($this->cacheManager->isCached($path) && $this->canBeCached($request)) { |
|
return $this->cacheManager->get($path); |
|
} |
|
|
|
return $next($request); |
|
} |
|
|
|
/** |
|
* Sometimes a middleware may need to do some work after the HTTP response |
|
* has already been sent to the browser. The ActionCache middleware will |
|
* store the response using the cacheManager for it to be used when |
|
* handling the next request. |
|
* |
|
* @param \Illuminate\Http\Request $request |
|
* @param \Illuminate\Http\Response $response |
|
*/ |
|
public function terminate($request, $response) |
|
{ |
|
$path = $request->path(); |
|
|
|
if ($this->cacheManager->isCached($path) || !$this->canBeCached($request)) { |
|
return; |
|
} |
|
|
|
$this->cleanCookies($response); |
|
$this->cacheManager->cache($path, $response); |
|
} |
|
|
|
/** |
|
* Tells if a request can be cached |
|
* |
|
* @param \Illuminate\Http\Request $request |
|
* |
|
* @return boolean |
|
*/ |
|
protected function canBeCached($request) |
|
{ |
|
return ! $request->get('preview'); |
|
} |
|
|
|
/** |
|
* Clean the cookies of the given response |
|
* |
|
* @param \Illuminate\Http\Response $response |
|
*/ |
|
protected function cleanCookies($response) |
|
{ |
|
foreach ($response->headers->getCookies(ResponseHeaderBag::COOKIES_ARRAY) as $path) { |
|
foreach ($path as $cookies) { |
|
foreach ($cookies as $cookie) { |
|
$response->headers->removeCookie($cookie->getName(), $cookie->getPath(), $cookie->getDomain()); |
|
} |
|
} |
|
} |
|
} |
|
} |