mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge branch '3.1'
This commit is contained in:
commit
9048eab4a2
@ -418,7 +418,7 @@ class Injector {
|
|||||||
// and reload the object; existing bindings don't get
|
// and reload the object; existing bindings don't get
|
||||||
// updated though! (for now...)
|
// updated though! (for now...)
|
||||||
if (isset($this->serviceCache[$id])) {
|
if (isset($this->serviceCache[$id])) {
|
||||||
$this->instantiate($spec, $id);
|
$this->instantiate(array('class'=>$id), $id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* @todo Add support for deep chaining of relation properties (e.g. Player.Team.Stats.GoalCount)
|
* @todo Add support for deep chaining of relation properties (e.g. Player.Team.Stats.GoalCount)
|
||||||
* @todo Character conversion
|
* @todo Character conversion
|
||||||
*
|
*
|
||||||
* @see http://rfc.net/rfc4180.html
|
* @see http://tools.ietf.org/html/rfc4180
|
||||||
* @package framework
|
* @package framework
|
||||||
* @subpackage bulkloading
|
* @subpackage bulkloading
|
||||||
* @author Ingo Schommer, Silverstripe Ltd. (<firstname>@silverstripe.com)
|
* @author Ingo Schommer, Silverstripe Ltd. (<firstname>@silverstripe.com)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Uses the fgetcsv() function to process CSV input. Accepts a file-handler as
|
* Uses the fgetcsv() function to process CSV input. Accepts a file-handler as
|
||||||
* input.
|
* input.
|
||||||
*
|
*
|
||||||
* @see http://rfc.net/rfc4180.html
|
* @see http://tools.ietf.org/html/rfc4180
|
||||||
*
|
*
|
||||||
* @package framework
|
* @package framework
|
||||||
* @subpackage bulkloading
|
* @subpackage bulkloading
|
||||||
|
@ -34,7 +34,7 @@ instead make it easier for developers to build other applications.
|
|||||||
|
|
||||||
## Finding Modules
|
## Finding Modules
|
||||||
|
|
||||||
* [Official module list on silverstripe.org](http://silverstripe.org/modules)
|
* [Official module list on silverstripe.org](http://addons.silverstripe.org/)
|
||||||
* [Packagist.org "silverstripe" tag](https://packagist.org/search/?tags=silverstripe)
|
* [Packagist.org "silverstripe" tag](https://packagist.org/search/?tags=silverstripe)
|
||||||
* [Github.com "silverstripe" search](https://github.com/search?q=silverstripe&ref=commandbar)
|
* [Github.com "silverstripe" search](https://github.com/search?q=silverstripe&ref=commandbar)
|
||||||
|
|
||||||
|
@ -129,17 +129,12 @@ class Upload extends Controller {
|
|||||||
$base = Director::baseFolder();
|
$base = Director::baseFolder();
|
||||||
$parentFolder = Folder::find_or_make($folderPath);
|
$parentFolder = Folder::find_or_make($folderPath);
|
||||||
|
|
||||||
// Create a folder for uploading.
|
|
||||||
if(!file_exists(ASSETS_PATH . "/" . $folderPath)){
|
|
||||||
Filesystem::makeFolder(ASSETS_PATH . "/" . $folderPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate default filename
|
// Generate default filename
|
||||||
$nameFilter = FileNameFilter::create();
|
$nameFilter = FileNameFilter::create();
|
||||||
$file = $nameFilter->filter($tmpFile['name']);
|
$file = $nameFilter->filter($tmpFile['name']);
|
||||||
$fileName = basename($file);
|
$fileName = basename($file);
|
||||||
|
|
||||||
$relativeFilePath = ASSETS_DIR . "/" . $folderPath . "/$fileName";
|
$relativeFilePath = $parentFolder->getRelativePath() . "/$fileName";
|
||||||
|
|
||||||
// Create a new file record (or try to retrieve an existing one)
|
// Create a new file record (or try to retrieve an existing one)
|
||||||
if(!$this->file) {
|
if(!$this->file) {
|
||||||
|
@ -292,10 +292,20 @@ class Form extends RequestHandler {
|
|||||||
|
|
||||||
// Protection against CSRF attacks
|
// Protection against CSRF attacks
|
||||||
$token = $this->getSecurityToken();
|
$token = $this->getSecurityToken();
|
||||||
if(!$token->checkRequest($request)) {
|
if( ! $token->checkRequest($request)) {
|
||||||
$this->httpError(400, _t("Form.CSRF_FAILED_MESSAGE",
|
if (empty($vars['SecurityID'])) {
|
||||||
"There seems to have been a technical problem. Please click the back button,"
|
$this->httpError(400, _t("Form.CSRF_FAILED_MESSAGE",
|
||||||
. " refresh your browser, and try again."));
|
"There seems to have been a technical problem. Please click the back button,
|
||||||
|
refresh your browser, and try again."));
|
||||||
|
} else {
|
||||||
|
Session::set("FormInfo.{$this->FormName()}.data", $this->getData());
|
||||||
|
Session::set("FormInfo.{$this->FormName()}.errors", array());
|
||||||
|
$this->sessionMessage(
|
||||||
|
_t("Form.CSRF_EXPIRED_MESSAGE", "Your session has expired. Please re-submit the form."),
|
||||||
|
"warning"
|
||||||
|
);
|
||||||
|
return $this->controller->redirectBack();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the action button clicked
|
// Determine the action button clicked
|
||||||
|
@ -957,8 +957,8 @@ class UploadField extends FileField {
|
|||||||
Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
|
Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
|
||||||
Requirements::javascript(THIRDPARTY_DIR . '/jquery-ui/jquery-ui.js');
|
Requirements::javascript(THIRDPARTY_DIR . '/jquery-ui/jquery-ui.js');
|
||||||
Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js');
|
Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js');
|
||||||
Requirements::javascript(FRAMEWORK_DIR . '/javascript/i18n.js');
|
|
||||||
Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/javascript/ssui.core.js');
|
Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/javascript/ssui.core.js');
|
||||||
|
Requirements::add_i18n_javascript(FRAMEWORK_DIR . '/javascript/lang');
|
||||||
|
|
||||||
Requirements::combine_files('uploadfield.js', array(
|
Requirements::combine_files('uploadfield.js', array(
|
||||||
// @todo jquery templates is a project no longer maintained and should be retired at some point.
|
// @todo jquery templates is a project no longer maintained and should be retired at some point.
|
||||||
|
@ -249,4 +249,4 @@ abstract class SS_Query implements Iterator {
|
|||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
abstract public function seek($rowNum);
|
abstract public function seek($rowNum);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,8 @@ class SS_Transliterator extends Object {
|
|||||||
'þ'=>'b', 'ÿ'=>'y', 'Ŕ'=>'R', 'ŕ'=>'r',
|
'þ'=>'b', 'ÿ'=>'y', 'Ŕ'=>'R', 'ŕ'=>'r',
|
||||||
'Ā'=>'A', 'ā'=>'a', 'Ē'=>'E', 'ē'=>'e', 'Ī'=>'I', 'ī'=>'i', 'Ō'=>'O', 'ō'=>'o', 'Ū'=>'U', 'ū'=>'u',
|
'Ā'=>'A', 'ā'=>'a', 'Ē'=>'E', 'ē'=>'e', 'Ī'=>'I', 'ī'=>'i', 'Ō'=>'O', 'ō'=>'o', 'Ū'=>'U', 'ū'=>'u',
|
||||||
'œ'=>'oe', 'ß'=>'ss', 'ij'=>'ij', 'ą'=>'a','ę'=>'e', 'ė'=>'e', 'į'=>'i','ų'=>'u','ū'=>'u', 'Ą'=>'A',
|
'œ'=>'oe', 'ß'=>'ss', 'ij'=>'ij', 'ą'=>'a','ę'=>'e', 'ė'=>'e', 'į'=>'i','ų'=>'u','ū'=>'u', 'Ą'=>'A',
|
||||||
'Ę'=>'E', 'Ė'=>'E', 'Į'=>'I','Ų'=>'U','Ū'=>'u'
|
'Ę'=>'E', 'Ė'=>'E', 'Į'=>'I','Ų'=>'U','Ū'=>'u',
|
||||||
|
"ľ"=>"l", "Ľ"=>"L", "ť"=>"t", "Ť"=>"T", "ů"=>"u", "Ů"=>"U",
|
||||||
);
|
);
|
||||||
|
|
||||||
return strtr($source, $table);
|
return strtr($source, $table);
|
||||||
|
@ -54,24 +54,41 @@ class SS_Datetime extends Date implements TemplateGlobalProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the date in the raw SQL-format, e.g. “2006-01-18 16:32:04”
|
* Returns the date and time (in 12-hour format) using the format string 'd/m/Y g:ia' e.g. '31/01/2014 2:23pm'.
|
||||||
|
* @return string Formatted date and time.
|
||||||
*/
|
*/
|
||||||
public function Nice() {
|
public function Nice() {
|
||||||
if($this->value) return $this->Format('d/m/Y g:ia');
|
if($this->value) return $this->Format('d/m/Y g:ia');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the date and time (in 24-hour format) using the format string 'd/m/Y H:i' e.g. '28/02/2014 13:32'.
|
||||||
|
* @return string Formatted date and time.
|
||||||
|
*/
|
||||||
public function Nice24() {
|
public function Nice24() {
|
||||||
if($this->value) return $this->Format('d/m/Y H:i');
|
if($this->value) return $this->Format('d/m/Y H:i');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the date using the format string 'd/m/Y' e.g. '28/02/2014'.
|
||||||
|
* @return string Formatted date.
|
||||||
|
*/
|
||||||
public function Date() {
|
public function Date() {
|
||||||
if($this->value) return $this->Format('d/m/Y');
|
if($this->value) return $this->Format('d/m/Y');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the time in 12-hour format using the format string 'g:ia' e.g. '1:32pm'.
|
||||||
|
* @return string Formatted time.
|
||||||
|
*/
|
||||||
public function Time() {
|
public function Time() {
|
||||||
if($this->value) return $this->Format('g:ia');
|
if($this->value) return $this->Format('g:ia');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the time in 24-hour format using the format string 'H:i' e.g. '13:32'.
|
||||||
|
* @return string Formatted time.
|
||||||
|
*/
|
||||||
public function Time24() {
|
public function Time24() {
|
||||||
if($this->value) return $this->Format('H:i');
|
if($this->value) return $this->Format('H:i');
|
||||||
}
|
}
|
||||||
@ -81,7 +98,13 @@ class SS_Datetime extends Date implements TemplateGlobalProvider {
|
|||||||
$values=Array('type'=>'SS_Datetime', 'parts'=>$parts);
|
$values=Array('type'=>'SS_Datetime', 'parts'=>$parts);
|
||||||
DB::requireField($this->tableName, $this->name, $values);
|
DB::requireField($this->tableName, $this->name, $values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the url encoded date and time in ISO 6801 format using format
|
||||||
|
* string 'Y-m-d%20H:i:s' e.g. '2014-02-28%2013:32:22'.
|
||||||
|
*
|
||||||
|
* @return string Formatted date and time.
|
||||||
|
*/
|
||||||
public function URLDatetime() {
|
public function URLDatetime() {
|
||||||
if($this->value) return $this->Format('Y-m-d%20H:i:s');
|
if($this->value) return $this->Format('Y-m-d%20H:i:s');
|
||||||
}
|
}
|
||||||
|
@ -10,4 +10,5 @@
|
|||||||
</div>
|
</div>
|
||||||
<% if $RightTitle %><label class="right">$RightTitle</label><% end_if %>
|
<% if $RightTitle %><label class="right">$RightTitle</label><% end_if %>
|
||||||
<% if $Message %><span class="message $MessageType">$Message</span><% end_if %>
|
<% if $Message %><span class="message $MessageType">$Message</span><% end_if %>
|
||||||
|
<% if $Description %><span class="description">$Description</span><% end_if %>
|
||||||
</div>
|
</div>
|
||||||
|
@ -320,7 +320,22 @@ class FormTest extends FunctionalTest {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
$this->assertEquals(400, $response->getStatusCode(), 'Submission fails without security token');
|
$this->assertEquals(400, $response->getStatusCode(), 'Submission fails without security token');
|
||||||
|
|
||||||
|
$response = $this->get('FormTest_ControllerWithSecurityToken');
|
||||||
|
$response = $this->post(
|
||||||
|
'FormTest_ControllerWithSecurityToken/Form',
|
||||||
|
array(
|
||||||
|
'Email' => 'test@test.com',
|
||||||
|
'action_doSubmit' => 1,
|
||||||
|
'SecurityID' => -1
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->assertEquals(200, $response->getStatusCode(), 'Submission reloads form if security token invalid');
|
||||||
|
|
||||||
|
$matched = $this->cssParser()->getBySelector('#Form_Form_Email');
|
||||||
|
$attrs = $matched[0]->attributes();
|
||||||
|
$this->assertEquals('test@test.com', (string)$attrs['value'], 'Submitted data is preserved');
|
||||||
|
|
||||||
$response = $this->get('FormTest_ControllerWithSecurityToken');
|
$response = $this->get('FormTest_ControllerWithSecurityToken');
|
||||||
$tokenEls = $this->cssParser()->getBySelector('#Form_Form_SecurityID');
|
$tokenEls = $this->cssParser()->getBySelector('#Form_Form_SecurityID');
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
|
@ -358,19 +358,28 @@ class SQLQueryTest extends SapphireTest {
|
|||||||
$query->setFrom('"SQLQueryTest_DO"');
|
$query->setFrom('"SQLQueryTest_DO"');
|
||||||
$query->setOrderBy('"Name"');
|
$query->setOrderBy('"Name"');
|
||||||
$result = $query->firstRow()->execute();
|
$result = $query->firstRow()->execute();
|
||||||
|
|
||||||
$this->assertCount(1, $result);
|
$records = array();
|
||||||
foreach($result as $row) {
|
foreach($result as $row) {
|
||||||
$this->assertEquals('Object 1', $row['Name']);
|
$records[] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->assertCount(1, $records);
|
||||||
|
$this->assertEquals('Object 1', $records[0]['Name']);
|
||||||
|
|
||||||
// Test first from empty sequence
|
// Test first from empty sequence
|
||||||
$query = new SQLQuery();
|
$query = new SQLQuery();
|
||||||
$query->setFrom('"SQLQueryTest_DO"');
|
$query->setFrom('"SQLQueryTest_DO"');
|
||||||
$query->setOrderBy('"Name"');
|
$query->setOrderBy('"Name"');
|
||||||
$query->setWhere(array("\"Name\" = 'Nonexistent Object'"));
|
$query->setWhere(array("\"Name\" = 'Nonexistent Object'"));
|
||||||
$result = $query->firstRow()->execute();
|
$result = $query->firstRow()->execute();
|
||||||
$this->assertCount(0, $result);
|
|
||||||
|
$records = array();
|
||||||
|
foreach($result as $row) {
|
||||||
|
$records[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertCount(0, $records);
|
||||||
|
|
||||||
// Test that given the last item, the 'first' in this list matches the last
|
// Test that given the last item, the 'first' in this list matches the last
|
||||||
$query = new SQLQuery();
|
$query = new SQLQuery();
|
||||||
@ -378,10 +387,14 @@ class SQLQueryTest extends SapphireTest {
|
|||||||
$query->setOrderBy('"Name"');
|
$query->setOrderBy('"Name"');
|
||||||
$query->setLimit(1, 1);
|
$query->setLimit(1, 1);
|
||||||
$result = $query->firstRow()->execute();
|
$result = $query->firstRow()->execute();
|
||||||
$this->assertCount(1, $result);
|
|
||||||
|
$records = array();
|
||||||
foreach($result as $row) {
|
foreach($result as $row) {
|
||||||
$this->assertEquals('Object 2', $row['Name']);
|
$records[] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->assertCount(1, $records);
|
||||||
|
$this->assertEquals('Object 2', $records[0]['Name']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSelectLast() {
|
public function testSelectLast() {
|
||||||
@ -391,11 +404,14 @@ class SQLQueryTest extends SapphireTest {
|
|||||||
$query->setFrom('"SQLQueryTest_DO"');
|
$query->setFrom('"SQLQueryTest_DO"');
|
||||||
$query->setOrderBy('"Name"');
|
$query->setOrderBy('"Name"');
|
||||||
$result = $query->lastRow()->execute();
|
$result = $query->lastRow()->execute();
|
||||||
|
|
||||||
$this->assertCount(1, $result);
|
$records = array();
|
||||||
foreach($result as $row) {
|
foreach($result as $row) {
|
||||||
$this->assertEquals('Object 2', $row['Name']);
|
$records[] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->assertCount(1, $records);
|
||||||
|
$this->assertEquals('Object 2', $records[0]['Name']);
|
||||||
|
|
||||||
// Test last from empty sequence
|
// Test last from empty sequence
|
||||||
$query = new SQLQuery();
|
$query = new SQLQuery();
|
||||||
@ -403,20 +419,30 @@ class SQLQueryTest extends SapphireTest {
|
|||||||
$query->setOrderBy('"Name"');
|
$query->setOrderBy('"Name"');
|
||||||
$query->setWhere(array("\"Name\" = 'Nonexistent Object'"));
|
$query->setWhere(array("\"Name\" = 'Nonexistent Object'"));
|
||||||
$result = $query->lastRow()->execute();
|
$result = $query->lastRow()->execute();
|
||||||
$this->assertCount(0, $result);
|
|
||||||
|
$records = array();
|
||||||
|
foreach($result as $row) {
|
||||||
|
$records[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertCount(0, $records);
|
||||||
|
|
||||||
// Test that given the first item, the 'last' in this list matches the first
|
// Test that given the first item, the 'last' in this list matches the first
|
||||||
$query = new SQLQuery();
|
$query = new SQLQuery();
|
||||||
$query->setFrom('"SQLQueryTest_DO"');
|
$query->setFrom('"SQLQueryTest_DO"');
|
||||||
$query->setOrderBy('"Name"');
|
$query->setOrderBy('"Name"');
|
||||||
$query->setLimit(1);
|
$query->setLimit(1);
|
||||||
$result = $query->lastRow()->execute();
|
$result = $query->lastRow()->execute();
|
||||||
$this->assertCount(1, $result);
|
|
||||||
|
$records = array();
|
||||||
foreach($result as $row) {
|
foreach($result as $row) {
|
||||||
$this->assertEquals('Object 1', $row['Name']);
|
$records[] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->assertCount(1, $records);
|
||||||
|
$this->assertEquals('Object 1', $records[0]['Name']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests aggregate() function
|
* Tests aggregate() function
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user