mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge branch '5.0' into 5
This commit is contained in:
commit
f54bbc50f0
@ -412,7 +412,10 @@ class CanonicalURLMiddleware implements HTTPMiddleware
|
|||||||
$paths = (array) $this->getEnforceTrailingSlashConfigIgnorePaths();
|
$paths = (array) $this->getEnforceTrailingSlashConfigIgnorePaths();
|
||||||
if (!empty($paths)) {
|
if (!empty($paths)) {
|
||||||
foreach ($paths as $path) {
|
foreach ($paths as $path) {
|
||||||
if (str_starts_with(trim($path, '/'), trim($requestPath, '/'))) {
|
if (str_starts_with(
|
||||||
|
$this->trailingSlashForComparison($requestPath),
|
||||||
|
$this->trailingSlashForComparison($path)
|
||||||
|
)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -439,6 +442,15 @@ class CanonicalURLMiddleware implements HTTPMiddleware
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure a string has a trailing slash to that we can use str_starts_with and compare
|
||||||
|
* paths like admin/ with administration/ and get a correct result.
|
||||||
|
*/
|
||||||
|
private function trailingSlashForComparison(string $path): string
|
||||||
|
{
|
||||||
|
return trim($path, '/') . '/';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
|
@ -3,12 +3,11 @@
|
|||||||
namespace SilverStripe\Core\Cache;
|
namespace SilverStripe\Core\Cache;
|
||||||
|
|
||||||
use SilverStripe\Core\Injector\Injector;
|
use SilverStripe\Core\Injector\Injector;
|
||||||
use Symfony\Component\Cache\Simple\ApcuCache;
|
use Symfony\Component\Cache\Adapter\ApcuAdapter;
|
||||||
use Memcached;
|
use Symfony\Component\Cache\Psr16Cache;
|
||||||
|
|
||||||
class ApcuCacheFactory implements CacheFactory
|
class ApcuCacheFactory implements CacheFactory
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
@ -31,10 +30,11 @@ class ApcuCacheFactory implements CacheFactory
|
|||||||
? $params['namespace'] . '_' . md5(BASE_PATH)
|
? $params['namespace'] . '_' . md5(BASE_PATH)
|
||||||
: md5(BASE_PATH);
|
: md5(BASE_PATH);
|
||||||
$defaultLifetime = isset($params['defaultLifetime']) ? $params['defaultLifetime'] : 0;
|
$defaultLifetime = isset($params['defaultLifetime']) ? $params['defaultLifetime'] : 0;
|
||||||
return Injector::inst()->createWithArgs(ApcuCache::class, [
|
$psr6Cache = Injector::inst()->createWithArgs(ApcuAdapter::class, [
|
||||||
$namespace,
|
$namespace,
|
||||||
$defaultLifetime,
|
$defaultLifetime,
|
||||||
$this->version
|
$this->version
|
||||||
]);
|
]);
|
||||||
|
return Injector::inst()->createWithArgs(Psr16Cache::class, [$psr6Cache]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
namespace SilverStripe\Core\Cache;
|
namespace SilverStripe\Core\Cache;
|
||||||
|
|
||||||
use SilverStripe\Core\Injector\Injector;
|
use SilverStripe\Core\Injector\Injector;
|
||||||
use Symfony\Component\Cache\Simple\MemcachedCache;
|
use Symfony\Component\Cache\Adapter\MemcachedAdapter;
|
||||||
|
use Symfony\Component\Cache\Psr16Cache;
|
||||||
use Memcached;
|
use Memcached;
|
||||||
|
|
||||||
class MemcachedCacheFactory implements CacheFactory
|
class MemcachedCacheFactory implements CacheFactory
|
||||||
@ -31,10 +32,11 @@ class MemcachedCacheFactory implements CacheFactory
|
|||||||
? $params['namespace'] . '_' . md5(BASE_PATH)
|
? $params['namespace'] . '_' . md5(BASE_PATH)
|
||||||
: md5(BASE_PATH);
|
: md5(BASE_PATH);
|
||||||
$defaultLifetime = isset($params['defaultLifetime']) ? $params['defaultLifetime'] : 0;
|
$defaultLifetime = isset($params['defaultLifetime']) ? $params['defaultLifetime'] : 0;
|
||||||
return Injector::inst()->createWithArgs(MemcachedCache::class, [
|
$psr6Cache = Injector::inst()->createWithArgs(MemcachedAdapter::class, [
|
||||||
$this->memcachedClient,
|
$this->memcachedClient,
|
||||||
$namespace,
|
$namespace,
|
||||||
$defaultLifetime
|
$defaultLifetime
|
||||||
]);
|
]);
|
||||||
|
return Injector::inst()->createWithArgs(Psr16Cache::class, [$psr6Cache]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ use SilverStripe\Control\HTTPResponse_Exception;
|
|||||||
use SilverStripe\Dev\Install\DatabaseAdapterRegistry;
|
use SilverStripe\Dev\Install\DatabaseAdapterRegistry;
|
||||||
use SilverStripe\ORM\DB;
|
use SilverStripe\ORM\DB;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use LogicException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple Kernel container
|
* Simple Kernel container
|
||||||
@ -112,6 +113,29 @@ class CoreKernel extends BaseKernel
|
|||||||
"password" => Environment::getEnv('SS_DATABASE_PASSWORD') ?: null,
|
"password" => Environment::getEnv('SS_DATABASE_PASSWORD') ?: null,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Only add SSL keys in the array if there is an actual value associated with them
|
||||||
|
$sslConf = [
|
||||||
|
'ssl_key' => 'SS_DATABASE_SSL_KEY',
|
||||||
|
'ssl_cert' => 'SS_DATABASE_SSL_CERT',
|
||||||
|
'ssl_ca' => 'SS_DATABASE_SSL_CA',
|
||||||
|
'ssl_cipher' => 'SS_DATABASE_SSL_CIPHER',
|
||||||
|
];
|
||||||
|
foreach ($sslConf as $key => $envVar) {
|
||||||
|
$envValue = Environment::getEnv($envVar);
|
||||||
|
if ($envValue) {
|
||||||
|
$databaseConfig[$key] = $envValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Having only the key or cert without the other is bad configuration.
|
||||||
|
if ((isset($databaseConfig['ssl_key']) && !isset($databaseConfig['ssl_cert']))
|
||||||
|
|| (!isset($databaseConfig['ssl_key']) && isset($databaseConfig['ssl_cert']))
|
||||||
|
) {
|
||||||
|
user_error('Database SSL cert and key must both be defined to use SSL in the database.', E_USER_WARNING);
|
||||||
|
unset($databaseConfig['ssl_key']);
|
||||||
|
unset($databaseConfig['ssl_cert']);
|
||||||
|
}
|
||||||
|
|
||||||
// Set the port if called for
|
// Set the port if called for
|
||||||
$dbPort = Environment::getEnv('SS_DATABASE_PORT');
|
$dbPort = Environment::getEnv('SS_DATABASE_PORT');
|
||||||
if ($dbPort) {
|
if ($dbPort) {
|
||||||
|
@ -32,15 +32,15 @@ class MySQLDatabaseConfigurationHelper implements DatabaseConfigurationHelper
|
|||||||
case 'MySQLDatabase':
|
case 'MySQLDatabase':
|
||||||
$conn = mysqli_init();
|
$conn = mysqli_init();
|
||||||
|
|
||||||
// Set SSL parameters if they exist. All parameters are required.
|
// Set SSL parameters if they exist.
|
||||||
if (array_key_exists('ssl_key', $databaseConfig) &&
|
// Must have both the SSL cert and key, or the common authority, or preferably all three.
|
||||||
array_key_exists('ssl_cert', $databaseConfig) &&
|
if ((array_key_exists('ssl_key', $databaseConfig) && array_key_exists('ssl_cert', $databaseConfig))
|
||||||
array_key_exists('ssl_ca', $databaseConfig)
|
|| array_key_exists('ssl_ca', $databaseConfig)
|
||||||
) {
|
) {
|
||||||
$conn->ssl_set(
|
$conn->ssl_set(
|
||||||
$databaseConfig['ssl_key'],
|
$databaseConfig['ssl_key'] ?? null,
|
||||||
$databaseConfig['ssl_cert'],
|
$databaseConfig['ssl_cert'] ?? null,
|
||||||
$databaseConfig['ssl_ca'],
|
$databaseConfig['ssl_ca'] ?? null,
|
||||||
dirname($databaseConfig['ssl_ca']),
|
dirname($databaseConfig['ssl_ca']),
|
||||||
array_key_exists('ssl_cipher', $databaseConfig)
|
array_key_exists('ssl_cipher', $databaseConfig)
|
||||||
? $databaseConfig['ssl_cipher']
|
? $databaseConfig['ssl_cipher']
|
||||||
|
@ -1617,7 +1617,9 @@ class Form extends ViewableData implements HasRequestHandler
|
|||||||
public function defaultAction()
|
public function defaultAction()
|
||||||
{
|
{
|
||||||
if ($this->hasDefaultAction && $this->actions) {
|
if ($this->hasDefaultAction && $this->actions) {
|
||||||
return $this->actions->first();
|
return $this->actions->flattenFields()->filterByCallback(function ($field) {
|
||||||
|
return $field instanceof FormAction;
|
||||||
|
})->first();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ use LogicException;
|
|||||||
use SilverStripe\Admin\LeftAndMain;
|
use SilverStripe\Admin\LeftAndMain;
|
||||||
use SilverStripe\Control\Controller;
|
use SilverStripe\Control\Controller;
|
||||||
use SilverStripe\Control\HTTPResponse;
|
use SilverStripe\Control\HTTPResponse;
|
||||||
|
use SilverStripe\Core\ClassInfo;
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
use SilverStripe\Forms\Form;
|
use SilverStripe\Forms\Form;
|
||||||
use SilverStripe\Forms\Schema\FormSchema;
|
use SilverStripe\Forms\Schema\FormSchema;
|
||||||
@ -203,9 +204,13 @@ class GridFieldFilterHeader extends AbstractGridFieldComponent implements GridFi
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$modelClass = $gridField->getModelClass();
|
$modelClass = $gridField->getModelClass();
|
||||||
|
$singleton = singleton($modelClass);
|
||||||
|
if (ClassInfo::hasMethod($singleton, 'summaryFields')
|
||||||
|
&& ClassInfo::hasMethod($singleton, 'searchableFields')
|
||||||
|
) {
|
||||||
// note: searchableFields() will return summary_fields if there are no searchable_fields on the model
|
// note: searchableFields() will return summary_fields if there are no searchable_fields on the model
|
||||||
$searchableFields = array_keys($modelClass::singleton()->searchableFields());
|
$searchableFields = array_keys($singleton->searchableFields());
|
||||||
$summaryFields = array_keys($modelClass::singleton()->summaryFields());
|
$summaryFields = array_keys($singleton->summaryFields());
|
||||||
sort($searchableFields);
|
sort($searchableFields);
|
||||||
sort($summaryFields);
|
sort($summaryFields);
|
||||||
// searchable_fields has been explictily defined i.e. searchableFields() is not falling back to summary_fields
|
// searchable_fields has been explictily defined i.e. searchableFields() is not falling back to summary_fields
|
||||||
@ -218,6 +223,18 @@ class GridFieldFilterHeader extends AbstractGridFieldComponent implements GridFi
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Allows non-DataObject classes to be used with this component
|
||||||
|
$columns = $gridField->getColumns();
|
||||||
|
foreach ($columns as $columnField) {
|
||||||
|
$metadata = $gridField->getColumnMetadata($columnField);
|
||||||
|
$title = $metadata['title'];
|
||||||
|
|
||||||
|
if ($title && $list->canFilterBy($columnField)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,14 +96,15 @@ class MySQLiConnector extends DBConnector
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set SSL parameters if they exist. All parameters are required.
|
// Set SSL parameters if they exist.
|
||||||
if (array_key_exists('ssl_key', $parameters ?? []) &&
|
// Must have both the SSL cert and key, or the common authority, or preferably all three.
|
||||||
array_key_exists('ssl_cert', $parameters ?? []) &&
|
if ((array_key_exists('ssl_key', $parameters ?? []) && array_key_exists('ssl_cert', $parameters ?? []))
|
||||||
array_key_exists('ssl_ca', $parameters ?? [])) {
|
|| array_key_exists('ssl_ca', $parameters ?? [])
|
||||||
|
) {
|
||||||
$this->dbConn->ssl_set(
|
$this->dbConn->ssl_set(
|
||||||
$parameters['ssl_key'],
|
$parameters['ssl_key'] ?? null,
|
||||||
$parameters['ssl_cert'],
|
$parameters['ssl_cert'] ?? null,
|
||||||
$parameters['ssl_ca'],
|
$parameters['ssl_ca'] ?? null,
|
||||||
dirname($parameters['ssl_ca'] ?? ''),
|
dirname($parameters['ssl_ca'] ?? ''),
|
||||||
array_key_exists('ssl_cipher', $parameters ?? [])
|
array_key_exists('ssl_cipher', $parameters ?? [])
|
||||||
? $parameters['ssl_cipher']
|
? $parameters['ssl_cipher']
|
||||||
|
@ -26,8 +26,6 @@ class SSViewer_BasicIteratorSupport implements TemplateIteratorProvider
|
|||||||
return [
|
return [
|
||||||
'IsFirst',
|
'IsFirst',
|
||||||
'IsLast',
|
'IsLast',
|
||||||
'First',
|
|
||||||
'Last',
|
|
||||||
'FirstLast',
|
'FirstLast',
|
||||||
'Middle',
|
'Middle',
|
||||||
'MiddleString',
|
'MiddleString',
|
||||||
|
@ -85,63 +85,42 @@ class CanonicalURLMiddlewareTest extends SapphireTest
|
|||||||
$this->assertFalse($middleware->getForceBasicAuthToSSL(), 'Explicitly set is returned');
|
$this->assertFalse($middleware->getForceBasicAuthToSSL(), 'Explicitly set is returned');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRedirectTrailingSlash()
|
public function provideRedirectTrailingSlash()
|
||||||
{
|
{
|
||||||
$testScenarios = [
|
$testScenarios = [];
|
||||||
[
|
foreach ([true, false] as $forceRedirect) {
|
||||||
'forceRedirect' => true,
|
foreach ([true, false] as $addTrailingSlash) {
|
||||||
'addTrailingSlash' => true,
|
foreach ([true, false] as $requestHasSlash) {
|
||||||
'requestHasSlash' => true,
|
$testScenarios[] = [
|
||||||
],
|
$forceRedirect,
|
||||||
[
|
$addTrailingSlash,
|
||||||
'forceRedirect' => true,
|
$requestHasSlash,
|
||||||
'addTrailingSlash' => true,
|
|
||||||
'requestHasSlash' => false,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'forceRedirect' => true,
|
|
||||||
'addTrailingSlash' => false,
|
|
||||||
'requestHasSlash' => true,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'forceRedirect' => true,
|
|
||||||
'addTrailingSlash' => false,
|
|
||||||
'requestHasSlash' => false,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'forceRedirect' => false,
|
|
||||||
'addTrailingSlash' => true,
|
|
||||||
'requestHasSlash' => true,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'forceRedirect' => false,
|
|
||||||
'addTrailingSlash' => true,
|
|
||||||
'requestHasSlash' => false,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'forceRedirect' => false,
|
|
||||||
'addTrailingSlash' => false,
|
|
||||||
'requestHasSlash' => true,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'forceRedirect' => false,
|
|
||||||
'addTrailingSlash' => false,
|
|
||||||
'requestHasSlash' => false,
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
foreach ($testScenarios as $scenario) {
|
}
|
||||||
$forceRedirect = $scenario['forceRedirect'];
|
}
|
||||||
$addTrailingSlash = $scenario['addTrailingSlash'];
|
}
|
||||||
$requestHasSlash = $scenario['requestHasSlash'];
|
return $testScenarios;
|
||||||
|
}
|
||||||
|
|
||||||
$middleware = $this->getMockedMiddleware(false);
|
/**
|
||||||
|
* @dataProvider provideRedirectTrailingSlash
|
||||||
$middleware->setEnforceTrailingSlashConfig($forceRedirect);
|
*/
|
||||||
|
public function testRedirectTrailingSlash(bool $forceRedirect, bool $addTrailingSlash, bool $requestHasSlash)
|
||||||
|
{
|
||||||
Controller::config()->set('add_trailing_slash', $addTrailingSlash);
|
Controller::config()->set('add_trailing_slash', $addTrailingSlash);
|
||||||
|
|
||||||
|
$noRedirect = !$forceRedirect || ($addTrailingSlash && $requestHasSlash) || (!$addTrailingSlash && !$requestHasSlash);
|
||||||
|
$middleware = $this->getMockedMiddleware(false);
|
||||||
|
$middleware->setEnforceTrailingSlashConfig($forceRedirect);
|
||||||
|
|
||||||
$requestSlash = $requestHasSlash ? '/' : '';
|
$requestSlash = $requestHasSlash ? '/' : '';
|
||||||
$requestURL = "/about-us{$requestSlash}";
|
$requestURL = "/about-us{$requestSlash}";
|
||||||
|
|
||||||
|
$this->performRedirectTest($requestURL, $middleware, !$noRedirect, $addTrailingSlash);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function performRedirectTest(string $requestURL, CanonicalURLMiddleware $middleware, bool $shouldRedirect, bool $addTrailingSlash)
|
||||||
|
{
|
||||||
Environment::setEnv('REQUEST_URI', $requestURL);
|
Environment::setEnv('REQUEST_URI', $requestURL);
|
||||||
$request = new HTTPRequest('GET', $requestURL);
|
$request = new HTTPRequest('GET', $requestURL);
|
||||||
$request->setScheme('https');
|
$request->setScheme('https');
|
||||||
@ -153,8 +132,7 @@ class CanonicalURLMiddlewareTest extends SapphireTest
|
|||||||
return $mockResponse;
|
return $mockResponse;
|
||||||
});
|
});
|
||||||
|
|
||||||
$noRedirect = !$forceRedirect || ($addTrailingSlash && $requestHasSlash) || (!$addTrailingSlash && !$requestHasSlash);
|
if (!$shouldRedirect) {
|
||||||
if ($noRedirect) {
|
|
||||||
$this->assertNull($result->getHeader('Location'), 'No location header should be added');
|
$this->assertNull($result->getHeader('Location'), 'No location header should be added');
|
||||||
$this->assertEquals(200, $result->getStatusCode(), 'No redirection should be made');
|
$this->assertEquals(200, $result->getStatusCode(), 'No redirection should be made');
|
||||||
} else {
|
} else {
|
||||||
@ -166,6 +144,56 @@ class CanonicalURLMiddlewareTest extends SapphireTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function provideRedirectTrailingSlashIgnorePaths()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
'addTrailingSlash' => false,
|
||||||
|
'requestHasSlash' => false,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'addTrailingSlash' => false,
|
||||||
|
'requestHasSlash' => true,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'addTrailingSlash' => true,
|
||||||
|
'requestHasSlash' => true,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'addTrailingSlash' => true,
|
||||||
|
'requestHasSlash' => false,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideRedirectTrailingSlashIgnorePaths
|
||||||
|
*/
|
||||||
|
public function testRedirectTrailingSlashIgnorePaths(bool $addTrailingSlash, bool $requestHasSlash)
|
||||||
|
{
|
||||||
|
Controller::config()->set('add_trailing_slash', $addTrailingSlash);
|
||||||
|
|
||||||
|
$middleware = $this->getMockedMiddleware(false);
|
||||||
|
$middleware->setEnforceTrailingSlashConfig(true);
|
||||||
|
|
||||||
|
$requestSlash = $requestHasSlash ? '/' : '';
|
||||||
|
$noRedirectPaths = [
|
||||||
|
"/admin{$requestSlash}",
|
||||||
|
"/admin/graphql{$requestSlash}",
|
||||||
|
"/dev/tasks/my-task{$requestSlash}",
|
||||||
|
];
|
||||||
|
$allowRedirectPaths = [
|
||||||
|
"/administration{$requestSlash}",
|
||||||
|
"/administration/more-path{$requestSlash}",
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($noRedirectPaths as $path) {
|
||||||
|
$this->performRedirectTest($path, $middleware, false, $addTrailingSlash);
|
||||||
|
}
|
||||||
|
foreach ($allowRedirectPaths as $path) {
|
||||||
|
$this->performRedirectTest($path, $middleware, $addTrailingSlash !== $requestHasSlash, $addTrailingSlash);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getMockedMiddleware($mockGetRedirect = true): CanonicalURLMiddleware
|
private function getMockedMiddleware($mockGetRedirect = true): CanonicalURLMiddleware
|
||||||
|
@ -2,14 +2,17 @@
|
|||||||
|
|
||||||
namespace SilverStripe\Core\Tests\Cache;
|
namespace SilverStripe\Core\Tests\Cache;
|
||||||
|
|
||||||
|
use Behat\Gherkin\Cache\MemoryCache;
|
||||||
use Psr\SimpleCache\CacheInterface;
|
use Psr\SimpleCache\CacheInterface;
|
||||||
use SilverStripe\Core\Cache\ApcuCacheFactory;
|
use SilverStripe\Core\Cache\ApcuCacheFactory;
|
||||||
use SilverStripe\Core\Cache\MemcachedCacheFactory;
|
use SilverStripe\Core\Cache\MemcachedCacheFactory;
|
||||||
use SilverStripe\Core\Injector\Injector;
|
use SilverStripe\Core\Injector\Injector;
|
||||||
use SilverStripe\Core\Tests\Cache\CacheTest\MockCache;
|
use SilverStripe\Core\Tests\Cache\CacheTest\MockCache;
|
||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
use Symfony\Component\Cache\Simple\ApcuCache;
|
use Symfony\Component\Cache\Psr16Cache;
|
||||||
use Symfony\Component\Cache\Simple\MemcachedCache;
|
use Symfony\Component\Cache\Adapter\ApcuAdapter;
|
||||||
|
use Symfony\Component\Cache\Adapter\MemcachedAdapter;
|
||||||
|
use Memcached;
|
||||||
|
|
||||||
class CacheTest extends SapphireTest
|
class CacheTest extends SapphireTest
|
||||||
{
|
{
|
||||||
@ -22,7 +25,10 @@ class CacheTest extends SapphireTest
|
|||||||
ApcuCacheFactory::class => [
|
ApcuCacheFactory::class => [
|
||||||
'constructor' => [ 'version' => 'ss40test' ]
|
'constructor' => [ 'version' => 'ss40test' ]
|
||||||
],
|
],
|
||||||
MemcachedCacheFactory::class => MemcachedCacheFactory::class,
|
'MemcachedClient' => Memcached::class,
|
||||||
|
MemcachedCacheFactory::class => [
|
||||||
|
'constructor' => [ 'memcachedClient' => '%$MemcachedClient' ]
|
||||||
|
],
|
||||||
CacheInterface::class . '.TestApcuCache' => [
|
CacheInterface::class . '.TestApcuCache' => [
|
||||||
'factory' => ApcuCacheFactory::class,
|
'factory' => ApcuCacheFactory::class,
|
||||||
'constructor' => [
|
'constructor' => [
|
||||||
@ -37,42 +43,42 @@ class CacheTest extends SapphireTest
|
|||||||
'defaultLifetime' => 5600,
|
'defaultLifetime' => 5600,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
ApcuCache::class => MockCache::class,
|
Psr16Cache::class => MockCache::class,
|
||||||
MemcachedCache::class => MockCache::class,
|
ApcuAdapter::class => MockCache::class,
|
||||||
|
MemcachedAdapter::class => MockCache::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testApcuCacheFactory()
|
public function testApcuCacheFactory()
|
||||||
{
|
{
|
||||||
$cache = Injector::inst()->get(CacheInterface::class . '.TestApcuCache');
|
$psr16Cache = Injector::inst()->get(CacheInterface::class . '.TestApcuCache');
|
||||||
$this->assertInstanceOf(
|
$this->assertInstanceOf(MockCache::class, $psr16Cache);
|
||||||
MockCache::class,
|
$this->assertEquals(MockCache::class, get_class($psr16Cache->getArgs()[0]));
|
||||||
$cache
|
|
||||||
);
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
[
|
[
|
||||||
'TestApcuCache_' . md5(BASE_PATH),
|
'TestApcuCache_' . md5(BASE_PATH),
|
||||||
2600,
|
2600,
|
||||||
'ss40test'
|
'ss40test'
|
||||||
],
|
],
|
||||||
$cache->getArgs()
|
$psr16Cache->getArgs()[0]->getArgs()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMemCacheFactory()
|
public function testMemCacheFactory()
|
||||||
{
|
{
|
||||||
$cache = Injector::inst()->get(CacheInterface::class . '.TestMemcache');
|
if (!class_exists(Memcached::class)) {
|
||||||
$this->assertInstanceOf(
|
$this->markTestSkipped('Memcached is not installed');
|
||||||
MockCache::class,
|
}
|
||||||
$cache
|
$psr16Cache = Injector::inst()->get(CacheInterface::class . '.TestMemcache');
|
||||||
);
|
$this->assertInstanceOf(MockCache::class, $psr16Cache);
|
||||||
|
$this->assertEquals(MockCache::class, get_class($psr16Cache->getArgs()[0]));
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
[
|
[
|
||||||
null,
|
new MemCached(),
|
||||||
'TestMemCache_' . md5(BASE_PATH),
|
'TestMemCache_' . md5(BASE_PATH),
|
||||||
5600
|
5600
|
||||||
],
|
],
|
||||||
$cache->getArgs()
|
$psr16Cache->getArgs()[0]->getArgs()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ use SilverStripe\Control\HTTPRequest;
|
|||||||
use SilverStripe\Control\Session;
|
use SilverStripe\Control\Session;
|
||||||
use SilverStripe\Dev\CSSContentParser;
|
use SilverStripe\Dev\CSSContentParser;
|
||||||
use SilverStripe\Dev\FunctionalTest;
|
use SilverStripe\Dev\FunctionalTest;
|
||||||
|
use SilverStripe\Forms\CompositeField;
|
||||||
use SilverStripe\Forms\DateField;
|
use SilverStripe\Forms\DateField;
|
||||||
use SilverStripe\Forms\DatetimeField;
|
use SilverStripe\Forms\DatetimeField;
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
@ -23,7 +24,6 @@ use SilverStripe\Forms\Tests\FormTest\ControllerWithStrictPostCheck;
|
|||||||
use SilverStripe\Forms\Tests\FormTest\Player;
|
use SilverStripe\Forms\Tests\FormTest\Player;
|
||||||
use SilverStripe\Forms\Tests\FormTest\Team;
|
use SilverStripe\Forms\Tests\FormTest\Team;
|
||||||
use SilverStripe\Forms\Tests\FormTest\TestController;
|
use SilverStripe\Forms\Tests\FormTest\TestController;
|
||||||
use SilverStripe\Forms\Tests\ValidatorTest\TestValidator;
|
|
||||||
use SilverStripe\Forms\TextareaField;
|
use SilverStripe\Forms\TextareaField;
|
||||||
use SilverStripe\Forms\TextField;
|
use SilverStripe\Forms\TextField;
|
||||||
use SilverStripe\Forms\TimeField;
|
use SilverStripe\Forms\TimeField;
|
||||||
@ -345,6 +345,23 @@ class FormTest extends FunctionalTest
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDefaultAction()
|
||||||
|
{
|
||||||
|
$form = Form::create(Controller::curr(), 'Form', new FieldList(), new FieldList(
|
||||||
|
new FormAction('doForm', 'Form Action')
|
||||||
|
));
|
||||||
|
$this->assertNotNull($form->defaultAction());
|
||||||
|
$this->assertEquals('action_doForm', $form->defaultAction()->getName());
|
||||||
|
|
||||||
|
$form = Form::create(Controller::curr(), 'AnotherForm', new FieldList(), new FieldList(
|
||||||
|
new CompositeField(
|
||||||
|
new FormAction('doAnotherForm', 'Another Form Action')
|
||||||
|
)
|
||||||
|
));
|
||||||
|
$this->assertNotNull($form->defaultAction());
|
||||||
|
$this->assertEquals('action_doAnotherForm', $form->defaultAction()->getName());
|
||||||
|
}
|
||||||
|
|
||||||
public function testLoadDataFromIgnoreFalseish()
|
public function testLoadDataFromIgnoreFalseish()
|
||||||
{
|
{
|
||||||
$form = new Form(
|
$form = new Form(
|
||||||
|
@ -8,13 +8,16 @@ use SilverStripe\Dev\SapphireTest;
|
|||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
use SilverStripe\Forms\Form;
|
use SilverStripe\Forms\Form;
|
||||||
use SilverStripe\Forms\GridField\GridField;
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldConfig;
|
||||||
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
|
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
|
||||||
use SilverStripe\Forms\GridField\GridFieldFilterHeader;
|
use SilverStripe\Forms\GridField\GridFieldFilterHeader;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\Cheerleader;
|
use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\Cheerleader;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\CheerleaderHat;
|
use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\CheerleaderHat;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\Mom;
|
use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\Mom;
|
||||||
|
use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\NonDataObject;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\Team;
|
use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\Team;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\TeamGroup;
|
use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\TeamGroup;
|
||||||
|
use SilverStripe\ORM\ArrayList;
|
||||||
use SilverStripe\ORM\DataList;
|
use SilverStripe\ORM\DataList;
|
||||||
use SilverStripe\ORM\DataObject;
|
use SilverStripe\ORM\DataObject;
|
||||||
|
|
||||||
@ -194,4 +197,33 @@ class GridFieldFilterHeaderTest extends SapphireTest
|
|||||||
Config::modify()->set(Team::class, 'summary_fields', ['MySummaryField']);
|
Config::modify()->set(Team::class, 'summary_fields', ['MySummaryField']);
|
||||||
$this->assertFalse($filterHeader->canFilterAnyColumns($gridField));
|
$this->assertFalse($filterHeader->canFilterAnyColumns($gridField));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCanFilterAnyColumnsNonDataObject()
|
||||||
|
{
|
||||||
|
$list = new ArrayList([
|
||||||
|
new NonDataObject([]),
|
||||||
|
]);
|
||||||
|
$config = GridFieldConfig::create()->addComponent(new GridFieldFilterHeader());
|
||||||
|
$gridField = new GridField('testfield', 'testfield', $list, $config);
|
||||||
|
$form = new Form(null, 'Form', new FieldList([$gridField]), new FieldList());
|
||||||
|
/** @var GridFieldFilterHeader $component */
|
||||||
|
$component = $gridField->getConfig()->getComponentByType(GridFieldFilterHeader::class);
|
||||||
|
|
||||||
|
$this->assertFalse($component->canFilterAnyColumns($gridField));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRenderHeadersNonDataObject()
|
||||||
|
{
|
||||||
|
$list = new ArrayList([
|
||||||
|
new NonDataObject([]),
|
||||||
|
]);
|
||||||
|
$config = GridFieldConfig::create()->addComponent(new GridFieldFilterHeader());
|
||||||
|
$gridField = new GridField('testfield', 'testfield', $list, $config);
|
||||||
|
$form = new Form(null, 'Form', new FieldList([$gridField]), new FieldList());
|
||||||
|
/** @var GridFieldFilterHeader $component */
|
||||||
|
$component = $gridField->getConfig()->getComponentByType(GridFieldFilterHeader::class);
|
||||||
|
$htmlFragment = $component->getHTMLFragments($gridField);
|
||||||
|
|
||||||
|
$this->assertNull($htmlFragment);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
|
class NonDataObject extends ArrayData implements TestOnly
|
||||||
|
{
|
||||||
|
public function summaryFields()
|
||||||
|
{
|
||||||
|
return ['Title' => 'Title'];
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user