mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
(merged from branches/roa. use "svn log -c <changeset> -g <module-svn-path>" for detailed commit message)
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@60206 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
03fcc80e19
commit
6bd5da7e6e
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
// Default director
|
// Default director
|
||||||
Director::addRules(10, array(
|
Director::addRules(10, array(
|
||||||
'Security' => 'Security',
|
'Security//$Action/$ID/$OtherID' => 'Security',
|
||||||
//'Security/$Action/$ID' => 'Security',
|
//'Security/$Action/$ID' => 'Security',
|
||||||
'db/$Action' => 'DatabaseAdmin',
|
'db/$Action' => 'DatabaseAdmin',
|
||||||
'$Controller' => array(
|
'$Controller' => array(
|
||||||
|
@ -24,24 +24,29 @@
|
|||||||
*
|
*
|
||||||
* - POST /api/v1/(ClassName)/(ID)/(MethodName) - executes a method on the given object (e.g, publish)
|
* - POST /api/v1/(ClassName)/(ID)/(MethodName) - executes a method on the given object (e.g, publish)
|
||||||
*
|
*
|
||||||
|
* @todo Finish RestfulServer_Item and RestfulServer_List implementation and re-enable $url_handlers
|
||||||
|
*
|
||||||
* @package sapphire
|
* @package sapphire
|
||||||
* @subpackage api
|
* @subpackage api
|
||||||
*/
|
*/
|
||||||
class RestfulServer extends Controller {
|
class RestfulServer extends Controller {
|
||||||
static $url_handlers = array(
|
static $url_handlers = array(
|
||||||
'$ClassName/#ID' => 'handleItem',
|
'$ClassName/$ID/$Relation' => 'handleAction'
|
||||||
'$ClassName' => 'handleList',
|
#'$ClassName/#ID' => 'handleItem',
|
||||||
|
#'$ClassName' => 'handleList',
|
||||||
);
|
);
|
||||||
|
|
||||||
protected static $api_base = "api/v1/";
|
protected static $api_base = "api/v1/";
|
||||||
|
|
||||||
function handleItem($params) {
|
/*
|
||||||
return new RestfulServer_Item(DataObject::get_by_id($params["ClassName"], $params["ID"]));
|
function handleItem($request) {
|
||||||
|
return new RestfulServer_Item(DataObject::get_by_id($request->param("ClassName"), $request->param("ID")));
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleList($params) {
|
function handleList($request) {
|
||||||
return new RestfulServer_List(DataObject::get($params["ClassName"],""));
|
return new RestfulServer_List(DataObject::get($request->param("ClassName"),""));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This handler acts as the switchboard for the controller.
|
* This handler acts as the switchboard for the controller.
|
||||||
@ -49,7 +54,7 @@ class RestfulServer extends Controller {
|
|||||||
*/
|
*/
|
||||||
function index() {
|
function index() {
|
||||||
ContentNegotiator::disable();
|
ContentNegotiator::disable();
|
||||||
|
|
||||||
$requestMethod = $_SERVER['REQUEST_METHOD'];
|
$requestMethod = $_SERVER['REQUEST_METHOD'];
|
||||||
|
|
||||||
if(!isset($this->urlParams['ClassName'])) return $this->notFound();
|
if(!isset($this->urlParams['ClassName'])) return $this->notFound();
|
||||||
@ -112,6 +117,12 @@ class RestfulServer extends Controller {
|
|||||||
*
|
*
|
||||||
* - static $api_access must be set. This enables the API on a class by class basis
|
* - static $api_access must be set. This enables the API on a class by class basis
|
||||||
* - $obj->canView() must return true. This lets you implement record-level security
|
* - $obj->canView() must return true. This lets you implement record-level security
|
||||||
|
*
|
||||||
|
* @param String $className
|
||||||
|
* @param Int $id
|
||||||
|
* @param String $relation
|
||||||
|
* @param String $contentType
|
||||||
|
* @return String The serialized representation of the requested object(s) - usually XML or JSON.
|
||||||
*/
|
*/
|
||||||
protected function getHandler($className, $id, $relation, $contentType) {
|
protected function getHandler($className, $id, $relation, $contentType) {
|
||||||
if($id) {
|
if($id) {
|
||||||
@ -156,7 +167,11 @@ class RestfulServer extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate an XML representation of the given DataObject.
|
* Generate an XML representation of the given {@link DataObject}.
|
||||||
|
*
|
||||||
|
* @param DataObject $obj
|
||||||
|
* @param $includeHeader Include <?xml ...?> header (Default: true)
|
||||||
|
* @return String XML
|
||||||
*/
|
*/
|
||||||
protected function dataObjectAsXML(DataObject $obj, $includeHeader = true) {
|
protected function dataObjectAsXML(DataObject $obj, $includeHeader = true) {
|
||||||
$className = $obj->class;
|
$className = $obj->class;
|
||||||
@ -212,22 +227,30 @@ class RestfulServer extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate an XML representation of the given DataObject.
|
* Generate an XML representation of the given {@link DataObjectSet}.
|
||||||
|
*
|
||||||
|
* @param DataObjectSet $set
|
||||||
|
* @return String XML
|
||||||
*/
|
*/
|
||||||
protected function dataObjectSetAsXML(DataObjectSet $set) {
|
protected function dataObjectSetAsXML(DataObjectSet $set) {
|
||||||
$className = $set->class;
|
$className = $set->class;
|
||||||
|
|
||||||
$json = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<$className>\n";
|
$xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<$className>\n";
|
||||||
foreach($set as $item) {
|
foreach($set as $item) {
|
||||||
if($item->canView()) $json .= $this->dataObjectAsXML($item, false);
|
if($item->canView()) $xml .= $this->dataObjectAsXML($item, false);
|
||||||
}
|
}
|
||||||
$json .= "</$className>";
|
$xml .= "</$className>";
|
||||||
|
|
||||||
return $json;
|
return $xml;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate an XML representation of the given DataObject.
|
* Generate an JSON representation of the given {@link DataObject}.
|
||||||
|
*
|
||||||
|
* @see http://json.org
|
||||||
|
*
|
||||||
|
* @param DataObject $obj
|
||||||
|
* @return String JSON
|
||||||
*/
|
*/
|
||||||
protected function dataObjectAsJSON(DataObject $obj) {
|
protected function dataObjectAsJSON(DataObject $obj) {
|
||||||
$className = $obj->class;
|
$className = $obj->class;
|
||||||
@ -278,7 +301,10 @@ class RestfulServer extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate an XML representation of the given DataObject.
|
* Generate an JSON representation of the given {@link DataObjectSet}.
|
||||||
|
*
|
||||||
|
* @param DataObjectSet $set
|
||||||
|
* @return String JSON
|
||||||
*/
|
*/
|
||||||
protected function dataObjectSetAsJSON(DataObjectSet $set) {
|
protected function dataObjectSetAsJSON(DataObjectSet $set) {
|
||||||
$jsonParts = array();
|
$jsonParts = array();
|
||||||
@ -346,8 +372,8 @@ class RestfulServer_List {
|
|||||||
$this->list = $list;
|
$this->list = $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleItem($params) {
|
function handleItem($request) {
|
||||||
return new RestulServer_Item($this->list->getById($params['ID']));
|
return new RestulServer_Item($this->list->getById($request->param('ID')));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,11 +389,11 @@ class RestfulServer_Item {
|
|||||||
$this->item = $item;
|
$this->item = $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleRelation($params) {
|
function handleRelation($request) {
|
||||||
$funcName = $params['Relation'];
|
$funcName = $request('Relation');
|
||||||
$relation = $this->item->$funcName();
|
$relation = $this->item->$funcName();
|
||||||
|
|
||||||
if($relation instanceof DataObjectSet) return new RestfulServer_List($relation);
|
if($relation instanceof DataObjectSet) return new RestfulServer_List($relation);
|
||||||
else return new RestfulServer_Item($relation)l
|
else return new RestfulServer_Item($relation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -284,11 +284,11 @@ class RestfulService extends ViewableData {
|
|||||||
$childElements = $xml->{$collection}->{$element};
|
$childElements = $xml->{$collection}->{$element};
|
||||||
|
|
||||||
if($childElements){
|
if($childElements){
|
||||||
foreach($childElements as $child){
|
foreach($childElements as $child){
|
||||||
$data = array();
|
$data = array();
|
||||||
$this->getRecurseValues($child,$data);
|
$this->getRecurseValues($child,$data);
|
||||||
$output->push(new ArrayData($data));
|
$output->push(new ArrayData($data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ class Controller extends RequestHandlingData {
|
|||||||
* Default URL handlers - (Action)/(ID)/(OtherID)
|
* Default URL handlers - (Action)/(ID)/(OtherID)
|
||||||
*/
|
*/
|
||||||
static $url_handlers = array(
|
static $url_handlers = array(
|
||||||
'$Action/$ID/$OtherID' => 'handleAction',
|
'$Action//$ID/$OtherID' => 'handleAction',
|
||||||
);
|
);
|
||||||
|
|
||||||
static $allowed_actions = array(
|
static $allowed_actions = array(
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* match() to get the information that they need out of the URL. This is generally handled by
|
* match() to get the information that they need out of the URL. This is generally handled by
|
||||||
* {@link RequestHandlingData::handleRequest()}.
|
* {@link RequestHandlingData::handleRequest()}.
|
||||||
*/
|
*/
|
||||||
class HTTPRequest extends Object {
|
class HTTPRequest extends Object implements ArrayAccess {
|
||||||
/**
|
/**
|
||||||
* The non-extension parts of the URL, separated by "/"
|
* The non-extension parts of the URL, separated by "/"
|
||||||
*/
|
*/
|
||||||
@ -52,6 +52,39 @@ class HTTPRequest extends Object {
|
|||||||
if(isset($this->postVars[$name])) return $this->postVars[$name];
|
if(isset($this->postVars[$name])) return $this->postVars[$name];
|
||||||
if(isset($this->getVars[$name])) return $this->getVars[$name];
|
if(isset($this->getVars[$name])) return $this->getVars[$name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables the existence of a key-value pair in the request to be checked using
|
||||||
|
* array syntax, so isset($request['title']) will check for $_POST['title'] and $_GET['title]
|
||||||
|
*
|
||||||
|
* @param unknown_type $offset
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
function offsetExists($offset) {
|
||||||
|
if(isset($this->postVars[$offset])) return true;
|
||||||
|
if(isset($this->getVars[$offset])) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access a request variable using array syntax. eg: $request['title'] instead of $request->postVar('title')
|
||||||
|
*
|
||||||
|
* @param unknown_type $offset
|
||||||
|
* @return unknown
|
||||||
|
*/
|
||||||
|
function offsetGet($offset) {
|
||||||
|
return $this->requestVar($offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
function offsetSet($offset, $value) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
function offsetUnset($offset) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a HTTPRequest from a URL relative to the site root.
|
* Construct a HTTPRequest from a URL relative to the site root.
|
||||||
@ -159,7 +192,7 @@ class HTTPRequest extends Object {
|
|||||||
// Load the arguments that actually have a value into $this->allParams
|
// Load the arguments that actually have a value into $this->allParams
|
||||||
// This ensures that previous values aren't overridden with blanks
|
// This ensures that previous values aren't overridden with blanks
|
||||||
foreach($arguments as $k => $v) {
|
foreach($arguments as $k => $v) {
|
||||||
if($v) $this->allParams[$k] = $v;
|
if($v || !isset($this->allParams[$k])) $this->allParams[$k] = $v;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $arguments;
|
return $arguments;
|
||||||
|
@ -69,7 +69,9 @@ class RequestHandlingData extends ViewableData {
|
|||||||
*/
|
*/
|
||||||
function handleRequest($request) {
|
function handleRequest($request) {
|
||||||
foreach($this->stat('url_handlers') as $rule => $action) {
|
foreach($this->stat('url_handlers') as $rule => $action) {
|
||||||
|
if(isset($_GET['debug_request'])) Debug::message("Testing '$rule' with '" . $request->remaining() . "' on $this->class");
|
||||||
if($params = $request->match($rule, true)) {
|
if($params = $request->match($rule, true)) {
|
||||||
|
if(isset($_GET['debug_request'])) Debug::message("Rule '$rule' matched on $this->class");
|
||||||
|
|
||||||
// Actions can reference URL parameters, eg, '$Action/$ID/$OtherID' => '$Action',
|
// Actions can reference URL parameters, eg, '$Action/$ID/$OtherID' => '$Action',
|
||||||
if($action[0] == '$') $action = $params[substr($action,1)];
|
if($action[0] == '$') $action = $params[substr($action,1)];
|
||||||
|
@ -7,23 +7,18 @@
|
|||||||
*/
|
*/
|
||||||
class RootURLController extends Controller {
|
class RootURLController extends Controller {
|
||||||
protected static $is_at_root = false;
|
protected static $is_at_root = false;
|
||||||
|
|
||||||
public function run($requestParams) {
|
|
||||||
self::$is_at_root = true;
|
|
||||||
|
|
||||||
$this->pushCurrent();
|
|
||||||
$controller = new ModelAsController();
|
|
||||||
$controller->setUrlParams(array(
|
|
||||||
'URLSegment' => self::get_homepage_urlsegment(),
|
|
||||||
'Action' => '',
|
|
||||||
));
|
|
||||||
|
|
||||||
$result = $controller->run($requestParams);
|
|
||||||
|
|
||||||
$this->popCurrent();
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public function handleRequest($request) {
|
||||||
|
self::$is_at_root = true;
|
||||||
|
|
||||||
|
$controller = new ModelAsController();
|
||||||
|
|
||||||
|
$request = new HTTPRequest("GET", self::get_homepage_urlsegment().'/', $request->getVars(), $request->postVars());
|
||||||
|
$request->match('$URLSegment//$Action');
|
||||||
|
|
||||||
|
return $controller->handleRequest($request);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the URL segment for the current HTTP_HOST value
|
* Return the URL segment for the current HTTP_HOST value
|
||||||
*/
|
*/
|
||||||
|
@ -616,6 +616,7 @@ class DataObject extends ViewableData implements DataObjectInterface {
|
|||||||
foreach($this->record as $fieldName => $fieldValue) {
|
foreach($this->record as $fieldName => $fieldValue) {
|
||||||
if(isset($this->changed[$fieldName]) && $this->changed[$fieldName] && $fieldType = $classSingleton->fieldExists($fieldName)) {
|
if(isset($this->changed[$fieldName]) && $this->changed[$fieldName] && $fieldType = $classSingleton->fieldExists($fieldName)) {
|
||||||
$fieldObj = $this->obj($fieldName);
|
$fieldObj = $this->obj($fieldName);
|
||||||
|
$fieldObj->setValue($this->record[$fieldName], $this->record);
|
||||||
if(!isset($manipulation[$class])) $manipulation[$class] = array();
|
if(!isset($manipulation[$class])) $manipulation[$class] = array();
|
||||||
if($fieldObj) $fieldObj->writeToManipulation($manipulation[$class]);
|
if($fieldObj) $fieldObj->writeToManipulation($manipulation[$class]);
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ class ComplexTableField extends TableListField {
|
|||||||
/**
|
/**
|
||||||
* @var string Classname of the parent-relation to correctly link new records.
|
* @var string Classname of the parent-relation to correctly link new records.
|
||||||
*/
|
*/
|
||||||
protected $parentClass;
|
public $parentClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string Database column name for the used relation (e.g. FamilyID
|
* @var string Database column name for the used relation (e.g. FamilyID
|
||||||
@ -71,7 +71,7 @@ class ComplexTableField extends TableListField {
|
|||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $templatePopup = "ComplexTableField_popup";
|
public $templatePopup = "ComplexTableField_popup";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Classname for each row/item
|
* Classname for each row/item
|
||||||
@ -110,6 +110,20 @@ class ComplexTableField extends TableListField {
|
|||||||
* @var boolean
|
* @var boolean
|
||||||
*/
|
*/
|
||||||
protected $relationAutoSetting = true;
|
protected $relationAutoSetting = true;
|
||||||
|
|
||||||
|
|
||||||
|
static $url_handlers = array(
|
||||||
|
'item/$ID' => 'handleItem',
|
||||||
|
);
|
||||||
|
|
||||||
|
function handleItem($request) {
|
||||||
|
return new ComplexTableField_ItemRequest($this, $request->param('ID'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getViewer() {
|
||||||
|
return new SSViewer('ComplexTableField');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See class comments
|
* See class comments
|
||||||
@ -208,6 +222,10 @@ JS;
|
|||||||
|
|
||||||
return $this->sourceItems;
|
return $this->sourceItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sourceClass() {
|
||||||
|
return $this->sourceClass;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return DataObjectSet
|
* @return DataObjectSet
|
||||||
@ -239,107 +257,6 @@ JS;
|
|||||||
$this->popupCaption = Convert::raw2js($caption);
|
$this->popupCaption = Convert::raw2js($caption);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders view, edit and add, depending on the given information.
|
|
||||||
* The form needs several parameters to function independently of its "parent-form", some derived from the context into a hidden-field,
|
|
||||||
* some derived from the parent context (which is not accessible here) and delivered by GET:
|
|
||||||
* ID, Identifier of the currently edited record (only if record is loaded).
|
|
||||||
* <parentIDName>, Link back to the correct parent record (e.g. "parentID").
|
|
||||||
* parentClass, Link back to correct container-class (the parent-record might have many 'has-one'-relationships)
|
|
||||||
* CAUTION: "ID" in the DetailForm would be the "childID" in the overview table.
|
|
||||||
*
|
|
||||||
* @param int $childID
|
|
||||||
*/
|
|
||||||
function DetailForm($childID = null) {
|
|
||||||
|
|
||||||
// Get all the requests
|
|
||||||
$ID = isset($_REQUEST['ctf']['ID']) ? Convert::raw2xml($_REQUEST['ctf']['ID']) : null;
|
|
||||||
if(!isset($childID)) $childID = isset($_REQUEST['ctf']['childID']) ? Convert::raw2xml($_REQUEST['ctf']['childID']) : null;
|
|
||||||
$childClass = Convert::raw2xml($_REQUEST['fieldName']);
|
|
||||||
$this->methodName = isset($_REQUEST['methodName']) ? $_REQUEST['methodName'] : null;
|
|
||||||
|
|
||||||
// used to discover fields if requested and for population of field
|
|
||||||
if(is_numeric($childID)) {
|
|
||||||
// we have to use the basedataclass, otherwise we might exclude other subclasses
|
|
||||||
$childData = DataObject::get_by_id(ClassInfo::baseDataClass($this->sourceClass), $childID);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the fieldset is passed, use it, else use the formfields returned
|
|
||||||
// from the object via a string method call.
|
|
||||||
if(is_a($this->detailFormFields,"Fieldset")){
|
|
||||||
$detailFields = clone $this->detailFormFields;
|
|
||||||
} else if( isset( $childData ) && is_string($this->detailFormFields)){
|
|
||||||
$functioncall = $this->detailFormFields;
|
|
||||||
if($childData->hasMethod($functioncall)){
|
|
||||||
$detailFields = $childData->$functioncall();
|
|
||||||
}
|
|
||||||
} elseif(! isset( $childData ) || $this->methodName == 'add') {
|
|
||||||
$SNG_sourceClass = singleton($this->sourceClass);
|
|
||||||
if(is_numeric($ID) && $this->getParentClass()) {
|
|
||||||
// make sure the relation-link is existing, even if we just add the sourceClass
|
|
||||||
// and didn't save it
|
|
||||||
$parentIDName = $this->getParentIdName( $this->getParentClass(), $this->sourceClass );
|
|
||||||
$SNG_sourceClass->$parentIDName = $ID;
|
|
||||||
}
|
|
||||||
$functioncall = $this->detailFormFields;
|
|
||||||
if($SNG_sourceClass->hasMethod($functioncall)){
|
|
||||||
$detailFields = $SNG_sourceClass->$functioncall();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$detailFields = $SNG_sourceClass->getCMSFields();
|
|
||||||
} else {
|
|
||||||
$detailFields = $childData->getCMSFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
if($this->getParentClass()) {
|
|
||||||
$parentIdName = $this->getParentIdName($this->getParentClass(), $this->sourceClass);
|
|
||||||
if(!$parentIdName) {
|
|
||||||
user_error("ComplexTableField::DetailForm() Cannot automatically
|
|
||||||
determine 'has-one'-relationship to parent,
|
|
||||||
please use setParentClass() to set it manually",
|
|
||||||
E_USER_WARNING);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// add relational fields
|
|
||||||
$detailFields->push(new HiddenField("ctf[parentClass]"," ",$this->getParentClass()));
|
|
||||||
|
|
||||||
if( $this->relationAutoSetting )
|
|
||||||
$detailFields->push(new HiddenField("$parentIdName"," ",$ID));
|
|
||||||
}
|
|
||||||
|
|
||||||
// the ID field confuses the Controller-logic in finding the right view for ReferencedField
|
|
||||||
$detailFields->removeByName('ID');
|
|
||||||
|
|
||||||
// only add childID if we're not adding a record
|
|
||||||
if($this->methodName != 'add') {
|
|
||||||
$detailFields->push(new HiddenField("ctf[childID]","",$childID));
|
|
||||||
}
|
|
||||||
|
|
||||||
// add a namespaced ID instead thats "converted" by saveComplexTableField()
|
|
||||||
$detailFields->push(new HiddenField("ctf[ClassName]","",$this->sourceClass));
|
|
||||||
|
|
||||||
$readonly = ($this->methodName == "show");
|
|
||||||
|
|
||||||
// if no custom validator is set, and there's on present on the object (e.g. Member), use it
|
|
||||||
if(!isset($this->detailFormValidator) && singleton($this->sourceClass)->hasMethod('getValidator')) {
|
|
||||||
$this->detailFormValidator = singleton($this->sourceClass)->getValidator();
|
|
||||||
}
|
|
||||||
|
|
||||||
$form = Object::create($this->popupClass,$this, "DetailForm", $detailFields, $this->sourceClass, $readonly, $this->detailFormValidator);
|
|
||||||
|
|
||||||
if (is_numeric($childID)) {
|
|
||||||
if ($this->methodName == "show" || $this->methodName == "edit") {
|
|
||||||
$form->loadDataFrom($childData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->methodName == "show") {
|
|
||||||
$form->makeReadonly();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $form;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $validator Validator
|
* @param $validator Validator
|
||||||
*/
|
*/
|
||||||
@ -357,67 +274,6 @@ JS;
|
|||||||
return $this->renderWith($this->template);
|
return $this->renderWith($this->template);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Just a hook, processed in {DetailForm()}
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function show() {
|
|
||||||
if($this->Can('show') !== true) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->methodName = "edit";
|
|
||||||
|
|
||||||
$this->sourceItems = $this->sourceItems();
|
|
||||||
|
|
||||||
$this->pageSize = 1;
|
|
||||||
|
|
||||||
if(isset($_REQUEST['ctf'][$this->Name()]['start']) && is_numeric($_REQUEST['ctf'][$this->Name()]['start'])) {
|
|
||||||
$this->unpagedSourceItems->setPageLimits($_REQUEST['ctf'][$this->Name()]['start'], $this->pageSize, $this->totalCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $this->renderWith($this->templatePopup);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Just a hook, processed in {DetailForm()}
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function edit() {
|
|
||||||
if($this->Can('edit') !== true) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->methodName = "edit";
|
|
||||||
|
|
||||||
$this->sourceItems = $this->sourceItems();
|
|
||||||
|
|
||||||
$this->pageSize = 1;
|
|
||||||
|
|
||||||
if(is_numeric($_REQUEST['ctf']['start'])) {
|
|
||||||
$this->unpagedSourceItems->setPageLimits($_REQUEST['ctf']['start'], $this->pageSize, $this->totalCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $this->renderWith($this->templatePopup);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Just a hook, processed in {DetailForm()}
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function add() {
|
|
||||||
if($this->Can('add') !== true) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->methodName = "add";
|
|
||||||
|
|
||||||
echo $this->renderWith($this->templatePopup);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the number of columns needed for colspans
|
* Calculates the number of columns needed for colspans
|
||||||
* used in template
|
* used in template
|
||||||
@ -449,11 +305,290 @@ JS;
|
|||||||
return ($idField->Value()) ? $idField->Value() : (isset($_REQUEST['ctf']['ID']) ? $_REQUEST['ctf']['ID'] : null);
|
return ($idField->Value()) ? $idField->Value() : (isset($_REQUEST['ctf']['ID']) ? $_REQUEST['ctf']['ID'] : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function AddLink() {
|
||||||
|
return $this->Link() . '/add';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* #################################
|
* @return FieldSet
|
||||||
* Pagination
|
|
||||||
* #################################
|
|
||||||
*/
|
*/
|
||||||
|
function createFieldSet() {
|
||||||
|
$fieldset = new FieldSet();
|
||||||
|
foreach($this->fieldTypes as $key => $fieldType){
|
||||||
|
$fieldset->push(new $fieldType($key));
|
||||||
|
}
|
||||||
|
return $fieldset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines on which relation-class the DetailForm is saved
|
||||||
|
* by looking at the surrounding form-record.
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
function getParentClass() {
|
||||||
|
if($this->parentClass === false) {
|
||||||
|
// purposely set parent-relation to false
|
||||||
|
return false;
|
||||||
|
} elseif(!empty($this->parentClass)) {
|
||||||
|
return $this->parentClass;
|
||||||
|
} else {
|
||||||
|
return $this->form->getRecord()->ClassName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (Optional) Setter for a correct parent-relation-class.
|
||||||
|
* Defaults to the record loaded into the surrounding form as a fallback.
|
||||||
|
* Caution: Please use the classname, not the actual column-name in the database.
|
||||||
|
*
|
||||||
|
* @param $className string
|
||||||
|
*/
|
||||||
|
function setParentClass($className) {
|
||||||
|
$this->parentClass = $className;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the db-fieldname of the currently used has_one-relationship.
|
||||||
|
*/
|
||||||
|
function getParentIdName( $parentClass, $childClass ) {
|
||||||
|
return $this->getParentIdNameRelation( $childClass, $parentClass, 'has_one' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manually overwrites the parent-ID relations.
|
||||||
|
* @see setParentClass()
|
||||||
|
*
|
||||||
|
* @param String $str Example: FamilyID (when one Individual has_one Family)
|
||||||
|
*/
|
||||||
|
function setParentIdName($str) {
|
||||||
|
$this->parentIdName = $str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the db-fieldname of the currently used relationship.
|
||||||
|
*/
|
||||||
|
function getParentIdNameRelation( $parentClass, $childClass, $relation ){
|
||||||
|
if($this->parentIdName) return $this->parentIdName;
|
||||||
|
|
||||||
|
$relations = singleton( $parentClass )->$relation();
|
||||||
|
$classes = ClassInfo::ancestry( $childClass );
|
||||||
|
foreach( $relations as $k => $v ) {
|
||||||
|
if( $v == $childClass )
|
||||||
|
return $k . 'ID';
|
||||||
|
else if( array_key_exists( $v, $classes ) )
|
||||||
|
return $classes[ $v ] . 'ID';
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTemplatePopup($template) {
|
||||||
|
$this->templatePopup = $template;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo Tie this into ComplexTableField_Item better.
|
||||||
|
*/
|
||||||
|
class ComplexTableField_ItemRequest extends RequestHandlingData {
|
||||||
|
protected $ctf;
|
||||||
|
protected $itemID;
|
||||||
|
protected $methodName;
|
||||||
|
|
||||||
|
static $url_handlers = array(
|
||||||
|
'$Action!' => '$Action',
|
||||||
|
'' => 'index',
|
||||||
|
);
|
||||||
|
|
||||||
|
function Link() {
|
||||||
|
return $this->ctf->Link() . '/item/' . $this->itemID;
|
||||||
|
}
|
||||||
|
|
||||||
|
function __construct($ctf, $itemID) {
|
||||||
|
$this->ctf = $ctf;
|
||||||
|
$this->itemID = $itemID;
|
||||||
|
}
|
||||||
|
|
||||||
|
function index() {
|
||||||
|
return $this->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just a hook, processed in {DetailForm()}
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
function show() {
|
||||||
|
if($this->ctf->Can('show') !== true) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->methodName = "show";
|
||||||
|
/*
|
||||||
|
$this->sourceItems = $this->ctg->sourceItems();
|
||||||
|
|
||||||
|
$this->pageSize = 1;
|
||||||
|
|
||||||
|
if(isset($_REQUEST['ctf'][$this->Name()]['start']) && is_numeric($_REQUEST['ctf'][$this->Name()]['start'])) {
|
||||||
|
$this->unpagedSourceItems->setPageLimits($_REQUEST['ctf'][$this->Name()]['start'], $this->pageSize, $this->totalCount);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo $this->renderWith($this->ctf->templatePopup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just a hook, processed in {DetailForm()}
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
function edit() {
|
||||||
|
if($this->ctf->Can('edit') !== true) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->methodName = "edit";
|
||||||
|
/*
|
||||||
|
$this->sourceItems = $this->sourceItems();
|
||||||
|
|
||||||
|
$this->pageSize = 1;
|
||||||
|
|
||||||
|
if(is_numeric($_REQUEST['ctf']['start'])) {
|
||||||
|
$this->unpagedSourceItems->setPageLimits($_REQUEST['ctf']['start'], $this->pageSize, $this->totalCount);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo $this->renderWith($this->ctf->templatePopup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just a hook, processed in {DetailForm()}
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
function add() {
|
||||||
|
if($this->Can('add') !== true) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->methodName = "add";
|
||||||
|
|
||||||
|
echo $this->renderWith($this->templatePopup);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the data object being manipulated
|
||||||
|
*/
|
||||||
|
function obj() {
|
||||||
|
// used to discover fields if requested and for population of field
|
||||||
|
if(is_numeric($this->itemID)) {
|
||||||
|
// we have to use the basedataclass, otherwise we might exclude other subclasses
|
||||||
|
return DataObject::get_by_id(ClassInfo::baseDataClass($this->ctf->sourceClass()), $this->itemID);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders view, edit and add, depending on the given information.
|
||||||
|
* The form needs several parameters to function independently of its "parent-form", some derived from the context into a hidden-field,
|
||||||
|
* some derived from the parent context (which is not accessible here) and delivered by GET:
|
||||||
|
* ID, Identifier of the currently edited record (only if record is loaded).
|
||||||
|
* <parentIDName>, Link back to the correct parent record (e.g. "parentID").
|
||||||
|
* parentClass, Link back to correct container-class (the parent-record might have many 'has-one'-relationships)
|
||||||
|
* CAUTION: "ID" in the DetailForm would be the "childID" in the overview table.
|
||||||
|
*
|
||||||
|
* @param int $childID
|
||||||
|
*/
|
||||||
|
function DetailForm($childID = null) {
|
||||||
|
$childData = $this->obj();
|
||||||
|
|
||||||
|
// If the fieldset is passed, use it, else use the formfields returned
|
||||||
|
// from the object via a string method call.
|
||||||
|
if(is_a($this->ctf->detailFormFields,"Fieldset")){
|
||||||
|
$detailFields = $this->detailFormFields;
|
||||||
|
|
||||||
|
} else if( isset( $childData ) && is_string($this->ctf->detailFormFields)){
|
||||||
|
$functioncall = $this->ctf->detailFormFields;
|
||||||
|
if($childData->hasMethod($functioncall)){
|
||||||
|
$detailFields = $childData->$functioncall();
|
||||||
|
}
|
||||||
|
|
||||||
|
} elseif(! isset( $childData ) || $this->methodName == 'add') {
|
||||||
|
$SNG_sourceClass = singleton($this->ctf->sourceClass());
|
||||||
|
if($childData && is_numeric($childData->ID) && $this->ctf->getParentClass()) {
|
||||||
|
// make sure the relation-link is existing, even if we just add the sourceClass
|
||||||
|
// and didn't save it
|
||||||
|
$parentIDName = $this->ctf->getParentIdName( $this->getParentClass(), $this->sourceClass() );
|
||||||
|
$SNG_sourceClass->$parentIDName = $childData->ID;
|
||||||
|
}
|
||||||
|
$functioncall = $this->detailFormFields;
|
||||||
|
if($SNG_sourceClass->hasMethod($functioncall)){
|
||||||
|
$detailFields = $SNG_sourceClass->$functioncall();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
$detailFields = $SNG_sourceClass->getCMSFields();
|
||||||
|
} else {
|
||||||
|
$detailFields = $childData->getCMSFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->ctf->getParentClass()) {
|
||||||
|
$parentIdName = $this->ctf->getParentIdName($this->ctf->getParentClass(), $this->ctf->sourceClass());
|
||||||
|
/*
|
||||||
|
if(!$parentIdName) {
|
||||||
|
user_error("ComplexTableField::DetailForm() Cannot automatically
|
||||||
|
determine 'has-one'-relationship to parent class " . $this->ctf->getParentClass() . ",
|
||||||
|
please use setParentClass() to set it manually",
|
||||||
|
E_USER_WARNING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if($parentIdName) {
|
||||||
|
// add relational fields
|
||||||
|
$detailFields->push(new HiddenField("ctf[parentClass]"," ",$this->ctf->getParentClass()));
|
||||||
|
|
||||||
|
if( $this->relationAutoSetting )
|
||||||
|
$detailFields->push(new HiddenField("$parentIdName"," ",$childData->ID));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the ID field confuses the Controller-logic in finding the right view for ReferencedField
|
||||||
|
$detailFields->removeByName('ID');
|
||||||
|
|
||||||
|
// only add childID if we're not adding a record
|
||||||
|
if($this->methodName != 'add') {
|
||||||
|
$detailFields->push(new HiddenField("ctf[childID]","",$childData->ID));
|
||||||
|
}
|
||||||
|
|
||||||
|
// add a namespaced ID instead thats "converted" by saveComplexTableField()
|
||||||
|
$detailFields->push(new HiddenField("ctf[ClassName]","",$this->ctf->sourceClass()));
|
||||||
|
|
||||||
|
$readonly = ($this->methodName == "show");
|
||||||
|
|
||||||
|
// if no custom validator is set, and there's on present on the object (e.g. Member), use it
|
||||||
|
if(!isset($this->ctf->detailFormValidator) && singleton($this->ctf->sourceClass())->hasMethod('getValidator')) {
|
||||||
|
$this->ctf->detailFormValidator = singleton($this->ctf->sourceClass())->getValidator();
|
||||||
|
}
|
||||||
|
|
||||||
|
$form = Object::create($this->ctf->popupClass,$this, "DetailForm", $detailFields, $this->ctf->detailFormValidator, $readonly, $childData);
|
||||||
|
|
||||||
|
if (is_numeric($childData->ID)) {
|
||||||
|
if ($this->methodName == "show" || $this->methodName == "edit") {
|
||||||
|
$form->loadDataFrom($childData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->methodName == "show") {
|
||||||
|
$form->makeReadonly();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $form;
|
||||||
|
}
|
||||||
|
|
||||||
function PopupBaseLink() {
|
function PopupBaseLink() {
|
||||||
$link = $this->FormAction() . "&action_callfieldmethod&fieldName={$this->Name()}";
|
$link = $this->FormAction() . "&action_callfieldmethod&fieldName={$this->Name()}";
|
||||||
if(!strpos($link,'ctf[ID]')) {
|
if(!strpos($link,'ctf[ID]')) {
|
||||||
@ -560,49 +695,8 @@ JS;
|
|||||||
|
|
||||||
return implode(" ", $items);
|
return implode(" ", $items);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function AddLink() {
|
|
||||||
return Convert::raw2att("{$this->PopupBaseLink()}&methodName=add");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return FieldSet
|
|
||||||
*/
|
|
||||||
function createFieldSet() {
|
|
||||||
$fieldset = new FieldSet();
|
|
||||||
foreach($this->fieldTypes as $key => $fieldType){
|
|
||||||
$fieldset->push(new $fieldType($key));
|
|
||||||
}
|
|
||||||
return $fieldset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines on which relation-class the DetailForm is saved
|
|
||||||
* by looking at the surrounding form-record.
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function getParentClass() {
|
|
||||||
if($this->parentClass === false) {
|
|
||||||
// purposely set parent-relation to false
|
|
||||||
return false;
|
|
||||||
} elseif(!empty($this->parentClass)) {
|
|
||||||
return $this->parentClass;
|
|
||||||
} else {
|
|
||||||
return $this->form->getRecord()->ClassName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* (Optional) Setter for a correct parent-relation-class.
|
|
||||||
* Defaults to the record loaded into the surrounding form as a fallback.
|
|
||||||
* Caution: Please use the classname, not the actual column-name in the database.
|
|
||||||
*
|
|
||||||
* @param $className string
|
|
||||||
*/
|
|
||||||
function setParentClass($className) {
|
|
||||||
$this->parentClass = $className;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the db-fieldname of the currently used has_one-relationship.
|
* Returns the db-fieldname of the currently used has_one-relationship.
|
||||||
@ -659,20 +753,20 @@ class ComplexTableField_Item extends TableListField_Item {
|
|||||||
parent::__construct($item, $parent);
|
parent::__construct($item, $parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
function PopupBaseLink() {
|
function Link() {
|
||||||
return $this->parent->FormAction() . "&action_callfieldmethod&fieldName={$this->parent->Name()}&ctf[childID]={$this->item->ID}&ctf[ID]={$this->parent->sourceID()}&ctf[start]={$this->start}";
|
return $this->parent->Link() . '/item/' . $this->item->ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
function EditLink() {
|
function EditLink() {
|
||||||
return Convert::raw2att($this->PopupBaseLink() . "&methodName=edit");
|
return $this->Link() . "/edit";
|
||||||
}
|
}
|
||||||
|
|
||||||
function ShowLink() {
|
function ShowLink() {
|
||||||
return Convert::raw2att($this->PopupBaseLink() . "&methodName=show");
|
return $this->Link() . "/show";
|
||||||
}
|
}
|
||||||
|
|
||||||
function DeleteLink() {
|
function DeleteLink() {
|
||||||
return Convert::raw2att($this->PopupBaseLink() . "&methodName=delete");
|
return $this->Link() . "/delete";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,8 +781,10 @@ class ComplexTableField_Item extends TableListField_Item {
|
|||||||
*/
|
*/
|
||||||
class ComplexTableField_Popup extends Form {
|
class ComplexTableField_Popup extends Form {
|
||||||
protected $sourceClass;
|
protected $sourceClass;
|
||||||
|
protected $dataObject;
|
||||||
|
|
||||||
function __construct($controller, $name, $field, $sourceClass, $readonly=false, $validator = null) {
|
function __construct($controller, $name, $fields, $validator, $readonly, $dataObject) {
|
||||||
|
$this->dataObject = $dataObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WARNING: DO NOT CHANGE THE ORDER OF THESE JS FILES
|
* WARNING: DO NOT CHANGE THE ORDER OF THESE JS FILES
|
||||||
@ -715,9 +811,8 @@ class ComplexTableField_Popup extends Form {
|
|||||||
Requirements::javascript("sapphire/javascript/ComplexTableField.js");
|
Requirements::javascript("sapphire/javascript/ComplexTableField.js");
|
||||||
Requirements::javascript("sapphire/javascript/ComplexTableField_popup.js");
|
Requirements::javascript("sapphire/javascript/ComplexTableField_popup.js");
|
||||||
|
|
||||||
$this->sourceClass = $sourceClass;
|
if($this->dataObject->hasMethod('getRequirementsForPopup')) {
|
||||||
if(singleton($sourceClass)->hasMethod('getRequirementsForPopup')){
|
$this->data->getRequirementsForPopup();
|
||||||
singleton($sourceClass)->getRequirementsForPopup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$actions = new FieldSet();
|
$actions = new FieldSet();
|
||||||
@ -728,7 +823,7 @@ class ComplexTableField_Popup extends Form {
|
|||||||
$saveAction->addExtraClass('save');
|
$saveAction->addExtraClass('save');
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct($controller, $name, $field, $actions, $validator);
|
parent::__construct($controller, $name, $fields, $actions, $validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
function FieldHolder() {
|
function FieldHolder() {
|
||||||
@ -748,22 +843,15 @@ class ComplexTableField_Popup extends Form {
|
|||||||
*
|
*
|
||||||
* @see {Form::ReferencedField}).
|
* @see {Form::ReferencedField}).
|
||||||
*/
|
*/
|
||||||
function saveComplexTableField() {
|
function saveComplexTableField($params) {
|
||||||
if(isset($_REQUEST['ctf']['childID']) && is_numeric($_REQUEST['ctf']['childID'])) {
|
$this->saveInto($this->dataObject);
|
||||||
$childObject = DataObject::get_by_id($this->sourceClass, $_REQUEST['ctf']['childID']);
|
$this->dataObject->write();
|
||||||
} else {
|
|
||||||
$childObject = new $this->sourceClass();
|
|
||||||
$this->fields->removeByName('ID');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->saveInto($childObject);
|
|
||||||
$childObject->write();
|
|
||||||
|
|
||||||
// if ajax-call in an iframe, update window
|
// if ajax-call in an iframe, update window
|
||||||
if(Director::is_ajax()) {
|
if(Director::is_ajax()) {
|
||||||
// Newly saved objects need their ID reflected in the reloaded form to avoid double saving
|
// Newly saved objects need their ID reflected in the reloaded form to avoid double saving
|
||||||
$form = $this->controller->DetailForm($childObject->ID);
|
$form = $this->controller->DetailForm();
|
||||||
$form->loadDataFrom($childObject);
|
//$form->loadDataFrom($this->dataObject);
|
||||||
FormResponse::update_dom_id($form->FormName(), $form->formHtmlContent(), true, 'update');
|
FormResponse::update_dom_id($form->FormName(), $form->formHtmlContent(), true, 'update');
|
||||||
return FormResponse::respond();
|
return FormResponse::respond();
|
||||||
} else {
|
} else {
|
||||||
|
@ -117,6 +117,7 @@ class Form extends RequestHandlingData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static $url_handlers = array(
|
static $url_handlers = array(
|
||||||
|
'field/$FieldName!' => 'handleField',
|
||||||
'POST ' => 'httpSubmission',
|
'POST ' => 'httpSubmission',
|
||||||
'GET ' => 'httpSubmission',
|
'GET ' => 'httpSubmission',
|
||||||
);
|
);
|
||||||
@ -126,7 +127,6 @@ class Form extends RequestHandlingData {
|
|||||||
*/
|
*/
|
||||||
function httpSubmission($request) {
|
function httpSubmission($request) {
|
||||||
$vars = $request->requestVars();
|
$vars = $request->requestVars();
|
||||||
|
|
||||||
if(isset($funcName)) {
|
if(isset($funcName)) {
|
||||||
Form::set_current_action($funcName);
|
Form::set_current_action($funcName);
|
||||||
}
|
}
|
||||||
@ -170,7 +170,7 @@ class Form extends RequestHandlingData {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the action wasnt' set, choose the default on the form.
|
// If the action wasnt' set, choose the default on the form.
|
||||||
if(!isset($funcName) && $defaultAction = $this->defaultAction()){
|
if(!isset($funcName) && $defaultAction = $this->defaultAction()){
|
||||||
$funcName = $defaultAction->actionName();
|
$funcName = $defaultAction->actionName();
|
||||||
@ -189,6 +189,13 @@ class Form extends RequestHandlingData {
|
|||||||
return $this->$funcName($vars, $this);
|
return $this->$funcName($vars, $this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a field request
|
||||||
|
*/
|
||||||
|
function handleField($request) {
|
||||||
|
return $this->dataFieldByName($request->param('FieldName'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert this form into a readonly form
|
* Convert this form into a readonly form
|
||||||
@ -461,8 +468,10 @@ class Form extends RequestHandlingData {
|
|||||||
function FormAction() {
|
function FormAction() {
|
||||||
if($this->controller->hasMethod("FormObjectLink")) {
|
if($this->controller->hasMethod("FormObjectLink")) {
|
||||||
return $this->controller->FormObjectLink($this->name);
|
return $this->controller->FormObjectLink($this->name);
|
||||||
} else {
|
} else {
|
||||||
return $this->controller->Link() . $this->name;
|
$link = $this->controller->Link();
|
||||||
|
if(substr($link,-1) != '/') $link .= '/';
|
||||||
|
return $link . $this->name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +60,13 @@ class FormField extends RequestHandlingData {
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a Link to this field
|
||||||
|
*/
|
||||||
|
function Link() {
|
||||||
|
return $this->form->FormAction() . '/field/' . $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the HTML ID of the field - used in the template by label tags.
|
* Returns the HTML ID of the field - used in the template by label tags.
|
||||||
* The ID is generated as FormName_FieldName. All Field functions should ensure
|
* The ID is generated as FormName_FieldName. All Field functions should ensure
|
||||||
|
@ -72,6 +72,8 @@ ComplexTableField.prototype = {
|
|||||||
popupLink = _popupLink;
|
popupLink = _popupLink;
|
||||||
table = _table;
|
table = _table;
|
||||||
} else {
|
} else {
|
||||||
|
alert(this.innerHTML);
|
||||||
|
|
||||||
// if clicked item is an input-element, don't trigger popup
|
// if clicked item is an input-element, don't trigger popup
|
||||||
var el = Event.element(e);
|
var el = Event.element(e);
|
||||||
var input = Event.findElement(e,"input");
|
var input = Event.findElement(e,"input");
|
||||||
@ -110,10 +112,6 @@ ComplexTableField.prototype = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($('SecurityID')) {
|
|
||||||
popupLink = popupLink + '&SecurityID=' + $('SecurityID').value;
|
|
||||||
}
|
|
||||||
|
|
||||||
GB_OpenerObj = this;
|
GB_OpenerObj = this;
|
||||||
// use same url to refresh the table after saving the popup, but use a generic rendering method
|
// use same url to refresh the table after saving the popup, but use a generic rendering method
|
||||||
GB_RefreshLink = popupLink;
|
GB_RefreshLink = popupLink;
|
||||||
@ -121,6 +119,7 @@ ComplexTableField.prototype = {
|
|||||||
// dont include pagination index
|
// dont include pagination index
|
||||||
GB_RefreshLink = GB_RefreshLink.replace(/ctf\[start\][^&]*/,"");
|
GB_RefreshLink = GB_RefreshLink.replace(/ctf\[start\][^&]*/,"");
|
||||||
GB_RefreshLink += '&forcehtml=1';
|
GB_RefreshLink += '&forcehtml=1';
|
||||||
|
|
||||||
if(this.GB_Caption) {
|
if(this.GB_Caption) {
|
||||||
var title = this.GB_Caption;
|
var title = this.GB_Caption;
|
||||||
} else {
|
} else {
|
||||||
|
@ -58,6 +58,7 @@ ComplexTableFieldPopupForm.prototype = {
|
|||||||
|
|
||||||
// don't update when validation is present and failed
|
// don't update when validation is present and failed
|
||||||
if(!this.validate || (this.validate && !hasHadFormError())) {
|
if(!this.validate || (this.validate && !hasHadFormError())) {
|
||||||
|
alert("GB:" + parent.parent.GB_RefreshLink);
|
||||||
new parent.parent.Ajax.Request(
|
new parent.parent.Ajax.Request(
|
||||||
parent.parent.GB_RefreshLink,
|
parent.parent.GB_RefreshLink,
|
||||||
{
|
{
|
||||||
|
1
main.php
1
main.php
@ -140,7 +140,6 @@ if(substr($url,0,strlen($baseURL)) == $baseURL) $url = substr($url,strlen($baseU
|
|||||||
|
|
||||||
// Direct away - this is the "main" function, that hands control to the appropriate controller
|
// Direct away - this is the "main" function, that hands control to the appropriate controller
|
||||||
if(isset($_GET['debug_profile'])) Profiler::unmark('main.php init');
|
if(isset($_GET['debug_profile'])) Profiler::unmark('main.php init');
|
||||||
|
|
||||||
Director::direct($url);
|
Director::direct($url);
|
||||||
|
|
||||||
if(isset($_GET['debug_profile'])) {
|
if(isset($_GET['debug_profile'])) {
|
||||||
|
@ -269,7 +269,7 @@ class Security extends Controller {
|
|||||||
$tmpPage->URLSegment = "Security";
|
$tmpPage->URLSegment = "Security";
|
||||||
$tmpPage->ID = -1; // Set the page ID to -1 so we dont get the top level pages as its children
|
$tmpPage->ID = -1; // Set the page ID to -1 so we dont get the top level pages as its children
|
||||||
|
|
||||||
$controller = new Page_Controller($this->urlParams, $this->urlTokeniser, $tmpPage);
|
$controller = new Page_Controller($tmpPage);
|
||||||
$controller->init();
|
$controller->init();
|
||||||
//Controller::$currentController = $controller;
|
//Controller::$currentController = $controller;
|
||||||
|
|
||||||
|
@ -34,8 +34,9 @@
|
|||||||
<a href="$PopupNextLink"><% _t('NEXT', 'Next') %><img src="cms/images/pagination/record-next.png" /></a>
|
<a href="$PopupNextLink"><% _t('NEXT', 'Next') %><img src="cms/images/pagination/record-next.png" /></a>
|
||||||
</td>
|
</td>
|
||||||
<% end_if %>
|
<% end_if %>
|
||||||
</td>
|
</tr>
|
||||||
<% end_if %>
|
</table>
|
||||||
<% end_if %>
|
<% end_if %>
|
||||||
|
<% end_if %>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user