Select Git revision
-
Bartek Jaskulski authored
Now, dev mode doesn't have to be explicitly set, only for WordPress, which has production type defined. Additionally, allow to build container without using cache, when server does not support it (i.e. cannot write to the disk). Signed-off-by:
Bart Jaskulski <bjaskulski@protonmail.com>
Bartek Jaskulski authoredNow, dev mode doesn't have to be explicitly set, only for WordPress, which has production type defined. Additionally, allow to build container without using cache, when server does not support it (i.e. cannot write to the disk). Signed-off-by:
Bart Jaskulski <bjaskulski@protonmail.com>
Kernel.php 4.41 KiB
<?php
declare( strict_types=1 );
namespace WPDesk\Init;
use DI\Container;
use DI\ContainerBuilder as DiBuilder;
use Psr\Container\ContainerInterface;
use WPDesk\Init\Binding\Binder\CallableBinder;
use WPDesk\Init\Binding\Binder\CompositeBinder;
use WPDesk\Init\Binding\Binder\HookableBinder;
use WPDesk\Init\Binding\Binder\StoppableBinder;
use WPDesk\Init\Binding\Loader\ClusteredLoader;
use WPDesk\Init\Binding\Loader\CompositeBindingLoader;
use WPDesk\Init\Binding\Loader\DebugBindingLoader;
use WPDesk\Init\Binding\Loader\OrderedBindingLoader;
use WPDesk\Init\Configuration\Configuration;
use WPDesk\Init\DependencyInjection\ContainerBuilder;
use WPDesk\Init\Extension\ExtensionsSet;
use WPDesk\Init\HookDriver\CompositeDriver;
use WPDesk\Init\HookDriver\GenericDriver;
use WPDesk\Init\HookDriver\HookDriver;
use WPDesk\Init\HookDriver\LegacyDriver;
use WPDesk\Init\Util\PhpFileDumper;
use WPDesk\Init\Util\PhpFileLoader;
use WPDesk\Init\Plugin\Header;
use WPDesk\Init\Util\Path;
use WPDesk\Init\Plugin\DefaultHeaderParser;
use WPDesk\Init\Plugin\HeaderParser;
use WPDesk\Init\Plugin\Plugin;
final class Kernel {
/** @var string|null Plugin filename. */
private ?string $filename;
private Configuration $config;
private PhpFileLoader $loader;
private HeaderParser $parser;
private ExtensionsSet $extensions;
private PhpFileDumper $dumper;
public function __construct(
string $filename,
Configuration $config,
ExtensionsSet $extensions
) {
$this->filename = $filename;
$this->config = $config;
$this->extensions = $extensions;
$this->loader = new PhpFileLoader();
$this->parser = new DefaultHeaderParser();
$this->dumper = new PhpFileDumper();
}
public function boot(): void {
$cache_path = $this->get_cache_path( 'plugin.php' );
try {
$plugin_data = $this->loader->load( $cache_path );
} catch ( \Exception $e ) {
try {
$this->dumper->dump(
$this->parser->parse( $this->filename ),
$cache_path
);
$plugin_data = $this->loader->load( $cache_path );
} catch ( \Exception $e ) {
$plugin_data = $this->parser->parse( $this->filename );
}
}
$plugin = new Plugin( $this->filename, new Header( $plugin_data ) );
$container = $this->initialize_container( $plugin );
$container->set( Plugin::class, $plugin );
$container->set( Configuration::class, $this->config );
$this->prepare_driver( $container )->register_hooks();
}
private function get_cache_path( string $path = '' ): string {
return (string) ( new Path( $this->config->get( 'cache_path', 'generated' ) ) )->join( $path )->absolute(
rtrim( plugin_dir_path( $this->filename ), '/' ) . '/'
);
}
private function get_container_name( Plugin $plugin ): string {
return preg_replace( '/[^\w_]/', '_', implode("_", [ $plugin->get_slug(), $plugin->get_version(), 'container' ]) );
}
private function initialize_container( Plugin $plugin, bool $useCache = true ): Container {
$original_builder = new DiBuilder();
if ( $this->is_prod() && $useCache ) {
$original_builder->enableCompilation(
$this->get_cache_path(),
$this->get_container_name( $plugin )
);
}
$builder = new ContainerBuilder( $original_builder );
if ( ! function_exists( 'WPDesk\Init\DI\create' ) ) {
require __DIR__ . '/di-functions.php';
}
foreach ( $this->extensions as $extension ) {
$extension->build( $builder, $plugin, $this->config );
}
try {
return $builder->build();
} catch ( \Exception $e ) {
return $this->initialize_container( $plugin, false );
}
}
private function prepare_driver( ContainerInterface $container ): HookDriver {
$loader = new CompositeBindingLoader();
foreach ( $this->extensions as $extension ) {
$loader->add( $extension->bindings( $container ) );
}
$loader = new OrderedBindingLoader(
new ClusteredLoader( $loader )
);
if ( $this->is_dev() ) {
$loader = new DebugBindingLoader( $loader );
}
$driver = new GenericDriver(
$loader,
new CompositeBinder(
new StoppableBinder( new HookableBinder( $container ), $container ),
new CallableBinder( $container )
)
);
if ( $this->config->get( 'legacy', false ) ) {
$driver = new CompositeDriver(
$driver,
new LegacyDriver( $container )
);
}
return $driver;
}
private function is_dev(): bool {
return $this->config->get( 'debug', false ) || wp_get_environment_type() !== 'development';
}
private function is_prod(): bool {
return $this->is_dev() === false;
}
}