Completed
Pull Request — master (#244)
by Łukasz
11:47
created

AdminAnnotatedElementPass::process()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 1
1
<?php
2
3
/**
4
 * (c) FSi sp. z o.o. <[email protected]>
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace FSi\Bundle\AdminBundle\DependencyInjection\Compiler;
11
12
use Doctrine\Common\Annotations\AnnotationReader;
13
use FSi\Bundle\AdminBundle\Annotation\Element;
14
use FSi\Bundle\AdminBundle\Extractor\BundlePathExtractor;
15
use FSi\Bundle\AdminBundle\Finder\AdminClassFinder;
16
use Symfony\Component\Config\Resource\DirectoryResource;
17
use Symfony\Component\DependencyInjection\ContainerBuilder;
18
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
19
use Symfony\Component\DependencyInjection\Definition;
20
21
class AdminAnnotatedElementPass implements CompilerPassInterface
22
{
23
    const ANNOTATION_CLASS = 'FSi\\Bundle\\AdminBundle\\Annotation\\Element';
24
25
    /**
26
     * @var AnnotationReader
27
     */
28
    private $annotationReader;
29
30
    /**
31
     * @var AdminClassFinder
32
     */
33
    private $adminClassFinder;
34
35
    /**
36
     * @param AnnotationReader $annotationReader
37
     * @param AdminClassFinder $adminClassFinder
38
     */
39
    public function __construct(AnnotationReader $annotationReader, AdminClassFinder $adminClassFinder)
40
    {
41
        $this->annotationReader = $annotationReader;
42
        $this->adminClassFinder = $adminClassFinder;
43
    }
44
45
    /**
46
     * @param ContainerBuilder $container
47
     */
48
    public function process(ContainerBuilder $container)
49
    {
50
        $paths = $this->getBundlesAdminPaths($container);
51
52
        $annotatedAdminClassess = $this->findAnnotatedAdminClasses($paths);
53
        $adminElementsDefinitions = array();
54
        foreach ($annotatedAdminClassess as $adminClass) {
55
            $adminElementsDefinitions[] = $this->createAdminElementDefinition($adminClass);
56
        }
57
        $container->addDefinitions($adminElementsDefinitions);
58
    }
59
60
    /**
61
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
62
     * @return array
63
     */
64
    private function getBundlesAdminPaths(ContainerBuilder $container)
65
    {
66
        $bundleClasses = $container->getParameter('kernel.bundles');
67
        $paths = array();
68
        foreach ($bundleClasses as $bundleClass) {
69
            $bundleClassReflector = new \ReflectionClass($bundleClass);
70
            $bundleAdminPath = dirname($bundleClassReflector->getFileName()) . '/Admin';
71
            if (is_dir($bundleAdminPath)) {
72
                $container->addResource(new DirectoryResource($bundleAdminPath, '/\.php$/'));
73
                $paths[] = $bundleAdminPath;
74
            }
75
        }
76
        return $paths;
77
    }
78
79
    /**
80
     * @param $class
81
     * @return \Symfony\Component\DependencyInjection\Definition
82
     */
83
    private function createAdminElementDefinition($class)
84
    {
85
        $definition = new Definition($class);
86
        $definition->addTag('admin.element');
87
88
        return $definition;
89
    }
90
91
    /**
92
     * @param array $paths
93
     * @return array
94
     */
95
    private function findAnnotatedAdminClasses(array $paths)
96
    {
97
        $annotatedAdminClasses = array();
98
99
        foreach ($this->adminClassFinder->findClasses($paths) as $class) {
100
            $annotation = $this->annotationReader->getClassAnnotation(
101
                new \ReflectionClass($class),
102
                self::ANNOTATION_CLASS
103
            );
104
105
            if (isset($annotation) && $annotation instanceof Element) {
106
                $annotatedAdminClasses[] = $class;
107
            }
108
        }
109
110
        return $annotatedAdminClasses;
111
    }
112
}
113