silverstripe-cms/code/Forms/CMSMainAddForm.php

224 lines
9.1 KiB
PHP
Raw Normal View History

<?php
namespace SilverStripe\CMS\Forms;
2016-07-22 11:32:32 +12:00
use SilverStripe\CMS\Controllers\CMSMain;
use SilverStripe\CMS\Controllers\CMSPageEditController;
use SilverStripe\CMS\Model\SiteTree;
2016-09-09 11:26:24 +12:00
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
2017-01-26 09:59:25 +13:00
{
public function __construct(CMSMain $controller)
2017-01-26 09:59:25 +13:00
{
$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 = '';
}
2017-01-26 09:59:25 +13:00
$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),
2017-01-26 09:59:25 +13:00
$type->getField('AddAction'),
$type->getField('Description')
);
$pageTypes[$class] = DBField::create_field('HTMLFragment', $html);
2017-01-26 09:59:25 +13:00
}
// Ensure generic page type shows on top
if (isset($pageTypes['Page'])) {
$pageTitle = $pageTypes['Page'];
$pageTypes = array_merge(['Page' => $pageTitle], $pageTypes);
2017-01-26 09:59:25 +13:00
}
$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())]
);
2017-01-26 09:59:25 +13:00
$fields = FieldList::create(
$parentModeField = SelectionGroup::create(
'ParentModeField',
[
$topField = SelectionGroup_Item::create(
'top',
2017-01-26 09:59:25 +13:00
null,
$topTitle
),
SelectionGroup_Item::create(
2017-01-26 09:59:25 +13:00
'child',
$parentField = TreeDropdownField::create(
'ParentID',
'',
$modelClass,
2017-01-26 09:59:25 +13:00
'ID',
'TreeTitle'
),
$childTitle
)
]
2017-01-26 09:59:25 +13:00
),
LiteralField::create(
2017-01-26 09:59:25 +13:00
'RestrictedNote',
sprintf(
'<p class="alert alert-info message-restricted">%s</p>',
2017-01-26 09:59:25 +13:00
_t(
2017-04-20 13:15:29 +12:00
'SilverStripe\\CMS\\Controllers\\CMSMain.AddPageRestriction',
2017-01-26 09:59:25 +13:00
'Note: Some page types are not allowed for this selection'
)
)
),
OptionsetField::create(
'PageType',
2017-01-26 09:59:25 +13:00
DBField::create_field(
'HTMLFragment',
2022-04-13 17:07:59 +12:00
sprintf($numericLabelTmpl ?? '', 2, _t('SilverStripe\\CMS\\Controllers\\CMSMain.ChoosePageType', 'Choose page type'))
2017-01-26 09:59:25 +13:00
),
$pageTypes,
'Page'
)
);
$parentModeField->setTitle(DBField::create_field(
'HTMLFragment',
2022-04-13 17:07:59 +12:00
sprintf($numericLabelTmpl ?? '', 1, _t('SilverStripe\\CMS\\Controllers\\CMSMain.ChoosePageParentMode', 'Choose where to create this page'))
2017-01-26 09:59:25 +13:00
));
$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,
2017-01-26 09:59:25 +13:00
// which we need to counteract in the default selection (which should default to root, ID=0)
if ($parentID = $controller->getRequest()->getVar('ParentID')) {
2017-01-26 09:59:25 +13:00
$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'))
2017-01-26 09:59:25 +13:00
->addExtraClass('btn-primary font-icon-plus-circled')
->setUseButtonTag(true),
FormAction::create('doCancel', _t('SilverStripe\\CMS\\Controllers\\CMSMain.Cancel', 'Cancel'))
2017-01-26 09:59:25 +13:00
->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();
2017-01-26 09:59:25 +13:00
if ($request->isAjax() && $negotiator) {
$result = $this->forTemplate();
return $negotiator->respond($request, [
2017-01-26 09:59:25 +13:00
'CurrentForm' => function () use ($result) {
return $result;
}
]);
2017-01-26 09:59:25 +13:00
}
return null;
});
$this->addExtraClass('flexbox-area-grow fill-height cms-add-form cms-content cms-edit-form ' . $controller->BaseCSSClasses());
$this->setTemplate($controller->getTemplatesWithSuffix('_AddForm'));
2017-01-26 09:59:25 +13:00
}
public function doAdd(array $data, Form $form): HTTPResponse
2017-01-26 09:59:25 +13:00
{
$controller = $this->getController();
$modelClass = $controller->getModelClass();
2017-01-26 09:59:25 +13:00
$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
2017-01-26 09:59:25 +13:00
if ($page) {
$parentID = $page->ID;
}
}
if (is_numeric($parentID) && $parentID > 0) {
$parentObj = DataObject::get($modelClass)->byID($parentID);
2017-01-26 09:59:25 +13:00
} else {
$parentObj = null;
}
if (!$parentObj || !$parentObj->ID) {
$parentID = 0;
}
if (!singleton($className)->canCreate(Security::getCurrentUser(), ['Parent' => $parentObj])) {
return Security::permissionFailure($controller);
2017-01-26 09:59:25 +13:00
}
$record = $controller->getNewItem("new-$className-$parentID", false);
$controller->extend('updateDoAdd', $record, $form);
2017-01-26 09:59:25 +13:00
$record->write();
$editController = CMSPageEditController::singleton();
$editController->setRequest($controller->getRequest());
$editController->setCurrentRecordID($record->ID);
2017-01-26 09:59:25 +13:00
2017-06-08 18:02:18 +12:00
$session = $this->getRequest()->getSession();
$session->set(
2017-01-26 09:59:25 +13:00
"FormInfo.Form_EditForm.formError.message",
2017-04-20 13:15:29 +12:00
_t('SilverStripe\\CMS\\Controllers\\CMSMain.PageAdded', 'Successfully created page')
2017-01-26 09:59:25 +13:00
);
2017-06-08 18:02:18 +12:00
$session->set("FormInfo.Form_EditForm.formError.type", 'good');
2017-01-26 09:59:25 +13:00
return $controller->redirect($editController->Link('show/' . $record->ID));
2017-01-26 09:59:25 +13:00
}
public function doCancel(): HTTPResponse
2017-01-26 09:59:25 +13:00
{
return $this->getController()->redirect(CMSMain::singleton()->Link()); // @TODO when there's no CMSPageEditController anymore, change this to $this->getController()->Link()
2017-01-26 09:59:25 +13:00
}
}