diff --git a/core/control/Director.php b/core/control/Director.php
index b66af1a91..12383b3a9 100644
--- a/core/control/Director.php
+++ b/core/control/Director.php
@@ -314,7 +314,7 @@ class Director {
}
static function getAbsURL($url) {
- return Director::baseURL() . '/' . $url;
+ return Director::baseURL() . $url;
}
static function getAbsFile($file) {
diff --git a/core/model/RedirectorPage.php b/core/model/RedirectorPage.php
index d0c45adbb..7df706dea 100755
--- a/core/model/RedirectorPage.php
+++ b/core/model/RedirectorPage.php
@@ -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(
diff --git a/core/model/SiteTree.php b/core/model/SiteTree.php
index bc9c5b3a3..e6ca2c52b 100644
--- a/core/model/SiteTree.php
+++ b/core/model/SiteTree.php
@@ -1211,13 +1211,26 @@ 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();
+ }
- $result[$class] = ($class == $this->class)
+ 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;
}
diff --git a/core/model/VirtualPage.php b/core/model/VirtualPage.php
index b62887f70..6daf14f0b 100755
--- a/core/model/VirtualPage.php
+++ b/core/model/VirtualPage.php
@@ -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");
diff --git a/core/model/fieldtypes/DBField.php b/core/model/fieldtypes/DBField.php
index a536f1071..b2f398b45 100644
--- a/core/model/fieldtypes/DBField.php
+++ b/core/model/fieldtypes/DBField.php
@@ -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;
}
}
-
?>
\ No newline at end of file
diff --git a/core/model/fieldtypes/Int.php b/core/model/fieldtypes/Int.php
index 8b2e8913b..d7eaf6df7 100644
--- a/core/model/fieldtypes/Int.php
+++ b/core/model/fieldtypes/Int.php
@@ -1,5 +1,7 @@
defaultVal = is_numeric($defaultVal) ? $defaultVal : 0;
+
+ parent::__construct($name);
+ }
+
function Formatted() {
return number_format($this->value);
}
@@ -35,4 +44,4 @@ class Int extends DBField {
}
}
-?>
\ No newline at end of file
+?>
diff --git a/forms/ComplexTableField.php b/forms/ComplexTableField.php
index 75cdf5bd7..58f1db3e3 100755
--- a/forms/ComplexTableField.php
+++ b/forms/ComplexTableField.php
@@ -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');
+ // 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[childID]","",$childID));
$detailFields->push(new HiddenField("ctf[ClassName]","",$this->sourceClass));
$readonly = ($this->methodName == "show");
@@ -399,9 +401,8 @@ 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'];
}
-
/**
* #################################
@@ -409,7 +410,11 @@ JS;
* #################################
*/
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();
diff --git a/forms/CompositeField.php b/forms/CompositeField.php
index d6678f68d..3d68ccfea 100755
--- a/forms/CompositeField.php
+++ b/forms/CompositeField.php
@@ -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;
}
diff --git a/forms/DateField.php b/forms/DateField.php
index 271b431f5..6ae537e31 100755
--- a/forms/DateField.php
+++ b/forms/DateField.php
@@ -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);
diff --git a/forms/FieldSet.php b/forms/FieldSet.php
index 156bd5feb..30d0b0609 100755
--- a/forms/FieldSet.php
+++ b/forms/FieldSet.php
@@ -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();
diff --git a/forms/Form.php b/forms/Form.php
index 120604787..defd0b17e 100644
--- a/forms/Form.php
+++ b/forms/Form.php
@@ -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());
+ }
+ }
+ }
+
+
+ }
+ }
}
diff --git a/forms/FormField.php b/forms/FormField.php
index ec1655e61..059b1a6d4 100644
--- a/forms/FormField.php
+++ b/forms/FormField.php
@@ -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 .= "\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.
diff --git a/forms/HeaderField.php b/forms/HeaderField.php
index 7ea6b3a92..927b2cb47 100755
--- a/forms/HeaderField.php
+++ b/forms/HeaderField.php
@@ -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 "