MINOR merged from branches/2.3

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@69856 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2009-01-07 23:00:54 +00:00
parent d32d4d5204
commit 0747fc6d52
23 changed files with 267 additions and 59 deletions

View File

@ -60,21 +60,6 @@ set_include_path(get_include_path() . PATH_SEPARATOR . $path);
*/ */
define('MCE_ROOT', 'jsparty/tiny_mce2/'); define('MCE_ROOT', 'jsparty/tiny_mce2/');
/**
* Should passwords be encrypted (TRUE) or stored in clear text (FALSE)?
*/
Security::encrypt_passwords(true);
/**
* Which algorithm should be used to encrypt? Should a salt be used to
* increase the security?
*
* You can get a list of supported algorithms by calling
* {@link Security::get_encryption_algorithms()}
*/
Security::set_password_encryption_algorithm('sha1', true);
/** /**
* The secret key that needs to be sent along with pings to /Email_BounceHandler * The secret key that needs to be sent along with pings to /Email_BounceHandler
* *

View File

@ -73,15 +73,12 @@ class HTTP {
return $content; return $content;
} }
static function setGetVar($varname, $varvalue, $currentURL = null) { public static function setGetVar($varname, $varvalue, $currentURL = null) {
$currentURL = $currentURL ? $currentURL : $_SERVER['REQUEST_URI']; $scriptbase = $currentURL ? $currentURL : $_SERVER['REQUEST_URI'];
$scriptbase = $currentURL; $scriptbase = str_replace('&', '&', $scriptbase);
$scriptbase = str_replace('&','&',$scriptbase); $scriptbase = preg_replace('/\?' . quotemeta($varname) . '=([^&]*)&/', '?', $scriptbase);
$scriptbase = preg_replace('/([\?&]+)' . quotemeta($varname) . '=([^&]*)/', null, $scriptbase);
$scriptbase = ereg_replace("&$varname=[^&]*",'',$scriptbase);
$scriptbase = ereg_replace("\?$varname=[^&]*&",'?',$scriptbase);
$scriptbase = ereg_replace("\?$varname=[^&]*",'',$scriptbase);
$suffix = ''; $suffix = '';
if(($hashPos = strpos($scriptbase,'#')) !== false) { if(($hashPos = strpos($scriptbase,'#')) !== false) {
@ -136,7 +133,7 @@ class HTTP {
* Outputs appropriate header for downloading a file * Outputs appropriate header for downloading a file
* exits() after the call, so that no further output is given. * exits() after the call, so that no further output is given.
* *
* @deprecated 2.3 Return a HTTPResponse::send_file() object instead * @deprecated 2.3 Return a HTTPRequest::send_file() object instead
*/ */
static function sendFileToBrowser($fileData, $fileName, $mimeType = false) { static function sendFileToBrowser($fileData, $fileName, $mimeType = false) {
user_error("HTTP::sendFileToBrowser() deprecated; return a HTTPRequest::send_file() object instead", E_USER_NOTICE); user_error("HTTP::sendFileToBrowser() deprecated; return a HTTPRequest::send_file() object instead", E_USER_NOTICE);

View File

@ -52,7 +52,7 @@ class Director {
* page. * page.
*/ */
static function history($pagesBack = 1) { static function history($pagesBack = 1) {
return Session::get('history.' . sizeof(Session::get('history')) - $pagesBack - 1); return Session::get('history.' . intval(sizeof(Session::get('history')) - $pagesBack - 1));
} }
@ -159,6 +159,7 @@ class Director {
if(!$httpMethod) $httpMethod = ($postVars || is_array($postVars)) ? "POST" : "GET"; if(!$httpMethod) $httpMethod = ($postVars || is_array($postVars)) ? "POST" : "GET";
$urlWithQuerystring = $url;
if(strpos($url, '?') !== false) { if(strpos($url, '?') !== false) {
list($url, $getVarsEncoded) = explode('?', $url, 2); list($url, $getVarsEncoded) = explode('?', $url, 2);
parse_str($getVarsEncoded, $getVars); parse_str($getVarsEncoded, $getVars);
@ -172,11 +173,11 @@ class Director {
$existingPostVars = $_POST; $existingPostVars = $_POST;
$existingSessionVars = $_SESSION; $existingSessionVars = $_SESSION;
$existingCookies = $_COOKIE; $existingCookies = $_COOKIE;
$existingServer = $_SERVER;
$existingCookieReportErrors = Cookie::report_errors(); $existingCookieReportErrors = Cookie::report_errors();
Cookie::set_report_errors(false);
$existingRequirementsBackend = Requirements::backend(); $existingRequirementsBackend = Requirements::backend();
Cookie::set_report_errors(false);
Requirements::set_backend(new Requirements_Backend()); Requirements::set_backend(new Requirements_Backend());
// Replace the superglobals with appropriate test values // Replace the superglobals with appropriate test values
@ -185,6 +186,7 @@ class Director {
$_POST = (array)$postVars; $_POST = (array)$postVars;
$_SESSION = $session ? $session->inst_getAll() : array(); $_SESSION = $session ? $session->inst_getAll() : array();
$_COOKIE = array(); $_COOKIE = array();
$_SERVER['REQUEST_URI'] = Director::baseURL() . $urlWithQuerystring;
$req = new HTTPRequest($httpMethod, $url, $getVars, $postVars, $body); $req = new HTTPRequest($httpMethod, $url, $getVars, $postVars, $body);
if($headers) foreach($headers as $k => $v) $req->addHeader($k, $v); if($headers) foreach($headers as $k => $v) $req->addHeader($k, $v);
@ -196,6 +198,8 @@ class Director {
$_POST = $existingPostVars; $_POST = $existingPostVars;
$_SESSION = $existingSessionVars; $_SESSION = $existingSessionVars;
$_COOKIE = $existingCookies; $_COOKIE = $existingCookies;
$_SERVER = $existingServer;
Cookie::set_report_errors($existingCookieReportErrors); Cookie::set_report_errors($existingCookieReportErrors);
Requirements::set_backend($existingRequirementsBackend); Requirements::set_backend($existingRequirementsBackend);

View File

@ -45,6 +45,13 @@ class DB {
$_SESSION["alternativeDatabaseName"] = $dbname; $_SESSION["alternativeDatabaseName"] = $dbname;
} }
/**
* Get the name of the database in use
*/
static function get_alternative_database_name() {
return $_SESSION["alternativeDatabaseName"];
}
/** /**
* Connect to a database. * Connect to a database.
* Given the database configuration, this method will create the correct subclass of Database, * Given the database configuration, this method will create the correct subclass of Database,

View File

@ -126,8 +126,8 @@ class MySQLDatabase extends Database {
} }
public function createDatabase() { public function createDatabase() {
$this->query("CREATE DATABASE $this->database"); $this->query("CREATE DATABASE `$this->database`");
$this->query("USE $this->database"); $this->query("USE `$this->database`");
$this->tableList = $this->fieldList = $this->indexList = null; $this->tableList = $this->fieldList = $this->indexList = null;

View File

@ -107,7 +107,7 @@
<label for="mysql_password">MySQL password:</label> <label for="mysql_password">MySQL password:</label>
<span class="middleColumn"><input id="mysql_password" class="text" type="password" name="mysql[password]" value="<?php echo $databaseConfig['password']; ?>" /></span> <span class="middleColumn"><input id="mysql_password" class="text" type="password" name="mysql[password]" value="<?php echo $databaseConfig['password']; ?>" /></span>
<label for="mysql_database">MySQL database:</label> <label for="mysql_database">MySQL database:</label>
<span class="middleColumn"><input id="mysql_database" class="text" type="text" name="mysql[database]" value="<?php echo $databaseConfig['database']; ?>" onchange="this.value = this.value.replace(/[^A-Za-z0-9_]+/g,'');" /></span> <span class="middleColumn"><input id="mysql_database" class="text" type="text" name="mysql[database]" value="<?php echo $databaseConfig['database']; ?>" onchange="this.value = this.value.replace(/[\/\\:*?&quot;<>|. \t]+/g,'');" /></span>
<input type="submit" class="action" value="Re-check requirements" /> <input type="submit" class="action" value="Re-check requirements" />
</p> </p>
<p class="mysql">SilverStripe stores its content in a MySQL database. Please provide the username and password to connect to the server here. If this account has permission to create databases, then we will create the database for you; otherwise, you must give the name of a database that already exists.</p> <p class="mysql">SilverStripe stores its content in a MySQL database. Please provide the username and password to connect to the server here. If this account has permission to create databases, then we will create the database for you; otherwise, you must give the name of a database that already exists.</p>

View File

@ -18,6 +18,13 @@
* If you want to process the submitted data in any way, please use {@link getData()} rather than * If you want to process the submitted data in any way, please use {@link getData()} rather than
* the raw request data. * the raw request data.
* *
* Validation
* Each form needs some form of {@link Validator} to trigger the {@link FormField->validate()} methods for each field.
* You can't disable validator for security reasons, because crucial behaviour like extension checks for file uploads depend on it.
* The default validator is an instance of {@link RequiredFields}.
* If you want to enforce serverside-validation to be ignored for a specific {@link FormField},
* you need to subclass it.
*
* @package forms * @package forms
* @subpackage core * @subpackage core
*/ */
@ -96,10 +103,11 @@ class Form extends RequestHandler {
/** /**
* Create a new form, with the given fields an action buttons. * Create a new form, with the given fields an action buttons.
* *
* @param controller The parent controller, necessary to create the appropriate form action tag. * @param Controller $controller The parent controller, necessary to create the appropriate form action tag.
* @param name The method on the controller that will return this form object. * @param String $name The method on the controller that will return this form object.
* @param fields All of the fields in the form - a {@link FieldSet} of {@link FormField} objects. * @param FieldSet $fields All of the fields in the form - a {@link FieldSet} of {@link FormField} objects.
* @param actions All of the action buttons in the form - a {@link FieldSet} of {@link FormAction} objects * @param FieldSet $actions All of the action buttons in the form - a {@link FieldSet} of {@link FormAction} objects
* @param Validator $validator Override the default validator instance (Default: {@link RequiredFields})
*/ */
function __construct($controller, $name, FieldSet $fields, FieldSet $actions, $validator = null) { function __construct($controller, $name, FieldSet $fields, FieldSet $actions, $validator = null) {
parent::__construct(); parent::__construct();
@ -115,10 +123,8 @@ class Form extends RequestHandler {
if(!$this->controller) user_error("$this->class form created without a controller", E_USER_ERROR); if(!$this->controller) user_error("$this->class form created without a controller", E_USER_ERROR);
// Form validation // Form validation
if($validator) { $this->validator = ($validator) ? $validator : new RequiredFields();
$this->validator = $validator; $this->validator->setForm($this);
$this->validator->setForm($this);
}
// Form error controls // Form error controls
$errorInfo = Session::get("FormInfo.{$this->FormName()}"); $errorInfo = Session::get("FormInfo.{$this->FormName()}");

View File

@ -32,6 +32,7 @@ class HasManyComplexTableField extends ComplexTableField {
if($controllerClass = $this->controllerClass()) { if($controllerClass = $this->controllerClass()) {
$this->joinField = $this->getParentIdName($controllerClass, $this->sourceClass); $this->joinField = $this->getParentIdName($controllerClass, $this->sourceClass);
if(!$this->joinField) user_error("Can't find a has_one relationship from '$this->sourceClass' to '$controllerClass'", E_USER_WARNING);
} else { } else {
user_error("Can't figure out the data class of $controller", E_USER_WARNING); user_error("Can't figure out the data class of $controller", E_USER_WARNING);
} }
@ -148,6 +149,11 @@ class HasManyComplexTableField_Item extends ComplexTableField_Item {
function MarkingCheckbox() { function MarkingCheckbox() {
$name = $this->parent->Name() . '[]'; $name = $this->parent->Name() . '[]';
if(!$this->parent->joinField) {
user_error("joinField not set in HasManyComplexTableField '{$this->parent->name}'", E_USER_WARNING);
return null;
}
$joinVal = $this->item->{$this->parent->joinField}; $joinVal = $this->item->{$this->parent->joinField};
$parentID = $this->parent->getControllerID(); $parentID = $this->parent->getControllerID();

View File

@ -18,7 +18,9 @@ class HeaderField extends DatalessField {
$args = func_get_args(); $args = func_get_args();
if(!isset($args[1]) || is_numeric($args[1])) { if(!isset($args[1]) || is_numeric($args[1])) {
$title = (isset($args[0])) ? $args[0] : null; $title = (isset($args[0])) ? $args[0] : null;
$name = $title; // this means i18nized fields won't be easily accessible through fieldByName() // Use "HeaderField(title)" as the default field name for a HeaderField; if it's just set to title then we risk
// causing accidental duplicate-field creation.
$name = 'HeaderField' . $title; // this means i18nized fields won't be easily accessible through fieldByName()
$headingLevel = (isset($args[1])) ? $args[1] : null; $headingLevel = (isset($args[1])) ? $args[1] : null;
$allowHTML = (isset($args[2])) ? $args[2] : null; $allowHTML = (isset($args[2])) ? $args[2] : null;
$form = (isset($args[3])) ? $args[3] : null; $form = (isset($args[3])) ? $args[3] : null;

View File

@ -423,6 +423,7 @@ class HtmlEditorField_Toolbar extends RequestHandler {
new TextField('getimagesSearch', _t('HtmlEditorField.SEARCHFILENAME', 'Search by file name')), new TextField('getimagesSearch', _t('HtmlEditorField.SEARCHFILENAME', 'Search by file name')),
new ThumbnailStripField('Image', 'FolderID', 'getimages'), new ThumbnailStripField('Image', 'FolderID', 'getimages'),
new TextField('AltText', _t('HtmlEditorField.ALTTEXT', 'Description'), '', 80), new TextField('AltText', _t('HtmlEditorField.ALTTEXT', 'Description'), '', 80),
new CheckboxField('Caption', _t('HtmlEditorField.CAPTION', 'Include as Caption')),
new HiddenField('CSSClass', _t('HtmlEditorField.CSSCLASS', 'Alignment / style')), new HiddenField('CSSClass', _t('HtmlEditorField.CSSCLASS', 'Alignment / style')),
new LiteralField('AlignmentStyle', '<div id="ImageAligmentStyle" class="field text"><label>Alignment / style</label>'), new LiteralField('AlignmentStyle', '<div id="ImageAligmentStyle" class="field text"><label>Alignment / style</label>'),
new LiteralField('AlignmentStyleLinks', ' new LiteralField('AlignmentStyleLinks', '

View File

@ -40,7 +40,7 @@ class TreeDropdownField extends FormField {
Requirements::javascript(SAPPHIRE_DIR . "/javascript/TreeSelectorField.js"); Requirements::javascript(SAPPHIRE_DIR . "/javascript/TreeSelectorField.js");
if($this->value) { if($this->value) {
$record = DataObject::get_by_id($this->sourceObject, $this->value); $record = $this->getByKey($this->value);
$title = ($record) ? $record->Title : _t('DropdownField.CHOOSE', "(Choose)", PR_MEDIUM, 'Start-value of a dropdown'); $title = ($record) ? $record->Title : _t('DropdownField.CHOOSE', "(Choose)", PR_MEDIUM, 'Start-value of a dropdown');
} else { } else {
$title = _t('DropdownField.CHOOSE', "(Choose)", PR_MEDIUM, 'Start-value of a dropdown'); $title = _t('DropdownField.CHOOSE', "(Choose)", PR_MEDIUM, 'Start-value of a dropdown');
@ -65,7 +65,6 @@ HTML;
if($this->treeBaseID) $obj = DataObject::get_by_id($this->sourceObject, $this->treeBaseID); if($this->treeBaseID) $obj = DataObject::get_by_id($this->sourceObject, $this->treeBaseID);
else $obj = singleton($this->sourceObject); else $obj = singleton($this->sourceObject);
if($this->filterFunc) $obj->setMarkingFilterFunction($this->filterFunc); if($this->filterFunc) $obj->setMarkingFilterFunction($this->filterFunc);
else if($this->sourceObject == 'Folder') $obj->setMarkingFilter('ClassName', 'Folder'); else if($this->sourceObject == 'Folder') $obj->setMarkingFilter('ClassName', 'Folder');
$obj->markPartialTree(); $obj->markPartialTree();
@ -86,11 +85,12 @@ HTML;
* Return a subtree via Ajax * Return a subtree via Ajax
*/ */
public function getsubtree() { public function getsubtree() {
if($this->keyField == "ID") $obj = DataObject::get_by_id($this->sourceObject, $_REQUEST['SubtreeRootID']); $obj = $this->getByKey($_REQUEST['SubtreeRootID']);
else $obj = DataObject::get_one($this->sourceObject, "\"$this->keyField\" = '$_REQUEST[SubtreeRootID]'");
if(!$obj) user_error("Can't find database record $this->sourceObject with $this->keyField = $_REQUEST[SubtreeRootID]", E_USER_ERROR); if(!$obj) user_error("Can't find database record $this->sourceObject with $this->keyField = $_REQUEST[SubtreeRootID]", E_USER_ERROR);
if($this->filterFunc) $obj->setMarkingFilterFunction($this->filterFunc); if($this->filterFunc) $obj->setMarkingFilterFunction($this->filterFunc);
else if($this->sourceObject == 'Folder') $obj->setMarkingFilter('ClassName', 'Folder');
$obj->markPartialTree(); $obj->markPartialTree();
$eval = '"<li id=\"selector-' . $this->name . '-$child->' . $this->keyField . '\" class=\"$child->class" . $child->markingClasses() . "\"><a>" . $child->' . $this->labelField . ' . "</a>"'; $eval = '"<li id=\"selector-' . $this->name . '-$child->' . $this->keyField . '\" class=\"$child->class" . $child->markingClasses() . "\"><a>" . $child->' . $this->labelField . ' . "</a>"';
@ -99,14 +99,11 @@ HTML;
} }
public function getByKey($key) { public function getByKey($key) {
if(!is_numeric($key)) {
return false;
}
if($this->keyField == 'ID') { if($this->keyField == 'ID') {
return DataObject::get_by_id($this->sourceObject, $key); return DataObject::get_by_id($this->sourceObject, $key);
} else { } else {
return DataObject::get_one($this->sourceObject, "\"$this->keyField\" = '$key'"); $SQL_key = Convert::raw2sql($key);
return DataObject::get_one($this->sourceObject, "\"$this->keyField\" = '$SQL_key'");
} }
} }
@ -114,8 +111,7 @@ HTML;
* Return the stack of values to be traversed to find the given key in the database * Return the stack of values to be traversed to find the given key in the database
*/ */
public function getstack() { public function getstack() {
if($this->keyField == "ID") $page = DataObject::get_by_id($this->sourceObject, $_REQUEST['SubtreeRootID']); $page = $this->getByKey($_REQUEST['SubtreeRootID']);
else $page = $this->getByKey($_REQUEST['SubtreeRootID']);
while($page->ParentID) { while($page->ParentID) {
echo $ids[] = $page->ID; echo $ids[] = $page->ID;

View File

@ -54,7 +54,7 @@ abstract class Validator extends Object {
public function __construct() { public function __construct() {
if(self::$javascript_validation_handler) $this->setJavascriptValidationHandler(self::$javascript_validation_handler); if(self::$javascript_validation_handler) $this->setJavascriptValidationHandler(self::$javascript_validation_handler);
if($this->javascriptValidationHandler) { if($this->javascriptValidationHandler && $this->javascriptValidationHandler != 'none') {
Requirements::javascript(SAPPHIRE_DIR . '/javascript/Validator.js'); Requirements::javascript(SAPPHIRE_DIR . '/javascript/Validator.js');
} }
parent::__construct(); parent::__construct();

BIN
images/smilies/confused.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 700 B

BIN
images/smilies/cool.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 703 B

BIN
images/smilies/grin.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 B

BIN
images/smilies/sad.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 B

BIN
images/smilies/smile.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 699 B

BIN
images/smilies/tongue.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 706 B

View File

@ -16,8 +16,32 @@ unset($options);
*/ */
class BBCodeParser extends TextParser { class BBCodeParser extends TextParser {
/**
* Set whether phrases starting with http:// or www. are automatically linked
* @var Boolean
*/
protected static $autolinkUrls = true; protected static $autolinkUrls = true;
/**
* Set whether similies :), :(, :P are converted to images
* @var Boolean
*/
protected static $allowSimilies = false;
/**
* Set the location of the smiles folder. By default use the ones in sapphire
* but this can be overridden by setting BBCodeParser::set_icon_folder('themes/yourtheme/images/');
* @var string
*/
protected static $smilies_location = 'sapphire/images/smilies';
static function smilies_location() {
return BBCodeParser::$smilies_location;
}
static function set_icon_folder($path) {
BBCodeParser::$smilies_location = $path;
}
static function autolinkUrls() { static function autolinkUrls() {
return (self::$autolinkUrls != null) ? true : false; return (self::$autolinkUrls != null) ? true : false;
} }
@ -26,6 +50,15 @@ class BBCodeParser extends TextParser {
BBCodeParser::$autolinkUrls = $autolink; BBCodeParser::$autolinkUrls = $autolink;
} }
static function smiliesAllowed() {
return (self::$allowSimilies != null) ? true : false;
}
static function enable_smilies() {
BBCodeParser::$allowSimilies = true;
}
static function usable_tags() { static function usable_tags() {
return new DataObjectSet( return new DataObjectSet(
new ArrayData(array( new ArrayData(array(
@ -98,6 +131,12 @@ class BBCodeParser extends TextParser {
return $useabletags."</ul>"; return $useabletags."</ul>";
} }
/**
* Main BBCode parser method. This takes plain jane content and
* runs it through so many filters
*
* @return Text
*/
function parse() { function parse() {
$this->content = str_replace(array('&', '<', '>'), array('&amp;', '&lt;', '&gt;'), $this->content); $this->content = str_replace(array('&', '<', '>'), array('&amp;', '&lt;', '&gt;'), $this->content);
$this->content = SSHTMLBBCodeParser::staticQparse($this->content); $this->content = SSHTMLBBCodeParser::staticQparse($this->content);
@ -108,6 +147,20 @@ class BBCodeParser extends TextParser {
$this->content = preg_replace("/\n\s*\n/", "</p><p>", $this->content); $this->content = preg_replace("/\n\s*\n/", "</p><p>", $this->content);
$this->content = str_replace("\n", "<br />", $this->content); $this->content = str_replace("\n", "<br />", $this->content);
if(BBCodeParser::smiliesAllowed()) {
$smilies = array(
'#(?<!\w):D(?!\w)#i' => " <img src='".BBCodeParser::smilies_location(). "/grin.gif'> ", // :D
'#(?<!\w):\)(?!\w)#i' => " <img src='".BBCodeParser::smilies_location(). "/smile.gif'> ", // :)
'#(?<!\w):-\)(?!\w)#i' => " <img src='".BBCodeParser::smilies_location(). "/smile.gif'> ", // :-)
'#(?<!\w):\((?!\w)#i' => " <img src='".BBCodeParser::smilies_location(). "/sad.gif'> ", // :(
'#(?<!\w):-\((?!\w)#i' => " <img src='".BBCodeParser::smilies_location(). "/sad.gif'> ", // :-(
'#(?<!\w):p(?!\w)#i' => " <img src='".BBCodeParser::smilies_location(). "/tongue.gif'> ", // :p
'#(?<!\w)8-\)(?!\w)#i' => " <img src='".BBCodeParser::smilies_location(). "/cool.gif'> ", // 8-)
'#(?<!\w):\^\)(?!\w)#i' => " <img src='".BBCodeParser::smilies_location(). "/confused.gif'> " // :^)
);
$this->content = preg_replace(array_keys($smilies), array_values($smilies), $this->content);
}
return $this->content; return $this->content;
} }

View File

@ -933,11 +933,13 @@ class Security extends Controller {
* @return bool * @return bool
*/ */
public static function database_is_ready() { public static function database_is_ready() {
return $requiredTables = ClassInfo::dataClassesFor('Member');
ClassInfo::hasTable('Member') && $requiredTables[] = 'Group';
ClassInfo::hasTable('Group') && $requiredTables[] = 'Permission';
ClassInfo::hasTable('Permission') &&
(($permissionFields = DB::fieldList('Permission')) && isset($permissionFields['Type'])) && foreach($requiredTables as $table) if(!ClassInfo::hasTable($table)) return false;
return (($permissionFields = DB::fieldList('Permission')) && isset($permissionFields['Type'])) &&
(($memberFields = DB::fieldList('Member')) && isset($memberFields['RememberLoginToken'])); (($memberFields = DB::fieldList('Member')) && isset($memberFields['RememberLoginToken']));
} }

29
tests/HTTPTest.php Normal file
View File

@ -0,0 +1,29 @@
<?php
/**
* Tests the {@link HTTP} class
*
* @package sapphire
* @subpackage tests
*/
class HTTPTest extends SapphireTest {
/**
* Tests {@link HTTP::setGetVar()}
*/
public function testSetGetVar() {
$expected = array (
'/?foo=bar' => array('foo', 'bar', '/'),
'/?baz=buz&foo=bar' => array('foo', 'bar', '/?baz=buz'),
'/?buz=baz&foo=baz' => array('foo', 'baz', '/?foo=bar&buz=baz'),
'/?foo=var' => array('foo', 'var', '/?foo=&foo=bar'),
'/?foo[test]=var' => array('foo[test]', 'var', '/?foo[test]=another')
);
foreach($expected as $result => $args) {
$this->assertEquals(
call_user_func_array(array('HTTP', 'setGetVar'), $args), str_replace('&', '&amp;', $result)
);
}
}
}

View File

@ -0,0 +1,109 @@
<?php
/**
* Possible actions:
* - action_save
* - action_publish
* - action_unpublish
* - action_delete
* - action_deletefromlive
* - action_rollback
* - action_revert
*
* @package sapphire
* @subpackage tests
*/
if(class_exists('SiteTreeCMSWorkflow')) {
class SiteTreeActionsTest extends FunctionalTest {
function testDummy() {}
}
} else {
class SiteTreeActionsTest extends FunctionalTest {
static $fixture_file = 'sapphire/tests/SiteTreeActionsTest.yml';
function testActionsNewPage() {
$className = 'Page';
$page = new $className();
$page->Title = 'New ' . $className;
$page->URLSegment = "new-" . strtolower($className);
$page->ClassName = $className;
$page->ParentID = 0;
$page->ID = 'new-Page-1';
$author = $this->objFromFixture('Member', 'cmseditor');
$this->session()->inst_set('loggedInAs', $author->ID);
$actionsArr = $page->getCMSActions()->column('Name');
$this->assertContains('action_save',$actionsArr);
$this->assertContains('action_publish',$actionsArr);
$this->assertNotContains('action_unpublish',$actionsArr);
$this->assertContains('action_delete',$actionsArr);
$this->assertNotContains('action_deletefromlive',$actionsArr);
$this->assertNotContains('action_rollback',$actionsArr);
$this->assertNotContains('action_revert',$actionsArr);
}
function testActionsPublishedRecord() {
$page = new Page();
$page->write();
$page->publish('Stage', 'Live');
$author = $this->objFromFixture('Member', 'cmseditor');
$this->session()->inst_set('loggedInAs', $author->ID);
$actionsArr = $page->getCMSActions()->column('Name');
$this->assertContains('action_save',$actionsArr);
$this->assertContains('action_publish',$actionsArr);
$this->assertContains('action_unpublish',$actionsArr);
$this->assertContains('action_delete',$actionsArr);
$this->assertNotContains('action_deletefromlive',$actionsArr);
$this->assertNotContains('action_rollback',$actionsArr);
$this->assertNotContains('action_revert',$actionsArr);
}
function testActionsDeletedFromStageRecord() {
$page = new Page();
$page->write();
$page->publish('Stage', 'Live');
$page->deleteFromStage('Stage');
$author = $this->objFromFixture('Member', 'cmseditor');
$this->session()->inst_set('loggedInAs', $author->ID);
$actionsArr = $page->getCMSActions()->column('Name');
$this->assertNotContains('action_save',$actionsArr);
$this->assertNotContains('action_publish',$actionsArr);
$this->assertNotContains('action_unpublish',$actionsArr);
$this->assertNotContains('action_delete',$actionsArr);
$this->assertContains('action_deletefromlive',$actionsArr);
$this->assertNotContains('action_rollback',$actionsArr);
$this->assertContains('action_revert',$actionsArr);
}
function testActionsChangedOnStageRecord() {
$page = new Page();
$page->write();
$page->publish('Stage', 'Live');
$page->Content = 'Changed on Stage';
$page->write();
$page->flushCache();
$author = $this->objFromFixture('Member', 'cmseditor');
$this->session()->inst_set('loggedInAs', $author->ID);
$actionsArr = $page->getCMSActions()->column('Name');
$this->assertContains('action_save',$actionsArr);
$this->assertContains('action_publish',$actionsArr);
$this->assertContains('action_unpublish',$actionsArr);
$this->assertContains('action_delete',$actionsArr);
$this->assertNotContains('action_deletefromlive',$actionsArr);
$this->assertContains('action_rollback',$actionsArr);
$this->assertNotContains('action_revert',$actionsArr);
}
}
}
?>

View File

@ -0,0 +1,11 @@
Permission:
cmsmain:
Code: CMS_ACCESS_CMSMain
Group:
cmseditors:
Title: CMS Editors
Permissions: =>Permission.cmsmain
Member:
cmseditor:
Email: cmseditor@test.com
Groups: =>Group.cmseditors