diff --git a/_config.php b/_config.php
index 5542c8b70..41198ca91 100644
--- a/_config.php
+++ b/_config.php
@@ -25,7 +25,6 @@ Director::addRules(10, array(
'$Controller//$Action/$ID/$OtherID' => '*',
'images' => 'Image_Uploader',
'' => 'RootURLController',
- 'sitemap.xml' => 'GoogleSitemap',
'api/v1' => 'RestfulServer',
'soap/v1' => 'SOAPModelAccess',
'dev' => 'DevelopmentAdmin',
@@ -47,7 +46,7 @@ Object::useCustomClass('Datetime','SSDatetime',true);
* Add pear parser to include path
*/
$path = Director::baseFolder().'/sapphire/parsers/';
-set_include_path(get_include_path() . PATH_SEPARATOR . $path);
+set_include_path(str_replace('.' . PATH_SEPARATOR, '.' . PATH_SEPARATOR . $path . PATH_SEPARATOR, get_include_path()));
/**
* Define a default language different than english
@@ -70,7 +69,4 @@ define('MCE_ROOT', 'jsparty/tiny_mce2/');
*/
define('EMAIL_BOUNCEHANDLER_KEY', '1aaaf8fb60ea253dbf6efa71baaacbb3');
-
-
-
?>
\ No newline at end of file
diff --git a/api/RSSFeed.php b/api/RSSFeed.php
index 273c10169..73a88396e 100755
--- a/api/RSSFeed.php
+++ b/api/RSSFeed.php
@@ -193,6 +193,7 @@ class RSSFeed extends ViewableData {
* Return the content of the RSS feed
*/
function feedContent() {
+ SSViewer::set_source_file_comments(false);
return str_replace(' ', ' ', $this->renderWith('RSSFeed'));
}
}
@@ -301,4 +302,4 @@ class RSSFeed_Entry extends ViewableData {
else user_error($this->failover->class . " object has either an AbsoluteLink nor a Link method. Can't put a link in the RSS feed", E_USER_WARNING);
}
}
-?>
+?>
\ No newline at end of file
diff --git a/api/RestfulServer.php b/api/RestfulServer.php
index a861ff6ba..e764bf3f8 100644
--- a/api/RestfulServer.php
+++ b/api/RestfulServer.php
@@ -137,6 +137,11 @@ class RestfulServer extends Controller {
$id = (isset($this->urlParams['ID'])) ? $this->urlParams['ID'] : null;
$relation = (isset($this->urlParams['Relation'])) ? $this->urlParams['Relation'] : null;
+ // Check input formats
+ if(!class_exists($className)) return $this->notFound();
+ if($id && !is_numeric($id)) return $this->notFound();
+ if($relation && !preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $relation)) return $this->notFound();
+
// if api access is disabled, don't proceed
$apiAccess = singleton($className)->stat('api_access');
if(!$apiAccess) return $this->permissionFailure();
diff --git a/api/RestfulService.php b/api/RestfulService.php
index 7f007e9cc..b64d8584e 100644
--- a/api/RestfulService.php
+++ b/api/RestfulService.php
@@ -124,8 +124,15 @@ class RestfulService extends ViewableData {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$responseBody = curl_exec($ch);
$curlError = curl_error($ch);
-
- if($curlError) {
+
+ // Problem verifying the server SSL certificate; just ignore it as it's not mandatory
+ if(strpos($curlError,'14090086') !== false) {
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $responseBody = curl_exec($ch);
+ $curlError = curl_error($ch);
+ }
+
+ if($responseBody === false) {
user_error("Curl Error:" . $curlError, E_USER_WARNING);
return;
}
@@ -338,4 +345,4 @@ class RestfulService_Response extends HTTPResponse {
}
}
-?>
\ No newline at end of file
+?>
diff --git a/api/XMLDataFormatter.php b/api/XMLDataFormatter.php
index 150ba31c8..d9f5f64c2 100644
--- a/api/XMLDataFormatter.php
+++ b/api/XMLDataFormatter.php
@@ -29,7 +29,7 @@ class XMLDataFormatter extends DataFormatter {
* @return String XML
*/
public function convertDataObject(DataObjectInterface $obj, $fields = null) {
- Controller::curr()->getResponse()->addHeader("Content-type", "text/xml");
+ Controller::curr()->getResponse()->addHeader("Content-Type", "text/xml");
return "\n" . $this->convertDataObjectWithoutHeader($obj, $fields);
}
@@ -111,7 +111,7 @@ class XMLDataFormatter extends DataFormatter {
* @return String XML
*/
public function convertDataObjectSet(DataObjectSet $set, $fields = null) {
- Controller::curr()->getResponse()->addHeader("Content-type", "text/xml");
+ Controller::curr()->getResponse()->addHeader("Content-Type", "text/xml");
$className = $set->class;
$xml = "\n";
diff --git a/cli/CliController.php b/cli/CliController.php
index 12bc2f1cf..260b5b317 100755
--- a/cli/CliController.php
+++ b/cli/CliController.php
@@ -11,8 +11,10 @@
*/
abstract class CliController extends Controller {
function init() {
- $this->disableBasicAuth();
- parent::init();
+ $this->disableBasicAuth();
+ parent::init();
+ // Unless called from the command line, all CliControllers need ADMIN privileges
+ if(!Director::is_cli() && !Permission::check("ADMIN")) return Security::permissionFailure();
}
function index() {
@@ -29,5 +31,6 @@ abstract class CliController extends Controller {
* Overload this method to contain the task logic.
*/
function process() {}
-}
-?>
\ No newline at end of file
+}
+
+?>
diff --git a/core/ClassInfo.php b/core/ClassInfo.php
index 9e497cc99..747be4339 100755
--- a/core/ClassInfo.php
+++ b/core/ClassInfo.php
@@ -93,16 +93,36 @@ class ClassInfo {
/**
* Returns a list of classes that inherit from the given class.
+ * The resulting array includes the base class passed
+ * through the $class parameter as the first array value.
+ *
+ * Example usage:
+ *
+ * class MyTestClass implements i18nEntityProvider {
+ * function provideI18nEntities() {
+ * $entities = array();
+ * $entities["MyOtherModuleClass.MYENTITY"] = array(
+ * $value,
+ * PR_MEDIUM,
+ * 'My context description',
+ * 'myothermodule'
+ * );
+ * }
+ * return $entities;
+ * }
+ *
+ *
* @return array All entites in an associative array, with
* entity name as the key, and a numerical array of pseudo-arguments
* for _t() as a value.
diff --git a/core/i18nTextCollector.php b/core/i18nTextCollector.php
index 126a3bab7..e0cddd508 100644
--- a/core/i18nTextCollector.php
+++ b/core/i18nTextCollector.php
@@ -110,6 +110,16 @@ class i18nTextCollector extends Object {
unset($entitiesByModule[$module][$fullName]);
}
}
+
+ // extract all entities for "foreign" modules (fourth argument)
+ foreach($entitiesByModule[$module] as $fullName => $spec) {
+ if(isset($spec[3]) && $spec[3] != $module) {
+ $othermodule = $spec[3];
+ if(!isset($entitiesByModule[$othermodule])) $entitiesByModule[$othermodule] = array();
+ unset($spec[3]);
+ $entitiesByModule[$othermodule][$fullName] = $spec;
+ }
+ }
}
// Write the generated master string tables
@@ -228,7 +238,7 @@ class i18nTextCollector extends Object {
if(class_exists($class) && in_array('i18nEntityProvider', class_implements($class))) {
$reflectionClass = new ReflectionClass($class);
if($reflectionClass->isAbstract()) continue;
-
+
$obj = singleton($class);
$entitiesArr = array_merge($entitiesArr,(array)$obj->provideI18nEntities());
}
diff --git a/core/model/DB.php b/core/model/DB.php
index f006fc038..19be4b36d 100755
--- a/core/model/DB.php
+++ b/core/model/DB.php
@@ -262,4 +262,4 @@ class DB {
return DB::$globalConn->quiet();
}
}
-?>
+?>
\ No newline at end of file
diff --git a/core/model/DataObject.php b/core/model/DataObject.php
index 97bdbe332..3ebf6c012 100644
--- a/core/model/DataObject.php
+++ b/core/model/DataObject.php
@@ -1581,7 +1581,7 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
* Used for simple frontend forms without relation editing
* or {@link TabSet} behaviour. Uses {@link scaffoldFormFields()}
* by default. To customize, either overload this method in your
- * subclass, or decorate it by {@link DataObjectDecorator->updateFormFields()}.
+ * subclass, or decorate it by {@link DataObjectDecorator->updateFrontEndFields()}.
*
* @todo Decide on naming for "website|frontend|site|page" and stick with it in the API
*
@@ -1590,7 +1590,7 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
*/
public function getFrontEndFields($params = null) {
$untabbedFields = $this->scaffoldFormFields($params);
- $this->extend('updateFormFields', $untabbedFields);
+ $this->extend('updateFrontEndFields', $untabbedFields);
return $untabbedFields;
}
@@ -1836,7 +1836,10 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
* Uses the rules for whether the table should exist rather than actually looking in the database.
*/
public function has_own_table($dataClass) {
- if(!is_subclass_of($dataClass,'DataObject')) return false;
+ // The condition below has the same effect as !is_subclass_of($dataClass,'DataObject'),
+ // which causes PHP < 5.3 to segfault in rare circumstances, see PHP bug #46753
+ if($dataClass == 'DataObject' || !in_array('DataObject', ClassInfo::ancestry($dataClass))) return false;
+
if(!isset(self::$cache_has_own_table[$dataClass])) {
if(get_parent_class($dataClass) == 'DataObject') {
self::$cache_has_own_table[$dataClass] = true;
@@ -2736,7 +2739,7 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
$fields = array();
// try to scaffold a couple of usual suspects
if ($this->hasField('Name')) $fields['Name'] = 'Name';
- if ($this->hasField('Title')) $fields['Title'] = 'Title';
+ if ($this->hasDataBaseField('Title')) $fields['Title'] = 'Title';
if ($this->hasField('Description')) $fields['Description'] = 'Description';
if ($this->hasField('FirstName')) $fields['FirstName'] = 'First Name';
}
@@ -2848,7 +2851,7 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
/**
* Inserts standard column-values when a DataObject
* is instanciated. Does not insert default records {@see $default_records}.
- * This is a map from classname to default value.
+ * This is a map from fieldname to default value.
*
* - If you would like to change a default value in a sub-class, just specify it.
* - If you would like to disable the default value given by a parent class, set the default value to 0,'',or false in your
@@ -3001,4 +3004,4 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
}
-?>
+?>
\ No newline at end of file
diff --git a/core/model/DataObjectDecorator.php b/core/model/DataObjectDecorator.php
index de8519371..d69560001 100755
--- a/core/model/DataObjectDecorator.php
+++ b/core/model/DataObjectDecorator.php
@@ -57,7 +57,6 @@ abstract class DataObjectDecorator extends Extension {
return $this->loadExtraStatics();
}
-
/**
* Edit the given query object to support queries for this extension
*
@@ -66,7 +65,6 @@ abstract class DataObjectDecorator extends Extension {
function augmentSQL(SQLQuery &$query) {
}
-
/**
* Update the database schema as required by this extension.
*/
@@ -139,7 +137,8 @@ abstract class DataObjectDecorator extends Extension {
/**
* This function is used to provide modifications to the form in the CMS
- * by the decorator. By default, no changes are made.
+ * by the decorator. By default, no changes are made. {@link DataObject->getCMSFields()}.
+ *
* Please consider using {@link updateFormFields()} to globally add
* formfields to the record. The method {@link updateCMSFields()}
* should just be used to add or modify tabs, or fields which
@@ -153,16 +152,22 @@ abstract class DataObjectDecorator extends Extension {
}
/**
- * This function is used to provide modifications to the form in the CMS
- * by the decorator.
+ * This function is used to provide modifications to the form used
+ * for front end forms. {@link DataObject->getFrontEndFields()}
*
* Caution: Use {@link FieldSet->push()} to add fields.
*
* @param FieldSet $fields FieldSet without TabSet nesting
*/
- function updateFormFields(FieldSet &$fields) {
+ function updateFrontEndFields(FieldSet &$fields) {
}
+ /**
+ * This is used to provide modifications to the form actions
+ * used in the CMS. {@link DataObject->getCMSActions()}.
+ *
+ * @param FieldSet $actions FieldSet
+ */
function updateCMSActions(FieldSet &$actions) {
}
@@ -176,6 +181,12 @@ abstract class DataObjectDecorator extends Extension {
$extra_fields = $this->extraStatics();
if(isset($extra_fields['summary_fields'])){
$summary_fields = $extra_fields['summary_fields'];
+
+ // if summary_fields were passed in numeric array,
+ // convert to an associative array
+ if($summary_fields && array_key_exists(0, $summary_fields)) {
+ $summary_fields = array_combine(array_values($summary_fields), array_values($summary_fields));
+ }
if($summary_fields) $fields = array_merge($fields, $summary_fields);
}
}
@@ -201,5 +212,4 @@ abstract class DataObjectDecorator extends Extension {
}
}
-
-?>
+?>
\ No newline at end of file
diff --git a/core/model/DataObjectSet.php b/core/model/DataObjectSet.php
index 3385fc91d..bb62d50e1 100644
--- a/core/model/DataObjectSet.php
+++ b/core/model/DataObjectSet.php
@@ -264,6 +264,85 @@ class DataObjectSet extends ViewableData implements IteratorAggregate {
return $ret;
}
+ /*
+ * Display a summarized pagination which limits the number of pages shown
+ * "around" the currently active page for visual balance.
+ * In case more paginated pages have to be displayed, only
+ *
+ * Example: 25 pages total, currently on page 6, context of 4 pages
+ * [prev] [1] ... [4] [5] [[6]] [7] [8] ... [25] [next]
+ *
+ * Example template usage:
+ *
+ * <% if MyPages.MoreThanOnePage %>
+ * <% if MyPages.NotFirstPage %>
+ * Prev
+ * <% end_if %>
+ * <% control MyPages.PaginationSummary(4) %>
+ * <% if CurrentBool %>
+ * $PageNum
+ * <% else %>
+ * <% if Link %>
+ * $PageNum
+ * <% else %>
+ * ...
+ * <% end_if %>
+ * <% end_if %>
+ * <% end_control %>
+ * <% if MyPages.NotLastPage %>
+ * Next
+ * <% end_if %>
+ * <% end_if %>
+ *
+ *
+ * @param integer $context Number of pages to display "around" the current page. Number should be even,
+ * because its halved to either side of the current page.
+ * @return DataObjectSet
+ */
+ public function PaginationSummary($context = 4) {
+ $ret = new DataObjectSet();
+
+ // convert number of pages to even number for offset calculation
+ if($context % 2) $context--;
+
+ // find out the offset
+ $current = $this->CurrentPage();
+ $totalPages = $this->TotalPages();
+
+ // if the first or last page is shown, use all content on one side (either left or right of current page)
+ // otherwise half the number for usage "around" the current page
+ $offset = ($current == 1 || $current == $totalPages) ? $context : floor($context/2);
+
+ $leftOffset = $current - ($offset);
+ if($leftOffset < 1) $leftOffset = 1;
+ if($leftOffset + $context > $totalPages) $leftOffset = $totalPages - $context;
+
+ for($i=0; $i < $totalPages; $i++) {
+ $link = HTTP::setGetVar($this->paginationGetVar, $i*$this->pageLength);
+ $num = $i+1;
+ $currentBool = ($current == $i+1) ? true:false;
+ if(
+ ($num == $leftOffset-1 && $num != 1 && $num != $totalPages)
+ || ($num == $leftOffset+$context+1 && $num != 1 && $num != $totalPages)
+ ) {
+ $ret->push(new ArrayData(array(
+ "PageNum" => null,
+ "Link" => null,
+ "CurrentBool" => $currentBool,
+ )
+ ));
+ } else if($num == 1 || $num == $totalPages || in_array($num, range($current-$offset,$current+$offset))) {
+ $ret->push(new ArrayData(array(
+ "PageNum" => $num,
+ "Link" => $link,
+ "CurrentBool" => $currentBool,
+ )
+ ));
+ }
+ }
+ return $ret;
+ }
+
/**
* Returns true if the current page is not the first page.
* @return boolean
@@ -694,7 +773,7 @@ class DataObjectSet extends ViewableData implements IteratorAggregate {
$myViewer = SSViewer::fromString($currentTemplate);
if(isset($nestingLevels[$level+1]['dataclass'])){
- $childrenMethod = $nestingLevels[$level+1]['dataclass'];if($level==1){print_r($childrenMethod);die;}
+ $childrenMethod = $nestingLevels[$level+1]['dataclass'];
}
// sql-parts
@@ -1044,4 +1123,4 @@ class DataObjectSet_Iterator implements Iterator {
}
}
-?>
+?>
\ No newline at end of file
diff --git a/core/model/Database.php b/core/model/Database.php
index bfcce0eba..a4ee06694 100755
--- a/core/model/Database.php
+++ b/core/model/Database.php
@@ -235,7 +235,9 @@ abstract class Database extends Object {
} else {
$this->checkAndRepairTable($table);
}
-
+
+ $this->requireField($table, "ID", "int(11) not null auto_increment");
+
// Create custom fields
if($fieldSchema) {
foreach($fieldSchema as $fieldName => $fieldSpec) {
@@ -591,10 +593,11 @@ abstract class Query extends Object implements Iterator {
* @return array
*/
public function column() {
+ $column = array();
foreach($this as $record) {
$column[] = reset($record);
}
- return isset($column) ? $column : null;
+ return $column;
}
/**
@@ -603,6 +606,7 @@ abstract class Query extends Object implements Iterator {
* @return array
*/
public function keyedColumn() {
+ $column = array();
foreach($this as $record) {
$val = reset($record);
$column[$val] = $val;
@@ -615,6 +619,7 @@ abstract class Query extends Object implements Iterator {
* @return array
*/
public function map() {
+ $column = array();
foreach($this as $record) {
$key = reset($record);
$val = next($record);
diff --git a/core/model/ErrorPage.php b/core/model/ErrorPage.php
index 11c30e65e..9db4f9128 100755
--- a/core/model/ErrorPage.php
+++ b/core/model/ErrorPage.php
@@ -103,6 +103,7 @@ class ErrorPage extends Page {
$errorContent = $response->getBody();
+ // Check we have an assets base directory, creating if it we don't
if(!file_exists(ASSETS_PATH)) {
mkdir(ASSETS_PATH, 02775);
}
@@ -113,6 +114,17 @@ class ErrorPage extends Page {
if($fh = fopen($filePath, "w")) {
fwrite($fh, $errorContent);
fclose($fh);
+ } else {
+ $fileErrorText = sprintf(
+ _t(
+ "ErrorPage.ERRORFILEPROBLEM",
+ "Error opening file \"%s\" for writing. Please check file permissions."
+ ),
+ $errorFile
+ );
+ FormResponse::status_message($fileErrorText, 'bad');
+ FormResponse::respond();
+ return;
}
// Restore the version we're currently connected to.
diff --git a/core/model/Hierarchy.php b/core/model/Hierarchy.php
index 74b063cc1..16456073c 100644
--- a/core/model/Hierarchy.php
+++ b/core/model/Hierarchy.php
@@ -159,7 +159,7 @@ class Hierarchy extends DataObjectDecorator {
protected function markingFinished() {
// Mark childless nodes as expanded.
foreach($this->markedNodes as $id => $node) {
- if(!$node->numChildren()) {
+ if(!$node->isExpanded() && !$node->numChildren()) {
$node->markExpanded();
}
}
@@ -351,7 +351,18 @@ class Hierarchy extends DataObjectDecorator {
* @return DataObjectSet
*/
public function Children() {
- return $this->owner->stageChildren(false);
+ if(!(isset($this->children) && $this->children)) {
+ $result = $this->owner->stageChildren(false);
+ if(isset($result)) {
+ $this->children = new DataObjectSet();
+ foreach($result as $child) {
+ if($child->canView()) {
+ $this->children->push($child);
+ }
+ }
+ }
+ }
+ return $this->children;
}
/**
diff --git a/core/model/Image.php b/core/model/Image.php
index c92e0e6ab..91310ecb7 100755
--- a/core/model/Image.php
+++ b/core/model/Image.php
@@ -780,4 +780,4 @@ class Image_Uploader extends Controller {
}
}
-?>
+?>
\ No newline at end of file
diff --git a/core/model/MySQLDatabase.php b/core/model/MySQLDatabase.php
index dec6f3f8a..756000eb4 100644
--- a/core/model/MySQLDatabase.php
+++ b/core/model/MySQLDatabase.php
@@ -174,11 +174,12 @@ class MySQLDatabase extends Database {
public function createTable($tableName, $fields = null, $indexes = null) {
$fieldSchemas = $indexSchemas = "";
+
+ if(!isset($fields['ID'])) $fields['ID'] = "int(11) not null auto_increment";
if($fields) foreach($fields as $k => $v) $fieldSchemas .= "\"$k\" $v,\n";
if($indexes) foreach($indexes as $k => $v) $fieldSchemas .= $this->getIndexSqlDefinition($k, $v) . ",\n";
$this->query("CREATE TABLE \"$tableName\" (
- ID int(11) not null auto_increment,
$fieldSchemas
$indexSchemas
primary key (ID)
@@ -468,7 +469,7 @@ class MySQLDatabase extends Database {
//$parts=Array('datatype'=>'decimal', 'precision'=>"$this->wholeSize,$this->decimalSize");
//DB::requireField($this->tableName, $this->name, "decimal($this->wholeSize,$this->decimalSize)");
- return 'decimal(' . (int)$values['precision'] . ')';
+ return 'decimal(' . (int)$values['precision'] . ') not null';
}
/**
diff --git a/core/model/PDODatabase.php b/core/model/PDODatabase.php
index 1a9155586..e70769932 100644
--- a/core/model/PDODatabase.php
+++ b/core/model/PDODatabase.php
@@ -727,5 +727,4 @@ class PDOQuery extends Query {
}
}
-
-?>
+?>
\ No newline at end of file
diff --git a/core/model/SQLQuery.php b/core/model/SQLQuery.php
index e50eeceda..ff3f55754 100755
--- a/core/model/SQLQuery.php
+++ b/core/model/SQLQuery.php
@@ -452,4 +452,4 @@ class SQLQuery extends Object {
}
}
-?>
+?>
\ No newline at end of file
diff --git a/core/model/SiteTree.php b/core/model/SiteTree.php
index efdb81ea3..feb09758f 100644
--- a/core/model/SiteTree.php
+++ b/core/model/SiteTree.php
@@ -191,6 +191,42 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
*/
private static $runCMSFieldsExtensions = true;
+ /**
+ * Return a subclass map of SiteTree
+ * that shouldn't be hidden through
+ * {@link SiteTree::$hide_ancestor}
+ *
+ * @return array
+ */
+ public static function page_type_classes() {
+ $classes = ClassInfo::getValidSubClasses();
+ array_shift($classes);
+ $kill_ancestors = array();
+
+ // figure out if there are any classes we don't want to appear
+ foreach($classes as $class) {
+ $instance = singleton($class);
+
+ // do any of the progeny want to hide an ancestor?
+ if($ancestor_to_hide = $instance->stat('hide_ancestor')) {
+ // note for killing later
+ $kill_ancestors[] = $ancestor_to_hide;
+ }
+ }
+
+ // If any of the descendents don't want any of the elders to show up, cruelly render the elders surplus to requirements.
+ if($kill_ancestors) {
+ $kill_ancestors = array_unique($kill_ancestors);
+ foreach($kill_ancestors as $mark) {
+ // unset from $classes
+ $idx = array_search($mark, $classes);
+ unset($classes[$idx]);
+ }
+ }
+
+ return $classes;
+ }
+
/**
* Get the URL for this page.
*
@@ -525,7 +561,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* @todo Check we get a endless recursion if we use parent::can()
*/
function can($perm, $member = null) {
- if(!$member && $member !== FALSE) $member = Member::currentUser();
+ if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser();
if($member && Permission::checkMember($member, "ADMIN")) return true;
@@ -562,7 +598,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* @return boolean True if the current user can add children.
*/
public function canAddChildren($member = null) {
- if(!$member && $member !== FALSE) $member = Member::currentUser();
+ if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser();
if($member && Permission::checkMember($member, "ADMIN")) return true;
// DEPRECATED 2.3: use canAddChildren() instead
@@ -593,7 +629,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* @return boolean True if the current user can view this page.
*/
public function canView($member = null) {
- if(!$member && $member !== FALSE) $member = Member::currentUser();
+ if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser();
// admin override
if($member && Permission::checkMember($member, "ADMIN")) return true;
@@ -648,7 +684,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* @return boolean True if the current user can delete this page.
*/
public function canDelete($member = null) {
- if(!$member && $member !== FALSE) $member = Member::currentUser();
+ if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser();
if($member && Permission::checkMember($member, "ADMIN")) return true;
@@ -690,7 +726,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* @return boolean True if the current user can create pages on this class.
*/
public function canCreate($member = null) {
- if(!$member && $member !== FALSE) $member = Member::currentUser();
+ if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser();
if($member && Permission::checkMember($member, "ADMIN")) return true;
@@ -726,7 +762,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* @return boolean True if the current user can edit this page.
*/
public function canEdit($member = null) {
- if(!$member && $member !== FALSE) $member = Member::currentUser();
+ if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser();
if($member && Permission::checkMember($member, "ADMIN")) return true;
@@ -774,7 +810,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* @return boolean True if the current user can publish this page.
*/
public function canPublish($member = null) {
- if(!$member && $member !== FALSE) $member = Member::currentUser();
+ if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser();
if($member && Permission::checkMember($member, "ADMIN")) return true;
@@ -816,7 +852,6 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
/**
* Return the title, description, keywords and language metatags.
*
- * @todo Make generator tag dynamically determine version number (currently defaults to "2.0")
* @todo Move " . _t('SiteTree.NOBACKLINKS', 'This page hasn\'t been linked to from any pages.') . "
"; - } - - // Status / message // Create a status message for multiple parents if($this->ID && is_numeric($this->ID)) { @@ -1139,18 +1156,37 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid $message .= "NOTE: " . implode("' . _t('NOBACKLINKEDPAGES', 'There are no pages linked to this page.') . '
'); + + // Create a table for showing pages linked to this one + if($this->BackLinkTracking() && $this->BackLinkTracking()->Count() > 0) { + $backLinksNote = new LiteralField('BackLinksNote', '' . _t('SiteTree.PAGESLINKING', 'The following pages link to this page:') . '
'); + $backLinksTable = new TableListField( + 'BackLinkTracking', + 'SiteTree', + array( + 'Title' => 'Title' + ), + 'ChildID = ' . $this->ID, + '', + 'LEFT JOIN SiteTree_LinkTracking ON SiteTree.ID = SiteTree_LinkTracking.SiteTreeID' + ); + $backLinksTable->setFieldFormatting(array( + 'Title' => '$Title' + )); + $backLinksTable->setPermissions(array( + 'show', + 'export' + )); + } + // Lay out the fields $fields = new FieldSet( new TabSet("Root", $tabContent = new TabSet('Content', $tabMain = new Tab('Main', new TextField("Title", $this->fieldLabel('Title')), - /*new UniqueTextField("Title", - "Title", - "SiteTree", - "Another page is using that name. Page names should be unique.", - "Page Name" - ),*/ new TextField("MenuTitle", $this->fieldLabel('MenuTitle')), new HtmlEditorField("Content", _t('SiteTree.HTMLEDITORTITLE', "Content", PR_MEDIUM, 'HTML editor title')) ), @@ -1206,8 +1242,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid new TextareaField("ToDo", "") ), $tabReports = new TabSet('Reports', - $tabBacklinks =new Tab('Backlinks', - new LiteralField("Backlinks", $backlinks) + $tabBacklinks = new Tab('Backlinks', + $backLinksNote, + $backLinksTable ) ), $tabAccess = new Tab('Access', @@ -1496,11 +1533,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid * @return array */ protected function getClassDropdown() { - $classes = ClassInfo::getValidSubClasses('SiteTree'); - array_shift($classes); - + $classes = self::page_type_classes(); $currentClass = null; - + $result = array(); + $result = array(); foreach($classes as $class) { $instance = singleton($class); @@ -1812,4 +1848,4 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid } } -?> +?> \ No newline at end of file diff --git a/core/model/Versioned.php b/core/model/Versioned.php index fb5f467ee..8e05d98d9 100755 --- a/core/model/Versioned.php +++ b/core/model/Versioned.php @@ -617,6 +617,27 @@ class Versioned extends DataObjectDecorator { return $version; } + /** + * Pre-populate the cache for Versioned::get_versionnumber_by_stage() for a list of record IDs, + * for more efficient database querying. If $idList is null, then every page will be pre-cached. + */ + static function prepopulate_versionnumber_cache($class, $stage, $idList = null) { + $filter = ""; + if($idList) { + // Validate the ID list + foreach($idList as $id) if(!is_numeric($id)) user_error("Bad ID passed to Versioned::prepopulate_versionnumber_cache() in \$idList: " . $id, E_USER_ERROR); + $filter = "WHERE ID IN(" .implode(", ", $idList) . ")"; + } + + $baseClass = ClassInfo::baseDataClass($class); + $stageTable = ($stage == 'Stage') ? $baseClass : "{$baseClass}_{$stage}"; + + $versions = DB::query("SELECT ID, Version FROM `$stageTable` $filter")->map(); + foreach($versions as $id => $version) { + self::$cache_versionnumber[$baseClass][$stage][$id] = $version; + } + } + /** * Get a set of class instances by the given stage. * @@ -802,4 +823,4 @@ class Versioned_Version extends ViewableData { } } -?> \ No newline at end of file +?> diff --git a/core/model/VirtualPage.php b/core/model/VirtualPage.php index 35eb033da..84960901e 100755 --- a/core/model/VirtualPage.php +++ b/core/model/VirtualPage.php @@ -170,4 +170,4 @@ class VirtualPage_Controller extends Page_Controller { } } -?> +?> \ No newline at end of file diff --git a/core/model/fieldtypes/DBField.php b/core/model/fieldtypes/DBField.php index 183ccaf7d..cb27fe49d 100644 --- a/core/model/fieldtypes/DBField.php +++ b/core/model/fieldtypes/DBField.php @@ -64,7 +64,8 @@ abstract class DBField extends ViewableData { } /** - * Returns the name of this field + * Returns the name of this field. + * @return string */ function getName() { return $this->name; diff --git a/core/model/fieldtypes/Decimal.php b/core/model/fieldtypes/Decimal.php index 6d0184461..42f08ceb9 100644 --- a/core/model/fieldtypes/Decimal.php +++ b/core/model/fieldtypes/Decimal.php @@ -42,6 +42,10 @@ class Decimal extends DBField { public function scaffoldFormField($title = null, $params = null) { return new NumericField($this->name, $title); } + + public function nullValue() { + return "0.00"; + } /** * Return an encoding of the given value suitable for inclusion in a SQL statement. diff --git a/core/model/fieldtypes/Int.php b/core/model/fieldtypes/Int.php index 964de2896..25217af64 100644 --- a/core/model/fieldtypes/Int.php +++ b/core/model/fieldtypes/Int.php @@ -60,4 +60,4 @@ class Int extends DBField { } -?> +?> \ No newline at end of file diff --git a/core/model/fieldtypes/SSDatetime.php b/core/model/fieldtypes/SSDatetime.php index cd6a8c123..85e4711dc 100644 --- a/core/model/fieldtypes/SSDatetime.php +++ b/core/model/fieldtypes/SSDatetime.php @@ -6,6 +6,10 @@ */ class SSDatetime extends Date { function setValue($value) { + // Default to NZ date format - strtotime expects a US date + if(ereg('^([0-9]+)/([0-9]+)/([0-9]+)$', $value, $parts)) + $value = "$parts[2]/$parts[1]/$parts[3]"; + if($value) $this->value = date('Y-m-d H:i:s', strtotime($value)); else $value = null; } @@ -41,4 +45,4 @@ class SSDatetime extends Date { } } -?> +?> \ No newline at end of file diff --git a/core/model/fieldtypes/Text.php b/core/model/fieldtypes/Text.php index 5f06ca58c..e5ba404f5 100644 --- a/core/model/fieldtypes/Text.php +++ b/core/model/fieldtypes/Text.php @@ -321,4 +321,4 @@ class Text extends DBField { } } -?> +?> \ No newline at end of file diff --git a/core/model/fieldtypes/Varchar.php b/core/model/fieldtypes/Varchar.php index 81e32c93e..b9c46ab9d 100644 --- a/core/model/fieldtypes/Varchar.php +++ b/core/model/fieldtypes/Varchar.php @@ -50,14 +50,10 @@ class Varchar extends DBField { return str_replace("\n", '\par ', $this->value); } - /*function forTemplate() { - return $this->raw2HTML(); - }*/ - function LimitCharacters($limit = 20, $add = "...") { $value = trim($this->value); return (strlen($value) > $limit) ? substr($value, 0, $limit) . $add : $value; } } -?> +?> \ No newline at end of file diff --git a/css/CalendarDateField.css b/css/CalendarDateField.css index e59be77ee..7e0a075f6 100755 --- a/css/CalendarDateField.css +++ b/css/CalendarDateField.css @@ -9,6 +9,10 @@ width: 200px; } +#SiteTreeFilterDate { + width: 68px; +} + .calendardate img { position: relative; top: 2px; @@ -17,11 +21,16 @@ .calendarpopup { position: absolute; - left: 13.6em; + left: 9em; + _left: 1.3em; top: -0.15em; + _top: 4em; display: none; z-index: 2; } + + + .calendarpopup.focused { display: block; } diff --git a/css/ComplexTableField_popup.css b/css/ComplexTableField_popup.css index acf26b69d..e2e071f5b 100755 --- a/css/ComplexTableField_popup.css +++ b/css/ComplexTableField_popup.css @@ -1,15 +1,17 @@ -html,body { - overflow:auto !important; - background: #fff !important; -} - .ComplexTableField_popup { background: #fff; } +html { + overflow-y: auto !important; +} +body { + height: auto; +} + #ComplexTableField_Popup_DetailForm input.loading { background: #fff url(../../cms/images/network-save.gif) left center no-repeat; - padding-left:16px; + padding-left: 16px; } .PageControls { diff --git a/css/Form.css b/css/Form.css index ec5f8e307..38053fd29 100644 --- a/css/Form.css +++ b/css/Form.css @@ -137,4 +137,24 @@ form .message { color:#FF4040; width:240px; border-color: #FF4040; - } \ No newline at end of file + } + + /** LOGIN FORM **/ + +#Remember { + margin: 0.5em 0 0.5em 11em !important; +} + p#Remember label { + display: inline-block; + margin: 0; + } + #Remember input { + float: left; + margin: 0 5px 0 0; + } +#MemberLoginForm_LoginForm .Actions { + padding-left: 12em; +} +#ForgotPassword { + margin-top: 1em; +} \ No newline at end of file diff --git a/css/MemberProfileForm.css b/css/MemberProfileForm.css index 71054fcbb..d81f6dbb0 100644 --- a/css/MemberProfileForm.css +++ b/css/MemberProfileForm.css @@ -1,8 +1,3 @@ -/* HACK Doesn't work in an iframe-popup at the moment, so we disable it */ -#Avatar { - display: none; -} - #i18nStatus { margin-left: 0; } \ No newline at end of file diff --git a/css/SilverStripeNavigator.css b/css/SilverStripeNavigator.css index d39246a34..d39cfc7e0 100755 --- a/css/SilverStripeNavigator.css +++ b/css/SilverStripeNavigator.css @@ -4,24 +4,25 @@ bottom: 0; left: 0; width: 100%; - border-top: 3px solid #d4d0c8; + border-top: 2px solid #d4d0c8; background-color:#81858d; - height: 18px; + height: 22px; overflow:hidden; - background-image:url(../../cms/images/textures/bottom.png); + background: #4d4e5a url(../../cms/images/textures/footerBg.gif) repeat-x left top; +} +#SilverStripeNavigator * { + font-family: Arial,Helvetica,sans-serif; + font-size: 10px !important; } #SilverStripeNavigator .holder { - text-align: center; - padding-top : 3px; + padding-top : 4px; padding-left : 3px; padding-right : 6px; - font-size: 10px; color: white; border-top: 1px solid #555555; - } #SilverStripeNavigator #logInStatus { float: right; @@ -32,72 +33,52 @@ } #SilverStripeNavigator a { - color: #333; - background-color: transparent; - text-decoration: none; -} -#SilverStripeNavigator a:hover { - color: #333; + color: #fff; background-color: transparent; text-decoration: underline; } +#SilverStripeNavigator a:hover { + background-color: transparent; +} #SilverStripeNavigator .bottomTabs a { - width: auto; - display: block; - float : left; - height : 13px; - padding-left : 12px; - padding-right : 12px; - position:relative; - top : -3px; - border : 1px solid #65686e; - border-top : none; - cursor:pointer; - background-color: #cdc9c1; - color : #333333; - background-image: none; + margin-right: 8px; + text-decoration: underline; } #SilverStripeNavigator .bottomTabs div.blank { display: block; float : left; height : 13px; - padding-left : 12px; - padding-right : 12px; position:relative; - top : -3px; - border : 1px solid #65686e; - border-top : none; - cursor:pointer; - background-color: #cdc9c1; - color : #333333; - + top : -2px; + cursor: pointer; border : none; background-color: transparent; - padding-right: 2px; - padding-left: 2px; - padding-top : 2px; - color:#FFFFFF; + padding: 2px 4px 2px 2px; + font-weight: bold; } #SilverStripeNavigator .bottomTabs a.current { - background-color : #d4d0c8; - padding-top : 1px; - top : -5px; - height : 15px; font-weight:bold; - font-size : 11px; - border : 1px solid #555555; + text-decoration: none; } #SilverStripeNavigatorMessage { + font-family: 'Lucida Grande', Verdana, Arial, 'sans-serif'; position: absolute; - right: 45%; - top: 10px; + right: 20px; + top: 40px; padding: 10px; border-color: #c99; color: #fff; background-color: #c00; + border: 1px solid #000; +} + +#SilverStripeNavigator #logInStatus { + background:transparent url(../../cms/images/logout.gif) no-repeat scroll right top !important; + padding-bottom:4px; + padding-right:20px; } \ No newline at end of file diff --git a/css/TableListField.css b/css/TableListField.css index 42a99c741..c6f42d80c 100644 --- a/css/TableListField.css +++ b/css/TableListField.css @@ -8,7 +8,7 @@ table.CMSList { width : 100%; } -/* HACK Preventing IE6 from showing double borders */ +/* Preventing IE6 from showing double borders */ body>div table.TableField, body>div table.TableListField, body>div .TableListField table.data, @@ -113,6 +113,7 @@ table.CMSList tbody td.checkbox { table.TableField tbody tr.over td, .TableListField table.data tbody tr.over td, +.TableListField table.data tbody tr.over td input, table.CMSList tbody td.over td{ background-color: #FFCC66; } diff --git a/dev/BulkLoader.php b/dev/BulkLoader.php index 1cf380a10..261f433a6 100644 --- a/dev/BulkLoader.php +++ b/dev/BulkLoader.php @@ -93,7 +93,14 @@ abstract class BulkLoader extends ViewableData { * Specifies how to determine duplicates based on one or more provided fields * in the imported data, matching to properties on the used {@link DataObject} class. * Alternatively the array values can contain a callback method (see example for - * implementation details). + * implementation details). The callback method should be defined on the source class. + * + * NOTE: If you're trying to get a unique Member record by a particular field that + * isn't Email, you need to ensure that Member is correctly set to the unique field + * you want, as it will merge any duplicates during {@link Member::onBeforeWrite()}. + * + * {@see Member::set_unique_identifier_field()}. + * * If multiple checks are specified, the first one "wins". * *
@@ -222,7 +229,7 @@ abstract class BulkLoader extends ViewableData {
* @return boolean
*/
protected function isNullValue($val, $fieldName = null) {
- return (empty($val));
+ return (empty($val) && $val !== '0');
}
}
diff --git a/dev/DevelopmentAdmin.php b/dev/DevelopmentAdmin.php
index 4dce4b7a3..a40eb3b98 100644
--- a/dev/DevelopmentAdmin.php
+++ b/dev/DevelopmentAdmin.php
@@ -130,4 +130,4 @@ class DevelopmentAdmin extends Controller {
}
}
-?>
+?>
\ No newline at end of file
diff --git a/dev/InstallerTest.php b/dev/InstallerTest.php
index f35f972e1..b061235b3 100644
--- a/dev/InstallerTest.php
+++ b/dev/InstallerTest.php
@@ -11,4 +11,4 @@ class InstallerTest extends Controller {
}
}
-?>
+?>
\ No newline at end of file
diff --git a/dev/ModelViewer.php b/dev/ModelViewer.php
index d85dcabd2..4f5b7f358 100644
--- a/dev/ModelViewer.php
+++ b/dev/ModelViewer.php
@@ -171,5 +171,4 @@ class ModelViewer_Relation extends ViewableData {
}
-
-?>
+?>
\ No newline at end of file
diff --git a/dev/SSCli.php b/dev/SSCli.php
index 6987e1cd8..008294619 100644
--- a/dev/SSCli.php
+++ b/dev/SSCli.php
@@ -76,4 +76,4 @@ class SSCli extends Object {
}
}
-?>
+?>
\ No newline at end of file
diff --git a/dev/SapphireTest.php b/dev/SapphireTest.php
index dc63cc0a7..4a290a69d 100644
--- a/dev/SapphireTest.php
+++ b/dev/SapphireTest.php
@@ -236,4 +236,4 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
}
}
-?>
+?>
\ No newline at end of file
diff --git a/email/Email.php b/email/Email.php
index b287cc11f..257e63e09 100755
--- a/email/Email.php
+++ b/email/Email.php
@@ -262,6 +262,22 @@ class Email extends ViewableData {
$this->body;
}
+ /**
+ * Set template name (without *.ss extension).
+ *
+ * @param string $template
+ */
+ public function setTemplate($template) {
+ $this->ss_template = $template;
+ }
+
+ /**
+ * @return string
+ */
+ public function getTemplate() {
+ return $this->ss_template;
+ }
+
protected function templateData() {
if($this->template_data) {
return $this->template_data->customise(array(
@@ -384,6 +400,8 @@ class Email extends ViewableData {
if(trim($headers['Bcc'])) $headers['Bcc'] .= ', ';
$headers['Bcc'] .= self::$bcc_all_emails_to;
}
+
+ Requirements::restore();
return self::mailer()->sendPlain($to, $this->from, $subject, $this->body, $this->attachments, $headers);
}
@@ -543,12 +561,19 @@ class Email extends ViewableData {
*
* @param string $email Email-address
* @param string $method Method for obfuscating/encoding the address
+ * - 'direction': Reverse the text and then use CSS to put the text direction back to normal
* - 'visible': Simple string substitution ('@' to '[at]', '.' to '[dot], '-' to [dash])
* - 'hex': Hexadecimal URL-Encoding - useful for mailto: links
* @return string
*/
public static function obfuscate($email, $method = 'visible') {
switch($method) {
+ case 'direction' :
+ Requirements::customCSS(
+ 'span.codedirection { unicode-bidi: bidi-override; direction: rtl; }',
+ 'codedirectionCSS'
+ );
+ return '' . strrev($email) . '';
case 'visible' :
$obfuscated = array('@' => ' [at] ', '.' => ' [dot] ', '-' => ' [dash] ');
return strtr($email, $obfuscated);
@@ -714,38 +739,21 @@ class Email_BounceRecord extends DataObject {
static $has_one = array(
'Member' => 'Member'
);
+
+ static $has_many = array();
+
+ static $many_many = array();
+
+ static $defaults = array();
+
+
+ /**
+ * a record of Email_BounceRecord can't be created manually. Instead, it should be
+ * created though system.
+ */
+ public function canCreate($member = null) {
+ return false;
+ }
}
-/**
- * This class is responsible for ensuring that members who are on it receive NO email
- * communication at all. any correspondance is caught before the email is sent.
- * @package sapphire
- * @subpackage email
- */
-class Email_BlackList extends DataObject{
- static $db = array(
- 'BlockedEmail' => 'Varchar',
- );
- static $has_one = array(
- 'Member' => 'Member'
- );
-
- /**
- * Helper function to see if the email being
- * sent has specifically been blocked.
- */
- static function isBlocked($email){
- $blockedEmails = DataObject::get("Email_BlackList")->toDropDownMap("ID","BlockedEmail");
- if($blockedEmails){
- if(in_array($email,$blockedEmails)){
- return true;
- }else{
- return false;
- }
- }else{
- return false;
- }
- }
-}
-
-?>
+?>
\ No newline at end of file
diff --git a/email/Mailer.php b/email/Mailer.php
index 2b635f3ce..2c553d5f8 100644
--- a/email/Mailer.php
+++ b/email/Mailer.php
@@ -17,7 +17,7 @@ class Mailer extends Object {
* Send a plain-text email
*/
function sendPlain($to, $from, $subject, $plainContent, $attachedFiles = false, $customheaders = false) {
- return plaintextEmail($to, $from, $subject, $htmlContent, $attachedFiles, $customheaders);
+ return plaintextEmail($to, $from, $subject, $plainContent, $attachedFiles, $customheaders);
}
/**
@@ -428,4 +428,3 @@ function loadMimeTypes() {
$global_mimetypes = $mimeData;
return $mimeData;
}
-
diff --git a/email/QueuedEmail.php b/email/QueuedEmail.php
index e8cdd6693..72702ebf3 100644
--- a/email/QueuedEmail.php
+++ b/email/QueuedEmail.php
@@ -17,6 +17,12 @@ class QueuedEmail extends DataObject {
'To' => 'Member'
);
+ static $has_many = array();
+
+ static $many_many = array();
+
+ static $defaults = array();
+
// overwrite this method to provide a check whether or not to send the email
function canSendEmail() {
return true;
@@ -27,4 +33,4 @@ class QueuedEmail extends DataObject {
$email->send();
}
}
-?>
+?>
\ No newline at end of file
diff --git a/filesystem/File.php b/filesystem/File.php
index 19583e0fb..bf7c0e858 100755
--- a/filesystem/File.php
+++ b/filesystem/File.php
@@ -33,14 +33,21 @@ class File extends DataObject {
"Owner" => "Member"
);
- static $extensions = array(
- "Hierarchy",
- );
+ static $has_many = array();
+
+ static $many_many = array();
static $belongs_many_many = array(
"BackLinkTracking" => "SiteTree",
);
+ static $defaults = array();
+
+ static $extensions = array(
+ "Hierarchy",
+ );
+
+
/**
* Cached result of a "SHOW FIELDS" call
* in instance_get() for performance reasons.
diff --git a/filesystem/Filesystem.php b/filesystem/Filesystem.php
index 786ac1015..6e5ed4506 100755
--- a/filesystem/Filesystem.php
+++ b/filesystem/Filesystem.php
@@ -124,4 +124,4 @@ class Filesystem extends Object {
}
-?>
+?>
\ No newline at end of file
diff --git a/filesystem/Folder.php b/filesystem/Folder.php
index 3e82f1423..4aa6cad58 100755
--- a/filesystem/Folder.php
+++ b/filesystem/Folder.php
@@ -441,11 +441,11 @@ class Folder extends File {
*/
function getUploadIframe() {
return <<
+
HTML;
}
}
-?>
+?>
\ No newline at end of file
diff --git a/filesystem/GD.php b/filesystem/GD.php
index b6b602311..43c0afa97 100755
--- a/filesystem/GD.php
+++ b/filesystem/GD.php
@@ -408,4 +408,4 @@ class GD extends Object {
}
-?>
+?>
\ No newline at end of file
diff --git a/forms/CheckboxSetField.php b/forms/CheckboxSetField.php
index cd5f9c944..a1531e362 100755
--- a/forms/CheckboxSetField.php
+++ b/forms/CheckboxSetField.php
@@ -4,6 +4,15 @@
*
* ASSUMPTION -> IF you pass your source as an array, you pass values as an array too.
* Likewise objects are handled the same.
+ *
+ * @todo Document the different source data that can be used
+ * with this form field - e.g ComponentSet, DataObjectSet,
+ * array. Is it also appropriate to accept so many different
+ * types of data when just using an array would be appropriate?
+ *
+ * @todo Make use of FormField->createTag() to generate the
+ * HTML tag(s) for this field.
+ *
* @package forms
* @subpackage fields-basic
*/
@@ -11,11 +20,12 @@ class CheckboxSetField extends OptionsetField {
protected $disabled = false;
- /**
- * Object handles arrays and dosets being passed by reference.
- *
- * @todo Should use CheckboxField FieldHolder rather than constructing own markup.
- */
+ /**
+ * @todo Explain different source data that can be used with this field,
+ * e.g. SQLMap, DataObjectSet or an array.
+ *
+ * @todo Should use CheckboxField FieldHolder rather than constructing own markup.
+ */
function Field() {
Requirements::css(SAPPHIRE_DIR . '/css/CheckboxSetField.css');
@@ -86,10 +96,10 @@ class CheckboxSetField extends OptionsetField {
$checked = '';
if(isset($items)) {
- in_array($key,$items) ? $checked = " checked=\"checked\"" : $checked = "";
+ $checked = (in_array($key, $items)) ? ' checked="checked"' : '';
}
- $this->disabled ? $disabled = " disabled=\"disabled\"" : $disabled = "";
+ $disabled = ($this->disabled) ? $disabled = ' disabled="disabled"' : '';
$options .= "name[$key]\" type=\"checkbox\" value=\"$key\"$checked $disabled class=\"checkbox\" /> \n";
}
@@ -108,7 +118,7 @@ class CheckboxSetField extends OptionsetField {
if(!$value && $obj && $obj instanceof DataObject && $obj->hasMethod($this->name)) {
$funcName = $this->name;
$selected = $obj->$funcName();
- $value = $selected->toDropdownMap('ID','ID');
+ $value = $selected->toDropdownMap('ID', 'ID');
}
parent::setValue($value, $obj);
@@ -133,7 +143,7 @@ class CheckboxSetField extends OptionsetField {
$record->$fieldname()->setByIDList($idList);
} elseif($fieldname && $record) {
if($this->value) {
- $this->value = str_replace(",", "{comma}", $this->value);
+ $this->value = str_replace(',', '{comma}', $this->value);
$record->$fieldname = implode(",", $this->value);
} else {
$record->$fieldname = '';
@@ -142,79 +152,93 @@ class CheckboxSetField extends OptionsetField {
}
/**
- * Return the CheckboxSetField value, as an array of the selected item keys
+ * Return the CheckboxSetField value as an array
+ * selected item keys.
+ *
+ * @return string
*/
function dataValue() {
- if($this->value&&is_array($this->value)){
- // Filter items to those who aren't 0
+ if($this->value && is_array($this->value)) {
$filtered = array();
- foreach($this->value as $item) if($item) $filtered[] = str_replace(",", "{comma}", $item);
- return implode(",", $filtered);
- } else {
- return '';
+ foreach($this->value as $item) {
+ if($item) {
+ $filtered[] = str_replace(",", "{comma}", $item);
+ }
+ }
+
+ return implode(',', $filtered);
}
+
+ return '';
}
function performDisabledTransformation() {
$clone = clone $this;
$clone->setDisabled(true);
+
return $clone;
}
/**
- * Makes a pretty readonly field
- */
-
+ * Transforms the source data for this CheckboxSetField
+ * into a comma separated list of values.
+ *
+ * @return ReadonlyField
+ */
function performReadonlyTransformation() {
$values = '';
+ $data = array();
$items = $this->value;
- foreach($this->source as $source) {
- if(is_object($source)) {
- $sourceTitles[$source->ID] = $source->Title;
+ if($this->source) {
+ foreach($this->source as $source) {
+ if(is_object($source)) {
+ $sourceTitles[$source->ID] = $source->Title;
+ }
}
}
- if($items){
+ if($items) {
// Items is a DO Set
- if(is_a($items,'DataObjectSet')){
-
- foreach($items as $item){
+ if(is_a($items, 'DataObjectSet')) {
+ foreach($items as $item) {
$data[] = $item->Title;
}
- if($data) {
- $values = implode(", ",$data);
- }
-
+ if($data) $values = implode(', ', $data);
+
// Items is an array or single piece of string (including comma seperated string)
- }else{
+ } else {
if(!is_array($items)) {
- $items = split(" *, *", trim($items));
+ $items = split(' *, *', trim($items));
}
- foreach($items as $item){
+
+ foreach($items as $item) {
if(is_array($item)) {
$data[] = $item['Title'];
- } else if(is_array($this->source) && !empty($this->source[$item])) {
+ } elseif(is_array($this->source) && !empty($this->source[$item])) {
$data[] = $this->source[$item];
- } else if(is_a($this->source, "ComponentSet")){
- //added for editable checkboxset.
+ } elseif(is_a($this->source, 'ComponentSet')) {
$data[] = $sourceTitles[$item];
-
} else {
$data[] = $item;
}
}
- $values = implode(", ",$data);
+
+ $values = implode(', ', $data);
}
}
- $field = new ReadonlyField($this->name,$this->title ? $this->title : "",$values);
+ $title = ($this->title) ? $this->title : '';
+
+ $field = new ReadonlyField($this->name, $title, $values);
$field->setForm($this->form);
+
return $field;
}
function ExtraOptions() {
return FormField::ExtraOptions();
- }
+ }
+
}
-?>
+?>
\ No newline at end of file
diff --git a/forms/ComplexTableField.php b/forms/ComplexTableField.php
index 104f30621..13c1dc951 100755
--- a/forms/ComplexTableField.php
+++ b/forms/ComplexTableField.php
@@ -472,7 +472,7 @@ JS;
if(!$childData->ID && $this->getParentClass()) {
// make sure the relation-link is existing, even if we just add the sourceClass and didn't save it
$parentIDName = $this->getParentIdName( $this->getParentClass(), $this->sourceClass() );
- $childData->$parentIDName = $childData->ID;
+ $childData->$parentIDName = $this->sourceID();
}
$detailFields = $this->getCustomFieldsFor($childData);
@@ -725,8 +725,10 @@ class ComplexTableField_ItemRequest extends RequestHandler {
* @see Form::ReferencedField
*/
function saveComplexTableField($data, $form, $request) {
- $form->saveInto($this->dataObj());
- $this->dataObj()->write();
+ $dataObject = $this->dataObj();
+
+ $form->saveInto($dataObject);
+ $dataObject->write();
$closeLink = sprintf(
'(%s)',
@@ -734,8 +736,8 @@ class ComplexTableField_ItemRequest extends RequestHandler {
);
$message = sprintf(
_t('ComplexTableField.SUCCESSEDIT', 'Saved %s %s %s'),
- $this->dataObj()->singular_name(),
- '"' . $this->dataObj()->Title . '"',
+ $dataObject->singular_name(),
+ '"' . $dataObject->Title . '"',
$closeLink
);
$form->sessionMessage($message, 'good');
@@ -753,8 +755,9 @@ class ComplexTableField_ItemRequest extends RequestHandler {
if(!isset($_REQUEST['ctf']['start']) || !is_numeric($_REQUEST['ctf']['start']) || $_REQUEST['ctf']['start'] == 0) {
return null;
}
-
- $item = $this->unpagedSourceItems->First();
+
+ // We never use $item afterwards in the function, where we have it here? disable it!
+ //$item = $this->unpagedSourceItems->First();
$start = 0;
return Controller::join_links($this->Link(), "$this->methodName?ctf[start]={$start}");
}
@@ -763,8 +766,9 @@ class ComplexTableField_ItemRequest extends RequestHandler {
if(!isset($_REQUEST['ctf']['start']) || !is_numeric($_REQUEST['ctf']['start']) || $_REQUEST['ctf']['start'] == $this->totalCount-1) {
return null;
}
-
- $item = $this->unpagedSourceItems->Last();
+
+ // We never use $item afterwards in the function, where we have it here? disable it!
+ // $item = $this->unpagedSourceItems->Last();
$start = $this->totalCount - 1;
return Controller::join_links($this->Link(), "$this->methodName?ctf[start]={$start}");
}
@@ -774,7 +778,8 @@ class ComplexTableField_ItemRequest extends RequestHandler {
return null;
}
- $item = $this->unpagedSourceItems->getIterator()->getOffset($_REQUEST['ctf']['start'] + 1);
+ // We never use $item afterwards in the function, where we have it here? disable it!
+ //$item = $this->unpagedSourceItems->getIterator()->getOffset($_REQUEST['ctf']['start'] + 1);
$start = $_REQUEST['ctf']['start'] + 1;
return Controller::join_links($this->Link(), "$this->methodName?ctf[start]={$start}");
@@ -785,7 +790,8 @@ class ComplexTableField_ItemRequest extends RequestHandler {
return null;
}
- $item = $this->unpagedSourceItems->getIterator()->getOffset($_REQUEST['ctf']['start'] - 1);
+ // We never use $item afterwards in the function, where we have it here? disable it!
+ //$item = $this->unpagedSourceItems->getIterator()->getOffset($_REQUEST['ctf']['start'] - 1);
$start = $_REQUEST['ctf']['start'] - 1;
return Controller::join_links($this->Link(), "$this->methodName?ctf[start]={$start}");
diff --git a/forms/CompositeDateField.php b/forms/CompositeDateField.php
index 3b52407a9..294c8de7a 100755
--- a/forms/CompositeDateField.php
+++ b/forms/CompositeDateField.php
@@ -175,4 +175,4 @@ class CompositeDateField_Disabled extends DateField {
return "date_disabled readonly";
}
}
-?>
+?>
\ No newline at end of file
diff --git a/forms/CountryDropdownField.php b/forms/CountryDropdownField.php
index 2b13786b8..74e0606b6 100644
--- a/forms/CountryDropdownField.php
+++ b/forms/CountryDropdownField.php
@@ -28,4 +28,4 @@ class CountryDropdownField extends DropdownField {
}
}
-?>
+?>
\ No newline at end of file
diff --git a/forms/DateField.php b/forms/DateField.php
index 524c79c48..92f26bf5b 100755
--- a/forms/DateField.php
+++ b/forms/DateField.php
@@ -112,15 +112,16 @@ class DateField_Disabled extends DateField {
$df->setValue($this->dataValue());
if(date('Y-m-d', time()) == $this->dataValue()) {
- $val = Convert::raw2xml($this->value . ' ('._t('DateField.TODAY','today').')');
+ $val = Convert::raw2xml($this->value . ' ('._t('DateField.TODAY','today').')');
} else {
$val = Convert::raw2xml($this->value . ', ' . $df->Ago());
}
} else {
- $val = '('._t('DateField.NOTSET', 'not set').')';
+ $val = '('._t('DateField.NOTSET', 'not set').')';
}
- return "id() . "\">$val";
+ return "id() . "\">$val
+ value}\" name=\"$this->name\" />";
}
function Type() {
@@ -139,4 +140,4 @@ class DateField_Disabled extends DateField {
return true;
}
}
-?>
+?>
\ No newline at end of file
diff --git a/forms/FieldGroup.php b/forms/FieldGroup.php
index 96dd4ef68..e40165346 100755
--- a/forms/FieldGroup.php
+++ b/forms/FieldGroup.php
@@ -83,7 +83,22 @@ class FieldGroup extends CompositeField {
}
function FieldHolder() {
- return FormField::FieldHolder();
+ $Title = $this->XML_val('Title');
+ $Message = $this->XML_val('Message');
+ $MessageType = $this->XML_val('MessageType');
+ $RightTitle = $this->XML_val('RightTitle');
+ $Type = $this->XML_val('Type');
+ $extraClass = $this->XML_val('extraClass');
+ $Name = $this->XML_val('Name');
+ $Field = $this->XML_val('Field');
+
+ $titleBlock = (!empty($Title)) ? "" : "";
+ $messageBlock = (!empty($Message)) ? " " : "";
+ $rightTitleBlock = (!empty($RightTitle)) ? "" : "";
+
+ return <<$titleBlock$Field$rightTitleBlock$messageBlock