mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02: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@59927 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
4fae9902e1
commit
aeab0115a0
@ -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 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) {
|
||||
$return = array();
|
||||
foreach($this->extension_instances as $extension) {
|
||||
if($extension->hasMethod($funcName)) {
|
||||
$extension->$funcName($arg);
|
||||
$return[] = $extension->$funcName($arg);
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1148,11 +1148,18 @@ class DataObject extends ViewableData implements DataObjectInterface {
|
||||
*/
|
||||
public function scaffoldSearchFields() {
|
||||
$fields = new FieldSet();
|
||||
foreach($this->databaseFields() as $fieldName => $fieldType) {
|
||||
foreach($this->searchableFields() as $fieldName => $fieldType) {
|
||||
// @todo Pass localized title
|
||||
$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;
|
||||
}
|
||||
|
||||
@ -1165,9 +1172,13 @@ class DataObject extends ViewableData implements DataObjectInterface {
|
||||
*/
|
||||
public function scaffoldFormFields() {
|
||||
$fields = new FieldSet();
|
||||
foreach($this->databaseFields() as $fieldName => $fieldType) {
|
||||
|
||||
foreach($this->inheritedDatabaseFields() as $fieldName => $fieldType) {
|
||||
|
||||
// @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
|
||||
@ -1953,6 +1964,56 @@ class DataObject extends ViewableData implements DataObjectInterface {
|
||||
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
|
||||
*/
|
||||
@ -2082,7 +2143,8 @@ class DataObject extends ViewableData implements DataObjectInterface {
|
||||
* @var string
|
||||
*/
|
||||
public static $default_sort = null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
||||
|
@ -18,7 +18,7 @@ class DropdownField extends FormField {
|
||||
* @param $emptyString mixed Add an empty selection on to of the {source}-Array
|
||||
* (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)) {
|
||||
$source = is_array($source) ? array(""=>$emptyString) + $source : array(""=>$emptyString);
|
||||
} elseif($emptyString === true) {
|
||||
@ -26,7 +26,7 @@ class DropdownField extends FormField {
|
||||
}
|
||||
$this->source = $source;
|
||||
|
||||
parent::__construct($name, $title, $value, $form);
|
||||
parent::__construct($name, ($title===null) ? $name : $title, $value, $form);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,7 +138,7 @@ class FieldSet extends DataObjectSet {
|
||||
// Create any missing tabs
|
||||
if(!$currentPointer) {
|
||||
if(is_a($parentPointer,'TabSet')) {
|
||||
$currentPointer = new Tab($part);
|
||||
$currentPointer = new Tab($tabName);
|
||||
$parentPointer->push($currentPointer);
|
||||
} else {
|
||||
user_error("FieldSet::addFieldToTab() Tried to add a tab to a " . $parentPointer->class . " object - '$part' didn't exist.", E_USER_ERROR);
|
||||
|
@ -11,14 +11,14 @@ class PhoneNumberField extends FormField {
|
||||
protected $countryCode;
|
||||
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 ) {
|
||||
|
||||
$this->areaCode = $areaCode;
|
||||
$this->ext = $extension;
|
||||
$this->countryCode = $countryCode;
|
||||
|
||||
parent::__construct( $name, $title, $value, $form );
|
||||
parent::__construct( $name, ($title===null) ? $name : $title, $value, $form );
|
||||
}
|
||||
|
||||
public function Field() {
|
||||
@ -82,6 +82,8 @@ class PhoneNumberField extends FormField {
|
||||
$parts = array_pad($parts, 4, false);
|
||||
}
|
||||
|
||||
if(sizeof($parts) < 4) $parts[] = '';
|
||||
|
||||
return $parts;
|
||||
}
|
||||
|
||||
|
@ -148,6 +148,32 @@ class SearchContext extends Object {
|
||||
$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);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
Loading…
Reference in New Issue
Block a user