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,62 +261,12 @@ HTML;
|
||||
public function currentPage() {
|
||||
$id = $this->currentPageID();
|
||||
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') {
|
||||
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 string HTML for site tree
|
||||
@ -377,7 +327,7 @@ HTML;
|
||||
* @return Form
|
||||
*/
|
||||
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');
|
||||
$form = new Form(
|
||||
$this,
|
||||
@ -452,18 +402,6 @@ HTML;
|
||||
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.
|
||||
|
150
code/CMSMain.php
150
code/CMSMain.php
@ -309,13 +309,6 @@ JS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Form
|
||||
*/
|
||||
function EditForm($request = null) {
|
||||
return $this->getEditForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link SiteTree->getCMSFields()}
|
||||
*/
|
||||
@ -323,16 +316,16 @@ JS;
|
||||
// Include JavaScript to ensure HtmlEditorField works.
|
||||
HtmlEditorField::include_js();
|
||||
|
||||
if(!$id) $id = $this->currentPageID();
|
||||
$form = parent::getEditForm($id);
|
||||
|
||||
$record = ($id) ? $this->getRecord($id) : null;
|
||||
if($record && !$record->canView()) return Security::permissionFailure($this);
|
||||
// TODO Duplicate record fetching (see parent implementation)
|
||||
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) {
|
||||
$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($liveURLField = new HiddenField("LiveURLSegment"));
|
||||
$fields->push($stageURLField = new HiddenField("StageURLSegment"));
|
||||
@ -349,47 +342,15 @@ JS;
|
||||
$stageURLField->setValue($record->AbsoluteLink());
|
||||
}
|
||||
|
||||
// getAllCMSActions can be used to completely redefine the action list
|
||||
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')));
|
||||
$actions->push($deleteAction = new FormAction('delete',_t('CMSMain.DELETE','Delete from the draft site')));
|
||||
$deleteAction = new FormAction(
|
||||
'delete',
|
||||
_t('CMSMain.DELETE','Delete from the draft site')
|
||||
);
|
||||
$deleteAction->addExtraClass('delete');
|
||||
}
|
||||
}
|
||||
}
|
||||
$actions->insertBefore($deleteAction, 'action_save');
|
||||
|
||||
$form = new Form($this, "EditForm", $fields, $actions);
|
||||
$form->loadDataFrom($record);
|
||||
$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);
|
||||
if($record->IsDeletedFromStage) {
|
||||
$form->makeReadonly();
|
||||
}
|
||||
} elseif ($id == 0) {
|
||||
$siteConfig = SiteConfig::current_site_config();
|
||||
@ -406,6 +367,89 @@ JS;
|
||||
//------------------------------------------------------------------------------------------//
|
||||
// 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) {
|
||||
$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) {
|
||||
$className = $this->stat('tree_class');
|
||||
@ -549,71 +549,15 @@ class LeftAndMain extends Controller {
|
||||
$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();
|
||||
$this->extend('onAfterSave', $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();
|
||||
}
|
||||
@ -790,10 +734,74 @@ JS;
|
||||
* Form might be readonly if the current user doesn't have the permission to edit
|
||||
* the record.
|
||||
*/
|
||||
/**
|
||||
* @return Form
|
||||
*/
|
||||
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.
|
||||
* Our javascript logic always requires a form to be present in the CMS interface.
|
||||
|
Loading…
Reference in New Issue
Block a user