(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@59927 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2008-08-06 03:43:48 +00:00
parent 4fae9902e1
commit aeab0115a0
6 changed files with 135 additions and 15 deletions

View File

@ -389,18 +389,48 @@ class Object {
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/** /**
* Run the given function on all of this object's extensions * Invokes a method on the object itself, or proxied through a decorator.
*
* This method breaks the normal rules of inheritance, and aggregates everything
* in the returned result. If the invoked methods return void, they are still recorded as
* empty array keys.
*
* @todo find a better way of integrating inheritance rules
*
* @param unknown_type $funcName
* @param unknown_type $arg
*/
public function invokeWithExtensions($funcName, $arg=null) {
$results = array();
if (method_exists($this, $funcName)) {
$results[] = $this->$funcName($arg);
}
$extras = $this->extend($funcName, $arg);
if ($extras) {
return array_merge($results, $extras);
} else {
return $results;
}
}
/**
* Run the given function on all of this object's extensions. Note that this method
* originally returned void, so if you wanted to return results, you're hosed.
*
* Currently returns an array, with an index resulting every time the function is called.
* *
* @param string $funcName The name of the function. * @param string $funcName The name of the function.
* @param mixed $arg An Argument to be passed to each of the extension functions. * @param mixed $arg An Argument to be passed to each of the extension functions.
*/ */
public function extend($funcName, &$arg) { public function extend($funcName, &$arg=null) {
if($this->extension_instances) { if($this->extension_instances) {
$return = array();
foreach($this->extension_instances as $extension) { foreach($this->extension_instances as $extension) {
if($extension->hasMethod($funcName)) { if($extension->hasMethod($funcName)) {
$extension->$funcName($arg); $return[] = $extension->$funcName($arg);
} }
} }
return $return;
} }
} }

View File

@ -1148,11 +1148,18 @@ class DataObject extends ViewableData implements DataObjectInterface {
*/ */
public function scaffoldSearchFields() { public function scaffoldSearchFields() {
$fields = new FieldSet(); $fields = new FieldSet();
foreach($this->databaseFields() as $fieldName => $fieldType) { foreach($this->searchableFields() as $fieldName => $fieldType) {
// @todo Pass localized title // @todo Pass localized title
$fields->push($this->dbObject($fieldName)->scaffoldSearchField()); $fields->push($this->dbObject($fieldName)->scaffoldSearchField());
} }
$extras = $this->invokeWithExtensions('extraSearchFields');
if ($extras) {
foreach($extras as $result) {
foreach($result as $fieldName => $fieldType) {
$fields->push(new $fieldType($fieldName));
}
}
}
return $fields; return $fields;
} }
@ -1165,9 +1172,13 @@ class DataObject extends ViewableData implements DataObjectInterface {
*/ */
public function scaffoldFormFields() { public function scaffoldFormFields() {
$fields = new FieldSet(); $fields = new FieldSet();
foreach($this->databaseFields() as $fieldName => $fieldType) {
foreach($this->inheritedDatabaseFields() as $fieldName => $fieldType) {
// @todo Pass localized title // @todo Pass localized title
$fields->addFieldToTab('Root.Main', $this->dbObject($fieldName)->scaffoldFormField()); // commented out, to be less of a pain in the ass
//$fields->addFieldToTab('Root.Main', $this->dbObject($fieldName)->scaffoldFormField());
$fields->push($this->dbObject($fieldName)->scaffoldFormField());
} }
// @todo Add relation tabs // @todo Add relation tabs
@ -1953,6 +1964,56 @@ class DataObject extends ViewableData implements DataObjectInterface {
return $def; return $def;
} }
/**
* Returns fields bu traversing the class heirachy in a bottom-up direction.
*
* Needed to avoid getCMSFields being empty when customDatabaseFields overlooks
* the inheritance chain of the $db array, where a child data object has no $db array,
* but still needs to know the properties of its parent. This should be merged into databaseFields or
* customDatabaseFields.
*
* @todo integrate with pre-existing crap
*/
public function inheritedDatabaseFields() {
$fields = array();
$currentObj = $this;
while(get_class($currentObj) != 'DataObject') {
$fields = array_merge($fields, $currentObj->customDatabaseFields());
$currentObj = singleton($currentObj->parentClass());
}
return $fields;
}
/**
* Get the default searchable fields for this object,
* excluding any fields that are specifically overriden
* in the data object itself.
*
* @todo rename $searchable to $excluded
* @todo overcomplicated, should be simpler way of looking up whether specific fields are supposed to be searchable or not
*/
public function searchableFields() {
$parents = ClassInfo::dataClassesFor($this);
$fields = array();
$searchable = array();
foreach($parents as $class) {
$fields = array_merge($fields, singleton($class)->stat('db'));
$obj = singleton($class);
$results = $obj->invokeWithExtensions('excludeFromSearch');
if ($results) {
foreach($results as $result) {
if (is_array($result)) {
$searchable = array_merge($searchable, $result);
}
}
}
}
foreach($searchable as $field) {
unset($fields[$field]);
}
return $fields;
}
/** /**
* @return boolean True if the object is in the database * @return boolean True if the object is in the database
*/ */
@ -2082,7 +2143,8 @@ class DataObject extends ViewableData implements DataObjectInterface {
* @var string * @var string
*/ */
public static $default_sort = null; public static $default_sort = null;
} }
?> ?>

View File

@ -18,7 +18,7 @@ class DropdownField extends FormField {
* @param $emptyString mixed Add an empty selection on to of the {source}-Array * @param $emptyString mixed Add an empty selection on to of the {source}-Array
* (can also be boolean, which results in an empty string) * (can also be boolean, which results in an empty string)
*/ */
function __construct($name, $title = "", $source = array(), $value = "", $form = null, $emptyString = null) { function __construct($name, $title = null, $source = array(), $value = "", $form = null, $emptyString = null) {
if(is_string($emptyString)) { if(is_string($emptyString)) {
$source = is_array($source) ? array(""=>$emptyString) + $source : array(""=>$emptyString); $source = is_array($source) ? array(""=>$emptyString) + $source : array(""=>$emptyString);
} elseif($emptyString === true) { } elseif($emptyString === true) {
@ -26,7 +26,7 @@ class DropdownField extends FormField {
} }
$this->source = $source; $this->source = $source;
parent::__construct($name, $title, $value, $form); parent::__construct($name, ($title===null) ? $name : $title, $value, $form);
} }
/** /**

View File

@ -138,7 +138,7 @@ class FieldSet extends DataObjectSet {
// Create any missing tabs // Create any missing tabs
if(!$currentPointer) { if(!$currentPointer) {
if(is_a($parentPointer,'TabSet')) { if(is_a($parentPointer,'TabSet')) {
$currentPointer = new Tab($part); $currentPointer = new Tab($tabName);
$parentPointer->push($currentPointer); $parentPointer->push($currentPointer);
} else { } else {
user_error("FieldSet::addFieldToTab() Tried to add a tab to a " . $parentPointer->class . " object - '$part' didn't exist.", E_USER_ERROR); user_error("FieldSet::addFieldToTab() Tried to add a tab to a " . $parentPointer->class . " object - '$part' didn't exist.", E_USER_ERROR);

View File

@ -11,14 +11,14 @@ class PhoneNumberField extends FormField {
protected $countryCode; protected $countryCode;
protected $ext; protected $ext;
public function __construct( $name, $title, $value = '', $extension = null, public function __construct( $name, $title = null, $value = '', $extension = null,
$areaCode = null, $countryCode = null, $form = null ) { $areaCode = null, $countryCode = null, $form = null ) {
$this->areaCode = $areaCode; $this->areaCode = $areaCode;
$this->ext = $extension; $this->ext = $extension;
$this->countryCode = $countryCode; $this->countryCode = $countryCode;
parent::__construct( $name, $title, $value, $form ); parent::__construct( $name, ($title===null) ? $name : $title, $value, $form );
} }
public function Field() { public function Field() {
@ -82,6 +82,8 @@ class PhoneNumberField extends FormField {
$parts = array_pad($parts, 4, false); $parts = array_pad($parts, 4, false);
} }
if(sizeof($parts) < 4) $parts[] = '';
return $parts; return $parts;
} }

View File

@ -148,6 +148,32 @@ class SearchContext extends Object {
$this->filters = $filters; $this->filters = $filters;
} }
function clearEmptySearchFields($value) {
return ($value != '');
}
/**
* Placeholder, until I figure out the rest of the SQLQuery stuff
* and link the $searchable_fields array to the SearchContext
*/
public function getResultSet($fields) {
$filter = "";
$current = 1;
$fields = array_filter($fields, array($this,'clearEmptySearchFields'));
$length = count($fields);
foreach($fields as $key=>$val) {
if ($val != '') {
$filter .= "`$key`='$val'";
} else {
$length--;
}
if ($current < $length) {
$filter .= " AND ";
}
$current++;
}
return DataObject::get($this->modelClass, $filter);
}
} }
?> ?>