mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
switch externals to trunk.
Inform-merge: from the changeset: r32477: Merge 2.0-inform from trunk previously r32478: Merge 2.0-inform from trunk previously r32481: merge 2.0infom with lastes chunk r32483: merge 2.0infom with lastes chunk r33526: Final styling of all forms and combined communication form add/alter javascript for height adjustment of First / Second block r33580: styling for combined form communication in myinfom pages r33706: styling of combined form (communication) in Email r33881: made compatible to $extraClass r33885: added defaultVal r33887: fixed typo r34728: modified SmallFieldHolder?() r34729: added "validationError"-class r34914: WIP3866: Factfinder: Hide "self emplyed" block r34964: Change current plan upto TraumaInsurance? r35038: disabled friggin field focus r35230: #1032 Fixed hash-link insertion r35887: conditionally setting parameters in sourceID() - to avoid empty overrides r35892: Saving value in SQL-compatible format (YYYY-MM-DD instead of DD/MM/YYYY), with fallback for non-sql values (just passed through without conversion) r35928: Removed "create a" from PageType?-dropdown, sorting alphabetically, falling back to $singular_name r35990: branched off for membertablefield r35994: fix for membertablefield r36024: added array-condition needed for DMYDateField r36083: fix bug for compositeField -> dropDatalessField r36394: removed debug code r36826: change wrong indent format r36828: WIP 4262: Logging out of My Inform goes to blank page r36858: Fixed error caused in r12472 while merging to Session-class r37132: Merged partial changesets from branches/2.0-nzct, only adding childID to detailform when not in add-mode r40815: add an unsubscribe record when a member subscribe a newslettertype r41113: fix the bug described in http://support.silverstripe.com/info/ticket/31: CRM not showing search results r43226: fixed search (partial merge from trunk) r43268: merged createNewPassword() from trunk, was referencing a non-existinent global function randomString() git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@45473 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
99e45e48c3
commit
26b8f7dffe
@ -314,7 +314,7 @@ class Director {
|
||||
}
|
||||
|
||||
static function getAbsURL($url) {
|
||||
return Director::baseURL() . '/' . $url;
|
||||
return Director::baseURL() . $url;
|
||||
}
|
||||
|
||||
static function getAbsFile($file) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
* A redirector page redirects when the page is visited.
|
||||
*/
|
||||
class RedirectorPage extends Page {
|
||||
static $add_action = "a redirector to another page";
|
||||
static $add_action = "Redirector to another page";
|
||||
static $icon = array("cms/images/treeicons/page-shortcut","file");
|
||||
|
||||
static $db = array(
|
||||
|
@ -1211,12 +1211,25 @@ class SiteTree extends DataObject {
|
||||
if((($instance instanceof HiddenClass) || !$instance->canCreate()) && ($class != $this->class)) continue;
|
||||
|
||||
$addAction = $instance->uninherited('add_action', true);
|
||||
if(!$addAction) $addAction = "a $class";
|
||||
if(!$addAction) {
|
||||
$addAction = $instance->singular_name();
|
||||
}
|
||||
|
||||
if($class == $this->class) {
|
||||
$currentClass = $class;
|
||||
$currentAddAction = $addAction;
|
||||
} else {
|
||||
$result[$class] = ($class == $this->class)
|
||||
? "Currently $addAction"
|
||||
: "Change to $addAction";
|
||||
}
|
||||
}
|
||||
|
||||
// sort alphabetically, and put current on top
|
||||
asort($result);
|
||||
$result = array_reverse($result);
|
||||
$result[$currentClass] = "{$currentAddAction} (current)";
|
||||
$result = array_reverse($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
* Note: This Only duplicates $db fields and not the $has_one etc..
|
||||
*/
|
||||
class VirtualPage extends Page {
|
||||
|
||||
static $add_action = "Virtual page (another page's content)";
|
||||
|
||||
static $icon = array("cms/images/treeicons/page-shortcut-gold","file");
|
||||
|
@ -6,10 +6,20 @@
|
||||
* the creation of the field in the database,
|
||||
*/
|
||||
abstract class DBField extends ViewableData {
|
||||
|
||||
protected $value;
|
||||
|
||||
protected $tableName;
|
||||
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var $default mixed Default-value in the database.
|
||||
* Might be overridden on DataObject-level, but still useful for setting defaults on
|
||||
* already existing records after a db-build.
|
||||
*/
|
||||
protected $defaultVal;
|
||||
|
||||
function __construct($name) {
|
||||
$this->name = $name;
|
||||
|
||||
@ -29,12 +39,15 @@ abstract class DBField extends ViewableData {
|
||||
function setVal($value) {
|
||||
return $this->setValue($value);
|
||||
}
|
||||
|
||||
function setValue($value) {
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
function setTable($tableName) {
|
||||
$this->tableName = $tableName;
|
||||
}
|
||||
|
||||
function forTemplate() {
|
||||
return $this->value;
|
||||
}
|
||||
@ -45,15 +58,19 @@ abstract class DBField extends ViewableData {
|
||||
function ATT() {
|
||||
return Convert::raw2att($this->value);
|
||||
}
|
||||
|
||||
function RAW() {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
function JS() {
|
||||
return Convert::raw2js($this->value);
|
||||
}
|
||||
|
||||
function HTML(){
|
||||
return Convert::raw2xml($this->value);
|
||||
}
|
||||
|
||||
function XML(){
|
||||
return Convert::raw2xml($this->value);
|
||||
}
|
||||
@ -93,5 +110,4 @@ abstract class DBField extends ViewableData {
|
||||
DBG;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @param $defaultVal int
|
||||
*/
|
||||
class Int extends DBField {
|
||||
|
||||
function __construct($name, $defaultVal = 0) {
|
||||
@ -10,6 +12,13 @@ class Int extends DBField {
|
||||
parent::__construct($name);
|
||||
}
|
||||
|
||||
|
||||
function __construct($name, $defaultVal = null) {
|
||||
$this->defaultVal = is_numeric($defaultVal) ? $defaultVal : 0;
|
||||
|
||||
parent::__construct($name);
|
||||
}
|
||||
|
||||
function Formatted() {
|
||||
return number_format($this->value);
|
||||
}
|
||||
|
@ -247,9 +247,8 @@ JS;
|
||||
} else {
|
||||
$detailFields = $childData->getCMSFields();
|
||||
}
|
||||
|
||||
if($this->getParentClass()) {
|
||||
$parentIdName = $this->getParentIdName( $this->getParentClass(), $this->sourceClass );
|
||||
$parentIdName = $this->getParentIdName($this->sourceClass,$this->getParentClass());
|
||||
if(!$parentIdName) {
|
||||
user_error("ComplexTableField::DetailForm() Cannot automatically
|
||||
determine 'has-one'-relationship to parent,
|
||||
@ -262,12 +261,15 @@ JS;
|
||||
$detailFields->push(new HiddenField("$parentIdName"," ",$ID));
|
||||
}
|
||||
|
||||
|
||||
// the ID field confuses the Controller-logic in finding the right view for ReferencedField
|
||||
$detailFields->removeByName('ID');
|
||||
|
||||
// add a namespaced ID instead thats "converted" by saveComplexTableField()
|
||||
// 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");
|
||||
@ -399,17 +401,20 @@ JS;
|
||||
// we can't rely on $idField being populated, and fall back to the request-params.
|
||||
// this is a workaround for a bug where each subsequent popup-call didn't have ID
|
||||
// of the parent set, and so didn't properly save the relation
|
||||
return ($idField->Value()) ? $idField->Value() : (isset($_REQUEST['ctf']['ID']) ? $_REQUEST['ctf']['ID'] : null);
|
||||
return ($idField->Value()) ? $idField->Value() : $_REQUEST['ctf']['ID'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* #################################
|
||||
* Pagination
|
||||
* #################################
|
||||
*/
|
||||
function PopupBaseLink() {
|
||||
return $this->FormAction() . "&action_callfieldmethod&fieldName={$this->Name()}&ctf[ID]={$this->sourceID()}";
|
||||
$link = $this->FormAction() . "&action_callfieldmethod&fieldName={$this->Name()}";
|
||||
if(!strpos($link,'ctf[ID]')) {
|
||||
$link = HTTP::setGetVar('ctf[ID]',$this->sourceID(),$link);
|
||||
}
|
||||
return $link;
|
||||
}
|
||||
|
||||
function PopupCurrentItem() {
|
||||
@ -689,8 +694,9 @@ class ComplexTableField_Popup extends Form {
|
||||
$childObject = DataObject::get_by_id($this->sourceClass, $id);
|
||||
} else {
|
||||
$childObject = new $this->sourceClass();
|
||||
$childObject->write(); // Give it an ID prior to calling saveInto
|
||||
$this->fields->removeByName('ID');
|
||||
}
|
||||
|
||||
$this->saveInto($childObject);
|
||||
$childObject->write();
|
||||
|
||||
|
@ -182,6 +182,40 @@ class CompositeField extends FormField {
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a readonly version of this field. Keeps the composition but returns readonly
|
||||
* versions of all the children
|
||||
*/
|
||||
public function dropDatalessField() {
|
||||
$newChildren = new FieldSet();
|
||||
|
||||
foreach($this->children as $idx => $child) {
|
||||
|
||||
if(is_object($child)){
|
||||
if(get_class($child)=='HeaderField'||get_class($child)=='LabelField'||get_class($child)=='TableListField'||is_subclass_of($child, 'TableListField')||get_class($field)=='SelectionGroup'||is_subclass_of($field, 'SelectionGroup')){
|
||||
$newChildren->push($child, $idx);
|
||||
}elseif($child->isComposite()){
|
||||
$newChildren->push($child->dropDatalessField());
|
||||
}elseif((get_class($child)!='DatalessField'&&!is_subclass_of($child, 'DatalessField'))){
|
||||
if($this->hasClass('Undropable')||$child->Value()!==NULL){
|
||||
$newChildren->push($child, $idx);
|
||||
}
|
||||
}
|
||||
}elseif(is_array($child)){
|
||||
foreach($child as $idx=>$subChild){
|
||||
if(is_object($subChild)){
|
||||
if($subChild->isComposite){
|
||||
$newChildren->push($subChild->dropDatalessField());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->children = $newChildren;
|
||||
return $this;
|
||||
}
|
||||
|
||||
function IsReadonly() {
|
||||
return $this->readonly;
|
||||
}
|
||||
|
@ -4,16 +4,27 @@
|
||||
* Default Value represented in the format
|
||||
*/
|
||||
class DateField extends TextField {
|
||||
|
||||
function setValue($val) {
|
||||
if(preg_match('/^([\d]{1,2})\/([\d]{1,2})\/([\d]{2,4})/', $val, $parts)) {
|
||||
$val = "$parts[3]-$parts[2]-$parts[1]";
|
||||
if($val && preg_match('/^([\d]{2,4})-([\d]{1,2})-([\d]{1,2})/', $val)) {
|
||||
$this->value = preg_replace('/^([\d]{2,4})-([\d]{1,2})-([\d]{1,2})/','\\3/\\2/\\1', $val);
|
||||
} else {
|
||||
$this->value = $val;
|
||||
}
|
||||
if($val) $this->value = date('d/m/Y', strtotime($val));
|
||||
else $this->value = null;
|
||||
}
|
||||
|
||||
function dataValue() {
|
||||
return preg_replace('/^([0-9]{1,2})\/([0-9]{1,2})\/([0-90-9]{2,4})/', '\\3-\\2-\\1', $this->value);
|
||||
if(is_array($this->value)) {
|
||||
return $this->value['Year'] . '-' . $this->value['Month'] . '-' . $this->value['Day'];
|
||||
} elseif(preg_match('/^([\d]{1,2})\/([\d]{1,2})\/([\d]{2,4})/', $this->value, $parts)) {
|
||||
return "$parts[3]-$parts[2]-$parts[1]";
|
||||
} elseif(!empty($this->value)) {
|
||||
return date('Y-m-d', strtotime($this->value));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function performReadonlyTransformation() {
|
||||
$field = new DateField_Disabled($this->name, $this->title, $this->value);
|
||||
$field->setForm($this->form);
|
||||
|
@ -20,6 +20,7 @@ class FieldSet extends DataObjectSet {
|
||||
|
||||
protected function collateDataFields(&$list) {
|
||||
foreach($this as $field) {
|
||||
|
||||
if($field->isComposite()) $field->collateDataFields($list);
|
||||
if($field->hasData()) {
|
||||
$name = $field->Name();
|
||||
|
@ -147,6 +147,10 @@ class Form extends ViewableData {
|
||||
}
|
||||
}
|
||||
|
||||
function unsetValidator(){
|
||||
$this->validator = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the {@link Validator} from this from.
|
||||
*/
|
||||
@ -673,7 +677,6 @@ class Form extends ViewableData {
|
||||
if($this->buttonClickedFunc == $action->actionName()) return $action;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default button that should be clicked when another one isn't available
|
||||
*/
|
||||
@ -763,4 +766,21 @@ class Form extends ViewableData {
|
||||
$data['ajax'] = 1;
|
||||
return $this->testSubmission($action, $data);
|
||||
}
|
||||
function dropDatalessField(){
|
||||
foreach($this->Fields() as $field){
|
||||
if(get_class($field)!='SelectionGroup'&&get_class($field)!='TableListField'&&!is_subclass_of($field, 'TableListField')){
|
||||
if((get_class($field)=='DatalessField' ||is_subclass_of($field, 'DatalessField'))&&get_class($field)!='HeaderField'&&get_class($field)!='LabelField'){
|
||||
$this->Fields()->removeByName($field->Name());
|
||||
}elseif($field->isComposite()){
|
||||
$field->dropDatalessField();
|
||||
}else{
|
||||
if(get_class($field) != "HeaderField" &&get_class($field) != "LabelField"&& $field->Value() === NULL){
|
||||
$this->Fields()->removeByName($field->Name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -237,6 +237,8 @@ class FormField extends ViewableData {
|
||||
* a good idea to put the actual HTML for field holders into templates. The default field holder
|
||||
* is the DefaultFieldHolder template. This lets you override the HTML for specific sites, if it's
|
||||
* necessary.
|
||||
*
|
||||
* TODO Add "validationError" if needed.
|
||||
*/
|
||||
function FieldHolder() {
|
||||
$Title = $this->XML_val('Title');
|
||||
@ -262,7 +264,6 @@ HTML;
|
||||
*/
|
||||
function SmallFieldHolder() {
|
||||
$result = '';
|
||||
|
||||
// set label
|
||||
if($title = $this->RightTitle()){
|
||||
$result .= "<label class=\"right\" for=\"" . $this->id() . "\">{$title}</label>\n";
|
||||
@ -326,6 +327,12 @@ HTML;
|
||||
return $trans->transform($this);
|
||||
}
|
||||
|
||||
function hasClass($class){
|
||||
$patten = '/'.strtolower($class).'/i';
|
||||
$subject = strtolower($this->class." ".$this->extraClass);
|
||||
return preg_match($patten, $subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field type - used by templates.
|
||||
* The field type is the class name with the word Field dropped off the end, all lowercase.
|
||||
|
@ -13,10 +13,12 @@ class HeaderField extends DatalessField {
|
||||
parent::__construct(null, $title, null, $form);
|
||||
}
|
||||
function Field() {
|
||||
if($this->allowHTML) $XML_title = $this->title;
|
||||
else $XML_title = Convert::raw2xml($this->title);
|
||||
$XML_title = ($this->allowHTML) ? $this->title : Convert::raw2xml($this->title);
|
||||
|
||||
return "<h$this->headingLevel>$XML_title</h$this->headingLevel>";
|
||||
// extraclass
|
||||
$XML_class = ($this->extraClass()) ? " class=\"{$this->extraClass()}\"" : '';
|
||||
|
||||
return "<h{$this->headingLevel}{$XML_class}>$XML_title</h$this->headingLevel>";
|
||||
}
|
||||
}
|
||||
?>
|
@ -38,13 +38,20 @@ class OptionsetField extends DropdownField {
|
||||
$odd = ($odd + 1) % 2;
|
||||
$extraClass = $odd ? "odd" : "even";
|
||||
$extraClass .= " val" . str_replace(' ','',$key);
|
||||
$this->disabled ? $disabled = " disabled=\"disabled\"" : $disable = "";
|
||||
|
||||
$options .= "<li class=\"".$extraClass."\"><input id=\"$itemID\" name=\"$this->name\" type=\"radio\" value=\"$key\"$checked /> <label for=\"$itemID\">$value</label></li>\n";
|
||||
$options .= "<li class=\"".$extraClass."\"><input id=\"$itemID\" name=\"$this->name\" type=\"radio\" value=\"$key\"$checked $disabled/> <label for=\"$itemID\">$value</label></li>\n";
|
||||
}
|
||||
$id = $this->id();
|
||||
return "<ul id=\"$id\" class=\"optionset\">\n$options</ul>\n";
|
||||
return "<ul id=\"$id\" class=\"optionset {$this->extraClass}\">\n$options</ul>\n";
|
||||
}
|
||||
|
||||
protected $disabled = false;
|
||||
function setDisabled($val) {
|
||||
$this->disabled = $val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function performReadonlyTransformation() {
|
||||
// Source and values are DataObject sets.
|
||||
|
@ -24,6 +24,24 @@ class SelectionGroup extends CompositeField {
|
||||
Requirements::css('sapphire/css/SelectionGroup.css');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a readonly version of this field. Keeps the composition but returns readonly
|
||||
* versions of all the children
|
||||
*/
|
||||
public function performDisabledTransformation($trans) {
|
||||
$newChildren = array();
|
||||
if($this->children) foreach($this->children as $idx => $child) {
|
||||
if(is_object($child)) {
|
||||
$child = $child->transform($trans);
|
||||
}
|
||||
$newChildren[$idx] = $child;
|
||||
}
|
||||
|
||||
$this->children = new FieldSet($newChildren);
|
||||
$this->readonly = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
function FieldSet() {
|
||||
$items = parent::FieldSet()->toArray();
|
||||
|
||||
|
@ -49,8 +49,12 @@ NumericField.prototype = {
|
||||
if( testedOk ) {
|
||||
this.oldValue = this.value = testValue;
|
||||
|
||||
// DEBUG This produces weird javascript-errors, and is not very useable at all
|
||||
// DONT MERGE
|
||||
/*
|
||||
if( this.value.length == this.maxLength && this.nextField )
|
||||
this.nextField.focus();
|
||||
*/
|
||||
|
||||
if( this.callOnValidate )
|
||||
this.callOnValidate();
|
||||
|
@ -42,12 +42,18 @@ function clearErrorMessage(holderDiv){
|
||||
Element.hide(el);
|
||||
});
|
||||
}
|
||||
$$('div.validationError', holderDiv.parentNode).each(function(el) {
|
||||
Element.removeClassName(el,'validationError');
|
||||
});
|
||||
}
|
||||
|
||||
function clearAllErrorMessages() {
|
||||
$$('span.message').each(function(el) {
|
||||
Element.hide(el);
|
||||
});
|
||||
$$('div.validationError').each(function(el) {
|
||||
Element.removeClassName(el,'validationError');
|
||||
});
|
||||
}
|
||||
|
||||
function require(fieldName,cachedError) {
|
||||
@ -249,6 +255,10 @@ function validationError(field,message, messageClass, cacheError) {
|
||||
validationMessage.className = "message " + messageClass;
|
||||
validationMessage.innerHTML = message;
|
||||
validationMessage.style.display = "block";
|
||||
|
||||
// Set Classname on holder
|
||||
var holder = document.getParentOfElement(field,'div','field');
|
||||
Element.addClassName(holder, 'validationError');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -414,6 +414,7 @@ class Member extends DataObject {
|
||||
* @return bool Returns TRUE if the member is in the given group,
|
||||
* otherwise FALSE.
|
||||
*/
|
||||
|
||||
public function inGroup($groupID) {
|
||||
foreach($this->Groups() as $group) {
|
||||
if($groupID == $group->ID)
|
||||
@ -423,6 +424,25 @@ class Member extends DataObject {
|
||||
return false;
|
||||
}
|
||||
|
||||
static function createNewPassword() {
|
||||
if(file_exists('/usr/share/silverstripe/wordlist.txt')) {
|
||||
$words = file('/usr/share/silverstripe/wordlist.txt');
|
||||
|
||||
list($usec, $sec) = explode(' ', microtime());
|
||||
srand($sec + ((float) $usec * 100000));
|
||||
|
||||
$word = trim($words[rand(0,sizeof($words)-1)]);
|
||||
$number = rand(10,999);
|
||||
|
||||
return $word . $number;
|
||||
} else {
|
||||
$random = rand();
|
||||
$string = md5($random);
|
||||
$output = substr($string, 0, 6);
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Alias for {@link inGroup}
|
||||
|
@ -1 +1 @@
|
||||
$URL$
|
||||
$URL:svn://svn.silverstripe.com/silverstripe/modules/sapphire/branches/2.0-inform/silverstripe_version $
|
Loading…
Reference in New Issue
Block a user