Skip to content

Commit

Permalink
Merge pull request #1634 from bolt/feature/extension-services-and-routes
Browse files Browse the repository at this point in the history
Copy extension services and routes into Bolt
  • Loading branch information
I-Valchev committed Jul 18, 2020
2 parents 1b70669 + 93390d7 commit 3148cfe
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 125 deletions.
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,12 @@
"prefer-stable": true,
"scripts": {
"post-install-cmd": [
"php bin/console extensions:configure --with-config",
"@auto-scripts",
"php bin/console bolt:info"
],
"post-update-cmd": [
"php bin/console extensions:configure",
"@auto-scripts",
"php bin/console bolt:info"
],
Expand Down
18 changes: 18 additions & 0 deletions config/packages/bolt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# This file is auto-generated by Bolt. Do not modify.

services:
_defaults:
autowire: true
autoconfigure: true
AcmeCorp\ReferenceExtension\:
resource: '../../vendor/acmecorp/reference-extension/src/*'
exclude: '../../vendor/acmecorp/reference-extension/src/{Entity,Exception}'
BobdenOtter\ConfigurationNotices\:
resource: '../../vendor/bobdenotter/configuration-notices/src/*'
exclude: '../../vendor/bobdenotter/configuration-notices/src/{Entity,Exception}'
BobdenOtter\WeatherWidget\:
resource: '../../vendor/bobdenotter/weatherwidget/src/*'
exclude: '../../vendor/bobdenotter/weatherwidget/src/{Entity,Exception}'
Bolt\NewsWidget\:
resource: '../../vendor/bolt/newswidget/src/*'
exclude: '../../vendor/bolt/newswidget/src/{Entity,Exception}'
18 changes: 0 additions & 18 deletions config/services_bolt.yaml

This file was deleted.

140 changes: 140 additions & 0 deletions src/Command/ExtensionsConfigureCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?php

declare(strict_types=1);

namespace Bolt\Command;

use Bolt\Common\Str;
use Bolt\Extension\ExtensionRegistry;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Webmozart\PathUtil\Path;

class ExtensionsConfigureCommand extends Command
{
protected static $defaultName = 'extensions:configure';

/** @var ExtensionRegistry */
private $extensionRegistry;

/** @var mixed */
private $projectDir;

public function __construct(ExtensionRegistry $extensionRegistry, ContainerInterface $container)
{
$this->extensionRegistry = $extensionRegistry;
$this->projectDir = $container->getParameter('kernel.project_dir');

parent::__construct();
}

protected function configure(): void
{
$this
->setDescription('Copy the config/config.yaml, config/services.yaml and config/routes.yaml files from extensions.')
->addOption('with-config', null, InputOption::VALUE_NONE, 'If set, Bolt will copy the default extension config.yaml file');
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$extensions = $this->extensionRegistry->getExtensions();

$this->copyExtensionRoutesAndServices($extensions);

if ($input->getOption('with-config')) {
$this->copyExtensionConfig($extensions);
}

return 0;
}

public function copyExtensionConfig(array $packages): void
{
// @todo: Combine this with Bolt\Extension\ConfigTrait.php
foreach ($packages as $package) {
$path = $this->getPackagePath($package);

$configPath = $this->getRelativePath($path) . '/config/config.yaml';
if (file_exists($configPath)) {
[$namespace, $name] = explode('\\', mb_strtolower($this->getNamespace($package)));
$destination = $this->getExtensionConfigPath($namespace, $name);
file_put_contents($destination, file_get_contents($configPath));
}
}
}

public function copyExtensionRoutesAndServices(array $packages): void
{
$oldExtensionsRoutes = glob($this->getExtensionRoutesPath());
$oldExtensionsServices = glob($this->getExtensionServicesPath());

foreach ($packages as $package) {
$path = $this->getPackagePath($package);

$extensionRoutesPath = $this->getRelativePath($path) . '/config/routes.yaml';
if (file_exists($extensionRoutesPath)) {
$destination = $this->getExtensionRoutesPath($path);
$oldExtensionsRoutes = array_diff($oldExtensionsRoutes, [$destination]);
file_put_contents($destination, file_get_contents($extensionRoutesPath));
}

$extensionServicesPath = $this->getRelativePath($path) . '/../config.services.yaml';
if (file_exists($extensionServicesPath)) {
$destination = $this->getExtensionServicesPath($path);
$oldExtensionsServices = array_diff($oldExtensionsServices, [$destination]);
file_put_contents($destination, file_get_contents($extensionRoutesPath));
}
}

// Remove routes.yaml files for old (uninstalled) extensions
array_map('unlink', $oldExtensionsRoutes);

// Remove services.yaml files for old (uninstalled) extensions
array_map('unlink', $oldExtensionsServices);
}

private function getRelativePath(string $path): string
{
return Path::makeRelative($path, $this->projectDir);
}

/**
* Helper function that returns the path of the extension routes.yaml file
* inside Bolt.
*/
private function getExtensionRoutesPath(string $path = '*'): string
{
return $this->projectDir . '/config/routes/extension_' . Str::splitLast($path, '/') . '.yaml';
}

/**
* Helper function that returns the path of the extension services.yaml file
* inside Bolt.
*/
private function getExtensionServicesPath(string $path = '*'): string
{
return $this->projectDir . '/config/packages/services_extension_' . Str::splitLast($path, '/') . '.yaml';
}

private function getExtensionConfigPath(string $namespace, string $name): string
{
return $this->projectDir . '/config/extensions/' . $namespace . '-' . $name . '.yaml';
}

private function getPackagePath($package): string
{
$reflection = new \ReflectionClass($package);

return dirname(dirname($reflection->getFilename()));
}

private function getNamespace($package): string
{
$reflection = new \ReflectionClass($package);

return $reflection->getNamespaceName();
}
}
96 changes: 0 additions & 96 deletions src/Extension/ExtensionCompilerPass.php

This file was deleted.

11 changes: 0 additions & 11 deletions src/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use Bolt\Configuration\Parser\ContentTypesParser;
use Bolt\Configuration\Parser\TaxonomyParser;
use Bolt\Extension\ExtensionCompilerPass;
use Bolt\Extension\ExtensionInterface;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\FileLocator;
Expand Down Expand Up @@ -44,9 +43,6 @@ public function build(ContainerBuilder $container): void
$container
->registerForAutoconfiguration(ExtensionInterface::class)
->addTag(ExtensionInterface::CONTAINER_TAG);

// Process all our implementors through our CompilerPass
$container->addCompilerPass(new ExtensionCompilerPass());
}

protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
Expand All @@ -64,13 +60,6 @@ protected function configureContainer(ContainerBuilder $container, LoaderInterfa
$this->setBoltParameters($container, $confDir);
$this->setContentTypeRequirements($container);
$this->setTaxonomyRequirements($container);

try {
$loader->load($confDir . '/{services}_bolt' . self::CONFIG_EXTS, 'glob');
} catch (\Throwable $e) {
// Ignore errors. The file will be updated on next `cache:clear` or whenever
// the container gets refreshed
}
}

protected function configureRoutes(RouteCollectionBuilder $routes): void
Expand Down

0 comments on commit 3148cfe

Please sign in to comment.