/autodiscovery

[READ-ONLY] Forget manual registration of Doctrine entities, Twig templates and routes. Let autodiscovery handle that for you

Primary LanguagePHPMIT LicenseMIT

Load Entities, Twig paths and Routes once and for All

Downloads total

For every

  • new Entity namespace,
  • new Twig path
  • new Translation catalogue path
  • and new routes files,

you need to modify your config. Why do it, when your application can do it for you? Do you autoload each Controller manually? :)

Another feature is YAML convertor - from old pre-Symfony 3.3 to new autodiscovery, autowire and autoconfigure format.

Install

composer require symplify/autodiscovery

Usage

1. Register Doctrine Annotation Mapping

When you create a new package with entities, you need to register them:

# app/config/doctrine.yml
doctrine:
    orm:
        mappings:
            # new set for each new namespace
            ShopsysFrameworkBundle:
                type: annotation
                dir: '%shopsys.framework.root_dir%/src/Model'
                alias: ShopsysFrameworkBundle
                prefix: Shopsys\FrameworkBundle\Model
                is_bundle: false
            # new set for each new namespace
            ShopsysFrameworkBundleComponent:
                type: annotation
                dir: '%shopsys.framework.root_dir%/src/Component'
                alias: ShopsysFrameworkBundleComponent
                prefix: Shopsys\FrameworkBundle\Component
                is_bundle: false

It's called memory lock and it nicely opens doors for "I forgot that..." bugs.

How can we avoid that?

With Autodiscovery

 # app/config/twig.yml
 doctrine:
     orm:
-        mappings:
-            # new set for each new namespace
-            ShopsysFrameworkBundle:
-                type: annotation
-                dir: '%shopsys.framework.root_dir%/src/Model'
-                alias: ShopsysFrameworkBundle
-                prefix: Shopsys\FrameworkBundle\Model
-                is_bundle: false
-            # new set for each new namespace
-            ShopsysFrameworkBundleComponent:
-                type: annotation
-                dir: '%shopsys.framework.root_dir%/src/Component'
-                alias: ShopsysFrameworkBundleComponent
-                prefix: Shopsys\FrameworkBundle\Component
-                is_bundle: false
namespace App;

use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel;
use Symplify\Autodiscovery\Discovery;

final class MyProjectKernel extends Kernel
{
    use MicroKernelTrait;

    /**
     * @var Discovery
     */
    private $discovery;

    public function __construct()
    {
        parent::__construct('dev', true);

        $this->discovery = new Discovery($this->getProjectDir());
    }

    protected function configureContainer(ContainerBuilder $containerBuilder, LoaderInterface $loader): void
    {
        $this->discovery->discoverEntityMappings($containerBuilder);
    }
}

2. Twig Paths

When you create a new package with templates, you need to register them:

# app/config/twig.yml
twig:
    paths:
        # new line for each new package
        - "%kernel.root_dir%/../package/Product/templates"
        # new line for each new package
        - "%kernel.root_dir%/../package/Social/templates"

With Autodiscovery

 # app/config/twig.yml
 twig:
-    paths:
-        - "%kernel.root_dir%/../package/Product/templates/views"
-        - "%kernel.root_dir%/../package/Social/templates/views"
namespace App;

use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel;

final class MyProjectKernel extends Kernel
{
    use MicroKernelTrait;

    // ...

    protected function configureContainer(ContainerBuilder $containerBuilder, LoaderInterface $loader): void
    {
        $this->discovery->discoverTemplates($containerBuilder);
    }
}

3. Translation Paths

When you create a new package with translations, you need to register them:

# app/config/packages/framework.yml
framework:
    translator:
        paths:
            # new line for each new package
            - "%kernel.root_dir%/../package/Product/translations"
            # new line for each new package
            - "%kernel.root_dir%/../package/Social/translations"

With Autodiscovery

 # app/config/packages/framework.yml
 framework:
     translator:
-        paths:
-            - "%kernel.root_dir%/../package/Product/translations"
-            - "%kernel.root_dir%/../package/Social/translations"
namespace App;

use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel;

final class MyProjectKernel extends Kernel
{
    use MicroKernelTrait;

    // ...

    protected function configureContainer(ContainerBuilder $containerBuilder, LoaderInterface $loader): void
    {
        $this->discovery->discoverTranslations($containerBuilder);
    }
}

4. Routing

# app/config/routes.yaml

# new set for each new package
product_annotations:
    resource: "../packages/Product/src/Controller/"
    type: "annotation"

# new set for each new package
social_annotations:
    resource: "../packages/Social/src/Controller/"
    type: "annotation"

With Autodiscovery

 # app/config/routes.yaml

-# new set for each new package
-product_annotations:
-    resource: "../packages/Product/src/Controller/"
-    type: "annotation"
-
-# new set for each new package
-social_annotations:
-    resource: "../packages/Social/src/Controller/"
-    type: "annotation"
namespace App;

use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Routing\RouteCollectionBuilder;

final class MyProjectKernel extends Kernel
{
    use MicroKernelTrait;

    protected function configureRoutes(RouteCollectionBuilder $routeCollectionBuilder): void
    {
        $this->discovery->discoverRoutes($routeCollectionBuilder);
    }
}

This works very well with local packages or monorepo architecture.


Report Issues

In case you are experiencing a bug or want to request a new feature head over to the Symplify monorepo issue tracker

Contribute

The sources of this package are contained in the Symplify monorepo. We welcome contributions for this package on symplify/symplify.