mirror of
https://github.com/silverstripe/silverstripe-cms
synced 2024-10-22 06:05:56 +00:00
Remove hardcoded references to pages and SiteTree Remove assumption that records are versioned Remove or validate assumptions about methods on the model class Improve general architecture of CMSMain
224 lines
9.1 KiB
PHP
224 lines
9.1 KiB
PHP
<?php
|
|
|
|
namespace SilverStripe\CMS\Forms;
|
|
|
|
use SilverStripe\CMS\Controllers\CMSMain;
|
|
use SilverStripe\CMS\Controllers\CMSPageEditController;
|
|
use SilverStripe\CMS\Model\SiteTree;
|
|
use SilverStripe\Control\HTTPResponse;
|
|
use SilverStripe\Core\Config\Config;
|
|
use SilverStripe\Core\Convert;
|
|
use SilverStripe\Forms\FieldList;
|
|
use SilverStripe\Forms\Form;
|
|
use SilverStripe\Forms\FormAction;
|
|
use SilverStripe\Forms\LiteralField;
|
|
use SilverStripe\Forms\OptionsetField;
|
|
use SilverStripe\Forms\SelectionGroup;
|
|
use SilverStripe\Forms\SelectionGroup_Item;
|
|
use SilverStripe\Forms\TreeDropdownField;
|
|
use SilverStripe\ORM\DataObject;
|
|
use SilverStripe\ORM\FieldType\DBField;
|
|
use SilverStripe\Security\Security;
|
|
use SilverStripe\SiteConfig\SiteConfig;
|
|
|
|
class CMSMainAddForm extends Form
|
|
{
|
|
public function __construct(CMSMain $controller)
|
|
{
|
|
$modelClass = $controller->getModelClass();
|
|
$pageTypes = [];
|
|
$defaultIcon = Config::inst()->get($modelClass, 'icon_class'); // @TODO need a better place for default - maybe try default on class, and fallback to default on cmsmain?
|
|
|
|
foreach ($controller->RecordTypes() as $type) {
|
|
$class = $type->getField('ClassName');
|
|
$icon = Config::inst()->get($class, 'icon_class') ?: $defaultIcon;
|
|
|
|
// If the icon is the default and there's some specific icon being provided by `getPageIconURL`
|
|
// then we don't need to add the icon class. Otherwise the class take precedence.
|
|
if ($icon === $defaultIcon && !empty(singleton($class)->getPageIconURL())) {
|
|
$icon = '';
|
|
}
|
|
|
|
$html = sprintf(
|
|
'<span class="page-icon %s class-%s"></span><span class="title">%s</span><span class="form__field-description">%s</span>',
|
|
$icon,
|
|
Convert::raw2htmlid($class),
|
|
$type->getField('AddAction'),
|
|
$type->getField('Description')
|
|
);
|
|
$pageTypes[$class] = DBField::create_field('HTMLFragment', $html);
|
|
}
|
|
// Ensure generic page type shows on top
|
|
if (isset($pageTypes['Page'])) {
|
|
$pageTitle = $pageTypes['Page'];
|
|
$pageTypes = array_merge(['Page' => $pageTitle], $pageTypes);
|
|
}
|
|
|
|
$numericLabelTmpl = '<span class="step-label"><span class="flyout">Step %d. </span><span class="title">%s</span></span>';
|
|
|
|
$topTitle = _t(__CLASS__ . '.ParentMode_top', 'Top level');
|
|
$childTitle = _t(
|
|
__CLASS__ . '.ParentMode_child',
|
|
'Under another {type}',
|
|
['type' => mb_strtolower(DataObject::singleton($modelClass)->i18n_singular_name())]
|
|
);
|
|
|
|
$fields = FieldList::create(
|
|
$parentModeField = SelectionGroup::create(
|
|
'ParentModeField',
|
|
[
|
|
$topField = SelectionGroup_Item::create(
|
|
'top',
|
|
null,
|
|
$topTitle
|
|
),
|
|
SelectionGroup_Item::create(
|
|
'child',
|
|
$parentField = TreeDropdownField::create(
|
|
'ParentID',
|
|
'',
|
|
$modelClass,
|
|
'ID',
|
|
'TreeTitle'
|
|
),
|
|
$childTitle
|
|
)
|
|
]
|
|
),
|
|
LiteralField::create(
|
|
'RestrictedNote',
|
|
sprintf(
|
|
'<p class="alert alert-info message-restricted">%s</p>',
|
|
_t(
|
|
'SilverStripe\\CMS\\Controllers\\CMSMain.AddPageRestriction',
|
|
'Note: Some page types are not allowed for this selection'
|
|
)
|
|
)
|
|
),
|
|
OptionsetField::create(
|
|
'PageType',
|
|
DBField::create_field(
|
|
'HTMLFragment',
|
|
sprintf($numericLabelTmpl ?? '', 2, _t('SilverStripe\\CMS\\Controllers\\CMSMain.ChoosePageType', 'Choose page type'))
|
|
),
|
|
$pageTypes,
|
|
'Page'
|
|
)
|
|
);
|
|
|
|
$parentModeField->setTitle(DBField::create_field(
|
|
'HTMLFragment',
|
|
sprintf($numericLabelTmpl ?? '', 1, _t('SilverStripe\\CMS\\Controllers\\CMSMain.ChoosePageParentMode', 'Choose where to create this page'))
|
|
));
|
|
|
|
$parentField->setSearchFunction(function ($sourceObject, $labelField, $search) {
|
|
return DataObject::get($sourceObject)
|
|
->filterAny([
|
|
'MenuTitle:PartialMatch' => $search,
|
|
'Title:PartialMatch' => $search,
|
|
]);
|
|
});
|
|
|
|
$parentModeField->addExtraClass('parent-mode');
|
|
|
|
// CMSMain->currentRecordID() automatically sets the homepage,
|
|
// which we need to counteract in the default selection (which should default to root, ID=0)
|
|
if ($parentID = $controller->getRequest()->getVar('ParentID')) {
|
|
$parentModeField->setValue('child');
|
|
$parentField->setValue((int)$parentID);
|
|
} else {
|
|
$parentModeField->setValue('top');
|
|
}
|
|
|
|
// Check if the current user has enough permissions to create top level pages
|
|
// If not, then disable the option to do that
|
|
if (is_a($modelClass, SiteTree::class, true) && !SiteConfig::current_site_config()->canCreateTopLevel()) { // @TODO probably need to make this generic
|
|
$topField->setDisabled(true);
|
|
$parentModeField->setValue('child');
|
|
}
|
|
|
|
$actions = FieldList::create(
|
|
FormAction::create('doAdd', _t('SilverStripe\\CMS\\Controllers\\CMSMain.Create', 'Create'))
|
|
->addExtraClass('btn-primary font-icon-plus-circled')
|
|
->setUseButtonTag(true),
|
|
FormAction::create('doCancel', _t('SilverStripe\\CMS\\Controllers\\CMSMain.Cancel', 'Cancel'))
|
|
->addExtraClass('btn-secondary')
|
|
->setUseButtonTag(true)
|
|
);
|
|
|
|
$controller->extend('updatePageOptions', $fields);
|
|
|
|
parent::__construct($controller, 'AddForm', $fields, $actions);
|
|
|
|
$negotiator = $controller->getResponseNegotiator();
|
|
$this->setHTMLID('Form_AddForm')->setStrictFormMethodCheck(false);
|
|
$this->setAttribute('data-hints', $controller->TreeHints());
|
|
$this->setAttribute('data-childfilter', $controller->Link('childfilter'));
|
|
$this->setValidationResponseCallback(function () use ($negotiator, $controller) {
|
|
$request = $controller->getRequest();
|
|
if ($request->isAjax() && $negotiator) {
|
|
$result = $this->forTemplate();
|
|
return $negotiator->respond($request, [
|
|
'CurrentForm' => function () use ($result) {
|
|
return $result;
|
|
}
|
|
]);
|
|
}
|
|
return null;
|
|
});
|
|
$this->addExtraClass('flexbox-area-grow fill-height cms-add-form cms-content cms-edit-form ' . $controller->BaseCSSClasses());
|
|
$this->setTemplate($controller->getTemplatesWithSuffix('_AddForm'));
|
|
}
|
|
|
|
public function doAdd(array $data, Form $form): HTTPResponse
|
|
{
|
|
$controller = $this->getController();
|
|
$modelClass = $controller->getModelClass();
|
|
$className = isset($data['PageType']) ? $data['PageType'] : "Page";
|
|
$parentID = isset($data['ParentID']) ? (int)$data['ParentID'] : 0;
|
|
|
|
if (!$parentID && isset($data['Parent'])) {
|
|
$page = $modelClass::get_by_link($data['Parent']); // @TODO Obviously no good
|
|
if ($page) {
|
|
$parentID = $page->ID;
|
|
}
|
|
}
|
|
|
|
if (is_numeric($parentID) && $parentID > 0) {
|
|
$parentObj = DataObject::get($modelClass)->byID($parentID);
|
|
} else {
|
|
$parentObj = null;
|
|
}
|
|
|
|
if (!$parentObj || !$parentObj->ID) {
|
|
$parentID = 0;
|
|
}
|
|
|
|
if (!singleton($className)->canCreate(Security::getCurrentUser(), ['Parent' => $parentObj])) {
|
|
return Security::permissionFailure($controller);
|
|
}
|
|
|
|
$record = $controller->getNewItem("new-$className-$parentID", false);
|
|
$controller->extend('updateDoAdd', $record, $form);
|
|
$record->write();
|
|
|
|
$editController = CMSPageEditController::singleton();
|
|
$editController->setRequest($controller->getRequest());
|
|
$editController->setCurrentRecordID($record->ID);
|
|
|
|
$session = $this->getRequest()->getSession();
|
|
$session->set(
|
|
"FormInfo.Form_EditForm.formError.message",
|
|
_t('SilverStripe\\CMS\\Controllers\\CMSMain.PageAdded', 'Successfully created page')
|
|
);
|
|
$session->set("FormInfo.Form_EditForm.formError.type", 'good');
|
|
|
|
return $controller->redirect($editController->Link('show/' . $record->ID));
|
|
}
|
|
|
|
public function doCancel(): HTTPResponse
|
|
{
|
|
return $this->getController()->redirect(CMSMain::singleton()->Link()); // @TODO when there's no CMSPageEditController anymore, change this to $this->getController()->Link()
|
|
}
|
|
}
|