mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
Merge branch '4.1' into 4
This commit is contained in:
commit
16d3498a56
@ -16,14 +16,16 @@ If you don't fully understand the configuration presented here, consult the
|
|||||||
Especially be aware of [accidental php-execution](https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx-dont-trust-the-tutorials-check-your-configuration/ "Don't trust the tutorials") when extending the configuration.
|
Especially be aware of [accidental php-execution](https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx-dont-trust-the-tutorials-check-your-configuration/ "Don't trust the tutorials") when extending the configuration.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
But enough of the disclaimer, on to the actual configuration — typically in `nginx.conf`. This assumes
|
But enough of the disclaimer, on to the actual configuration — typically in `nginx.conf`:
|
||||||
you are running your site configuration with a separate `public/` webroot folder.
|
|
||||||
|
|
||||||
server {
|
```nginx
|
||||||
|
server {
|
||||||
|
include mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
client_max_body_size 0; # Manage this in php.ini
|
||||||
listen 80;
|
listen 80;
|
||||||
root /var/www/the-website/public;
|
root /path/to/ss/folder;
|
||||||
|
server_name example.com www.example.com;
|
||||||
server_name site.com www.site.com;
|
|
||||||
|
|
||||||
# Defend against SS-2015-013 -- http://www.silverstripe.org/software/download/security-releases/ss-2015-013
|
# Defend against SS-2015-013 -- http://www.silverstripe.org/software/download/security-releases/ss-2015-013
|
||||||
if ($http_x_forwarded_host) {
|
if ($http_x_forwarded_host) {
|
||||||
@ -38,35 +40,56 @@ you are running your site configuration with a separate `public/` webroot folder
|
|||||||
error_page 500 /assets/error-500.html;
|
error_page 500 /assets/error-500.html;
|
||||||
|
|
||||||
location ^~ /assets/ {
|
location ^~ /assets/ {
|
||||||
location ~ /\. {
|
|
||||||
deny all;
|
|
||||||
}
|
|
||||||
sendfile on;
|
sendfile on;
|
||||||
try_files $uri /index.php?$query_string;
|
try_files $uri =404;
|
||||||
}
|
}
|
||||||
|
|
||||||
location ~ /\.. {
|
location /index.php {
|
||||||
deny all;
|
fastcgi_buffer_size 32k;
|
||||||
}
|
fastcgi_busy_buffers_size 64k;
|
||||||
|
fastcgi_buffers 4 32k;
|
||||||
location ~ web\.config$ {
|
|
||||||
deny all;
|
|
||||||
}
|
|
||||||
|
|
||||||
location ~ \.php$ {
|
|
||||||
fastcgi_keep_conn on;
|
fastcgi_keep_conn on;
|
||||||
fastcgi_pass 127.0.0.1:9000;
|
fastcgi_pass 127.0.0.1:9000;
|
||||||
fastcgi_index index.php;
|
fastcgi_index index.php;
|
||||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
include fastcgi_params;
|
include fastcgi_params;
|
||||||
fastcgi_buffer_size 32k;
|
|
||||||
fastcgi_busy_buffers_size 64k;
|
|
||||||
fastcgi_buffers 4 32k;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
The above configuration sets up a virtual host `site.com` with
|
# Denials
|
||||||
rewrite rules suited for SilverStripe. The location block for php files
|
location ~ /\.. {
|
||||||
passes all php scripts to the FastCGI-wrapper via a TCP socket.
|
deny all;
|
||||||
|
}
|
||||||
|
location ~ \.ss$ {
|
||||||
|
satisfy any;
|
||||||
|
allow 127.0.0.1;
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
location ~ web\.config$ {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
location ~ \.ya?ml$ {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
location ~* README.*$ {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
location ^~ /vendor/ {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
location ~* /silverstripe-cache/ {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
location ~* composer\.(json|lock)$ {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
location ~* /(cms|framework)/silverstripe_version$ {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The above configuration sets up a virtual host `example.com` with
|
||||||
|
rewrite rules suited for SilverStripe. The location block for index.php
|
||||||
|
passes the php script to the FastCGI-wrapper via a TCP socket.
|
||||||
|
|
||||||
Now you can proceed with the SilverStripe installation normally.
|
Now you can proceed with the SilverStripe installation normally.
|
||||||
|
@ -263,7 +263,7 @@ _t('CMSMain.RESTORED',
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Plurals are invoked via a `|` pipe-delimeter with a {count} argument
|
// Plurals are invoked via a `|` pipe-delimeter with a {count} argument
|
||||||
_t('MyObject.PLURALS', 'An object|{count} objects', [ 'count' => '$count ]);
|
_t('MyObject.PLURALS', 'An object|{count} objects', [ 'count' => $count ]);
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Usage in Template Files
|
#### Usage in Template Files
|
||||||
|
18
docs/en/04_Changelogs/3.5.7.md
Normal file
18
docs/en/04_Changelogs/3.5.7.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# 3.5.7
|
||||||
|
|
||||||
|
<!--- Changes below this line will be automatically regenerated -->
|
||||||
|
|
||||||
|
## Change Log
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
* 2018-01-26 [416915b08](https://github.com/silverstripe/silverstripe-framework/commit/416915b08248285083518850ad8d015ca8ed25c2) tableName is blank in CompositeDBField->addToQuery (Dominik Beerbohm)
|
||||||
|
* 2018-01-25 [cf69d0486](https://github.com/silverstripe/silverstripe-framework/commit/cf69d048665befa90eb43146f86cde984b876b3a) Fix ping including requirements (Damian Mooyman)
|
||||||
|
* 2018-01-24 [c2cd6b383](https://github.com/silverstripe/silverstripe-framework/commit/c2cd6b3832c6bc4775b2742df593b445c2aca391) Fix Member_GroupSet::removeAll() (fixes #3948) (Loz Calver)
|
||||||
|
* 2018-01-24 [f2b4c192e](https://github.com/silverstripe/silverstripe-framework/commit/f2b4c192ec4d70779f7c667a976e741a7f3a26c5) Fix UploadField cuts off “Save” button (closes #2862) (Loz Calver)
|
||||||
|
* 2018-01-23 [7384e3fc2](https://github.com/silverstripe/silverstripe-framework/commit/7384e3fc25987742ea08af74b704857a936e8ec0) Gridfields with dropdowns having lots of overflow (Scott Hutchinson)
|
||||||
|
* 2017-12-21 [44930f211](https://github.com/silverstripe/silverstripe-framework/commit/44930f211be3f658fc92f2d5318255de03078701) Allow HTML 5 input tags in FunctionalTest form submissions (Daniel Hensby)
|
||||||
|
* 2017-12-14 [81150c592](https://github.com/silverstripe/silverstripe-framework/commit/81150c59225dbf1e95bb0b4dbcfbe18346f2bdff) Use PHP 5.3 array syntax (Daniel Hensby)
|
||||||
|
* 2016-10-21 [8e5bb6fbd](https://github.com/silverstripe/silverstripe-framework/commit/8e5bb6fbdce0b2ca2d08a45534df2264db5e6b12) Fix : relObject() should return null if one of the node is null (Jason)
|
||||||
|
* 2016-03-15 [22b3a71ec](https://github.com/silverstripe/silverstripe-framework/commit/22b3a71ec0c8cd8c38030fa0bf5449abefafe8a3) ing val reference to url in https hotlink (Denise Rivera)
|
||||||
|
* 2015-04-22 [1f63637b9](https://github.com/silverstripe/silverstripe-framework/commit/1f63637b9369d4644a92523ada5d1a5dc0576c12) for #4095, TinyMCE not able to modify props of embed media (bug 1) and invalid HTML inserted (bug 2) (Patrick Nelson)
|
16
docs/en/04_Changelogs/3.6.5.md
Normal file
16
docs/en/04_Changelogs/3.6.5.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# 3.6.5
|
||||||
|
|
||||||
|
<!--- Changes below this line will be automatically regenerated -->
|
||||||
|
|
||||||
|
## Change Log
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
* 2018-01-26 [416915b08](https://github.com/silverstripe/silverstripe-framework/commit/416915b08248285083518850ad8d015ca8ed25c2) tableName is blank in CompositeDBField->addToQuery (Dominik Beerbohm)
|
||||||
|
* 2018-01-25 [cf69d0486](https://github.com/silverstripe/silverstripe-framework/commit/cf69d048665befa90eb43146f86cde984b876b3a) Fix ping including requirements (Damian Mooyman)
|
||||||
|
* 2018-01-24 [c2cd6b383](https://github.com/silverstripe/silverstripe-framework/commit/c2cd6b3832c6bc4775b2742df593b445c2aca391) Fix Member_GroupSet::removeAll() (fixes #3948) (Loz Calver)
|
||||||
|
* 2018-01-24 [f2b4c192e](https://github.com/silverstripe/silverstripe-framework/commit/f2b4c192ec4d70779f7c667a976e741a7f3a26c5) Fix UploadField cuts off “Save” button (closes #2862) (Loz Calver)
|
||||||
|
* 2018-01-23 [7384e3fc2](https://github.com/silverstripe/silverstripe-framework/commit/7384e3fc25987742ea08af74b704857a936e8ec0) Gridfields with dropdowns having lots of overflow (Scott Hutchinson)
|
||||||
|
* 2016-10-21 [8e5bb6fbd](https://github.com/silverstripe/silverstripe-framework/commit/8e5bb6fbdce0b2ca2d08a45534df2264db5e6b12) Fix : relObject() should return null if one of the node is null (Jason)
|
||||||
|
* 2016-03-15 [22b3a71ec](https://github.com/silverstripe/silverstripe-framework/commit/22b3a71ec0c8cd8c38030fa0bf5449abefafe8a3) ing val reference to url in https hotlink (Denise Rivera)
|
||||||
|
* 2015-04-22 [1f63637b9](https://github.com/silverstripe/silverstripe-framework/commit/1f63637b9369d4644a92523ada5d1a5dc0576c12) for #4095, TinyMCE not able to modify props of embed media (bug 1) and invalid HTML inserted (bug 2) (Patrick Nelson)
|
@ -11,7 +11,7 @@ Requires PHPUnit ^5.7
|
|||||||
<directory>tests/php</directory>
|
<directory>tests/php</directory>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
<testsuite name="cms">
|
<testsuite name="cms">
|
||||||
<directory>cms/tests</directory>
|
<directory>vendor/silverstripe/cms/tests</directory>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
<filter>
|
<filter>
|
||||||
<whitelist addUncoveredFilesFromWhitelist="true">
|
<whitelist addUncoveredFilesFromWhitelist="true">
|
||||||
|
@ -160,7 +160,7 @@ class CliDebugView extends DebugView
|
|||||||
public function debugVariableText($val)
|
public function debugVariableText($val)
|
||||||
{
|
{
|
||||||
// Check debug
|
// Check debug
|
||||||
if (ClassInfo::hasMethod($val, 'debug')) {
|
if (is_object($val) && ClassInfo::hasMethod($val, 'debug')) {
|
||||||
return $val->debug();
|
return $val->debug();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionP
|
|||||||
* Generate export fields for CSV.
|
* Generate export fields for CSV.
|
||||||
*
|
*
|
||||||
* @param GridField $gridField
|
* @param GridField $gridField
|
||||||
* @return array
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function generateExportFileData($gridField)
|
public function generateExportFileData($gridField)
|
||||||
{
|
{
|
||||||
@ -232,7 +232,7 @@ class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionP
|
|||||||
// Convert the $fileData array into csv by capturing fputcsv's output
|
// Convert the $fileData array into csv by capturing fputcsv's output
|
||||||
$csv = fopen('php://temp', 'r+');
|
$csv = fopen('php://temp', 'r+');
|
||||||
foreach ($fileData as $line) {
|
foreach ($fileData as $line) {
|
||||||
fputcsv($csv, $line, $this->csvSeparator, $this->csvEnclosure);
|
fputcsv($csv, $line, $this->getCsvSeparator(), $this->getCsvEnclosure());
|
||||||
}
|
}
|
||||||
rewind($csv);
|
rewind($csv);
|
||||||
return stream_get_contents($csv);
|
return stream_get_contents($csv);
|
||||||
|
@ -57,6 +57,11 @@ class MySQLDatabase extends Database
|
|||||||
*/
|
*/
|
||||||
private static $collation = 'utf8_general_ci';
|
private static $collation = 'utf8_general_ci';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $transactionNesting = 0;
|
||||||
|
|
||||||
public function connect($parameters)
|
public function connect($parameters)
|
||||||
{
|
{
|
||||||
// Ensure that driver is available (required by PDO)
|
// Ensure that driver is available (required by PDO)
|
||||||
@ -300,6 +305,9 @@ class MySQLDatabase extends Database
|
|||||||
|
|
||||||
public function transactionStart($transactionMode = false, $sessionCharacteristics = false)
|
public function transactionStart($transactionMode = false, $sessionCharacteristics = false)
|
||||||
{
|
{
|
||||||
|
if ($this->transactionNesting > 0) {
|
||||||
|
$this->transactionSavepoint('NESTEDTRANSACTION' . $this->transactionNesting);
|
||||||
|
} else {
|
||||||
// This sets the isolation level for the NEXT transaction, not the current one.
|
// This sets the isolation level for the NEXT transaction, not the current one.
|
||||||
if ($transactionMode) {
|
if ($transactionMode) {
|
||||||
$this->query('SET TRANSACTION ' . $transactionMode);
|
$this->query('SET TRANSACTION ' . $transactionMode);
|
||||||
@ -311,6 +319,8 @@ class MySQLDatabase extends Database
|
|||||||
$this->query('SET SESSION TRANSACTION ' . $sessionCharacteristics);
|
$this->query('SET SESSION TRANSACTION ' . $sessionCharacteristics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
++$this->transactionNesting;
|
||||||
|
}
|
||||||
|
|
||||||
public function transactionSavepoint($savepoint)
|
public function transactionSavepoint($savepoint)
|
||||||
{
|
{
|
||||||
@ -321,15 +331,24 @@ class MySQLDatabase extends Database
|
|||||||
{
|
{
|
||||||
if ($savepoint) {
|
if ($savepoint) {
|
||||||
$this->query('ROLLBACK TO ' . $savepoint);
|
$this->query('ROLLBACK TO ' . $savepoint);
|
||||||
|
} else {
|
||||||
|
--$this->transactionNesting;
|
||||||
|
if ($this->transactionNesting > 0) {
|
||||||
|
$this->transactionRollback('NESTEDTRANSACTION' . $this->transactionNesting);
|
||||||
} else {
|
} else {
|
||||||
$this->query('ROLLBACK');
|
$this->query('ROLLBACK');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function transactionEnd($chain = false)
|
public function transactionEnd($chain = false)
|
||||||
{
|
{
|
||||||
|
--$this->transactionNesting;
|
||||||
|
if ($this->transactionNesting <= 0) {
|
||||||
|
$this->transactionNesting = 0;
|
||||||
$this->query('COMMIT AND ' . ($chain ? '' : 'NO ') . 'CHAIN');
|
$this->query('COMMIT AND ' . ($chain ? '' : 'NO ') . 'CHAIN');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function comparisonClause(
|
public function comparisonClause(
|
||||||
$field,
|
$field,
|
||||||
|
@ -5,6 +5,7 @@ namespace SilverStripe\Security;
|
|||||||
use SilverStripe\ORM\DataObject;
|
use SilverStripe\ORM\DataObject;
|
||||||
use SilverStripe\ORM\DB;
|
use SilverStripe\ORM\DB;
|
||||||
use SilverStripe\ORM\ManyManyList;
|
use SilverStripe\ORM\ManyManyList;
|
||||||
|
use SilverStripe\ORM\Queries\SQLDelete;
|
||||||
use SilverStripe\ORM\Queries\SQLSelect;
|
use SilverStripe\ORM\Queries\SQLSelect;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,6 +86,36 @@ class Member_GroupSet extends ManyManyList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function removeAll()
|
||||||
|
{
|
||||||
|
// Remove the join to the join table to avoid MySQL row locking issues.
|
||||||
|
$query = $this->dataQuery();
|
||||||
|
$foreignFilter = $query->getQueryParam('Foreign.Filter');
|
||||||
|
$query->removeFilterOn($foreignFilter);
|
||||||
|
|
||||||
|
// Select ID column
|
||||||
|
$selectQuery = $query->query();
|
||||||
|
$dataClassIDColumn = DataObject::getSchema()->sqlColumnForField($this->dataClass(), 'ID');
|
||||||
|
$selectQuery->setSelect($dataClassIDColumn);
|
||||||
|
|
||||||
|
$from = $selectQuery->getFrom();
|
||||||
|
unset($from[$this->joinTable]);
|
||||||
|
$selectQuery->setFrom($from);
|
||||||
|
$selectQuery->setOrderBy(); // ORDER BY in subselects breaks MS SQL Server and is not necessary here
|
||||||
|
$selectQuery->setDistinct(false);
|
||||||
|
|
||||||
|
// Use a sub-query as SQLite does not support setting delete targets in
|
||||||
|
// joined queries.
|
||||||
|
$delete = new SQLDelete();
|
||||||
|
$delete->setFrom("\"{$this->joinTable}\"");
|
||||||
|
$delete->addWhere(parent::foreignIDFilter());
|
||||||
|
$subSelect = $selectQuery->sql($parameters);
|
||||||
|
$delete->addWhere(array(
|
||||||
|
"\"{$this->joinTable}\".\"{$this->localKey}\" IN ($subSelect)" => $parameters
|
||||||
|
));
|
||||||
|
$delete->execute();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the following groups IDs can be added
|
* Determine if the following groups IDs can be added
|
||||||
*
|
*
|
||||||
|
@ -25,6 +25,7 @@ use SilverStripe\ORM\FieldType\DBField;
|
|||||||
use SilverStripe\ORM\FieldType\DBHTMLText;
|
use SilverStripe\ORM\FieldType\DBHTMLText;
|
||||||
use SilverStripe\ORM\ValidationResult;
|
use SilverStripe\ORM\ValidationResult;
|
||||||
use SilverStripe\View\ArrayData;
|
use SilverStripe\View\ArrayData;
|
||||||
|
use SilverStripe\View\Requirements;
|
||||||
use SilverStripe\View\SSViewer;
|
use SilverStripe\View\SSViewer;
|
||||||
use SilverStripe\View\TemplateGlobalProvider;
|
use SilverStripe\View\TemplateGlobalProvider;
|
||||||
|
|
||||||
@ -491,6 +492,7 @@ class Security extends Controller implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public function ping()
|
public function ping()
|
||||||
{
|
{
|
||||||
|
Requirements::clear();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,5 +61,16 @@ EOS
|
|||||||
,
|
,
|
||||||
$view->debugVariable(new ObjectWithDebug(), $this->caller)
|
$view->debugVariable(new ObjectWithDebug(), $this->caller)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
<<<EOS
|
||||||
|
Debug (CLIDebugViewTest.php:17 - SilverStripe\\Dev\\Tests\\CLIDebugViewTest::setUp())
|
||||||
|
SilverStripe\\Dev\\Tests\\DebugViewTest\\ObjectWithDebug
|
||||||
|
|
||||||
|
|
||||||
|
EOS
|
||||||
|
,
|
||||||
|
$view->debugVariable(ObjectWithDebug::class, $this->caller)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,36 +5,70 @@ namespace SilverStripe\ORM\Tests;
|
|||||||
use SilverStripe\ORM\DB;
|
use SilverStripe\ORM\DB;
|
||||||
use SilverStripe\ORM\DataObject;
|
use SilverStripe\ORM\DataObject;
|
||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
|
use SilverStripe\ORM\Tests\TransactionTest\TestObject;
|
||||||
|
|
||||||
class TransactionTest extends SapphireTest
|
class TransactionTest extends SapphireTest
|
||||||
{
|
{
|
||||||
|
protected $usesDatabase = true;
|
||||||
|
|
||||||
protected static $extra_dataobjects = array(
|
protected static $extra_dataobjects = [
|
||||||
TransactionTest\TestObject::class
|
TransactionTest\TestObject::class,
|
||||||
);
|
];
|
||||||
|
|
||||||
|
public static function setUpBeforeClass()
|
||||||
|
{
|
||||||
|
parent::setUpBeforeClass();
|
||||||
|
if (!DB::get_conn()->supportsTransactions()) {
|
||||||
|
static::markTestSkipped('Current database does not support transactions');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNestedTransaction()
|
||||||
|
{
|
||||||
|
$this->assertCount(0, TestObject::get());
|
||||||
|
try {
|
||||||
|
DB::get_conn()->withTransaction(function () {
|
||||||
|
$obj = TransactionTest\TestObject::create();
|
||||||
|
$obj->Title = 'Test';
|
||||||
|
$obj->write();
|
||||||
|
|
||||||
|
$this->assertCount(1, TestObject::get());
|
||||||
|
|
||||||
|
DB::get_conn()->withTransaction(function () {
|
||||||
|
$obj = TransactionTest\TestObject::create();
|
||||||
|
$obj->Title = 'Test2';
|
||||||
|
$obj->write();
|
||||||
|
$this->assertCount(2, TestObject::get());
|
||||||
|
});
|
||||||
|
|
||||||
|
throw new \Exception('roll back transaction');
|
||||||
|
});
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->assertEquals('roll back transaction', $e->getMessage());
|
||||||
|
}
|
||||||
|
$this->assertCount(0, TestObject::get());
|
||||||
|
}
|
||||||
|
|
||||||
public function testCreateWithTransaction()
|
public function testCreateWithTransaction()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (DB::get_conn()->supportsTransactions()==true) {
|
|
||||||
DB::get_conn()->transactionStart();
|
DB::get_conn()->transactionStart();
|
||||||
$obj=new TransactionTest\TestObject();
|
$obj = new TransactionTest\TestObject();
|
||||||
$obj->Title='First page';
|
$obj->Title = 'First page';
|
||||||
$obj->write();
|
$obj->write();
|
||||||
|
|
||||||
$obj=new TransactionTest\TestObject();
|
$obj = new TransactionTest\TestObject();
|
||||||
$obj->Title='Second page';
|
$obj->Title = 'Second page';
|
||||||
$obj->write();
|
$obj->write();
|
||||||
|
|
||||||
//Create a savepoint here:
|
//Create a savepoint here:
|
||||||
DB::get_conn()->transactionSavepoint('rollback');
|
DB::get_conn()->transactionSavepoint('rollback');
|
||||||
|
|
||||||
$obj=new TransactionTest\TestObject();
|
$obj = new TransactionTest\TestObject();
|
||||||
$obj->Title='Third page';
|
$obj->Title = 'Third page';
|
||||||
$obj->write();
|
$obj->write();
|
||||||
|
|
||||||
$obj=new TransactionTest\TestObject();
|
$obj = new TransactionTest\TestObject();
|
||||||
$obj->Title='Fourth page';
|
$obj->Title = 'Fourth page';
|
||||||
$obj->write();
|
$obj->write();
|
||||||
|
|
||||||
//Revert to a savepoint:
|
//Revert to a savepoint:
|
||||||
@ -42,10 +76,10 @@ class TransactionTest extends SapphireTest
|
|||||||
|
|
||||||
DB::get_conn()->transactionEnd();
|
DB::get_conn()->transactionEnd();
|
||||||
|
|
||||||
$first=DataObject::get(TransactionTest\TestObject::class, "\"Title\"='First page'");
|
$first = DataObject::get(TransactionTest\TestObject::class, "\"Title\"='First page'");
|
||||||
$second=DataObject::get(TransactionTest\TestObject::class, "\"Title\"='Second page'");
|
$second = DataObject::get(TransactionTest\TestObject::class, "\"Title\"='Second page'");
|
||||||
$third=DataObject::get(TransactionTest\TestObject::class, "\"Title\"='Third page'");
|
$third = DataObject::get(TransactionTest\TestObject::class, "\"Title\"='Third page'");
|
||||||
$fourth=DataObject::get(TransactionTest\TestObject::class, "\"Title\"='Fourth page'");
|
$fourth = DataObject::get(TransactionTest\TestObject::class, "\"Title\"='Fourth page'");
|
||||||
|
|
||||||
//These pages should be in the system
|
//These pages should be in the system
|
||||||
$this->assertTrue(is_object($first) && $first->exists());
|
$this->assertTrue(is_object($first) && $first->exists());
|
||||||
@ -54,8 +88,5 @@ class TransactionTest extends SapphireTest
|
|||||||
//These pages should NOT exist, we reverted to a savepoint:
|
//These pages should NOT exist, we reverted to a savepoint:
|
||||||
$this->assertFalse(is_object($third) && $third->exists());
|
$this->assertFalse(is_object($third) && $third->exists());
|
||||||
$this->assertFalse(is_object($fourth) && $fourth->exists());
|
$this->assertFalse(is_object($fourth) && $fourth->exists());
|
||||||
} else {
|
|
||||||
$this->markTestSkipped('Current database does not support transactions');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -411,6 +411,35 @@ class MemberTest extends FunctionalTest
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assertions to check that Member_GroupSet is functionally equivalent to ManyManyList
|
||||||
|
*/
|
||||||
|
public function testRemoveGroups()
|
||||||
|
{
|
||||||
|
$staffmember = $this->objFromFixture(Member::class, 'staffmember');
|
||||||
|
|
||||||
|
$staffgroup = $this->objFromFixture(Group::class, 'staffgroup');
|
||||||
|
$managementgroup = $this->objFromFixture(Group::class, 'managementgroup');
|
||||||
|
|
||||||
|
$this->assertTrue(
|
||||||
|
$staffmember->inGroups(array($staffgroup, $managementgroup)),
|
||||||
|
'inGroups() succeeds if a membership is detected on one of many passed groups'
|
||||||
|
);
|
||||||
|
|
||||||
|
$staffmember->Groups()->remove($managementgroup);
|
||||||
|
$this->assertFalse(
|
||||||
|
$staffmember->inGroup($managementgroup),
|
||||||
|
'member was not removed from group using ->Groups()->remove()'
|
||||||
|
);
|
||||||
|
|
||||||
|
$staffmember->Groups()->removeAll();
|
||||||
|
$this->assertCount(
|
||||||
|
0,
|
||||||
|
$staffmember->Groups(),
|
||||||
|
'member was not removed from all groups using ->Groups()->removeAll()'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testAddToGroupByCode()
|
public function testAddToGroupByCode()
|
||||||
{
|
{
|
||||||
/** @var Member $grouplessMember */
|
/** @var Member $grouplessMember */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user