Merged from branches/2.3

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@75579 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Sean Harvey 2009-04-28 23:52:15 +00:00
parent ec9765d9f2
commit 76b5adc979
19 changed files with 87 additions and 34 deletions

4
.htaccess Normal file
View File

@ -0,0 +1,4 @@
<Files cli-script.php>
Order deny,allow
Deny from all
</Files>

View File

@ -7,12 +7,14 @@
* @subpackage view * @subpackage view
*/ */
class Requirements { class Requirements {
/** /**
* Enable combining of css/javascript files. * Enable combining of css/javascript files.
* *
* @var boolean * @var boolean
*/ */
private static $combined_files_enabled = true; private static $combined_files_enabled = true;
public static function set_combined_files_enabled($enable) { public static function set_combined_files_enabled($enable) {
self::$combined_files_enabled = (bool) $enable; self::$combined_files_enabled = (bool) $enable;
} }
@ -21,6 +23,34 @@ class Requirements {
return self::$combined_files_enabled; return self::$combined_files_enabled;
} }
/**
* Do we want requirements to suffix onto the requirement link
* tags for caching or is it disabled. Getter / Setter available
* through {@link Requirements::set_suffix_requirements()}
*
* @var bool
*/
private static $suffix_requirements = true;
/**
* Set whether we want to suffix requirements with the time /
* location on to the requirements
*
* @param bool
*/
public static function set_suffix_requirements($var) {
self::$suffix_requirements = $var;
}
/**
* Return whether we want to suffix requirements
*
* @return bool
*/
public static function get_suffix_requirements() {
return self::$suffix_requirements;
}
/** /**
* Instance of requirements for storage * Instance of requirements for storage
* *
@ -668,7 +698,10 @@ class Requirements_Backend {
return $fileOrUrl; return $fileOrUrl;
} elseif(Director::fileExists($fileOrUrl)) { } elseif(Director::fileExists($fileOrUrl)) {
$prefix = Director::absoluteBaseURL(); $prefix = Director::absoluteBaseURL();
$mtimesuffix = "";
if(Requirements::get_suffix_requirements()) {
$mtimesuffix = "?m=" . filemtime(Director::baseFolder() . '/' . $fileOrUrl); $mtimesuffix = "?m=" . filemtime(Director::baseFolder() . '/' . $fileOrUrl);
}
return "{$prefix}{$fileOrUrl}{$mtimesuffix}"; return "{$prefix}{$fileOrUrl}{$mtimesuffix}";
} else { } else {
return false; return false;

View File

@ -123,7 +123,7 @@ class ViewableData extends Object implements IteratorAggregate {
* @param mixed $val The field value. * @param mixed $val The field value.
*/ */
public function __set($field, $val) { public function __set($field, $val) {
if(method_exists($this, $funcName = "set$field")) { if($this->hasMethod($funcName = "set$field")) {
return $this->$funcName($val); return $this->$funcName($val);
} else { } else {
$this->setField($field, $val); $this->setField($field, $val);

View File

@ -141,9 +141,10 @@ class DataObjectSet extends ViewableData implements IteratorAggregate {
* @param string $index The field you wish to use as a key for the array * @param string $index The field you wish to use as a key for the array
* @param string $titleField The field or method you wish to use to get values for the map * @param string $titleField The field or method you wish to use to get values for the map
* @param string $emptyString String for no option selected * @param string $emptyString String for no option selected
* @param bool $sort If you want to sort the map based on $titleField
* @return array * @return array
*/ */
public function toDropDownMap($index = "ID",$titleField = "Title",$emptyString = null){ public function toDropDownMap($index = "ID",$titleField = "Title",$emptyString = null, $sort = false){
$map = array(); $map = array();
foreach($this->items as $item) { foreach($this->items as $item) {
$map[$item->$index] = $item->$titleField; $map[$item->$index] = $item->$titleField;
@ -151,6 +152,9 @@ class DataObjectSet extends ViewableData implements IteratorAggregate {
if($emptyString) { if($emptyString) {
$map = array("0"=>"$emptyString") + $map; $map = array("0"=>"$emptyString") + $map;
} }
if($sort) {
asort($map);
}
return $map; return $map;
} }

View File

@ -100,7 +100,7 @@ class Image extends File {
function getTag() { function getTag() {
if(file_exists("../" . $this->Filename)) { if(file_exists("../" . $this->Filename)) {
$url = $this->URL(); $url = $this->URL();
$title = $this->Title; $title = ($this->Title) ? $this->Title : $this->Filename;
return "<img src=\"$url\" alt=\"$title\" />"; return "<img src=\"$url\" alt=\"$title\" />";
} }
} }

View File

@ -1469,6 +1469,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$clone = DataObject::get_by_id("SiteTree", $this->ID); $clone = DataObject::get_by_id("SiteTree", $this->ID);
$clone->Status = "Published"; $clone->Status = "Published";
$clone->writeWithoutVersion(); $clone->writeWithoutVersion();
$this->extend('onAfterRevertToLive');
} }
/** /**

View File

@ -6,7 +6,7 @@ html {
overflow-y: auto !important; overflow-y: auto !important;
} }
body { body {
height: auto; height: 100%;
} }
#ComplexTableField_Popup_DetailForm input.loading { #ComplexTableField_Popup_DetailForm input.loading {

View File

@ -81,6 +81,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
$this->originalMailer = Email::mailer(); $this->originalMailer = Email::mailer();
$this->mailer = new TestMailer(); $this->mailer = new TestMailer();
Email::set_mailer($this->mailer); Email::set_mailer($this->mailer);
Email::send_all_emails_to(null);
} }
/** /**

View File

@ -228,6 +228,13 @@ class File extends DataObject {
return $upload->isError(); return $upload->isError();
} }
/**
* Should be called after the file was uploaded
*/
function onAfterUpload() {
$this->extend('onAfterUpload');
}
/** /**
* Delete the database record (recursively for folders) without touching the filesystem * Delete the database record (recursively for folders) without touching the filesystem
*/ */
@ -431,7 +438,7 @@ class File extends DataObject {
if($this->ParentID) { if($this->ParentID) {
$p = DataObject::get_one('Folder', "\"ID\"={$this->ParentID}"); $p = DataObject::get_one('Folder', "\"ID\"={$this->ParentID}");
if($p->ID) return $p->getRelativePath() . $this->getField("Name"); if($p && $p->ID) return $p->getRelativePath() . $this->getField("Name");
else return ASSETS_DIR . "/" . $this->getField("Name"); else return ASSETS_DIR . "/" . $this->getField("Name");
} else if($this->getField("Name")) { } else if($this->getField("Name")) {

View File

@ -330,6 +330,9 @@ class Folder extends File {
$deleteButton = new HiddenField('deletemarked'); $deleteButton = new HiddenField('deletemarked');
} }
$inlineFormAction = new InlineFormAction("delete_unused_thumbnails", _t('Folder.DELETEUNUSEDTHUMBNAILS', 'Delete unused thumbnails'));
$inlineFormAction->includeDefaultJS(false) ;
$fields = new FieldSet( $fields = new FieldSet(
new HiddenField("Title"), new HiddenField("Title"),
new TabSet("Root", new TabSet("Root",
@ -352,16 +355,11 @@ class Folder extends File {
) )
), ),
new Tab("UnusedFiles", _t('Folder.UNUSEDFILESTAB', "Unused files"), new Tab("UnusedFiles", _t('Folder.UNUSEDFILESTAB', "Unused files"),
new LiteralField("UnusedAssets", new LiteralField( "UnusedAssets", "<h2>"._t('Folder.UNUSEDFILESTITLE', 'Unused files')."</h2>" ),
"<div id=\"UnusedAssets\"><h2>"._t('Folder.UNUSEDFILESTITLE', 'Unused files')."</h2>"
),
$this->getAssetList(), $this->getAssetList(),
new LiteralField("UnusedThumbnails", new FieldGroup(
"</div> new LiteralField( "UnusedThumbnails", "<h2>"._t('Folder.UNUSEDTHUMBNAILSTITLE', 'Unused thumbnails')."</h2>"),
<div id=\"UnusedThumbnails\"> $inlineFormAction
<h2>"._t('Folder.UNUSEDTHUMBNAILSTITLE', 'Unused thumbnails')."</h2>
<button class=\"action\">"._t('Folder.DELETEUNUSEDTHUMBNAILS', 'Delete unused thumbnails')."</button>
</div>"
) )
) )
), ),

View File

@ -352,8 +352,8 @@ class GD extends Object {
$rr = ($rv == 0) ? 0 : 1/($rt/$rv); $rr = ($rv == 0) ? 0 : 1/($rt/$rv);
$br = ($bv == 0) ? 0 : 1/($rt/$bv); $br = ($bv == 0) ? 0 : 1/($rt/$bv);
$gr = ($gv == 0) ? 0 : 1/($rt/$gv); $gr = ($gv == 0) ? 0 : 1/($rt/$gv);
for($dy = 0; $dy <= $height; $dy++) { for($dy = 0; $dy < $height; $dy++) {
for($dx = 0; $dx <= $width; $dx++) { for($dx = 0; $dx < $width; $dx++) {
$pxrgb = imagecolorat($this->gd, $dx, $dy); $pxrgb = imagecolorat($this->gd, $dx, $dy);
$heightgb = ImageColorsforIndex($this->gd, $pxrgb); $heightgb = ImageColorsforIndex($this->gd, $pxrgb);
$newcol = ($rr*$heightgb['red']) + ($br*$heightgb['blue']) + ($gr*$heightgb['green']); $newcol = ($rr*$heightgb['red']) + ($br*$heightgb['blue']) + ($gr*$heightgb['green']);

View File

@ -65,7 +65,7 @@ class CustomRequiredFields extends RequiredFields{
if(!$data[$fieldName] || preg_match('/^\s*$/', $data[$fieldName])) { if(!$data[$fieldName] || preg_match('/^\s*$/', $data[$fieldName])) {
$this->validationError( $this->validationError(
$fieldName, $fieldName,
sprintf(_t('Form.FIELDISREQUIRED', "%s is required"), sprintf(_t('Form.FIELDISREQUIRED', "%s is required."),
$formField->Title()), $formField->Title()),
"required" "required"
); );

View File

@ -32,9 +32,13 @@ class FieldSet extends DataObjectSet {
$itemsArr = (!is_array($items) || count(func_get_args()) > 1) ? func_get_args() : $items; $itemsArr = (!is_array($items) || count(func_get_args()) > 1) ? func_get_args() : $items;
parent::__construct($itemsArr); parent::__construct($itemsArr);
if(isset($this->items)&&count($this->items)){
foreach($this->items as $item) { foreach($this->items as $item) {
if(isset($item)&&is_a($item,"FormField")){
$item->setContainerFieldSet($this); $item->setContainerFieldSet($this);
} }
}
}
} }

View File

@ -60,7 +60,7 @@ class InlineFormAction_ReadOnly extends FormField {
protected $readonly = true; protected $readonly = true;
function Field() { function Field() {
return "<input type=\"submit\" name=\"action_{$this->name}\" value=\"{$this->title}\" id=\"{$this->id()}\" disabled=\"disabled\" class=\"action$this->extraClass\" />"; return "<input type=\"submit\" name=\"action_{$this->name}\" value=\"{$this->title}\" id=\"{$this->id()}\" disabled=\"disabled\" class=\"action disabled$this->extraClass\" />";
} }
function Title() { function Title() {

View File

@ -102,7 +102,7 @@ JS;
$this->validationError( $this->validationError(
$fieldName, $fieldName,
sprintf( sprintf(
_t('Form.FIELDISREQUIRED'), _t('Form.FIELDISREQUIRED').'.',
strip_tags('"' . ($formField->Title() ? $formField->Title() : $fieldName) . '"') strip_tags('"' . ($formField->Title() ? $formField->Title() : $fieldName) . '"')
), ),
"required" "required"

View File

@ -167,7 +167,7 @@ abstract class Validator extends Object {
} }
function requireField($fieldName, $data) { function requireField($fieldName, $data) {
if(!$data[$fieldName]) $this->validationError($fieldName, "$fieldName is required", "required"); if(!$data[$fieldName]) $this->validationError($fieldName, "$fieldName is required.", "required");
} }
function includeJavascriptValidation() { function includeJavascriptValidation() {

View File

@ -1,12 +1,12 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html> <html>
<head> <head>
<% base_tag %>
</head> </head>
<body> <body>
<p class="body"> <p class="body">
$Body $Body
</p> </p>
</body> </body>

View File

@ -207,7 +207,7 @@ class FormTest extends FunctionalTest {
$this->assertPartialMatchBySelector( $this->assertPartialMatchBySelector(
'#SomeRequiredField span.required', '#SomeRequiredField span.required',
array( array(
sprintf(_t('Form.FIELDISREQUIRED'),'"SomeRequiredField"') sprintf(_t('Form.FIELDISREQUIRED').'.','"SomeRequiredField"')
), ),
'Required fields show a notification on field when left blank' 'Required fields show a notification on field when left blank'
); );