mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
API CHANGE: Added GridField_URLHandler component interface.
This commit is contained in:
parent
1e1e3a2d80
commit
cb13299cf9
@ -194,11 +194,55 @@ A `GridField_DataManipulator` component can modify the data list. For example,
|
||||
|
||||
* **`getManipulatedData(GridField $gridField, SS_List $dataList)`:** Given this grid's data list, return an updated list to be used with this grid.
|
||||
|
||||
### GridField_URLProvider
|
||||
### GridField_URLHandler
|
||||
|
||||
**COMING SOON**
|
||||
Sometimes an action isn't enough: you need to provide additional support URLs for the grid. These URLs may return user-visible content, for example a pop-up form for editing a record's details, or they may be support URLs for front-end functionality, for example a URL that will return JSON-formatted data for a javascript grid control.
|
||||
|
||||
This interface isn't implemented yet, but will let you define a component that provides additional support URLs for the grid. These URLs may return user-visible content, for example a pop-up form for editing a record's details, or they may be support URLs for front-end functionality, for example a URL that will return JSON-formatted data for a javascript grid control.
|
||||
To build these components, you should implement the `GridField_URLHandler` interface. It only specifies one method: `getURLHandlers($gridField)`. This method should return an array similar to the `RequestHandler::$url_handlers` static. The action handlers should also be defined on the component; they will be passed `$gridField` and `$request`.
|
||||
|
||||
Here is an example in full. The actual implementation of the view and edit forms isn't included.
|
||||
|
||||
:::php
|
||||
/**
|
||||
* Provides view and edit forms at GridField-specific URLs. These can be placed into pop-ups by an appropriate front-end.
|
||||
*
|
||||
* The URLs provided will be off the following form:
|
||||
* - <FormURL>/field/<GridFieldName>/item/<RecordID>
|
||||
* - <FormURL>/field/<GridFieldName>/item/<RecordID>/edit
|
||||
*/
|
||||
class GridFieldPopupForms implements GridField_URLHandler {
|
||||
function getURLHandlers($gridField) {
|
||||
return array(
|
||||
'item/$ID' => 'handleItem',
|
||||
);
|
||||
}
|
||||
|
||||
function handleItem($gridField, $request) {
|
||||
$record = $gridField->getList()->byId($request->param("ID"));
|
||||
return new GridFieldPopupForm_ItemRequest($gridField, $this, $record);
|
||||
}
|
||||
}
|
||||
|
||||
class GridFieldPopupForm_ItemRequest extends RequestHandler {
|
||||
protected $gridField;
|
||||
protected $component;
|
||||
protected $record;
|
||||
|
||||
function __construct($gridField, $component, $record) {
|
||||
$this->gridField = $gridField;
|
||||
$this->component = $gridField;
|
||||
$this->record = $record;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
function index() {
|
||||
echo "view form for record #" . $record->ID;
|
||||
}
|
||||
|
||||
function edit() {
|
||||
echo "edit form for record #" . $record->ID;
|
||||
}
|
||||
}
|
||||
|
||||
## Other tools
|
||||
|
||||
|
@ -461,6 +461,74 @@ class GridField extends FormField {
|
||||
}
|
||||
throw new InvalidArgumentException("Can't handle action '$actionName'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom request handler that will check component handlers before proceeding to the default implementation.
|
||||
*
|
||||
* @todo There is too much code copied from RequestHandler here.
|
||||
*/
|
||||
function handleRequest(SS_HTTPRequest $request, DataModel $model) {
|
||||
if($this->brokenOnConstruct) {
|
||||
user_error("parent::__construct() needs to be called on {$handlerClass}::__construct()", E_USER_WARNING);
|
||||
}
|
||||
|
||||
$this->request = $request;
|
||||
$this->setModel($model);
|
||||
|
||||
///
|
||||
|
||||
foreach($this->components as $component) {
|
||||
if(!($component instanceof GridField_URLHandler)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$urlHandlers = $component->getURLHandlers($this);
|
||||
|
||||
if($urlHandlers) foreach($urlHandlers as $rule => $action) {
|
||||
if($params = $request->match($rule, true)) {
|
||||
// Actions can reference URL parameters, eg, '$Action/$ID/$OtherID' => '$Action',
|
||||
if($action[0] == '$') $action = $params[substr($action,1)];
|
||||
if(!method_exists($component, 'checkAccessAction') || $component->checkAccessAction($action)) {
|
||||
if(!$action) {
|
||||
$action = "index";
|
||||
} else if(!is_string($action)) {
|
||||
throw new LogicException("Non-string method name: " . var_export($action, true));
|
||||
}
|
||||
|
||||
try {
|
||||
$result = $component->$action($this, $request);
|
||||
} catch(SS_HTTPResponse_Exception $responseException) {
|
||||
$result = $responseException->getResponse();
|
||||
}
|
||||
|
||||
if($result instanceof SS_HTTPResponse && $result->isError()) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
if($this !== $result && !$request->isEmptyPattern($rule) && is_object($result) && $result instanceof RequestHandler) {
|
||||
$returnValue = $result->handleRequest($request, $model);
|
||||
|
||||
if(is_array($returnValue)) {
|
||||
throw new LogicException("GridField_URLHandler handlers can't return arrays");
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
|
||||
// If we return some other data, and all the URL is parsed, then return that
|
||||
} else if($request->allParsed()) {
|
||||
return $result;
|
||||
|
||||
// But if we have more content on the URL and we don't know what to do with it, return an error.
|
||||
} else {
|
||||
return $this->httpError(404, "I can't handle sub-URLs of a " . get_class($result) . " object.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent::handleRequest($request, $model);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,3 +42,14 @@ interface GridField_DataManipulator extends GridFieldComponent {
|
||||
*/
|
||||
function getManipulatedData(GridField $gridField, SS_List $dataList);
|
||||
}
|
||||
|
||||
interface GridField_URLHandler extends GridFieldComponent {
|
||||
/**
|
||||
* Return URLs to be handled by this grid field, in an array the same form as $url_handlers.
|
||||
*
|
||||
* Handler methods will be called on the component, rather than the grid field.
|
||||
*
|
||||
* The handlers will be passed two arguments, $gridField and $request
|
||||
*/
|
||||
function getURLHandlers($gridField);
|
||||
}
|
Loading…
Reference in New Issue
Block a user