mirror of
https://github.com/symbiote/silverstripe-gridfieldextensions.git
synced 2024-10-22 17:05:39 +02:00
Merge branch 'master' into pulls/3.0/fix-closure-import
This commit is contained in:
commit
a7c5283bdd
43
.travis.yml
43
.travis.yml
@ -1,26 +1,31 @@
|
|||||||
# See https://github.com/silverstripe/silverstripe-travis-support for setup details
|
|
||||||
|
|
||||||
sudo: false
|
|
||||||
|
|
||||||
language: php
|
language: php
|
||||||
|
|
||||||
php:
|
|
||||||
- 5.6
|
|
||||||
- 7.0
|
|
||||||
- 7.1
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- DB=MYSQL CORE_RELEASE=4
|
global:
|
||||||
- DB=PGSQL CORE_RELEASE=4
|
- COMPOSER_ROOT_VERSION="4.0.x-dev"
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- php: 5.6
|
||||||
|
env: DB=MYSQL PHPCS_TEST=1 PHPUNIT_TEST=1
|
||||||
|
- php: 7.0
|
||||||
|
env: DB=PGSQL PHPUNIT_TEST=1
|
||||||
|
- php: 7.1
|
||||||
|
env: DB=MYSQL PHPUNIT_COVERAGE_TEST=1
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- composer self-update || true
|
- phpenv rehash
|
||||||
- git clone git://github.com/silverstripe/silverstripe-travis-support.git ~/travis-support
|
- phpenv config-rm xdebug.ini
|
||||||
- php ~/travis-support/travis_setup.php --source `pwd` --target ~/builds/ss
|
|
||||||
- cd ~/builds/ss
|
- composer validate
|
||||||
- composer install --prefer-dist --no-progress --no-suggest
|
- composer require silverstripe/recipe-core 1.0.x-dev --no-update
|
||||||
- composer require silverstripe/versioned:1.x-dev --prefer-dist --no-progress --no-suggest
|
- if [[ $DB == PGSQL ]]; then composer require silverstripe/postgresql:2.0.x-dev --no-update; fi
|
||||||
- composer dump-autoload --optimize
|
- composer install --prefer-dist --no-interaction --no-progress --no-suggest --optimize-autoloader --verbose --profile
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- vendor/bin/phpunit gridfieldextensions/tests
|
- if [[ $PHPUNIT_TEST ]]; then vendor/bin/phpunit tests/; fi
|
||||||
|
- if [[ $PHPUNIT_COVERAGE_TEST ]]; then phpdbg -qrr vendor/bin/phpunit --coverage-clover=coverage.xml; fi
|
||||||
|
- if [[ $PHPCS_TEST ]]; then vendor/bin/phpcs --standard=vendor/silverstripe/framework/phpcs.xml.dist src/ tests/ ; fi
|
||||||
|
|
||||||
|
after_success:
|
||||||
|
- if [[ $PHPUNIT_COVERAGE_TEST ]]; then bash <(curl -s https://codecov.io/bash) -f coverage.xml; fi
|
||||||
|
@ -20,10 +20,11 @@ This module provides a number of useful grid field components:
|
|||||||
custom grid field detail views including tabs, breadcrumbs and other CMS
|
custom grid field detail views including tabs, breadcrumbs and other CMS
|
||||||
features.
|
features.
|
||||||
* `GridFieldTitleHeader` - a simple header which displays column titles.
|
* `GridFieldTitleHeader` - a simple header which displays column titles.
|
||||||
|
* `GridFieldConfigurablePaginator` - a paginator for GridField that allows customisable page sizes.
|
||||||
|
|
||||||
This branch will aim for compatibility with SilverStripe 4.x.
|
This branch will aim for compatibility with SilverStripe 4.x.
|
||||||
|
|
||||||
For SilverStripe 3.x, please see the [compatible branch](https://github.com/symbiote/silverstripe-gridfieldextensions/tree/1).
|
For SilverStripe 3.x, please see the [compatible branch](https://github.com/symbiote/silverstripe-gridfieldextensions/tree/2).
|
||||||
|
|
||||||
|
|
||||||
See [docs/en/index.md](docs/en/index.md) for documentation and examples.
|
See [docs/en/index.md](docs/en/index.md) for documentation and examples.
|
||||||
|
1
codecov.yml
Normal file
1
codecov.yml
Normal file
@ -0,0 +1 @@
|
|||||||
|
comment: false
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "symbiote/silverstripe-gridfieldextensions",
|
"name": "symbiote/silverstripe-gridfieldextensions",
|
||||||
"description": "A collection of useful grid field components",
|
"description": "A collection of useful grid field components",
|
||||||
"type": "silverstripe-module",
|
"type": "silverstripe-vendormodule",
|
||||||
"homepage": "http://github.com/symbiote/silverstripe-gridfieldextensions",
|
"homepage": "http://github.com/symbiote/silverstripe-gridfieldextensions",
|
||||||
"keywords": ["silverstripe", "gridfield"],
|
"keywords": ["silverstripe", "gridfield"],
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
@ -19,8 +19,14 @@
|
|||||||
"issues": "http://github.com/symbiote/silverstripe-gridfieldextensions/issues"
|
"issues": "http://github.com/symbiote/silverstripe-gridfieldextensions/issues"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
"silverstripe/vendor-plugin": "^1.0",
|
||||||
"silverstripe/framework": "~4.0"
|
"silverstripe/framework": "~4.0"
|
||||||
},
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^5.7",
|
||||||
|
"squizlabs/php_codesniffer": "^3.0",
|
||||||
|
"silverstripe/versioned": "^1@dev"
|
||||||
|
},
|
||||||
"extra": {
|
"extra": {
|
||||||
"installer-name": "gridfieldextensions",
|
"installer-name": "gridfieldextensions",
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
@ -29,6 +35,10 @@
|
|||||||
"screenshots": [
|
"screenshots": [
|
||||||
"docs/en/_images/editable-rows.png",
|
"docs/en/_images/editable-rows.png",
|
||||||
"docs/en/_images/add-existing-search.png"
|
"docs/en/_images/add-existing-search.png"
|
||||||
|
],
|
||||||
|
"expose": [
|
||||||
|
"css",
|
||||||
|
"javascript"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"replace": {
|
"replace": {
|
||||||
@ -37,7 +47,8 @@
|
|||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Symbiote\\GridFieldExtensions\\": "src/"
|
"Symbiote\\GridFieldExtensions\\": "src/",
|
||||||
|
"Symbiote\\GridFieldExtensions\\Tests\\": "tests/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"prefer-stable": true,
|
"prefer-stable": true,
|
||||||
|
@ -73,8 +73,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
.ss-gridfield-add-new-multi-class {
|
.ss-gridfield-add-new-multi-class {
|
||||||
margin-bottom: 8px !important;
|
margin-bottom: 8px !important;white-space: nowrap;
|
||||||
white-space: nowrap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ss-gridfield-add-new-multi-class .field {
|
.ss-gridfield-add-new-multi-class .field {
|
||||||
@ -131,7 +130,7 @@
|
|||||||
.ss-gridfield-editable select.dropdown {
|
.ss-gridfield-editable select.dropdown {
|
||||||
border: 1px solid #b3b3b3;
|
border: 1px solid #b3b3b3;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
padding: 7px 7px 7px 4px;
|
padding: 7px 7px7px 4px;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
-moz-border-radius: 4px;
|
-moz-border-radius: 4px;
|
||||||
-webkit-border-radius: 4px;
|
-webkit-border-radius: 4px;
|
||||||
@ -166,12 +165,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ss-gridfield-orderable .col-reorder .handle {
|
.ss-gridfield-orderable .col-reorder .handle {
|
||||||
cursor: move;
|
|
||||||
padding: 16px 0 11px;
|
cursor: move;padding: 16px 0 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ss-gridfield-orderable .col-reorder .handle .icon {
|
.ss-gridfield-orderable .col-reorder .handle .icon {
|
||||||
line-height: 100%;
|
line-
|
||||||
|
height: 100%;
|
||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,3 +199,25 @@
|
|||||||
background-position: -40px 9px !important;
|
background-position: -40px 9px !important;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GridFieldConfigurablePaginator
|
||||||
|
*/
|
||||||
|
.ss-gridfield-configurable-paginator .pagination-page-size {
|
||||||
|
color: #fff;
|
||||||
|
float: left;
|
||||||
|
padding: 6px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ss-gridfield-configurable-paginator .pagination-page-size-select {
|
||||||
|
margin-left: 0;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ss-gridfield-configurable-paginator .ss-gridfield-pagesize-submit {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ss-gridfield-configurable-paginator .pagination-page-number input {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
@ -106,3 +106,36 @@ class Item extends DataObject {
|
|||||||
|
|
||||||
**Please NOTE:** There is a limitation when using `GridFieldOrderableRows` on unsaved data objects; namely, that it doesn't work as without data being saved, the list of related objects has no context. Please check `$this->ID` before adding the `GridFieldOrderableRows` component to the grid field config (or even, before adding the gridfield at all).
|
**Please NOTE:** There is a limitation when using `GridFieldOrderableRows` on unsaved data objects; namely, that it doesn't work as without data being saved, the list of related objects has no context. Please check `$this->ID` before adding the `GridFieldOrderableRows` component to the grid field config (or even, before adding the gridfield at all).
|
||||||
|
|
||||||
|
Configurable Paginator
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
The `GridFieldConfigurablePaginator` component allows you to have a page size dropdown added to your GridField
|
||||||
|
pagination controls. The page sizes are configurable via the configuration system, or at call time using the public API.
|
||||||
|
To use this component you should remove the original paginator component first:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$gridField->getConfig()
|
||||||
|
->removeComponentsByType('GridFieldPaginator')
|
||||||
|
->addComponent(new GridFieldConfigurablePaginator());
|
||||||
|
```
|
||||||
|
|
||||||
|
You can configure the page sizes with the configuration system. Note that merging is the default strategy, so to replace
|
||||||
|
the default sizes with your own you will need to unset the original first, for example:
|
||||||
|
|
||||||
|
```php
|
||||||
|
# File: mysite/_config.php
|
||||||
|
Config::inst()->remove('GridFieldConfigurablePaginator', 'default_page_sizes');
|
||||||
|
Config::inst()->update('GridFieldConfigurablePaginator', 'default_page_sizes', array(100, 200, 500));
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also override these at call time:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$paginator = new GridFieldConfigurablePaginator(100, array(100, 200, 500));
|
||||||
|
|
||||||
|
$paginator->setPageSizes(array(200, 500, 1000));
|
||||||
|
$paginator->setItemsPerPage(500);
|
||||||
|
```
|
||||||
|
|
||||||
|
The first shown record will be maintained across page size changes, and the number of pages and current page will be
|
||||||
|
recalculated on each request, based on the current first shown record and page size.
|
||||||
|
@ -250,7 +250,7 @@
|
|||||||
* GridFieldEditableColumns
|
* GridFieldEditableColumns
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$('.ss-gridfield.ss-gridfield-editable .ss-gridfield-item td').entwine({
|
$('.grid-field .ss-gridfield-item').entwine({
|
||||||
onclick: function(e) {
|
onclick: function(e) {
|
||||||
// Prevent the default row click action when clicking a cell that contains a field
|
// Prevent the default row click action when clicking a cell that contains a field
|
||||||
if (this.find('.editable-column-field').length) {
|
if (this.find('.editable-column-field').length) {
|
||||||
@ -387,5 +387,14 @@
|
|||||||
if(this.hasClass("ui-droppable")) this.droppable("destroy");
|
if(this.hasClass("ui-droppable")) this.droppable("destroy");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GridFieldConfigurablePaginator
|
||||||
|
*/
|
||||||
|
$('.ss-gridfield-configurable-paginator .pagination-page-size-select').entwine({
|
||||||
|
onchange: function () {
|
||||||
|
this.parent().find('.ss-gridfield-pagesize-submit').trigger('click');
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
14
phpunit.xml.dist
Normal file
14
phpunit.xml.dist
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<phpunit bootstrap="vendor/silverstripe/framework/tests/bootstrap.php" colors="true">
|
||||||
|
<testsuite name="Default">
|
||||||
|
<directory>tests</directory>
|
||||||
|
</testsuite>
|
||||||
|
|
||||||
|
<filter>
|
||||||
|
<whitelist addUncoveredFilesFromWhitelist="true">
|
||||||
|
<directory suffix=".php">src/</directory>
|
||||||
|
<exclude>
|
||||||
|
<directory suffix=".php">tests/</directory>
|
||||||
|
</exclude>
|
||||||
|
</whitelist>
|
||||||
|
</filter>
|
||||||
|
</phpunit>
|
@ -144,8 +144,10 @@ class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_S
|
|||||||
sprintf('[%s][{%%=o.num%%}]', self::POST_KEY),
|
sprintf('[%s][{%%=o.num%%}]', self::POST_KEY),
|
||||||
$content
|
$content
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Cast content as HTML
|
// Cast content
|
||||||
|
if (! $content instanceof DBField) {
|
||||||
$content = DBField::create_field('HTMLFragment', $content);
|
$content = DBField::create_field('HTMLFragment', $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +159,7 @@ class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_S
|
|||||||
|
|
||||||
$columns->push(new ArrayData(array(
|
$columns->push(new ArrayData(array(
|
||||||
'Content' => $content,
|
'Content' => $content,
|
||||||
'Attributes' => $attrs,
|
'Attributes' => DBField::create_field('HTMLFragment', $attrs),
|
||||||
'IsActions' => $column == 'Actions'
|
'IsActions' => $column == 'Actions'
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
@ -179,7 +181,6 @@ class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_S
|
|||||||
$editable = $grid->getConfig()->getComponentByType(GridFieldEditableColumns::class);
|
$editable = $grid->getConfig()->getComponentByType(GridFieldEditableColumns::class);
|
||||||
/** @var GridFieldOrderableRows $sortable */
|
/** @var GridFieldOrderableRows $sortable */
|
||||||
$sortable = $grid->getConfig()->getComponentByType(GridFieldOrderableRows::class);
|
$sortable = $grid->getConfig()->getComponentByType(GridFieldOrderableRows::class);
|
||||||
$form = $editable->getForm($grid, $record);
|
|
||||||
|
|
||||||
if (!singleton($class)->canCreate()) {
|
if (!singleton($class)->canCreate()) {
|
||||||
return;
|
return;
|
||||||
@ -190,6 +191,7 @@ class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_S
|
|||||||
$item = $class::create();
|
$item = $class::create();
|
||||||
$extra = array();
|
$extra = array();
|
||||||
|
|
||||||
|
$form = $editable->getForm($grid, $record);
|
||||||
$form->loadDataFrom($fields, Form::MERGE_CLEAR_MISSING);
|
$form->loadDataFrom($fields, Form::MERGE_CLEAR_MISSING);
|
||||||
$form->saveInto($item);
|
$form->saveInto($item);
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ class GridFieldAddNewMultiClass implements GridField_HTMLProvider, GridField_URL
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sanitised = array();
|
$sanitised = array();
|
||||||
foreach($result as $class=>$title) {
|
foreach ($result as $class => $title) {
|
||||||
$sanitised[$this->sanitiseClassName($class)] = $title;
|
$sanitised[$this->sanitiseClassName($class)] = $title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
453
src/GridFieldConfigurablePaginator.php
Normal file
453
src/GridFieldConfigurablePaginator.php
Normal file
@ -0,0 +1,453 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symbiote\GridFieldExtensions;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use SilverStripe\Core\Config\Configurable;
|
||||||
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldPaginator;
|
||||||
|
use SilverStripe\Forms\GridField\GridField_FormAction;
|
||||||
|
use SilverStripe\Forms\GridField\GridState_Data;
|
||||||
|
use SilverStripe\ORM\ArrayList;
|
||||||
|
use SilverStripe\ORM\Limitable;
|
||||||
|
use SilverStripe\ORM\SS_List;
|
||||||
|
use SilverStripe\ORM\UnsavedRelationList;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GridFieldConfigurablePaginator paginates the {@link GridField} list and adds controls to the bottom of
|
||||||
|
* the {@link GridField}. The page sizes are configurable.
|
||||||
|
*/
|
||||||
|
class GridFieldConfigurablePaginator extends GridFieldPaginator
|
||||||
|
{
|
||||||
|
use Configurable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies default page sizes
|
||||||
|
*
|
||||||
|
* @config
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private static $default_page_sizes = array(15, 30, 60);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var GridField
|
||||||
|
*/
|
||||||
|
protected $gridField;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var GridState_Data
|
||||||
|
*/
|
||||||
|
protected $gridFieldState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int[]
|
||||||
|
*/
|
||||||
|
protected $pageSizes = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $itemsPerPage How many items should be displayed per page
|
||||||
|
* @param int $pageSizes The page sizes to show in the dropdown
|
||||||
|
*/
|
||||||
|
public function __construct($itemsPerPage = null, $pageSizes = null)
|
||||||
|
{
|
||||||
|
$this->setPageSizes($pageSizes ?: $this->config()->get('default_page_sizes'));
|
||||||
|
|
||||||
|
if (!$itemsPerPage) {
|
||||||
|
$itemsPerPage = $this->pageSizes[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($itemsPerPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the total number of records in the list
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTotalRecords()
|
||||||
|
{
|
||||||
|
return (int) $this->getGridField()->getList()->count();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the first shown record number
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getFirstShown()
|
||||||
|
{
|
||||||
|
$firstShown = $this->getGridPagerState()->firstShown ?: 1;
|
||||||
|
// Prevent visiting a page with an offset higher than the total number of items
|
||||||
|
if ($firstShown > $this->getTotalRecords()) {
|
||||||
|
$this->getGridPagerState()->firstShown = $firstShown = 1;
|
||||||
|
}
|
||||||
|
return $firstShown;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the first shown record number. Will be stored in the state.
|
||||||
|
*
|
||||||
|
* @param int $firstShown
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setFirstShown($firstShown = 1)
|
||||||
|
{
|
||||||
|
$this->getGridPagerState()->firstShown = (int) $firstShown;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the last shown record number
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getLastShown()
|
||||||
|
{
|
||||||
|
return min($this->getTotalRecords(), $this->getFirstShown() + $this->getItemsPerPage() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the total number of pages, given the current number of items per page. The total
|
||||||
|
* pages might be higher than <totalitems> / <itemsperpage> if the first shown record
|
||||||
|
* is half way through a standard page break point.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTotalPages()
|
||||||
|
{
|
||||||
|
// Pages before
|
||||||
|
$pages = ceil(($this->getFirstShown() - 1) / $this->getItemsPerPage());
|
||||||
|
|
||||||
|
// Current page
|
||||||
|
$pages++;
|
||||||
|
|
||||||
|
// Pages after
|
||||||
|
$pages += ceil(($this->getTotalRecords() - $this->getLastShown()) / $this->getItemsPerPage());
|
||||||
|
|
||||||
|
return (int) $pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the page currently active. This is calculated by adding one to the previous number
|
||||||
|
* of pages calculated via the "first shown record" position.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getCurrentPage()
|
||||||
|
{
|
||||||
|
return (int) ceil(($this->getFirstShown() - 1) / $this->getItemsPerPage()) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the next page number
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getNextPage()
|
||||||
|
{
|
||||||
|
return min($this->getTotalPages(), $this->getCurrentPage() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the previous page number
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getPreviousPage()
|
||||||
|
{
|
||||||
|
return max(1, $this->getCurrentPage() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the page sizes to use in the "Show x" dropdown
|
||||||
|
*
|
||||||
|
* @param array $pageSizes
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setPageSizes(array $pageSizes)
|
||||||
|
{
|
||||||
|
$this->pageSizes = $pageSizes;
|
||||||
|
|
||||||
|
// Reset items per page
|
||||||
|
$this->setItemsPerPage(current($pageSizes));
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the sizes for the "Show x" dropdown
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getPageSizes()
|
||||||
|
{
|
||||||
|
return $this->pageSizes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of page sizes for use in templates as a dropdown
|
||||||
|
*
|
||||||
|
* @return ArrayList
|
||||||
|
*/
|
||||||
|
public function getPageSizesAsList()
|
||||||
|
{
|
||||||
|
$pageSizes = ArrayList::create();
|
||||||
|
$perPage = $this->getItemsPerPage();
|
||||||
|
foreach ($this->getPageSizes() as $pageSize) {
|
||||||
|
$pageSizes->push(array(
|
||||||
|
'Size' => $pageSize,
|
||||||
|
'Selected' => $pageSize == $perPage
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return $pageSizes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the GridField used in this request
|
||||||
|
*
|
||||||
|
* @return GridField
|
||||||
|
* @throws Exception If the GridField has not been previously set
|
||||||
|
*/
|
||||||
|
public function getGridField()
|
||||||
|
{
|
||||||
|
if ($this->gridField) {
|
||||||
|
return $this->gridField;
|
||||||
|
}
|
||||||
|
throw new Exception('No GridField available yet for this request!');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the GridField so it can be used in other parts of the component during this request
|
||||||
|
*
|
||||||
|
* @param GridField $gridField
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setGridField(GridField $gridField)
|
||||||
|
{
|
||||||
|
$this->gridField = $gridField;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleAction(GridField $gridField, $actionName, $arguments, $data)
|
||||||
|
{
|
||||||
|
$this->setGridField($gridField);
|
||||||
|
|
||||||
|
if ($actionName !== 'paginate') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$state = $this->getGridPagerState();
|
||||||
|
|
||||||
|
$state->firstShown = (int) $arguments['first-shown'];
|
||||||
|
$state->pageSize = $data[$gridField->getName()]['page-sizes'];
|
||||||
|
|
||||||
|
$this->setItemsPerPage($state->pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getManipulatedData(GridField $gridField, SS_List $dataList)
|
||||||
|
{
|
||||||
|
// Assign the GridField to the class so it can be used later in the request
|
||||||
|
$this->setGridField($gridField);
|
||||||
|
|
||||||
|
// Retain page sizes during actions provided by other components
|
||||||
|
$state = $this->getGridPagerState();
|
||||||
|
if (is_numeric($state->pageSize)) {
|
||||||
|
$this->setItemsPerPage($state->pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!($dataList instanceof Limitable) || ($dataList instanceof UnsavedRelationList)) {
|
||||||
|
return $dataList;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dataList->limit($this->getItemsPerPage(), $this->getFirstShown() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the configurable page size options to the template data
|
||||||
|
*
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @param GridField $gridField
|
||||||
|
* @return ArrayList|null
|
||||||
|
*/
|
||||||
|
public function getTemplateParameters(GridField $gridField)
|
||||||
|
{
|
||||||
|
$state = $this->getGridPagerState();
|
||||||
|
if (is_numeric($state->pageSize)) {
|
||||||
|
$this->setItemsPerPage($state->pageSize);
|
||||||
|
}
|
||||||
|
$arguments = $this->getPagerArguments();
|
||||||
|
|
||||||
|
// Figure out which page and record range we're on
|
||||||
|
if (!$arguments['total-rows']) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define a list of the FormActions that should be generated for pager controls (see getPagerActions())
|
||||||
|
$controls = array(
|
||||||
|
'first' => array(
|
||||||
|
'title' => 'First',
|
||||||
|
'args' => array('first-shown' => 1),
|
||||||
|
'extra-class' => 'btn btn-secondary btn--hide-text btn-sm font-icon-angle-double-left ss-gridfield-firstpage',
|
||||||
|
'disable-previous' => ($this->getCurrentPage() == 1)
|
||||||
|
),
|
||||||
|
'prev' => array(
|
||||||
|
'title' => 'Previous',
|
||||||
|
'args' => array('first-shown' => $arguments['first-shown'] - $this->getItemsPerPage()),
|
||||||
|
'extra-class' => 'btn btn-secondary btn--hide-text btn-sm font-icon-angle-left ss-gridfield-previouspage',
|
||||||
|
'disable-previous' => ($this->getCurrentPage() == 1)
|
||||||
|
),
|
||||||
|
'next' => array(
|
||||||
|
'title' => 'Next',
|
||||||
|
'args' => array('first-shown' => $arguments['first-shown'] + $this->getItemsPerPage()),
|
||||||
|
'extra-class' => 'btn btn-secondary btn--hide-text btn-sm font-icon-angle-right ss-gridfield-nextpage',
|
||||||
|
'disable-next' => ($this->getCurrentPage() == $arguments['total-pages'])
|
||||||
|
),
|
||||||
|
'last' => array(
|
||||||
|
'title' => 'Last',
|
||||||
|
'args' => array('first-shown' => ($this->getTotalPages() - 1) * $this->getItemsPerPage() + 1),
|
||||||
|
'extra-class' => 'btn btn-secondary btn--hide-text btn-sm font-icon-angle-double-right ss-gridfield-lastpage',
|
||||||
|
'disable-next' => ($this->getCurrentPage() == $arguments['total-pages'])
|
||||||
|
),
|
||||||
|
'pagesize' => array(
|
||||||
|
'title' => 'Page Size',
|
||||||
|
'args' => array('first-shown' => $arguments['first-shown']),
|
||||||
|
'extra-class' => 'ss-gridfield-pagesize-submit'
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($controls['prev']['args']['first-shown'] < 1) {
|
||||||
|
$controls['prev']['args']['first-shown'] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$actions = $this->getPagerActions($controls, $gridField);
|
||||||
|
|
||||||
|
// Render in template
|
||||||
|
return ArrayData::create(array(
|
||||||
|
'OnlyOnePage' => ($arguments['total-pages'] == 1),
|
||||||
|
'FirstPage' => $actions['first'],
|
||||||
|
'PreviousPage' => $actions['prev'],
|
||||||
|
'NextPage' => $actions['next'],
|
||||||
|
'LastPage' => $actions['last'],
|
||||||
|
'PageSizesSubmit' => $actions['pagesize'],
|
||||||
|
'CurrentPageNum' => $this->getCurrentPage(),
|
||||||
|
'NumPages' => $arguments['total-pages'],
|
||||||
|
'FirstShownRecord' => $arguments['first-shown'],
|
||||||
|
'LastShownRecord' => $arguments['last-shown'],
|
||||||
|
'NumRecords' => $arguments['total-rows'],
|
||||||
|
'PageSizes' => $this->getPageSizesAsList(),
|
||||||
|
'PageSizesName' => $gridField->getName() . '[page-sizes]',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHTMLFragments($gridField)
|
||||||
|
{
|
||||||
|
GridFieldExtensions::include_requirements();
|
||||||
|
|
||||||
|
$gridField->addExtraClass('ss-gridfield-configurable-paginator');
|
||||||
|
|
||||||
|
$forTemplate = $this->getTemplateParameters($gridField);
|
||||||
|
if ($forTemplate) {
|
||||||
|
return array(
|
||||||
|
'footer' => $forTemplate->renderWith(
|
||||||
|
__CLASS__,
|
||||||
|
array('Colspan' => count($gridField->getColumns()))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array containing the arguments for the pagination: total rows, pages, first record etc
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getPagerArguments()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'total-rows' => $this->getTotalRecords(),
|
||||||
|
'total-pages' => $this->getTotalPages(),
|
||||||
|
'items-per-page' => $this->getItemsPerPage(),
|
||||||
|
'first-shown' => $this->getFirstShown(),
|
||||||
|
'last-shown' => $this->getLastShown(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns FormActions for each of the pagination actions, in an array
|
||||||
|
*
|
||||||
|
* @param array $controls
|
||||||
|
* @param GridField $gridField
|
||||||
|
* @return GridField_FormAction[]
|
||||||
|
*/
|
||||||
|
public function getPagerActions(array $controls, GridField $gridField)
|
||||||
|
{
|
||||||
|
$actions = array();
|
||||||
|
|
||||||
|
foreach ($controls as $key => $arguments) {
|
||||||
|
$action = GridField_FormAction::create(
|
||||||
|
$gridField,
|
||||||
|
'pagination_' . $key,
|
||||||
|
$arguments['title'],
|
||||||
|
'paginate',
|
||||||
|
$arguments['args']
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isset($arguments['extra-class'])) {
|
||||||
|
$action->addExtraClass($arguments['extra-class']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($arguments['disable-previous']) && $arguments['disable-previous']) {
|
||||||
|
$action = $action->performDisabledTransformation();
|
||||||
|
} elseif (isset($arguments['disable-next']) && $arguments['disable-next']) {
|
||||||
|
$action = $action->performDisabledTransformation();
|
||||||
|
}
|
||||||
|
|
||||||
|
$actions[$key] = $action;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getActions($gridField)
|
||||||
|
{
|
||||||
|
return array('paginate');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the state from the current request's GridField and sets some default values on it
|
||||||
|
*
|
||||||
|
* @param GridField $gridField Not used, but present for parent method compatibility
|
||||||
|
* @return GridState_Data
|
||||||
|
*/
|
||||||
|
protected function getGridPagerState(GridField $gridField = null)
|
||||||
|
{
|
||||||
|
if (!$this->gridFieldState) {
|
||||||
|
$state = $this->getGridField()->State->GridFieldConfigurablePaginator;
|
||||||
|
|
||||||
|
// SS 3.1 compatibility (missing __call)
|
||||||
|
if (is_object($state->firstShown)) {
|
||||||
|
$state->firstShown = 1;
|
||||||
|
}
|
||||||
|
if (is_object($state->pageSize)) {
|
||||||
|
$state->pageSize = $this->getItemsPerPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle free input in the page number field
|
||||||
|
$parentState = $this->getGridField()->State->GridFieldPaginator;
|
||||||
|
if (is_object($parentState->currentPage)) {
|
||||||
|
$parentState->currentPage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($parentState->currentPage >= 1) {
|
||||||
|
$state->firstShown = ($parentState->currentPage - 1) * $this->getItemsPerPage() + 1;
|
||||||
|
$parentState->currentPage = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->gridFieldState = $state;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->gridFieldState;
|
||||||
|
}
|
||||||
|
}
|
@ -124,8 +124,6 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements
|
|||||||
/** @var GridFieldOrderableRows $sortable */
|
/** @var GridFieldOrderableRows $sortable */
|
||||||
$sortable = $grid->getConfig()->getComponentByType(GridFieldOrderableRows::class);
|
$sortable = $grid->getConfig()->getComponentByType(GridFieldOrderableRows::class);
|
||||||
|
|
||||||
$form = $this->getForm($grid, $record);
|
|
||||||
|
|
||||||
foreach ($value[self::POST_KEY] as $id => $fields) {
|
foreach ($value[self::POST_KEY] as $id => $fields) {
|
||||||
if (!is_numeric($id) || !is_array($fields)) {
|
if (!is_numeric($id) || !is_array($fields)) {
|
||||||
continue;
|
continue;
|
||||||
@ -139,6 +137,7 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements
|
|||||||
|
|
||||||
$extra = array();
|
$extra = array();
|
||||||
|
|
||||||
|
$form = $this->getForm($grid, $record);
|
||||||
$form->loadDataFrom($fields, Form::MERGE_CLEAR_MISSING);
|
$form->loadDataFrom($fields, Form::MERGE_CLEAR_MISSING);
|
||||||
$form->saveInto($item);
|
$form->saveInto($item);
|
||||||
|
|
||||||
|
@ -9,16 +9,9 @@ use SilverStripe\View\Requirements;
|
|||||||
*/
|
*/
|
||||||
class GridFieldExtensions
|
class GridFieldExtensions
|
||||||
{
|
{
|
||||||
|
|
||||||
public static function include_requirements()
|
public static function include_requirements()
|
||||||
{
|
{
|
||||||
$moduleDir = self::get_module_dir();
|
Requirements::css('symbiote/silverstripe-gridfieldextensions:css/GridFieldExtensions.css');
|
||||||
Requirements::css($moduleDir.'/css/GridFieldExtensions.css');
|
Requirements::javascript('symbiote/silverstripe-gridfieldextensions:javascript/GridFieldExtensions.js');
|
||||||
Requirements::javascript($moduleDir.'/javascript/GridFieldExtensions.js');
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function get_module_dir()
|
|
||||||
{
|
|
||||||
return basename(dirname(__DIR__));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -516,11 +516,11 @@ class GridFieldOrderableRows extends RequestHandler implements
|
|||||||
$sortTable = $this->getSortTable($list);
|
$sortTable = $this->getSortTable($list);
|
||||||
$additionalSQL = '';
|
$additionalSQL = '';
|
||||||
$baseTable = $sortTable;
|
$baseTable = $sortTable;
|
||||||
if(class_exists($sortTable)) {
|
if (class_exists($sortTable)) {
|
||||||
$baseTable = singleton($sortTable)->baseTable();
|
$baseTable = singleton($sortTable)->baseTable();
|
||||||
}
|
}
|
||||||
$isBaseTable = ($baseTable == $sortTable);
|
$isBaseTable = ($baseTable == $sortTable);
|
||||||
if(!$list instanceof ManyManyList && $isBaseTable){
|
if (!$list instanceof ManyManyList && $isBaseTable) {
|
||||||
$additionalSQL = ', "LastEdited" = NOW()';
|
$additionalSQL = ', "LastEdited" = NOW()';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,7 +535,7 @@ class GridFieldOrderableRows extends RequestHandler implements
|
|||||||
$this->getSortTableClauseForIds($list, $id)
|
$this->getSortTableClauseForIds($list, $id)
|
||||||
));
|
));
|
||||||
|
|
||||||
if(!$isBaseTable) {
|
if (!$isBaseTable) {
|
||||||
DB::query(sprintf(
|
DB::query(sprintf(
|
||||||
'UPDATE "%s" SET "LastEdited" = NOW() WHERE %s',
|
'UPDATE "%s" SET "LastEdited" = NOW() WHERE %s',
|
||||||
$baseTable,
|
$baseTable,
|
||||||
@ -570,11 +570,11 @@ class GridFieldOrderableRows extends RequestHandler implements
|
|||||||
|
|
||||||
$additionalSQL = '';
|
$additionalSQL = '';
|
||||||
$baseTable = $table;
|
$baseTable = $table;
|
||||||
if(class_exists($table)) {
|
if (class_exists($table)) {
|
||||||
$baseTable = singleton($table)->baseTable();
|
$baseTable = singleton($table)->baseTable();
|
||||||
}
|
}
|
||||||
$isBaseTable = ($baseTable == $table);
|
$isBaseTable = ($baseTable == $table);
|
||||||
if(!$list instanceof ManyManyList && $isBaseTable){
|
if (!$list instanceof ManyManyList && $isBaseTable) {
|
||||||
$additionalSQL = ', "LastEdited" = NOW()';
|
$additionalSQL = ', "LastEdited" = NOW()';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,7 +591,7 @@ class GridFieldOrderableRows extends RequestHandler implements
|
|||||||
$this->getSortTableClauseForIds($list, $id)
|
$this->getSortTableClauseForIds($list, $id)
|
||||||
));
|
));
|
||||||
|
|
||||||
if(!$isBaseTable) {
|
if (!$isBaseTable) {
|
||||||
DB::query(sprintf(
|
DB::query(sprintf(
|
||||||
'UPDATE "%s" SET "LastEdited" = NOW() WHERE %s',
|
'UPDATE "%s" SET "LastEdited" = NOW() WHERE %s',
|
||||||
$baseTable,
|
$baseTable,
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
<tr>
|
||||||
|
<td class="bottom-all" colspan="$Colspan">
|
||||||
|
<span class="pagination-page-size">
|
||||||
|
<%t GridFieldConfigurablePaginator.SHOW 'Show' %>
|
||||||
|
<select name="$PageSizesName" class="pagination-page-size-select" data-skip-autofocus="true">
|
||||||
|
<% loop $PageSizes %>
|
||||||
|
<option <% if $Selected %>selected="selected"<% end_if %>>$Size</option>
|
||||||
|
<% end_loop %>
|
||||||
|
</select>
|
||||||
|
$PageSizesSubmit
|
||||||
|
</span>
|
||||||
|
<% if not $OnlyOnePage %>
|
||||||
|
<div class="datagrid-pagination">
|
||||||
|
$FirstPage $PreviousPage
|
||||||
|
<span class="pagination-page-number">
|
||||||
|
<%t Pagination.Page 'Page' %>
|
||||||
|
<input class="text" value="$CurrentPageNum" data-skip-autofocus="true" />
|
||||||
|
<%t TableListField_PageControls_ss.OF 'of' is 'Example: View 1 of 2' %>
|
||||||
|
$NumPages
|
||||||
|
</span>
|
||||||
|
$NextPage $LastPage
|
||||||
|
</div>
|
||||||
|
<% end_if %>
|
||||||
|
<span class="pagination-records-number">
|
||||||
|
{$FirstShownRecord}–{$LastShownRecord}
|
||||||
|
<%t TableListField_PageControls_ss.OF 'of' is 'Example: View 1 of 2' %>
|
||||||
|
$NumRecords
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
@ -1,9 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace Symbiote\GridFieldExtensions\Tests;
|
||||||
|
|
||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
use SilverStripe\Dev\TestOnly;
|
use SilverStripe\Dev\TestOnly;
|
||||||
use SilverStripe\Forms\GridField\GridField;
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
use Symbiote\GridFieldExtensions\GridFieldAddNewMultiClass;
|
use Symbiote\GridFieldExtensions\GridFieldAddNewMultiClass;
|
||||||
|
use Symbiote\GridFieldExtensions\Tests\Stub\StubA;
|
||||||
|
use Symbiote\GridFieldExtensions\Tests\Stub\StubB;
|
||||||
|
use Symbiote\GridFieldExtensions\Tests\Stub\StubC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link GridFieldAddNewMultiClass}.
|
* Tests for {@link GridFieldAddNewMultiClass}.
|
||||||
@ -14,59 +19,32 @@ class GridFieldAddNewMultiClassTest extends SapphireTest
|
|||||||
public function testGetClasses()
|
public function testGetClasses()
|
||||||
{
|
{
|
||||||
$grid = new GridField('TestGridField');
|
$grid = new GridField('TestGridField');
|
||||||
$grid->setModelClass('GridFieldAddNewMultiClassTest_A');
|
$grid->setModelClass(StubA::class);
|
||||||
|
|
||||||
$component = new GridFieldAddNewMultiClass();
|
$component = new GridFieldAddNewMultiClass();
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
array(
|
array(
|
||||||
'GridFieldAddNewMultiClassTest_A' => 'A',
|
'Symbiote-GridFieldExtensions-Tests-Stub-StubA' => 'A',
|
||||||
'GridFieldAddNewMultiClassTest_B' => 'B',
|
'Symbiote-GridFieldExtensions-Tests-Stub-StubB' => 'B',
|
||||||
'GridFieldAddNewMultiClassTest_C' => 'C'
|
'Symbiote-GridFieldExtensions-Tests-Stub-StubC' => 'C'
|
||||||
),
|
),
|
||||||
$component->getClasses($grid),
|
$component->getClasses($grid),
|
||||||
'Subclasses are populated by default and sorted'
|
'Subclasses are populated by default and sorted'
|
||||||
);
|
);
|
||||||
|
|
||||||
$component->setClasses(array(
|
$component->setClasses(array(
|
||||||
'GridFieldAddNewMultiClassTest_B' => 'Custom Title',
|
StubB::class => 'Custom Title',
|
||||||
'GridFieldAddNewMultiClassTest_A'
|
StubA::class
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
array(
|
array(
|
||||||
'GridFieldAddNewMultiClassTest_B' => 'Custom Title',
|
'Symbiote-GridFieldExtensions-Tests-Stub-StubB' => 'Custom Title',
|
||||||
'GridFieldAddNewMultiClassTest_A' => 'A'
|
'Symbiote-GridFieldExtensions-Tests-Stub-StubA' => 'A'
|
||||||
),
|
),
|
||||||
$component->getClasses($grid),
|
$component->getClasses($grid),
|
||||||
'Sorting and custom titles can be specified'
|
'Sorting and custom titles can be specified'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**#@+
|
|
||||||
* @ignore
|
|
||||||
*/
|
|
||||||
|
|
||||||
class GridFieldAddNewMultiClassTest_A implements TestOnly
|
|
||||||
{
|
|
||||||
public function i18n_singular_name()
|
|
||||||
{
|
|
||||||
$class = get_class($this);
|
|
||||||
return substr($class, strpos($class, '_') + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function canCreate()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class GridFieldAddNewMultiClassTest_B extends GridFieldAddNewMultiClassTest_A implements TestOnly
|
|
||||||
{
|
|
||||||
}
|
|
||||||
class GridFieldAddNewMultiClassTest_C extends GridFieldAddNewMultiClassTest_A implements TestOnly
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**#@-*/
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Symbiote\Test;
|
namespace Symbiote\GridFieldExtensions\Tests;
|
||||||
|
|
||||||
use SilverStripe\Control\Controller;
|
use SilverStripe\Control\Controller;
|
||||||
use SilverStripe\Control\HTTPRequest;
|
use SilverStripe\Control\HTTPRequest;
|
||||||
@ -12,55 +12,42 @@ use SilverStripe\Forms\GridField\GridField;
|
|||||||
use SilverStripe\Forms\GridField\GridFieldDetailForm;
|
use SilverStripe\Forms\GridField\GridFieldDetailForm;
|
||||||
use Symbiote\GridFieldExtensions\GridFieldAddNewMultiClass;
|
use Symbiote\GridFieldExtensions\GridFieldAddNewMultiClass;
|
||||||
use Symbiote\GridFieldExtensions\GridFieldAddNewMultiClassHandler;
|
use Symbiote\GridFieldExtensions\GridFieldAddNewMultiClassHandler;
|
||||||
|
use Symbiote\GridFieldExtensions\Tests\Stub\NamespacedClass;
|
||||||
|
|
||||||
class GridFieldAddNewMultiClassWithNamespacesTest extends SapphireTest {
|
class GridFieldAddNewMultiClassWithNamespacesTest extends SapphireTest
|
||||||
|
{
|
||||||
|
|
||||||
public function testGetClassesWithNamespaces() {
|
public function testGetClassesWithNamespaces()
|
||||||
$grid = new GridField('TestGridField');
|
{
|
||||||
$grid->setModelClass('Symbiote\\Test\\NamespacedClass');
|
$grid = new GridField('TestGridField');
|
||||||
|
$grid->setModelClass(NamespacedClass::class);
|
||||||
|
|
||||||
$component = new GridFieldAddNewMultiClass();
|
$component = new GridFieldAddNewMultiClass();
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
array(
|
array(
|
||||||
'Symbiote-Test-NamespacedClass' => 'NamespacedClass'
|
'Symbiote-GridFieldExtensions-Tests-Stub-NamespacedClass' => 'NamespacedClass'
|
||||||
),
|
),
|
||||||
$component->getClasses($grid),
|
$component->getClasses($grid),
|
||||||
'Namespaced classes are sanitised'
|
'Namespaced classes are sanitised'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testHandleAddWithNamespaces() {
|
public function testHandleAddWithNamespaces()
|
||||||
$grid = new GridField('TestGridField');
|
{
|
||||||
$grid->getConfig()->addComponent(new GridFieldDetailForm());
|
$grid = new GridField('TestGridField');
|
||||||
$grid->setModelClass('Symbiote\\Test\\NamespacedClass');
|
$grid->getConfig()->addComponent(new GridFieldDetailForm());
|
||||||
$grid->setForm(Form::create(Controller::create(), 'test', FieldList::create(), FieldList::create()));
|
$grid->setModelClass(NamespacedClass::class);
|
||||||
|
$grid->setForm(Form::create(Controller::create(), 'test', FieldList::create(), FieldList::create()));
|
||||||
|
|
||||||
$request = new HTTPRequest('POST', 'test');
|
$request = new HTTPRequest('POST', 'test');
|
||||||
$request->setRouteParams(array('ClassName' => 'Symbiote-Test-NamespacedClass'));
|
$request->setRouteParams(array('ClassName' => 'Symbiote-GridFieldExtensions-Tests-Stub-NamespacedClass'));
|
||||||
|
|
||||||
$component = new GridFieldAddNewMultiClass();
|
$component = new GridFieldAddNewMultiClass();
|
||||||
$response = $component->handleAdd($grid, $request);
|
$response = $component->handleAdd($grid, $request);
|
||||||
|
|
||||||
$record = new \ReflectionProperty(GridFieldAddNewMultiClassHandler::class, 'record');
|
|
||||||
$record->setAccessible(true);
|
|
||||||
$this->assertInstanceOf('Symbiote\\Test\\NamespacedClass', $record->getValue($response));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
$record = new \ReflectionProperty(GridFieldAddNewMultiClassHandler::class, 'record');
|
||||||
|
$record->setAccessible(true);
|
||||||
|
$this->assertInstanceOf(NamespacedClass::class, $record->getValue($response));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**#@+
|
|
||||||
* @ignore
|
|
||||||
*/
|
|
||||||
|
|
||||||
class NamespacedClass implements TestOnly {
|
|
||||||
public function i18n_singular_name() {
|
|
||||||
return 'NamespacedClass';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function canCreate() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**#@-*/
|
|
||||||
|
240
tests/GridFieldConfigurablePaginatorTest.php
Normal file
240
tests/GridFieldConfigurablePaginatorTest.php
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symbiote\GridFieldExtensions\Tests;
|
||||||
|
|
||||||
|
use SilverStripe\Core\Config\Config;
|
||||||
|
use SilverStripe\Dev\SapphireTest;
|
||||||
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
|
use SilverStripe\Forms\GridField\GridField_FormAction;
|
||||||
|
use SilverStripe\ORM\ArrayList;
|
||||||
|
use Symbiote\GridFieldExtensions\GridFieldConfigurablePaginator;
|
||||||
|
|
||||||
|
class GridFieldConfigurablePaginatorTest extends SapphireTest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var GridField
|
||||||
|
*/
|
||||||
|
protected $gridField;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
// Some dummy GridField list data
|
||||||
|
$data = ArrayList::create();
|
||||||
|
for ($i = 1; $i <= 130; $i++) {
|
||||||
|
$data->push(array('ID' => $i));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->gridField = GridField::create('Mock', null, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetTotalRecords()
|
||||||
|
{
|
||||||
|
$paginator = new GridFieldConfigurablePaginator;
|
||||||
|
$paginator->setGridField($this->gridField);
|
||||||
|
|
||||||
|
$this->assertSame(130, $paginator->getTotalRecords());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetFirstShown()
|
||||||
|
{
|
||||||
|
$paginator = new GridFieldConfigurablePaginator;
|
||||||
|
$paginator->setGridField($this->gridField);
|
||||||
|
|
||||||
|
// No state
|
||||||
|
$this->assertSame(1, $paginator->getFirstShown());
|
||||||
|
|
||||||
|
// With a state
|
||||||
|
$paginator->setFirstShown(123);
|
||||||
|
$this->assertSame(123, $paginator->getFirstShown());
|
||||||
|
|
||||||
|
// Too high!
|
||||||
|
$paginator->setFirstShown(234);
|
||||||
|
$this->assertSame(1, $paginator->getFirstShown());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetLastShown()
|
||||||
|
{
|
||||||
|
$paginator = new GridFieldConfigurablePaginator(20, array(10, 20, 30));
|
||||||
|
$paginator->setGridField($this->gridField);
|
||||||
|
|
||||||
|
$this->assertSame(20, $paginator->getLastShown());
|
||||||
|
|
||||||
|
$paginator->setFirstShown(5);
|
||||||
|
$this->assertSame(24, $paginator->getLastShown());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetTotalPages()
|
||||||
|
{
|
||||||
|
$paginator = new GridFieldConfigurablePaginator(20, array(20, 40, 60));
|
||||||
|
$paginator->setGridField($this->gridField);
|
||||||
|
|
||||||
|
// Default calculation
|
||||||
|
$this->assertSame(7, $paginator->getTotalPages());
|
||||||
|
|
||||||
|
// With a standard "first shown" record number, e.g. page 2
|
||||||
|
$paginator->setFirstShown(21);
|
||||||
|
$this->assertSame(7, $paginator->getTotalPages());
|
||||||
|
|
||||||
|
// Non-standard "first shown", e.g. when a page size is changed at page 3. In this case the first page is
|
||||||
|
// 20 records, the second page is 7 records, third page 20 records, etc
|
||||||
|
$paginator->setFirstShown(27);
|
||||||
|
$this->assertSame(8, $paginator->getTotalPages());
|
||||||
|
|
||||||
|
// ... and when the page size has also been changed. In this case the first page is 57 records, second page
|
||||||
|
// 60 records and last page is 13 records
|
||||||
|
$paginator->setFirstShown(57);
|
||||||
|
$paginator->setItemsPerPage(60);
|
||||||
|
$this->assertSame(3, $paginator->getTotalPages());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItemsPerPageIsSetToFirstInPageSizesListWhenChanged()
|
||||||
|
{
|
||||||
|
$paginator = new GridFieldConfigurablePaginator(20, array(20, 40, 60));
|
||||||
|
$paginator->setGridField($this->gridField);
|
||||||
|
|
||||||
|
// Initial state, should be what was provided to the constructor
|
||||||
|
$this->assertSame(20, $paginator->getItemsPerPage());
|
||||||
|
|
||||||
|
$paginator->setPageSizes(array(50, 100, 200));
|
||||||
|
|
||||||
|
// Set via public API, should now be set to 50
|
||||||
|
$this->assertSame(50, $paginator->getItemsPerPage());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetCurrentPreviousAndNextPages()
|
||||||
|
{
|
||||||
|
$paginator = new GridFieldConfigurablePaginator(20, array(20, 40, 60));
|
||||||
|
$paginator->setGridField($this->gridField);
|
||||||
|
|
||||||
|
// No page selected (first page)
|
||||||
|
$this->assertSame(1, $paginator->getCurrentPage());
|
||||||
|
$this->assertSame(1, $paginator->getPreviousPage());
|
||||||
|
$this->assertSame(2, $paginator->getNextPage());
|
||||||
|
|
||||||
|
// Second page
|
||||||
|
$paginator->setFirstShown(21);
|
||||||
|
$this->assertSame(2, $paginator->getCurrentPage());
|
||||||
|
$this->assertSame(1, $paginator->getPreviousPage());
|
||||||
|
$this->assertSame(3, $paginator->getNextPage());
|
||||||
|
|
||||||
|
// Third page
|
||||||
|
$paginator->setFirstShown(41);
|
||||||
|
$this->assertSame(3, $paginator->getCurrentPage());
|
||||||
|
$this->assertSame(2, $paginator->getPreviousPage());
|
||||||
|
$this->assertSame(4, $paginator->getNextPage());
|
||||||
|
|
||||||
|
// Fourth page, partial record count
|
||||||
|
$paginator->setFirstShown(42);
|
||||||
|
$this->assertSame(4, $paginator->getCurrentPage());
|
||||||
|
$this->assertSame(3, $paginator->getPreviousPage());
|
||||||
|
$this->assertSame(5, $paginator->getNextPage());
|
||||||
|
|
||||||
|
// Last page (default paging)
|
||||||
|
$paginator->setFirstShown(121);
|
||||||
|
$this->assertSame(7, $paginator->getCurrentPage());
|
||||||
|
$this->assertSame(6, $paginator->getPreviousPage());
|
||||||
|
$this->assertSame(7, $paginator->getNextPage());
|
||||||
|
|
||||||
|
// Non-standard page size should recalculate the page numbers to be relative to the page size
|
||||||
|
$paginator->setFirstShown(121);
|
||||||
|
$paginator->setItemsPerPage(60);
|
||||||
|
$this->assertSame(3, $paginator->getCurrentPage());
|
||||||
|
$this->assertSame(2, $paginator->getPreviousPage());
|
||||||
|
$this->assertSame(3, $paginator->getNextPage());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPageSizesAreConfigurable()
|
||||||
|
{
|
||||||
|
// Via constructor
|
||||||
|
$paginator = new GridFieldConfigurablePaginator(3, array(2, 4, 6));
|
||||||
|
$this->assertSame(3, $paginator->getItemsPerPage());
|
||||||
|
$this->assertSame(array(2, 4, 6), $paginator->getPageSizes());
|
||||||
|
|
||||||
|
// Via public API
|
||||||
|
$paginator->setPageSizes(array(10, 20, 30));
|
||||||
|
$this->assertSame(array(10, 20, 30), $paginator->getPageSizes());
|
||||||
|
|
||||||
|
// Via default configuration
|
||||||
|
$paginator = new GridFieldConfigurablePaginator;
|
||||||
|
$default = Config::inst()->get(GridFieldConfigurablePaginator::class, 'default_page_sizes');
|
||||||
|
$this->assertSame($default, $paginator->getPageSizes());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetPageSizesAsList()
|
||||||
|
{
|
||||||
|
$paginator = new GridFieldConfigurablePaginator(10, array(10, 20, 30));
|
||||||
|
$this->assertDOSEquals(array(
|
||||||
|
array('Size' => '10', 'Selected' => true),
|
||||||
|
array('Size' => '20', 'Selected' => false),
|
||||||
|
array('Size' => '30', 'Selected' => false),
|
||||||
|
), $paginator->getPageSizesAsList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException Exception
|
||||||
|
* @expectedExceptionMessage No GridField available yet for this request!
|
||||||
|
*/
|
||||||
|
public function testGetGridFieldThrowsExceptionWhenNotSet()
|
||||||
|
{
|
||||||
|
$paginator = new GridFieldConfigurablePaginator;
|
||||||
|
$paginator->getGridField();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetPagerActions()
|
||||||
|
{
|
||||||
|
$controls = array(
|
||||||
|
'prev' => array(
|
||||||
|
'title' => 'Previous',
|
||||||
|
'args' => array(
|
||||||
|
'next-page' => 123,
|
||||||
|
'first-shown' => 234
|
||||||
|
),
|
||||||
|
'extra-class' => 'ss-gridfield-previouspage',
|
||||||
|
'disable-previous' => false
|
||||||
|
),
|
||||||
|
'next' => array(
|
||||||
|
'title' => 'Next',
|
||||||
|
'args' => array(
|
||||||
|
'next-page' => 234,
|
||||||
|
'first-shown' => 123
|
||||||
|
),
|
||||||
|
'extra-class' => 'ss-gridfield-nextpage',
|
||||||
|
'disable-next' => true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$gridField = $this->getMockBuilder(GridField::class)->disableOriginalConstructor()->getMock();
|
||||||
|
$paginator = new GridFieldConfigurablePaginator;
|
||||||
|
$result = $paginator->getPagerActions($controls, $gridField);
|
||||||
|
|
||||||
|
$this->assertCount(2, $result);
|
||||||
|
$this->assertArrayHasKey('next', $result);
|
||||||
|
$this->assertContainsOnlyInstancesOf(GridField_FormAction::class, $result);
|
||||||
|
|
||||||
|
$this->assertFalse($result['prev']->isDisabled());
|
||||||
|
|
||||||
|
$this->assertTrue((bool) $result['next']->hasClass('ss-gridfield-nextpage'));
|
||||||
|
$this->assertTrue($result['next']->isDisabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSinglePageWithLotsOfItems()
|
||||||
|
{
|
||||||
|
$paginator = new GridFieldConfigurablePaginator(null, array(100, 200, 300));
|
||||||
|
$this->assertSame(100, $paginator->getItemsPerPage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set something to the GridField's paginator state data
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $value
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
protected function setState($key, $value)
|
||||||
|
{
|
||||||
|
$this->gridField->State->GridFieldConfigurablePaginator->$key = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,15 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace Symbiote\GridFieldExtensions\Tests;
|
||||||
|
|
||||||
|
use ReflectionMethod;
|
||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
use SilverStripe\Dev\TestOnly;
|
|
||||||
use SilverStripe\Forms\GridField\GridField;
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor;
|
use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor;
|
||||||
use Symbiote\GridFieldExtensions\GridFieldOrderableRows;
|
use Symbiote\GridFieldExtensions\GridFieldOrderableRows;
|
||||||
use SilverStripe\ORM\DataObject;
|
use Symbiote\GridFieldExtensions\Tests\Stub\StubOrdered;
|
||||||
|
use Symbiote\GridFieldExtensions\Tests\Stub\StubParent;
|
||||||
|
use Symbiote\GridFieldExtensions\Tests\Stub\StubSubclass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for the {@link GridFieldOrderableRows} component.
|
* Tests for the {@link GridFieldOrderableRows} component.
|
||||||
@ -15,27 +19,21 @@ class GridFieldOrderableRowsTest extends SapphireTest
|
|||||||
|
|
||||||
protected $usesDatabase = true;
|
protected $usesDatabase = true;
|
||||||
|
|
||||||
// protected static $fixture_file = 'GridFieldOrderableRowsTest.yml';
|
protected static $fixture_file = 'GridFieldOrderableRowsTest.yml';
|
||||||
|
|
||||||
protected $extraDataObjects = array(
|
protected static $extra_dataobjects = array(
|
||||||
'GridFieldOrderableRowsTest_Parent',
|
StubParent::class,
|
||||||
'GridFieldOrderableRowsTest_Ordered',
|
StubOrdered::class,
|
||||||
'GridFieldOrderableRowsTest_Subclass',
|
StubSubclass::class,
|
||||||
);
|
);
|
||||||
|
|
||||||
public function setUp()
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
$this->markTestSkipped('Upgrade to 4.0: Needs to be re-implemented.');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testReorderItems()
|
public function testReorderItems()
|
||||||
{
|
{
|
||||||
$orderable = new GridFieldOrderableRows('ManyManySort');
|
$orderable = new GridFieldOrderableRows('ManyManySort');
|
||||||
$reflection = new ReflectionMethod($orderable, 'executeReorder');
|
$reflection = new ReflectionMethod($orderable, 'executeReorder');
|
||||||
$reflection->setAccessible(true);
|
$reflection->setAccessible(true);
|
||||||
|
|
||||||
$parent = $this->objFromFixture('GridFieldOrderableRowsTest_Parent', 'parent');
|
$parent = $this->objFromFixture(StubParent::class, 'parent');
|
||||||
|
|
||||||
$config = new GridFieldConfig_RelationEditor();
|
$config = new GridFieldConfig_RelationEditor();
|
||||||
$config->addComponent($orderable);
|
$config->addComponent($orderable);
|
||||||
@ -71,70 +69,27 @@ class GridFieldOrderableRowsTest extends SapphireTest
|
|||||||
{
|
{
|
||||||
$orderable = new GridFieldOrderableRows();
|
$orderable = new GridFieldOrderableRows();
|
||||||
|
|
||||||
$parent = new GridFieldOrderableRowsTest_Parent();
|
$parent = new StubParent();
|
||||||
$parent->write();
|
$parent->write();
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
'GridFieldOrderableRowsTest_Ordered',
|
'StubOrdered',
|
||||||
$orderable->getSortTable($parent->MyHasMany())
|
$orderable->getSortTable($parent->MyHasMany())
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
'GridFieldOrderableRowsTest_Ordered',
|
'StubOrdered',
|
||||||
$orderable->getSortTable($parent->MyHasManySubclass())
|
$orderable->getSortTable($parent->MyHasManySubclass())
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
'GridFieldOrderableRowsTest_Ordered',
|
'StubOrdered',
|
||||||
$orderable->getSortTable($parent->MyManyMany())
|
$orderable->getSortTable($parent->MyManyMany())
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
'GridFieldOrderableRowsTest_Parent_MyManyMany',
|
'StubParent_MyManyMany',
|
||||||
$orderable->setSortField('ManyManySort')->getSortTable($parent->MyManyMany())
|
$orderable->setSortField('ManyManySort')->getSortTable($parent->MyManyMany())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**#@+
|
|
||||||
* @ignore
|
|
||||||
*/
|
|
||||||
|
|
||||||
class GridFieldOrderableRowsTest_Parent extends DataObject implements TestOnly
|
|
||||||
{
|
|
||||||
|
|
||||||
private static $has_many = array(
|
|
||||||
'MyHasMany' => 'GridFieldOrderableRowsTest_Ordered',
|
|
||||||
'MyHasManySubclass' => 'GridFieldOrderableRowsTest_Subclass'
|
|
||||||
);
|
|
||||||
|
|
||||||
private static $many_many = array(
|
|
||||||
'MyManyMany' => 'GridFieldOrderableRowsTest_Ordered'
|
|
||||||
);
|
|
||||||
|
|
||||||
private static $many_many_extraFields = array(
|
|
||||||
'MyManyMany' => array('ManyManySort' => 'Int')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
class GridFieldOrderableRowsTest_Ordered extends DataObject implements TestOnly
|
|
||||||
{
|
|
||||||
|
|
||||||
private static $db = array(
|
|
||||||
'Sort' => 'Int'
|
|
||||||
);
|
|
||||||
|
|
||||||
private static $has_one = array(
|
|
||||||
'Parent' => 'GridFieldOrderableRowsTest_Parent'
|
|
||||||
);
|
|
||||||
|
|
||||||
private static $belongs_many_many =array(
|
|
||||||
'MyManyMany' => 'GridFieldOrderableRowsTest_Parent',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
class GridFieldOrderableRowsTest_Subclass extends GridFieldOrderableRowsTest_Ordered implements TestOnly
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**#@-*/
|
|
||||||
|
@ -1,22 +1,29 @@
|
|||||||
GridFieldOrderableRowsTest_Ordered:
|
Symbiote\GridFieldExtensions\Tests\Stub\StubOrdered:
|
||||||
item1:
|
item1:
|
||||||
|
Sort: 1
|
||||||
item2:
|
item2:
|
||||||
|
Sort: 2
|
||||||
item3:
|
item3:
|
||||||
|
Sort: 3
|
||||||
item4:
|
item4:
|
||||||
|
Sort: 4
|
||||||
item5:
|
item5:
|
||||||
|
Sort: 5
|
||||||
item6:
|
item6:
|
||||||
GridFieldOrderableRowsTest_Parent:
|
Sort: 6
|
||||||
|
|
||||||
|
Symbiote\GridFieldExtensions\Tests\Stub\StubParent:
|
||||||
parent:
|
parent:
|
||||||
MyManyMany:
|
MyManyMany:
|
||||||
- 0: =>GridFieldOrderableRowsTest_Ordered.item1
|
- =>Symbiote\GridFieldExtensions\Tests\Stub\StubOrdered.item1:
|
||||||
ManyManySort: 1
|
ManyManySort: 1
|
||||||
- 1: =>GridFieldOrderableRowsTest_Ordered.item2
|
- =>Symbiote\GridFieldExtensions\Tests\Stub\StubOrdered.item2:
|
||||||
ManyManySort: 1
|
ManyManySort: 1
|
||||||
- 2: =>GridFieldOrderableRowsTest_Ordered.item3
|
- =>Symbiote\GridFieldExtensions\Tests\Stub\StubOrdered.item3:
|
||||||
ManyManySort: 2
|
ManyManySort: 2
|
||||||
- 3: =>GridFieldOrderableRowsTest_Ordered.item4
|
- =>Symbiote\GridFieldExtensions\Tests\Stub\StubOrdered.item4:
|
||||||
ManyManySort: 2
|
ManyManySort: 2
|
||||||
- 4: =>GridFieldOrderableRowsTest_Ordered.item5
|
- =>Symbiote\GridFieldExtensions\Tests\Stub\StubOrdered.item5:
|
||||||
ManyManySort: 108
|
ManyManySort: 108
|
||||||
- 5: =>GridFieldOrderableRowsTest_Ordered.item6
|
- =>Symbiote\GridFieldExtensions\Tests\Stub\StubOrdered.item6:
|
||||||
ManyManySort: 108
|
ManyManySort: 108
|
||||||
|
18
tests/Stub/NamespacedClass.php
Normal file
18
tests/Stub/NamespacedClass.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symbiote\GridFieldExtensions\Tests\Stub;
|
||||||
|
|
||||||
|
use Silverstripe\Dev\TestOnly;
|
||||||
|
|
||||||
|
class NamespacedClass implements TestOnly
|
||||||
|
{
|
||||||
|
public function i18n_singular_name()
|
||||||
|
{
|
||||||
|
return 'NamespacedClass';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canCreate()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
19
tests/Stub/StubA.php
Normal file
19
tests/Stub/StubA.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symbiote\GridFieldExtensions\Tests\Stub;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
|
||||||
|
class StubA implements TestOnly
|
||||||
|
{
|
||||||
|
public function i18n_singular_name()
|
||||||
|
{
|
||||||
|
$class = get_class($this);
|
||||||
|
return substr($class, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canCreate()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
9
tests/Stub/StubB.php
Normal file
9
tests/Stub/StubB.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symbiote\GridFieldExtensions\Tests\Stub;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
|
||||||
|
class StubB extends StubA implements TestOnly
|
||||||
|
{
|
||||||
|
}
|
9
tests/Stub/StubC.php
Normal file
9
tests/Stub/StubC.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symbiote\GridFieldExtensions\Tests\Stub;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
|
||||||
|
class StubC extends StubA implements TestOnly
|
||||||
|
{
|
||||||
|
}
|
23
tests/Stub/StubOrdered.php
Normal file
23
tests/Stub/StubOrdered.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symbiote\GridFieldExtensions\Tests\Stub;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
|
||||||
|
class StubOrdered extends DataObject implements TestOnly
|
||||||
|
{
|
||||||
|
private static $db = array(
|
||||||
|
'Sort' => 'Int'
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $has_one = array(
|
||||||
|
'Parent' => StubParent::class
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $belongs_many_many =array(
|
||||||
|
'MyManyMany' => StubParent::class,
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $table_name = 'StubOrdered';
|
||||||
|
}
|
24
tests/Stub/StubParent.php
Normal file
24
tests/Stub/StubParent.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symbiote\GridFieldExtensions\Tests\Stub;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
|
||||||
|
class StubParent extends DataObject implements TestOnly
|
||||||
|
{
|
||||||
|
private static $has_many = array(
|
||||||
|
'MyHasMany' => StubOrdered::class,
|
||||||
|
'MyHasManySubclass' => StubSubclass::class
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $many_many = array(
|
||||||
|
'MyManyMany' => StubOrdered::class
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $many_many_extraFields = array(
|
||||||
|
'MyManyMany' => array('ManyManySort' => 'Int')
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $table_name = 'StubParent';
|
||||||
|
}
|
11
tests/Stub/StubSubclass.php
Normal file
11
tests/Stub/StubSubclass.php
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symbiote\GridFieldExtensions\Tests\Stub;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
|
||||||
|
class StubSubclass extends StubOrdered implements TestOnly
|
||||||
|
{
|
||||||
|
private static $table_name = 'StubSubclass';
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user