Making TreeMultiSelectField consistent with parent class

NEW TreeDropdownField sanatiser helper added
Use config for default_cast of objects
FIX Determine if Diffed value should be escaped
Forcing casting for core DB fields
Fixing permissions labels
This commit is contained in:
Daniel Hensby 2015-02-07 23:00:36 +00:00 committed by Damian Mooyman
parent e7dbb27498
commit 89c14d079d
9 changed files with 64 additions and 36 deletions

View File

@ -94,12 +94,32 @@ class TreeDropdownField extends FormField {
$this->keyField = $keyField; $this->keyField = $keyField;
$this->labelField = $labelField; $this->labelField = $labelField;
$this->showSearch = $showSearch; $this->showSearch = $showSearch;
$this->addExtraClass('single');
parent::__construct($name, $title); parent::__construct($name, $title);
} }
/** /**
* Set the ID of the root node of the tree. This defaults to 0 - i.e. * Helper for the front end to know if we should escape the label value
*
* @return bool Whether the label field should be escaped
*/
public function getEscapeLabelField() {
// be defensive
$escape = true;
$sourceClass = $this->getSourceObject();
//if it's an array, then it's an explicit set of values and we have to assume they've escaped their values already
//if the field is cast as XML, then we don't need to escape
if (is_array($sourceClass) || (is_a($sourceClass, 'ViewableData', true) && singleton($sourceClass)->escapeTypeForField($this->getLabelField()) == 'xml')) {
$escape = false;
}
return $escape;
}
/**
* Set the ID of the root node of the tree. This defaults to 0 - i.e.
* displays the whole tree. * displays the whole tree.
* *
* @param int $ID * @param int $ID

View File

@ -46,6 +46,8 @@
class TreeMultiselectField extends TreeDropdownField { class TreeMultiselectField extends TreeDropdownField {
public function __construct($name, $title=null, $sourceObject="Group", $keyField="ID", $labelField="Title") { public function __construct($name, $title=null, $sourceObject="Group", $keyField="ID", $labelField="Title") {
parent::__construct($name, $title, $sourceObject, $keyField, $labelField); parent::__construct($name, $title, $sourceObject, $keyField, $labelField);
$this->removeExtraClass('single');
$this->addExtraClass('multiple');
$this->value = 'unchanged'; $this->value = 'unchanged';
} }
@ -103,7 +105,11 @@ class TreeMultiselectField extends TreeDropdownField {
if($items && count($items)) { if($items && count($items)) {
foreach($items as $id => $item) { foreach($items as $id => $item) {
$titleArray[] = $item->Title; $title = $item->Title;
if ($item instanceof ViewableData && $item->escapeTypeForField('Title') != 'xml') {
$title = Convert::raw2xml($title);
}
$titleArray[] = $title;
$idArray[] = $item->ID; $idArray[] = $item->ID;
} }
@ -118,30 +124,18 @@ class TreeMultiselectField extends TreeDropdownField {
$dataUrlTree = ''; $dataUrlTree = '';
if ($this->form){ if ($this->form){
$dataUrlTree = $this->Link('tree'); $dataUrlTree = $this->Link('tree');
if (isset($idArray) && count($idArray)){ if (!empty($idArray)){
$dataUrlTree = Controller::join_links($dataUrlTree, '?forceValue='.implode(',',$idArray)); $dataUrlTree = Controller::join_links($dataUrlTree, '?forceValue='.implode(',',$idArray));
} }
} }
return FormField::create_tag( $properties = array_merge(
'div', $properties,
array ( array(
'id' => "TreeDropdownField_{$this->id()}", 'Title' => $title,
'class' => 'TreeDropdownField multiple' . ($this->extraClass() ? " {$this->extraClass()}" : '') 'Link' => $dataUrlTree,
. ($this->showSearch ? " searchable" : ''),
'data-url-tree' => $dataUrlTree,
'data-title' => $title,
'title' => $this->getDescription()
),
FormField::create_tag(
'input',
array (
'id' => $this->id(),
'type' => 'hidden',
'name' => $this->name,
'value' => $value
)
) )
); );
return $this->customise($properties)->renderWith('TreeDropdownField');
} }
/** /**

View File

@ -192,6 +192,10 @@ class GridFieldPrintButton implements GridField_HTMLProvider, GridField_ActionPr
foreach($printColumns as $field => $label) { foreach($printColumns as $field => $label) {
$value = $gridField->getDataFieldValue($item, $field); $value = $gridField->getDataFieldValue($item, $field);
if ($item->escapeTypeForField('Title') != 'xml') {
$value = Convert::raw2xml($value);
}
$itemRow->push(new ArrayData(array( $itemRow->push(new ArrayData(array(
"CellString" => $value, "CellString" => $value,
))); )));

View File

@ -139,9 +139,11 @@
}, },
setTitle: function(title) { setTitle: function(title) {
title = title || this.data('title') || strings.fieldTitle; title = title || this.data('title') || strings.fieldTitle;
this.find('.treedropdownfield-title').html(title); var func = this.data('escape-label-field') ? 'text' : 'html';
this.data('title', title); // separate view from storage (important for search cancellation)
this.find('.treedropdownfield-title')[func](title);
this.data('title', title); // separate view from storage (important for search cancellation)
}, },
getTitle: function() { getTitle: function() {
return this.find('.treedropdownfield-title').text(); return this.find('.treedropdownfield-title').text();

View File

@ -85,10 +85,15 @@ class DataDifferencer extends ViewableData {
if(in_array($field, $this->ignoredFields)) continue; if(in_array($field, $this->ignoredFields)) continue;
if(in_array($field, array_keys($hasOnes))) continue; if(in_array($field, array_keys($hasOnes))) continue;
$escape = false;
if ($this->toRecord->escapeTypeForField($field) != 'xml') {
$escape = true;
}
if(!$this->fromRecord) { if(!$this->fromRecord) {
$diffed->setField($field, "<ins>" . $this->toRecord->$field . "</ins>"); $val = $escape ? Convert::raw2xml($this->toRecord->$field) : $this->toRecord->$field;
$diffed->setField($field, "<ins>" . $val . "</ins>");
} else if($this->fromRecord->$field != $this->toRecord->$field) { } else if($this->fromRecord->$field != $this->toRecord->$field) {
$diffed->setField($field, Diff::compareHTML($this->fromRecord->$field, $this->toRecord->$field)); $diffed->setField($field, Diff::compareHTML($this->fromRecord->$field, $this->toRecord->$field, $escape));
} }
} }

View File

@ -3435,6 +3435,8 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
* @var array * @var array
*/ */
private static $casting = array( private static $casting = array(
"ID" => 'Int',
"ClassName" => 'Varchar',
"LastEdited" => "SS_Datetime", "LastEdited" => "SS_Datetime",
"Created" => "SS_Datetime", "Created" => "SS_Datetime",
"Title" => 'Text', "Title" => 'Text',

View File

@ -99,7 +99,7 @@ class PermissionCheckboxSetField extends FormField {
if(!isset($uninheritedCodes[$permission->Code])) $uninheritedCodes[$permission->Code] = array(); if(!isset($uninheritedCodes[$permission->Code])) $uninheritedCodes[$permission->Code] = array();
$uninheritedCodes[$permission->Code][] = _t( $uninheritedCodes[$permission->Code][] = _t(
'PermissionCheckboxSetField.AssignedTo', 'assigned to "{title}"', 'PermissionCheckboxSetField.AssignedTo', 'assigned to "{title}"',
array('title' => $record->Title) array('title' => $record->dbObject('Title')->forTemplate())
); );
} }
@ -115,7 +115,7 @@ class PermissionCheckboxSetField extends FormField {
'PermissionCheckboxSetField.FromRole', 'PermissionCheckboxSetField.FromRole',
'inherited from role "{title}"', 'inherited from role "{title}"',
'A permission inherited from a certain permission role', 'A permission inherited from a certain permission role',
array('title' => $role->Title) array('title' => $role->dbObject('Title')->forTemplate())
); );
} }
} }
@ -134,7 +134,7 @@ class PermissionCheckboxSetField extends FormField {
'PermissionCheckboxSetField.FromRoleOnGroup', 'PermissionCheckboxSetField.FromRoleOnGroup',
'inherited from role "%s" on group "%s"', 'inherited from role "%s" on group "%s"',
'A permission inherited from a role on a certain group', 'A permission inherited from a role on a certain group',
array('roletitle' => $role->Title, 'grouptitle' => $parent->Title) array('roletitle' => $role->dbObject('Title')->forTemplate(), 'grouptitle' => $parent->dbObject('Title')->forTemplate())
); );
} }
} }
@ -149,7 +149,7 @@ class PermissionCheckboxSetField extends FormField {
'PermissionCheckboxSetField.FromGroup', 'PermissionCheckboxSetField.FromGroup',
'inherited from group "{title}"', 'inherited from group "{title}"',
'A permission inherited from a certain group', 'A permission inherited from a certain group',
array('title' => $parent->Title) array('title' => $parent->dbObject('Title')->forTemplate())
); );
} }
} }

View File

@ -1,7 +1,8 @@
<div id="TreeDropdownField_$ID" <div id="TreeDropdownField_$ID"
class="TreeDropdownField single<% if extraClass %> $extraClass<% end_if %><% if ShowSearch %> searchable<% end_if %>" class="TreeDropdownField <% if extraClass %> $extraClass<% end_if %><% if ShowSearch %> searchable<% end_if %>"
data-url-tree="$Link(tree)" data-url-tree="$Link(tree)"
data-title="$Title.ATT" data-title="$Title.ATT"
data-escape-label-field="$EscapeLabelField"
<% if $Description %>title="$Description.ATT"<% end_if %> <% if $Description %>title="$Description.ATT"<% end_if %>
<% if $Metadata %>data-metadata="$Metadata.ATT"<% end_if %>> <% if $Metadata %>data-metadata="$Metadata.ATT"<% end_if %>>
<input id="$ID" type="hidden" name="$Name.ATT" value="$Value.ATT" /> <input id="$ID" type="hidden" name="$Name.ATT" value="$Value.ATT" />

View File

@ -274,12 +274,12 @@ class ViewableData extends Object implements IteratorAggregate {
*/ */
public function escapeTypeForField($field) { public function escapeTypeForField($field) {
if(!$class = $this->castingClass($field)) { if(!$class = $this->castingClass($field)) {
$class = self::$default_cast; $class = $this->config()->get('default_cast');
} }
return Config::inst()->get($class, 'escape_type', Config::FIRST_SET); return Config::inst()->get($class, 'escape_type', Config::FIRST_SET);
} }
/** /**
* Save the casting cache for this object (including data from any failovers) into a variable * Save the casting cache for this object (including data from any failovers) into a variable
* *