Version 6 pre-stable
This version of Silverstripe CMS has not yet been given a stable release. See the release roadmap for more information. Go to documentation for the most recent stable version.

Single-record admin sections

The SingleRecordAdmin class lets you create an admin section which presents an edit form for a single record. Unlike ModelAdmin, there's no UI mechanism in a SingleRecordAdmin to swap what record you're editing.

The main use cases for using SingleRecordAdmin are for a settings section (where a single record holds all the settings needed for that section), or editing a record that is unique for each signed-in user (such as that user's profile).

namespace App\Admin;

use App\Model\MySettingsModel;
use SilverStripe\Admin\SingleRecordAdmin;

class MySettingsAdmin extends SingleRecordAdmin
{
    private static $url_segment = 'my-settings';

    private static $menu_title = 'My Settings';

    private static $model_class = MySettingsModel::class;
}

This admin section will fetch a record of the MySettingsModel class using the get_one() method.

If you don't want the admin section to fetch your record in this way, you can set the restrict_to_single_record configuration property to false. In this case you must provide another way for the admin section to know which record to edit. This could be in the form of a separate action on the controller (e.g. edit/$ID), or by calling setCurrentRecordID() in the init() method of the controller.

If there's no record to edit, by default it will create one for you. To disable that behaviour, set the allow_new_record configuration property to false.

If you need more complex behaviour to fetch your record, for example you use the silverstripe/subsites or tractorcow/silverstripe-fluent module, you could either override the getSingleRecord() method, or you could create an extension that implements the augmentSQL() extension hook.

The latter option is the most flexible, as it affects all high-level ORM queries for your model which ensures consistency when fetching the record from other areas of your code.

For records that hold settings, it's common to provide a static method to get the current settings record. Below is a basic example.

namespace App\Model;

use SilverStripe\ORM\DataObject;

class MySettingsModel extends DataObject
{
    // ...

    /**
     * Get the current settings record
     */
    public static function currentRecord(): MySettingsModel
    {
        $record = MySettingsModel::get_one();
        if (!$record) {
            $record = MySettingsModel::create();
            $record->write(skipValidation: true);
        }
        return $record;
    }
}