This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * This file is part of the DTForce Nette-Doctrine extension (http://www.dtforce.com/). |
||
5 | * |
||
6 | * This source file is subject to the GNU Lesser General Public License. |
||
7 | */ |
||
8 | |||
9 | namespace DTForce\DoctrineExtension\DI; |
||
10 | |||
11 | use Doctrine\ORM\Events; |
||
12 | use DTForce\DoctrineExtension\Contract\IClassMappingProvider; |
||
13 | use DTForce\DoctrineExtension\Contract\IEntitySourceProvider; |
||
14 | use Nette\DI\CompilerExtension; |
||
15 | use Nette\DI\ContainerBuilder; |
||
16 | use Nette\DI\Statement; |
||
17 | use Nette\InvalidStateException; |
||
18 | use Nette\PhpGenerator\ClassType; |
||
19 | use Nette\Utils\Validators; |
||
20 | |||
21 | |||
22 | /** |
||
23 | * Doctrine Extension for Nette. |
||
24 | * |
||
25 | * Sample configuration: |
||
26 | * <code> |
||
27 | * doctrine: |
||
28 | * config: |
||
29 | * driver: pdo_pgsql |
||
30 | * host: localhost |
||
31 | * port: 5432 |
||
32 | * user: username |
||
33 | * password: password |
||
34 | * dbname: database |
||
35 | * |
||
36 | * debug: true |
||
37 | * prefix: doctrine.default |
||
38 | * proxyDir: %tempDir%/cache/proxies |
||
39 | * </code> |
||
40 | * |
||
41 | * @author Jan Mareš |
||
42 | * @package DTForce\DoctrineExtension\DI |
||
43 | */ |
||
44 | class DoctrineExtension extends CompilerExtension |
||
45 | { |
||
46 | |||
47 | const DOCTRINE_SQL_PANEL_FQN = 'DTForce\DoctrineExtension\Debug\DoctrineSQLPanel'; |
||
48 | const DOCTRINE_DEFAULT_CACHE = 'Doctrine\Common\Cache\ArrayCache'; |
||
49 | const KDYBY_CONSOLE_EXTENSION = 'Kdyby\Console\DI\ConsoleExtension'; |
||
50 | |||
51 | /** |
||
52 | * @var array |
||
53 | */ |
||
54 | public static $defaults = [ |
||
55 | 'debug' => TRUE, |
||
56 | |||
57 | 'dbal' => [ |
||
58 | 'type_overrides' => [], |
||
59 | 'types' => [], |
||
60 | 'schema_filter' => NULL |
||
61 | ], |
||
62 | |||
63 | 'prefix' => 'doctrine.default', |
||
64 | 'proxyDir' => '%tempDir%/cache/proxies', |
||
65 | 'sourceDir' => NULL, |
||
66 | 'ownEventManager' => FALSE, |
||
67 | 'targetEntityMappings' => [], |
||
68 | 'metadata' => [], |
||
69 | 'functions' => [] |
||
70 | ]; |
||
71 | |||
72 | private $entitySources = []; |
||
73 | |||
74 | private $classMappings = []; |
||
75 | |||
76 | |||
77 | public function loadConfiguration() |
||
78 | { |
||
79 | $config = $this->getConfig(self::$defaults); |
||
80 | |||
81 | $this->classMappings = $config['targetEntityMappings']; |
||
82 | $this->entitySources = $config['metadata']; |
||
83 | foreach ($this->compiler->getExtensions() as $extension) { |
||
84 | if ($extension instanceof IEntitySourceProvider) { |
||
85 | $entitySource = $extension->getEntityFolderMappings(); |
||
86 | Validators::assert($entitySource, 'array'); |
||
87 | $this->entitySources = array_merge($this->entitySources, $entitySource); |
||
88 | } |
||
89 | |||
90 | if ($extension instanceof IClassMappingProvider) { |
||
91 | $entityMapping = $extension->getClassnameToClassnameMapping(); |
||
92 | Validators::assert($entityMapping, 'array'); |
||
93 | $this->classMappings = array_merge($this->classMappings, $entityMapping); |
||
94 | } |
||
95 | |||
96 | } |
||
97 | |||
98 | if ($config['sourceDir'] !== NULL) { |
||
99 | $this->entitySources[] = $config['sourceDir']; |
||
100 | } |
||
101 | |||
102 | $builder = $this->getContainerBuilder(); |
||
103 | |||
104 | $name = $config['prefix']; |
||
105 | |||
106 | |||
107 | $builder->addDefinition($name . ".resolver") |
||
108 | ->setClass('\Doctrine\ORM\Tools\ResolveTargetEntityListener'); |
||
109 | |||
110 | $builder->addDefinition($name . ".naming") |
||
111 | ->setClass('\Doctrine\ORM\Mapping\UnderscoreNamingStrategy'); |
||
112 | |||
113 | $builder->addDefinition($name . ".config") |
||
114 | ->setClass('\Doctrine\ORM\Configuration') |
||
115 | ->addSetup(new Statement('setFilterSchemaAssetsExpression', [$config['dbal']['schema_filter']])); |
||
116 | |||
117 | |||
118 | $builder->addDefinition($name . ".connection") |
||
119 | ->setClass('\Doctrine\DBAL\Connection') |
||
120 | ->setFactory('@' . $name . '.entityManager::getConnection'); |
||
121 | |||
122 | |||
123 | $builder->addDefinition($name . ".entityManager") |
||
124 | ->setClass('\Doctrine\ORM\EntityManager') |
||
125 | ->setFactory('\Doctrine\ORM\EntityManager::create', [ |
||
126 | $config['connection'], |
||
127 | '@' . $name . '.config', |
||
128 | '@Doctrine\Common\EventManager' |
||
129 | ]); |
||
130 | |||
131 | if ($this->hasIBarPanelInterface()) { |
||
132 | $builder->addDefinition($this->prefix($name . '.diagnosticsPanel')) |
||
133 | ->setClass(self::DOCTRINE_SQL_PANEL_FQN); |
||
134 | } |
||
135 | |||
136 | $this->addHelpersToKdybyConsole($builder); |
||
137 | } |
||
138 | |||
139 | public function beforeCompile() |
||
140 | { |
||
141 | $builder = $this->getContainerBuilder(); |
||
142 | |||
143 | $config = $this->getConfig(self::$defaults); |
||
144 | $name = $config['prefix']; |
||
145 | |||
146 | $cache = $this->getCache($name, $builder); |
||
147 | |||
148 | $configService = $builder->getDefinition($name . ".config") |
||
149 | ->setFactory('\Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration', [ |
||
150 | array_values($this->entitySources), |
||
151 | $config['debug'], |
||
152 | $config['proxyDir'], |
||
153 | $cache, |
||
154 | FALSE |
||
155 | ]) |
||
156 | ->addSetup('setNamingStrategy', ['@' . $name . '.naming']); |
||
157 | |||
158 | |||
159 | foreach ($config['functions'] as $functionName => $function) { |
||
160 | $configService->addSetup( |
||
161 | 'addCustomStringFunction', |
||
162 | [ |
||
163 | $functionName, |
||
164 | $function |
||
165 | ] |
||
166 | ); |
||
167 | } |
||
168 | |||
169 | |||
170 | foreach ($this->classMappings as $source => $target) { |
||
171 | $builder->getDefinition($name . '.resolver') |
||
172 | ->addSetup('addResolveTargetEntity', [ |
||
173 | $source, $target, [] |
||
174 | ]); |
||
175 | } |
||
176 | |||
177 | if($this->hasEventManager($builder)) { |
||
178 | $builder->getDefinition($builder->getByType('Doctrine\Common\EventManager')) |
||
179 | ->addSetup('addEventListener', [Events::loadClassMetadata, '@' . $name . '.resolver']); |
||
180 | } else { |
||
181 | if($config['ownEventManager']){ |
||
182 | throw new InvalidStateException("Where is your own EventManager?"); |
||
183 | } |
||
184 | $builder->addDefinition($name . ".eventManager") |
||
185 | ->setClass('Doctrine\Common\EventManager') |
||
186 | ->addSetup('addEventListener', [Events::loadClassMetadata, '@' . $name . '.resolver']); |
||
187 | } |
||
188 | |||
189 | $this->processDbalTypes($name, $config['dbal']['types']); |
||
190 | $this->processDbalTypeOverrides($name, $config['dbal']['type_overrides']); |
||
191 | } |
||
192 | |||
193 | |||
194 | /** |
||
195 | * @param string $name |
||
196 | * @param array $types |
||
197 | */ |
||
198 | View Code Duplication | private function processDbalTypes($name, array $types) |
|
0 ignored issues
–
show
|
|||
199 | { |
||
200 | $builder = $this->getContainerBuilder(); |
||
201 | $connection = $builder->getDefinition($name . '.entityManager'); |
||
202 | |||
203 | foreach ($types as $type => $className) { |
||
204 | $connection->addSetup( |
||
205 | 'if ( ! Doctrine\DBAL\Types\Type::hasType(?)) { Doctrine\DBAL\Types\Type::addType(?, ?); }', |
||
206 | [$type, $type, $className] |
||
207 | ); |
||
208 | } |
||
209 | } |
||
210 | |||
211 | |||
212 | /** |
||
213 | * @param string $name |
||
214 | * @param array $types |
||
215 | */ |
||
216 | View Code Duplication | private function processDbalTypeOverrides($name, array $types) |
|
0 ignored issues
–
show
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...
|
|||
217 | { |
||
218 | $builder = $this->getContainerBuilder(); |
||
219 | $entityManagerDefinition = $builder->getDefinition($name . '.entityManager'); |
||
220 | |||
221 | foreach ($types as $type => $className) { |
||
222 | $entityManagerDefinition->addSetup('Doctrine\DBAL\Types\Type::overrideType(?, ?);', [$type, $className]); |
||
223 | } |
||
224 | } |
||
225 | |||
226 | |||
227 | public function afterCompile(ClassType $class) |
||
228 | { |
||
229 | $initialize = $class->methods['initialize']; |
||
230 | if ($this->hasIBarPanelInterface()) { |
||
231 | $initialize->addBody('$this->getByType(\'' . self::DOCTRINE_SQL_PANEL_FQN . '\')->bindToBar();'); |
||
232 | } |
||
233 | } |
||
234 | |||
235 | |||
236 | /** |
||
237 | * @return bool |
||
238 | */ |
||
239 | private function hasIBarPanelInterface() |
||
240 | { |
||
241 | return interface_exists('Tracy\IBarPanel'); |
||
242 | } |
||
243 | |||
244 | |||
245 | private function addHelpersToKdybyConsole(ContainerBuilder $builder) |
||
246 | { |
||
247 | if(class_exists(self::KDYBY_CONSOLE_EXTENSION)){ |
||
248 | $helperTag = constant(self::KDYBY_CONSOLE_EXTENSION . '::HELPER_TAG'); |
||
249 | $builder->addDefinition($this->prefix('helper.entityManager')) |
||
250 | ->setClass('Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper') |
||
251 | ->addTag($helperTag, 'em'); |
||
252 | } |
||
253 | } |
||
254 | |||
255 | /** |
||
256 | * Tests whether EventManager is defined. |
||
257 | * |
||
258 | * @param ContainerBuilder $builder |
||
259 | * @return bool |
||
260 | */ |
||
261 | private function hasEventManager(ContainerBuilder $builder) |
||
262 | { |
||
263 | return strlen($builder->getByType('Doctrine\Common\EventManager')) > 0; |
||
264 | } |
||
265 | |||
266 | private function getCache($prefix, ContainerBuilder $builder){ |
||
267 | if(strlen($builder->getByType('Doctrine\Common\Cache\Cache')) > 0){ |
||
268 | return '@' . $builder->getByType('Doctrine\Common\Cache\Cache'); |
||
269 | } else { |
||
270 | $builder->addDefinition($prefix . ".cache") |
||
271 | ->setClass(self::DOCTRINE_DEFAULT_CACHE); |
||
272 | return '@' . $prefix . ".cache"; |
||
273 | } |
||
274 | } |
||
275 | } |
||
276 |
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.