1 <?php
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
31 abstract class ModelAdmin extends LeftAndMain {
32
33 static $url_rule = '/$Action';
34
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
57 public static $managed_models = null;
58
59 60 61
62 public static $allowed_actions = array(
63 'add',
64 'edit',
65 'delete',
66 'import',
67 'renderimportform',
68 'handleList',
69 'handleItem',
70 'ImportForm'
71 );
72
73 74 75
76 public static $collection_controller_class = "ModelAdmin_CollectionController";
77
78 79 80
81 public static $record_controller_class = "ModelAdmin_RecordController";
82
83 84 85
86 public static $url_handlers = array(
87 '$Action' => 'handleAction'
88 );
89
90 91 92 93 94 95
96 private $currentModel = false;
97
98 99 100 101 102 103 104 105 106 107
108 public static $model_importers = null;
109
110 111 112 113 114
115 public static $page_length = 30;
116
117 118 119 120
121 protected $resultsTableClassName = 'TableListField';
122
123 124 125
126 public function resultsTableClassName() {
127 return $this->resultsTableClassName;
128 }
129
130 131 132 133 134
135 public function init() {
136 parent::init();
137
138 if($this->getRequest()->requestVar("Locale")) {
139 $this->Locale = $this->getRequest()->requestVar("Locale");
140 } elseif($this->getRequest()->requestVar("locale")) {
141 $this->Locale = $this->getRequest()->requestVar("locale");
142 } else {
143 $this->Locale = Translatable::default_locale();
144 }
145 Translatable::set_current_locale($this->Locale);
146
147
148 if(isset($this->urlParams['Action']) && !in_array($this->urlParams['Action'], $this->getManagedModels())) {
149
150 }
151
152 Requirements::css(CMS_DIR . '/css/ModelAdmin.css');
153 Requirements::css(CMS_DIR . '/css/silverstripe.tabs.css');
154
155 Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
156 Requirements::javascript(THIRDPARTY_DIR . '/jquery-form/jquery.form.js');
157 Requirements::javascript(THIRDPARTY_DIR . '/jquery-effen/jquery.fn.js');
158 Requirements::javascript(SAPPHIRE_DIR . '/javascript/jquery_improvements.js');
159 Requirements::javascript(CMS_DIR . '/javascript/ModelAdmin.js');
160 }
161
162 163 164 165
166 static function set_page_length($length){
167 self::$page_length = $length;
168 }
169
170 171 172
173 static function get_page_length(){
174 return self::$page_length;
175 }
176
177 178 179 180 181 182
183 function getCollectionControllerClass($model) {
184 $models = $this->getManagedModels();
185
186 if(isset($models[$model]['collection_controller'])) {
187 $class = $models[$model]['collection_controller'];
188 } else {
189 $class = $this->stat('collection_controller_class');
190 }
191
192 return $class;
193 }
194
195 196 197 198 199 200
201 function getRecordControllerClass($model) {
202 $models = $this->getManagedModels();
203
204 if(isset($models[$model]['record_controller'])) {
205 $class = $models[$model]['record_controller'];
206 } else {
207 $class = $this->stat('record_controller_class');
208 }
209
210 return $class;
211 }
212
213 214 215
216 function defineMethods() {
217 parent::defineMethods();
218 foreach($this->getManagedModels() as $class => $options) {
219 if(is_numeric($class)) $class = $options;
220 $this->addWrapperMethod($class, 'bindModelController');
221 self::$allowed_actions[] = $class;
222 }
223 }
224
225 226 227
228 public function bindModelController($model, $request = null) {
229 $class = $this->getCollectionControllerClass($model);
230 return new $class($this, $model);
231 }
232
233 234 235 236
237 function LangSelector() {
238 $member = Member::currentUser();
239 $dropdown = new LanguageDropdownField(
240 'LangSelector',
241 'Language',
242 array(),
243 'SiteTree',
244 'Locale-English',
245 singleton('SiteTree')
246 );
247 $dropdown->setValue(Translatable::get_current_locale());
248 return $dropdown;
249 }
250
251 252 253
254 function IsTranslatableEnabled($model=false) {
255 if ($model) {
256 return Object::has_extension($model, 'Translatable');
257 }
258 if (count($this->getManagedModels()) == 1) {
259 if (!is_numeric(array_shift(array_keys($this->getManagedModels())))) {
260 return Object::has_extension(array_shift(array_keys($this->getManagedModels())), 'Translatable');
261 } else {
262 return Object::has_extension(array_shift($this->getManagedModels()), 'Translatable');
263 }
264 }
265 return false;
266 }
267
268 269 270 271 272 273 274 275
276 public function SearchClassSelector() {
277 return sizeof($this->getManagedModels()) > 2 ? 'dropdown' : 'tabs';
278 }
279
280 281 282 283 284 285
286 protected function getModelForms() {
287 $models = $this->getManagedModels();
288 $forms = new DataObjectSet();
289
290 foreach($models as $class => $options) {
291 if(is_numeric($class)) $class = $options;
292 $forms->push(new ArrayData(array (
293 'Title' => (is_array($options) && isset($options['title'])) ? $options['title'] : singleton($class)->i18n_plural_name(),
294 'ClassName' => $class,
295 'Content' => $this->$class()->getModelSidebar()
296 )));
297 }
298
299 return $forms;
300 }
301
302 303 304
305 function getManagedModels() {
306 $models = $this->stat('managed_models');
307 if(is_string($models)) {
308 $models = array($models);
309 }
310 if(!count($models)) {
311 user_error(
312 'ModelAdmin::getManagedModels():
313 You need to specify at least one DataObject subclass in public static $managed_models.
314 Make sure that this property is defined, and that its visibility is set to "public"',
315 E_USER_ERROR
316 );
317 }
318
319 return $models;
320 }
321
322 323 324 325 326 327 328 329
330 function getModelImporters() {
331 $importers = $this->stat('model_importers');
332
333
334 if(is_null($importers)) {
335 $models = $this->getManagedModels();
336 foreach($models as $modelName => $options) {
337 if(is_numeric($modelName)) $modelName = $options;
338 $importers[$modelName] = 'CsvBulkLoader';
339 }
340 }
341
342 return $importers;
343 }
344
345 }
346
347 348 349 350 351 352
353 class ModelAdmin_CollectionController extends Controller {
354 public $parentController;
355 protected $modelClass;
356
357 static $url_handlers = array(
358 '$Action' => 'handleActionOrID'
359 );
360
361 function __construct($parent, $model) {
362 $this->parentController = $parent;
363 $this->modelClass = $model;
364
365 parent::__construct();
366 }
367
368 369 370 371 372 373
374 function Link($action = null) {
375 return $this->parentController->Link(Controller::join_links($this->modelClass, $action));
376 }
377
378 379 380 381 382
383 function getModelClass() {
384 return $this->modelClass;
385 }
386
387 388 389 390 391 392 393
394 function handleActionOrID($request) {
395 if (is_numeric($request->param('Action'))) {
396 return $this->handleID($request);
397 } else {
398 return $this->handleAction($request);
399 }
400 }
401
402 403 404 405 406 407 408
409 public function handleID($request) {
410 $class = $this->parentController->getRecordControllerClass($this->getModelClass());
411 return new $class($this, $request);
412 }
413
414
415
416 417 418 419 420
421 public function () {
422 return $this->renderWith('ModelSidebar');
423 }
424
425 426 427 428 429
430 public function SearchForm() {
431 $context = singleton($this->modelClass)->getDefaultSearchContext();
432 $fields = $context->getSearchFields();
433 if ($fields) {
434 foreach($fields as $field) {
435 if ($field->is_a('DropdownField')) {
436 if (!$field->getSource()) {
437 $fields->removeByName($field->Name());
438 } else {
439 $dbObj = singleton($this->modelClass)->dbObject($field->Name());
440 if ($dbObj->is_a('Enum')) {
441 $map = array();
442 if ($field->getHasEmptyDefault()) {
443 $map[''] = $field->getEmptyString();
444 }
445 foreach($dbObj->enumValues() as $value) {
446 $map[$value] = _t("{$this->modelClass}.".$field->Name()."_{$value}", $value);
447 }
448 $field->setSource($map);
449 }
450 }
451 }
452 }
453 }
454 $columnSelectionField = $this->ColumnSelectionField();
455 $fields->push($columnSelectionField);
456 if ($this->parentController->IsTranslatableEnabled($this->modelClass)) {
457 $fields->push(new HiddenField('Locale','Locale', Translatable::get_current_locale()));
458 }
459 $validator = new RequiredFields();
460 $validator->setJavascriptValidationHandler('none');
461
462 $form = new Form($this, "SearchForm",
463 $fields,
464 new FieldSet(
465 new FormAction('search', _t('MemberTableField.SEARCH', 'Search')),
466 $clearAction = new ResetFormAction('clearsearch', _t('ModelAdmin.CLEAR_SEARCH','Clear Search'))
467 ),
468 $validator
469 );
470
471 $form->setFormMethod('get');
472 $form->setHTMLID("Form_SearchForm_" . $this->modelClass);
473 $form->disableSecurityToken();
474 $clearAction->useButtonTag = true;
475 $clearAction->addExtraClass('minorAction');
476
477 return $form;
478 }
479
480 481 482 483
484 public function CreateForm() {
485 $modelName = $this->modelClass;
486
487 if($this->hasMethod('alternatePermissionCheck')) {
488 if(!$this->alternatePermissionCheck()) return false;
489 } else {
490 if(!singleton($modelName)->canCreate(Member::currentUser())) return false;
491 }
492
493 $buttonLabel = sprintf(_t('ModelAdmin.CREATEBUTTON', "Create '%s'", PR_MEDIUM, "Create a new instance from a model class"), singleton($modelName)->i18n_singular_name());
494
495 $fields = new FieldSet();
496 if ($this->parentController->IsTranslatableEnabled($modelName)) {
497 $fields->push(new HiddenField('Locale','Locale', Translatable::get_current_locale()));
498 }
499
500 $form = new Form($this, "CreateForm",
501 $fields,
502 new FieldSet($createButton = new FormAction('add', $buttonLabel)),
503 $validator = new RequiredFields()
504 );
505
506 $createButton->dontEscape = true;
507 $validator->setJavascriptValidationHandler('none');
508 $form->setHTMLID("Form_CreateForm_" . $this->modelClass);
509 return $form;
510 }
511
512 513 514 515 516
517 public function ImportForm() {
518 $modelName = $this->modelClass;
519 $importers = $this->parentController->getModelImporters();
520 if(!$importers || !isset($importers[$modelName])) return false;
521
522 if(!singleton($modelName)->canCreate(Member::currentUser())) return false;
523
524 $fields = new FieldSet(
525 new HiddenField('ClassName', _t('ModelAdmin.CLASSTYPE'), $modelName),
526 new FileField('_CsvFile', false)
527 );
528
529
530 $importerClass = $importers[$modelName];
531 $importer = new $importerClass($modelName);
532 $spec = $importer->getImportSpec();
533 $specFields = new DataObjectSet();
534 foreach($spec['fields'] as $name => $desc) {
535 $specFields->push(new ArrayData(array('Name' => $name, 'Description' => $desc)));
536 }
537 $specRelations = new DataObjectSet();
538 foreach($spec['relations'] as $name => $desc) {
539 $specRelations->push(new ArrayData(array('Name' => $name, 'Description' => $desc)));
540 }
541 $specHTML = $this->customise(array(
542 'ModelName' => Convert::raw2att($modelName),
543 'ModelTitle' => singleton($modelName)->i18n_singular_name(),
544 'Fields' => $specFields,
545 'Relations' => $specRelations,
546 ))->renderWith('ModelAdmin_ImportSpec');
547
548 $fields->push(new LiteralField("SpecFor{$modelName}", $specHTML));
549 $fields->push(new CheckboxField('EmptyBeforeImport', _t('ModelAdmin.CLEAR_DB', 'Clear Database before import'), true));
550
551 $actions = new FieldSet(
552 new FormAction('import', _t('ModelAdmin.IMPORT', 'Import from CSV'))
553 );
554
555 $validator = new RequiredFields();
556 $validator->setJavascriptValidationHandler('none');
557
558 $form = new Form(
559 $this,
560 "ImportForm",
561 $fields,
562 $actions,
563 $validator
564 );
565 $form->setHTMLID("Form_ImportForm");
566 return $form;
567 }
568
569 570 571 572 573 574 575 576 577 578 579
580 function import($data, $form, $request) {
581 $modelName = $data['ClassName'];
582 $importers = $this->parentController->getModelImporters();
583 $importerClass = $importers[$modelName];
584
585 $loader = new $importerClass($data['ClassName']);
586
587
588 if(empty($_FILES['_CsvFile']['tmp_name'])) {
589 $form->sessionMessage(_t('ModelAdmin.NOCSVFILE', 'Please browse for a CSV file to import'), 'good');
590 Director::redirectBack();
591 return false;
592 }
593
594 if (!empty($data['EmptyBeforeImport']) && $data['EmptyBeforeImport']) {
595 $loader->deleteExistingRecords = true;
596 }
597 $results = $loader->load($_FILES['_CsvFile']['tmp_name']);
598
599 $message = '';
600 if($results->CreatedCount()) $message .= sprintf(
601 _t('ModelAdmin.IMPORTEDRECORDS', "Imported %s records."),
602 $results->CreatedCount()
603 );
604 if($results->UpdatedCount()) $message .= sprintf(
605 _t('ModelAdmin.UPDATEDRECORDS', "Updated %s records."),
606 $results->UpdatedCount()
607 );
608 if($results->DeletedCount()) $message .= sprintf(
609 _t('ModelAdmin.DELETEDRECORDS', "Deleted %s records."),
610 $results->DeletedCount()
611 );
612 if(!$results->CreatedCount() && !$results->UpdatedCount()) $message .= _t('ModelAdmin.NOIMPORT', "Nothing to import");
613
614 $form->sessionMessage($message, 'good');
615 Director::redirectBack();
616 }
617
618 619 620 621
622 public function columnsAvailable() {
623 return singleton($this->modelClass)->summaryFields();
624 }
625
626 627 628 629
630 public function columnsSelectedByDefault() {
631 return array_keys(singleton($this->modelClass)->summaryFields());
632 }
633
634 635 636
637 public function ColumnSelectionField() {
638 $model = singleton($this->modelClass);
639 $source = $this->columnsAvailable();
640
641
642 $value = $this->columnsSelectedByDefault();
643
644
645 $columnisedSource = array();
646 $keys = array_keys($source);
647 $midPoint = ceil(sizeof($source)/2);
648 for($i=0;$i<$midPoint;$i++) {
649 $key1 = $keys[$i];
650 $columnisedSource[$key1] = $model->fieldLabel($source[$key1]);
651
652 if(isset($keys[$i+$midPoint])) {
653 $key2 = $keys[$i+$midPoint];
654 $columnisedSource[$key2] = $model->fieldLabel($source[$key2]);
655 }
656 }
657
658 $checkboxes = new CheckboxSetField("ResultAssembly", false, $columnisedSource, $value);
659
660 $field = new CompositeField(
661 new LiteralField(
662 "ToggleResultAssemblyLink",
663 sprintf("<a class=\"form_frontend_function toggle_result_assembly\" href=\"#\">%s</a>",
664 _t('ModelAdmin.CHOOSE_COLUMNS', 'Select result columns...')
665 )
666 ),
667 $checkboxesBlock = new CompositeField(
668 $checkboxes,
669 new LiteralField("ClearDiv", "<div class=\"clear\"></div>"),
670 new LiteralField(
671 "TickAllAssemblyLink",
672 sprintf(
673 "<a class=\"form_frontend_function tick_all_result_assembly\" href=\"#\">%s</a>",
674 _t('ModelAdmin.SELECTALL', 'select all')
675 )
676 ),
677 new LiteralField(
678 "UntickAllAssemblyLink",
679 sprintf(
680 "<a class=\"form_frontend_function untick_all_result_assembly\" href=\"#\">%s</a>",
681 _t('ModelAdmin.SELECTNONE', 'select none')
682 )
683 )
684 )
685 );
686
687 $field->addExtraClass("ResultAssemblyBlock");
688 $checkboxesBlock->addExtraClass("hidden");
689 return $field;
690 }
691
692 693 694 695 696 697
698 function search($request, $form) {
699
700 $resultsForm = $this->ResultsForm(array_merge($form->getData(), $request));
701
702 $tableField = $resultsForm->Fields()->fieldByName($this->modelClass);
703 $numResults = $tableField->TotalCount();
704
705 if($numResults) {
706 return new SS_HTTPResponse(
707 $resultsForm->forTemplate(),
708 200,
709 sprintf(
710 _t('ModelAdmin.FOUNDRESULTS',"Your search found %s matching items"),
711 $numResults
712 )
713 );
714 } else {
715 return new SS_HTTPResponse(
716 $resultsForm->forTemplate(),
717 200,
718 _t('ModelAdmin.NORESULTS',"Your search didn't return any matching items")
719 );
720 }
721 }
722
723 724 725 726 727 728 729
730 function getSearchQuery($searchCriteria) {
731 $context = singleton($this->modelClass)->getDefaultSearchContext();
732 return $context->getQuery($searchCriteria);
733 }
734
735 736 737 738 739 740 741
742 function getResultColumns($searchCriteria, $selectedOnly = true) {
743 $model = singleton($this->modelClass);
744
745 $summaryFields = $this->columnsAvailable();
746
747 if($selectedOnly && isset($searchCriteria['ResultAssembly'])) {
748 $resultAssembly = $searchCriteria['ResultAssembly'];
749 if(!is_array($resultAssembly)) {
750 $explodedAssembly = split(' *, *', $resultAssembly);
751 $resultAssembly = array();
752 foreach($explodedAssembly as $item) $resultAssembly[$item] = true;
753 }
754 return array_intersect_key($summaryFields, $resultAssembly);
755 } else {
756 return $summaryFields;
757 }
758 }
759
760 761 762 763 764 765 766 767 768
769 function getResultsTable($searchCriteria) {
770
771 $summaryFields = $this->getResultColumns($searchCriteria);
772
773 $className = $this->parentController->resultsTableClassName();
774 $tf = new $className(
775 $this->modelClass,
776 $this->modelClass,
777 $summaryFields
778 );
779
780 $tf->setCustomQuery($this->getSearchQuery($searchCriteria));
781 $tf->setPageSize($this->parentController->stat('page_length'));
782 $tf->setShowPagination(true);
783
784 $tf->setPermissions(array_merge(array('view','export'), TableListField::permissions_for_object($this->modelClass)));
785
786
787 $exportFields = $this->getResultColumns($searchCriteria, false);
788 $tf->setFieldListCsv($exportFields);
789
790 $editLink = $this->Link() . '/$ID/edit';
791 if ($this->parentController->IsTranslatableEnabled($this->modelClass)) {
792 $editLink .= '?Locale=' . Translatable::get_current_locale();
793 }
794
795 $url = '<a href=\"' . $editLink . '\">$value</a>';
796
797 $tf->setFieldFormatting(array_combine(array_keys($summaryFields), array_fill(0,count($summaryFields), $url)));
798
799 return $tf;
800 }
801
802 803 804 805 806 807 808
809 function ResultsForm($searchCriteria) {
810
811 if($searchCriteria instanceof SS_HTTPRequest) $searchCriteria = $searchCriteria->getVars();
812
813 $tf = $this->getResultsTable($searchCriteria);
814
815
816
817 $form = new Form(
818 $this,
819 'ResultsForm',
820 new FieldSet(
821 new HeaderField('SearchResultsHeader',_t('ModelAdmin.SEARCHRESULTS','Search Results'), 2),
822 $tf
823 ),
824 new FieldSet(
825 new FormAction("goBack", _t('ModelAdmin.GOBACK', "Back")),
826 new FormAction("goForward", _t('ModelAdmin.GOFORWARD', "Forward"))
827 )
828 );
829
830
831 $filteredCriteria = $searchCriteria;
832 unset($filteredCriteria['ctf']);
833 unset($filteredCriteria['url']);
834 unset($filteredCriteria['action_search']);
835
836 $form->setFormAction($this->Link() . '/ResultsForm?' . http_build_query($filteredCriteria));
837 return $form;
838 }
839
840
841
842
843 844 845 846 847 848
849 function add($request) {
850 return new SS_HTTPResponse(
851 $this->AddForm()->forAjaxTemplate(),
852 200,
853 sprintf(
854 _t('ModelAdmin.ADDFORM', "Fill out this form to add a %s to the database."),
855 $this->modelClass
856 )
857 );
858 }
859
860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881
882 public function AddForm() {
883 $newRecord = new $this->modelClass();
884
885 if($newRecord->canCreate()){
886 if($newRecord->hasMethod('getCMSAddFormFields')) {
887 $fields = $newRecord->getCMSAddFormFields();
888 } else {
889 $fields = $newRecord->getCMSFields();
890 }
891
892 $validator = ($newRecord->hasMethod('getCMSValidator')) ? $newRecord->getCMSValidator() : null;
893 if(!$validator) $validator = new RequiredFields();
894 $validator->setJavascriptValidationHandler('none');
895
896 $actions = new FieldSet (
897 new FormAction("doCreate", _t('ModelAdmin.ADDBUTTON', "Add"))
898 );
899
900 $form = new Form($this, "AddForm", $fields, $actions, $validator);
901 $form->loadDataFrom($newRecord);
902
903 if ($this->parentController->IsTranslatableEnabled($this->modelClass) && ($localeField = $fields->dataFieldByName('Locale'))) {
904 $localeField->setValue(Translatable::get_current_locale());
905 }
906
907
908 return $form;
909 }
910 }
911
912 function doCreate($data, $form, $request) {
913 $className = $this->getModelClass();
914 $model = new $className();
915
916 $model->write();
917 $form->saveInto($model);
918 $model->write();
919
920 if(Director::is_ajax()) {
921 $class = $this->parentController->getRecordControllerClass($this->getModelClass());
922 $recordController = new $class($this, $request, $model->ID);
923 return new SS_HTTPResponse(
924 $recordController->EditForm()->forAjaxTemplate(),
925 200,
926 sprintf(
927 _t('ModelAdmin.LOADEDFOREDITING', "Loaded '%s' for editing."),
928 $model->Title
929 )
930 );
931 } else {
932 Director::redirect(Controller::join_links($this->Link(), $model->ID , 'edit'));
933 }
934 }
935 }
936
937 938 939 940 941 942 943
944 class ModelAdmin_RecordController extends Controller {
945 protected $parentController;
946 protected $currentRecord;
947
948 static $allowed_actions = array('edit', 'view', 'EditForm', 'ViewForm');
949
950 function __construct($parentController, $request, $recordID = null) {
951 $this->parentController = $parentController;
952 $modelName = $parentController->getModelClass();
953 $recordID = ($recordID) ? $recordID : $request->param('Action');
954 $this->currentRecord = DataObject::get_by_id($modelName, $recordID);
955
956 parent::__construct();
957 }
958
959 960 961
962 public function Link($action = null) {
963 return $this->parentController->Link(Controller::join_links($this->currentRecord->ID, $action));
964 }
965
966
967
968 969 970
971 function edit($request) {
972 if ($this->currentRecord) {
973 if(Director::is_ajax()) {
974 return new SS_HTTPResponse(
975 $this->EditForm()->forAjaxTemplate(),
976 200,
977 sprintf(
978 _t('ModelAdmin.LOADEDFOREDITING', "Loaded '%s' for editing."),
979 $this->currentRecord->Title
980 )
981 );
982 } else {
983
984 return $this->parentController->parentController->customise(array(
985 'Right' => $this->parentController->parentController->customise(array(
986 'EditForm' => $this->EditForm()
987 ))->renderWith('ModelAdmin_right')
988 ))->renderWith(array('ModelAdmin','LeftAndMain'));
989 return ;
990 }
991 } else {
992 return _t('ModelAdmin.ITEMNOTFOUND', "I can't find that item");
993 }
994 }
995
996 997 998
999 public function EditForm() {
1000 $fields = $this->currentRecord->getCMSFields();
1001 $fields->push(new HiddenField("ID"));
1002
1003 $validator = ($this->currentRecord->hasMethod('getCMSValidator')) ? $this->currentRecord->getCMSValidator() : new RequiredFields();
1004 $validator->setJavascriptValidationHandler('none');
1005
1006 $actions = $this->currentRecord->getCMSActions();
1007 if($this->currentRecord->canEdit(Member::currentUser())){
1008 $actions->push(new FormAction("doSave", _t('ModelAdmin.SAVE', "Save")));
1009 }else{
1010 $fields = $fields->makeReadonly();
1011 }
1012
1013 if($this->currentRecord->canDelete(Member::currentUser())) {
1014 $actions->insertFirst($deleteAction = new FormAction('doDelete', _t('ModelAdmin.DELETE', 'Delete')));
1015 $deleteAction->addExtraClass('delete');
1016 }
1017
1018 $actions->insertFirst(new FormAction("goBack", _t('ModelAdmin.GOBACK', "Back")));
1019
1020 $form = new Form($this, "EditForm", $fields, $actions, $validator);
1021 $form->loadDataFrom($this->currentRecord);
1022
1023 return $form;
1024 }
1025
1026 1027 1028 1029 1030 1031 1032 1033
1034 function doSave($data, $form, $request) {
1035 $form->saveInto($this->currentRecord);
1036
1037 try {
1038 $this->currentRecord->write();
1039 } catch(ValidationException $e) {
1040 $form->sessionMessage($e->getResult()->message(), 'bad');
1041 }
1042
1043
1044
1045 if(Director::is_ajax()) {
1046 return $this->edit($request);
1047 } else {
1048 Director::redirectBack();
1049 }
1050 }
1051
1052 1053 1054
1055 public function doDelete($data, $form, $request) {
1056 if($this->currentRecord->canDelete(Member::currentUser())) {
1057 $this->currentRecord->delete();
1058 Director::redirect($this->parentController->Link('SearchForm?action=search'));
1059 }
1060 else Director::redirectBack();
1061 return;
1062 }
1063
1064
1065
1066 1067 1068 1069 1070 1071
1072 function view($request) {
1073 if($this->currentRecord) {
1074 $form = $this->ViewForm();
1075 return $form->forAjaxTemplate();
1076 } else {
1077 return _t('ModelAdmin.ITEMNOTFOUND');
1078 }
1079 }
1080
1081 1082 1083 1084 1085
1086 public function ViewForm() {
1087 $fields = $this->currentRecord->getCMSFields();
1088 $form = new Form($this, "EditForm", $fields, new FieldSet());
1089 $form->loadDataFrom($this->currentRecord);
1090 $form->makeReadonly();
1091 return $form;
1092 }
1093
1094
1095
1096 function index() {
1097 Director::redirect(Controller::join_links($this->Link(), 'edit'));
1098 }
1099
1100 function getCurrentRecord(){
1101 return $this->currentRecord;
1102 }
1103
1104 }
1105
1106 ?>
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-