mirror of
https://github.com/silverstripe/silverstripe-reports
synced 2024-10-22 11:05:53 +02:00
API CHANGE Moved CMSMain/AssetAdmin/SecurityAdmin implementations for getEditForm() and save() to a common parent: LeftAndMain
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@92834 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
9d0954e129
commit
45f87288fc
@ -261,61 +261,11 @@ HTML;
|
|||||||
public function currentPage() {
|
public function currentPage() {
|
||||||
$id = $this->currentPageID();
|
$id = $this->currentPageID();
|
||||||
if($id && is_numeric($id)) {
|
if($id && is_numeric($id)) {
|
||||||
return DataObject::get_by_id($this->stat('tree_class'), $id);
|
return DataObject::get_by_id('File', $id);
|
||||||
} else if($id == 'root') {
|
} else if($id == 'root') {
|
||||||
return singleton($this->stat('tree_class'));
|
return singleton('File');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Form
|
|
||||||
*/
|
|
||||||
function EditForm($request = null) {
|
|
||||||
return $this->getEditForm();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the form that displays the details of a folder, including a file list and fields for editing the folder name.
|
|
||||||
*/
|
|
||||||
function getEditForm($id = null) {
|
|
||||||
if(!$id) $id = $this->currentPageID();
|
|
||||||
|
|
||||||
$record = ($id && $id != "root") ? DataObject::get_by_id("File", $id) : null;
|
|
||||||
if($record && !$record->canView()) return Security::permissionFailure($this);
|
|
||||||
|
|
||||||
if($record) {
|
|
||||||
$fields = $record->getCMSFields();
|
|
||||||
// Required for file tree setup
|
|
||||||
if(!$fields->dataFieldByName('ParentID')) $fields->push(new HiddenField('ParentID'));
|
|
||||||
|
|
||||||
$actions = new FieldSet();
|
|
||||||
|
|
||||||
// Only show save button if not 'assets' folder
|
|
||||||
if($record->canEdit() && $id != 'root') {
|
|
||||||
$actions = new FieldSet(
|
|
||||||
new FormAction('save',_t('AssetAdmin.SAVEFOLDERNAME','Save folder name'))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$form = new Form($this, "EditForm", $fields, $actions);
|
|
||||||
if($record->ID) {
|
|
||||||
$form->loadDataFrom($record);
|
|
||||||
} else {
|
|
||||||
$form->loadDataFrom(array(
|
|
||||||
"ID" => "root",
|
|
||||||
"URL" => Director::absoluteBaseURL() . 'assets/',
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$record->canEdit()) {
|
|
||||||
$form->makeReadonly();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$form = $this->EmptyForm();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $form;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the entire site tree as a nested UL.
|
* Return the entire site tree as a nested UL.
|
||||||
@ -377,7 +327,7 @@ HTML;
|
|||||||
* @return Form
|
* @return Form
|
||||||
*/
|
*/
|
||||||
function AddForm() {
|
function AddForm() {
|
||||||
$typeMap = array('Folder' => singleton('Folder')->i18n_singular_name());
|
$typeMap = array('Folder' => singleton($this->stat('tree_class'))->i18n_singular_name());
|
||||||
$typeField = new DropdownField('Type', false, $typeMap, 'Folder');
|
$typeField = new DropdownField('Type', false, $typeMap, 'Folder');
|
||||||
$form = new Form(
|
$form = new Form(
|
||||||
$this,
|
$this,
|
||||||
@ -451,19 +401,7 @@ HTML;
|
|||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save($urlParams, $form) {
|
|
||||||
// Don't save the root folder - there's no database record
|
|
||||||
if($_REQUEST['ID'] == 'root') {
|
|
||||||
FormResponse::status_message('Saved', 'good');
|
|
||||||
return FormResponse::respond();
|
|
||||||
}
|
|
||||||
|
|
||||||
$form->dataFieldByName('Title')->value = $form->dataFieldByName('Name')->value;
|
|
||||||
|
|
||||||
return parent::save($urlParams, $form);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* #################################
|
* #################################
|
||||||
* Garbage collection.
|
* Garbage collection.
|
||||||
|
154
code/CMSMain.php
154
code/CMSMain.php
@ -309,13 +309,6 @@ JS;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Form
|
|
||||||
*/
|
|
||||||
function EditForm($request = null) {
|
|
||||||
return $this->getEditForm();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls {@link SiteTree->getCMSFields()}
|
* Calls {@link SiteTree->getCMSFields()}
|
||||||
*/
|
*/
|
||||||
@ -323,16 +316,16 @@ JS;
|
|||||||
// Include JavaScript to ensure HtmlEditorField works.
|
// Include JavaScript to ensure HtmlEditorField works.
|
||||||
HtmlEditorField::include_js();
|
HtmlEditorField::include_js();
|
||||||
|
|
||||||
if(!$id) $id = $this->currentPageID();
|
$form = parent::getEditForm($id);
|
||||||
|
|
||||||
$record = ($id) ? $this->getRecord($id) : null;
|
// TODO Duplicate record fetching (see parent implementation)
|
||||||
if($record && !$record->canView()) return Security::permissionFailure($this);
|
if(!$id) $id = $this->currentPageID();
|
||||||
|
$record = ($id && $id != "root") ? DataObject::get_by_id($this->stat('tree_class'), $id) : null;
|
||||||
|
|
||||||
|
$fields = $form->Fields();
|
||||||
|
$actions = $form->Actions();
|
||||||
|
|
||||||
if($record) {
|
if($record) {
|
||||||
$fields = $record->getCMSFields($this);
|
|
||||||
if ($fields == null) {
|
|
||||||
user_error("getCMSFields returned null on a '".get_class($record)."' object - it should return a FieldSet object. Perhaps you forgot to put a return statement at the end of your method?", E_USER_ERROR);
|
|
||||||
}
|
|
||||||
$fields->push($idField = new HiddenField("ID", false, $id));
|
$fields->push($idField = new HiddenField("ID", false, $id));
|
||||||
$fields->push($liveURLField = new HiddenField("LiveURLSegment"));
|
$fields->push($liveURLField = new HiddenField("LiveURLSegment"));
|
||||||
$fields->push($stageURLField = new HiddenField("StageURLSegment"));
|
$fields->push($stageURLField = new HiddenField("StageURLSegment"));
|
||||||
@ -349,47 +342,15 @@ JS;
|
|||||||
$stageURLField->setValue($record->AbsoluteLink());
|
$stageURLField->setValue($record->AbsoluteLink());
|
||||||
}
|
}
|
||||||
|
|
||||||
// getAllCMSActions can be used to completely redefine the action list
|
$deleteAction = new FormAction(
|
||||||
if($record->hasMethod('getAllCMSActions')) {
|
'delete',
|
||||||
$actions = $record->getAllCMSActions();
|
_t('CMSMain.DELETE','Delete from the draft site')
|
||||||
} else {
|
);
|
||||||
$actions = $record->getCMSActions();
|
$deleteAction->addExtraClass('delete');
|
||||||
// add default actions if none are defined
|
$actions->insertBefore($deleteAction, 'action_save');
|
||||||
if(!$actions || !$actions->Count()) {
|
|
||||||
if($record->canEdit()) {
|
|
||||||
$actions->push(new FormAction('save',_t('CMSMain.SAVE','Save')));
|
|
||||||
$actions->push($deleteAction = new FormAction('delete',_t('CMSMain.DELETE','Delete from the draft site')));
|
|
||||||
$deleteAction->addExtraClass('delete');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$form = new Form($this, "EditForm", $fields, $actions);
|
if($record->IsDeletedFromStage) {
|
||||||
$form->loadDataFrom($record);
|
$form->makeReadonly();
|
||||||
$form->disableDefaultAction();
|
|
||||||
|
|
||||||
// Add a default or custom validator.
|
|
||||||
// @todo Currently the default Validator.js implementation
|
|
||||||
// adds javascript to the document body, meaning it won't
|
|
||||||
// be included properly if the associated fields are loaded
|
|
||||||
// through ajax. This means only serverside validation
|
|
||||||
// will kick in for pages+validation loaded through ajax.
|
|
||||||
// This will be solved by using less obtrusive javascript validation
|
|
||||||
// in the future, see http://open.silverstripe.com/ticket/2915 and http://open.silverstripe.com/ticket/3386
|
|
||||||
if($record->hasMethod('getCMSValidator')) {
|
|
||||||
$validator = $record->getCMSValidator();
|
|
||||||
// The clientside (mainly LeftAndMain*.js) rely on ajax responses
|
|
||||||
// which can be evaluated as javascript, hence we need
|
|
||||||
// to override any global changes to the validation handler.
|
|
||||||
$validator->setJavascriptValidationHandler('prototype');
|
|
||||||
$form->setValidator($validator);
|
|
||||||
} else {
|
|
||||||
$form->unsetValidator();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$record->canEdit() || $record->IsDeletedFromStage) {
|
|
||||||
$readonlyFields = $form->Fields()->makeReadonly();
|
|
||||||
$form->setFields($readonlyFields);
|
|
||||||
}
|
}
|
||||||
} elseif ($id == 0) {
|
} elseif ($id == 0) {
|
||||||
$siteConfig = SiteConfig::current_site_config();
|
$siteConfig = SiteConfig::current_site_config();
|
||||||
@ -406,6 +367,89 @@ JS;
|
|||||||
//------------------------------------------------------------------------------------------//
|
//------------------------------------------------------------------------------------------//
|
||||||
// Data saving handlers
|
// Data saving handlers
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save and Publish page handler
|
||||||
|
*/
|
||||||
|
public function save($data, $form) {
|
||||||
|
$className = $this->stat('tree_class');
|
||||||
|
|
||||||
|
// Existing or new record?
|
||||||
|
$SQL_id = Convert::raw2sql($data['ID']);
|
||||||
|
if(substr($SQL_id,0,3) != 'new') {
|
||||||
|
$record = DataObject::get_by_id($className, $SQL_id);
|
||||||
|
if($record && !$record->canEdit()) return Security::permissionFailure($this);
|
||||||
|
} else {
|
||||||
|
if(!singleton($this->stat('tree_class'))->canCreate()) return Security::permissionFailure($this);
|
||||||
|
$record = $this->getNewItem($SQL_id, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Coupling to SiteTree
|
||||||
|
$record->HasBrokenLink = 0;
|
||||||
|
$record->HasBrokenFile = 0;
|
||||||
|
|
||||||
|
$record->writeWithoutVersion();
|
||||||
|
|
||||||
|
// Update the class instance if necessary
|
||||||
|
if($data['ClassName'] != $record->ClassName) {
|
||||||
|
$newClassName = $record->ClassName;
|
||||||
|
// The records originally saved attribute was overwritten by $form->saveInto($record) before.
|
||||||
|
// This is necessary for newClassInstance() to work as expected, and trigger change detection
|
||||||
|
// on the ClassName attribute
|
||||||
|
$record->setClassName($data['ClassName']);
|
||||||
|
// Replace $record with a new instance
|
||||||
|
$record = $record->newClassInstance($newClassName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// save form data into record
|
||||||
|
$form->saveInto($record, true);
|
||||||
|
$record->write();
|
||||||
|
|
||||||
|
// if changed to a single_instance_only page type
|
||||||
|
if ($record->stat('single_instance_only')) {
|
||||||
|
FormResponse::add("jQuery('#sitetree li.{$record->ClassName}').addClass('{$record->stat('single_instance_only_css_class')}');");
|
||||||
|
FormResponse::add($this->hideSingleInstanceOnlyFromCreateFieldJS($record));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FormResponse::add("jQuery('#sitetree li.{$record->ClassName}').removeClass('{$record->stat('single_instance_only_css_class')}');");
|
||||||
|
}
|
||||||
|
// if chnaged from a single_instance_only page type
|
||||||
|
$sampleOriginalClassObject = new $data['ClassName']();
|
||||||
|
if($sampleOriginalClassObject->stat('single_instance_only')) {
|
||||||
|
FormResponse::add($this->showSingleInstanceOnlyInCreateFieldJS($sampleOriginalClassObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the 'Save & Publish' button was clicked, also publish the page
|
||||||
|
if (isset($data['publish']) && $data['publish'] == 1) {
|
||||||
|
$record->doPublish();
|
||||||
|
|
||||||
|
// Update classname with original and get new instance (see above for explanation)
|
||||||
|
$record->setClassName($data['ClassName']);
|
||||||
|
$publishedRecord = $record->newClassInstance($record->ClassName);
|
||||||
|
|
||||||
|
$this->response->addHeader(
|
||||||
|
'X-Status',
|
||||||
|
sprintf(
|
||||||
|
_t(
|
||||||
|
'LeftAndMain.STATUSPUBLISHEDSUCCESS',
|
||||||
|
"Published '%s' successfully",
|
||||||
|
PR_MEDIUM,
|
||||||
|
'Status message after publishing a page, showing the page title'
|
||||||
|
),
|
||||||
|
$publishedRecord->Title
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$form->loadDataFrom($publishedRecord);
|
||||||
|
} else {
|
||||||
|
$this->response->addHeader('X-Status', _t('LeftAndMain.SAVEDUP'));
|
||||||
|
|
||||||
|
// write process might've changed the record, so we reload before returning
|
||||||
|
$form->loadDataFrom($record);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $form->formHtmlContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function doAdd($data, $form) {
|
public function doAdd($data, $form) {
|
||||||
$className = isset($data['PageType']) ? $data['PageType'] : "Page";
|
$className = isset($data['PageType']) ? $data['PageType'] : "Page";
|
||||||
|
@ -534,7 +534,7 @@ class LeftAndMain extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save and Publish page handler
|
* Save handler
|
||||||
*/
|
*/
|
||||||
public function save($data, $form) {
|
public function save($data, $form) {
|
||||||
$className = $this->stat('tree_class');
|
$className = $this->stat('tree_class');
|
||||||
@ -549,71 +549,15 @@ class LeftAndMain extends Controller {
|
|||||||
$record = $this->getNewItem($SQL_id, false);
|
$record = $this->getNewItem($SQL_id, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Coupling to SiteTree
|
|
||||||
$record->HasBrokenLink = 0;
|
|
||||||
$record->HasBrokenFile = 0;
|
|
||||||
|
|
||||||
$record->writeWithoutVersion();
|
|
||||||
|
|
||||||
// Update the class instance if necessary
|
|
||||||
if($data['ClassName'] != $record->ClassName) {
|
|
||||||
$newClassName = $record->ClassName;
|
|
||||||
// The records originally saved attribute was overwritten by $form->saveInto($record) before.
|
|
||||||
// This is necessary for newClassInstance() to work as expected, and trigger change detection
|
|
||||||
// on the ClassName attribute
|
|
||||||
$record->setClassName($data['ClassName']);
|
|
||||||
// Replace $record with a new instance
|
|
||||||
$record = $record->newClassInstance($newClassName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// save form data into record
|
// save form data into record
|
||||||
$form->saveInto($record, true);
|
$form->saveInto($record, true);
|
||||||
$record->write();
|
$record->write();
|
||||||
|
$this->extend('onAfterSave', $record);
|
||||||
// if changed to a single_instance_only page type
|
|
||||||
if ($record->stat('single_instance_only')) {
|
|
||||||
FormResponse::add("jQuery('#sitetree li.{$record->ClassName}').addClass('{$record->stat('single_instance_only_css_class')}');");
|
|
||||||
FormResponse::add($this->hideSingleInstanceOnlyFromCreateFieldJS($record));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
FormResponse::add("jQuery('#sitetree li.{$record->ClassName}').removeClass('{$record->stat('single_instance_only_css_class')}');");
|
|
||||||
}
|
|
||||||
// if chnaged from a single_instance_only page type
|
|
||||||
$sampleOriginalClassObject = new $data['ClassName']();
|
|
||||||
if($sampleOriginalClassObject->stat('single_instance_only')) {
|
|
||||||
FormResponse::add($this->showSingleInstanceOnlyInCreateFieldJS($sampleOriginalClassObject));
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the 'Save & Publish' button was clicked, also publish the page
|
$this->response->addHeader('X-Status', _t('LeftAndMain.SAVEDUP'));
|
||||||
if (isset($data['publish']) && $data['publish'] == 1) {
|
|
||||||
$record->doPublish();
|
// write process might've changed the record, so we reload before returning
|
||||||
$this->extend('onAfterSave', $record);
|
$form->loadDataFrom($record);
|
||||||
|
|
||||||
// Update classname with original and get new instance (see above for explanation)
|
|
||||||
$record->setClassName($data['ClassName']);
|
|
||||||
$publishedRecord = $record->newClassInstance($record->ClassName);
|
|
||||||
|
|
||||||
$this->response->addHeader(
|
|
||||||
'X-Status',
|
|
||||||
sprintf(
|
|
||||||
_t(
|
|
||||||
'LeftAndMain.STATUSPUBLISHEDSUCCESS',
|
|
||||||
"Published '%s' successfully",
|
|
||||||
PR_MEDIUM,
|
|
||||||
'Status message after publishing a page, showing the page title'
|
|
||||||
),
|
|
||||||
$publishedRecord->Title
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
$form->loadDataFrom($publishedRecord);
|
|
||||||
} else {
|
|
||||||
$this->extend('onAfterSave', $record);
|
|
||||||
$this->response->addHeader('X-Status', _t('LeftAndMain.SAVEDUP'));
|
|
||||||
|
|
||||||
// write process might've changed the record, so we reload before returning
|
|
||||||
$form->loadDataFrom($record);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $form->formHtmlContent();
|
return $form->formHtmlContent();
|
||||||
}
|
}
|
||||||
@ -790,10 +734,74 @@ JS;
|
|||||||
* Form might be readonly if the current user doesn't have the permission to edit
|
* Form might be readonly if the current user doesn't have the permission to edit
|
||||||
* the record.
|
* the record.
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* @return Form
|
||||||
|
*/
|
||||||
function EditForm($request = null) {
|
function EditForm($request = null) {
|
||||||
return $this->EmptyForm();
|
return $this->getEditForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getEditForm($id = null) {
|
||||||
|
if(!$id) $id = $this->currentPageID();
|
||||||
|
|
||||||
|
$record = ($id && $id != "root") ? DataObject::get_by_id($this->stat('tree_class'), $id) : null;
|
||||||
|
if($record && !$record->canView()) return Security::permissionFailure($this);
|
||||||
|
|
||||||
|
if($record) {
|
||||||
|
$fields = $record->getCMSFields();
|
||||||
|
if ($fields == null) {
|
||||||
|
user_error(
|
||||||
|
"getCMSFields() returned null - it should return a FieldSet object.
|
||||||
|
Perhaps you forgot to put a return statement at the end of your method?",
|
||||||
|
E_USER_ERROR
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($record->hasMethod('getAllCMSActions')) {
|
||||||
|
$actions = $record->getAllCMSActions();
|
||||||
|
} else {
|
||||||
|
$actions = $record->getCMSActions();
|
||||||
|
// add default actions if none are defined
|
||||||
|
if(!$actions || !$actions->Count()) {
|
||||||
|
if($record->canEdit()) {
|
||||||
|
$actions->push(new FormAction('save',_t('CMSMain.SAVE','Save')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$form = new Form($this, "EditForm", $fields, $actions);
|
||||||
|
$form->loadDataFrom($record);
|
||||||
|
|
||||||
|
// Add a default or custom validator.
|
||||||
|
// @todo Currently the default Validator.js implementation
|
||||||
|
// adds javascript to the document body, meaning it won't
|
||||||
|
// be included properly if the associated fields are loaded
|
||||||
|
// through ajax. This means only serverside validation
|
||||||
|
// will kick in for pages+validation loaded through ajax.
|
||||||
|
// This will be solved by using less obtrusive javascript validation
|
||||||
|
// in the future, see http://open.silverstripe.com/ticket/2915 and
|
||||||
|
// http://open.silverstripe.com/ticket/3386
|
||||||
|
if($record->hasMethod('getCMSValidator')) {
|
||||||
|
$validator = $record->getCMSValidator();
|
||||||
|
// The clientside (mainly LeftAndMain*.js) rely on ajax responses
|
||||||
|
// which can be evaluated as javascript, hence we need
|
||||||
|
// to override any global changes to the validation handler.
|
||||||
|
$validator->setJavascriptValidationHandler('prototype');
|
||||||
|
$form->setValidator($validator);
|
||||||
|
} else {
|
||||||
|
$form->unsetValidator();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$record->canEdit()) {
|
||||||
|
$readonlyFields = $form->Fields()->makeReadonly();
|
||||||
|
$form->setFields($readonlyFields);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$form = $this->EmptyForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $form;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Returns a placeholder form, used by {@link getEditForm()} if no record is selected.
|
* Returns a placeholder form, used by {@link getEditForm()} if no record is selected.
|
||||||
* Our javascript logic always requires a form to be present in the CMS interface.
|
* Our javascript logic always requires a form to be present in the CMS interface.
|
||||||
|
Loading…
Reference in New Issue
Block a user