1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13: namespace DcGeneral\Contao\Dca\Builder\Legacy;
14:
15: use DcGeneral\Contao\DataDefinition\Definition\Contao2BackendViewDefinition;
16: use DcGeneral\Contao\DataDefinition\Definition\Contao2BackendViewDefinitionInterface;
17: use DcGeneral\Contao\Dca\ContaoDataProviderInformation;
18: use DcGeneral\Contao\Dca\Definition\ExtendedDca;
19: use DcGeneral\DataDefinition\ContainerInterface;
20: use DcGeneral\DataDefinition\Definition\DataProviderDefinitionInterface;
21: use DcGeneral\DataDefinition\Definition\DefaultBasicDefinition;
22: use DcGeneral\DataDefinition\Definition\DefaultDataProviderDefinition;
23: use DcGeneral\DataDefinition\Definition\DefaultModelRelationshipDefinition;
24: use DcGeneral\DataDefinition\Definition\DefaultPalettesDefinition;
25: use DcGeneral\DataDefinition\Definition\ModelRelationshipDefinitionInterface;
26: use DcGeneral\DataDefinition\Definition\PalettesDefinitionInterface;
27: use DcGeneral\DataDefinition\Definition\View\DefaultModelFormatterConfig;
28: use DcGeneral\DataDefinition\Definition\View\ListingConfigInterface;
29: use DcGeneral\DataDefinition\ModelRelationship\ParentChildCondition;
30: use DcGeneral\DataDefinition\ModelRelationship\RootCondition;
31: use DcGeneral\Exception\DcGeneralInvalidArgumentException;
32: use DcGeneral\Exception\DcGeneralRuntimeException;
33: use DcGeneral\Factory\DcGeneralFactory;
34: use DcGeneral\Factory\Event\BuildDataDefinitionEvent;
35: use DcGeneral\Factory\Event\PopulateEnvironmentEvent;
36:
37: 38: 39:
40: class ExtendedLegacyDcaDataDefinitionBuilder extends DcaReadingDataDefinitionBuilder
41: {
42: const PRIORITY = 101;
43:
44: 45: 46:
47: public function build(ContainerInterface $container, BuildDataDefinitionEvent $event)
48: {
49: if (!$this->loadDca($container->getName(), $event->getDispatcher()))
50: {
51: return;
52: }
53:
54: $this->parseBasicDefinition($container);
55: $this->parseDataProvider($container);
56: $this->parsePalettes($container);
57: $this->parseConditions($container);
58: $this->parseBackendView($container);
59: $this->parseClassNames($container);
60: $this->loadAdditionalDefinitions($container, $event);
61: }
62:
63: 64: 65: 66: 67: 68: 69:
70: protected function parseBasicDefinition(ContainerInterface $container)
71: {
72: if (!$container->hasBasicDefinition())
73: {
74: $config = new DefaultBasicDefinition();
75: $container->setBasicDefinition($config);
76: }
77: }
78:
79: 80: 81: 82: 83: 84: 85: 86: 87:
88: protected function loadAdditionalDefinitions(ContainerInterface $container, BuildDataDefinitionEvent $event)
89: {
90: if (($providers = $this->getFromDca('dca_config/data_provider')) !== null)
91: {
92: $event->getDispatcher()->addListener(
93: sprintf('%s[%s]', PopulateEnvironmentEvent::NAME, $container->getName()),
94: function (PopulateEnvironmentEvent $event) {
95: $environment = $event->getEnvironment();
96: $definition = $environment->getDataDefinition();
97: $parentName = $definition->getBasicDefinition()->getParentDataProvider();
98:
99: if ($parentName)
100: {
101: $factory = DcGeneralFactory::deriveEmptyFromEnvironment($environment)->setContainerName($parentName);
102: $parentDefinition = $factory->createContainer();
103:
104: $environment->setParentDataDefinition($parentDefinition);
105: }
106:
107: $rootName = $definition->getBasicDefinition()->getRootDataProvider();
108: if ($rootName)
109: {
110:
111: $factory = DcGeneralFactory::deriveEmptyFromEnvironment($environment)->setContainerName($rootName);
112: $rootDefinition = $factory->createContainer();
113:
114: $environment->setRootDataDefinition($rootDefinition);
115: }
116: }
117: );
118: }
119: }
120:
121: 122: 123: 124: 125: 126: 127: 128: 129:
130: protected function parseClassNames(ContainerInterface $container)
131: {
132: if ($container->hasDefinition(ExtendedDca::NAME))
133: {
134: $definition = $container->getDefinition(ExtendedDca::NAME);
135:
136: if (!($definition instanceof ExtendedDca))
137: {
138: throw new DcGeneralInvalidArgumentException(sprintf(
139: 'Definition with name %s must be an instance of ExtendedDca but instance of %s encountered.',
140: ExtendedDca::NAME,
141: get_class($definition)
142: ));
143: }
144: }
145: else
146: {
147: $definition = new ExtendedDca();
148: $container->setDefinition(ExtendedDca::NAME, $definition);
149: }
150:
151: if ($this->getFromDca('dca_config') === null)
152: {
153: return;
154: }
155:
156: if (($class = $this->getFromDca('dca_config/controller')) !== null)
157: {
158: $definition->setControllerClass($class);
159: }
160:
161: if (($class = $this->getFromDca('dca_config/view')) !== null)
162: {
163: $definition->setViewClass($class);
164: }
165: }
166:
167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177:
178: protected function parseSingleDataProvider(
179: ContainerInterface $container,
180: DataProviderDefinitionInterface $providers,
181: array $information
182: )
183: {
184: if (isset($information['factory']))
185: {
186: $factoryClass = new \ReflectionClass($information['factory']);
187: $factory = $factoryClass->newInstance();
188: $providerInformation = $factory->build($information);
189: }
190: else
191: {
192:
193: if (isset($information['source']))
194: {
195: $providerName = $information['source'];
196: }
197: else
198: {
199: $providerName = $container->getName();
200: }
201:
202:
203: if (!$providers->hasInformation($providerName))
204: {
205: $providerInformation = new ContaoDataProviderInformation();
206: $providerInformation->setName($providerName);
207: $providers->addInformation($providerInformation);
208: }
209: else
210: {
211: $providerInformation = $providers->getInformation($providerName);
212: }
213:
214: if (!$providerInformation->getTableName())
215: {
216: $providerInformation
217: ->setTableName($providerName);
218: }
219:
220: if (isset($information['class']))
221: {
222: $providerInformation->setClassName($information['class']);
223: }
224: }
225:
226: return $providerInformation;
227: }
228:
229: 230: 231: 232: 233: 234: 235:
236: protected function parseDataProvider(ContainerInterface $container)
237: {
238:
239: if ($container->hasDataProviderDefinition())
240: {
241: $config = $container->getDataProviderDefinition();
242: }
243: else
244: {
245: $config = new DefaultDataProviderDefinition();
246: $container->setDataProviderDefinition($config);
247: }
248:
249:
250: if (!is_array($this->getFromDca('dca_config/data_provider')))
251: {
252: return;
253: }
254:
255: $dataProvidersDca = $this->getFromDca('dca_config/data_provider');
256:
257: foreach ($dataProvidersDca as $dataProviderDcaName => $dataProviderDca)
258: {
259: $providerInformation = $this->parseSingleDataProvider($container, $config, $dataProviderDca);
260:
261: if ($providerInformation instanceof ContaoDataProviderInformation)
262: {
263: $initializationData = (array)$providerInformation->getInitializationData();
264:
265: $providerInformation->setInitializationData(array_merge(
266: $dataProviderDca,
267: $initializationData
268: ));
269:
270: switch ($dataProviderDcaName)
271: {
272: case 'default':
273: $providerInformation->setVersioningEnabled(
274: (bool)$this->getFromDca('config/enableVersioning')
275: );
276:
277: $container->getBasicDefinition()->setDataProvider($providerInformation->getName());
278: break;
279:
280: case 'root':
281: $container->getBasicDefinition()->setRootDataProvider($providerInformation->getName());
282: break;
283:
284: case 'parent':
285: $container->getBasicDefinition()->setParentDataProvider($providerInformation->getName());
286: break;
287:
288: default:
289: }
290: }
291: }
292: }
293:
294: 295: 296: 297: 298: 299: 300:
301: protected function parsePalettes(ContainerInterface $container)
302: {
303: $palettesDca = $this->getFromDca('palettes');
304:
305:
306: if (!is_callable($palettesDca))
307: {
308: return;
309: }
310:
311: if ($container->hasDefinition(PalettesDefinitionInterface::NAME))
312: {
313: $palettesDefinition = $container->getDefinition(PalettesDefinitionInterface::NAME);
314: }
315: else
316: {
317: $palettesDefinition = new DefaultPalettesDefinition();
318: $container->setDefinition(PalettesDefinitionInterface::NAME, $palettesDefinition);
319: }
320:
321: call_user_func($palettesDca, $palettesDefinition, $container);
322: }
323:
324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334:
335: protected function parseConditions(ContainerInterface $container)
336: {
337: if ($container->hasDefinition(ModelRelationshipDefinitionInterface::NAME))
338: {
339: $definition = $container->getDefinition(ModelRelationshipDefinitionInterface::NAME);
340: }
341: else
342: {
343: $definition = new DefaultModelRelationshipDefinition();
344: $container->setDefinition(ModelRelationshipDefinitionInterface::NAME, $definition);
345: }
346:
347: if (($rootCondition = $this->getFromDca('dca_config/rootEntries')) !== null)
348: {
349: $rootProvider = $container->getBasicDefinition()->getRootDataProvider();
350:
351: if (!$rootProvider)
352: {
353: throw new DcGeneralRuntimeException(
354: 'Root data provider name not specified in DCA but rootEntries section specified.'
355: );
356: }
357:
358: if (!$container->getDataProviderDefinition()->hasInformation($rootProvider))
359: {
360: throw new DcGeneralRuntimeException('Unknown root data provider but rootEntries section specified.');
361: }
362:
363: if (isset($rootCondition[$rootProvider]))
364: {
365: $rootCondition = $rootCondition[$rootProvider];
366:
367: $myFilter = $rootCondition['filter'];
368: $mySetter = $rootCondition['setOn'];
369:
370: if (($relationship = $definition->getRootCondition()) === null)
371: {
372: $relationship = new RootCondition();
373: $setter = $mySetter;
374: $filter = array(
375: 'operation' => 'AND',
376: 'children' => $myFilter
377: );
378: }
379: else
380: {
381:
382: if ($relationship->getSetters())
383: {
384: $setter = array_merge_recursive($mySetter, $relationship->getSetters());
385: }
386: else
387: {
388: $setter = $mySetter;
389: }
390: $filter = array_merge($relationship->getFilterArray(), $myFilter);
391: $filter = array(
392: 'operation' => 'AND',
393: 'children' => array($filter)
394: );
395: }
396:
397: $relationship
398: ->setSourceName($rootProvider)
399: ->setFilterArray(array($filter))
400: ->setSetters($setter);
401: $definition->setRootCondition($relationship);
402: }
403: }
404:
405: if (($childConditions = $this->getFromDca('dca_config/childCondition')) !== null)
406: {
407: foreach ((array)$childConditions as $childCondition)
408: {
409: $relationship = new ParentChildCondition();
410:
411: $relationship
412: ->setSourceName($childCondition['from'])
413: ->setDestinationName($childCondition['to'])
414: ->setFilterArray($childCondition['filter'])
415: ->setSetters($childCondition['setOn'])
416: ->setInverseFilterArray($childCondition['inverse']);
417: $definition->addChildCondition($relationship);
418: }
419: }
420: }
421:
422: 423: 424: 425: 426: 427: 428: 429: 430: 431: 432:
433: protected function parseBackendView(ContainerInterface $container)
434: {
435: if ($container->hasDefinition(Contao2BackendViewDefinitionInterface::NAME))
436: {
437: $view = $container->getDefinition(Contao2BackendViewDefinitionInterface::NAME);
438: }
439: else
440: {
441: $view = new Contao2BackendViewDefinition();
442: $container->setDefinition(Contao2BackendViewDefinitionInterface::NAME, $view);
443: }
444:
445: if (!$view instanceof Contao2BackendViewDefinitionInterface)
446: {
447: throw new DcGeneralInvalidArgumentException(
448: 'Configured BackendViewDefinition does not implement Contao2BackendViewDefinitionInterface.'
449: );
450: }
451:
452: $this->parseListing($view);
453: }
454:
455: 456: 457: 458: 459: 460: 461:
462: protected function parseListing(Contao2BackendViewDefinitionInterface $view)
463: {
464: $listing = $view->getListingConfig();
465:
466: $this->parseListLabel($listing);
467: }
468:
469: 470: 471: 472: 473: 474: 475:
476: protected function parseListLabel(ListingConfigInterface $listing)
477: {
478: if (($formats = $this->getFromDca('dca_config/child_list')) === null)
479: {
480: return;
481: }
482:
483: foreach ($formats as $providerName => $format)
484: {
485: $formatter = new DefaultModelFormatterConfig();
486: $configured = false;
487:
488: if (isset($format['fields']))
489: {
490: $formatter->setPropertyNames($format['fields']);
491: $configured = true;
492: }
493:
494: if (isset($format['format']))
495: {
496: $formatter->setFormat($format['format']);
497: $configured = true;
498: }
499:
500: if (isset($format['maxCharacters']))
501: {
502: $formatter->setMaxLength($format['maxCharacters']);
503: $configured = true;
504: }
505:
506: if ($configured)
507: {
508: $listing->setLabelFormatter($providerName, $formatter);
509: }
510: }
511: }
512: }
513: