1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13: namespace DcGeneral\Contao\View\Contao2BackendView;
14:
15: use ContaoCommunityAlliance\Contao\Bindings\ContaoEvents;
16: use ContaoCommunityAlliance\Contao\Bindings\Events\Backend\AddToUrlEvent;
17: use ContaoCommunityAlliance\Contao\Bindings\Events\Controller\LoadDataContainerEvent;
18: use ContaoCommunityAlliance\Contao\Bindings\Events\Controller\RedirectEvent;
19: use ContaoCommunityAlliance\Contao\Bindings\Events\Image\GenerateHtmlEvent;
20: use ContaoCommunityAlliance\Contao\Bindings\Events\System\LoadLanguageFileEvent;
21: use ContaoCommunityAlliance\Contao\Bindings\Events\System\LogEvent;
22: use DcGeneral\Contao\BackendBindings;
23: use DcGeneral\Data\CollectionInterface;
24: use DcGeneral\Data\DCGE;
25: use DcGeneral\Contao\View\Contao2BackendView\Event\GetParentHeaderEvent;
26: use DcGeneral\Contao\View\Contao2BackendView\Event\ParentViewChildRecordEvent;
27: use DcGeneral\Data\ModelInterface;
28: use DcGeneral\DataDefinition\Definition\View\ListingConfigInterface;
29: use DcGeneral\Exception\DcGeneralRuntimeException;
30:
31: 32: 33: 34: 35: 36: 37:
38: class ParentView extends BaseView
39: {
40: 41: 42: 43: 44: 45: 46:
47: public function loadCollection()
48: {
49: $environment = $this->getEnvironment();
50:
51: $objCurrentDataProvider = $environment->getDataProvider();
52:
53: $objChildConfig = $environment->getController()->getBaseConfig();
54:
55: if (!$objChildConfig->getSorting())
56: {
57: $objChildConfig->setSorting($this->getViewSection()->getListingConfig()->getDefaultSortingFields());
58: }
59:
60: $this->getPanel()->initialize($objChildConfig);
61:
62: $objChildCollection = $objCurrentDataProvider->fetchAll($objChildConfig);
63:
64: return $objChildCollection;
65: }
66:
67: 68: 69: 70: 71: 72: 73: 74:
75: protected function loadParentModel()
76: {
77: $environment = $this->getEnvironment();
78:
79: if (!($parentId = $environment->getInputProvider()->getParameter('pid')))
80: {
81: throw new DcGeneralRuntimeException(
82: 'ParentView needs a proper parent id defined, somehow none is defined?',
83: 1
84: );
85: }
86:
87: if (!($objParentProvider =
88: $environment->getDataProvider(
89: $environment->getDataDefinition()->getBasicDefinition()->getParentDataProvider()
90: )
91: ))
92: {
93: throw new DcGeneralRuntimeException(
94: 'ParentView needs a proper parent data provider defined, somehow none is defined?',
95: 1
96: );
97: }
98:
99: $objParentItem = $objParentProvider->fetch($objParentProvider->getEmptyConfig()->setId($parentId));
100:
101: if (!$objParentItem)
102: {
103:
104:
105:
106: $objParentItem = $objParentProvider->getEmptyModel();
107: $objParentItem->setID($parentId);
108: }
109:
110: return $objParentItem;
111: }
112:
113: 114: 115: 116: 117: 118: 119: 120: 121: 122:
123: protected function renderEntries($collection, $groupingInformation)
124: {
125: $environment = $this->getEnvironment();
126: $definition = $environment->getDataDefinition();
127: $view = $this->getViewSection();
128: $listing = $view->getListingConfig();
129: $remoteCur = null;
130: $groupClass = 'tl_folder_tlist';
131: $eoCount = -1;
132:
133: $objConfig = $environment->getDataProvider()->getEmptyConfig();
134: $this->getPanel()->initialize($objConfig);
135:
136:
137: $i = 0;
138: foreach ($collection as $model)
139: {
140:
141: $i++;
142:
143:
144: if ($groupingInformation)
145: {
146: $remoteNew = $this->formatCurrentValue(
147: $groupingInformation['property'],
148: $model,
149: $groupingInformation['mode'],
150: $groupingInformation['length']
151: );
152:
153:
154: if (!$listing->getShowColumns()
155: && ($groupingInformation['mode'] !== ListingConfigInterface::GROUP_NONE)
156: && (($remoteNew != $remoteCur) || ($remoteCur === null))
157: )
158: {
159: $eoCount = -1;
160:
161: $model->setMeta(DCGE::MODEL_GROUP_VALUE, array(
162: 'class' => $groupClass,
163: 'value' => $remoteNew
164: ));
165:
166: $groupClass = 'tl_folder_list';
167: $remoteCur = $remoteNew;
168: }
169: }
170:
171: if ($listing->getItemCssClass())
172: {
173: $model->setMeta(DCGE::MODEL_CLASS, $listing->getItemCssClass());
174: }
175:
176:
177: if (!$this->isSelectModeActive())
178: {
179: $previous = ((!is_null($collection->get($i - 1))) ? $collection->get($i - 1) : null);
180: $next = ((!is_null($collection->get($i + 1))) ? $collection->get($i + 1) : null);
181:
182: $buttons = $this->generateButtons($model, $previous, $next);
183:
184: $model->setMeta(DCGE::MODEL_BUTTONS, $buttons);
185: }
186:
187: $event = new ParentViewChildRecordEvent($this->getEnvironment(), $model);
188:
189: $this->getEnvironment()->getEventPropagator()->propagate(
190: $event::NAME,
191: $event,
192: array(
193: $this->getEnvironment()->getDataDefinition()->getName(),
194: $model->getId()
195: )
196: );
197:
198: $model->setMeta(DCGE::MODEL_EVEN_ODD_CLASS, (((++$eoCount) % 2 == 0) ? 'even' : 'odd'));
199:
200: if ($event->getHtml() !== null)
201: {
202: $information = array(
203: array(
204: 'colspan' => 1,
205: 'class' => 'tl_file_list col_1',
206: 'content' => $event->getHtml()
207: )
208: );
209: $model->setMeta(DCGE::MODEL_LABEL_VALUE, $information);
210: }
211: else
212: {
213: $model->setMeta(DCGE::MODEL_LABEL_VALUE, $this->formatModel($model));
214: }
215: }
216: }
217:
218: 219: 220: 221: 222: 223: 224:
225: protected function ($parentModel)
226: {
227: $environment = $this->getEnvironment();
228: $definition = $environment->getDataDefinition();
229: $viewDefinition = $this->getViewSection();
230: $listingDefinition = $viewDefinition->getListingConfig();
231: $headerFields = $listingDefinition->getHeaderPropertyNames();
232: $parentDefinition = $environment->getParentDataDefinition();
233: $parentName = $definition->getBasicDefinition()->getParentDataProvider();
234: $add = array();
235:
236: foreach ($headerFields as $v)
237: {
238: $value = deserialize($parentModel->getProperty($v));
239:
240: if ($v == 'tstamp')
241: {
242: $value = date($GLOBALS['TL_CONFIG']['datimFormat'], $value);
243: }
244:
245: $property = $parentDefinition->getPropertiesDefinition()->getProperty($v);
246:
247:
248: if ($property && (($v != 'tstamp')))
249: {
250: $evaluation = $property->getExtra();
251:
252:
253: $options = $property->getOptions();
254:
255: if (is_array($value))
256: {
257: $value = implode(', ', $value);
258: }
259: elseif ($property->getWidgetType() == 'checkbox' && !$evaluation['multiple'])
260: {
261: $value = strlen($value) ? $this->translate('yes', 'MSC') : $this->translate('no', 'MSC');
262: }
263: elseif ($value && $evaluation['rgxp'] == 'date')
264: {
265: $value = BackendBindings::parseDate($GLOBALS['TL_CONFIG']['dateFormat'], $value);
266: }
267: elseif ($value && $evaluation['rgxp'] == 'time')
268: {
269: $value = BackendBindings::parseDate($GLOBALS['TL_CONFIG']['timeFormat'], $value);
270: }
271: elseif ($value && $evaluation['rgxp'] == 'datim')
272: {
273: $value = BackendBindings::parseDate($GLOBALS['TL_CONFIG']['datimFormat'], $value);
274: }
275: elseif (is_array($reference[$value]))
276: {
277: $value = $reference[$value][0];
278: }
279: elseif (isset($reference[$value]))
280: {
281: $value = $reference[$value];
282: }
283: elseif ($evaluation['isAssociative'] || array_is_assoc($options))
284: {
285: $value = $options[$value];
286: }
287: }
288:
289:
290: if ($value != '')
291: {
292: $lang = $this->translate(sprintf('%s.0', $v), $parentName);
293: $key = $lang ? $lang : $v;
294:
295: $add[$key] = $value;
296: }
297: }
298:
299: $event = new GetParentHeaderEvent($environment);
300: $event->setAdditional($add);
301:
302: $this->getEnvironment()->getEventPropagator()->propagate(
303: $event::NAME,
304: $event,
305: $this->getEnvironment()->getDataDefinition()->getName()
306: );
307:
308: if (!$event->getAdditional() !== null)
309: {
310: $add = $event->getAdditional();
311: }
312:
313:
314: $arrHeader = array();
315: foreach ($add as $k => $v)
316: {
317: if (is_array($v))
318: {
319: $v = $v[0];
320: }
321:
322: $arrHeader[$k] = $v;
323: }
324:
325: return $arrHeader;
326: }
327:
328: 329: 330: 331: 332: 333: 334:
335: protected function ($parentModel)
336: {
337: $environment = $this->getEnvironment();
338: $definition = $environment->getDataDefinition();
339: $clipboard = $environment->getClipboard();
340: $basicDefinition = $definition->getBasicDefinition();
341: $parentDefinition = $environment->getParentDataDefinition();
342: $parentName = $basicDefinition->getParentDataProvider();
343:
344: $headerButtons = array();
345: if ($this->isSelectModeActive())
346: {
347: $headerButtons['selectAll'] = sprintf(
348: '<label for="tl_select_trigger" class="tl_select_label">%s</label>
349: <input type="checkbox"
350: id="tl_select_trigger"
351: onclick="Backend.toggleCheckboxes(this)"
352: class="tl_tree_checkbox" />',
353: $this->translate('selectAll', 'MSC')
354: );
355: }
356: else
357: {
358: $propagator = $environment->getEventPropagator();
359:
360: $objConfig = $this->getEnvironment()->getController()->getBaseConfig();
361: $this->getPanel()->initialize($objConfig);
362: $sorting = $objConfig->getSorting();
363:
364: if ($sorting
365: && !$basicDefinition->isClosed()
366: && $basicDefinition->isCreatable())
367: {
368:
369: $urlEvent = $propagator->propagate(
370: ContaoEvents::BACKEND_ADD_TO_URL,
371: new AddToUrlEvent(
372: 'act=paste&mode=create&pid=' . $parentModel->getID()
373: )
374: );
375:
376:
377: $imageEvent = $propagator->propagate(
378: ContaoEvents::IMAGE_GET_HTML,
379: new GenerateHtmlEvent(
380: 'new.gif',
381: $this->translate('pastenew.0', $definition->getName())
382: )
383: );
384:
385: $headerButtons['pasteNew'] = sprintf(
386: '<a href="%s" title="%s" onclick="Backend.getScrollOffset()">%s</a>',
387: $urlEvent->getUrl(),
388: specialchars($this->translate('pastenew.1', $definition->getName())),
389: $imageEvent->getHtml()
390: );
391: }
392:
393: if ($parentDefinition && $parentDefinition->getBasicDefinition()->isEditable())
394: {
395:
396: $imageEvent = $propagator->propagate(
397: ContaoEvents::IMAGE_GET_HTML,
398: new GenerateHtmlEvent(
399: 'edit.gif',
400: $this->translate('editheader.0', $definition->getName())
401: )
402: );
403:
404: $headerButtons['editHeader'] = sprintf(
405: '<a href="%s" title="%s" onclick="Backend.getScrollOffset()">%s</a>',
406: sprintf(
407: 'contao/main.php?do=%s&act=edit&table=%s&id=%s',
408: $environment->getInputProvider()->getParameter('do'),
409: $parentName,
410: $parentModel->getID()
411: ),
412: specialchars($this->translate('editheader.1', $definition->getName())),
413: $imageEvent->getHtml()
414: );
415: }
416:
417: if ($sorting && $clipboard->isNotEmpty())
418: {
419:
420: $urlEvent = $propagator->propagate(
421: ContaoEvents::BACKEND_ADD_TO_URL,
422: new AddToUrlEvent('act=' . $clipboard->getMode() . '&mode=2&pid=' . $parentModel->getID())
423: );
424:
425:
426: $imageEvent = $propagator->propagate(
427: ContaoEvents::IMAGE_GET_HTML,
428: new GenerateHtmlEvent(
429: 'pasteafter.gif',
430: $this->translate('pasteafter.0', $definition->getName()),
431: 'class="blink"'
432: )
433: );
434:
435: $headerButtons['pasteAfter'] = sprintf(
436: '<a href="%s" title="%s" onclick="Backend.getScrollOffset()">%s</a>',
437: $urlEvent->getUrl(),
438: specialchars($this->translate('pasteafter.1', $definition->getName())),
439: $imageEvent->getHtml()
440: );
441: }
442: }
443:
444: return implode(' ', $headerButtons);
445: }
446:
447:
448: 449: 450: 451: 452: 453: 454: 455: 456:
457: protected function viewParent($collection, $parentModel)
458: {
459: $definition = $this->getEnvironment()->getDataDefinition();
460: $parentProvider = $definition->getBasicDefinition()->getParentDataProvider();
461: $groupingInformation = $this->getGroupingMode();
462: $propagator = $this->getEnvironment()->getEventPropagator();
463:
464:
465:
466: if (!$parentModel)
467: {
468: $propagator->propagate(
469: ContaoEvents::SYSTEM_LOG,
470: new LogEvent(
471: sprintf(
472: 'The view for %s has either a empty parent data provider or collection.',
473: $parentProvider
474: ),
475: __CLASS__ . '::' . __FUNCTION__ . '()',
476: TL_ERROR
477: )
478: );
479:
480: $propagator->propagate(
481: ContaoEvents::CONTROLLER_REDIRECT,
482: new RedirectEvent('contao/main.php?act=error')
483: );
484: }
485:
486:
487: if ($groupingInformation['mode'] != ListingConfigInterface::GROUP_NONE)
488: {
489: $objTemplate = $this->getTemplate('dcbe_general_grouping');
490: }
491: else
492: {
493: $objTemplate = $this->getTemplate('dcbe_general_parentView');
494: }
495:
496: $this
497: ->addToTemplate('tableName', strlen($definition->getName())? $definition->getName() : 'none', $objTemplate)
498: ->addToTemplate('collection', $collection, $objTemplate)
499: ->addToTemplate('select', $this->isSelectModeActive(), $objTemplate)
500: ->addToTemplate('action', ampersand(\Environment::getInstance()->request, true), $objTemplate)
501: ->addToTemplate('header', $this->renderFormattedHeaderFields($parentModel), $objTemplate)
502: ->addToTemplate('hasSorting', ($groupingInformation['property'] == 'sorting'), $objTemplate)
503: ->addToTemplate('mode', ($groupingInformation ? $groupingInformation['mode'] : null), $objTemplate)
504: ->addToTemplate('pdp', (string)$parentProvider, $objTemplate)
505: ->addToTemplate('cdp', $definition->getName(), $objTemplate)
506: ->addToTemplate('selectButtons', $this->getSelectButtons(), $objTemplate)
507: ->addToTemplate('headerButtons', $this->getHeaderButtons($parentModel), $objTemplate);
508:
509: $this->renderEntries($collection, $groupingInformation);
510:
511:
512: $strBreadcrumb = $this->breadcrumb();
513: if ($strBreadcrumb != null)
514: {
515: $this->addToTemplate('breadcrumb', $strBreadcrumb, $objTemplate);
516: }
517:
518: return $objTemplate->parse();
519: }
520:
521: 522: 523:
524: public function enforceModelRelationship($model)
525: {
526: $definition = $this->getEnvironment()->getDataDefinition();
527: $basic = $definition->getBasicDefinition();
528: $parent = $this->loadParentModel();
529:
530: $condition = $definition
531: ->getModelRelationshipDefinition()
532: ->getChildCondition(
533: $basic->getParentDataProvider(),
534: $basic->getDataProvider()
535: );
536:
537: if ($condition)
538: {
539: $condition->applyTo($parent, $model);
540: }
541: }
542:
543: 544: 545: 546: 547:
548: public function showAll()
549: {
550: $this->checkClipboard();
551: $collection = $this->loadCollection();
552: $parentModel = $this->loadParentModel();
553:
554: $arrReturn = array();
555: $arrReturn['panel'] = $this->panel();
556: $arrReturn['buttons'] = $this->generateHeaderButtons('tl_buttons_a');
557: $arrReturn['body'] = $this->viewParent($collection, $parentModel);
558:
559: return implode("\n", $arrReturn);
560: }
561: }
562: