Skip to content

Commit

Permalink
Pre-Compiled View Runtime #26
Browse files Browse the repository at this point in the history
  • Loading branch information
iamacarpet committed Sep 5, 2018
1 parent e83d65a commit 9ee127f
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Illuminate\Routing\Route as LaravelRoute;
use Illuminate\Routing\Router as LaravelRouter;
use Illuminate\Pipeline\Pipeline as LaravelPipeline;
use A1comms\GaeSupportLaravel\View\Engines\CompilerEngine;

class LaravelExtended implements IntegrationInterface
{
Expand Down Expand Up @@ -56,6 +57,11 @@ public static function load()

// Trace the controller run, where we'd expect the bit of exeuction we care about to happen.
opencensus_trace_method(LaravelRoute::class, 'run', [self::class, 'handleControllerRun']);

// ---
// Alternative View Compiler for Pre-Compiled Views
// ---
opencensus_trace_method(CompilerEngine::class, 'get', [self::class, 'handleView']);
}

public static function handleApplicationConstruct($scope, $basePath = null)
Expand Down Expand Up @@ -151,6 +157,17 @@ public static function handleControllerRun($scope)
];
}

public static function handleView($scope, $path, $data)
{
return [
'name' => 'laravel/view',
'attributes' => [
'path' => $path,
'pre-compiled' => true,
]
];
}

/*
| Taken from Illuminate\Pipeline\Pipeline
| as the visibility was set to protected
Expand Down
56 changes: 56 additions & 0 deletions src/A1comms/GaeSupportLaravel/View/Compilers/FakeCompiler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace A1comms\GaeSupportLaravel\View\Compilers;

use InvalidArgumentException;
use Illuminate\Filesystem\Filesystem;

class FakeCompiler
{

/**
* Get the cache path for the compiled views.
*
* @var string
*/
protected $cachePath;

/**
* Create a new compiler instance.
*
* @param string $cachePath
* @return void
*
* @throws \InvalidArgumentException
*/
public function __construct($cachePath)
{
if (! $cachePath) {
throw new InvalidArgumentException('Please provide a valid cache path.');
}

$this->cachePath = $cachePath;
}

/**
* Get the path to the compiled version of a view.
*
* @param string $path
* @return string
*/
public function getCompiledPath($path)
{
return $this->cachePath.'/'.sha1($path).'.php';
}

/**
* Determine if the view at the given path is expired.
*
* @param string $path
* @return bool
*/
public function isExpired($path)
{
return false;
}
}
31 changes: 31 additions & 0 deletions src/A1comms/GaeSupportLaravel/View/Engines/CompilerEngine.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace A1comms\GaeSupportLaravel\View\Engines;

use Illuminate\View\Engines\CompilerEngine as LaravelCompilerEngine;

class CompilerEngine extends LaravelCompilerEngine
{
/**
* Get the evaluated contents of the view.
*
* @param string $path
* @param array $data
* @return string
*/
public function get($path, array $data = [])
{
$this->lastCompiled[] = $path;

$compiled = $this->compiler->getCompiledPath($path);

// Once we have the path to the compiled file, we will evaluate the paths with
// typical PHP just like any other templates. We also keep a stack of views
// which have been rendered for right exception messages to be generated.
$results = $this->evaluatePath($compiled, $data);

array_pop($this->lastCompiled);

return $results;
}
}
41 changes: 41 additions & 0 deletions src/A1comms/GaeSupportLaravel/View/FileViewFinder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace A1comms\GaeSupportLaravel\View;

use InvalidArgumentException;
use Illuminate\Filesystem\Filesystem;
use Illuminate\View\FileViewFinder as LaravelFileViewFinder;

class FileViewFinder extends LaravelFileViewFinder
{
public function __construct(Filesystem $files, array $paths, array $extensions = null, string $cachePath = null)
{
$this->files = $files;
$this->paths = $paths;

if (isset($extensions)) {
$this->extensions = $extensions;
}

if (!empty($cachePath)) {
$manifestPath = $cachePath . '/manifest.php';
if (is_file($manifestPath)) {
$this->views = require $manifestPath;
}
}
}

/**
* Find the given view in the list of paths.
*
* @param string $name
* @param array $paths
* @return string
*
* @throws \InvalidArgumentException
*/
protected function findInPaths($name, $paths)
{
throw new InvalidArgumentException("View [$name] not found.");
}
}
88 changes: 88 additions & 0 deletions src/A1comms/GaeSupportLaravel/View/ViewServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

namespace A1comms\GaeSupportLaravel\View;

use Illuminate\View\ViewServiceProvider as LaravelViewServiceProvider;
use A1comms\GaeSupportLaravel\View\Compilers\FakeCompiler;
use A1comms\GaeSupportLaravel\View\Engines\CompilerEngine;

class ViewServiceProvider extends LaravelViewServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
if (is_gae()){
$this->registerFactory();

$this->registerGaeViewFinder();

$this->registerGaeEngineResolver();
} else {
parent::register();
}
}

/**
* Register the view finder implementation.
*
* @return void
*/
public function registerGaeViewFinder()
{
$this->app->bind('view.finder', function ($app) {
// TODO: Replace with a static manifest array search.
return new FileViewFinder($app['files'], $app['config']['view.paths'], null, $this->app['config']['view.compiled']);
});
}

/**
* Register the engine resolver instance.
*
* @return void
*/
public function registerGaeEngineResolver()
{
$this->app->singleton('view.engine.resolver', function () {
$resolver = new EngineResolver;

// Next, we will register the various view engines with the resolver so that the
// environment will resolve the engines needed for various views based on the
// extension of view file. We call a method for each of the view's engines.
foreach (['file', 'php'] as $engine) {
$this->{'register'.ucfirst($engine).'Engine'}($resolver);
}

foreach (['blade'] as $engine) {
$this->{'registerGae'.ucfirst($engine).'Engine'}($resolver);
}

return $resolver;
});
}

/**
* Register the Blade engine implementation.
*
* @param \Illuminate\View\Engines\EngineResolver $resolver
* @return void
*/
public function registerGaeBladeEngine($resolver)
{
// The Compiler engine requires an instance of the CompilerInterface, which in
// this case will be the Blade compiler, so we'll first create the compiler
// instance to pass into the engine so it can compile the views properly.
$this->app->singleton('blade.compiler', function () {
return new FakeCompiler(
$this->app['config']['view.compiled']
);
});

$resolver->register('blade', function () {
return new CompilerEngine($this->app['blade.compiler']);
});
}
}

0 comments on commit 9ee127f

Please sign in to comment.