Completed
Push — master ( 11b317...37df4d )
by Lucas
09:27
created

ExtRefFieldsCompilerPass::processDocument()   C

Complexity

Conditions 8
Paths 8

Size

Total Lines 33
Code Lines 22

Duplication

Lines 9
Ratio 27.27 %

Code Coverage

Tests 29
CRAP Score 8.0023

Importance

Changes 0
Metric Value
dl 9
loc 33
ccs 29
cts 30
cp 0.9667
rs 5.3846
c 0
b 0
f 0
cc 8
eloc 22
nc 8
nop 2
crap 8.0023
1
<?php
2
/**
3
 * build a list of all services that have extref mappings
4
 *
5
 * This list later gets used during rendering URLs in the output where we
6
 * need to know when and wht really needs rendering after our doctrine
7
 * custom type is only able to spit out the raw data during hydration.
8
 */
9
10
namespace Graviton\DocumentBundle\DependencyInjection\Compiler;
11
12
use Graviton\DocumentBundle\DependencyInjection\Compiler\Utils\ArrayField;
13
use Graviton\DocumentBundle\DependencyInjection\Compiler\Utils\Document;
14
use Graviton\DocumentBundle\DependencyInjection\Compiler\Utils\DocumentMap;
15
use Graviton\DocumentBundle\DependencyInjection\Compiler\Utils\EmbedMany;
16
use Graviton\DocumentBundle\DependencyInjection\Compiler\Utils\EmbedOne;
17
use Graviton\DocumentBundle\DependencyInjection\Compiler\Utils\Field;
18
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
19
use Symfony\Component\DependencyInjection\ContainerBuilder;
20
use Symfony\Component\DependencyInjection\Definition;
21
22
/**
23
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
24
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
25
 * @link     http://swisscom.ch
26
 */
27
class ExtRefFieldsCompilerPass implements CompilerPassInterface
28
{
29
    /**
30
     * @var DocumentMap
31
     */
32
    private $documentMap;
33
34
    /**
35
     * Constructor
36
     *
37
     * @param DocumentMap $documentMap Document map
38
     */
39 4
    public function __construct(DocumentMap $documentMap)
40
    {
41 4
        $this->documentMap = $documentMap;
42 4
    }
43
44
    /**
45
     * Make extref fields map and set it to parameter
46
     *
47
     * @param ContainerBuilder $container container builder
48
     * @return void
49
     */
50 4
    public function process(ContainerBuilder $container)
51
    {
52 4
        $map = [];
53
54 4
        $services = array_keys($container->findTaggedServiceIds('graviton.rest'));
55 4
        foreach ($services as $id) {
56 4
            list($ns, $bundle, , $doc) = explode('.', $id);
57 4
            if (empty($bundle) || empty($doc)) {
58
                continue;
59
            }
60 4
            if ($bundle === 'core' && $doc === 'main') {
61
                continue;
62
            }
63
64 4
            $className = $this->getServiceDocument(
65 4
                $container->getDefinition($id),
66 2
                $ns,
67 2
                $bundle,
68
                $doc
69 2
            );
70 4
            $extRefFields = $this->processDocument($this->documentMap->getDocument($className));
71 4
            $routePrefix = strtolower($ns.'.'.$bundle.'.'.'rest'.'.'.$doc);
72
73 4
            $map[$routePrefix.'.get'] = $extRefFields;
74 4
            $map[$routePrefix.'.all'] = $extRefFields;
75 2
        }
76
77 4
        $container->setParameter('graviton.document.extref.fields', $map);
78 4
    }
79
80
81
    /**
82
     * Get document class name from service
83
     *
84
     * @param Definition $service Service definition
85
     * @param string     $ns      Bundle namespace
86
     * @param string     $bundle  Bundle name
87
     * @param string     $doc     Document name
88
     * @return string
89
     */
90 4 View Code Duplication
    private function getServiceDocument(Definition $service, $ns, $bundle, $doc)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
91
    {
92 4
        $tags = $service->getTag('graviton.rest');
93 4
        if (!empty($tags[0]['collection'])) {
94 2
            $doc = $tags[0]['collection'];
95 2
            $bundle = $tags[0]['collection'];
96 1
        }
97
98 4
        if (strtolower($ns) === 'gravitondyn') {
99 2
            $ns = 'GravitonDyn';
100 1
        }
101
102 4
        return sprintf(
103 4
            '%s\\%s\\Document\\%s',
104 2
            ucfirst($ns),
105 4
            ucfirst($bundle).'Bundle',
106 2
            ucfirst($doc)
107 2
        );
108
    }
109
110
    /**
111
     * Recursive doctrine document processing
112
     *
113
     * @param Document $document      Document
114
     * @param string   $exposedPrefix Exposed field prefix
115
     * @return array
116
     */
117 4
    private function processDocument(Document $document, $exposedPrefix = '')
118
    {
119 4
        $result = [];
120 4
        foreach ($document->getFields() as $field) {
121 4
            if ($field instanceof Field) {
122 4
                if ($field->getType() === 'extref') {
123 4
                    $result[] = $exposedPrefix.$field->getExposedName();
124 2
                }
125 4
            } elseif ($field instanceof ArrayField) {
126 2
                if ($field->getItemType() === 'extref') {
127 1
                    $result[] = $exposedPrefix.$field->getExposedName().'.0';
128
                }
129 2
            } elseif ($field instanceof EmbedOne) {
130 4
                $result = array_merge(
131 2
                    $result,
132 4
                    $this->processDocument(
133 4
                        $field->getDocument(),
134 4
                        $exposedPrefix.$field->getExposedName().'.'
135 2
                    )
136 2
                );
137 2 View Code Duplication
            } elseif ($field instanceof EmbedMany) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
138 4
                $result = array_merge(
139 2
                    $result,
140 4
                    $this->processDocument(
141 4
                        $field->getDocument(),
142 4
                        $exposedPrefix.$field->getExposedName().'.0.'
143 2
                    )
144 2
                );
145 2
            }
146 2
        }
147
148 4
        return $result;
149
    }
150
}
151