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.
|
* **`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
|
## Other tools
|
||||||
|
|
||||||
|
@ -461,6 +461,74 @@ class GridField extends FormField {
|
|||||||
}
|
}
|
||||||
throw new InvalidArgumentException("Can't handle action '$actionName'");
|
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);
|
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