Skip to content

Instantly share code, notes, and snippets.

@faizanakram99
Created May 30, 2024 22:39
Show Gist options
  • Save faizanakram99/a7241274a3f923a3d2c78dc20c0a5ca8 to your computer and use it in GitHub Desktop.
Save faizanakram99/a7241274a3f923a3d2c78dc20c0a5ca8 to your computer and use it in GitHub Desktop.
Kcs Finder Interface performant implementation for graphqlite symfony bundle
<?php
declare(strict_types=1);
namespace Yay;
use Kcs\ClassFinder\Finder\FinderInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\Finder\Finder;
class GraphQLiteClassesFinder implements FinderInterface
{
private array $namespaces;
/**
* @param string[] $namespaceControllers
* @param string[] $namespaceTypes
*/
public function __construct(
#[Autowire(param: 'kernel.project_dir')]
private string $projectDir,
#[Autowire(param: 'graphqlite.namespace.controllers')]
private array $namespaceControllers,
#[Autowire(param: 'graphqlite.namespace.types')]
private array $namespaceTypes,
) {
}
public function getIterator(): \Traversable
{
$namespaces = $this->namespaces ?? [...$this->namespaceControllers, ...$this->namespaceTypes];
foreach ($namespaces as $namespace) {
$dir = "{$this->projectDir}/src/".\str_replace(['Yay\\', '\\'], '/', $namespace);
if (!\is_dir($dir)) {
continue;
}
$finder = new Finder();
$finder->files()->in($dir)->name('*.php');
foreach ($finder as $file) {
$class = 'Yay'
.\str_replace(
'/',
'\\',
\str_replace(["$this->projectDir/src/", '.php'], '', $file->getPathname()),
);
yield $class => new \ReflectionClass($class);
}
}
}
public function implementationOf(array|string $interface): FinderInterface
{
return $this;
}
public function subclassOf(?string $superClass): FinderInterface
{
return $this;
}
public function annotatedBy(?string $annotationClass): FinderInterface
{
return $this;
}
public function withAttribute(?string $attributeClass): FinderInterface
{
return $this;
}
public function in(array|string $dirs): FinderInterface
{
return $this;
}
public function inNamespace(array|string $namespaces): FinderInterface
{
$this->namespaces = (array) $namespaces;
return $this;
}
public function notInNamespace(array|string $namespaces): FinderInterface
{
return $this;
}
public function filter(?callable $callback): FinderInterface
{
return $this;
}
public function path(string $pattern): FinderInterface
{
return $this;
}
public function notPath(string $pattern): FinderInterface
{
return $this;
}
public function pathFilter(?callable $callback): FinderInterface
{
return $this;
}
}
<?php
declare(strict_types=1);
namespace Yay;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
use TheCodingMachine\GraphQLite\SchemaFactory;
class Kernel extends BaseKernel implements CompilerPassInterface
{
use MicroKernelTrait;
protected function configureContainer(ContainerConfigurator $container): void
{
// ... skipped for brevity
}
protected function configureRoutes(RoutingConfigurator $routes): void
{
// ... skipped for brevity
}
public function process(ContainerBuilder $container): void
{
$container->autowire(GraphQLiteClassesFinder::class, GraphQLiteClassesFinder::class);
$schemaFactory = $container->getDefinition(SchemaFactory::class);
$schemaFactory->addMethodCall('setFinder', [
new Reference(GraphQLiteClassesFinder::class),
]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment