mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
Merge branch '4.3' into 4
This commit is contained in:
commit
9ceef59e1b
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -85,5 +85,6 @@ class ExtensionTestState implements TestState
|
||||
|
||||
public function tearDownOnce($class)
|
||||
{
|
||||
DataObject::flush_extra_methods_cache();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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)");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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>
|
||||
|
@ -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(
|
||||
|
Loading…
x
Reference in New Issue
Block a user