mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merged branches/2.3
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@66108 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
8052c5dce4
commit
3d9532db83
@ -54,6 +54,14 @@ class RestfulService extends ViewableData {
|
|||||||
return "$this->baseURL" . ($this->queryString ? "?$this->queryString" : "");
|
return "$this->baseURL" . ($this->queryString ? "?$this->queryString" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use RestfulService::request()
|
||||||
|
*/
|
||||||
|
public function connect($subURL = '') {
|
||||||
|
user_error("RestfulService::connect is deprecated; use RestfulService::request", E_USER_NOTICE);
|
||||||
|
return $this->request($subURL, 'GET');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a request to the RESTful server, and return a {@link RestfulService_Response} object for parsing of the result.
|
* Makes a request to the RESTful server, and return a {@link RestfulService_Response} object for parsing of the result.
|
||||||
* @todo Better POST, PUT, DELETE, and HEAD support
|
* @todo Better POST, PUT, DELETE, and HEAD support
|
||||||
|
@ -14,6 +14,12 @@
|
|||||||
* - SS_DATABASE_SUFFIX: A suffix to add to the database name.
|
* - SS_DATABASE_SUFFIX: A suffix to add to the database name.
|
||||||
* - SS_DATABASE_PREFIX: A prefix to add to the database name.
|
* - SS_DATABASE_PREFIX: A prefix to add to the database name.
|
||||||
*
|
*
|
||||||
|
* There is one more setting that is intended to be used by people who work on SilverStripe.
|
||||||
|
* - SS_DATABASE_CHOOSE_NAME: Boolean. If true, then the system will choose a default database name for you if one isn't give
|
||||||
|
* in the $database variable. The database name will be "SS_" followed by the name of the folder into which you have installed
|
||||||
|
* SilverStripe. If this is enabled, it means that the phpinstaller will work out of the box without the installer needing to
|
||||||
|
* alter any files. This helps prevent accidental changes to the environment.
|
||||||
|
*
|
||||||
* You can configure the environment with this define:
|
* You can configure the environment with this define:
|
||||||
* - SS_ENVIRONMENT_TYPE: The environment type: dev, test or live.
|
* - SS_ENVIRONMENT_TYPE: The environment type: dev, test or live.
|
||||||
*
|
*
|
||||||
@ -31,15 +37,31 @@
|
|||||||
/*
|
/*
|
||||||
* _ss_environment.php handler
|
* _ss_environment.php handler
|
||||||
*/
|
*/
|
||||||
|
if(defined('SS_ENVIRONMENT_FILE')) {
|
||||||
|
// Only perform valdiation if SS_ENVIRONMENT_FILE is actually set, which is to say, there is an _ss_environment.php file
|
||||||
foreach(array(
|
foreach(array(
|
||||||
'SS_DATABASE_PASSWORD',
|
'SS_DATABASE_PASSWORD',
|
||||||
'SS_DATABASE_USERNAME',
|
'SS_DATABASE_USERNAME',
|
||||||
'SS_ENVIRONMENT_TYPE',) as $reqDefine) {
|
'SS_ENVIRONMENT_TYPE',) as $reqDefine) {
|
||||||
if(!defined($reqDefine)) user_error("$reqDefine must be defined in your _ss_environment.php. See http://doc.silverstripe.com/doku.php?id=environment-management for more infomration", E_USER_ERROR);
|
if(!defined($reqDefine)) user_error("$reqDefine must be defined in your _ss_environment.php. See http://doc.silverstripe.com/doku.php?id=environment-management for more infomration", E_USER_ERROR);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(defined('SS_ENVIRONMENT_TYPE')) {
|
||||||
Director::set_environment_type(SS_ENVIRONMENT_TYPE);
|
Director::set_environment_type(SS_ENVIRONMENT_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
global $database;
|
||||||
|
|
||||||
|
// No database provided
|
||||||
|
if(!isset($database) || !$database) {
|
||||||
|
// if SS_DATABASE_CHOOSE_NAME
|
||||||
|
if(defined('SS_DATABASE_CHOOSE_NAME') && SS_DATABASE_CHOOSE_NAME) {
|
||||||
|
$database = "SS_" . basename(dirname(dirname($_SERVER['SCRIPT_FILENAME'])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(defined('SS_DATABASE_USERNAME') && defined('SS_DATABASE_PASSWORD')) {
|
||||||
global $databaseConfig;
|
global $databaseConfig;
|
||||||
$databaseConfig = array(
|
$databaseConfig = array(
|
||||||
"type" => "MySQLDatabase",
|
"type" => "MySQLDatabase",
|
||||||
@ -50,6 +72,7 @@ $databaseConfig = array(
|
|||||||
. $database
|
. $database
|
||||||
. (defined('SS_DATABASE_SUFFIX') ? SS_DATABASE_SUFFIX : ''),
|
. (defined('SS_DATABASE_SUFFIX') ? SS_DATABASE_SUFFIX : ''),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if(defined('SS_SEND_ALL_EMAILS_TO')) {
|
if(defined('SS_SEND_ALL_EMAILS_TO')) {
|
||||||
Email::send_all_emails_to(SS_SEND_ALL_EMAILS_TO);
|
Email::send_all_emails_to(SS_SEND_ALL_EMAILS_TO);
|
||||||
|
@ -29,6 +29,7 @@ error_reporting(E_ALL);
|
|||||||
$envFiles = array('../_ss_environment.php', '../../_ss_environment.php', '../../../_ss_environment.php');
|
$envFiles = array('../_ss_environment.php', '../../_ss_environment.php', '../../../_ss_environment.php');
|
||||||
foreach($envFiles as $envFile) {
|
foreach($envFiles as $envFile) {
|
||||||
if(file_exists($envFile)) {
|
if(file_exists($envFile)) {
|
||||||
|
define('SS_ENVIRONMENT_FILE', $envFile);
|
||||||
include_once($envFile);
|
include_once($envFile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -257,6 +258,7 @@ function getClassFile($className) {
|
|||||||
function singleton($className) {
|
function singleton($className) {
|
||||||
static $_SINGLETONS;
|
static $_SINGLETONS;
|
||||||
if(!isset($className)) user_error("singleton() Called without a class", E_USER_ERROR);
|
if(!isset($className)) user_error("singleton() Called without a class", E_USER_ERROR);
|
||||||
|
if(!is_string($className)) user_error("singleton() passed bad class_name: " . var_export($className,true), E_USER_ERROR);
|
||||||
if(!isset($_SINGLETONS[$className])) {
|
if(!isset($_SINGLETONS[$className])) {
|
||||||
if(!class_exists($className)) user_error("Bad class to singleton() - $className", E_USER_ERROR);
|
if(!class_exists($className)) user_error("Bad class to singleton() - $className", E_USER_ERROR);
|
||||||
$_SINGLETONS[$className] = Object::strong_create($className,null, true);
|
$_SINGLETONS[$className] = Object::strong_create($className,null, true);
|
||||||
|
@ -104,6 +104,8 @@ class HTTP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static function findByTagAndAttribute($content, $attribs) {
|
static function findByTagAndAttribute($content, $attribs) {
|
||||||
|
$regExps = array();
|
||||||
|
$content = '';
|
||||||
|
|
||||||
foreach($attribs as $tag => $attrib) {
|
foreach($attribs as $tag => $attrib) {
|
||||||
if(!is_numeric($tag)) $tagPrefix = "$tag ";
|
if(!is_numeric($tag)) $tagPrefix = "$tag ";
|
||||||
@ -114,9 +116,11 @@ class HTTP {
|
|||||||
$regExps[] = "/(<{$tagPrefix}[^>]*$attrib *= *)([^\"' ]*)( )/ie";
|
$regExps[] = "/(<{$tagPrefix}[^>]*$attrib *= *)([^\"' ]*)( )/ie";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($regExps) {
|
||||||
foreach($regExps as $regExp) {
|
foreach($regExps as $regExp) {
|
||||||
$content = preg_replace($regExp, '$items[] = "$2"', $content);
|
$content = preg_replace($regExp, '$items[] = "$2"', $content);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return isset($items) ? $items : null;
|
return isset($items) ? $items : null;
|
||||||
}
|
}
|
||||||
|
@ -343,18 +343,11 @@ class Object {
|
|||||||
if($builtIn) {
|
if($builtIn) {
|
||||||
$val = $this->stat($name);
|
$val = $this->stat($name);
|
||||||
$val2 = null;
|
$val2 = null;
|
||||||
try {
|
|
||||||
// The reflection doesn't work properly in 5.1.2
|
// isset() can handle the case where a variable isn't defined; more reliable than reflection
|
||||||
if(phpversion() == '5.1.2') {
|
$propertyName = get_parent_class($this) . "::\$$name";
|
||||||
$val2 = eval('return ' . get_parent_class($this) . "::\$$name;");
|
$val2 = eval("return isset($propertyName) ? $propertyName : null;");
|
||||||
} else {
|
|
||||||
$reflection = new ReflectionClass(get_parent_class($this));
|
|
||||||
$property = $reflection->getProperty($name);
|
|
||||||
$val2 = $property->getValue();
|
|
||||||
}
|
|
||||||
} catch(Exception $exc) {
|
|
||||||
// do nothing.. the property doesn't exists!
|
|
||||||
}
|
|
||||||
return ($val != $val2) ? $val : null;
|
return ($val != $val2) ? $val : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -793,11 +793,6 @@ class Requirements_Backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @todo Alters the original information, which means you can't call this
|
|
||||||
// method repeatedly - it will behave different on the second call!
|
|
||||||
$this->javascript = $newJSRequirements;
|
|
||||||
$this->css = $newCSSRequirements;
|
|
||||||
|
|
||||||
// Process the combined files
|
// Process the combined files
|
||||||
$base = Director::baseFolder() . '/';
|
$base = Director::baseFolder() . '/';
|
||||||
foreach(array_diff_key($combinedFiles,$this->blocked) as $combinedFile => $dummy) {
|
foreach(array_diff_key($combinedFiles,$this->blocked) as $combinedFile => $dummy) {
|
||||||
@ -834,11 +829,35 @@ class Requirements_Backend {
|
|||||||
if(!file_exists(dirname($base . $combinedFile))) {
|
if(!file_exists(dirname($base . $combinedFile))) {
|
||||||
Filesytem::makeFolder(dirname($base . $combinedFile));
|
Filesytem::makeFolder(dirname($base . $combinedFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$successfulWrite = false;
|
||||||
$fh = fopen($base . $combinedFile, 'w');
|
$fh = fopen($base . $combinedFile, 'w');
|
||||||
fwrite($fh, $combinedData);
|
if($fh) {
|
||||||
|
if(fwrite($fh, $combinedData) == strlen($combinedData)) $successfulWrite = true;
|
||||||
fclose($fh);
|
fclose($fh);
|
||||||
unset($fh);
|
unset($fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unsuccessful write - just include the regular JS files, rather than the combined one
|
||||||
|
if(!$successfulWrite) {
|
||||||
|
user_error("Requirements_Backend::process_combined_files(): Couldn't create '$base$combinedFile'", E_USER_WARNING);
|
||||||
|
$keyedFileList = array();
|
||||||
|
foreach($fileList as $file) $keyedFileList[$file] = true;
|
||||||
|
$combinedPos = array_search($combinedFile, array_keys($newJSRequirements));
|
||||||
|
if($combinedPos) {
|
||||||
|
$newJSRequirements = array_merge(
|
||||||
|
array_slice($newJSRequirements, 0, $combinedPos),
|
||||||
|
$keyedFileList,
|
||||||
|
array_slice($newJSRequirements, $combinedPos+1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @todo Alters the original information, which means you can't call this
|
||||||
|
// method repeatedly - it will behave different on the second call!
|
||||||
|
$this->javascript = $newJSRequirements;
|
||||||
|
$this->css = $newCSSRequirements;
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_custom_scripts() {
|
function get_custom_scripts() {
|
||||||
|
@ -963,7 +963,7 @@ class ViewableData_Customised extends ViewableData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function XML_val($fieldName, $args = null) {
|
function XML_val($fieldName, $args = null, $cache = false) {
|
||||||
if(isset($this->extraData[$fieldName])) {
|
if(isset($this->extraData[$fieldName])) {
|
||||||
if(isset($_GET['debug_profile'])) {
|
if(isset($_GET['debug_profile'])) {
|
||||||
Profiler::mark("template($fieldName)", " on $this->class object");
|
Profiler::mark("template($fieldName)", " on $this->class object");
|
||||||
@ -981,7 +981,7 @@ class ViewableData_Customised extends ViewableData {
|
|||||||
|
|
||||||
return $val;
|
return $val;
|
||||||
} else {
|
} else {
|
||||||
return $this->obj->XML_val($fieldName, $args);
|
return $this->obj->XML_val($fieldName, $args, $cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,8 +677,6 @@ class Director {
|
|||||||
* For information about environment types, see {@link Director::set_environment_type()}.
|
* For information about environment types, see {@link Director::set_environment_type()}.
|
||||||
*/
|
*/
|
||||||
static function isDev() {
|
static function isDev() {
|
||||||
if(self::$environment_type) return self::$environment_type == 'dev';
|
|
||||||
|
|
||||||
// Use ?isDev=1 to get development access on the live server
|
// Use ?isDev=1 to get development access on the live server
|
||||||
if(isset($_GET['isDev'])) {
|
if(isset($_GET['isDev'])) {
|
||||||
if(Security::database_is_ready()) {
|
if(Security::database_is_ready()) {
|
||||||
@ -691,6 +689,8 @@ class Director {
|
|||||||
|
|
||||||
if(isset($_SESSION['isDev']) && $_SESSION['isDev']) return true;
|
if(isset($_SESSION['isDev']) && $_SESSION['isDev']) return true;
|
||||||
|
|
||||||
|
if(self::$environment_type) return self::$environment_type == 'dev';
|
||||||
|
|
||||||
// Check if we are running on one of the development servers
|
// Check if we are running on one of the development servers
|
||||||
if(in_array($_SERVER['HTTP_HOST'], Director::$dev_servers)) {
|
if(in_array($_SERVER['HTTP_HOST'], Director::$dev_servers)) {
|
||||||
return true;
|
return true;
|
||||||
@ -710,6 +710,8 @@ class Director {
|
|||||||
* For information about environment types, see {@link Director::set_environment_type()}.
|
* For information about environment types, see {@link Director::set_environment_type()}.
|
||||||
*/
|
*/
|
||||||
static function isTest() {
|
static function isTest() {
|
||||||
|
if(self::isDev()) return false;
|
||||||
|
|
||||||
if(self::$environment_type) {
|
if(self::$environment_type) {
|
||||||
return self::$environment_type == 'test';
|
return self::$environment_type == 'test';
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,8 @@ class DB {
|
|||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
static function isActive() {
|
static function isActive() {
|
||||||
return DB::$globalConn->isActive();
|
if(DB::$globalConn) return DB::$globalConn->isActive();
|
||||||
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1250,7 +1250,13 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
return $candidate;
|
return $candidate;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
eval("\$items = isset(\$items) ? array_merge((array){$class}::\$has_one, (array)\$items) : (array){$class}::\$has_one;");
|
$newItems = eval("return (array){$class}::\$has_one;");
|
||||||
|
// Validate the data
|
||||||
|
foreach($newItems as $k => $v) {
|
||||||
|
if(!is_string($k) || is_numeric($k) || !is_string($v)) user_error("$class::\$has_one has a bad entry: "
|
||||||
|
. var_export($k,true). " => " . var_export($v,true) . ". Each map key should be a relationship name, and the map value should be the data class to join to.", E_USER_ERROR);
|
||||||
|
}
|
||||||
|
$items = isset($items) ? array_merge($newItems, (array)$items) : $newItems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return isset($items) ? $items : null;
|
return isset($items) ? $items : null;
|
||||||
@ -1282,7 +1288,13 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
return $candidate;
|
return $candidate;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
eval("\$items = array_merge((array)\$items, (array){$class}::\$db);");
|
$newItems = eval("return (array){$class}::\$db;");
|
||||||
|
// Validate the data
|
||||||
|
foreach($newItems as $k => $v) {
|
||||||
|
if(!is_string($k) || is_numeric($k) || !is_string($v)) user_error("$class::\$db has a bad entry: "
|
||||||
|
. var_export($k,true). " => " . var_export($v,true) . ". Each map key should be a property name, and the map value should be the property type.", E_USER_ERROR);
|
||||||
|
}
|
||||||
|
$items = isset($items) ? array_merge($newItems, (array)$items) : $newItems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1310,7 +1322,13 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
return $candidate;
|
return $candidate;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
eval("\$items = isset(\$items) ? array_merge((array){$class}::\$has_many, (array)\$items) : (array){$class}::\$has_many;");
|
$newItems = eval("return (array){$class}::\$has_many;");
|
||||||
|
// Validate the data
|
||||||
|
foreach($newItems as $k => $v) {
|
||||||
|
if(!is_string($k) || is_numeric($k) || !is_string($v)) user_error("$class::\$has_many has a bad entry: "
|
||||||
|
. var_export($k,true). " => " . var_export($v,true) . ". Each map key should be a relationship name, and the map value should be the data class to join to.", E_USER_ERROR);
|
||||||
|
}
|
||||||
|
$items = isset($items) ? array_merge($newItems, (array)$items) : $newItems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1369,10 +1387,25 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
user_error("Orphaned \$belongs_many_many value for $this->class.$component", E_USER_ERROR);
|
user_error("Orphaned \$belongs_many_many value for $this->class.$component", E_USER_ERROR);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
eval("\$items = isset(\$items) ? array_merge((array){$class}::\$many_many, (array)\$items) : (array){$class}::\$many_many;");
|
$newItems = eval("return (array){$class}::\$many_many;");
|
||||||
eval("\$items = array_merge((array){$class}::\$belongs_many_many, (array)\$items);");
|
// Validate the data
|
||||||
|
foreach($newItems as $k => $v) {
|
||||||
|
if(!is_string($k) || is_numeric($k) || !is_string($v)) user_error("$class::\$many_many has a bad entry: "
|
||||||
|
. var_export($k,true). " => " . var_export($v,true) . ". Each map key should be a relationship name, and the map value should be the data class to join to.", E_USER_ERROR);
|
||||||
|
}
|
||||||
|
$items = isset($items) ? array_merge($newItems, $items) : $newItems;
|
||||||
|
|
||||||
|
$newItems = eval("return (array){$class}::\$belongs_many_many;");
|
||||||
|
// Validate the data
|
||||||
|
foreach($newItems as $k => $v) {
|
||||||
|
if(!is_string($k) || is_numeric($k) || !is_string($v)) user_error("$class::\$belongs_many_many has a bad entry: "
|
||||||
|
. var_export($k,true). " => " . var_export($v,true) . ". Each map key should be a relationship name, and the map value should be the data class to join to.", E_USER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
$items = isset($items) ? array_merge($newItems, $items) : $newItems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return isset($items) ? $items : null;
|
return isset($items) ? $items : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2176,7 +2209,7 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
*/
|
*/
|
||||||
function buildDataObjectSet($records, $containerClass = "DataObjectSet", $query = null, $baseClass = null) {
|
function buildDataObjectSet($records, $containerClass = "DataObjectSet", $query = null, $baseClass = null) {
|
||||||
foreach($records as $record) {
|
foreach($records as $record) {
|
||||||
if(!$record['RecordClassName']) {
|
if(empty($record['RecordClassName'])) {
|
||||||
$record['RecordClassName'] = $record['ClassName'];
|
$record['RecordClassName'] = $record['ClassName'];
|
||||||
}
|
}
|
||||||
if(class_exists($record['RecordClassName'])) {
|
if(class_exists($record['RecordClassName'])) {
|
||||||
|
@ -103,6 +103,7 @@ class ErrorPage extends Page {
|
|||||||
Requirements::clear();
|
Requirements::clear();
|
||||||
$controller = new ErrorPage_Controller($this);
|
$controller = new ErrorPage_Controller($this);
|
||||||
$errorContent = $controller->handleRequest(new HTTPRequest('GET',''))->getBody();
|
$errorContent = $controller->handleRequest(new HTTPRequest('GET',''))->getBody();
|
||||||
|
Requirements::clear();
|
||||||
|
|
||||||
if(!file_exists(ASSETS_PATH)) {
|
if(!file_exists(ASSETS_PATH)) {
|
||||||
mkdir(ASSETS_PATH, 02775);
|
mkdir(ASSETS_PATH, 02775);
|
||||||
|
@ -80,8 +80,8 @@ class SiteTree extends DataObject {
|
|||||||
"ReportClass" => "Varchar",
|
"ReportClass" => "Varchar",
|
||||||
"Priority" => "Float",
|
"Priority" => "Float",
|
||||||
|
|
||||||
"CanViewType" => "Enum('Anyone, LoggedInUsers, OnlyTheseUsers, Inherit', 'Anyone')",
|
"CanViewType" => "Enum('Anyone, LoggedInUsers, OnlyTheseUsers, Inherit', 'Inherit')",
|
||||||
"CanEditType" => "Enum('LoggedInUsers, OnlyTheseUsers, Inherit', 'OnlyTheseUsers')",
|
"CanEditType" => "Enum('LoggedInUsers, OnlyTheseUsers, Inherit', 'Inherit')",
|
||||||
|
|
||||||
// Simple task tracking
|
// Simple task tracking
|
||||||
"ToDo" => "Text",
|
"ToDo" => "Text",
|
||||||
@ -123,8 +123,8 @@ class SiteTree extends DataObject {
|
|||||||
"ShowInMenus" => 1,
|
"ShowInMenus" => 1,
|
||||||
"ShowInSearch" => 1,
|
"ShowInSearch" => 1,
|
||||||
"Status" => "New page",
|
"Status" => "New page",
|
||||||
"CanViewType" => "Anyone",
|
"CanViewType" => "Inherit",
|
||||||
"CanEditType" => "OnlyTheseUsers"
|
"CanEditType" => "Inherit"
|
||||||
);
|
);
|
||||||
|
|
||||||
static $has_one = array(
|
static $has_one = array(
|
||||||
@ -609,14 +609,13 @@ class SiteTree extends DataObject {
|
|||||||
if($results && is_array($results)) if(!min($results)) return false;
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
|
|
||||||
// check for empty spec
|
// check for empty spec
|
||||||
if(
|
if(!$this->CanViewType || $this->CanViewType == 'Anyone') return true;
|
||||||
!$this->CanViewType || $this->CanViewType == 'Anyone'
|
|
||||||
) return true;
|
|
||||||
|
|
||||||
// check for inherit
|
// check for inherit
|
||||||
if(
|
if($this->CanViewType == 'Inherit') {
|
||||||
$this->CanViewType == 'Inherit' && $this->Parent()
|
if($this->ParentID) return $this->Parent()->canView($member);
|
||||||
) return $this->Parent()->canView($member);
|
else return true;
|
||||||
|
}
|
||||||
|
|
||||||
// check for any logged-in users
|
// check for any logged-in users
|
||||||
if(
|
if(
|
||||||
@ -743,27 +742,19 @@ class SiteTree extends DataObject {
|
|||||||
if(!$this->canView()) return false;
|
if(!$this->canView()) return false;
|
||||||
|
|
||||||
// check for empty spec
|
// check for empty spec
|
||||||
if(
|
if(!$this->CanEditType || $this->CanEditType == 'Anyone') return true;
|
||||||
!$this->CanEditType || $this->CanEditType == 'Anyone'
|
|
||||||
) return true;
|
|
||||||
|
|
||||||
// check for inherit
|
// check for inherit
|
||||||
if(
|
if($this->CanEditType == 'Inherit') {
|
||||||
$this->CanEditType == 'Inherit' && $this->Parent()
|
if($this->ParentID) return $this->Parent()->canEdit($member);
|
||||||
) return $this->Parent()->canEdit($member);
|
else return Permission::checkMember($member, 'CMS_ACCESS_CMSMain');
|
||||||
|
}
|
||||||
|
|
||||||
// check for any logged-in users
|
// check for any logged-in users
|
||||||
if(
|
if($this->CanEditType == 'LoggedInUsers' && Permission::checkMember($member, 'CMS_ACCESS_CMSMain')) return true;
|
||||||
$this->CanEditType == 'LoggedInUsers'
|
|
||||||
&& Permission::checkMember($member, 'CMS_ACCESS_CMSMain')
|
|
||||||
) return true;
|
|
||||||
|
|
||||||
// check for specific groups
|
// check for specific groups
|
||||||
if(
|
if($this->CanEditType == 'OnlyTheseUsers' && $member && $member->inGroups($this->EditorGroups())) return true;
|
||||||
$this->CanEditType == 'OnlyTheseUsers'
|
|
||||||
&& $member
|
|
||||||
&& $member->inGroups($this->EditorGroups())
|
|
||||||
) return true;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1527,6 +1518,8 @@ class SiteTree extends DataObject {
|
|||||||
$result[$class] = ($class == $this->class)
|
$result[$class] = ($class == $this->class)
|
||||||
? _t('SiteTree.CURRENTLY', 'Currently').' '.$addAction
|
? _t('SiteTree.CURRENTLY', 'Currently').' '.$addAction
|
||||||
: _t('SiteTree.CHANGETO', 'Change to').' '.$addAction;
|
: _t('SiteTree.CHANGETO', 'Change to').' '.$addAction;
|
||||||
|
$currentAddAction = null;
|
||||||
|
$currentClass = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1703,6 +1696,9 @@ class SiteTree extends DataObject {
|
|||||||
if(!$this->canEdit() && !$this->canAddChildren())
|
if(!$this->canEdit() && !$this->canAddChildren())
|
||||||
$classes .= " disabled";
|
$classes .= " disabled";
|
||||||
|
|
||||||
|
if(!$this->ShowInMenus)
|
||||||
|
$classes .= " notinmenu";
|
||||||
|
|
||||||
$classes .= $this->markingClasses();
|
$classes .= $this->markingClasses();
|
||||||
|
|
||||||
return $classes;
|
return $classes;
|
||||||
|
@ -96,6 +96,8 @@ class Text extends DBField {
|
|||||||
*/
|
*/
|
||||||
function FirstSentence() {
|
function FirstSentence() {
|
||||||
$data = Convert::xml2raw( $this->value );
|
$data = Convert::xml2raw( $this->value );
|
||||||
|
if( !$data ) return "";
|
||||||
|
|
||||||
|
|
||||||
$sentences = explode( '.', $data );
|
$sentences = explode( '.', $data );
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ class CsvBulkLoader extends BulkLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach($csv as $row) {
|
foreach($csv as $row) {
|
||||||
$this->processRecord($row, array(), $results, $preview);
|
$this->processRecord($row, $this->columnMap, $results, $preview);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $results;
|
return $results;
|
||||||
@ -100,8 +100,10 @@ class CsvBulkLoader extends BulkLoader {
|
|||||||
// second run: save data
|
// second run: save data
|
||||||
foreach($record as $fieldName => $val) {
|
foreach($record as $fieldName => $val) {
|
||||||
if($this->isNullValue($val, $fieldName)) continue;
|
if($this->isNullValue($val, $fieldName)) continue;
|
||||||
|
if(strpos($fieldName, '->') !== FALSE) {
|
||||||
if($obj->hasMethod("import{$fieldName}")) {
|
$funcName = substr($fieldName, 2);
|
||||||
|
$this->$funcName($obj, $val, $record);
|
||||||
|
} else if($obj->hasMethod("import{$fieldName}")) {
|
||||||
$obj->{"import{$fieldName}"}($val, $record);
|
$obj->{"import{$fieldName}"}($val, $record);
|
||||||
} else {
|
} else {
|
||||||
$obj->update(array($fieldName => $val));
|
$obj->update(array($fieldName => $val));
|
||||||
|
@ -75,7 +75,7 @@ class DevelopmentAdmin extends Controller {
|
|||||||
function build() {
|
function build() {
|
||||||
$renderer = new DebugView();
|
$renderer = new DebugView();
|
||||||
$renderer->writeHeader();
|
$renderer->writeHeader();
|
||||||
$renderer->writeInfo("Environment <i>re</i>Builder (formerly db/build)", Director::absoluteBaseURL());
|
$renderer->writeInfo("Environment Builder (formerly db/build)", Director::absoluteBaseURL());
|
||||||
echo "<div style=\"margin: 0 2em\">";
|
echo "<div style=\"margin: 0 2em\">";
|
||||||
|
|
||||||
$da = new DatabaseAdmin();
|
$da = new DatabaseAdmin();
|
||||||
|
@ -79,7 +79,6 @@ Behaviour.register({
|
|||||||
new Ajax.Request('{$url}?ajax=1&{$this->name}=' + encodeURIComponent(this.value), {
|
new Ajax.Request('{$url}?ajax=1&{$this->name}=' + encodeURIComponent(this.value), {
|
||||||
method: 'get',
|
method: 'get',
|
||||||
onSuccess: function(response) {
|
onSuccess: function(response) {
|
||||||
console.debug(this);
|
|
||||||
if(response.responseText == 'ok')
|
if(response.responseText == 'ok')
|
||||||
Element.removeClassName(this, 'inuse');
|
Element.removeClassName(this, 'inuse');
|
||||||
else {
|
else {
|
||||||
|
@ -130,6 +130,7 @@ TableListField.prototype = {
|
|||||||
var el = $(this.id);
|
var el = $(this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(el.getAttribute('href')) {
|
||||||
new Ajax.Request(
|
new Ajax.Request(
|
||||||
el.getAttribute('href'),
|
el.getAttribute('href'),
|
||||||
{
|
{
|
||||||
@ -140,6 +141,7 @@ TableListField.prototype = {
|
|||||||
}.bind(this)
|
}.bind(this)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if(e) Event.stop(e);
|
if(e) Event.stop(e);
|
||||||
return false;
|
return false;
|
||||||
|
@ -22,18 +22,24 @@
|
|||||||
|
|
||||||
|
|
||||||
// Added by SRM: Initialise the loaded_list with the scripts included on first load
|
// Added by SRM: Initialise the loaded_list with the scripts included on first load
|
||||||
initialiseJSLoadedList : function() {
|
initialiseItemLoadedList : function() {
|
||||||
if(this.loaded_list == null) {
|
if(this.loaded_list == null) {
|
||||||
$this = this;
|
$this = this;
|
||||||
$this.loaded_list = [];
|
$this.loaded_list = {};
|
||||||
$('script').each(function() {
|
$('script').each(function() {
|
||||||
if($(this).attr('src')) $this.loaded_list[ $(this).attr('src') ] = 1;
|
if($(this).attr('src')) $this.loaded_list[ $(this).attr('src') ] = 1;
|
||||||
});
|
});
|
||||||
|
$('link[@rel="stylesheet"]').each(function() {
|
||||||
|
if($(this).attr('href')) $this.loaded_list[ $(this).attr('href') ] = 1;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
isJsLoaded : function(scriptUrl) {
|
/**
|
||||||
this.initialiseJSLoadedList();
|
* Returns true if the given CSS or JS script has already been loaded
|
||||||
|
*/
|
||||||
|
isItemLoaded : function(scriptUrl) {
|
||||||
|
this.initialiseItemLoadedList();
|
||||||
return this.loaded_list[scriptUrl] != undefined;
|
return this.loaded_list[scriptUrl] != undefined;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -60,7 +66,7 @@
|
|||||||
|
|
||||||
this.pending = _request;
|
this.pending = _request;
|
||||||
|
|
||||||
this.initialiseJSLoadedList();
|
this.initialiseItemLoadedList();
|
||||||
|
|
||||||
if (this.loaded_list[this.pending.url] != undefined) { // if required file exists (by PGA)
|
if (this.loaded_list[this.pending.url] != undefined) { // if required file exists (by PGA)
|
||||||
this.requestComplete(); // => request complete
|
this.requestComplete(); // => request complete
|
||||||
@ -118,6 +124,9 @@
|
|||||||
requireCss : function(styleUrl, media){
|
requireCss : function(styleUrl, media){
|
||||||
if(media == null) media = 'all';
|
if(media == null) media = 'all';
|
||||||
|
|
||||||
|
// Don't double up on loading scripts
|
||||||
|
if(this.isItemLoaded(styleUrl)) return;
|
||||||
|
|
||||||
if(document.createStyleSheet){
|
if(document.createStyleSheet){
|
||||||
var ss = document.createStyleSheet($.requireConfig.routeCss + styleUrl);
|
var ss = document.createStyleSheet($.requireConfig.routeCss + styleUrl);
|
||||||
ss.media = media;
|
ss.media = media;
|
||||||
@ -130,9 +139,10 @@
|
|||||||
media : media,
|
media : media,
|
||||||
rel : 'stylesheet'
|
rel : 'stylesheet'
|
||||||
}).appendTo($('head').get(0));
|
}).appendTo($('head').get(0));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.loaded_list[styleUrl] = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
@ -148,7 +158,8 @@
|
|||||||
var _dataType = s.dataType;
|
var _dataType = s.dataType;
|
||||||
|
|
||||||
// This replaces the usual ajax success & complete handlers. They are called after any on demand JS is loaded.
|
// This replaces the usual ajax success & complete handlers. They are called after any on demand JS is loaded.
|
||||||
var _ondemandComplete = function(xml, status) {
|
var _ondemandComplete = function(xml) {
|
||||||
|
var status = jQuery.httpSuccess(xml) ? 'success' : 'error';
|
||||||
if(status == 'success') {
|
if(status == 'success') {
|
||||||
data = jQuery.httpData(xml, _dataType);
|
data = jQuery.httpData(xml, _dataType);
|
||||||
if(_success) _success(data, status, xml);
|
if(_success) _success(data, status, xml);
|
||||||
@ -159,7 +170,7 @@
|
|||||||
// We remove the success handler and take care of calling it outselves within _ondemandComplete
|
// We remove the success handler and take care of calling it outselves within _ondemandComplete
|
||||||
s.success = null;
|
s.success = null;
|
||||||
s.complete = function(xml, status) {
|
s.complete = function(xml, status) {
|
||||||
processOnDemandHeaders(xml);
|
processOnDemandHeaders(xml, _ondemandComplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
_originalAjax(s);
|
_originalAjax(s);
|
||||||
@ -172,14 +183,14 @@
|
|||||||
* once we get rid of all uses of prototype, we can remove this
|
* once we get rid of all uses of prototype, we can remove this
|
||||||
*/
|
*/
|
||||||
function prototypeOnDemandHandler(xml, callback) {
|
function prototypeOnDemandHandler(xml, callback) {
|
||||||
processOnDemandHandlers(xml, callback);
|
processOnDemandHeaders(xml, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the X-Include-CSS and X-Include-JS headers provided by the Requirements class
|
* Process the X-Include-CSS and X-Include-JS headers provided by the Requirements class
|
||||||
*/
|
*/
|
||||||
function processOnDemandHandlers(xml, _ondemandComplete) {
|
function processOnDemandHeaders(xml, _ondemandComplete) {
|
||||||
var i;
|
var i;
|
||||||
// CSS
|
// CSS
|
||||||
if(xml.getResponseHeader('X-Include-CSS')) {
|
if(xml.getResponseHeader('X-Include-CSS')) {
|
||||||
@ -201,7 +212,7 @@ function processOnDemandHandlers(xml, _ondemandComplete) {
|
|||||||
if(xml.getResponseHeader('X-Include-JS')) {
|
if(xml.getResponseHeader('X-Include-JS')) {
|
||||||
var jsIncludes = xml.getResponseHeader('X-Include-JS').split(',');
|
var jsIncludes = xml.getResponseHeader('X-Include-JS').split(',');
|
||||||
for(i=0;i<jsIncludes.length;i++) {
|
for(i=0;i<jsIncludes.length;i++) {
|
||||||
if(!jQuery.isJsLoaded(jsIncludes[i])) {
|
if(!jQuery.isItemLoaded(jsIncludes[i])) {
|
||||||
newIncludes.push(jsIncludes[i]);
|
newIncludes.push(jsIncludes[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,7 +223,7 @@ function processOnDemandHandlers(xml, _ondemandComplete) {
|
|||||||
// be able to execute script in the new includes (such as a livequery update)
|
// be able to execute script in the new includes (such as a livequery update)
|
||||||
if(newIncludes.length > 0) {
|
if(newIncludes.length > 0) {
|
||||||
for(i=0;i<jsIncludes.length;i++) {
|
for(i=0;i<jsIncludes.length;i++) {
|
||||||
jQuery.requireJs(jsIncludes[i], (i == jsIncludes.length-1) ? function() { _ondemandComplete(xml, status); } : null);
|
jQuery.requireJs(jsIncludes[i], (i == jsIncludes.length-1) ? function() { _ondemandComplete(xml); } : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there aren't any new includes, then we can just call the callbacks ourselves
|
// If there aren't any new includes, then we can just call the callbacks ourselves
|
||||||
|
7
main.php
7
main.php
@ -78,6 +78,13 @@ if (isset($_GET['debug_profile'])) {
|
|||||||
// Connect to database
|
// Connect to database
|
||||||
require_once("core/model/DB.php");
|
require_once("core/model/DB.php");
|
||||||
|
|
||||||
|
// Redirect to the installer if no database is selected
|
||||||
|
if(!isset($databaseConfig) || !isset($databaseConfig['database']) || !$databaseConfig['database']) {
|
||||||
|
$installURL = dirname(dirname($_SERVER['SCRIPT_NAME'])) . '/install.php';
|
||||||
|
header("Location: $installURL");
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($_GET['debug_profile'])) Profiler::mark('DB::connect');
|
if (isset($_GET['debug_profile'])) Profiler::mark('DB::connect');
|
||||||
DB::connect($databaseConfig);
|
DB::connect($databaseConfig);
|
||||||
if (isset($_GET['debug_profile'])) Profiler::unmark('DB::connect');
|
if (isset($_GET['debug_profile'])) Profiler::unmark('DB::connect');
|
||||||
|
@ -30,7 +30,7 @@ class Member extends DataObject {
|
|||||||
);
|
);
|
||||||
|
|
||||||
static $has_one = array();
|
static $has_one = array();
|
||||||
|
static $has_many = array();
|
||||||
static $many_many = array();
|
static $many_many = array();
|
||||||
|
|
||||||
static $many_many_extraFields = array();
|
static $many_many_extraFields = array();
|
||||||
|
@ -119,6 +119,7 @@ class MemberLoginForm extends LoginForm {
|
|||||||
Session::clear("BackURL");
|
Session::clear("BackURL");
|
||||||
Director::redirect($backURL);
|
Director::redirect($backURL);
|
||||||
} else {
|
} else {
|
||||||
|
$member=Member::CurrentUser();
|
||||||
$firstname = Convert::raw2xml($member->FirstName);
|
$firstname = Convert::raw2xml($member->FirstName);
|
||||||
Session::set("Security.Message.message",
|
Session::set("Security.Message.message",
|
||||||
sprintf(_t('Member.WELCOMEBACK', "Welcome Back, %s"), $firstname)
|
sprintf(_t('Member.WELCOMEBACK', "Welcome Back, %s"), $firstname)
|
||||||
|
@ -315,6 +315,11 @@ class Security extends Controller {
|
|||||||
// with the tabstrip library otherwise
|
// with the tabstrip library otherwise
|
||||||
$link_base = Director::absoluteURL($this->Link("login"));
|
$link_base = Director::absoluteURL($this->Link("login"));
|
||||||
|
|
||||||
|
Requirements::javascript(THIRDPARTY_DIR . "/jquery/jquery.js");
|
||||||
|
Requirements::javascript(THIRDPARTY_DIR . '/jquery/plugins/livequery/jquery.livequery.js');
|
||||||
|
Requirements::javascript(THIRDPARTY_DIR . "/tabstrip/tabstrip.js");
|
||||||
|
Requirements::css(THIRDPARTY_DIR . "/tabstrip/tabstrip.css");
|
||||||
|
|
||||||
$content = '<div id="Form_EditForm">';
|
$content = '<div id="Form_EditForm">';
|
||||||
$content .= '<ul class="tabstrip">';
|
$content .= '<ul class="tabstrip">';
|
||||||
$content_forms = '';
|
$content_forms = '';
|
||||||
|
@ -31,8 +31,8 @@ class UpgradeSiteTreePermissionSchemaTask extends BuildTask {
|
|||||||
$pageIDs = DB::query("SELECT ID FROM SiteTree")->column('ID');
|
$pageIDs = DB::query("SELECT ID FROM SiteTree")->column('ID');
|
||||||
foreach($pageIDs as $pageID) {
|
foreach($pageIDs as $pageID) {
|
||||||
$page = DataObject::get_by_id('SiteTree', $pageID);
|
$page = DataObject::get_by_id('SiteTree', $pageID);
|
||||||
if($page->ViewersGroup) $page->ViewerGroups()->add($page->ViewersGroup);
|
if($page->ViewersGroup && DataObject::get_by_id("Group", $page->ViewersGroup)) $page->ViewerGroups()->add($page->ViewersGroup);
|
||||||
if($page->EditorsGroup) $page->EditorGroups()->add($page->EditorsGroup);
|
if($page->EditorsGroup && DataObject::get_by_id("Group", $page->EditorsGroup)) $page->EditorGroups()->add($page->EditorsGroup);
|
||||||
|
|
||||||
$page->destroy();
|
$page->destroy();
|
||||||
unset($page);
|
unset($page);
|
||||||
|
@ -136,6 +136,20 @@ class CsvBulkLoaderTest extends SapphireTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testLoadWithCustomImportMethods() {
|
||||||
|
$loader = new CsvBulkLoaderTest_CustomLoader('CsvBulkLoaderTest_Player');
|
||||||
|
$filepath = Director::baseFolder() . '/sapphire/tests/dev/CsvBulkLoaderTest_PlayersWithHeader.csv';
|
||||||
|
$loader->columnMap = array(
|
||||||
|
'FirstName' => '->importFirstName',
|
||||||
|
'Biography' => 'Biography',
|
||||||
|
'Birthday' => 'Birthday'
|
||||||
|
);
|
||||||
|
$results = $loader->load($filepath);
|
||||||
|
$player = DataObject::get_by_id('CsvBulkLoaderTest_Player', 1);
|
||||||
|
$this->assertEquals($player->FirstName, 'Customized John');
|
||||||
|
$this->assertEquals($player->Biography, "He's a good guy");
|
||||||
|
}
|
||||||
|
|
||||||
protected function getLineCount(&$file) {
|
protected function getLineCount(&$file) {
|
||||||
$i = 0;
|
$i = 0;
|
||||||
while(fgets($file) !== false) $i++;
|
while(fgets($file) !== false) $i++;
|
||||||
@ -145,6 +159,12 @@ class CsvBulkLoaderTest extends SapphireTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CsvBulkLoaderTest_CustomLoader extends CsvBulkLoader implements TestOnly {
|
||||||
|
function importFirstName(&$obj, $val, $record) {
|
||||||
|
$obj->FirstName = "Customized {$val}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class CsvBulkLoaderTest_Team extends DataObject implements TestOnly {
|
class CsvBulkLoaderTest_Team extends DataObject implements TestOnly {
|
||||||
|
|
||||||
static $db = array(
|
static $db = array(
|
||||||
@ -184,7 +204,7 @@ class CsvBulkLoaderTest_Player extends DataObject implements TestOnly {
|
|||||||
* @param string $val
|
* @param string $val
|
||||||
* @param array $record
|
* @param array $record
|
||||||
*/
|
*/
|
||||||
public function setUSBirthday($val, $record) {
|
public function setUSBirthday($val, $record = null) {
|
||||||
$this->Birthday = preg_replace('/^([0-9]{1,2})\/([0-9]{1,2})\/([0-90-9]{2,4})/', '\\3-\\1-\\2', $val);
|
$this->Birthday = preg_replace('/^([0-9]{1,2})\/([0-9]{1,2})\/([0-90-9]{2,4})/', '\\3-\\1-\\2', $val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user