Merge branch '4.3' into 4

This commit is contained in:
Robbie Averill 2018-10-20 18:31:04 +02:00
commit 9ceef59e1b
10 changed files with 117 additions and 26 deletions

View File

@ -1086,7 +1086,61 @@ const transformReadNotes = (manager) => {
export default transformReadNotes;
```
Simple! The transformation passes us a `ApolloGraphQLManager` instance that provides a fluent API for updating a query definition the same way the `FormStateManager` allows us to update Redux form state. In this case, our need is really straightforward. We'l just add a new field and be done with it.
Simple! The transformation passes us a `ApolloGraphQLManager` instance that provides a fluent API for updating a query definition the same way the `FormStateManager` allows us to update Redux form state.
#### Adding fields
In the above example, we added a single field to a query. Here's how that works:
```js
manager.addField(fieldName, fieldPath = 'root')
```
The `fieldPath` argument tells the manager at what level to add the field. In this case, since the `Priority` field is going on the root query (`readNotes`), we'll use `root` as the path. But suppose we had a more complex query like this:
```
query readMembers {
FirstName
Surname
Friends {
Email
Company {
Name
}
}
}
```
If we wanted to add a field to the nested `Company` query on `Friends`, we would use a path syntax.
```js
manager.addField('Tagline', 'root/Friends/Company');
```
#### Adding field arguments
Let's suppose we had the following query:
```
query ReadMembers($ImageSize: String!) {
readMembers {
FirstName
Avatar(Size: $ImageSize)
Company {
Name
}
}
}
```
Maybe the `Company` type has a `Logo`, and we want to apply the `ImageSize` parameter as an argument to that field.
```js
manager.addArg('Size', 'ImageSize', 'root/Company/Logo');
```
Where `root/Company/Logo` is the path to the field, `Size` is the name of the argument on that field, and `ImageSize` is the name of the variable.
#### Applying the transforms

View File

@ -135,6 +135,10 @@ trait Extensible
$this->addCallbackMethod($method, function ($inst, $args) use ($method, $extensionClass) {
/** @var Extensible $inst */
$extension = $inst->getExtensionInstance($extensionClass);
if (!$extension) {
return null;
}
try {
$extension->setOwner($inst);
return call_user_func_array([$extension, $method], $args);

View File

@ -85,5 +85,6 @@ class ExtensionTestState implements TestState
public function tearDownOnce($class)
{
DataObject::flush_extra_methods_cache();
}
}

View File

@ -43,13 +43,6 @@ class TabSet extends CompositeField
*/
protected $schemaComponent = 'Tabs';
/**
* Alter datatype from structural to track the current tab in redux state.
*
* @var string
*/
protected $schemaDataType = FormField::SCHEMA_DATA_TYPE_STRING;
/**
* @var TabSet
*/

View File

@ -8,6 +8,7 @@ use SilverStripe\View\ViewableData;
use ArrayIterator;
use InvalidArgumentException;
use LogicException;
use SilverStripe\Dev\Deprecation;
/**
* A list object that wraps around an array of objects or arrays.
@ -160,7 +161,29 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
*/
public function limit($length, $offset = 0)
{
// Type checking: designed for consistency with DataList::limit()
if (!is_numeric($length) || !is_numeric($offset)) {
Deprecation::notice(
'4.3',
'Arguments to ArrayList::limit() should be numeric'
);
}
if ($length < 0 || $offset < 0) {
Deprecation::notice(
'4.3',
'Arguments to ArrayList::limit() should be positive'
);
}
if (!$length) {
if ($length === 0) {
Deprecation::notice(
'4.3',
"limit(0) is deprecated in SS4. In SS5 a limit of 0 will instead return no records."
);
}
$length = count($this->items);
}

View File

@ -73,8 +73,8 @@ class MySQLiConnector extends DBConnector
$selectedDB = ($selectDB && !empty($parameters['database'])) ? $parameters['database'] : null;
// Connection charset and collation
$connCharset = Config::inst()->get('SilverStripe\ORM\Connect\MySQLDatabase', 'connection_charset');
$connCollation = Config::inst()->get('SilverStripe\ORM\Connect\MySQLDatabase', 'connection_collation');
$connCharset = Config::inst()->get(MySQLDatabase::class, 'connection_charset');
$connCollation = Config::inst()->get(MySQLDatabase::class, 'connection_collation');
$this->dbConn = mysqli_init();
@ -186,7 +186,8 @@ class MySQLiConnector extends DBConnector
$types = '';
$values = array();
$blobs = array();
for ($index = 0; $index < count($parameters); $index++) {
$parametersCount = count($parameters);
for ($index = 0; $index < $parametersCount; $index++) {
$value = $parameters[$index];
$phpType = gettype($value);
@ -247,12 +248,13 @@ class MySQLiConnector extends DBConnector
// Because mysqli_stmt::bind_param arguments must be passed by reference
// we need to do a bit of hackery
$boundNames = [];
for ($i = 0; $i < count($parameters); $i++) {
$parametersCount = count($parameters);
for ($i = 0; $i < $parametersCount; $i++) {
$boundName = "param$i";
$$boundName = $parameters[$i];
$boundNames[] = &$$boundName;
}
call_user_func_array(array($statement, 'bind_param'), $boundNames);
$statement->bind_param(...$boundNames);
}
public function preparedQuery($sql, $parameters, $errorLevel = E_USER_ERROR)
@ -293,10 +295,10 @@ class MySQLiConnector extends DBConnector
$metaData = $statement->result_metadata();
if ($metaData) {
return new MySQLStatement($statement, $metaData);
} else {
// Replicate normal behaviour of ->query() on non-select calls
return new MySQLQuery($this, true);
}
// Replicate normal behaviour of ->query() on non-select calls
return new MySQLQuery($this, true);
}
public function selectDatabase($name)
@ -304,9 +306,9 @@ class MySQLiConnector extends DBConnector
if ($this->dbConn->select_db($name)) {
$this->databaseName = $name;
return true;
} else {
return false;
}
return false;
}
public function getSelectedDatabase()

View File

@ -106,7 +106,7 @@ class PDOConnector extends DBConnector
*/
public static function is_emulate_prepare()
{
return Config::inst()->get('SilverStripe\ORM\Connect\PDOConnector', 'emulate_prepare');
return self::config()->get('emulate_prepare');
}
public function connect($parameters, $selectDB = false)
@ -159,8 +159,8 @@ class PDOConnector extends DBConnector
}
// Connection charset and collation
$connCharset = Config::inst()->get('SilverStripe\ORM\Connect\MySQLDatabase', 'connection_charset');
$connCollation = Config::inst()->get('SilverStripe\ORM\Connect\MySQLDatabase', 'connection_collation');
$connCharset = Config::inst()->get(MySQLDatabase::class, 'connection_charset');
$connCollation = Config::inst()->get(MySQLDatabase::class, 'connection_collation');
// Set charset if given and not null. Can explicitly set to empty string to omit
if (!in_array($parameters['driver'], ['sqlsrv', 'pgsql'])) {
@ -325,7 +325,8 @@ class PDOConnector extends DBConnector
public function bindParameters(PDOStatement $statement, $parameters)
{
// Bind all parameters
for ($index = 0; $index < count($parameters); $index++) {
$parameterCount = count($parameters);
for ($index = 0; $index < $parameterCount; $index++) {
$value = $parameters[$index];
$phpType = gettype($value);
@ -338,7 +339,7 @@ class PDOConnector extends DBConnector
// Check type of parameter
$type = $this->getPDOParamType($phpType);
if ($type === PDO::PARAM_STR) {
$value = strval($value);
$value = (string) $value;
}
// Bind this value
@ -388,7 +389,6 @@ class PDOConnector extends DBConnector
// Ensure statement is closed
if ($statement) {
$statement->closeCursor();
unset($statement);
}
// Report any errors

View File

@ -145,7 +145,7 @@ class DBEnum extends DBString
public function scaffoldSearchField($title = null)
{
$anyText = _t('SilverStripe\\ORM\\FieldType\\DBEnum.ANY', 'Any');
return $this->formField($title, null, true, $anyText, "($anyText)");
return $this->formField($title, null, true, '', "($anyText)");
}
/**

View File

@ -6,7 +6,7 @@
$FirstPage $PreviousPage
<span class="pagination-page-number">
<%t SilverStripe\\Forms\\GridField\\GridFieldPaginator.Page 'Page' %>
<input class="text" title="Current page" value="$CurrentPageNum" data-skip-autofocus="true" />
<input class="text no-change-track" title="Current page" value="$CurrentPageNum" data-skip-autofocus="true" />
<%t SilverStripe\\Forms\\GridField\\GridFieldPaginator.OF 'of' is 'Example: View 1 of 2' %>
$NumPages
</span>

View File

@ -7,6 +7,7 @@ use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\Filterable;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\View\ArrayData;
use SilverStripe\Dev\Deprecation;
use stdClass;
class ArrayListTest extends SapphireTest
@ -133,6 +134,19 @@ class ArrayListTest extends SapphireTest
);
}
/**
* @expectedException PHPUnit_Framework_Error
*/
public function testZeroLimit()
{
Deprecation::notification_version('4.3.0');
$list = new ArrayList([
['Key' => 1],
['Key' => 2],
]);
$list->limit(0);
}
public function testAddRemove()
{
$list = new ArrayList(