Skip to content

Commit

Permalink
Cleanup and optimize code
Browse files Browse the repository at this point in the history
Add strict types and return types where it was missing.
  • Loading branch information
bschultz committed Apr 3, 2024
1 parent c08343a commit 50f2c96
Show file tree
Hide file tree
Showing 30 changed files with 147 additions and 84 deletions.
14 changes: 12 additions & 2 deletions src/Cache/ComponentsWarmer.php
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
<?php

declare(strict_types=1);

namespace Qossmic\TwigDocBundle\Cache;

use Psr\Cache\InvalidArgumentException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
use Qossmic\TwigDocBundle\Service\ComponentService;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;

class ComponentsWarmer implements CacheWarmerInterface
readonly class ComponentsWarmer implements CacheWarmerInterface
{
public function __construct(private readonly ContainerInterface $container)
public function __construct(private ContainerInterface $container)
{
}

Expand All @@ -17,6 +22,11 @@ public function isOptional(): bool
return true;
}

/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws InvalidArgumentException
*/
public function warmUp(string $cacheDir, ?string $buildDir = null): array
{
$componentService ??= $this->container->get('twig_doc.service.component');
Expand Down
6 changes: 3 additions & 3 deletions src/Component/ComponentInvalid.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
/**
* @codeCoverageIgnore
*/
class ComponentInvalid
readonly class ComponentInvalid
{
public function __construct(
public readonly ConstraintViolationList $violationList,
public readonly array $originalConfig
public ConstraintViolationList $violationList,
public array $originalConfig
) {
}
}
8 changes: 8 additions & 0 deletions src/Component/ComponentItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,29 @@ class ComponentItem
{
#[Assert\NotBlank]
private string $name;

#[Assert\NotBlank]
private string $title;

#[Assert\NotBlank]
private string $description;

#[Assert\Type('array')]
private array $tags;

#[Assert\Type('array')]
private array $parameters;

#[Assert\Type('array')]
private array $variations;

#[Assert\Valid]
private ComponentCategory $category;

#[Assert\Length(max: 4096)]
#[Assert\NotBlank]
private string $projectPath;

#[Assert\Length(max: 4096)]
#[Assert\NotBlank]
private string $renderPath;
Expand Down
11 changes: 8 additions & 3 deletions src/Component/ComponentItemFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Component\Validator\Validator\ValidatorInterface;

class ComponentItemFactory
readonly class ComponentItemFactory
{
public function __construct(private readonly ValidatorInterface $validator, private readonly CategoryService $categoryService)
public function __construct(private ValidatorInterface $validator, private CategoryService $categoryService)
{
}

/**
* @throws InvalidComponentConfigurationException
*/
public function create(array $data): ComponentItem
{
$item = $this->createItem($data);
Expand All @@ -28,7 +31,7 @@ public function create(array $data): ComponentItem
isset($data['sub_category']) ? 'sub_category' : 'category',
$data['sub_category'] ?? $data['category'],
implode(', ', array_keys($this->categoryService->getCategories())),
implode(', ', array_map(fn (ComponentCategory $category) => $category->getName(), $this->categoryService->getSubCategories()))
implode(', ', array_map(static fn (ComponentCategory $category) => $category->getName(), $this->categoryService->getSubCategories()))
)
);
throw new InvalidComponentConfigurationException($violations);
Expand Down Expand Up @@ -68,12 +71,14 @@ public function getParamsFromVariables(array $variables): array
foreach ($variables as $dotted) {
$keys = explode('.', $dotted);
$c = &$r[array_shift($keys)];

foreach ($keys as $key) {
if (isset($c[$key]) && $c[$key] === true) {
$c[$key] = [];
}
$c = &$c[$key];
}

if ($c === null) {
$c = 'Scalar';
}
Expand Down
18 changes: 11 additions & 7 deletions src/Component/ComponentItemList.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace Qossmic\TwigDocBundle\Component;

/**
Expand Down Expand Up @@ -34,7 +36,7 @@ public function paginate(int $start = 0, int $limit = 15): array

public function sort(string $field, string $direction = self::SORT_ASC): void
{
if (!\in_array($field, $this->sortableFields)) {
if (!\in_array($field, $this->sortableFields, true)) {
throw new \InvalidArgumentException(sprintf('field "%s" is not sortable', $field));
}

Expand All @@ -52,13 +54,15 @@ public function sort(string $field, string $direction = self::SORT_ASC): void
public function filter(string $query, ?string $type): self
{
$components = [];

switch ($type) {
case 'category':
$components = array_filter(
$this->getArrayCopy(),
function (ComponentItem $item) use ($query) {
static function (ComponentItem $item) use ($query) {
$category = $item->getCategory()->getName();
$parent = $item->getCategory()->getParent();

while ($parent !== null) {
$category = $parent->getName();
$parent = $parent->getParent();
Expand All @@ -72,28 +76,28 @@ function (ComponentItem $item) use ($query) {
case 'sub_category':
$components = array_filter(
$this->getArrayCopy(),
fn (ComponentItem $item) => $item->getCategory()->getParent() !== null
static fn (ComponentItem $item) => $item->getCategory()->getParent() !== null
&& strtolower($item->getCategory()->getName()) === strtolower($query)
);

break;
case 'tags':
$tags = array_map('trim', explode(',', strtolower($query)));
$components = array_filter($this->getArrayCopy(), function (ComponentItem $item) use ($tags) {
$components = array_filter($this->getArrayCopy(), static function (ComponentItem $item) use ($tags) {
return array_intersect($tags, array_map('strtolower', $item->getTags())) !== [];
});

break;
case 'name':
$components = array_filter(
$this->getArrayCopy(),
fn (ComponentItem $item) => str_contains(strtolower($item->getName()), strtolower($query))
static fn (ComponentItem $item) => str_contains(strtolower($item->getName()), strtolower($query))
);

break;
default:
foreach (['category', 'sub_category', 'tags', 'name'] as $type) {
$components = array_merge($components, (array) $this->filter($query, $type));
foreach (['category', 'sub_category', 'tags', 'name'] as $componentType) {
$components = array_merge($components, (array) $this->filter($query, $componentType));
}

break;
Expand Down
2 changes: 2 additions & 0 deletions src/Configuration/ParserInterface.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace Qossmic\TwigDocBundle\Configuration;

interface ParserInterface
Expand Down
6 changes: 5 additions & 1 deletion src/Configuration/YamlParser.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace Qossmic\TwigDocBundle\Configuration;

use Symfony\Component\Yaml\Yaml;
Expand All @@ -21,15 +23,16 @@ private function fixIndentation(string $content): string

$firstLineDetected = false;
$indentationWhitespace = null;

$lines = [];

while ($fileObject->valid()) {
$line = $fileObject->current();

if (empty(trim($line))) {
$fileObject->next();
continue;
}

if ($firstLineDetected === false) {
$firstLineDetected = true;
// check for whitespaces at the beginning
Expand All @@ -39,6 +42,7 @@ private function fixIndentation(string $content): string
}
$indentationWhitespace = $matches[1];
}

$line = substr($line, \strlen($indentationWhitespace));
$lines[] = $line;
$fileObject->next();
Expand Down
8 changes: 4 additions & 4 deletions src/Controller/TwigDocController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
use Symfony\Component\HttpKernel\Profiler\Profiler;
use Twig\Environment;

class TwigDocController
readonly class TwigDocController
{
public function __construct(
private readonly Environment $twig,
private readonly ComponentService $componentService,
private readonly ?Profiler $profiler = null
private Environment $twig,
private ComponentService $componentService,
private ?Profiler $profiler = null
) {
}

Expand Down
26 changes: 13 additions & 13 deletions src/DependencyInjection/Compiler/TwigDocCollectDocsPass.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace Qossmic\TwigDocBundle\DependencyInjection\Compiler;

use Qossmic\TwigDocBundle\Component\ComponentCategory;
Expand All @@ -11,9 +13,9 @@
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;

class TwigDocCollectDocsPass implements CompilerPassInterface
readonly class TwigDocCollectDocsPass implements CompilerPassInterface
{
public function __construct(private readonly ParserInterface $parser)
public function __construct(private ParserInterface $parser)
{
}

Expand All @@ -22,6 +24,7 @@ public function process(ContainerBuilder $container): void
if (!$container->hasExtension('twig_doc')) {
return;
}

$config = $container->getParameter('twig_doc.config');
$directories = $this->resolveDirectories($container, $config['directories']);
$container->getParameterBag()->remove('twig_doc.config');
Expand Down Expand Up @@ -51,9 +54,10 @@ public function process(ContainerBuilder $container): void
$filename = $file->getFilename();
$componentName = substr($filename, 0, strpos($filename, '.'));

if (array_filter($componentConfig, fn (array $data) => $data['name'] === $componentName)) {
throw new InvalidConfigException(sprintf('component "%s" is configured twice, please configure either directly in the template or the general bundle configuration', $componentName));
if (array_filter($componentConfig, static fn (array $data) => $data['name'] === $componentName)) {
throw new InvalidConfigException(sprintf('Component "%s" is configured twice, please configure either directly in the template or the general bundle configuration', $componentName));
}

$itemConfig = [
'name' => $componentName,
'path' => str_replace($projectDir.'/', '', $file->getRealPath()),
Expand All @@ -69,7 +73,6 @@ public function process(ContainerBuilder $container): void
private function parseDoc(SplFileInfo $file, string $docIdentifier): ?array
{
$content = $file->getContents();

$pattern = sprintf("/\{#%s\s(.*)%s#}/s", $docIdentifier, $docIdentifier);

preg_match($pattern, $content, $matches);
Expand All @@ -84,10 +87,10 @@ private function parseDoc(SplFileInfo $file, string $docIdentifier): ?array
private function enrichComponentsConfig(ContainerBuilder $container, array $directories, array $components): array
{
foreach ($components as &$component) {
if (!isset($component['path'])) {
$component['path'] = str_replace($container->getParameter('kernel.project_dir').'/', '', $this->getTemplatePath($component['name'], $directories));
if (!isset($component['path']) && $templatePath = $this->getTemplatePath($component['name'], $directories)) {
$component['path'] = str_replace($container->getParameter('kernel.project_dir').'/', '', $templatePath);
}
if (!isset($component['renderPath'])) {
if (!isset($component['renderPath']) && isset($component['path'])) {
$component['renderPath'] = str_replace($container->getParameter('twig.default_path').'/', '', $component['path']);
}
}
Expand All @@ -98,8 +101,7 @@ private function enrichComponentsConfig(ContainerBuilder $container, array $dire
private function resolveDirectories(ContainerBuilder $container, array $directories): array
{
$directories[] = $container->getParameter('twig.default_path').'/components';

$directories = array_map(fn (string $dir) => $container->getParameterBag()->resolveValue($dir), $directories);
$directories = array_map(static fn (string $dir) => $container->getParameterBag()->resolveValue($dir), $directories);

foreach ($directories as $idx => $dir) {
if (!is_dir($dir)) {
Expand All @@ -113,9 +115,7 @@ private function resolveDirectories(ContainerBuilder $container, array $director
private function getTemplatePath(string $name, array $directories): ?string
{
$template = sprintf('%s.html.twig', $name);

$finder = new Finder();

$files = $finder->in($directories)->files()->filter(fn (SplFileInfo $file) => $file->getFilename() === $template);

if ($files->count() > 1) {
Expand All @@ -128,6 +128,6 @@ private function getTemplatePath(string $name, array $directories): ?string

$files->getIterator()->rewind();

return $files->getIterator()->current();
return $files->getIterator()->current()?->__toString();
}
}
2 changes: 2 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace Qossmic\TwigDocBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
Expand Down
2 changes: 2 additions & 0 deletions src/DependencyInjection/TwigDocExtension.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace Qossmic\TwigDocBundle\DependencyInjection;

use Qossmic\TwigDocBundle\Component\ComponentCategory;
Expand Down
2 changes: 1 addition & 1 deletion src/Service/CategoryService.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function getCategories(): array
public function getSubCategories(?ComponentCategory $mainCategory = null): array
{
if ($mainCategory !== null) {
return array_filter($this->subCategories, fn (ComponentCategory $category) => $category->getParent() === $mainCategory);
return array_filter($this->subCategories, static fn (ComponentCategory $category) => $category->getParent() === $mainCategory);
}

return $this->subCategories;
Expand Down
14 changes: 7 additions & 7 deletions src/Service/ComponentService.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
use Qossmic\TwigDocBundle\Exception\InvalidComponentConfigurationException;
use Symfony\Contracts\Cache\CacheInterface;

class ComponentService
readonly class ComponentService
{
public function __construct(
private readonly ComponentItemFactory $itemFactory,
private readonly array $componentsConfig,
private readonly CacheInterface $cache,
private readonly array $breakpointConfig,
private readonly int $configReadTime = 0
private ComponentItemFactory $itemFactory,
private array $componentsConfig,
private CacheInterface $cache,
private array $breakpointConfig,
private int $configReadTime = 0
) {
}

Expand Down Expand Up @@ -94,7 +94,7 @@ public function getInvalidComponents(): array

public function getComponent(string $name): ?ComponentItem
{
return array_values(array_filter((array) $this->getComponents(), fn (ComponentItem $c) => $c->getName() === $name))[0] ?? null;
return array_values(array_filter((array) $this->getComponents(), static fn (ComponentItem $c) => $c->getName() === $name))[0] ?? null;
}

public function getBreakpoints(): array
Expand Down
Loading

0 comments on commit 50f2c96

Please sign in to comment.