/**
  * Prevent duplicate code being entered.
  *
  * @param \ValidationResult $result
  * @return array|void
  * @throws \ValidationException
  */
 public function validate(ValidationResult $result)
 {
     // this could throw an exception, let it
     parent::validate($result);
     $code = $this->owner->{self::CodeFieldName};
     if ($this->owner->isInDB()) {
         // code should be read-only in CMS but check anyway that doesn't exist on another ID
         $existing = Model::get($this->owner->class)->exclude('ID', $this->owner->ID)->filter(self::CodeFieldName, $code)->first();
     } else {
         // check code doesn't exist already
         $existing = Model::get($this->owner->class)->filter(self::CodeFieldName, $code)->first();
     }
     if ($existing) {
         $message = $this->fieldDecoration(self::CodeFieldName, 'Duplicate', "Code must be unique, the {singular} '{title}' already uses '{code}'", ['code' => $code, 'title' => $existing->Title ?: $existing->Name]);
         $result->error($message);
         throw new ValidationException($result);
     }
 }
 /**
  * If we don't already have an associated block then create and attach one (BlockType is the class selector). If we do
  * have an associated block then check it is of correct class, if not re-create and relate it as correct Class. It will leave dangling
  * blocks.
  *
  * We do this because initially only a single Block of constrained Class (type) can be created, however doing it this way enables us
  * to keep templates clean via Blocks interface and possibly easier change later to more than one block or new block types.
  */
 public function onBeforeWrite()
 {
     // just get the data for this extension when creating blocks.
     $blockData = $this()->extendedFieldData();
     // block type is either the class of the current block or the BlockTypeField name which is not in the DB but submitted by CMS form.
     $blockType = $this->getBlockType();
     /** @var Model $block */
     if (!($block = $this()->Block())) {
         // create a new related block
         $block = Model::create($blockType, $blockData);
         $this()->BlockID = $block->write();
     } else {
         if ($block->ClassName != $blockType) {
             /** @var Block $newBlock */
             $block = $blockType::create($blockData);
             // force insert
             $this()->BlockID = $block->write(false, true);
             // this will leave dangling blocks
         } else {
             $block->update($blockData);
             $block->write();
         }
     }
 }
 public function getCMSFields()
 {
     $fields = parent::getCMSFields();
     $fields->replaceField('Sort', new \ReadonlyField('Sort', 'Sort order'));
     return $fields;
 }
 public function getCMSFields()
 {
     $fields = parent::getCMSFields();
     $fields->replaceField(self::SortFieldName, new \HiddenField(self::SortFieldName));
     return $fields;
 }