├── _config.php ├── .gitattributes ├── dist └── images │ └── singleobjectadmin.png ├── templates └── LittleGiant │ └── SingleObjectAdmin │ ├── SingleObjectAdmin_SilverStripeNavigator.ss │ ├── SingleObjectAdmin_EditForm.ss │ └── SingleObjectAdmin_Content.ss ├── .editorconfig ├── composer.json ├── README.md └── src └── SingleObjectAdmin.php /_config.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | /.gitignore export-ignore 2 | -------------------------------------------------------------------------------- /dist/images/singleobjectadmin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isobar-nz/silverstripe-singleobjectadmin/HEAD/dist/images/singleobjectadmin.png -------------------------------------------------------------------------------- /templates/LittleGiant/SingleObjectAdmin/SingleObjectAdmin_SilverStripeNavigator.ss: -------------------------------------------------------------------------------- 1 |
2 | 3 | « <%t SilverStripe\\SiteConfig\\SiteConfigLeftAndMain_SilverStripeNavigator.EDIT 'Edit' %> 4 | 5 |
6 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # For more information about the properties used in this file, 2 | # please see the EditorConfig documentation: 3 | # http://editorconfig.org 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_size = 4 9 | indent_style = space 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [{*.yml,package.json}] 14 | indent_size = 2 15 | 16 | # The indent size used in the package.json file cannot be changed: 17 | # https://github.com/npm/npm/pull/3180#issuecomment-16336516 18 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "littlegiant/silverstripe-singleobjectadmin", 3 | "type": "silverstripe-vendormodule", 4 | "description": "Single object administration via a LeftAndMain like interface", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Stevie Mayhew", 9 | "email": "stevie@stevie.co.nz", 10 | "role": "Developer" 11 | }, 12 | { 13 | "name": "Jeremy Bridson", 14 | "email": "jeremy.bridson@littlegiant.co.nz", 15 | "role": "Developer" 16 | } 17 | ], 18 | "require": 19 | { 20 | "silverstripe/framework": "^4.0" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "LittleGiant\\SingleObjectAdmin\\": "src/" 25 | } 26 | }, 27 | "extra": { 28 | "expose": [ 29 | "dist/" 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /templates/LittleGiant/SingleObjectAdmin/SingleObjectAdmin_EditForm.ss: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | <% if $Message %> 5 |

$Message

6 | <% else %> 7 | 8 | <% end_if %> 9 | 10 |
11 | <% if $Legend %>$Legend<% end_if %> 12 | <% loop $Fields %> 13 | $FieldHolder 14 | <% end_loop %> 15 |
16 |
17 |
18 | 19 |
20 | <% if $Actions %> 21 |
22 | <% loop $Actions %> 23 | $Field 24 | <% end_loop %> 25 | <% if $Controller.LinkPreview %> 26 | 27 | <%t SilverStripe\\Admin\\LeftAndMain.PreviewButton 'Preview' %> » 28 | 29 | <% end_if %> 30 |
31 | <% end_if %> 32 |
33 |
34 | -------------------------------------------------------------------------------- /templates/LittleGiant/SingleObjectAdmin/SingleObjectAdmin_Content.ss: -------------------------------------------------------------------------------- 1 |
2 | $Tools 3 | 4 |
5 |
6 |
7 | <% if $BreadcrumbsBackLink %><% end_if %> 8 | <% include SilverStripe\\Admin\\CMSBreadcrumbs %> 9 |
10 | 11 | <% if $EditForm.Fields.hasTabset %> 12 | <% with $EditForm.Fields.fieldByName('Root') %> 13 |
14 | 19 |
20 | <% end_with %> 21 | <% end_if %> 22 |
23 | 24 |
25 | $EditForm 26 |
27 |
28 |
29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SilverStripe Single Object Administration 2 | 3 | Single object administration via a LeftAndMain like interface. Lets your clients edit single objects similar to site config. 4 | 5 | ## Features 6 | 7 | * Single object administration 8 | * Only allows publish functionality for the object 9 | 10 | ## Installation 11 | 12 | Installation via composer 13 | 14 | ```bash 15 | $ composer require littlegiant/silverstripe-singleobjectadmin 16 | ``` 17 | 18 | ## How to use 19 | 20 | Simply extend the SingleObjectAdmin class instead of ModelAdmin and include the class via the `tree_class` static. 21 | 22 | ```php 23 | use LittleGiant\SingleObjectAdmin\SingleObjectAdmin; 24 | 25 | class ProductSettingsAdmin extends SingleObjectAdmin 26 | { 27 | private static $menu_title = "Product Settings"; 28 | private static $tree_class = 'ProductSettings'; 29 | private static $url_segment = "product-settings"; 30 | 31 | } 32 | ``` 33 | 34 | The single object admin assumes you have one and only have one item of the class which you are trying to administrate and 35 | makes no attempt to try and check if this is the case, naively getting the first object which matches. It is up to you 36 | to ensure that the class has one and only one instance created, usually via canCreate() functionality. 37 | 38 | ## License 39 | 40 | The MIT License (MIT) 41 | 42 | Copyright (c) 2015 Little Giant Design Ltd 43 | 44 | Permission is hereby granted, free of charge, to any person obtaining a copy 45 | of this software and associated documentation files (the "Software"), to deal 46 | in the Software without restriction, including without limitation the rights 47 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 48 | copies of the Software, and to permit persons to whom the Software is 49 | furnished to do so, subject to the following conditions: 50 | 51 | The above copyright notice and this permission notice shall be included in 52 | all copies or substantial portions of the Software. 53 | 54 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 55 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 56 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 57 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 58 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 59 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 60 | THE SOFTWARE. 61 | 62 | ## Contributing 63 | 64 | 65 | ### Code guidelines 66 | 67 | This project follows the standards defined in: 68 | 69 | * [PSR-0](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md) 70 | * [PSR-1](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md) 71 | * [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) 72 | -------------------------------------------------------------------------------- /src/SingleObjectAdmin.php: -------------------------------------------------------------------------------- 1 | [ 54 | 'name' => "Access to Single Object Administration", 55 | 'category' => 'CMS Access', 56 | 'help' => 'Allow use of Single Object Administration' 57 | ] 58 | ]; 59 | } 60 | 61 | /** 62 | * @return DataObject 63 | */ 64 | public function getCurrentObject() 65 | { 66 | $objectClass = $this->config()->get('tree_class'); 67 | 68 | /** @var DataObject|Versioned $object */ 69 | $object = $objectClass::get()->first(); 70 | 71 | if ($object && $object->exists()) { 72 | return $object; 73 | } 74 | 75 | $currentStage = Versioned::get_stage(); 76 | Versioned::set_stage('Stage'); 77 | 78 | $object = $objectClass::create(); 79 | $object->write(); 80 | if ($objectClass::has_extension(Versioned::class)) { 81 | $object->publishRecursive(); 82 | } 83 | 84 | Versioned::set_stage($currentStage); 85 | 86 | return $object; 87 | } 88 | 89 | /** 90 | * @return FieldList 91 | */ 92 | public function getCMSActions() 93 | { 94 | $actions = new FieldList(FormAction::create('doSave', 'Save')->addExtraClass('btn-primary font-icon-save')); 95 | 96 | $this->extend('updateCMSActions', $actions); 97 | 98 | return $actions; 99 | } 100 | 101 | /** 102 | * @param null $id Not used. 103 | * @param null $fields Not used. 104 | * 105 | * @return Form 106 | */ 107 | public function getEditForm($id = null, $fields = null) 108 | { 109 | $object = $this->getCurrentObject(); 110 | 111 | $fields = $object->getCMSFields(); 112 | 113 | $fields->push(HiddenField::create('ID', 'ID', $object->ID)); 114 | $fields->push($navField = new LiteralField(SilverStripeNavigator::class, $this->getSilverStripeNavigator())); 115 | $navField->setAllowHTML(true); 116 | 117 | $actions = $this->getCMSActions(); 118 | $negotiator = $this->getResponseNegotiator(); 119 | 120 | // Retrieve validator, if one has been setup 121 | if ($object->hasMethod("getCMSValidator")) { 122 | $validator = $object->getCMSValidator(); 123 | } else { 124 | $validator = null; 125 | } 126 | 127 | $form = Form::create($this, 'EditForm', $fields, $actions, $validator)->setHTMLID('Form_EditForm'); 128 | 129 | $form->setValidationResponseCallback(function (ValidationResult $errors) use ($negotiator, $form) { 130 | $request = $this->getRequest(); 131 | if ($request->isAjax() && $negotiator) { 132 | $result = $form->forTemplate(); 133 | return $negotiator->respond($request, [ 134 | 'CurrentForm' => function () use ($result) { 135 | return $result; 136 | } 137 | ]); 138 | } 139 | }); 140 | 141 | $form->addExtraClass('flexbox-area-grow fill-height cms-content cms-edit-form'); 142 | $form->setAttribute('data-pjax-fragment', 'CurrentForm'); 143 | 144 | if ($form->Fields()->hasTabSet()) { 145 | $form->Fields()->findOrMakeTab('Root')->setTemplate('SilverStripe\\Forms\\CMSTabSet'); 146 | } 147 | 148 | $form->loadDataFrom($object); 149 | $form->setTemplate($this->getTemplatesWithSuffix('_EditForm')); 150 | 151 | // Use