mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
BUGFIX Enabled Link() methods for RecordController and CollectionController, and adjusted url handling to ModelAdmin counterparts to avoid linkage handling problems
BUGFIX Requiring a parentController for RecordController ENHANCEMENT Custom getViewer() methods to use Page main templates if CollectionController is nested in a ContentController git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@63681 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
6878171375
commit
711de868c9
@ -21,20 +21,22 @@ abstract class CollectionController extends Controller {
|
|||||||
|
|
||||||
static $url_handlers = array(
|
static $url_handlers = array(
|
||||||
'' => 'index',
|
'' => 'index',
|
||||||
'$Action' => 'handleAction',
|
'$Action' => 'handleActionOrID',
|
||||||
);
|
);
|
||||||
|
|
||||||
static $page_size = 20;
|
public static $page_size = 20;
|
||||||
|
|
||||||
static $allowed_actions = array('index','search', 'SearchForm', 'ResultsForm');
|
static $allowed_actions = array('index','search','add','AddForm','SearchForm','ResultsForm');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $parentController
|
* @param string $parentController
|
||||||
* @param string $modelClass
|
* @param string $modelClass
|
||||||
*/
|
*/
|
||||||
function __construct($parentController = null, $modelClass = null) {
|
function __construct($parentController = null, $modelClass = null) {
|
||||||
if($parentController) $this->parentController = $parent;
|
if($parentController) $this->parentController = $parentController;
|
||||||
if($modelClass) $this->modelClass = $modelClass;
|
if($modelClass) $this->modelClass = $modelClass;
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
@ -51,7 +53,38 @@ abstract class CollectionController extends Controller {
|
|||||||
* @return unknown
|
* @return unknown
|
||||||
*/
|
*/
|
||||||
function Link() {
|
function Link() {
|
||||||
die("not implemented yet");
|
if($this->parentController) {
|
||||||
|
return Controller::join_links($this->parentController->Link(), "$this->modelClass");
|
||||||
|
} else {
|
||||||
|
return Controller::join_links("$this->modelClass");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegate to different control flow, depending on whether the
|
||||||
|
* URL parameter is a number (record id) or string (action).
|
||||||
|
*
|
||||||
|
* @param unknown_type $request
|
||||||
|
* @return unknown
|
||||||
|
*/
|
||||||
|
function handleActionOrID($request) {
|
||||||
|
if (is_numeric($request->param('Action'))) {
|
||||||
|
return $this->handleID($request);
|
||||||
|
} else {
|
||||||
|
return $this->handleAction($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegate to the RecordController if a valid numeric ID appears in the URL
|
||||||
|
* segment.
|
||||||
|
*
|
||||||
|
* @param HTTPRequest $request
|
||||||
|
* @return RecordController
|
||||||
|
*/
|
||||||
|
function handleID($request) {
|
||||||
|
$class = $this->recordControllerClass;
|
||||||
|
return new $class($this, $request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,20 +96,6 @@ abstract class CollectionController extends Controller {
|
|||||||
return $this->modelClass;
|
return $this->modelClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Delegate to the {@link RecordController} if a valid numeric ID appears in the URL
|
|
||||||
* segment.
|
|
||||||
*
|
|
||||||
* @param HTTPRequest $request
|
|
||||||
* @return RecordController
|
|
||||||
*/
|
|
||||||
function record($request) {
|
|
||||||
if(!$this->recordControllerClass) return $this->httpError(403);
|
|
||||||
|
|
||||||
$class = $this->recordControllerClass;
|
|
||||||
return new $class($this, $this->modelClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function index($request) {
|
function index($request) {
|
||||||
@ -144,6 +163,74 @@ abstract class CollectionController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new model record.
|
||||||
|
*
|
||||||
|
* @param unknown_type $request
|
||||||
|
* @return unknown
|
||||||
|
*/
|
||||||
|
function add($request) {
|
||||||
|
if(!singleton($this->modelClass)->canCreate(Member::currentUser())) {
|
||||||
|
return $this->httpError(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render(array(
|
||||||
|
'Form' => $this->AddForm(),
|
||||||
|
'SearchForm' => false
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a form for editing the attached model
|
||||||
|
*/
|
||||||
|
public function AddForm() {
|
||||||
|
$newRecord = new $this->modelClass();
|
||||||
|
if($newRecord->hasMethod('getAddFormFields')) {
|
||||||
|
$fields = $newRecord->getAddFormFields();
|
||||||
|
} else {
|
||||||
|
$fields = $newRecord->getFormFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
$validator = ($newRecord->hasMethod('getValidator')) ? $newRecord->getValidator() : null;
|
||||||
|
|
||||||
|
$actions = new FieldSet(new FormAction("doAdd", "Add"));
|
||||||
|
|
||||||
|
$form = new Form($this, "AddForm", $fields, $actions, $validator);
|
||||||
|
|
||||||
|
return $form;
|
||||||
|
}
|
||||||
|
|
||||||
|
function doAdd($data, $form, $request) {
|
||||||
|
if(!singleton($this->modelClass)->canCreate(Member::currentUser())) {
|
||||||
|
return $this->httpError(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
$className = $this->modelClass;
|
||||||
|
$model = new $className();
|
||||||
|
// We write before saveInto, since this will let us save has-many and many-many relationships :-)
|
||||||
|
$model->write();
|
||||||
|
$form->saveInto($model);
|
||||||
|
$model->write();
|
||||||
|
|
||||||
|
/*
|
||||||
|
$form->sessionMessage(
|
||||||
|
_t('RecordController.SAVESUCCESS','Saved record'),
|
||||||
|
'good'
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
|
if($this->canDetailView()) {
|
||||||
|
Director::redirect(Controller::join_links($this->Link(), $model->ID , 'edit'));
|
||||||
|
} else {
|
||||||
|
Director::redirectBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,5 +255,28 @@ abstract class CollectionController extends Controller {
|
|||||||
public function canDetailView() {
|
public function canDetailView() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a parentcontroller exists, use its main template,
|
||||||
|
* and mix in specific collectioncontroller subtemplates.
|
||||||
|
*/
|
||||||
|
function getViewer($action) {
|
||||||
|
if($this->parentController) {
|
||||||
|
$viewer = $this->parentController->getViewer($action);
|
||||||
|
$parentClass = $this->class;
|
||||||
|
$layoutTemplate = null;
|
||||||
|
while($parentClass != "Controller" && !$layoutTemplate) {
|
||||||
|
$templates[] = strtok($parentClass,'_') . '_' . $action;
|
||||||
|
$parentClass = get_parent_class($parentClass);
|
||||||
|
$layoutTemplate = SSViewer::getTemplateFileByType($parentClass, 'Layout');
|
||||||
|
}
|
||||||
|
|
||||||
|
if($layoutTemplate) $viewer->setTemplateFile('Layout', $layoutTemplate);
|
||||||
|
|
||||||
|
return $viewer;
|
||||||
|
} else {
|
||||||
|
return parent::getViewer($action);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
@ -4,27 +4,18 @@
|
|||||||
* @subpackage control
|
* @subpackage control
|
||||||
*/
|
*/
|
||||||
class RecordController extends Controller {
|
class RecordController extends Controller {
|
||||||
|
protected $parentController;
|
||||||
protected $modelClass;
|
|
||||||
|
|
||||||
protected $currentRecord;
|
protected $currentRecord;
|
||||||
|
|
||||||
static $allowed_actions = array('add','edit', 'view', 'EditForm', 'ViewForm');
|
static $allowed_actions = array('edit','view','delete','EditForm','ViewForm','DeleteForm');
|
||||||
|
|
||||||
static $url_handlers = array(
|
function __construct($parentController, $request) {
|
||||||
'' => 'index',
|
$this->parentController = $parentController;
|
||||||
'add' => 'add',
|
$modelName = $parentController->getModelClass();
|
||||||
'AddForm' => 'AddForm',
|
|
||||||
'$ID/$Action' => 'handleAction',
|
if(is_numeric($request->latestParam('Action'))) {
|
||||||
);
|
$this->currentRecord = DataObject::get_by_id($this->modelClass, $request->latestParam('Action'));
|
||||||
|
}
|
||||||
/**
|
|
||||||
* @param string $parentController
|
|
||||||
* @param string $modelClass
|
|
||||||
*/
|
|
||||||
function __construct($parentController = null, $modelClass = null) {
|
|
||||||
if($parentController) $this->parentController = $parentController;
|
|
||||||
if($modelClass) $this->modelClass = $modelClass;
|
|
||||||
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
@ -37,20 +28,12 @@ class RecordController extends Controller {
|
|||||||
Requirements::themedCSS('form');
|
Requirements::themedCSS('form');
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleAction($request) {
|
|
||||||
if(is_numeric($request->latestParam('ID'))) {
|
|
||||||
$this->currentRecord = DataObject::get_by_id($this->modelClass, $request->latestParam('ID'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent::handleAction($request);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link fragment - appends the current record ID to the URL.
|
* Link fragment - appends the current record ID to the URL.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function Link() {
|
function Link() {
|
||||||
die("not implemented yet");
|
return Controller::join_links($this->parentController->Link(), "/{$this->currentRecord->ID}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -71,7 +54,8 @@ class RecordController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $this->render(array(
|
return $this->render(array(
|
||||||
'Form' => $this->EditForm()
|
'Form' => $this->EditForm(),
|
||||||
|
'ExtraForm' => $this->DeleteForm()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,19 +69,28 @@ class RecordController extends Controller {
|
|||||||
$validator = ($this->currentRecord->hasMethod('getValidator')) ? $this->currentRecord->getValidator() : null;
|
$validator = ($this->currentRecord->hasMethod('getValidator')) ? $this->currentRecord->getValidator() : null;
|
||||||
|
|
||||||
$actions = new FieldSet(
|
$actions = new FieldSet(
|
||||||
new FormAction("doSave", "Save")
|
new FormAction("doEdit", "Save")
|
||||||
);
|
);
|
||||||
|
|
||||||
if($this->currentRecord->canDelete(Member::currentUser())) {
|
|
||||||
$actions->push($deleteAction = new FormAction('doDelete', 'Delete'));
|
|
||||||
$deleteAction->addExtraClass('delete');
|
|
||||||
}
|
|
||||||
|
|
||||||
$form = new Form($this, "EditForm", $fields, $actions, $validator);
|
$form = new Form($this, "EditForm", $fields, $actions, $validator);
|
||||||
$form->loadDataFrom($this->currentRecord);
|
$form->loadDataFrom($this->currentRecord);
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function DeleteForm() {
|
||||||
|
if(!$this->currentRecord->canDelete(Member::currentUser())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$form = new Form($this,
|
||||||
|
"DeleteForm",
|
||||||
|
new FieldSet(),
|
||||||
|
new FieldSet(new ConfirmedFormAction('doDelete', 'Delete'))
|
||||||
|
);
|
||||||
|
|
||||||
|
return $form;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Postback action to save a record
|
* Postback action to save a record
|
||||||
@ -107,7 +100,7 @@ class RecordController extends Controller {
|
|||||||
* @param HTTPRequest $request
|
* @param HTTPRequest $request
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
function doSave($data, $form, $request) {
|
function doEdit($data, $form, $request) {
|
||||||
if(!$this->currentRecord->canEdit(Member::currentUser())) {
|
if(!$this->currentRecord->canEdit(Member::currentUser())) {
|
||||||
return $this->httpError(403);
|
return $this->httpError(403);
|
||||||
}
|
}
|
||||||
@ -152,7 +145,7 @@ class RecordController extends Controller {
|
|||||||
if(!$this->currentRecord) {
|
if(!$this->currentRecord) {
|
||||||
return $this->httpError(404);
|
return $this->httpError(404);
|
||||||
}
|
}
|
||||||
if(!$this->currentRecord->canDelete(Member::currentUser())) {
|
if(!$this->currentRecord->canView(Member::currentUser())) {
|
||||||
return $this->httpError(403);
|
return $this->httpError(403);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,60 +167,6 @@ class RecordController extends Controller {
|
|||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new model record.
|
|
||||||
*
|
|
||||||
* @param unknown_type $request
|
|
||||||
* @return unknown
|
|
||||||
*/
|
|
||||||
function add($request) {
|
|
||||||
if(!singleton($this->modelClass)->canCreate(Member::currentUser())) {
|
|
||||||
return $this->httpError(403);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render(array(
|
|
||||||
'Form' => $this->AddForm()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a form for editing the attached model
|
|
||||||
*/
|
|
||||||
public function AddForm() {
|
|
||||||
$newRecord = new $this->modelClass();
|
|
||||||
if($newRecord->hasMethod('getAddFormFields')) {
|
|
||||||
$fields = $newRecord->getAddFormFields();
|
|
||||||
} else {
|
|
||||||
$fields = $newRecord->getFormFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
$validator = ($newRecord->hasMethod('getValidator')) ? $newRecord->getValidator() : null;
|
|
||||||
|
|
||||||
$actions = new FieldSet(new FormAction("doAdd", "Add"));
|
|
||||||
|
|
||||||
$form = new Form($this, "AddForm", $fields, $actions, $validator);
|
|
||||||
|
|
||||||
return $form;
|
|
||||||
}
|
|
||||||
|
|
||||||
function doAdd($data, $form, $request) {
|
|
||||||
if(!singleton($this->modelClass)->canCreate(Member::currentUser())) {
|
|
||||||
return $this->httpError(403);
|
|
||||||
}
|
|
||||||
|
|
||||||
$className = $this->modelClass;
|
|
||||||
$model = new $className();
|
|
||||||
// We write before saveInto, since this will let us save has-many and many-many relationships :-)
|
|
||||||
$model->write();
|
|
||||||
$form->saveInto($model);
|
|
||||||
$model->write();
|
|
||||||
|
|
||||||
Director::redirect(Controller::join_links($this->Link(), $model->ID , 'edit'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -244,5 +183,28 @@ class RecordController extends Controller {
|
|||||||
public function ModelNamePlural() {
|
public function ModelNamePlural() {
|
||||||
return singleton($this->modelClass)->i18n_plural_name();
|
return singleton($this->modelClass)->i18n_plural_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a parentcontroller exists, use its main template,
|
||||||
|
* and mix in specific collectioncontroller subtemplates.
|
||||||
|
*/
|
||||||
|
function getViewer($action) {
|
||||||
|
if($this->parentController) {
|
||||||
|
$viewer = $this->parentController->getViewer($action);
|
||||||
|
$parentClass = $this->class;
|
||||||
|
$layoutTemplate = null;
|
||||||
|
while($parentClass != "Controller" && !$layoutTemplate) {
|
||||||
|
$templates[] = strtok($parentClass,'_') . '_' . $action;
|
||||||
|
$parentClass = get_parent_class($parentClass);
|
||||||
|
$layoutTemplate = SSViewer::getTemplateFileByType($parentClass, 'Layout');
|
||||||
|
}
|
||||||
|
|
||||||
|
if($layoutTemplate) $viewer->setTemplateFile('Layout', $layoutTemplate);
|
||||||
|
|
||||||
|
return $viewer;
|
||||||
|
} else {
|
||||||
|
return parent::getViewer($action);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
36
templates/Includes/CollectionController_Results.ss
Normal file
36
templates/Includes/CollectionController_Results.ss
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<% if Results %>
|
||||||
|
<h3><% _t('RESULTS','Results') %></h3>
|
||||||
|
<ul class="records">
|
||||||
|
<% control Results %>
|
||||||
|
<li>
|
||||||
|
<% if Top.canDetailView %>
|
||||||
|
<a href="{$Top.Link}/$ID/view">$Title</a>
|
||||||
|
<% else %>
|
||||||
|
$Title
|
||||||
|
<% end_if %>
|
||||||
|
</li>
|
||||||
|
<% end_control %>
|
||||||
|
</ul>
|
||||||
|
<% else %>
|
||||||
|
<p class="message"><% _t('NORESULTSFOUND','No records found') %></p>
|
||||||
|
<% end_if %>
|
||||||
|
|
||||||
|
<% if Results.MoreThanOnePage %>
|
||||||
|
<div id="PageNumbers">
|
||||||
|
<% if Results.NotFirstPage %>
|
||||||
|
<a class="prev" href="$Results.PrevLink"><% _t('PREV','Prev') %></a>
|
||||||
|
<% end_if %>
|
||||||
|
<span>
|
||||||
|
<% control Results.Pages %>
|
||||||
|
<% if CurrentBool %>
|
||||||
|
$PageNum
|
||||||
|
<% else %>
|
||||||
|
<a href="$Link">$PageNum</a>
|
||||||
|
<% end_if %>
|
||||||
|
<% end_control %>
|
||||||
|
</span>
|
||||||
|
<% if Results.NotLastPage %>
|
||||||
|
<a class="next" href="$Results.NextLink"><% _t('NEXT','Next') %></a>
|
||||||
|
<% end_if %>
|
||||||
|
</div>
|
||||||
|
<% end_if %>
|
@ -3,45 +3,18 @@
|
|||||||
|
|
||||||
<h2>$Title</h2>
|
<h2>$Title</h2>
|
||||||
|
|
||||||
|
$Form
|
||||||
|
|
||||||
<% if SearchForm %>
|
<% if SearchForm %>
|
||||||
<h3><% _t('SEARCH','Search') %></h3>
|
<h3><% _t('SEARCH','Search') %></h3>
|
||||||
$SearchForm
|
$SearchForm
|
||||||
<% end_if %>
|
<% end_if %>
|
||||||
|
|
||||||
<% if Results %>
|
<% include CollectionController_Results %>
|
||||||
<ul class="records">
|
|
||||||
<% control Results %>
|
|
||||||
<li>
|
|
||||||
<% if Top.canDetailView %>
|
|
||||||
<a href="{$Top.Link}/record/$ID/view">$Title</a>
|
|
||||||
<% else %>
|
|
||||||
$Title
|
|
||||||
<% end_if %>
|
|
||||||
</li>
|
|
||||||
<% end_control %>
|
|
||||||
</ul>
|
|
||||||
<% else %>
|
|
||||||
<p class="message"><% _t('NORESULTSFOUND','No records found') %></p>
|
|
||||||
<% end_if %>
|
|
||||||
|
|
||||||
<% if Results.MoreThanOnePage %>
|
<% if canCurrentUserCreate %>
|
||||||
<div id="PageNumbers">
|
<h3>Add</h3>
|
||||||
<% if Results.NotLastPage %>
|
<a href="$Link/add"><% _t('ADDNEWRECORD','Add new record') %></a>
|
||||||
<a class="next" href="$Results.NextLink"><% _t('NEXT','Next') %></a>
|
|
||||||
<% end_if %>
|
|
||||||
<% if Results.NotFirstPage %>
|
|
||||||
<a class="prev" href="$Results.PrevLink"><% _t('PREV','Prev') %></a>
|
|
||||||
<% end_if %>
|
|
||||||
<span>
|
|
||||||
<% control Results.Pages %>
|
|
||||||
<% if CurrentBool %>
|
|
||||||
$PageNum
|
|
||||||
<% else %>
|
|
||||||
<a href="$Link">$PageNum</a>
|
|
||||||
<% end_if %>
|
|
||||||
<% end_control %>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<% end_if %>
|
<% end_if %>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
<h2>$Title</h2>
|
<h2>$Title</h2>
|
||||||
|
|
||||||
$Form
|
$Form
|
||||||
|
|
||||||
|
$ExtraForm
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
Loading…
Reference in New Issue
Block a user