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\RedirectEvent;
18: use ContaoCommunityAlliance\Contao\Bindings\Events\Controller\ReloadEvent;
19: use ContaoCommunityAlliance\Contao\Bindings\Events\Image\GenerateHtmlEvent;
20: use ContaoCommunityAlliance\Contao\Bindings\Events\Image\ResizeImageEvent;
21: use ContaoCommunityAlliance\Contao\Bindings\Events\System\GetReferrerEvent;
22: use ContaoCommunityAlliance\Contao\Bindings\Events\System\LogEvent;
23: use DcGeneral\Contao\View\Contao2BackendView\Event\EditModelBeforeSaveEvent;
24: use DcGeneral\Contao\View\Contao2BackendView\Event\ModelToLabelEvent;
25: use DcGeneral\Data\ModelInterface;
26: use DcGeneral\Data\MultiLanguageDataProviderInterface;
27: use DcGeneral\Data\DCGE;
28: use DcGeneral\Data\PropertyValueBag;
29: use DcGeneral\Contao\DataDefinition\Definition\Contao2BackendViewDefinitionInterface;
30: use DcGeneral\DataDefinition\Definition\BasicDefinitionInterface;
31: use DcGeneral\DataDefinition\Definition\Properties\PropertyInterface;
32: use DcGeneral\DataDefinition\Definition\View\Command;
33: use DcGeneral\DataDefinition\Definition\View\CommandInterface;
34: use DcGeneral\DataDefinition\Definition\View\CutCommandInterface;
35: use DcGeneral\DataDefinition\Definition\View\ListingConfigInterface;
36: use DcGeneral\EnvironmentInterface;
37: use DcGeneral\Event\PostCreateModelEvent;
38: use DcGeneral\Event\PostDeleteModelEvent;
39: use DcGeneral\Event\PostPersistModelEvent;
40: use DcGeneral\Event\PreCreateModelEvent;
41: use DcGeneral\Event\PreDeleteModelEvent;
42: use DcGeneral\Event\PrePersistModelEvent;
43: use DcGeneral\Exception\DcGeneralInvalidArgumentException;
44: use DcGeneral\Exception\DcGeneralRuntimeException;
45: use DcGeneral\Panel\FilterElementInterface;
46: use DcGeneral\Panel\LimitElementInterface;
47: use DcGeneral\Panel\PanelContainerInterface;
48: use DcGeneral\Panel\SearchElementInterface;
49: use DcGeneral\Panel\SortElementInterface;
50: use DcGeneral\Panel\SubmitElementInterface;
51: use DcGeneral\View\Event\RenderReadablePropertyValueEvent;
52: use DcGeneral\Contao\View\Contao2BackendView\Event\GetBreadcrumbEvent;
53: use DcGeneral\Contao\View\Contao2BackendView\Event\GetEditModeButtonsEvent;
54: use DcGeneral\Contao\View\Contao2BackendView\Event\GetGlobalButtonEvent;
55: use DcGeneral\Contao\View\Contao2BackendView\Event\GetGlobalButtonsEvent;
56: use DcGeneral\Contao\View\Contao2BackendView\Event\GetGroupHeaderEvent;
57: use DcGeneral\Contao\View\Contao2BackendView\Event\GetOperationButtonEvent;
58: use DcGeneral\Contao\View\Contao2BackendView\Event\GetPasteButtonEvent;
59: use DcGeneral\Contao\View\Contao2BackendView\Event\GetSelectModeButtonsEvent;
60: use DcGeneral\Contao\BackendBindings;
61:
62: 63: 64: 65: 66: 67: 68:
69: class BaseView implements BackendViewInterface
70: {
71: 72: 73: 74: 75:
76: protected $notImplMsg =
77: '<div style="text-align:center; font-weight:bold; padding:40px;">
78: The function/view "%s" is not implemented.
79: </div>';
80:
81: 82: 83: 84: 85:
86: protected $environment;
87:
88: 89: 90: 91: 92:
93: protected $panel;
94:
95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115:
116: protected function dispatchEvent($eventName, $event)
117: {
118: $this->getEnvironment()->getEventPropagator()->propagate(
119: $event::NAME,
120: $event,
121: array($this->getEnvironment()->getDataDefinition()->getName())
122: );
123: }
124:
125: 126: 127:
128: public function setEnvironment(EnvironmentInterface $environment)
129: {
130: $this->environment = $environment;
131: }
132:
133: 134: 135:
136: public function getEnvironment()
137: {
138: return $this->environment;
139: }
140:
141: 142: 143: 144: 145:
146: protected function getDataDefinition()
147: {
148: return $this->getEnvironment()->getDataDefinition();
149: }
150:
151: 152: 153: 154: 155: 156: 157: 158: 159:
160: protected function translate($path, $section = null)
161: {
162: return $this->getEnvironment()->getTranslator()->translate($path, $section);
163: }
164:
165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175:
176: protected function addToTemplate($name, $value, $template)
177: {
178: $template->$name = $value;
179:
180: return $this;
181: }
182:
183: 184: 185:
186: public function setPanel($panelContainer)
187: {
188: $this->panel = $panelContainer;
189:
190: return $this;
191: }
192:
193: 194: 195:
196: public function getPanel()
197: {
198: return $this->panel;
199: }
200:
201: 202: 203: 204: 205:
206: protected function getViewSection()
207: {
208: return $this->getDataDefinition()->getDefinition(Contao2BackendViewDefinitionInterface::NAME);
209: }
210:
211: 212: 213: 214: 215:
216: protected function redirectHome()
217: {
218: $environment = $this->getEnvironment();
219: $input = $environment->getInputProvider();
220:
221: if ($input->hasParameter('table') && $input->hasParameter('pid'))
222: {
223: if ($input->hasParameter('pid'))
224: {
225: $event = new RedirectEvent(sprintf(
226: 'contao/main.php?do=%s&table=%s&pid=%s',
227: $input->getParameter('do'),
228: $input->getParameter('table'),
229: $input->getParameter('pid')
230: ));
231: }
232: else
233: {
234: $event = new RedirectEvent(sprintf(
235: 'contao/main.php?do=%s&table=%s',
236: $input->getParameter('do'),
237: $input->getParameter('table')
238: ));
239: }
240: }
241: else
242: {
243: $event = new RedirectEvent(sprintf(
244: 'contao/main.php?do=%s',
245: $input->getParameter('do')
246: ));
247: }
248:
249: $environment->getEventPropagator()->propagate(ContaoEvents::CONTROLLER_REDIRECT, $event);
250: }
251:
252: 253: 254: 255: 256:
257: protected function ()
258: {
259: return \Input::getInstance()->get('popup');
260: }
261:
262: 263: 264: 265: 266:
267: protected function isSelectModeActive()
268: {
269: return \Input::getInstance()->get('act') == 'select';
270: }
271:
272: 273: 274: 275: 276: 277: 278:
279: protected function getGroupingMode()
280: {
281:
282: $viewDefinition = $this->getViewSection();
283: $listingConfig = $viewDefinition->getListingConfig();
284:
285: if ($listingConfig->getSortingMode() === ListingConfigInterface::SORT_RANDOM)
286: {
287: return null;
288: }
289:
290: $definition = $this->getEnvironment()->getDataDefinition();
291: $properties = $definition->getPropertiesDefinition();
292: $sortingFields = array_keys((array)$listingConfig->getDefaultSortingFields());
293: $firstSorting = reset($sortingFields);
294:
295: $panel = $this->getPanel()->getPanel('sorting');
296: if ($panel)
297: {
298:
299: $firstSorting = $panel->getSelected();
300: }
301:
302:
303: if (!$firstSorting)
304: {
305: return null;
306: }
307:
308: $property = $properties->getProperty($firstSorting);
309:
310: if (count($sortingFields) == 0)
311: {
312: $groupMode = ListingConfigInterface::GROUP_NONE;
313: $groupLength = 0;
314: }
315:
316: elseif ($property->getGroupingMode() != '')
317: {
318: $groupMode = $property->getGroupingMode();
319: $groupLength = $property->getGroupingLength();
320: }
321:
322: else
323: {
324: $groupMode = $listingConfig->getGroupingMode();
325: $groupLength = $listingConfig->getGroupingLength();
326: }
327:
328: return array
329: (
330: 'mode' => $groupMode,
331: 'length' => $groupLength,
332: 'property' => $firstSorting
333: );
334: }
335:
336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349:
350: public function formatCurrentValue($field, $model, $groupMode, $groupLength)
351: {
352: $value = $model->getProperty($field);
353: $property = $this->getDataDefinition()->getPropertiesDefinition()->getProperty($field);
354:
355:
356: if (!$property)
357: {
358: return '-';
359: }
360:
361: $evaluation = $property->getExtra();
362: $remoteNew = '';
363:
364: if ($property->getWidgetType() == 'checkbox' && !$evaluation['multiple'])
365: {
366: $remoteNew = ($value != '') ? ucfirst($this->translate('MSC.yes')) : ucfirst($this->translate('MSC.no'));
367: }
368:
369: elseif (false && $property->getForeignKey())
370: {
371:
372: if ($objParentModel->hasProperties())
373: {
374: $remoteNew = $objParentModel->getProperty('value');
375: }
376:
377: }
378: elseif ($groupMode != ListingConfigInterface::GROUP_NONE)
379: {
380: switch ($groupMode)
381: {
382: case ListingConfigInterface::GROUP_CHAR:
383: $remoteNew = ($value != '') ? ucfirst(utf8_substr($value, 0, $groupLength)) : '-';
384: break;
385:
386: case ListingConfigInterface::GROUP_DAY:
387: $remoteNew = ($value != '') ? BackendBindings::parseDate($GLOBALS['TL_CONFIG']['dateFormat'], $value) : '-';
388: break;
389:
390: case ListingConfigInterface::GROUP_MONTH:
391: $remoteNew = ($value != '') ? date('Y-m', $value) : '-';
392: $intMonth = ($value != '') ? (date('m', $value) - 1) : '-';
393:
394: if ($month = $this->translate('MONTHS' . $intMonth))
395: {
396: $remoteNew = ($value != '') ? $month . ' ' . date('Y', $value) : '-';
397: }
398: break;
399:
400: case ListingConfigInterface::GROUP_YEAR:
401: $remoteNew = ($value != '') ? date('Y', $value) : '-';
402: break;
403:
404: default:
405: }
406: }
407: else
408: {
409: if ($property->getWidgetType() == 'checkbox' && !$evaluation['multiple'])
410: {
411: $remoteNew = ($value != '') ? $field : '';
412: }
413:
414: elseif (false && is_array($property->get('reference')))
415: {
416: $reference = $property->get('reference');
417: $remoteNew = $reference[$value];
418: }
419: elseif (array_is_assoc($property->getOptions()))
420: {
421: $options = $property->getOptions();
422: $remoteNew = $options[$value];
423: }
424: else
425: {
426: $remoteNew = $value;
427: }
428:
429: if (is_array($remoteNew))
430: {
431: $remoteNew = $remoteNew[0];
432: }
433:
434: if (empty($remoteNew))
435: {
436: $remoteNew = '-';
437: }
438: }
439:
440: $event = new GetGroupHeaderEvent($this->getEnvironment(), $model, $field, $remoteNew, $groupMode);
441:
442: $this->getEnvironment()->getEventPropagator()->propagate(
443: $event::NAME,
444: $event,
445: array($this->getEnvironment()->getDataDefinition()->getName())
446: );
447:
448: $remoteNew = $event->getValue();
449:
450: return $remoteNew;
451: }
452:
453: 454: 455: 456: 457: 458: 459: 460: 461: 462: 463: 464:
465: protected function getButtonLabel($strButton)
466: {
467: $definition = $this->getEnvironment()->getDataDefinition();
468: if (($label = $this->translate($strButton, $definition->getName())) !== $strButton)
469: {
470: return $label;
471: }
472: elseif (($label = $this->translate('MSC.' . $strButton)) !== $strButton)
473: {
474: return $label;
475: }
476:
477:
478: return $strButton;
479: }
480:
481: 482: 483: 484: 485:
486: protected function getEditButtons()
487: {
488: $buttons = array();
489: $definition = $this->getEnvironment()->getDataDefinition();
490: $basicDefinition = $definition->getBasicDefinition();
491:
492: $buttons['save'] = sprintf(
493: '<input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="%s" />',
494: $this->getButtonLabel('save')
495: );
496:
497: $buttons['saveNclose'] = sprintf(
498: '<input type="submit" name="saveNclose" id="saveNclose" class="tl_submit" accesskey="c" value="%s" />',
499: $this->getButtonLabel('saveNclose')
500: );
501:
502: if (!($this->isPopup() || $basicDefinition->isClosed()) && $basicDefinition->isCreatable())
503: {
504: $buttons['saveNcreate'] = sprintf(
505: '<input type="submit" name="saveNcreate" id="saveNcreate" class="tl_submit" accesskey="n" value="%s" />',
506: $this->getButtonLabel('saveNcreate')
507: );
508: }
509:
510:
511: if (\Input::get('s2e'))
512: {
513: $buttons['saveNedit'] = sprintf(
514: '<input type="submit" name="saveNedit" id="saveNedit" class="tl_submit" accesskey="e" value="%s" />',
515: $this->getButtonLabel('saveNedit')
516: );
517: }
518: elseif(!$this->isPopup()
519: && (($basicDefinition->getMode() == BasicDefinitionInterface::MODE_PARENTEDLIST)
520: || strlen($basicDefinition->getParentDataProvider())
521: || $basicDefinition->isSwitchToEditEnabled()
522: )
523: )
524: {
525: $buttons['saveNback'] = sprintf(
526: '<input type="submit" name="saveNback" id="saveNback" class="tl_submit" accesskey="g" value="%s" />',
527: $this->getButtonLabel('saveNback')
528: );
529: }
530:
531: $event = new GetEditModeButtonsEvent($this->getEnvironment());
532: $event->setButtons($buttons);
533:
534: $this->getEnvironment()->getEventPropagator()->propagate(
535: $event::NAME,
536: $event,
537: array($definition->getName())
538: );
539:
540: return $event->getButtons();
541: }
542:
543: 544: 545: 546: 547:
548: protected function getSelectButtons()
549: {
550: $definition = $this->getDataDefinition();
551: $basicDefinition = $definition->getBasicDefinition();
552: $buttons = array();
553:
554: if ($basicDefinition->isDeletable())
555: {
556: $buttons['delete'] = sprintf(
557: '<input
558: type="submit"
559: name="delete"
560: id="delete"
561: class="tl_submit"
562: accesskey="d"
563: onclick="return confirm(\'%s\')"
564: value="%s" />',
565: $GLOBALS['TL_LANG']['MSC']['delAllConfirm'],
566: specialchars($this->translate('MSC.deleteSelected'))
567: );
568: }
569:
570: if ($basicDefinition->isEditable())
571: {
572: $buttons['cut'] = sprintf(
573: '<input type="submit" name="cut" id="cut" class="tl_submit" accesskey="x" value="%s">',
574: specialchars($this->translate('MSC.moveSelected'))
575: );
576: }
577:
578: if ($basicDefinition->isCreatable())
579: {
580: $buttons['copy'] = sprintf(
581: '<input type="submit" name="copy" id="copy" class="tl_submit" accesskey="c" value="%s">',
582: specialchars($this->translate('MSC.copySelected'))
583: );
584: }
585:
586: if ($basicDefinition->isEditable())
587: {
588: $buttons['override'] = sprintf(
589: '<input type="submit" name="override" id="override" class="tl_submit" accesskey="v" value="%s">',
590: specialchars($this->translate('MSC.overrideSelected'))
591: );
592:
593: $buttons['edit'] = sprintf(
594: '<input type="submit" name="edit" id="edit" class="tl_submit" accesskey="s" value="%s">',
595: specialchars($this->translate('MSC.editSelected'))
596: );
597: }
598:
599: $event = new GetSelectModeButtonsEvent($this->getEnvironment());
600: $event->setButtons($buttons);
601:
602: $this->getEnvironment()->getEventPropagator()->propagate(
603: $event::NAME,
604: $event,
605: array($this->getEnvironment()->getDataDefinition()->getName())
606: );
607:
608: return $event->getButtons();
609: }
610:
611: 612: 613: 614: 615: 616: 617: 618: 619: 620: 621: 622:
623: public function checkClipboard()
624: {
625: $objInput = $this->getEnvironment()->getInputProvider();
626: $objClipboard = $this->getEnvironment()->getClipboard();
627:
628:
629: if ($objInput->getParameter('clipboard') == '1')
630: {
631: $objClipboard->clear();
632: }
633:
634: elseif ($objInput->getParameter('act') == 'paste')
635: {
636: $objDataProv = $this->getEnvironment()->getDataProvider();
637: $id = $objInput->getParameter('id');
638:
639: if ($objInput->getParameter('mode') == 'cut')
640: {
641: $arrIgnored = array($id);
642:
643: $objModel = $objDataProv->fetch($objDataProv->getEmptyConfig()->setId($id));
644:
645:
646: if ($this->getDataDefinition()->getBasicDefinition()->getMode() == BasicDefinitionInterface::MODE_HIERARCHICAL)
647: {
648: $arrIgnored = $this->getEnvironment()->getController()->assembleAllChildrenFrom($objModel);
649: }
650:
651: $objClipboard
652: ->clear()
653: ->cut($id)
654: ->setCircularIds($arrIgnored);
655: }
656: elseif ($objInput->getParameter('mode') == 'create')
657: {
658: $arrIgnored = array($id);
659: $objContainedId = trimsplit(',', $objInput->getParameter('childs'));
660:
661: $objClipboard
662: ->clear()
663: ->create($id)
664: ->setCircularIds($arrIgnored);
665:
666: if (is_array($objContainedId) && !empty($objContainedId))
667: {
668: $objClipboard->setContainedIds($objContainedId);
669: }
670: }
671: }
672:
673: else
674: {
675: $objClipboard->loadFrom($this->getEnvironment());
676: }
677:
678:
679: $objClipboard->saveTo($this->getEnvironment());
680:
681: return $this;
682: }
683:
684: 685: 686: 687: 688: 689: 690:
691: protected function isMultiLanguage($mixId)
692: {
693: return count($this->getEnvironment()->getController()->getSupportedLanguages($mixId)) > 0;
694: }
695:
696: 697: 698: 699: 700:
701: protected function checkLanguage()
702: {
703: $environment = $this->getEnvironment();
704: $inputProvider = $environment->getInputProvider();
705: $objDataProvider = $environment->getDataProvider();
706: $strProviderName = $environment->getDataDefinition()->getName();
707: $mixID = $environment->getInputProvider()->getParameter('id');
708: $arrLanguage = $environment->getController()->getSupportedLanguages($mixID);
709:
710: if (!$arrLanguage)
711: {
712: return;
713: }
714:
715:
716: $arrSession = $inputProvider->getPersistentValue('dc_general');
717: if (!is_array($arrSession))
718: {
719: $arrSession = array();
720: }
721:
722:
723:
724: if (isset($arrSession['ml_support'][$strProviderName][$mixID]))
725: {
726: $strCurrentLanguage = $arrSession['ml_support'][$strProviderName][$mixID];
727: }
728: else
729: {
730: $strCurrentLanguage = $GLOBALS['TL_LANGUAGE'];
731: }
732:
733:
734: if ((strlen($inputProvider->getValue('language')) != 0)
735: && ($inputProvider->getValue('FORM_SUBMIT') == 'language_switch'))
736: {
737: if (array_key_exists($inputProvider->getValue('language'), $arrLanguage))
738: {
739: $strCurrentLanguage = $inputProvider->getValue('language');
740: }
741: }
742:
743: if (!array_key_exists($strCurrentLanguage, $arrLanguage))
744: {
745: $strCurrentLanguage = $objDataProvider->getFallbackLanguage($mixID)->getLanguageCode();
746: }
747:
748: $arrSession['ml_support'][$strProviderName][$mixID] = $strCurrentLanguage;
749: $inputProvider->setPersistentValue('dc_general', $arrSession);
750:
751: $objDataProvider->setCurrentLanguage($strCurrentLanguage);
752: }
753:
754: 755: 756: 757: 758: 759: 760:
761: protected function getTemplate($strTemplate)
762: {
763: return new ContaoBackendViewTemplate($strTemplate);
764: }
765:
766: 767: 768: 769: 770:
771: public function handleAjaxCall()
772: {
773: $action = $this->getEnvironment()->getInputProvider()->getValue('action');
774: return vsprintf($this->notImplMsg, 'handleAjaxCall()');
775: }
776:
777: 778: 779: 780:
781: public function copy()
782: {
783: return vsprintf($this->notImplMsg, 'copy - Mode');
784: }
785:
786: 787: 788: 789:
790: public function copyAll()
791: {
792: return vsprintf($this->notImplMsg, 'copyAll - Mode');
793: }
794:
795: 796: 797: 798: 799: 800: 801:
802: public function create()
803: {
804: $preFunction = function($environment, $model, $originalModel)
805: {
806: $copyEvent = new PreCreateModelEvent($environment, $model);
807: $environment->getEventPropagator()->propagate(
808: $copyEvent::NAME,
809: $copyEvent,
810: array(
811: $environment->getDataDefinition()->getName(),
812: )
813: );
814: };
815:
816: $postFunction = function($environment, $model, $originalModel)
817: {
818: $copyEvent = new PostCreateModelEvent($environment, $model);
819: $environment->getEventPropagator()->propagate(
820: $copyEvent::NAME,
821: $copyEvent,
822: array(
823: $environment->getDataDefinition()->getName(),
824: )
825: );
826: };
827:
828: return $this->createEditMask($this->createEmptyModelWithDefaults(), null, $preFunction, $postFunction);
829: }
830:
831: 832: 833: 834:
835: public function cut()
836: {
837: return vsprintf($this->notImplMsg, 'cut - Mode');
838: }
839:
840: public function paste()
841: {
842:
843: }
844:
845: 846: 847: 848:
849: public function cutAll()
850: {
851: return vsprintf($this->notImplMsg, 'cutAll - Mode');
852: }
853:
854: 855: 856: 857: 858: 859: 860: 861: 862:
863: public function delete()
864: {
865:
866: if (!$this->getEnvironment()->getDataDefinition()->getBasicDefinition()->isDeletable())
867: {
868: $this->getEnvironment()->getEventPropagator()->propagate(
869: ContaoEvents::SYSTEM_LOG,
870: new LogEvent(
871: sprintf(
872: 'Table "%s" is not deletable', 'DC_General - DefaultController - delete()',
873: $this->getEnvironment()->getDataDefinition()->getName()
874: ),
875: __CLASS__ . '::delete()',
876: TL_ERROR
877: )
878: );
879:
880: $this->getEnvironment()->getEventPropagator()->propagate(
881: ContaoEvents::CONTROLLER_REDIRECT,
882: new RedirectEvent('contao/main.php?act=error')
883: );
884: }
885:
886: $environment = $this->getEnvironment();
887: $dataProvider = $environment->getDataProvider();
888: $modelId = $environment->getInputProvider()->getParameter('id');
889: $model = $dataProvider->fetch($dataProvider->getEmptyConfig()->setId($modelId));
890:
891: if (!$model->getId())
892: {
893: throw new DcGeneralRuntimeException('Could not load model with id ' . $modelId);
894: }
895:
896:
897: $event = new PreDeleteModelEvent($environment, $model);
898: $environment->getEventPropagator()->propagate(
899: $event::NAME,
900: $event,
901: array(
902: $this->getEnvironment()->getDataDefinition()->getName(),
903: )
904: );
905:
906:
907: 908: 909: 910: 911: 912: 913: 914: 915: 916: 917: 918: 919: 920: 921: 922: 923: 924: 925: 926: 927: 928: 929: 930: 931: 932: 933: 934: 935: 936: 937: 938: 939:
940:
941: $dataProvider->delete($model);
942:
943:
944:
945: $event = new PostDeleteModelEvent($environment, $model);
946: $environment->getEventPropagator()->propagate(
947: $event::NAME,
948: $event,
949: array(
950: $this->getEnvironment()->getDataDefinition()->getName(),
951: )
952: );
953:
954: $this->redirectHome();
955: }
956:
957: 958: 959: 960:
961: public function move()
962: {
963: return vsprintf($this->notImplMsg, 'move - Mode');
964: }
965:
966: 967: 968: 969:
970: public function undo()
971: {
972: return vsprintf($this->notImplMsg, 'undo - Mode');
973: }
974:
975: 976: 977: 978: 979: 980: 981: 982: 983:
984: protected function handleSubmit(ModelInterface $model)
985: {
986: $environment = $this->getEnvironment();
987: $inputProvider = $environment->getInputProvider();
988:
989: if ($inputProvider->hasValue('save'))
990: {
991: if ($inputProvider->getParameter('id'))
992: {
993: $environment->getEventPropagator()->propagate(ContaoEvents::CONTROLLER_RELOAD, new ReloadEvent());
994: }
995: else
996: {
997: $newUrlEvent = new AddToUrlEvent('act=edit&id=' . $model->getId());
998: $environment->getEventPropagator()->propagate(ContaoEvents::BACKEND_ADD_TO_URL, $newUrlEvent);
999: $environment->getEventPropagator()->propagate(
1000: ContaoEvents::CONTROLLER_REDIRECT,
1001: new RedirectEvent($newUrlEvent->getUrl())
1002: );
1003: }
1004: }
1005: elseif ($inputProvider->hasValue('saveNclose'))
1006: {
1007: setcookie('BE_PAGE_OFFSET', 0, 0, '/');
1008:
1009: $_SESSION['TL_INFO'] = '';
1010: $_SESSION['TL_ERROR'] = '';
1011: $_SESSION['TL_CONFIRM'] = '';
1012:
1013: $newUrlEvent = new GetReferrerEvent();
1014: $environment->getEventPropagator()->propagate(ContaoEvents::SYSTEM_GET_REFERRER, $newUrlEvent);
1015: $environment->getEventPropagator()->propagate(
1016: ContaoEvents::CONTROLLER_REDIRECT,
1017: new RedirectEvent($newUrlEvent->getReferrerUrl())
1018: );
1019: }
1020: elseif ($inputProvider->hasValue('saveNcreate'))
1021: {
1022: setcookie('BE_PAGE_OFFSET', 0, 0, '/');
1023:
1024: $_SESSION['TL_INFO'] = '';
1025: $_SESSION['TL_ERROR'] = '';
1026: $_SESSION['TL_CONFIRM'] = '';
1027:
1028: $newUrlEvent = new AddToUrlEvent('act=create&id=');
1029: $environment->getEventPropagator()->propagate(ContaoEvents::BACKEND_ADD_TO_URL, $newUrlEvent);
1030: $environment->getEventPropagator()->propagate(
1031: ContaoEvents::CONTROLLER_REDIRECT,
1032: new RedirectEvent($newUrlEvent->getUrl())
1033: );
1034:
1035: }
1036: elseif ($inputProvider->hasValue('saveNback'))
1037: {
1038: echo vsprintf($this->notImplMsg, 'Save and go back');
1039: exit;
1040: }
1041: else
1042: {
1043:
1044:
1045: }
1046: }
1047:
1048: 1049: 1050: 1051: 1052: 1053: 1054: 1055: 1056: 1057:
1058: protected function checkRestoreVersion()
1059: {
1060: $environment = $this->getEnvironment();
1061: $definition = $environment->getDataDefinition();
1062: $basicDefinition = $definition->getBasicDefinition();
1063: $dataProviderDefinition = $definition->getDataProviderDefinition();
1064: $dataProvider = $environment->getDataProvider();
1065: $dataProviderInformation = $dataProviderDefinition->getInformation($basicDefinition->getDataProvider());
1066: $inputProvider = $environment->getInputProvider();
1067: $modelId = $inputProvider->getParameter('id');
1068:
1069: if ($dataProviderInformation->isVersioningEnabled()
1070: && ($inputProvider->getValue('FORM_SUBMIT') === 'tl_version')
1071: && ($modelVersion = $inputProvider->getValue('version')) !== null)
1072: {
1073: $model = $dataProvider->getVersion($modelId, $modelVersion);
1074:
1075: if ($model === null)
1076: {
1077: $message = sprintf(
1078: 'Could not load version %s of record ID %s from %s',
1079: $modelVersion,
1080: $modelId,
1081: $basicDefinition->getDataProvider()
1082: );
1083:
1084: $environment->getEventPropagator()->propagate(
1085: ContaoEvents::SYSTEM_LOG,
1086: new LogEvent($message, TL_ERROR, 'DC_General - checkRestoreVersion()')
1087: );
1088:
1089: throw new DcGeneralRuntimeException($message);
1090: }
1091:
1092: $dataProvider->save($model);
1093: $dataProvider->setVersionActive($modelId, $modelVersion);
1094: $environment->getEventPropagator()->propagate(ContaoEvents::CONTROLLER_RELOAD, new ReloadEvent());
1095: }
1096: }
1097:
1098: 1099: 1100: 1101: 1102: 1103: 1104: 1105: 1106:
1107: public function enforceModelRelationship($model)
1108: {
1109:
1110: }
1111:
1112: 1113: 1114: 1115: 1116:
1117: protected function createEmptyModelWithDefaults()
1118: {
1119: $environment = $this->getEnvironment();
1120: $definition = $environment->getDataDefinition();
1121: $environment = $this->getEnvironment();
1122: $dataProvider = $environment->getDataProvider();
1123: $propertyDefinition = $definition->getPropertiesDefinition();
1124: $properties = $propertyDefinition->getProperties();
1125: $model = $dataProvider->getEmptyModel();
1126:
1127: foreach ($properties as $property)
1128: {
1129: $propName = $property->getName();
1130: $model->setProperty($propName, $property->getDefaultValue());
1131: }
1132:
1133: return $model;
1134: }
1135:
1136: 1137: 1138: 1139: 1140: 1141: 1142:
1143: protected function storeVersion(ModelInterface $model)
1144: {
1145: $modelId = $model->getId();
1146: $environment = $this->getEnvironment();
1147: $definition = $environment->getDataDefinition();
1148: $basicDefinition = $definition->getBasicDefinition();
1149: $dataProvider = $environment->getDataProvider();
1150: $dataProviderDefinition = $definition->getDataProviderDefinition();
1151: $dataProviderInformation = $dataProviderDefinition->getInformation($basicDefinition->getDataProvider());
1152:
1153: if (!$dataProviderInformation->isVersioningEnabled())
1154: {
1155: return;
1156: }
1157:
1158:
1159: $currentVersion = $dataProvider->getActiveVersion($modelId);
1160: if (!$currentVersion
1161: || !$dataProvider->sameModels($model, $dataProvider->getVersion($modelId, $currentVersion))
1162: )
1163: {
1164: $user = \BackendUser::getInstance();
1165:
1166: $dataProvider->saveVersion($model, $user->username);
1167: }
1168: }
1169:
1170: 1171: 1172: 1173: 1174: 1175: 1176: 1177: 1178:
1179: public function edit()
1180: {
1181: $this->checkLanguage();
1182:
1183: $environment = $this->getEnvironment();
1184: $dataProvider = $environment->getDataProvider();
1185: $inputProvider = $environment->getInputProvider();
1186: $modelId = $inputProvider->getParameter('id');
1187:
1188: $this->checkRestoreVersion();
1189:
1190: if (strlen($modelId))
1191: {
1192: $model = $dataProvider->fetch($dataProvider->getEmptyConfig()->setId($modelId));
1193: }
1194: else
1195: {
1196: $model = $this->createEmptyModelWithDefaults();
1197: }
1198:
1199:
1200: $originalModel = clone $model;
1201: $originalModel->setId($model->getId());
1202:
1203: return $this->createEditMask($model, $originalModel, null, null);
1204: }
1205:
1206: 1207: 1208: 1209: 1210: 1211: 1212: 1213: 1214: 1215: 1216: 1217: 1218: 1219: 1220: 1221: 1222:
1223: protected function createEditMask($model, $originalModel, $preFunction, $postFunction)
1224: {
1225: $this->checkLanguage();
1226:
1227: $environment = $this->getEnvironment();
1228: $definition = $environment->getDataDefinition();
1229: $basicDefinition = $definition->getBasicDefinition();
1230: $dataProvider = $environment->getDataProvider();
1231: $dataProviderDefinition = $definition->getDataProviderDefinition();
1232: $dataProviderInformation = $dataProviderDefinition->getInformation($basicDefinition->getDataProvider());
1233: $inputProvider = $environment->getInputProvider();
1234: $palettesDefinition = $definition->getPalettesDefinition();
1235: $modelId = $inputProvider->getParameter('id');
1236: $propertyDefinitions = $definition->getPropertiesDefinition();
1237: $blnSubmitted = ($inputProvider->getValue('FORM_SUBMIT') === $definition->getName());
1238: $blnIsAutoSubmit = ($inputProvider->getValue('SUBMIT_TYPE') === 'auto');
1239:
1240: $widgetManager = new ContaoWidgetManager($environment, $model);
1241:
1242:
1243: if (!$basicDefinition->isEditable())
1244: {
1245: $message = 'DataContainer ' . $definition->getName() . ' is not editable';
1246: $environment->getEventPropagator()->propagate(
1247: ContaoEvents::SYSTEM_LOG,
1248: new LogEvent($message, TL_ERROR, 'DC_General - edit()')
1249: );
1250: throw new DcGeneralRuntimeException($message);
1251: }
1252:
1253:
1254: if ((!$modelId) && $basicDefinition->isClosed())
1255: {
1256: $message = 'DataContainer ' . $definition->getName() . ' is closed';
1257: $environment->getEventPropagator()->propagate(
1258: ContaoEvents::SYSTEM_LOG,
1259: new LogEvent($message, TL_ERROR, 'DC_General - edit()')
1260: );
1261: throw new DcGeneralRuntimeException($message);
1262: }
1263:
1264: $this->enforceModelRelationship($model);
1265:
1266:
1267: $palette = $palettesDefinition->findPalette($model);
1268:
1269: $propertyValues = $this->processInput($widgetManager);
1270: $errors = array();
1271: if ($blnSubmitted && $propertyValues)
1272: {
1273:
1274: $palette = $palettesDefinition->findPalette($model, $propertyValues);
1275:
1276:
1277: $this->getEnvironment()->getController()->updateModelFromPropertyBag($model, $propertyValues);
1278: }
1279:
1280: $arrFieldSets = array();
1281: foreach ($palette->getLegends() as $legend)
1282: {
1283: $legendName = $environment->getTranslator()->translate($legend->getName() . '_legend', $definition->getName());
1284: $fields = array();
1285: $properties = $legend->getProperties($model, $propertyValues);
1286:
1287: if (!$properties)
1288: {
1289: continue;
1290: }
1291:
1292: foreach ($properties as $property)
1293: {
1294: if (!$propertyDefinitions->hasProperty($property->getName()))
1295: {
1296: throw new DcGeneralInvalidArgumentException(
1297: sprintf(
1298: 'Property %s is mentioned in palette but not defined in propertyDefinition.',
1299: $property->getName()
1300: )
1301: );
1302: }
1303:
1304:
1305: if ((!$blnIsAutoSubmit)
1306: && $propertyValues
1307: && $propertyValues->hasPropertyValue($property->getName())
1308: && $propertyValues->isPropertyValueInvalid($property->getName())
1309: )
1310: {
1311: $errors = array_merge($errors, $propertyValues->getPropertyValueErrors($property->getName()));
1312: }
1313:
1314: $fields[] = $widgetManager->renderWidget($property->getName(), $blnIsAutoSubmit);
1315: }
1316:
1317: $arrFieldSet['label'] = $legendName;
1318: $arrFieldSet['class'] = 'tl_box';
1319: $arrFieldSet['palette'] = implode('', $fields);
1320: $arrFieldSet['legend'] = $legend->getName();
1321: $arrFieldSets[] = $arrFieldSet;
1322: }
1323:
1324: if ((!$blnIsAutoSubmit) && $blnSubmitted && empty($errors))
1325: {
1326: if ($model->getMeta(DCGE::MODEL_IS_CHANGED))
1327: {
1328:
1329: if ($preFunction != null)
1330: {
1331: $preFunction($environment, $model, $originalModel);
1332: }
1333:
1334: $event = new PrePersistModelEvent($environment, $model, $originalModel);
1335: $environment->getEventPropagator()->propagate(
1336: $event::NAME,
1337: $event,
1338: array(
1339: $this->getEnvironment()->getDataDefinition()->getName(),
1340: )
1341: );
1342:
1343:
1344: $dataProvider->save($model);
1345:
1346:
1347: if ($postFunction != null)
1348: {
1349: $postFunction($environment, $model, $originalModel);
1350: }
1351:
1352: $event = new PostPersistModelEvent($environment, $model, $originalModel);
1353: $environment->getEventPropagator()->propagate(
1354: $event::NAME,
1355: $event,
1356: array(
1357: $this->getEnvironment()->getDataDefinition()->getName(),
1358: )
1359: );
1360:
1361: $this->storeVersion($model);
1362: }
1363:
1364: $this->handleSubmit($model);
1365: }
1366:
1367: if ($model->getId())
1368: {
1369: $strHeadline = sprintf($this->translate('editRecord', $definition->getName()), 'ID ' . $model->getId());
1370: if ($strHeadline === 'editRecord')
1371: {
1372: $strHeadline = sprintf($this->translate('MSC.editRecord'), 'ID ' . $model->getId());
1373: }
1374: }
1375: else
1376: {
1377: $strHeadline = sprintf($this->translate('newRecord', $definition->getName()), 'ID ' . $model->getId());
1378: if ($strHeadline === 'newRecord')
1379: {
1380: $strHeadline = sprintf($this->translate('MSC.editRecord'), '');
1381: }
1382: }
1383:
1384: $objTemplate = $this->getTemplate('dcbe_general_edit');
1385: $objTemplate->setData(array(
1386: 'fieldsets' => $arrFieldSets,
1387: 'versions' => $dataProviderInformation->isVersioningEnabled() ? $dataProvider->getVersions($model->getId()) : null,
1388: 'subHeadline' => $strHeadline,
1389: 'table' => $definition->getName(),
1390: 'enctype' => 'multipart/form-data',
1391: 'error' => $errors,
1392: 'editButtons' => $this->getEditButtons(),
1393: 'noReload' => (bool)$errors
1394: ));
1395:
1396: if ($this->isMultiLanguage($model->getId()))
1397: {
1398:
1399: $langsNative = array();
1400: require TL_ROOT . '/system/config/languages.php';
1401:
1402: $this
1403: ->addToTemplate('languages', $environment->getController()->getSupportedLanguages($model->getId()), $objTemplate)
1404: ->addToTemplate('language', $dataProvider->getCurrentLanguage(), $objTemplate)
1405: ->addToTemplate('languageHeadline', $langsNative[$dataProvider->getCurrentLanguage()], $objTemplate);
1406: }
1407: else
1408: {
1409: $this
1410: ->addToTemplate('languages', null, $objTemplate)
1411: ->addToTemplate('languageHeadline', '', $objTemplate);
1412: }
1413:
1414: return $objTemplate->parse();
1415: }
1416:
1417: 1418: 1419: 1420: 1421: 1422: 1423:
1424: protected function getLabelForShow(PropertyInterface $property)
1425: {
1426: $environment = $this->getEnvironment();
1427: $definition = $environment->getDataDefinition();
1428:
1429: $label = $environment->getTranslator()->translate($property->getLabel(), $definition->getName());
1430:
1431: if (!$label)
1432: {
1433: $label = $environment->getTranslator()->translate('MSC.' . $property->getName());
1434: }
1435:
1436: if (is_array($label))
1437: {
1438: $label = $label[0];
1439: }
1440:
1441: if (!$label)
1442: {
1443: $label = $property->getName();
1444: }
1445:
1446: return $label;
1447: }
1448:
1449: 1450: 1451: 1452: 1453: 1454: 1455:
1456: public function show()
1457: {
1458:
1459: $environment = $this->getEnvironment();
1460: $definition = $environment->getDataDefinition();
1461: $properties = $definition->getPropertiesDefinition();
1462: $translator = $environment->getTranslator();
1463: $dataProvider = $environment->getDataProvider();
1464: $modelId = $environment->getInputProvider()->getParameter('id');
1465:
1466:
1467: $this->checkLanguage();
1468:
1469: $objDBModel = $dataProvider->fetch($dataProvider->getEmptyConfig()->setId($modelId));
1470:
1471: if ($objDBModel == null)
1472: {
1473: $environment->getEventPropagator()->propagate(
1474: ContaoEvents::SYSTEM_LOG,
1475: new LogEvent(
1476: sprintf(
1477: 'Could not find ID %s in %s.', 'DC_General show()',
1478: $modelId,
1479: $definition->getName()
1480: ),
1481: __CLASS__ . '::' . __FUNCTION__,
1482: TL_ERROR
1483: )
1484: );
1485:
1486: $environment->getEventPropagator()->propagate(
1487: ContaoEvents::CONTROLLER_REDIRECT,
1488: new RedirectEvent('contao/main.php?act=error')
1489: );
1490: }
1491:
1492: $values = array();
1493: $labels = array();
1494:
1495: $palette = $definition->getPalettesDefinition()->findPalette($objDBModel);
1496:
1497:
1498: foreach ($palette->getVisibleProperties($objDBModel) as $paletteProperty)
1499: {
1500: $property = $properties->getProperty($paletteProperty->getName());
1501:
1502: if (!$property)
1503: {
1504: throw new DcGeneralRuntimeException('Unable to retrieve property ' . $paletteProperty->getName());
1505: }
1506:
1507:
1508: $values[$paletteProperty->getName()] = $this->getReadableFieldValue(
1509: $property,
1510: $objDBModel,
1511: $objDBModel->getProperty($paletteProperty->getName())
1512: );
1513: $labels[$paletteProperty->getName()] = $this->getLabelForShow($property);
1514: }
1515:
1516: $headline = $translator->translate(
1517: 'MSC.showRecord',
1518: $definition->getName(),
1519: array($objDBModel->getId() ? 'ID ' . $objDBModel->getId() : '')
1520: );
1521:
1522: if ($headline == 'MSC.showRecord')
1523: {
1524: $headline = $translator->translate(
1525: 'MSC.showRecord',
1526: null,
1527: array($objDBModel->getId() ? 'ID ' . $objDBModel->getId() : '')
1528: );
1529: }
1530:
1531: $template = $this->getTemplate('dcbe_general_show');
1532: $this
1533: ->addToTemplate('headline', $headline, $template)
1534: ->addToTemplate('arrFields', $values, $template)
1535: ->addToTemplate('arrLabels', $labels, $template);
1536:
1537: if ($this->isMultiLanguage($objDBModel->getId()))
1538: {
1539:
1540: $this
1541: ->addToTemplate('languages', $environment->getController()->getSupportedLanguages($objDBModel->getId()), $template)
1542: ->addToTemplate('currentLanguage', $dataProvider->getCurrentLanguage(), $template)
1543: ->addToTemplate('languageSubmit', specialchars($translator->translate('MSC.showSelected')), $template)
1544: ->addToTemplate('backBT', specialchars($translator->translate('MSC.backBT')), $template);
1545: }
1546: else
1547: {
1548: $this->addToTemplate('language', null, $template);
1549: }
1550:
1551: return $template->parse();
1552: }
1553:
1554: 1555: 1556: 1557: 1558:
1559: public function showAll()
1560: {
1561: return sprintf(
1562: $this->notImplMsg,
1563: 'showAll - Mode ' . $this->getViewSection()->getListingConfig()->getGroupingMode()
1564: );
1565: }
1566:
1567: 1568: 1569: 1570: 1571: 1572: 1573:
1574: public function generateAjaxPalette($strSelector)
1575: {
1576: return vsprintf($this->notImplMsg, 'generateAjaxPalette');
1577: }
1578:
1579: 1580: 1581: 1582: 1583:
1584: protected function getCreateModelCommand()
1585: {
1586: $environment = $this->getEnvironment();
1587: $definition = $environment->getDataDefinition();
1588: $basicDefinition = $definition->getBasicDefinition();
1589: $parentProviderName = $environment->getDataDefinition()->getBasicDefinition()->getParentDataProvider();
1590: $providerName = $environment->getDataDefinition()->getName();
1591:
1592: if ($basicDefinition->isClosed())
1593: {
1594: return null;
1595: }
1596:
1597: $pid = $environment->getInputProvider()->getParameter('pid');
1598: $mode = $basicDefinition->getMode();
1599: $config = $this->getEnvironment()->getController()->getBaseConfig();
1600: $sorting = $config->getSorting();
1601:
1602: $command = new Command();
1603: $parameters = $command->getParameters();
1604: $extra = $command->getExtra();
1605:
1606: $extra['class'] = 'header_new';
1607: $extra['accesskey'] = 'n';
1608: $extra['attributes'] = 'onclick="Backend.getScrollOffset();"';
1609:
1610: $command
1611: ->setName('button_new')
1612: ->setLabel($this->translate('new.0', $providerName))
1613: ->setDescription($this->translate('new.1', $providerName));
1614:
1615: $this->getPanel()->initialize($config);
1616:
1617:
1618: if (($mode == BasicDefinitionInterface::MODE_FLAT)
1619: || (($mode == BasicDefinitionInterface::MODE_PARENTEDLIST) && !$sorting))
1620: {
1621: $parameters['act'] = 'create';
1622:
1623: if (strlen($parentProviderName) && $pid)
1624: {
1625: $parameters['pid'] = $pid;
1626: }
1627: }
1628: elseif(($mode == BasicDefinitionInterface::MODE_PARENTEDLIST)
1629: || ($mode == BasicDefinitionInterface::MODE_HIERARCHICAL))
1630: {
1631: if ($environment->getClipboard()->isNotEmpty())
1632: {
1633: return null;
1634: }
1635:
1636: $parameters['act'] = 'paste';
1637: $parameters['mode'] = 'create';
1638:
1639: if (strlen($parentProviderName) && $pid)
1640: {
1641: $parameters['pid'] = $pid;
1642: }
1643: }
1644:
1645: return $command;
1646: }
1647: 1648: 1649: 1650: 1651:
1652: protected function getClearClipboardCommand()
1653: {
1654: if ($this->getEnvironment()->getClipboard()->isEmpty())
1655: {
1656: return null;
1657: }
1658: $command = new Command();
1659: $parameters = $command->getParameters();
1660: $extra = $command->getExtra();
1661: $extra['class'] = 'header_clipboard';
1662: $extra['accesskey'] = 'x';
1663: $extra['attributes'] = 'onclick="Backend.getScrollOffset();"';
1664:
1665: $parameters['clipboard'] = '1';
1666:
1667: $command
1668: ->setName('button_clipboard')
1669: ->setLabel($this->translate('MSC.clearClipboard'))
1670: ->setDescription($this->translate('MSC.clearClipboard'));
1671:
1672: return $command;
1673: }
1674:
1675: 1676: 1677: 1678: 1679:
1680: protected function getBackCommand()
1681: {
1682: $environment = $this->getEnvironment();
1683: if (!($this->isSelectModeActive() || $environment->getDataDefinition()->getBasicDefinition()->getParentDataProvider()))
1684: {
1685: return null;
1686: }
1687:
1688:
1689: $event = $environment->getEventPropagator()->propagate(
1690: ContaoEvents::SYSTEM_GET_REFERRER,
1691: new GetReferrerEvent(true, $environment->getParentDataDefinition()->getName())
1692: );
1693:
1694: $command = new Command();
1695: $extra = $command->getExtra();
1696: $extra['class'] = 'header_back';
1697: $extra['accesskey'] = 'b';
1698: $extra['attributes'] = 'onclick="Backend.getScrollOffset();"';
1699: $extra['href'] = $event->getReferrerUrl();
1700:
1701: $command
1702: ->setName('back_button')
1703: ->setLabel($this->translate('MSC.backBT'))
1704: ->setDescription($this->translate('MSC.backBT'));
1705:
1706: return $command;
1707: }
1708:
1709: 1710: 1711: 1712: 1713: 1714: 1715:
1716: protected function (CommandInterface $command)
1717: {
1718: $environment = $this->getEnvironment();
1719: $extra = $command->getExtra();
1720: $label = $command->getLabel();
1721:
1722: if (isset($extra['href']))
1723: {
1724: $href = $extra['href'];
1725: }
1726: else
1727: {
1728: $href = '';
1729: foreach ($command->getParameters() as $key => $value)
1730: {
1731: $href .= '&' . $key . '=' . $value;
1732: }
1733:
1734:
1735: $event = $environment->getEventPropagator()->propagate(
1736: ContaoEvents::BACKEND_ADD_TO_URL,
1737: new AddToUrlEvent(
1738: $href
1739: )
1740: );
1741:
1742: $href = $event->getUrl();
1743: }
1744:
1745: if (!strlen($label))
1746: {
1747: $label = $command->getName();
1748: }
1749:
1750: $buttonEvent = new GetGlobalButtonEvent($this->getEnvironment());
1751: $buttonEvent
1752: ->setAccessKey(trim($extra['accesskey']))
1753: ->setAttributes(' ' . ltrim($extra['attributes']))
1754: ->setClass($extra['class'])
1755: ->setKey($command->getName())
1756: ->setHref($href)
1757: ->setLabel($label)
1758: ->setTitle($command->getDescription());
1759:
1760: $this->getEnvironment()->getEventPropagator()->propagate(
1761: $buttonEvent::NAME,
1762: $buttonEvent,
1763: array(
1764: $this->getEnvironment()->getDataDefinition()->getName(),
1765: $command->getName()
1766: )
1767: );
1768:
1769:
1770: $html = $buttonEvent->getHtml();
1771: if (!is_null($html))
1772: {
1773: return $html;
1774: }
1775:
1776:
1777: return sprintf(
1778: '<a href="%s" class="%s" title="%s"%s>%s</a> ',
1779: $buttonEvent->getHref(),
1780: $buttonEvent->getClass(),
1781: specialchars($buttonEvent->getTitle()),
1782: $buttonEvent->getAttributes(),
1783: $buttonEvent->getLabel()
1784: );
1785: }
1786:
1787:
1788: 1789: 1790: 1791: 1792: 1793: 1794:
1795: protected function ($strButtonId)
1796: {
1797:
1798: $globalOperations = $this->getViewSection()->getGlobalCommands()->getCommands();
1799: $buttons = array();
1800:
1801: if (!is_array($globalOperations))
1802: {
1803: $globalOperations = array();
1804: }
1805:
1806:
1807: if ($this->isSelectModeActive())
1808: {
1809: unset($globalOperations['all']);
1810: }
1811:
1812: else
1813: {
1814: $command = $this->getCreateModelCommand();
1815: if ($command !== null)
1816: {
1817:
1818: array_unshift($globalOperations, $command);
1819: }
1820:
1821: $command = $this->getClearClipboardCommand();
1822: if ($command !== null)
1823: {
1824:
1825: $globalOperations[] = $command;
1826: }
1827: }
1828:
1829: $command = $this->getBackCommand();
1830: if ($command !== null)
1831: {
1832:
1833: $globalOperations[] = $command;
1834: }
1835:
1836:
1837: foreach ($globalOperations as $command)
1838: {
1839: $buttons[$command->getName()] = $this->generateHeaderButton($command);
1840: }
1841:
1842: $buttonsEvent = new GetGlobalButtonsEvent($this->getEnvironment());
1843: $buttonsEvent->setButtons($buttons);
1844:
1845: $this->getEnvironment()->getEventPropagator()->propagate(
1846: $buttonsEvent::NAME,
1847: $buttonsEvent,
1848: array($this->getEnvironment()->getDataDefinition()->getName())
1849: );
1850:
1851: return '<div id="' . $strButtonId . '">' . implode(' :: ', $buttonsEvent->getButtons()) . '</div>';
1852: }
1853:
1854: 1855: 1856: 1857: 1858: 1859: 1860: 1861: 1862: 1863: 1864: 1865: 1866: 1867: 1868: 1869: 1870: 1871:
1872: protected function buildCommand($objCommand, $objModel, $blnCircularReference, $arrChildRecordIds, $previous, $next)
1873: {
1874: $propagator = $this->getEnvironment()->getEventPropagator();
1875:
1876:
1877: $opLabel = $objCommand->getLabel();
1878: if (strlen($opLabel))
1879: {
1880: $label = $opLabel;
1881: }
1882: else
1883: {
1884: $label = $objCommand->getName();
1885: }
1886:
1887: $opDesc = $objCommand->getDescription();
1888: if (strlen($opDesc))
1889: {
1890: $title = sprintf($opDesc, $objModel->getID());
1891: }
1892: else
1893: {
1894: $title = sprintf('%s id %s', $label, $objModel->getID());
1895: }
1896:
1897: $strAttributes = $objCommand->getExtra()['attributes'];
1898: $attributes = '';
1899: if (strlen($strAttributes))
1900: {
1901: $attributes = ltrim(sprintf($strAttributes, $objModel->getID()));
1902: }
1903:
1904:
1905: if ($objCommand instanceof CutCommandInterface)
1906: {
1907: $arrParameters = array();
1908: $arrParameters['act'] = 'cut';
1909:
1910:
1911: $strParentDataProvider = $objModel->getMeta(DCGE::MODEL_PTABLE);
1912: $arrParameters['cdp'] = $objModel->getProviderName();
1913:
1914:
1915: if ($strParentDataProvider != null)
1916: {
1917: $arrParameters['pdp'] = $strParentDataProvider;
1918: }
1919:
1920:
1921: if ($this->getEnvironment()->getInputProvider()->hasParameter('pid'))
1922: {
1923: $arrParameters['pid'] = $this->getEnvironment()->getInputProvider()->getParameter('pid');
1924: }
1925:
1926:
1927: $arrParameters['source'] = $objModel->getID();
1928: }
1929: else
1930: {
1931: $arrParameters = (array)$objCommand->getParameters();
1932:
1933:
1934: $idParam = $objCommand->getExtra()['idparam'];
1935: if ($idParam)
1936: {
1937: $arrParameters[$idParam] = $objModel->getID();
1938: }
1939: else
1940: {
1941: $arrParameters['id'] = $objModel->getID();
1942: }
1943: }
1944:
1945: $strHref = '';
1946: foreach ($arrParameters as $key => $value)
1947: {
1948: $strHref .= sprintf('&%s=%s', $key, $value);
1949: }
1950:
1951:
1952: $event = $propagator->propagate(
1953: ContaoEvents::BACKEND_ADD_TO_URL,
1954: new AddToUrlEvent($strHref)
1955: );
1956:
1957: $strHref = $event->getUrl();
1958:
1959: $buttonEvent = new GetOperationButtonEvent($this->getEnvironment());
1960: $buttonEvent
1961: ->setCommand($objCommand)
1962: ->setObjModel($objModel)
1963: ->setAttributes($attributes)
1964: ->setLabel($label)
1965: ->setTitle($title)
1966: ->setHref($strHref)
1967: ->setChildRecordIds($arrChildRecordIds)
1968: ->setCircularReference($blnCircularReference)
1969: ->setPrevious($previous)
1970: ->setNext($next);
1971:
1972: $propagator->propagate(
1973: $buttonEvent::NAME,
1974: $buttonEvent,
1975: array(
1976: $this->getEnvironment()->getDataDefinition()->getName(),
1977: $objCommand->getName()
1978: )
1979: );
1980:
1981:
1982: if (!is_null($buttonEvent->getHtml()))
1983: {
1984: return trim($buttonEvent->getHtml());
1985: }
1986:
1987: $extra = $objCommand->getExtra();
1988: $icon = $extra['icon'];
1989:
1990: if ($objCommand->isDisabled())
1991: {
1992:
1993: $event = $propagator->propagate(
1994: ContaoEvents::IMAGE_GET_HTML,
1995: new GenerateHtmlEvent(
1996: substr_replace($icon, '_1', strrpos($icon, '.'), 0),
1997: $buttonEvent->getLabel()
1998: )
1999: );
2000:
2001: return $event->getHtml();
2002: }
2003:
2004:
2005: $event = $propagator->propagate(
2006: ContaoEvents::IMAGE_GET_HTML,
2007: new GenerateHtmlEvent(
2008: $icon,
2009: $buttonEvent->getLabel()
2010: )
2011: );
2012:
2013: return sprintf(' <a href="%s" title="%s" %s>%s</a>',
2014: $buttonEvent->getHref(),
2015: specialchars($buttonEvent->getTitle()),
2016: $buttonEvent->getAttributes(),
2017: $event->getHtml()
2018: );
2019: }
2020:
2021: 2022: 2023: 2024: 2025: 2026: 2027:
2028: public function renderPasteIntoButton(GetPasteButtonEvent $event)
2029: {
2030: if (!is_null($event->getHtmlPasteInto()))
2031: {
2032: return $event->getHtmlPasteInto();
2033: }
2034:
2035: $strLabel = $this->translate('pasteinto.0', $event->getModel()->getProviderName());
2036: if ($event->isPasteIntoDisabled())
2037: {
2038:
2039: $imageEvent = $this->getEnvironment()->getEventPropagator()->propagate(
2040: ContaoEvents::IMAGE_GET_HTML,
2041: new GenerateHtmlEvent(
2042: 'pasteinto_.gif',
2043: $strLabel,
2044: 'class="blink"'
2045: )
2046: );
2047:
2048: return $imageEvent->getHtml();
2049: }
2050:
2051:
2052: $imageEvent = $this->getEnvironment()->getEventPropagator()->propagate(
2053: ContaoEvents::IMAGE_GET_HTML,
2054: new GenerateHtmlEvent(
2055: 'pasteinto.gif',
2056: $strLabel,
2057: 'class="blink"'
2058: )
2059: );
2060:
2061: return sprintf(' <a href="%s" title="%s" %s>%s</a>',
2062: $event->getHrefInto(),
2063: specialchars($strLabel),
2064: 'onclick="Backend.getScrollOffset()"',
2065: $imageEvent->getHtml()
2066: );
2067: }
2068:
2069: 2070: 2071: 2072: 2073: 2074: 2075:
2076: public function renderPasteAfterButton(GetPasteButtonEvent $event)
2077: {
2078: if (!is_null($event->getHtmlPasteAfter()))
2079: {
2080: return $event->getHtmlPasteAfter();
2081: }
2082:
2083: $strLabel = $this->translate('pasteafter.0', $event->getModel()->getProviderName());
2084: if ($event->isPasteAfterDisabled())
2085: {
2086:
2087: $imageEvent = $this->getEnvironment()->getEventPropagator()->propagate(
2088: ContaoEvents::IMAGE_GET_HTML,
2089: new GenerateHtmlEvent(
2090: 'pasteafter_.gif',
2091: $strLabel,
2092: 'class="blink"'
2093: )
2094: );
2095:
2096: return $imageEvent->getHtml();
2097: }
2098:
2099:
2100: $imageEvent = $this->getEnvironment()->getEventPropagator()->propagate(
2101: ContaoEvents::IMAGE_GET_HTML,
2102: new GenerateHtmlEvent(
2103: 'pasteafter.gif',
2104: $strLabel,
2105: 'class="blink"'
2106: )
2107: );
2108:
2109: return sprintf(' <a href="%s" title="%s" %s>%s</a>',
2110: $event->getHrefAfter(),
2111: specialchars($strLabel),
2112: 'onclick="Backend.getScrollOffset()"',
2113: $imageEvent->getHtml()
2114: );
2115: }
2116:
2117: 2118: 2119: 2120: 2121: 2122: 2123: 2124:
2125: protected function generateButtons(
2126: ModelInterface $model,
2127: ModelInterface $previous = null,
2128: ModelInterface $next = null
2129: )
2130: {
2131: $commands = $this->getViewSection()->getModelCommands();
2132: $objClipboard = $this->getEnvironment()->getClipboard();
2133: $propagator = $this->getEnvironment()->getEventPropagator();
2134:
2135: if ($this->getEnvironment()->getClipboard()->isNotEmpty())
2136: {
2137: $circularIds = $objClipboard->getCircularIds();
2138: $isCircular = in_array($model->getID(), $circularIds);
2139: }
2140: else
2141: {
2142: $circularIds = array();
2143: $isCircular = false;
2144: }
2145:
2146: $arrButtons = array();
2147: foreach ($commands->getCommands() as $command)
2148: {
2149: $arrButtons[$command->getName()] = $this->buildCommand(
2150: $command,
2151: $model,
2152: $isCircular,
2153: $circularIds,
2154: $previous,
2155: $next
2156: );
2157: }
2158:
2159:
2160: if ($this->getEnvironment()->getClipboard()->isNotEmpty())
2161: {
2162:
2163: $strMode = $objClipboard->getMode();
2164:
2165:
2166: $add2UrlAfter = sprintf('act=%s&after=%s&',
2167: $strMode,
2168: $model->getID()
2169: );
2170:
2171: $add2UrlInto = sprintf('act=%s&into=%s&',
2172: $strMode,
2173: $model->getID()
2174: );
2175:
2176:
2177: $urlAfter = $propagator->propagate(
2178: ContaoEvents::BACKEND_ADD_TO_URL,
2179: new AddToUrlEvent($add2UrlAfter)
2180: );
2181:
2182:
2183: $urlInto = $propagator->propagate(
2184: ContaoEvents::BACKEND_ADD_TO_URL,
2185: new AddToUrlEvent($add2UrlInto)
2186: );
2187:
2188: $buttonEvent = new GetPasteButtonEvent($this->getEnvironment());
2189: $buttonEvent
2190: ->setModel($model)
2191: ->setCircularReference($isCircular)
2192: ->setPrevious($previous)
2193: ->setNext($next)
2194: ->setHrefAfter($urlAfter->getUrl())
2195: ->setHrefInto($urlInto->getUrl())
2196:
2197: ->setPasteAfterDisabled($objClipboard->isCut() && $isCircular)
2198: ->setPasteIntoDisabled($objClipboard->isCut() && $isCircular);
2199:
2200: $this->getEnvironment()->getEventPropagator()->propagate(
2201: $buttonEvent::NAME,
2202: $buttonEvent,
2203: array($this->getEnvironment()->getDataDefinition()->getName())
2204: );
2205:
2206: $arrButtons['pasteafter'] = $this->renderPasteAfterButton($buttonEvent);
2207: if ($this->getDataDefinition()->getBasicDefinition()->getMode() == BasicDefinitionInterface::MODE_HIERARCHICAL)
2208: {
2209: $arrButtons['pasteinto'] = $this->renderPasteIntoButton($buttonEvent);
2210: }
2211:
2212: }
2213:
2214: return implode(' ', $arrButtons);
2215: }
2216:
2217: 2218: 2219: 2220: 2221: 2222: 2223:
2224: protected function panel()
2225: {
2226: if ($this->getPanel() === null)
2227: {
2228: throw new DcGeneralRuntimeException('No panel information stored in data container.');
2229: }
2230:
2231: $arrPanels = array();
2232: foreach ($this->getPanel() as $objPanel)
2233: {
2234: $arrPanel = array();
2235: foreach ($objPanel as $objElement)
2236: {
2237: $objElementTemplate = null;
2238: if ($objElement instanceof FilterElementInterface)
2239: {
2240: $objElementTemplate = $this->getTemplate('dcbe_general_panel_filter');
2241: }
2242: elseif ($objElement instanceof LimitElementInterface)
2243: {
2244: $objElementTemplate = $this->getTemplate('dcbe_general_panel_limit');
2245: }
2246: elseif ($objElement instanceof SearchElementInterface)
2247: {
2248: $objElementTemplate = $this->getTemplate('dcbe_general_panel_search');
2249: }
2250: elseif ($objElement instanceof SortElementInterface)
2251: {
2252: $objElementTemplate = $this->getTemplate('dcbe_general_panel_sort');
2253: }
2254: elseif ($objElement instanceof SubmitElementInterface)
2255: {
2256: $objElementTemplate = $this->getTemplate('dcbe_general_panel_submit');
2257: }
2258: $objElement->render($objElementTemplate);
2259:
2260: $arrPanel[] = $objElementTemplate->parse();
2261: }
2262: $arrPanels[] = $arrPanel;
2263: }
2264:
2265: if (count($arrPanels))
2266: {
2267: $objTemplate = $this->getTemplate('dcbe_general_panel');
2268: $this
2269: ->addToTemplate('action', ampersand($this->getEnvironment()->getInputProvider()->getRequestUrl(), true), $objTemplate)
2270:
2271: ->addToTemplate('panel', $arrPanels, $objTemplate);
2272:
2273: return $objTemplate->parse();
2274: }
2275:
2276: return '';
2277: }
2278:
2279: 2280: 2281: 2282: 2283:
2284: protected function breadcrumb()
2285: {
2286: $event = new GetBreadcrumbEvent($this->getEnvironment());
2287:
2288: $this->getEnvironment()->getEventPropagator()->propagate(
2289: $event::NAME,
2290: $event,
2291: array($this->getEnvironment()->getDataDefinition()->getName())
2292: );
2293:
2294: $arrReturn = $event->getElements();
2295:
2296: if (!is_array($arrReturn) || count($arrReturn) == 0)
2297: {
2298: return null;
2299: }
2300:
2301: $GLOBALS['TL_CSS'][] = 'system/modules/dc-general/html/css/generalBreadcrumb.css';
2302:
2303: $objTemplate = $this->getTemplate('dcbe_general_breadcrumb');
2304: $this->addToTemplate('elements', $arrReturn, $objTemplate);
2305:
2306: return $objTemplate->parse();
2307: }
2308:
2309: 2310: 2311: 2312: 2313: 2314: 2315:
2316: public function processInput($widgetManager)
2317: {
2318: $input = $this->getEnvironment()->getInputProvider();
2319:
2320: if ($input->getValue('FORM_SUBMIT') == $this->getEnvironment()->getDataDefinition()->getName())
2321: {
2322: $propertyValues = new PropertyValueBag();
2323: $propertyNames = $this->getEnvironment()->getDataDefinition()->getPropertiesDefinition()->getPropertyNames();
2324:
2325:
2326: foreach ($propertyNames as $propertyName)
2327: {
2328: if ($input->hasValue($propertyName))
2329: {
2330: $propertyValue = $input->getValue($propertyName);
2331: $propertyValues->setPropertyValue($propertyName, $propertyValue);
2332: }
2333: }
2334: $widgetManager->processInput($propertyValues);
2335:
2336: return $propertyValues;
2337: }
2338:
2339: return null;
2340: }
2341:
2342: 2343: 2344: 2345: 2346: 2347: 2348: 2349: 2350:
2351: public function formatModel(ModelInterface $model)
2352: {
2353: $listing = $this->getViewSection()->getListingConfig();
2354: $properties = $this->getDataDefinition()->getPropertiesDefinition();
2355: $formatter = $listing->getLabelFormatter($model->getProviderName());
2356: $sorting = array_keys((array)$listing->getDefaultSortingFields());
2357: $firstSorting = reset($sorting);
2358:
2359: $args = array();
2360: foreach ($formatter->getPropertyNames() as $propertyName)
2361: {
2362: if ($properties->hasProperty($propertyName))
2363: {
2364: $property = $properties->getProperty($propertyName);
2365:
2366: $args[$propertyName] = (string)$this->getReadableFieldValue($property, $model, $model->getProperty($propertyName));
2367: }
2368: else
2369: {
2370: $args[$propertyName] = '-';
2371: }
2372:
2373: }
2374:
2375: $event = new ModelToLabelEvent($this->getEnvironment(), $model);
2376: $event
2377: ->setArgs($args)
2378: ->setLabel($formatter->getFormat())
2379: ->setFormatter($formatter);
2380:
2381: $this->getEnvironment()->getEventPropagator()->propagate(
2382: $event::NAME,
2383: $event,
2384: array($this->getEnvironment()->getDataDefinition()->getName())
2385: );
2386:
2387: $arrLabel = array();
2388:
2389:
2390: if ($listing->getShowColumns())
2391: {
2392: $fields = $formatter->getPropertyNames();
2393: $args = $event->getArgs();
2394:
2395: if (!is_array($args))
2396: {
2397: $arrLabel[] = array(
2398: 'colspan' => count($fields),
2399: 'class' => 'tl_file_list col_1',
2400: 'content' => $args
2401: );
2402: }
2403: else
2404: {
2405: foreach ($fields as $j => $propertyName)
2406: {
2407: $arrLabel[] = array(
2408: 'colspan' => 1,
2409: 'class' => 'tl_file_list col_' . $j . (($propertyName == $firstSorting) ? ' ordered_by' : ''),
2410: 'content' => (($args[$propertyName] != '') ? $args[$propertyName] : '-')
2411: );
2412: }
2413: }
2414: }
2415: else
2416: {
2417: if (!is_array($event->getArgs()))
2418: {
2419: $string = $event->getArgs();
2420: }
2421: else
2422: {
2423: $string = vsprintf($event->getLabel(), $event->getArgs());
2424: }
2425:
2426: if ($formatter->getMaxLength() !== null && strlen($string) > $formatter->getMaxLength())
2427: {
2428: $string = substr($string, 0, $formatter->getMaxLength());
2429: }
2430:
2431: $arrLabel[] = array(
2432: 'colspan' => null,
2433: 'class' => 'tl_file_list',
2434: 'content' => $string
2435: );
2436: }
2437:
2438: return $arrLabel;
2439: }
2440:
2441: 2442: 2443: 2444: 2445: 2446: 2447: 2448: 2449: 2450: 2451:
2452: public function getReadableFieldValue(PropertyInterface $property, ModelInterface $model, $value)
2453: {
2454: $event = new RenderReadablePropertyValueEvent($this->getEnvironment(), $model, $property, $value);
2455: $this->getEnvironment()->getEventPropagator()->propagate(
2456: $event::NAME,
2457: $event,
2458: array(
2459: $this->getEnvironment()->getDataDefinition()->getName(),
2460: $property->getName()
2461: )
2462: );
2463:
2464: if ($event->getRendered() !== null)
2465: {
2466: return $event->getRendered();
2467: }
2468:
2469: return $value;
2470: }
2471: }
2472: