Version 3 end of life
This version of Silverstripe CMS will not recieve any additional bug fixes or documentation updates. Go to documentation for the most recent stable version.

ModelAdmin

ModelAdmin provides a simple way to utilize the SilverStripe Admin UI with your own data models. It can create searchables list and edit views of DataObject subclasses, and even provides import and export of your data.

It uses the framework's knowledge about the model to provide sensible defaults, allowing you to get started in a couple of lines of code, while still providing a solid base for customization.

[info] The interface is mainly powered by the GridField class (documentation), which can also be used in other areas of your application. [/info]

Let's assume we want to manage a simple product listing as a sample data model: A product can have a name, price, and a category.

mysite/code/Product.php

	<?php

	class Product extends DataObject {

		private static $db = array(
			'Name' => 'Varchar',
			'ProductCode' => 'Varchar',
			'Price' => 'Currency'
		);

		private static $has_one = array(
			'Category' => 'Category'
		);
	}
	<?php

	class Category extends DataObject {

		private static $db = array(
			'Title' => 'Text'
		);

		private static $has_many = array(
			'Products' => 'Product'
		);
	}

DataObject's you want to scaffold an interface for. The class can manage multiple models in parallel, if required.

We'll name it MyAdmin, but the class name can be anything you want.

mysite/code/MyAdmin.php

	<?php

	class MyAdmin extends ModelAdmin {

		private static $managed_models = array(
			'Product',
			'Category'
		);

		private static $url_segment = 'products';

		private static $menu_title = 'My Product Admin';
	}

users will be able to upload and manage Product and Category instances through http://yoursite.com/admin/products.

[alert] After defining these classes, make sure you have rebuilt your SilverStripe database and flushed your cache. [/alert]

Permissions

Each new ModelAdmin subclass creates its' own permission code, for the example above this would be CMS_ACCESS_MyAdmin. Users with access to the Admin UI will need to have this permission assigned through admin/security/ or have the ADMIN permission code in order to gain access to the controller.

[notice] For more information on the security and permission system see the Security Documentation [/notice]

The DataObject API has more granular permission control, which is enforced in ModelAdmin by default. Available checks are canEdit(), canCreate(), canView() and canDelete(). Models check for administrator permissions by default. For most cases, less restrictive checks make sense, e.g. checking for general CMS access rights.

mysite/code/Category.php

	<?php

	class Category extends DataObject {
	  // ...
		public function canView($member = null) {
			return Permission::check('CMS_ACCESS_MyAdmin', 'any', $member);
		}

		public function canEdit($member = null) {
			return Permission::check('CMS_ACCESS_MyAdmin', 'any', $member);
		}

		public function canDelete($member = null) {
			return Permission::check('CMS_ACCESS_MyAdmin', 'any', $member);
		}

		public function canCreate($member = null) {
			return Permission::check('CMS_ACCESS_MyAdmin', 'any', $member);
		}

ModelAdmin uses the SearchContext class to provide a search form, as well as get the searched results. Every DataObject can have its own context, based on the fields which should be searchable. The class makes a guess at how those fields should be searched, e.g. showing a checkbox for any boolean fields in your $db definition.

To remove, add or modify searchable fields, define a new DataObject::$searchable_fields static on your model class (see SearchContext docs for details).

mysite/code/Product.php

	<?php

	class Product extends DataObject {

	   private static $searchable_fields = array(
	      'Name',
	      'ProductCode'
	   );
	}

SearchContext documentation has more information on providing the search functionality. [/hint]

Displaying Results

The results are shown in a tabular listing, powered by the GridField, more specifically the GridFieldDataColumns component. This component looks for a DataObject::$summary_fields static on your model class, where you can add or remove columns. To change the title, use DataObject::$field_labels.

mysite/code/Product.php

	<?php

	class Product extends DataObject {

	   private static $field_labels = array(
	      'Price' => 'Cost' // renames the column to "Cost"
	   );

	   private static $summary_fields = array(
	      'Name',
	      'Price'
	   );
	}

form. If no search parameters are given, the results will show every record. Results are a DataList instance, so can be customised by additional SQL filters, joins.

For example, we might want to exclude all products without prices in our sample MyAdmin implementation.

mysite/code/MyAdmin.php

	<?php

	class MyAdmin extends ModelAdmin {

		public function getList() {
			$list = parent::getList();

			// Always limit by model class, in case you're managing multiple
			if($this->modelClass == 'Product') {
				$list = $list->exclude('Price', '0');
			}

			return $list;
		}
	}

checkbox which limits search results to expensive products (over $100).

mysite/code/MyAdmin.php

	<?php

	class MyAdmin extends ModelAdmin {

		public function getSearchContext() {
			$context = parent::getSearchContext();

			if($this->modelClass == 'Product') {
				$context->getFields()->push(new CheckboxField('q[ExpensiveOnly]', 'Only expensive stuff'));
			}

			return $context;
		}

		public function getList() {
			$list = parent::getList();

			$params = $this->getRequest()->requestVar('q'); // use this to access search parameters

			if($this->modelClass == 'Product' && isset($params['ExpensiveOnly']) && $params['ExpensiveOnly']) {
				$list = $list->exclude('Price:LessThan', '100');
			}

			return $list;
		}
	}

example, to add a new component.

mysite/code/MyAdmin.php

	<?php

	class MyAdmin extends ModelAdmin {

		private static $managed_models = array(
			'Product',
			'Category'
		);

		// ...
		public function getEditForm($id = null, $fields = null) {
			$form = parent::getEditForm($id, $fields);

			// $gridFieldName is generated from the ModelClass, eg if the Class 'Product'
			// is managed by this ModelAdmin, the GridField for it will also be named 'Product'

			$gridFieldName = $this->sanitiseClassName($this->modelClass);
			$gridField = $form->Fields()->fieldByName($gridFieldName);

			// modify the list view.
			$gridField->getConfig()->addComponent(new GridFieldFilterHeader());

			return $form;
		}
	}

to only one specific GridField:

mysite/code/MyAdmin.php

	<?php

	class MyAdmin extends ModelAdmin {

		private static $managed_models = array(
			'Product',
			'Category'
		);

		public function getEditForm($id = null, $fields = null) {
			$form = parent::getEditForm($id, $fields);

			$gridFieldName = 'Product';
			$gridField = $form->Fields()->fieldByName($gridFieldName);

			if ($gridField) {
				$gridField->getConfig()->addComponent(new GridFieldFilterHeader());
			}

			return $form;
		}
	}

The ModelAdmin class provides import of CSV files through the CsvBulkLoader API. which has support for column mapping, updating existing records, and identifying relationships - so its a powerful tool to get your data into a SilverStripe database.

By default, each model management interface allows uploading a CSV file with all columns auto detected. To override with a more specific importer implementation, use the ModelAdmin::$model_importers static.

Data Export

Export is available as a CSV format through a button at the end of a results list. You can also export search results. This is handled through the GridFieldExportButton component.

To customise the exported columns, create a new method called getExportFields in your ModelAdmin:

	<?php

	class MyAdmin extends ModelAdmin {
		// ...

		public function getExportFields() {
			return array(
				'Name' => 'Name',
				'ProductCode' => 'Product Code',
				'Category.Title' => 'Category'
			);
		}
	}

Related Documentation

API Documentation