handle(); * } * * and add an AddToCampaignHandler_FormAction to the EditForm, possibly through getCMSActions */ class AddToCampaignHandler { use Injectable; /** * Parent controller for this form * * @var Controller */ protected $controller; /** * The submitted form data * * @var array */ protected $data; /** * Form name to use * * @var string */ protected $name; protected $showTitle = true; /** * AddToCampaignHandler constructor. * * @param Controller $parentController Controller for this form * @param array|DataObject $data The data submitted as part of that form * @param string $name Form name */ public function __construct($controller = null, $data = [], $name = 'AddToCampaignForm') { $this->controller = $controller; if ($data instanceof DataObject) { $data = $data->toMap(); } $this->data = $data; $this->name = $name; } public function setShowTitle($show) { $this->showTitle = $show; } /** * Perform the action. Either returns a Form or performs the action, as per the class doc * * @return DBHTMLText|SS_HTTPResponse */ public function handle() { $object = $this->getObject($this->data['ID'], $this->data['ClassName']); if (empty($this->data['Campaign'])) { return $this->Form($object)->forTemplate(); } else { return $this->addToCampaign($object, $this->data['Campaign']); } } /** * Get what ChangeSets are available for an item to be added to by this user * * @return ArrayList[ChangeSet] */ protected function getAvailableChangeSets() { return ChangeSet::get() ->filter('State', ChangeSet::STATE_OPEN) ->filterByCallback(function($item) { /** @var ChangeSet $item */ return $item->canView(); }); } /** * Safely get a DataObject from a client-supplied ID and ClassName, checking: argument * validity; existence; and canView permissions. * * @param int $id The ID of the DataObject * @param string $class The Class of the DataObject * @return DataObject The referenced DataObject * @throws SS_HTTPResponse_Exception */ protected function getObject($id, $class) { $id = (int)$id; $class = ClassInfo::class_name($class); if (!$class || !is_subclass_of($class, 'SilverStripe\\ORM\\DataObject') || !Object::has_extension($class, 'SilverStripe\\ORM\\Versioning\\Versioned')) { $this->controller->httpError(400, _t( 'AddToCampaign.ErrorGeneral', 'We apologise, but there was an error' )); return null; } $object = DataObject::get($class)->byID($id); if (!$object) { $this->controller->httpError(404, _t( 'AddToCampaign.ErrorNotFound', 'That {Type} couldn\'t be found', '', ['Type' => $class] )); return null; } if (!$object->canView()) { $this->controller->httpError(403, _t( 'AddToCampaign.ErrorItemPermissionDenied', 'It seems you don\'t have the necessary permissions to add {ObjectTitle} to a campaign', '', ['ObjectTitle' => $object->Title] ) ); return null; } return $object; } /** * Builds a Form that mirrors the parent editForm, but with an extra field to collect the ChangeSet ID * * @param DataObject $object The object we're going to be adding to whichever ChangeSet is chosen * @return Form */ public function Form($object) { $inChangeSets = array_unique(ChangeSetItem::get_for_object($object)->column('ChangeSetID')); $changeSets = $this->getAvailableChangeSets()->map(); $campaignDropdown = DropdownField::create('Campaign', '', $changeSets); $campaignDropdown->setEmptyString(_t('Campaigns.AddToCampaignFormFieldLabel', 'Select a Campaign')); $campaignDropdown->addExtraClass('noborder'); $campaignDropdown->setDisabledItems($inChangeSets); $fields = new FieldList([ $campaignDropdown, HiddenField::create('ID', null, $this->data['ID']), HiddenField::create('ClassName', null, $this->data['ClassName']) ]); if ($this->showTitle) { $fields = new FieldList( $header = new CompositeField( new LiteralField( 'Heading', sprintf('