Skip to content

Commit

Permalink
feat(package): add a package service to map metadata paths to package…
Browse files Browse the repository at this point in the history
…/vendor paths
  • Loading branch information
JoelAlphonso committed Jun 13, 2022
1 parent 5169163 commit 9ffeec1
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 2 deletions.
95 changes: 95 additions & 0 deletions packages/app/src/Charcoal/App/Service/PackageMapService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

namespace Charcoal\App\Service;

use UnexpectedValueException;

/**
* Class PackageMapService
*/
class PackageMapService
{
const PACKAGES_DIRECTORY = '/vendor/charcoal/charcoal/packages/';
private bool $isMonoRepo;
private string $basePath;

/**
* @param array $data The init data.
*/
public function __construct(array $data)
{
$this->isMonoRepo = \Composer\InstalledVersions::isInstalled('charcoal/charcoal');
$this->basePath = $data['basePath'];
}

/**
* @param string|string[] $value The value(s) to map to package.
* @return mixed
*/
public function map($value)
{
if (is_array($value)) {
return array_map([$this, 'mapOne'], $value);
}

return $this->mapOne($value);
}

/**
* Replaces placeholders (%package.key.path%) by their values in the config.
*
* @param string $value A value to resolve.
* @throws UnexpectedValueException If the resolved value is not a string or number.
* @return mixed
*/
public function mapOne(string $value): string
{
return preg_replace_callback('/%%|%package\.([^\.%\s]+)\.path%/', function ($match) use ($value) {
// skip escaped %%
if (!isset($match[1])) {
return '%%';
}

$package = $match[1];

$resolved = ($this->resolvePackagePath($package) ?? null);

if (!is_string($resolved) && !is_numeric($resolved)) {
$resolvedType = (is_object($resolved) ? get_class($resolved) : gettype($resolved));

throw new UnexpectedValueException(sprintf(
'Invalid config parameter "%s" inside string value "%s"; '.
'must be a string or number, received %s',
$package,
$value,
$resolvedType
));
}

return $resolved;
}, $value);
}

/**
* @param string $package The package string identifier.
* @return string|null
*/
private function resolvePackagePath(string $package): ?string
{
if ($this->isMonoRepo) {
$directory = self::PACKAGES_DIRECTORY.$package;

if (file_exists($this->basePath.$directory)) {
return $directory;
}
} else {
$packageName = 'charcoal/'.$package;

if (\Composer\InstalledVersions::isInstalled($packageName)) {
return \Composer\InstalledVersions::getInstallPath($packageName);
};
}

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
use Charcoal\App\Handler\NotFound;

use Charcoal\App\Template\TemplateInterface;
use Charcoal\App\Template\TemplateBuilder;
use Charcoal\App\Template\WidgetInterface;
use Charcoal\App\Template\WidgetBuilder;

Expand Down Expand Up @@ -94,6 +93,7 @@ public function register(Container $container)
$container->register(new ScriptServiceProvider());
$container->register(new TranslatorServiceProvider());
$container->register(new ViewServiceProvider());
$container->register(new PackageServiceProvider());

$this->registerKernelServices($container);
$this->registerHandlerServices($container);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Charcoal\App\ServiceProvider;

use Charcoal\App\Service\PackageMapService;
use Pimple\Container;

/**
* Class PackageServiceProvider
*/
class PackageServiceProvider implements \Pimple\ServiceProviderInterface
{

/**
* @param Container $container Pimple DI container.
* @return void
*/
public function register(Container $container)
{
$container['package/map'] = function (Container $container) {
return new PackageMapService([
'basePath' => $container['config']['base_path']
]);
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ protected function registerMetadataDependencies(Container $container)
return new MetadataLoader([
'logger' => $container['logger'],
'cache' => $container['metadata/cache'],
'paths' => $metaConfig['paths'],
'paths' => $container['package/map']->map($metaConfig['paths']),
'base_path' => $appConfig['base_path'],
]);
};
Expand Down

0 comments on commit 9ffeec1

Please sign in to comment.