Compare commits

...

47 Commits

Author SHA1 Message Date
UndefinedOffset f6ce5741ab
Added error when a many_many relationship could not be found 2024-05-13 11:21:18 -03:00
UndefinedOffset b1febae3d8
Updated description 2024-01-30 14:45:48 -04:00
UndefinedOffset 9e5908c4ef
Updated description 2024-01-30 14:44:55 -04:00
UndefinedOffset 09f7be61ae
Removed Silverstripe supported badge from the readme 2023-06-16 09:30:10 -03:00
UndefinedOffset 402dab8faa
Updated calls to set-output in the github actions workflow 2023-05-08 10:51:31 -03:00
UndefinedOffset bb65d01748
Removed PHPCS test's plugin enabling 2023-05-08 10:40:38 -03:00
UndefinedOffset e3d92e774a
Changed mysql engine for tests 2023-05-08 10:38:12 -03:00
UndefinedOffset 237716571f
Added missing allow plugins for composer 2023-05-08 10:36:11 -03:00
UndefinedOffset 3940a7475f
Updated changelog and license 2023-05-08 10:32:33 -03:00
UndefinedOffset 29957be873
Enabled Silverstripe 5 testing
Adjusted composer requirements to allow Silverstripe 5

Replaced some deprecated api calls
2023-05-08 10:27:50 -03:00
UndefinedOffset c3915cc2b8
Updated changelog 2022-07-06 14:53:04 -03:00
UndefinedOffset 255347b755
Added allow plugin configs for composer 2 in ci 2022-07-06 14:50:18 -03:00
UndefinedOffset eabbe33342
Adjusted ci workflow to only run against 4.11 2022-07-06 14:46:33 -03:00
Ed Chipman f5a5346349
Merge pull request #134 from GuySartorelli/enh/injectable
NEW Extend new AbstractGridFieldComponent class
2022-07-06 14:42:50 -03:00
UndefinedOffset 66dfcc25ad
Added new badges
Updated the license
2022-02-16 16:29:10 -04:00
UndefinedOffset 6f44c555cd
Renamed tests to have simpler cleaner names 2022-02-16 16:23:08 -04:00
UndefinedOffset 8ed1621f8b
Split unit test classes into separate files 2022-02-16 16:15:33 -04:00
UndefinedOffset 5f37c8a0b4
Added phpunit/phpunit and squizlabs/php_codesniffer as dev dependencies
Coding style update
2022-02-16 15:35:10 -04:00
UndefinedOffset e1b1bbf8b3
Updated PHPUnit config
Added phpcs config

Added GitHub Actions badge

Re-organized tests folder
2022-02-16 15:25:43 -04:00
UndefinedOffset c965eb0c2e
Attempt at getting GitHub actions working 2022-02-16 15:19:42 -04:00
Guy Sartorelli e374c93ae3 NEW Extend new AbstractGridFieldComponent class
This makes the `GridFieldSortableRows` component `Injectable`, and
allows any future enhancements in the new abstract class to
automatically apply without requiring additional changes in this module.

The class is introduced in silverstripe/framework 4.11.0 so the
dependency constraint needs to be updated.
2022-02-12 19:24:44 +13:00
UndefinedOffset fff3f08901
Updated localizations from transifex 2021-07-19 09:51:48 -03:00
Robbie Averill 7bdeebb6cd
Merge pull request #130 from samandeggs/patch-1
Update ModelAdminExample.md
2020-09-17 00:07:24 -07:00
Samuel Mulliss 6a14bfbcc1
Update ModelAdminExample.md
adding semicolon, readability.
2020-09-17 14:14:35 +12:00
Ed Chipman 51c43642ff
Merge pull request #129 from creative-commoners/pulls/master/travis
Update travis
2020-06-24 09:41:38 -03:00
Steve Boyd c3d202d4a0 Update travis, allow dev packages to be installed 2020-06-24 14:48:06 +12:00
Ed Chipman ee5f10e1e7
Merge pull request #128 from sunnysideup/patch-3
MINOR: better example
2020-06-01 11:43:04 -03:00
Nicolaas 902fe50c96
MINOR: better example (#127) 2020-06-01 11:42:19 -03:00
Nicolaas a0d1272238
Update HasManyExample.md 2020-05-30 13:17:03 +12:00
Nicolaas f1a9c92784
MINOR: better example 2020-05-30 13:16:11 +12:00
UndefinedOffset 74756cad52
Re-worked unit tests for Silverstripe 4.4+ compatibility 2020-05-29 10:44:04 -03:00
UndefinedOffset dd955ff1bb
Updated travis config 2020-05-29 08:55:24 -03:00
Robbie Averill 30b50a0597
Merge pull request #126 from sunnysideup/patch-1
MINOR: better keywords
2020-05-28 17:40:34 -07:00
Nicolaas 2e9d0e6b33
MINOR: better keywords 2020-05-29 12:26:04 +12:00
UndefinedOffset af492d0267 Updated changelog
Removed helpfulbot badge

Updated license year
2019-01-08 12:23:14 -04:00
UndefinedOffset 35775ad2ce More adjustments to how ManyManyThroughLists are handled
Fixed issue causing the alert to be empty when an error occurs on the server
2019-01-08 12:21:33 -04:00
UndefinedOffset aef0a8acc1 Updated changelog
Changed Travis postgres and sqlite requirements
2018-12-13 14:38:11 -04:00
UndefinedOffset 3ab5aadf45 Attempt to correct the core release used 2018-12-13 14:31:34 -04:00
UndefinedOffset a622fd4d6f Fixed syntax error in travis config 2018-12-13 14:26:24 -04:00
UndefinedOffset cd86fe2fd4 Fixed composer requirement in travis for versioned 2018-12-13 14:21:06 -04:00
UndefinedOffset fc83d6813e Adjust Travis to use 4.3 and 4.2 2018-12-13 14:15:20 -04:00
UndefinedOffset 8a2417a750 Fixed functionality when using ManyManyThroughList 2018-12-13 14:05:12 -04:00
UndefinedOffset 504387d711 Switched Travis to test against 4.1 2018-07-04 14:06:01 -03:00
UndefinedOffset bc633e151d Fixed issue where versioned objects in would not be flagged as modified preventing the sort order from publishing to the live state when the owner is published 2018-07-04 14:01:37 -03:00
UndefinedOffset ae12e74aa8 Added templates for github (fixes #117) 2018-06-07 09:57:03 -03:00
UndefinedOffset 97b526ea87 Updated changelog 2018-06-07 09:51:29 -03:00
ChrissiQ 118838fb79 Fixes "undefined offset" error when moving a many_many item to previous page (#121)
When viewing the last page of a list of data objects, trying to move one of them to the previous page triggers an "undefined offset" error.
2018-05-31 14:56:51 -03:00
45 changed files with 1605 additions and 964 deletions

2
.gitattributes vendored
View File

@ -2,4 +2,4 @@
/docs export-ignore
/.gitignore export-ignore
/.travis.yml export-ignore
/phpunit.xml.dist export-ignore
/.github export-ignore

14
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,14 @@
## Affected Version
Show version numbers by pasting the output of `composer info --direct`.
Alternatively, hover over the SilverStripe logo in the CMS to basic version information.
## Description
Describe expected and observed behaviour.
For visual issues, please include browser version and screenshots.
Please read https://docs.silverstripe.org/en/contributing/issues_and_bugs/
## Steps to Reproduce
Help us with step-by-step instructions.

5
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,5 @@
Thanks for contributing, you're awesome! :star:
Please describe expected and observed behaviour, and what you're fixing.
For visual fixes, please include tested browsers and screenshots.
Search for related existing issues and link to them if possible.
Please read https://github.com/UndefinedOffset/SortableGridField/blob/master/CONTRIBUTING.md

23
.github/matchers/phpcs.json vendored Normal file
View File

@ -0,0 +1,23 @@
{
"problemMatcher": [
{
"owner": "phpcs",
"severity": "error",
"pattern": [
{
"regexp": "^<file name=\"(?:\\/github\\/workspace\\/)?(.*)\">$",
"file": 1
},
{
"regexp": "<error line=\"(\\d*)\" column=\"(\\d*)\" severity=\"(error|warning)\" message=\"(.*)\" source=\"(.*)(\"\\/>+)$",
"line": 1,
"column": 2,
"severity": 3,
"message": 4,
"code": 5,
"loop": true
}
]
}
]
}

241
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,241 @@
name: CI
on:
push:
branches: [ '**' ]
paths-ignore:
- 'docs/**'
- '*.md'
pull_request:
branches: [ '**' ]
paths-ignore:
- 'docs/**'
- '*.md'
jobs:
silverstripe_5_php81:
name: "Silverstripe 5.0 | PHP 8.1"
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')"
env:
php_version: 8.1
php_extensions: ctype, dom, fileinfo, hash, intl, mbstring, session, simplexml, tokenizer, xml, pdo, mysqli, gd, zip
services:
mysql:
image: mysql:5.7
env:
MYSQL_ALLOW_EMPTY_PASSWORD: false
MYSQL_ROOT_PASSWORD: testpassword
MYSQL_DATABASE: test_db
ports:
- 3306/tcp
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup PHP Extension Cache
id: cache-env
uses: shivammathur/cache-extensions@v1
with:
php-version: ${{ env.php_version }}
extensions: ${{ env.php_extensions }}
key: php74-ext-cache-${{ hashFiles('.github/workflows/ci.yml') }}
- name: Cache PHP Extensions
uses: actions/cache@v3
with:
path: ${{ steps.cache-env.outputs.dir }}
key: ${{ steps.cache-env.outputs.key }}
restore-keys: ${{ steps.cache-env.outputs.key }}
- name: Setup PHP, with composer and extensions
uses: shivammathur/setup-php@v2
with:
php-version: ${{ env.php_version }}
extensions: ${{ env.php_extensions }}
ini-values: log_errors=On, error_log="${{github.workspace}}/artifacts/php_errors.log"
coverage: none
tools: composer:v2
- name: Get composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache composer dependencies
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-ss5-php81-${{ hashFiles('**/composer.json') }}-${{ hashFiles('.github/workflows/ci.yml') }}
restore-keys: ${{ runner.os }}-composer-ss5-php81-
- name: Install Composer dependencies
env:
GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
composer self-update --ansi || true
if [[ $GITHUB_ACCESS_TOKEN ]]; then composer config --ansi -g github-oauth.github.com $GITHUB_ACCESS_TOKEN; fi
composer config allow-plugins.composer/installers true
composer config allow-plugins.silverstripe/recipe-plugin true
composer config allow-plugins.silverstripe/vendor-plugin true
composer require silverstripe/admin 2.0.* --no-update
composer require silverstripe/versioned 2.0.*
composer install --verbose --no-interaction --no-progress --no-suggest --optimize-autoloader --ansi
- name: Configure Environment
run: |
cp tests/utils/actions.env.template .env
mkdir artifacts
- name: Perform PHPUnit Tests
env:
SS_DATABASE_PORT: ${{ job.services.mysql.ports['3306'] }}
run: vendor/bin/phpunit --colors=always --printer UndefinedOffset\\SortableGridField\\Tests\\PHPUnit\\Bootstrap\\GitHubActionsAnnotatorPrinter
silverstripe_411_php80:
name: "Silverstripe 4.11 | PHP 8.0"
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')"
env:
php_version: 8.0
php_extensions: ctype, dom, fileinfo, hash, intl, mbstring, session, simplexml, tokenizer, xml, pdo, mysqli, gd, zip
services:
mysql:
image: mysql:5.7
env:
MYSQL_ALLOW_EMPTY_PASSWORD: false
MYSQL_ROOT_PASSWORD: testpassword
MYSQL_DATABASE: test_db
ports:
- 3306/tcp
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup PHP Extension Cache
id: cache-env
uses: shivammathur/cache-extensions@v1
with:
php-version: ${{ env.php_version }}
extensions: ${{ env.php_extensions }}
key: php80-ext-cache-${{ hashFiles('.github/workflows/ci.yml') }}
- name: Cache PHP Extensions
uses: actions/cache@v3
with:
path: ${{ steps.cache-env.outputs.dir }}
key: ${{ steps.cache-env.outputs.key }}
restore-keys: ${{ steps.cache-env.outputs.key }}
- name: Setup PHP, with composer and extensions
uses: shivammathur/setup-php@v2
with:
php-version: ${{ env.php_version }}
extensions: ${{ env.php_extensions }}
ini-values: log_errors=On, error_log="${{github.workspace}}/artifacts/php_errors.log"
coverage: none
tools: composer:v2
- name: Get composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache composer dependencies
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-ss411-php80-${{ hashFiles('**/composer.json') }}-${{ hashFiles('.github/workflows/ci.yml') }}
restore-keys: ${{ runner.os }}-composer-ss411-php80-
- name: Install Composer dependencies
env:
GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
composer self-update --ansi || true
if [[ $GITHUB_ACCESS_TOKEN ]]; then composer config --ansi -g github-oauth.github.com $GITHUB_ACCESS_TOKEN; fi
composer config allow-plugins.composer/installers true
composer config allow-plugins.silverstripe/recipe-plugin true
composer config allow-plugins.silverstripe/vendor-plugin true
composer require silverstripe/admin 1.11.* --no-update
composer require silverstripe/versioned 1.11.*
composer install --verbose --no-interaction --no-progress --no-suggest --optimize-autoloader --ansi
- name: Configure Environment
run: |
cp tests/utils/actions.env.template .env
mkdir artifacts
- name: Perform PHPUnit Tests
env:
SS_DATABASE_PORT: ${{ job.services.mysql.ports['3306'] }}
run: vendor/bin/phpunit --colors=always --printer UndefinedOffset\\SortableGridField\\Tests\\PHPUnit\\Bootstrap\\GitHubActionsAnnotatorPrinter
phpcs:
name: "PHP_CodeSniffer"
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')"
env:
php_version: 8.0
php_extensions: ctype, dom, fileinfo, hash, intl, mbstring, session, simplexml, tokenizer, xml, pdo, mysqli, gd, zip
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup PHP Extension Cache
id: cache-env
uses: shivammathur/cache-extensions@v1
with:
php-version: ${{ env.php_version }}
extensions: ${{ env.php_extensions }}
key: php74-ext-cache-${{ hashFiles('.github/workflows/ci.yml') }}
- name: Cache PHP Extensions
uses: actions/cache@v3
with:
path: ${{ steps.cache-env.outputs.dir }}
key: ${{ steps.cache-env.outputs.key }}
restore-keys: ${{ steps.cache-env.outputs.key }}
- name: Setup PHP, with composer and extensions
uses: shivammathur/setup-php@v2
with:
php-version: ${{ env.php_version }}
extensions: ${{ env.php_extensions }}
ini-values: log_errors=On, error_log="${{github.workspace}}/artifacts/php_errors.log"
coverage: none
tools: composer:v2
- name: Get composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache composer dependencies
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-phpcs-${{ hashFiles('.github/workflows/ci.yml') }}
restore-keys: ${{ runner.os }}-composer-phpcs-
- name: Install Composer dependencies
env:
GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
rm composer.json
composer self-update --ansi || true
if [[ $GITHUB_ACCESS_TOKEN ]]; then composer config --ansi -g github-oauth.github.com $GITHUB_ACCESS_TOKEN; fi
composer require squizlabs/php_codesniffer ~3.4
composer install --verbose --no-interaction --no-progress --no-suggest --optimize-autoloader --ansi
mkdir artifacts
- name: Validate Code Style
run: vendor/bin/phpcs --colors --report=full --report-checkstyle=artifacts/phpcs.xml
- name: Annotate Code Style Issues
if: failure()
run: (test -f artifacts/phpcs.xml && echo "::add-matcher::.github/matchers/phpcs.json" && cat artifacts/phpcs.xml && echo "::remove-matcher owner=phpcs::")

3
.gitignore vendored
View File

@ -2,4 +2,5 @@
/.buildpath
/.project
/.settings
/.settings/*
/.settings/*
.phpunit.result.cache

View File

@ -1,19 +1,27 @@
language: php
php:
- 5.6
- 7.0
- 7.1
dist: xenial
env:
- DB=MYSQL CORE_RELEASE=4.0
services:
- mysql
- postgresql
cache:
directories:
- $HOME/.composer/cache/files
matrix:
include:
- php: 5.6
env: DB=MYSQL CORE_RELEASE=4.4.x-dev PHPUNIT_TEST=1
- php: 7.1
env: DB=PGSQL CORE_RELEASE=4.0
- php: 7.1
env: DB=SQLITE3 CORE_RELEASE=4.0
env: DB=MYSQL CORE_RELEASE=4.5.x-dev PHPUNIT_TEST=1 PDO=1
- php: 7.2
env: DB=PGSQL CORE_RELEASE=4.6.x-dev PHPUNIT_TEST=1
- php: 7.3
env: DB=MYSQL CORE_RELEASE=4.6.x-dev PHPUNIT_TEST=1
- php: 7.4
env: DB=MYSQL CORE_RELEASE=4.x-dev PHPUNIT_TEST=1
before_script:
# Init PHP
@ -23,11 +31,12 @@ before_script:
# Install composer dependencies
- composer validate
- composer require --no-update silverstripe/recipe-core:^1.0
- composer require --no-update silverstripe/recipe-core:$CORE_RELEASE
- composer require --no-update phpunit/phpunit:^5.7
- if [[ $DB == PGSQL ]]; then composer require silverstripe/postgresql:2.0.x-dev --prefer-dist --no-update; fi
- if [[ $DB == SQLITE ]]; then composer require silverstripe/sqlite3:2.1.x-dev --prefer-dist --no-update; fi
# Fix for running phpunit 5 on php 7.4+
- composer require --no-update sminnee/phpunit-mock-objects:^3
- if [[ $DB == PGSQL ]]; then composer require silverstripe/postgresql:^2 --prefer-dist --no-update; fi
- composer install --prefer-dist --no-interaction --no-progress --no-suggest --optimize-autoloader --verbose --profile
script:
- vendor/bin/phpunit
- vendor/bin/phpunit

View File

@ -1,12 +1,37 @@
# Change Log
## [2.0.4](https://github.com/UndefinedOffset/SortableGridField/tree/2.0.4) (2018-03-07)
[Full Changelog](https://github.com/UndefinedOffset/SortableGridField/compare/2.0.3...2.0.4)
## [2.2.0](https://github.com/UndefinedOffset/SortableGridField/tree/2.2.0) (2023-05-08)
[Full Changelog](https://github.com/UndefinedOffset/SortableGridField/compare/2.1.0...2.2.0)
## [2.1.0](https://github.com/UndefinedOffset/SortableGridField/tree/2.1.0) (2022-07-06)
[Full Changelog](https://github.com/UndefinedOffset/SortableGridField/compare/2.0.9...2.1.0)
## [2.0.9](https://github.com/UndefinedOffset/SortableGridField/tree/2.0.9) (2021-07-19)
[Full Changelog](https://github.com/UndefinedOffset/SortableGridField/compare/2.0.8...2.0.9)
## [2.0.8](https://github.com/UndefinedOffset/SortableGridField/tree/2.0.8) (2019-01-08)
[Full Changelog](https://github.com/UndefinedOffset/SortableGridField/compare/2.0.7...2.0.8)
## [2.0.7](https://github.com/UndefinedOffset/SortableGridField/tree/2.0.7) (2018-12-13)
[Full Changelog](https://github.com/UndefinedOffset/SortableGridField/compare/2.0.6...2.0.7)
## [2.0.6](https://github.com/UndefinedOffset/SortableGridField/tree/2.0.6) (2018-07-04)
[Full Changelog](https://github.com/UndefinedOffset/SortableGridField/compare/2.0.5...2.0.6)
## [2.0.5](https://github.com/UndefinedOffset/SortableGridField/tree/2.0.5) (2018-06-07)
[Full Changelog](https://github.com/UndefinedOffset/SortableGridField/compare/2.0.4...2.0.5)
**Closed issues:**
- Int to DBInt [\#120](https://github.com/UndefinedOffset/SortableGridField/issues/120)
**Merged pull requests:**
- Fixes "undefined offset" error when moving a many\_many item to previous page [\#121](https://github.com/UndefinedOffset/SortableGridField/pull/121) ([ChrissiQ](https://github.com/ChrissiQ))
## [2.0.4](https://github.com/UndefinedOffset/SortableGridField/tree/2.0.4) (2018-03-07)
[Full Changelog](https://github.com/UndefinedOffset/SortableGridField/compare/2.0.3...2.0.4)
## [2.0.3](https://github.com/UndefinedOffset/SortableGridField/tree/2.0.3) (2018-03-01)
[Full Changelog](https://github.com/UndefinedOffset/SortableGridField/compare/2.0.2...2.0.3)

View File

@ -1,4 +1,4 @@
Copyright (c) 2017, Ed Chipman
Copyright (c) 2024, Ed Chipman
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,

View File

@ -1,13 +1,17 @@
SortableGridField
=================
[![Build Status](https://travis-ci.org/UndefinedOffset/SortableGridField.png)](https://travis-ci.org/UndefinedOffset/SortableGridField) ![helpfulrobot](https://helpfulrobot.io/undefinedoffset/sortablegridfield/badge)
[![CI](https://github.com/UndefinedOffset/SortableGridField/actions/workflows/ci.yml/badge.svg)](https://github.com/UndefinedOffset/SortableGridField/actions/workflows/ci.yml)
[![Latest Stable Version](https://poser.pugx.org/undefinedoffset/sortablegridfield/version.svg)](http://www.silverstripe.org/stable-download/)
[![Latest Unstable Version](https://poser.pugx.org/undefinedoffset/sortablegridfield/v/unstable.svg)](https://packagist.org/packages/undefinedoffset/sortablegridfield)
[![Total Downloads](https://poser.pugx.org/undefinedoffset/sortablegridfield/downloads.svg)](https://packagist.org/packages/undefinedoffset/sortablegridfield)
[![License](https://poser.pugx.org/undefinedoffset/sortablegridfield/license.svg)](https://github.com/UndefinedOffset/SortableGridField/blob/master/LICENSE)
Adds drag and drop functionality to SilverStripe 4's GridField
Adds drag and drop functionality to Silverstripe's GridField
## Requirements
* SilverStripe 4.x
* Silverstripe 4.11+ or 5.0+
## Installation
@ -25,12 +29,12 @@ to the end of the address to force the templates to regenerate
To enable sorting on a `has_many` relationship set up an integer field on your data object. Also for `has_many`
relationships make sure to set the `$default_sort` on the `DataObject` to this new integer field to ensure that the sort
order is applied when the relationship is requested. For `many_many` relationships you must add a
`$many_many_extraFields` static to the `DataObject` defining the relationship, see the
[SilverStripe documentation](https://docs.silverstripe.org/en/3/developer_guides/model/relations/#many-many)
for more information on this. If you are using a `many_many` relationship you will need to do a custom getter to set the
order is applied when the relationship is requested. For `many_many` relationships you must add a
`$many_many_extraFields` static to the `DataObject` defining the relationship, see the
[SilverStripe documentation](https://docs.silverstripe.org/en/3/developer_guides/model/relations/#many-many)
for more information on this. If you are using a `many_many` relationship you will need to do a custom getter to set the
sort order of this relationship for use on the front end see below for an example. As well for `many_many` relationships
the name of the GridField *must* be the same as the relationship name other wise error's will occur. For new
the name of the GridField *must* be the same as the relationship name other wise error's will occur. For new
`DataObject`s you do not need to increment the sort order yourself in your `DataObject`, `GridFieldSortableRows` will
automatically do this the next time the grid is displayed.
@ -116,7 +120,7 @@ When you're reporting an issue please ensure you specify what version of SilverS
3.1beta3, 3.0-master etc. Also be sure to include any JavaScript or PHP errors you receive, for PHP errors please ensure
you include the full stack trace. Also please include your implementation code (where your setting up your grid field)
as well as how you produced the issue. You may also be asked to provide some of the classes to aid in re-producing the
issue. Stick with the issue, remember that you seen the issue not the maintainer of the module so it may take a lot of
issue. Stick with the issue, remember that you seen the issue not the maintainer of the module so it may take a lot of
questions to arrive at a fix or answer.
### Notes

View File

@ -1,8 +1,8 @@
{
"name": "undefinedoffset/sortablegridfield",
"description": "Adds drag and drop functionality to SilverStripe 4.x's GridField",
"description": "Adds drag and drop functionality to Silverstripe's GridField",
"type": "silverstripe-vendormodule",
"keywords": ["silverstripe", "gridfield"],
"keywords": ["silverstripe", "gridfield", "sortable", "sort"],
"license": "BSD-3-Clause",
"authors": [
{
@ -12,10 +12,13 @@
}
],
"require": {
"silverstripe/framework": "~4.0",
"silverstripe/versioned": "^1.0",
"silverstripe/vendor-plugin": "^1.0"
"silverstripe/framework": "~4.11 | ^5",
"silverstripe/versioned": "^1 | ^2"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"squizlabs/php_codesniffer": "~3.4"
},
"autoload": {
"psr-4": {
"UndefinedOffset\\SortableGridField\\": "src/",
@ -34,5 +37,7 @@
"branch-alias": {
"dev-master": "2.0.x-dev"
}
}
},
"prefer-stable": true,
"minimum-stability": "dev"
}

View File

@ -2,28 +2,37 @@ has_many Example
=================
```php
/*** TestPage.php ***/
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor;
use UndefinedOffset\SortableGridField\Forms\GridFieldSortableRows;
class TestPage extends Page
{
private static $has_many = [
'TestObjects' => 'TestObject',
];
private static $has_many = [
'TestObjects' => 'TestObject',
];
public function getCMSFields()
{
$fields = parent::getCMSFields();
$conf = GridFieldConfig_RecordEditor::create(10);
$conf->addComponent(new GridFieldSortableRows('SortOrder'));
public function getCMSFields()
{
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.TestObjects', new GridField('TestObjects', 'TestObjects', $this->TestObjects(), $conf));
$conf = GridFieldConfig_RelationEditor::create(10);
$conf->addComponent(GridFieldSortableRows::create('SortOrder'));
return $fields;
}
$fields->addFieldToTab(
'Root.TestObjects',
GridField::create(
'TestObjects',
'TestObjects',
$this->TestObjects(),
$conf
)
);
return $fields;
}
}
@ -32,15 +41,18 @@ use SilverStripe\ORM\DataObject;
class TestObject extends DataObject
{
private static $db = [
'Title' => 'Text',
'SortOrder' => 'Int',
];
private static $db = [
'Title' => 'Text',
'SortOrder' => 'Int',
];
private static $indexes = [
'SortOrder' => true,
];
private static $has_one = [
'Parent' => 'TestPage',
];
private static $default_sort = 'SortOrder';
private static $default_sort = 'SortOrder';
}
```

View File

@ -25,9 +25,9 @@ class TestPage extends Page
$fields = parent::getCMSFields();
$conf = GridFieldConfig_RelationEditor::create(10);
$conf->addComponent(new GridFieldSortableRows('SortOrder'));
$conf->addComponent(GridFieldSortableRows::create('SortOrder'));
$fields->addFieldToTab('Root.TestObjects', new GridField('TestObjects', 'TestObjects', $this->TestObjects(), $conf));
$fields->addFieldToTab('Root.TestObjects', GridField::create('TestObjects', 'TestObjects', $this->TestObjects(), $conf));
return $fields;
}

View File

@ -10,22 +10,24 @@ use UndefinedOffset\SortableGridField\Forms\GridFieldSortableRows;
class MyModelAdmin extends ModelAdmin
{
private static $menu_title = 'My Model Admin';
private static $url_segment = 'my-model-admin';
private static $managed_models = [
'MATestObject',
MATestObject::class,
];
public function getEditForm($id = null, $fields = null)
{
$form = parent::getEditForm($id, $fields);
//This check is simply to ensure you are on the managed model you want adjust accordingly
if($this->modelClass == 'MATestObject' && $gridField = $form->Fields()->dataFieldByName($this->sanitiseClassName($this->modelClass))) {
//This is just a precaution to ensure we got a GridField from dataFieldByName() which you should have
if($gridField instanceof GridField) {
$gridField->getConfig()->addComponent(new GridFieldSortableRows('SortOrder'));
// This check is simply to ensure you are on the managed model you want adjust accordingly
if ($this->modelClass === MATestObject::class) {
$gridField = $form->Fields()->dataFieldByName($this->sanitiseClassName($this->modelClass));
// This is just a precaution to ensure we got a GridField from dataFieldByName() which you should have
if ($gridField instanceof GridField) {
$gridField->getConfig()->addComponent(GridFieldSortableRows::create('SortOrder'));
}
}
@ -43,6 +45,10 @@ class MATestObject extends DataObject
'SortOrder' => 'Int',
];
private static $indexes = [
'SortOrder' => true,
];
private static $default_sort = 'SortOrder';
}
```

View File

@ -107,7 +107,7 @@
dataType: 'html',
success: callback,
error: function (e) {
alert(ss.i18n._t('GRIDFIELD.ERRORINTRANSACTION'));
alert(ss.i18n._t('Admin.ERRORINTRANSACTION', 'An error occured while fetching data from the server\n Please try again later.'));
}
}, ajaxOpts));
}

6
lang/da.yml Normal file
View File

@ -0,0 +1,6 @@
da:
GridFieldSortableRows:
ALLOW_DRAG_DROP: 'Tillad træk og slip sortering'
EditPermissionsFailure: 'Manglende tilladelse til at redigere'
NEXT: 'Flyt til næste side'
PREVIOUS: 'Flyt til forrige side'

View File

@ -2,3 +2,5 @@ nl:
GridFieldSortableRows:
ALLOW_DRAG_DROP: 'Rangschikken met drag & drop toestaan'
EditPermissionsFailure: 'Geen toegang'
NEXT: 'Verplaats naar Volgende Pagina'
PREVIOUS: 'Verplaats naar Vorige Pagina'

View File

@ -2,3 +2,5 @@ pl:
GridFieldSortableRows:
ALLOW_DRAG_DROP: 'Pozwól na reorganizację przez drag and drop'
EditPermissionsFailure: 'Brak możliwości edycji'
NEXT: 'Przenieś do następnej strony'
PREVIOUS: 'Przenieś do poprzedniej strony'

6
lang/sl.yml Normal file
View File

@ -0,0 +1,6 @@
sl:
GridFieldSortableRows:
ALLOW_DRAG_DROP: 'Omogoči razvrščanje s "povleci in spusti" '
EditPermissionsFailure: 'Nimate pravic za urejanje'
NEXT: 'Prestavi na naslednjo stran'
PREVIOUS: 'Prestavi na prejšnjo stran'

View File

@ -2,3 +2,5 @@ sv:
GridFieldSortableRows:
ALLOW_DRAG_DROP: 'Aktivera dra och släpp sortering'
EditPermissionsFailure: 'Rättighet för att redigera saknas'
NEXT: 'Gå till nästa sida'
PREVIOUS: 'Gå till föregående sida'

49
phpcs.xml.dist Normal file
View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="SilverStripe">
<description>CodeSniffer ruleset for SilverStripe coding conventions.</description>
<!-- base rules are PSR-2 -->
<rule ref="PSR2" >
<!-- Current exclusions -->
<exclude name="PSR1.Methods.CamelCapsMethodName" />
<exclude name="PSR1.Files.SideEffects.FoundWithSymbols" />
<exclude name="PSR2.Classes.PropertyDeclaration" />
<exclude name="PSR2.Methods.MethodDeclaration.Underscore" />
<exclude name="Squiz.Scope.MethodScope" />
<exclude name="Squiz.Classes.ValidClassName.NotCamelCaps" />
<exclude name="Generic.Files.LineLength.TooLong" />
<exclude name="PEAR.Functions.ValidDefaultValue.NotAtEnd" />
<exclude name="PSR2.ControlStructures.ElseIfDeclaration" />
</rule>
<rule ref="Squiz.Strings.ConcatenationSpacing">
<properties>
<property name="spacing" value="1" />
<property name="ignoreNewlines" value="true"/>
</properties>
</rule>
<rule ref="PEAR.ControlStructures.MultiLineCondition" />
<rule ref="Generic.Formatting.SpaceAfterCast" />
<rule ref="Generic.Arrays.DisallowLongArraySyntax.Found">
<type>warning</type>
</rule>
<rule ref="Squiz.Arrays.ArrayDeclaration.NoComma" />
<rule ref="Squiz.WhiteSpace.OperatorSpacing">
<properties>
<property name="ignoreNewlines" value="true" />
</properties>
</rule>
<rule ref="PSR12.Functions.ReturnTypeDeclaration" />
<!-- include php files only -->
<arg name="extensions" value="php,lib,inc,php5"/>
<file>./src</file>
<file>./tests</file>
<file>./_config.php</file>
</ruleset>

View File

@ -1,5 +1,27 @@
<phpunit bootstrap="vendor/silverstripe/framework/tests/bootstrap.php" colors="true">
<testsuite name="Default">
<directory>tests/</directory>
</testsuite>
<?xml version="1.0"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/silverstripe/framework/tests/bootstrap.php" colors="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<testsuites>
<testsuite name="Default">
<directory suffix=".php">tests/PHPUnit</directory>
</testsuite>
</testsuites>
<groups>
<exclude>
<group>sanitychecks</group>
</exclude>
</groups>
<coverage includeUncoveredFiles="true">
<include>
<directory suffix=".php">src/</directory>
</include>
<exclude>
<directory suffix=".php">tests/</directory>
</exclude>
</coverage>
<php>
<get name="flush" value="1"/>
</php>
</phpunit>

View File

@ -1,13 +1,12 @@
<?php
namespace UndefinedOffset\SortableGridField\Forms;
use SilverStripe\Admin\ModelAdmin;
use SilverStripe\Control\Controller;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Extensible;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forms\GridField\AbstractGridFieldComponent;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridField_ActionProvider;
use SilverStripe\Forms\GridField\GridField_DataManipulator;
@ -16,12 +15,11 @@ use SilverStripe\Forms\GridField\GridField_HTMLProvider;
use SilverStripe\Forms\GridField\GridFieldFilterHeader;
use SilverStripe\Forms\GridField\GridFieldPaginator;
use SilverStripe\Forms\GridField\GridFieldSortableHeader;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DataObjectSchema;
use SilverStripe\ORM\DataQuery;
use SilverStripe\ORM\DB;
use SilverStripe\ORM\ManyManyList;
use SilverStripe\ORM\ManyManyThroughList;
use SilverStripe\ORM\RelationList;
use SilverStripe\ORM\SS_List;
use SilverStripe\ORM\UnsavedRelationList;
@ -32,10 +30,8 @@ use SilverStripe\View\Requirements;
/**
* This component provides a checkbox which when checked enables drag-and-drop re-ordering of elements displayed in a {@link GridField}
*
* @package forms
*/
class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionProvider, GridField_DataManipulator
class GridFieldSortableRows extends AbstractGridFieldComponent implements GridField_HTMLProvider, GridField_ActionProvider, GridField_DataManipulator
{
/** @var string */
protected $sortColumn;
@ -76,7 +72,7 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
$dataList = $gridField->getList();
if (class_exists('UnsavedRelationList') && $dataList instanceof UnsavedRelationList) {
return array();
return [];
}
$state = $gridField->State->GridFieldSortableRows;
@ -86,7 +82,7 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
//Ensure user can edit
if (!singleton($gridField->getModelClass())->canEdit()) {
return array();
return [];
}
@ -119,20 +115,22 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
)->addExtraClass('sortablerows-sorttopage');
$data = array('SortableToggle' => $sortOrderToggle,
$data = [
'SortableToggle' => $sortOrderToggle,
'SortOrderSave' => $sortOrderSave,
'SortToPage' => $sortToPage,
'Checked' => ($state->sortableToggle == true ? ' checked = "checked"' : ''),
'List' => $dataList);
'List' => $dataList,
];
$forTemplate = new arrayData($data);
$forTemplate = new ArrayData($data);
Requirements::css('undefinedoffset/sortablegridfield:css/GridFieldSortableRows.css');
Requirements::javascript('undefinedoffset/sortablegridfield:javascript/GridFieldSortableRows.js');
$args = array('Colspan' => count($gridField->getColumns()), 'ID' => $gridField->ID(), 'DisableSelection' => $this->disable_selection);
$args = ['Colspan' => count($gridField->getColumns()), 'ID' => $gridField->ID(), 'DisableSelection' => $this->disable_selection];
$fragments = array('header' => $forTemplate->renderWith('SortableGridField\Forms\Includes\GridFieldSortableRows', $args));
$fragments = ['header' => $forTemplate->renderWith('SortableGridField\Forms\Includes\GridFieldSortableRows', $args)];
if ($gridField->getConfig()->getComponentByType(GridFieldPaginator::class)) {
$fragments['after'] = $forTemplate->renderWith('SortableGridField\Forms\Includes\GridFieldSortableRows_paginator');
@ -144,8 +142,8 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
/**
* Manipulate the datalist as needed by this grid modifier.
* @param GridField $gridField Grid Field Reference
* @param SS_List|DataList $dataList Data List to adjust
* @return DataList Modified Data List
* @param SS_List|\SilverStripe\ORM\DataList $dataList Data List to adjust
* @return \SilverStripe\ORM\DataList Modified Data List
*/
public function getManipulatedData(GridField $gridField, SS_List $dataList)
{
@ -213,7 +211,7 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
/**
* Detects and corrects items with a sort column value of 0, by appending them to the bottom of the list
* @param GridField $gridField Grid Field Reference
* @param SS_List|DataList $dataList Data List of items to be checked
* @param SS_List|\SilverStripe\ORM\DataList $dataList Data List of items to be checked
*/
protected function fixSortColumn($gridField, SS_List $dataList)
{
@ -221,15 +219,15 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
return;
}
/** @var SS_List|DataList $list */
/** @var SS_List|\SilverStripe\ORM\DataList $list */
$list = clone $dataList;
$list = $list->alterDataQuery(function ($query, SS_List $tmplist) {
/** @var DataQuery $query */
$query->limit(array());
/** @var \SilverStripe\ORM\DataQuery $query */
$query->limit(null);
return $query;
});
$many_many = ($list instanceof ManyManyList);
$many_many = ($list instanceof ManyManyList || $list instanceof ManyManyThroughList);
if (!$many_many) {
$sng = singleton($gridField->getModelClass());
$fieldType = $sng->config()->db[$this->sortColumn];
@ -253,13 +251,22 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
$i = 1;
if ($many_many) {
$schema=Injector::inst()->get(DataObjectSchema::class);
$componentDetails=$schema->manyManyComponent(get_class($owner), (!empty($this->custom_relation_name) ? $this->custom_relation_name : $gridField->getName()));
$parentField=$componentDetails['parentField'];
$componentField=$componentDetails['childField'];
$table=$componentDetails['join'];
$schema = Injector::inst()->get(DataObjectSchema::class);
$componentDetails = $schema->manyManyComponent(get_class($owner), (!empty($this->custom_relation_name) ? $this->custom_relation_name : $gridField->getName()));
if (empty($componentDetails)) {
user_error('Could not find the relationship "' . (!empty($this->custom_relation_name) ? $this->custom_relation_name : $gridField->getName()) . '" on "' . get_class($owner) . '"', E_USER_ERROR);
}
$extraFields = $schema->manyManyExtraFieldsForComponent(get_class($owner), (!empty($this->custom_relation_name) ? $this->custom_relation_name : $gridField->getName()));
$parentField = $componentDetails['parentField'];
$componentField = $componentDetails['childField'];
$table = $componentDetails['join'];
//For ManyManyThroughLists get the right join table
if ($list instanceof ManyManyThroughList && class_exists($table)) {
$table = $schema->tableName($table);
}
$extraFields = $list->getExtraFields();
if (!$extraFields || !array_key_exists($this->sortColumn, $extraFields) || !($extraFields[$this->sortColumn] == 'Int' || $extraFields[$this->sortColumn] == 'SilverStripe\\ORM\\FieldType\\DBInt' || is_subclass_of('SilverStripe\\ORM\\FieldType\\DBInt', $extraFields[$this->sortColumn]))) {
user_error('Sort column ' . $this->sortColumn . ' must be an SilverStripe\\ORM\\FieldType\\DBInt, column is of type ' . $extraFields[$this->sortColumn], E_USER_ERROR);
@ -305,9 +312,11 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
}
if ($this->append_to_top) {
$topIncremented = array();
$topIncremented = [];
}
$modelClass = $gridField->getModelClass();
$hasVersioned = $this->hasVersionedExtension($modelClass);
foreach ($list as $obj) {
if ($many_many) {
if ($this->append_to_top) {
@ -324,10 +333,21 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
. ' WHERE "' . $componentField . '" = ' . $obj->ID . ' AND "' . $parentField . '" = ' . $owner->ID);
}
} else if ($this->append_to_top) {
//Upgrade all the records (including the last inserted from 0 to 1)
DB::query('UPDATE "' . $table
. '" SET "' . $sortColumn . '" = "' . $sortColumn . '"+1'
. ' WHERE ' . ($list instanceof RelationList ? '"' . $list->foreignKey . '" = ' . $owner->ID : $idCondition) . (!empty($topIncremented) ? ' AND "ID" NOT IN(\'' . implode('\',\'', $topIncremented) . '\')' : ''));
if ($hasVersioned) {
// For versioned objects, modify them with the ORM so that the *_versions table is updated
$itemsToUpdate = $modelClass::get()->where(($list instanceof RelationList ? '"' . $list->foreignKey . '" = ' . $owner->ID : $idCondition) . (!empty($topIncremented) ? ' AND "ID" NOT IN(\'' . implode('\',\'', $topIncremented) . '\')' : ''));
if ($itemsToUpdate->exists()) {
foreach ($itemsToUpdate as $item) {
$item->$sortColumn = $item->$sortColumn + 1;
$item->write();
}
}
} else {
//Upgrade all the records (including the last inserted from 0 to 1)
DB::query('UPDATE "' . $table
. '" SET "' . $sortColumn . '" = "' . $sortColumn . '"+1'
. ' WHERE ' . ($list instanceof RelationList ? '"' . $list->foreignKey . '" = ' . $owner->ID : $idCondition) . (!empty($topIncremented) ? ' AND "ID" NOT IN(\'' . implode('\',\'', $topIncremented) . '\')' : ''));
}
if ($this->update_versioned_stage && $this->hasVersionedExtension($gridField->getModelClass())) {
DB::query('UPDATE "' . $table . '_' . $this->update_versioned_stage
@ -337,14 +357,21 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
$topIncremented[] = $obj->ID;
} else {
//Append the last record to the bottom
DB::query('UPDATE "' . $table
. '" SET "' . $sortColumn . '" = ' . ($max + $i)
. ' WHERE "ID" = ' . $obj->ID);
//LastEdited
DB::query('UPDATE "' . $baseDataTable
. '" SET "LastEdited" = \'' . date('Y-m-d H:i:s') . '\''
. ' WHERE "ID" = ' . $obj->ID);
if ($hasVersioned) {
// For versioned objects, modify them with the ORM so that the *_versions table is updated
$obj->$sortColumn = ($max + $i);
$obj->write();
} else {
//Append the last record to the bottom
DB::query('UPDATE "' . $table
. '" SET "' . $sortColumn . '" = ' . ($max + $i)
. ' WHERE "ID" = ' . $obj->ID);
//LastEdited
DB::query('UPDATE "' . $baseDataTable
. '" SET "LastEdited" = \'' . date('Y-m-d H:i:s') . '\''
. ' WHERE "ID" = ' . $obj->ID);
}
if ($this->update_versioned_stage && $this->hasVersionedExtension($gridField->getModelClass())) {
DB::query('UPDATE "' . $table . '_' . $this->update_versioned_stage
@ -390,7 +417,7 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
*/
public function getActions($gridField)
{
return array('saveGridRowSort', 'sortableRowsToggle', 'sortToPage');
return ['saveGridRowSort', 'sortableRowsToggle', 'sortToPage'];
}
/**
@ -444,7 +471,7 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
$className = $gridField->getModelClass();
$owner = $gridField->Form->getRecord();
$items = clone $gridField->getList();
$many_many = ($items instanceof ManyManyList);
$many_many = ($items instanceof ManyManyList || $items instanceof ManyManyThroughList);
$sortColumn = $this->sortColumn;
$pageOffset = 0;
@ -458,11 +485,20 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
if ($many_many) {
$schema=Injector::inst()->get(DataObjectSchema::class);
$componentDetails=$schema->manyManyComponent(get_class($owner), (!empty($this->custom_relation_name) ? $this->custom_relation_name : $gridField->getName()));
$parentField=$componentDetails['parentField'];
$componentField=$componentDetails['childField'];
$table=$componentDetails['join'];
$schema = Injector::inst()->get(DataObjectSchema::class);
$componentDetails = $schema->manyManyComponent(get_class($owner), (!empty($this->custom_relation_name) ? $this->custom_relation_name : $gridField->getName()));
if (empty($componentDetails)) {
user_error('Could not find the relationship "' . (!empty($this->custom_relation_name) ? $this->custom_relation_name : $gridField->getName()) . '" on "' . get_class($owner) . '"', E_USER_ERROR);
}
$parentField = $componentDetails['parentField'];
$componentField = $componentDetails['childField'];
$table = $componentDetails['join'];
//For ManyManyThroughLists get the right join table
if ($items instanceof ManyManyThroughList && class_exists($table)) {
$table = $schema->tableName($table);
}
} else {
//Find table containing the sort column
$table = false;
@ -505,6 +541,8 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
//Perform sorting
$ids = explode(',', $data['ItemIDs']);
$modelClass = $gridField->getModelClass();
$hasVersioned = $this->hasVersionedExtension($modelClass);
for ($sort = 0; $sort < count($ids); $sort++) {
$id = intval($ids[$sort]);
if ($many_many) {
@ -512,15 +550,24 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
. '" SET "' . $sortColumn . '" = ' . (($sort + 1) + $pageOffset)
. ' WHERE "' . $componentField . '" = ' . $id . ' AND "' . $parentField . '" = ' . $owner->ID);
} else {
DB::query('UPDATE "' . $table
. '" SET "' . $sortColumn . '" = ' . (($sort + 1) + $pageOffset)
. ' WHERE "ID" = ' . $id);
if ($hasVersioned) {
// For versioned objects, modify them with the ORM so that the *_versions table is updated
$obj = $modelClass::get()->byID(intval($id));
if (!empty($obj) && $obj !== false && $obj->exists()) {
$obj->$sortColumn = (($sort + 1) + $pageOffset);
$obj->write();
}
} else {
DB::query('UPDATE "' . $table
. '" SET "' . $sortColumn . '" = ' . (($sort + 1) + $pageOffset)
. ' WHERE "ID" = ' . $id);
DB::query('UPDATE "' . $baseDataTable
. '" SET "LastEdited" = \'' . date('Y-m-d H:i:s') . '\''
. ' WHERE "ID" = ' . $id);
DB::query('UPDATE "' . $baseDataTable
. '" SET "LastEdited" = \'' . date('Y-m-d H:i:s') . '\''
. ' WHERE "ID" = ' . $id);
}
if ($this->update_versioned_stage && $this->hasVersionedExtension($gridField->getModelClass())) {
if ($this->update_versioned_stage && $hasVersioned) {
DB::query('UPDATE "' . $table . '_' . $this->update_versioned_stage
. '" SET "' . $sortColumn . '" = ' . (($sort + 1) + $pageOffset)
. ' WHERE "ID" = ' . $id);
@ -568,14 +615,14 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
user_error('No target page', E_USER_ERROR);
}
/** @var Extensible $className */
/** @var \SilverStripe\Core\Extensible $className */
$className = $gridField->getModelClass();
$owner = $gridField->Form->getRecord();
/** @var DataList $items */
$items = clone $gridField->getList();
$many_many = ($items instanceof ManyManyList);
$many_many = ($items instanceof ManyManyList || $items instanceof ManyManyThroughList);
$sortColumn = $this->sortColumn;
$targetItem = $items->byID(intval($data['ItemID']));
@ -591,11 +638,16 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
}
if ($many_many) {
$schema=Injector::inst()->get(DataObjectSchema::class);
$componentDetails=$schema->manyManyComponent(get_class($owner), (!empty($this->custom_relation_name) ? $this->custom_relation_name : $gridField->getName()));
$parentField=$componentDetails['parentField'];
$componentField=$componentDetails['childField'];
$table=$componentDetails['join'];
$schema = Injector::inst()->get(DataObjectSchema::class);
$componentDetails = $schema->manyManyComponent(get_class($owner), (!empty($this->custom_relation_name) ? $this->custom_relation_name : $gridField->getName()));
$parentField = $componentDetails['parentField'];
$componentField = $componentDetails['childField'];
$table = $componentDetails['join'];
//For ManyManyThroughLists get the right join table
if ($items instanceof ManyManyThroughList && class_exists($table)) {
$table = $schema->tableName($table);
}
}
if ($data['Target'] == 'previouspage') {
@ -656,7 +708,7 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
$i = 1;
foreach ($items as $obj) {
if ($obj->ID == $targetItem->ID) {
if ($obj->ID == $targetItem->ID || $i >= count($sortPositions)) {
continue;
}
@ -735,8 +787,7 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
/**
* Check to see if the given class name has the Versioned extension
*
* @param Extensible|string $className
* @param \SilverStripe\Core\Extensible|string $className
* @return bool
*/
public function hasVersionedExtension($className)
@ -746,7 +797,6 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
/**
* Checks to see if $table_name is declared on the DataObject, if not returns string as given
*
* @param $className
* @return string
* @deprecated Use DataObject::getSchema()->tableName() instead

View File

@ -0,0 +1,112 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests\PHPUnit\Bootstrap;
use PHPUnit\Framework\TestFailure;
use PHPUnit\TextUI\DefaultResultPrinter;
class GitHubActionsAnnotatorPrinter extends DefaultResultPrinter
{
protected $currentType = null;
/**
* Handles printing of the defects
* @param array $defects Array of Test Failures
* @param string $type Type of the failure
*/
protected function printDefects(array $defects, string $type): void
{
$this->currentType = $type;
parent::printDefects($defects, $type);
}
/**
* Handles printing of a single defect
* @param TestFailure $defect Test Failure Object
* @param int $count Current position
*/
protected function printDefect(TestFailure $defect, int $count): void
{
parent::printDefect($defect, $count);
$this->printGitHubAnnotation($defect);
}
/**
* Prints a GitHub Annotation Command
* @param TestFailure $defect Defect to print
*/
protected function printGitHubAnnotation(TestFailure $defect)
{
$e = $defect->thrownException();
$errorLines = array_filter(
explode("\n", (string) $e),
function ($l) {
return $l;
}
);
$error = end($errorLines);
$lineIndex = strrpos($error, ":");
$path = substr($error, 0, $lineIndex);
$line = substr($error, $lineIndex + 1);
if (!$path) {
list($path, $line) = $this->getReflectionFromTest(
$defect->getTestName()
);
}
$message = explode("\n", trim($defect->getTestName() . "\n\n" . (string) $e));
$message = implode('%0A', $message);
$type = $this->getCurrentType();
$file = "file={$this->relativePath($path)}";
$line = "line={$line}";
$this->write("::{$type} $file,$line::{$message}\n");
}
/**
* Gets the current type of the defect
* @return string
*/
protected function getCurrentType()
{
if (in_array($this->currentType, ['error', 'failure'])) {
return 'error';
}
return 'warning';
}
/**
* Gets the relative path to the file
* @param string $path Path to make relative
* @return string
*/
protected function relativePath($path)
{
$relative = str_replace(getcwd() . DIRECTORY_SEPARATOR, '', $path);
//Normalize
$relative = str_replace('\\', '/', $relative);
return $relative;
}
/**
* Gets the file name and start line for the test
* @param string $name Name of the test
* @return array
*/
protected function getReflectionFromTest($name)
{
list($klass, $method) = explode('::', $name);
$c = new \ReflectionClass($klass);
$m = $c->getMethod($method);
return [$m->getFileName(), $m->getStartLine()];
}
}

View File

@ -0,0 +1,264 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests\Forms;
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig;
use SilverStripe\ORM\DB;
use SilverStripe\Security\Security;
use SilverStripe\Versioned\Versioned;
use UndefinedOffset\SortableGridField\Forms\GridFieldSortableRows;
use UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\BaseObject;
use UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\ChildObject;
use UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\DummyController;
use UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\Player;
use UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\TestParent;
use UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\VPlayer;
class AutoSortTest extends SapphireTest
{
/** @var string */
public static $fixture_file = 'AutoSortTest.yml';
/** @var array */
protected static $extra_dataobjects = [
Player::class,
VPlayer::class,
TestParent::class,
BaseObject::class,
ChildObject::class
];
public function testAutoSort()
{
if (Security::getCurrentUser()) {
$this->logOut();
}
$list = Player::get();
$config = GridFieldConfig::create()->addComponent(new GridFieldSortableRows('SortOrder'));
$gridField = new GridField('testfield', 'testfield', $list, $config);
$form = new Form(new DummyController(), 'mockform', new FieldList([$gridField]), new FieldList());
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', [], ['action_gridFieldAlterAction?StateID=' . $stateID => true, $form->getSecurityToken()->getName() => $form->getSecurityToken()->getValue()]);
$session = Controller::curr()->getRequest()->getSession();
$session->set($form->getSecurityToken()->getName(), $form->getSecurityToken()->getValue());
$session->set($stateID, ['grid' => '', 'actionName' => 'sortableRowsToggle', 'args' => ['GridFieldSortableRows' => ['sortableToggle' => true]]]);
$request->setSession($session);
$gridField->gridFieldAlterAction(['StateID' => $stateID], $form, $request);
//Insure sort ran
$this->assertEquals(3, $list->last()->SortOrder, 'Auto sort should have run');
//Check for duplicates (there shouldn't be any)
$count = $list->Count();
$indexes = count(array_unique($list->column('SortOrder')));
$this->assertEquals(0, $count - $indexes, 'Duplicate indexes detected');
}
public function testAppendToTopAutoSort()
{
if (Security::getCurrentUser()) {
$this->logOut();
}
$list = Player::get();
$config = GridFieldConfig::create()->addComponent(new GridFieldSortableRows('SortOrder'));
$gridField = new GridField('testfield', 'testfield', $list, $config);
$form = new Form(new DummyController(), 'mockform', new FieldList([$gridField]), new FieldList());
/** @var GridFieldSortableRows $sortableRows */
$sortableRows = $gridField->getConfig()->getComponentByType(GridFieldSortableRows::class);
$sortableRows->setAppendToTop(true);
$this->assertEquals(0, $list->last()->SortOrder, 'Auto sort should not have run');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', [], ['action_gridFieldAlterAction?StateID=' . $stateID => true, $form->getSecurityToken()->getName() => $form->getSecurityToken()->getValue()]);
$session = Controller::curr()->getRequest()->getSession();
$session->set($form->getSecurityToken()->getName(), $form->getSecurityToken()->getValue());
$session->set($stateID, ['grid' => '', 'actionName' => 'sortableRowsToggle', 'args' => ['GridFieldSortableRows' => ['sortableToggle' => true]]]);
$request->setSession($session);
$gridField->gridFieldAlterAction(['StateID' => $stateID], $form, $request);
//Insure sort ran
$this->assertEquals(3, $list->last()->SortOrder, 'Auto sort should have run');
//Check for duplicates (there shouldn't be any)
$count = $list->Count();
$indexes = count(array_unique($list->column('SortOrder')));
$this->assertEquals(0, $count - $indexes, 'Duplicate indexes detected');
}
public function testAutoSortVersioned()
{
if (Security::getCurrentUser()) {
$this->logOut();
}
//Force versioned to reset
Versioned::reset();
$list = VPlayer::get();
//Publish all records
foreach ($list as $item) {
$item->publishSingle();
}
$config = GridFieldConfig::create()->addComponent(new GridFieldSortableRows('SortOrder', true, 'Live'));
$gridField = new GridField('testfield', 'testfield', $list, $config);
$form = new Form(new DummyController(), 'mockform', new FieldList([$gridField]), new FieldList());
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', [], ['action_gridFieldAlterAction?StateID=' . $stateID => true, $form->getSecurityToken()->getName() => $form->getSecurityToken()->getValue()]);
$session = Controller::curr()->getRequest()->getSession();
$session->set($form->getSecurityToken()->getName(), $form->getSecurityToken()->getValue());
$session->set($stateID, ['grid' => '', 'actionName' => 'sortableRowsToggle', 'args' => ['GridFieldSortableRows' => ['sortableToggle' => true]]]);
$request->setSession($session);
$gridField->gridFieldAlterAction(['StateID' => $stateID], $form, $request);
//Insure sort ran
$this->assertEquals(3, $list->last()->SortOrder, 'Auto sort should have run on Versioned stage "Stage"');
//Check for duplicates (there shouldn't be any)
$count = $list->Count();
$indexes = count(array_unique($list->column('SortOrder')));
$this->assertEquals(0, $count - $indexes, 'Duplicate indexes detected on Versioned stage "Stage"');
//Force versioned over to Live stage
Versioned::set_reading_mode('Live');
//Get live instance
$obj = Versioned::get_one_by_stage(VPlayer::class, 'Live', '"ID"=' . $list->last()->ID);
//Insure sort ran
$this->assertEquals(3, $obj->SortOrder, 'Auto sort should have run on Versioned stage "Live"');
//Check for duplicates (there shouldn't be any)
$list = Versioned::get_by_stage(VPlayer::class, 'Live');
$count = $list->Count();
$indexes = count(array_unique($list->column('SortOrder')));
$this->assertEquals(0, $count - $indexes, 'Duplicate indexes detected on Versioned stage "Live"');
}
public function testAppendToTopAutoSortVersioned()
{
if (Security::getCurrentUser()) {
$this->logOut();
}
//Force versioned to reset
Versioned::reset();
$list = VPlayer::get();
//Publish all records
foreach ($list as $item) {
$item->publishSingle();
}
$config = GridFieldConfig::create()->addComponent(new GridFieldSortableRows('SortOrder', true, 'Live'));
$gridField = new GridField('testfield', 'testfield', $list, $config);
$form = new Form(new DummyController(), 'mockform', new FieldList([$gridField]), new FieldList());
/** @var GridFieldSortableRows $sortableRows */
$sortableRows = $gridField->getConfig()->getComponentByType(GridFieldSortableRows::class);
$sortableRows->setAppendToTop(true);
$this->assertEquals(0, $list->last()->SortOrder, 'Auto sort should not have run on Versioned stage "Stage"');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', [], ['action_gridFieldAlterAction?StateID=' . $stateID => true, $form->getSecurityToken()->getName() => $form->getSecurityToken()->getValue()]);
$session = Controller::curr()->getRequest()->getSession();
$session->set($form->getSecurityToken()->getName(), $form->getSecurityToken()->getValue());
$session->set($stateID, ['grid' => '', 'actionName' => 'sortableRowsToggle', 'args' => ['GridFieldSortableRows' => ['sortableToggle' => true]]]);
$request->setSession($session);
$gridField->gridFieldAlterAction(['StateID' => $stateID], $form, $request);
//Insure sort ran
$this->assertEquals(3, $list->last()->SortOrder, 'Auto sort should have run on Versioned stage "Stage"');
//Check for duplicates (there shouldn't be any)
$count = $list->Count();
$indexes = count(array_unique($list->column('SortOrder')));
$this->assertEquals(0, $count - $indexes, 'Duplicate indexes detected on Versioned stage "Stage"');
//Force versioned over to Live stage
Versioned::set_reading_mode('Live');
//Insure sort ran
$this->assertEquals(3, $list->last()->SortOrder, 'Auto sort should have run on Versioned stage "Live"');
//Check for duplicates (there shouldn't be any)
$count = $list->Count();
$indexes = count(array_unique($list->column('SortOrder')));
$this->assertEquals(0, $count - $indexes, 'Duplicate indexes detected on Versioned stage "Live"');
}
public function testAppendToTopAutoSortChild()
{
if (Security::getCurrentUser()) {
$this->logOut();
}
//Push the edit date into the past, we're checking this later
DB::query('UPDATE "GridFieldAction_SortOrder_BaseObject" SET "LastEdited"=\'' . date('Y-m-d 00:00:00', strtotime('yesterday')) . '\'');
/** @var TestParent $parent */
$parent = TestParent::get()->first();
/** @var DataList $list */
$list = $parent->TestRelation();
$config = GridFieldConfig::create()->addComponent(new GridFieldSortableRows('SortOrder'));
$gridField = new GridField('testfield', 'testfield', $list, $config);
$form = new Form(new DummyController(), 'mockform', new FieldList([$gridField]), new FieldList());
$form->loadDataFrom($parent);
/** @var GridFieldSortableRows $sortableRows */
$sortableRows = $gridField->getConfig()->getComponentByType(GridFieldSortableRows::class);
$sortableRows->setAppendToTop(true);
$this->assertEquals(0, $list->last()->SortOrder, 'Auto sort should not have run');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', [], ['action_gridFieldAlterAction?StateID=' . $stateID => true, $form->getSecurityToken()->getName() => $form->getSecurityToken()->getValue()]);
$session = Controller::curr()->getRequest()->getSession();
$session->set($form->getSecurityToken()->getName(), $form->getSecurityToken()->getValue());
$session->set($stateID, ['grid' => '', 'actionName' => 'sortableRowsToggle', 'args' => ['GridFieldSortableRows' => ['sortableToggle' => true]]]);
$request->setSession($session);
$gridField->gridFieldAlterAction(['StateID' => $stateID], $form, $request);
//Insure sort ran
$this->assertEquals(3, $list->last()->SortOrder, 'Auto sort should have run');
//Check for duplicates (there shouldn't be any)
$count = $list->Count();
$indexes = count(array_unique($list->column('SortOrder')));
$this->assertEquals(0, $count - $indexes, 'Duplicate indexes detected');
//Make sure the last edited is today for all records
$this->assertEquals(3, $list->filter('LastEdited:GreaterThan', date('Y-m-d 00:00:00'))->count());
}
}

View File

@ -0,0 +1,39 @@
UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\Player:
player1:
Name: Player 1
SortOrder: 0
player2:
Name: Player 2
SortOrder: 0
player3:
Name: Player 3
SortOrder: 0
UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\VPlayer:
player1:
Name: Player 1
SortOrder: 0
player2:
Name: Player 2
SortOrder: 0
player3:
Name: Player 3
SortOrder: 0
UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\TestParent:
testparent:
Name: Test
UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\ChildObject:
testitem1:
Name: Test 1
SortOrder: 0
Parent: =>UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\TestParent.testparent
testitem2:
Name: Test 2
SortOrder: 0
Parent: =>UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\TestParent.testparent
testitem3:
Name: Test 3
SortOrder: 0
Parent: =>UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\TestParent.testparent

View File

@ -0,0 +1,19 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
/**
* Class \UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\BaseObject
*
* @property string Name
*/
class BaseObject extends DataObject implements TestOnly
{
private static $table_name = 'GridFieldAction_SortOrder_BaseObject';
private static $db = [
'Name' => 'Varchar',
];
}

View File

@ -0,0 +1,27 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\FieldType\DBInt;
/**
* Class \UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\ChildObject
*
* @package SortableGridField\Tests
* @property int SortOrder
* @method TestParent Parent
*/
class ChildObject extends BaseObject implements TestOnly
{
private static $table_name = 'GridFieldAction_SortOrder_ChildObject';
private static $db = [
'SortOrder' => DBInt::class,
];
private static $has_one = [
'Parent' => TestParent::class,
];
private static $default_sort = 'SortOrder';
}

View File

@ -0,0 +1,12 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest;
use SilverStripe\Control\Controller;
/**
* Class \UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\DummyController
*/
class DummyController extends Controller
{
private static $url_segment = 'sortable-grid-field';
}

View File

@ -0,0 +1,23 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
/**
* Class \UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\Player
*
* @property string Name
* @property int SortOrder
*/
class Player extends DataObject implements TestOnly
{
private static $table_name = 'GridFieldAction_SortOrder_Player';
private static $db = [
'Name' => 'Varchar',
'SortOrder' => 'Int',
];
private static $default_sort = 'SortOrder';
}

View File

@ -0,0 +1,25 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
/**
* Class \UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\TestParent
*
* @package SortableGridField\Tests
* @property string Name
* @method ChildObject TestRelation
*/
class TestParent extends DataObject implements TestOnly
{
private static $table_name = 'GridFieldAction_SortOrder_TestParent';
private static $db = [
'Name' => 'Varchar',
];
private static $has_many = [
'TestRelation' => ChildObject::class,
];
}

View File

@ -0,0 +1,28 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
use SilverStripe\Versioned\Versioned;
/**
* Class \UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\VPlayer
*
* @property string Name
* @property int SortOrder
*/
class VPlayer extends DataObject implements TestOnly
{
private static $table_name = 'GridFieldAction_SortOrder_VPlayer';
private static $db = [
'Name' => 'Varchar',
'SortOrder' => 'Int',
];
private static $default_sort = 'SortOrder';
private static $extensions = [
Versioned::class,
];
}

View File

@ -0,0 +1,123 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig;
use SilverStripe\ORM\ValidationException;
use SilverStripe\Security\IdentityStore;
use SilverStripe\Security\Security;
use SilverStripe\Versioned\Versioned;
use UndefinedOffset\SortableGridField\Forms\GridFieldSortableRows;
use UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\DummyController;
use UndefinedOffset\SortableGridField\Tests\Forms\OrderingTest\Team;
use UndefinedOffset\SortableGridField\Tests\Forms\OrderingTest\VTeam;
class OrderingTest extends SapphireTest
{
/** @var ArrayList */
protected $list;
/** @var GridField */
protected $gridField;
/** @var Form */
protected $form;
/** @var string */
public static $fixture_file = 'OrderingTest.yml';
/** @var array */
protected static $extra_dataobjects = [
Team::class,
VTeam::class
];
protected function setUp(): void
{
parent::setUp();
$this->list = Team::get();
$config = GridFieldConfig::create()->addComponent(new GridFieldSortableRows('SortOrder'));
$this->gridField = new GridField('testfield', 'testfield', $this->list, $config);
$this->form = new Form(new DummyController(), 'mockform', new FieldList([$this->gridField]), new FieldList());
}
public function testSortActionWithoutCorrectPermission()
{
if (Security::getCurrentUser()) {
Injector::inst()->get(IdentityStore::class)->logOut(Controller::curr()->getRequest());
}
$this->expectException(ValidationException::class);
$team1 = $this->objFromFixture(Team::class, 'team1');
$team2 = $this->objFromFixture(Team::class, 'team2');
$team3 = $this->objFromFixture(Team::class, 'team3');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', ['ItemIDs' => "$team1->ID, $team3->ID, $team2->ID"], ['action_gridFieldAlterAction?StateID=' . $stateID => true, $this->form->getSecurityToken()->getName() => $this->form->getSecurityToken()->getValue()]);
$session = Controller::curr()->getRequest()->getSession();
$session->set($this->form->getSecurityToken()->getName(), $this->form->getSecurityToken()->getValue());
$session->set($stateID, ['grid' => '', 'actionName' => 'saveGridRowSort', 'args' => ['GridFieldSortableRows' => ['sortableToggle' => true]]]);
$request->setSession($session);
$this->gridField->gridFieldAlterAction(['StateID' => $stateID], $this->form, $request);
$this->assertEquals($team3->ID, $this->list->last()->ID, 'User should\'t be able to sort records without correct permissions.');
}
public function testSortActionWithAdminPermission()
{
$team1 = $this->objFromFixture(Team::class, 'team1');
$team2 = $this->objFromFixture(Team::class, 'team2');
$team3 = $this->objFromFixture(Team::class, 'team3');
$this->logInWithPermission('ADMIN');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', ['ItemIDs' => "$team1->ID, $team3->ID, $team2->ID"], ['action_gridFieldAlterAction?StateID=' . $stateID => true, $this->form->getSecurityToken()->getName() => $this->form->getSecurityToken()->getValue()]);
$session = Controller::curr()->getRequest()->getSession();
$session->set($this->form->getSecurityToken()->getName(), $this->form->getSecurityToken()->getValue());
$session->set($stateID, ['grid' => '', 'actionName' => 'saveGridRowSort', 'args' => ['GridFieldSortableRows' => ['sortableToggle' => true]]]);
$request->setSession($session);
$this->gridField->gridFieldAlterAction(['StateID' => $stateID], $this->form, $request);
$this->assertEquals($team2->ID, $this->list->last()->ID, 'User should be able to sort records with ADMIN permission.');
}
public function testSortActionVersioned()
{
//Force versioned to reset
Versioned::reset();
$list = VTeam::get();
$this->gridField->setList($list);
/** @var GridFieldSortableRows $sortableGrid */
$sortableGrid = $this->gridField->getConfig()->getComponentByType(GridFieldSortableRows::class);
$sortableGrid->setUpdateVersionedStage('Live');
//Publish all records
foreach ($list as $item) {
$item->publishSingle();
}
$team1 = $this->objFromFixture(VTeam::class, 'team1');
$team2 = $this->objFromFixture(VTeam::class, 'team2');
$team3 = $this->objFromFixture(VTeam::class, 'team3');
$this->logInWithPermission('ADMIN');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', ['ItemIDs' => "$team1->ID, $team3->ID, $team2->ID"], ['action_gridFieldAlterAction?StateID=' . $stateID => true, $this->form->getSecurityToken()->getName() => $this->form->getSecurityToken()->getValue()]);
$session = Controller::curr()->getRequest()->getSession();
$session->set($this->form->getSecurityToken()->getName(), $this->form->getSecurityToken()->getValue());
$session->set($stateID, ['grid' => '', 'actionName' => 'saveGridRowSort', 'args' => ['GridFieldSortableRows' => ['sortableToggle' => true]]]);
$request->setSession($session);
$this->gridField->gridFieldAlterAction(['StateID' => $stateID], $this->form, $request);
$this->assertEquals($team2->ID, $list->last()->ID, 'Sort should have happened on Versioned stage "Stage"');
$list = Versioned::get_by_stage(VTeam::class, 'Live');
$this->assertEquals($team2->ID, $list->last()->ID, 'Sort should have happened on Versioned stage "Live"');
}
}

View File

@ -1,4 +1,4 @@
UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_Team:
UndefinedOffset\SortableGridField\Tests\Forms\OrderingTest\Team:
team1:
Name: Team 1
City: Cologne
@ -12,7 +12,7 @@ UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_Team:
City: Auckland
SortOrder: 3
UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_VTeam:
UndefinedOffset\SortableGridField\Tests\Forms\OrderingTest\VTeam:
team1:
Name: Team 1
City: Cologne

View File

@ -0,0 +1,25 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests\Forms\OrderingTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
/**
* Class \UndefinedOffset\SortableGridField\Tests\Forms\OrderingTest\Team
*
* @property string Name
* @property string City
* @property int SortOrder
*/
class Team extends DataObject implements TestOnly
{
private static $table_name = 'GridFieldAction_SortOrder_Team';
private static $db = [
'Name' => 'Varchar',
'City' => 'Varchar',
'SortOrder' => 'Int',
];
private static $default_sort = 'SortOrder';
}

View File

@ -0,0 +1,29 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests\Forms\OrderingTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
use SilverStripe\Versioned\Versioned;
/**
* Class \UndefinedOffset\SortableGridField\Tests\Forms\OrderingTest\VTeam
*
* @property string Name
* @property string City
* @property int SortOrder
*/
class VTeam extends DataObject implements TestOnly
{
private static $table_name = 'GridFieldAction_SortOrder_VTeam';
private static $db = [
'Name' => 'Varchar',
'City' => 'Varchar',
'SortOrder' => 'Int',
];
private static $default_sort = 'SortOrder';
private static $extensions = [
Versioned::class,
];
}

View File

@ -0,0 +1,188 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests;
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig_Base;
use SilverStripe\Versioned\Versioned;
use UndefinedOffset\SortableGridField\Forms\GridFieldSortableRows;
use UndefinedOffset\SortableGridField\Tests\Forms\AutoSortTest\DummyController;
use UndefinedOffset\SortableGridField\Tests\Forms\PageSortingTest\Team;
use UndefinedOffset\SortableGridField\Tests\Forms\PageSortingTest\VTeam;
/**
* Class \UndefinedOffset\SortableGridField\Tests\PageSortingTest
*/
class PageSortingTest extends SapphireTest
{
/** @var ArrayList */
protected $list;
/** @var GridField */
protected $gridField;
/** @var Form */
protected $form;
/** @var string */
public static $fixture_file = 'PageSortingTest.yml';
/** @var array */
protected static $extra_dataobjects = [
Team::class,
VTeam::class
];
protected function setUp(): void
{
parent::setUp();
$this->list = Team::get();
$config = GridFieldConfig_Base::create(5)->addComponent(new GridFieldSortableRows('SortOrder'));
$this->gridField = new GridField('testfield', 'testfield', $this->list, $config);
$this->form = new Form(new DummyController(), 'mockform', FieldList::create([$this->gridField]), FieldList::create());
}
public function testSortToNextPage()
{
$this->gridField->State->GridFieldPaginator->currentPage = 1;
$team3 = $this->objFromFixture(Team::class, 'team3');
$this->logInWithPermission('ADMIN');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', ['ItemID' => $team3->ID, 'Target' => 'nextpage'], ['action_gridFieldAlterAction?StateID=' . $stateID => true, $this->form->getSecurityToken()->getName() => $this->form->getSecurityToken()->getValue()]);
$session = Controller::curr()->getRequest()->getSession();
$session->set($this->form->getSecurityToken()->getName(), $this->form->getSecurityToken()->getValue());
$session->set($stateID, ['grid' => '', 'actionName' => 'sortToPage', 'args' => ['GridFieldSortableRows' => ['sortableToggle' => true], 'GridFieldPaginator' => ['currentPage' => 1]]]);
$request->setSession($session);
$this->gridField->gridFieldAlterAction(['StateID' => $stateID], $this->form, $request);
$team6 = $this->objFromFixture(Team::class, 'team6');
$this->assertEquals(5, $team6->SortOrder, 'Team 6 Should have moved to the bottom of the first page');
$team3 = $this->objFromFixture(Team::class, 'team3');
$this->assertEquals(6, $team3->SortOrder, 'Team 3 Should have moved to the top of the second page');
}
public function testSortToPrevPage()
{
$this->gridField->State->GridFieldPaginator->currentPage = 2;
$team7 = $this->objFromFixture(Team::class, 'team7');
$this->logInWithPermission('ADMIN');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', ['ItemID' => $team7->ID, 'Target' => 'previouspage'], ['action_gridFieldAlterAction?StateID=' . $stateID => true, $this->form->getSecurityToken()->getName() => $this->form->getSecurityToken()->getValue()]);
$session = Controller::curr()->getRequest()->getSession();
$session->set($this->form->getSecurityToken()->getName(), $this->form->getSecurityToken()->getValue());
$session->set($stateID, ['grid' => '', 'actionName' => 'sortToPage', 'args' => ['GridFieldSortableRows' => ['sortableToggle' => true], 'GridFieldPaginator' => ['currentPage' => 1]]]);
$request->setSession($session);
$this->gridField->gridFieldAlterAction(['StateID' => $stateID], $this->form, $request);
$team7 = $this->objFromFixture(Team::class, 'team7');
$this->assertEquals(5, $team7->SortOrder, 'Team 7 Should have moved to the bottom of the first page');
$team5 = $this->objFromFixture(Team::class, 'team5');
$this->assertEquals(6, $team5->SortOrder, 'Team 5 Should have moved to the top of the second page');
}
public function testSortToNextPageVersioned()
{
//Force versioned to reset
Versioned::reset();
$list = VTeam::get();
$this->gridField->setList($list);
/** @var GridFieldSortableRows $sortableGrid */
$sortableGrid = $this->gridField->getConfig()->getComponentByType(GridFieldSortableRows::class);
$sortableGrid->setUpdateVersionedStage('Live');
$this->gridField->State->GridFieldPaginator->currentPage = 1;
//Publish all records
foreach ($list as $item) {
$item->publishSingle();
}
$team3 = $this->objFromFixture(VTeam::class, 'team3');
$this->logInWithPermission('ADMIN');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', ['ItemID' => $team3->ID, 'Target' => 'nextpage'], ['action_gridFieldAlterAction?StateID=' . $stateID => true, $this->form->getSecurityToken()->getName() => $this->form->getSecurityToken()->getValue()]);
$session = Controller::curr()->getRequest()->getSession();
$session->set($this->form->getSecurityToken()->getName(), $this->form->getSecurityToken()->getValue());
$session->set($stateID, ['grid' => '', 'actionName' => 'sortToPage', 'args' => ['GridFieldSortableRows' => ['sortableToggle' => true], 'GridFieldPaginator' => ['currentPage' => 1]]]);
$request->setSession($session);
$this->gridField->gridFieldAlterAction(['StateID' => $stateID], $this->form, $request);
$team6 = $this->objFromFixture(VTeam::class, 'team6');
$this->assertEquals(5, $team6->SortOrder, 'Team 6 Should have moved to the bottom of the first page on Versioned stage "Stage"');
$team3 = $this->objFromFixture(VTeam::class, 'team3');
$this->assertEquals(6, $team3->SortOrder, 'Team 3 Should have moved to the top of the second page on Versioned stage "Stage"');
$list = Versioned::get_by_stage(VTeam::class, 'Live');
$team6 = $list->byID($team6->ID);
$this->assertEquals(5, $team6->SortOrder, 'Team 6 Should have moved to the bottom of the first page on Versioned stage "Live"');
$team3 = $list->byID($team3->ID);
$this->assertEquals(6, $team3->SortOrder, 'Team 3 Should have moved to the top of the second page on Versioned stage "Live"');
}
public function testSortToPrevPageVersioned()
{
//Force versioned to reset
Versioned::reset();
$list = VTeam::get();
$this->gridField->setList($list);
/** @var GridFieldSortableRows $sortableGrid */
$sortableGrid = $this->gridField->getConfig()->getComponentByType(GridFieldSortableRows::class);
$sortableGrid->setUpdateVersionedStage('Live');
$this->gridField->State->GridFieldPaginator->currentPage = 2;
//Publish all records
foreach ($list as $item) {
$item->publishSingle();
}
$team7 = $this->objFromFixture(VTeam::class, 'team7');
$this->logInWithPermission('ADMIN');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', ['ItemID' => $team7->ID, 'Target' => 'previouspage'], ['action_gridFieldAlterAction?StateID=' . $stateID => true, $this->form->getSecurityToken()->getName() => $this->form->getSecurityToken()->getValue()]);
$session = Controller::curr()->getRequest()->getSession();
$session->set($this->form->getSecurityToken()->getName(), $this->form->getSecurityToken()->getValue());
$session->set($stateID, ['grid' => '', 'actionName' => 'sortToPage', 'args' => ['GridFieldSortableRows' => ['sortableToggle' => true], 'GridFieldPaginator' => ['currentPage' => 1]]]);
$request->setSession($session);
$this->gridField->gridFieldAlterAction(['StateID' => $stateID], $this->form, $request);
$team7 = $this->objFromFixture(VTeam::class, 'team7');
$this->assertEquals(5, $team7->SortOrder, 'Team 7 Should have moved to the bottom of the first page on Versioned stage "Stage"');
$team5 = $this->objFromFixture(VTeam::class, 'team5');
$this->assertEquals(6, $team5->SortOrder, 'Team 5 Should have moved to the top of the second page on Versioned stage "Stage"');
$list = Versioned::get_by_stage(VTeam::class, 'Live');
$team7 = $list->byID($team7->ID);
$this->assertEquals(5, $team7->SortOrder, 'Team 7 Should have moved to the bottom of the first page on Versioned stage "Live"');
$team5 = $list->byID($team5->ID);
$this->assertEquals(6, $team5->SortOrder, 'Team 5 Should have moved to the top of the second page on Versioned stage "Live"');
}
}

View File

@ -1,4 +1,4 @@
UndefinedOffset\SortableGridField\Tests\GridFieldAction_PageSortOrder_Team:
UndefinedOffset\SortableGridField\Tests\Forms\PageSortingTest\Team:
team1:
Name: Team 1
City: Cologne
@ -36,7 +36,7 @@ UndefinedOffset\SortableGridField\Tests\GridFieldAction_PageSortOrder_Team:
City: Auckland
SortOrder: 9
UndefinedOffset\SortableGridField\Tests\GridFieldAction_PageSortOrder_VTeam:
UndefinedOffset\SortableGridField\Tests\Forms\PageSortingTest\VTeam:
team1:
Name: Team 1
City: Cologne

View File

@ -0,0 +1,25 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests\Forms\PageSortingTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
/**
* Class \UndefinedOffset\SortableGridField\Tests\Forms\PageSortingTest\Team
*
* @property string Name
* @property string City
* @property int SortOrder
*/
class Team extends DataObject implements TestOnly
{
private static $table_name = 'GridFieldAction_PageSortOrder_Team';
private static $db = [
'Name' => 'Varchar',
'City' => 'Varchar',
'SortOrder' => 'Int',
];
private static $default_sort = 'SortOrder';
}

View File

@ -0,0 +1,30 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests\Forms\PageSortingTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
use SilverStripe\Versioned\Versioned;
/**
* Class \UndefinedOffset\SortableGridField\Tests\Forms\PageSortingTest\VTeam
*
* @property string Name
* @property string City
* @property int SortOrder
*/
class VTeam extends DataObject implements TestOnly
{
private static $table_name = 'GridFieldAction_PageSortOrder_VTeam';
private static $db = [
'Name' => 'Varchar',
'City' => 'Varchar',
'SortOrder' => 'Int',
];
private static $default_sort = 'SortOrder';
private static $extensions = [
Versioned::class,
];
}

View File

@ -1,380 +0,0 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests;
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\Session;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DB;
use SilverStripe\ORM\FieldType\DBInt;
use SilverStripe\ORM\FieldType\DBVarchar;
use SilverStripe\Security\Member;
use SilverStripe\Versioned\Versioned;
use UndefinedOffset\SortableGridField\Forms\GridFieldSortableRows;
/**
* Class GridFieldSortableRowsAutoSortTest
*
* @package SortableGridField\Tests
*/
class GridFieldSortableRowsAutoSortTest extends SapphireTest
{
/** @var string */
public static $fixture_file = 'GridFieldSortableRowsAutoSortTest.yml';
/** @var array */
protected static $extra_dataobjects = array(
GridFieldAction_SortOrder_Player::class,
GridFieldAction_SortOrder_VPlayer::class,
GridFieldAction_SortOrder_TestParent::class,
GridFieldAction_SortOrder_BaseObject::class,
GridFieldAction_SortOrder_ChildObject::class
);
public function testAutoSort()
{
if (Member::currentUser()) {
Member::currentUser()->logOut();
}
$list = GridFieldAction_SortOrder_Player::get();
$config = GridFieldConfig::create()->addComponent(new GridFieldSortableRows('SortOrder'));
$gridField = new GridField('testfield', 'testfield', $list, $config);
$form = new Form(new SortableGridField_DummyController(), 'mockform', new FieldList(array($gridField)), new FieldList());
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', array(), array('action_gridFieldAlterAction?StateID=' . $stateID => true, $form->getSecurityToken()->getName() => $form->getSecurityToken()->getValue()));
$session = Injector::inst()->create(Session::class, []);
$request->setSession($session);
$session->init($request);
$session->set($stateID, array('grid' => '', 'actionName' => 'sortableRowsToggle', 'args' => array('GridFieldSortableRows' => array('sortableToggle' => true))));
$gridField->gridFieldAlterAction(array('StateID' => $stateID), $form, $request);
//Insure sort ran
$this->assertEquals(3, $list->last()->SortOrder, 'Auto sort should have run');
//Check for duplicates (there shouldn't be any)
$count = $list->Count();
$indexes = count(array_unique($list->column('SortOrder')));
$this->assertEquals(0, $count - $indexes, 'Duplicate indexes detected');
}
public function testAppendToTopAutoSort()
{
if (Member::currentUser()) {
Member::currentUser()->logOut();
}
$list = GridFieldAction_SortOrder_Player::get();
$config = GridFieldConfig::create()->addComponent(new GridFieldSortableRows('SortOrder'));
$gridField = new GridField('testfield', 'testfield', $list, $config);
$form = new Form(new SortableGridField_DummyController(), 'mockform', new FieldList(array($gridField)), new FieldList());
/** @var GridFieldSortableRows $sortableRows */
$sortableRows = $gridField->getConfig()->getComponentByType(GridFieldSortableRows::class);
$sortableRows->setAppendToTop(true);
$this->assertEquals(0, $list->last()->SortOrder, 'Auto sort should not have run');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', array(), array('action_gridFieldAlterAction?StateID=' . $stateID => true, $form->getSecurityToken()->getName() => $form->getSecurityToken()->getValue()));
$session = Injector::inst()->create(Session::class, []);
$request->setSession($session);
$session->init($request);
$session->set($stateID, array('grid' => '', 'actionName' => 'sortableRowsToggle', 'args' => array('GridFieldSortableRows' => array('sortableToggle' => true))));
$gridField->gridFieldAlterAction(array('StateID' => $stateID), $form, $request);
//Insure sort ran
$this->assertEquals(3, $list->last()->SortOrder, 'Auto sort should have run');
//Check for duplicates (there shouldn't be any)
$count = $list->Count();
$indexes = count(array_unique($list->column('SortOrder')));
$this->assertEquals(0, $count - $indexes, 'Duplicate indexes detected');
}
public function testAutoSortVersioned()
{
if (Member::currentUser()) {
Member::currentUser()->logOut();
}
//Force versioned to reset
Versioned::reset();
$list = GridFieldAction_SortOrder_VPlayer::get();
//Publish all records
foreach ($list as $item) {
$item->publish('Stage', 'Live');
}
$config = GridFieldConfig::create()->addComponent(new GridFieldSortableRows('SortOrder', true, 'Live'));
$gridField = new GridField('testfield', 'testfield', $list, $config);
$form = new Form(new SortableGridField_DummyController(), 'mockform', new FieldList(array($gridField)), new FieldList());
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', array(), array('action_gridFieldAlterAction?StateID=' . $stateID => true, $form->getSecurityToken()->getName() => $form->getSecurityToken()->getValue()));
$session = Injector::inst()->create(Session::class, []);
$request->setSession($session);
$session->init($request);
$session->set($stateID, array('grid' => '', 'actionName' => 'sortableRowsToggle', 'args' => array('GridFieldSortableRows' => array('sortableToggle' => true))));
$gridField->gridFieldAlterAction(array('StateID' => $stateID), $form, $request);
//Insure sort ran
$this->assertEquals(3, $list->last()->SortOrder, 'Auto sort should have run on Versioned stage "Stage"');
//Check for duplicates (there shouldn't be any)
$count = $list->Count();
$indexes = count(array_unique($list->column('SortOrder')));
$this->assertEquals(0, $count - $indexes, 'Duplicate indexes detected on Versioned stage "Stage"');
//Force versioned over to Live stage
Versioned::set_reading_mode('Live');
//Get live instance
$obj = Versioned::get_one_by_stage(GridFieldAction_SortOrder_VPlayer::class, 'Live', '"ID"=' . $list->last()->ID);
//Insure sort ran
$this->assertEquals(3, $obj->SortOrder, 'Auto sort should have run on Versioned stage "Live"');
//Check for duplicates (there shouldn't be any)
$list = Versioned::get_by_stage(GridFieldAction_SortOrder_VPlayer::class, 'Live');
$count = $list->Count();
$indexes = count(array_unique($list->column('SortOrder')));
$this->assertEquals(0, $count - $indexes, 'Duplicate indexes detected on Versioned stage "Live"');
}
public function testAppendToTopAutoSortVersioned()
{
if (Member::currentUser()) {
Member::currentUser()->logOut();
}
//Force versioned to reset
Versioned::reset();
$list = GridFieldAction_SortOrder_VPlayer::get();
//Publish all records
foreach ($list as $item) {
$item->publish('Stage', 'Live');
}
$config = GridFieldConfig::create()->addComponent(new GridFieldSortableRows('SortOrder', true, 'Live'));
$gridField = new GridField('testfield', 'testfield', $list, $config);
$form = new Form(new SortableGridField_DummyController(), 'mockform', new FieldList(array($gridField)), new FieldList());
/** @var GridFieldSortableRows $sortableRows */
$sortableRows = $gridField->getConfig()->getComponentByType(GridFieldSortableRows::class);
$sortableRows->setAppendToTop(true);
$this->assertEquals(0, $list->last()->SortOrder, 'Auto sort should not have run on Versioned stage "Stage"');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', array(), array('action_gridFieldAlterAction?StateID=' . $stateID => true, $form->getSecurityToken()->getName() => $form->getSecurityToken()->getValue()));
$session = Injector::inst()->create(Session::class, []);
$request->setSession($session);
$session->init($request);
$session->set($stateID, array('grid' => '', 'actionName' => 'sortableRowsToggle', 'args' => array('GridFieldSortableRows' => array('sortableToggle' => true))));
$gridField->gridFieldAlterAction(array('StateID' => $stateID), $form, $request);
//Insure sort ran
$this->assertEquals(3, $list->last()->SortOrder, 'Auto sort should have run on Versioned stage "Stage"');
//Check for duplicates (there shouldn't be any)
$count = $list->Count();
$indexes = count(array_unique($list->column('SortOrder')));
$this->assertEquals(0, $count - $indexes, 'Duplicate indexes detected on Versioned stage "Stage"');
//Force versioned over to Live stage
Versioned::set_reading_mode('Live');
//Insure sort ran
$this->assertEquals(3, $list->last()->SortOrder, 'Auto sort should have run on Versioned stage "Live"');
//Check for duplicates (there shouldn't be any)
$count = $list->Count();
$indexes = count(array_unique($list->column('SortOrder')));
$this->assertEquals(0, $count - $indexes, 'Duplicate indexes detected on Versioned stage "Live"');
}
public function testAppendToTopAutoSortChild()
{
if (Member::currentUser()) {
Member::currentUser()->logOut();
}
//Push the edit date into the past, we're checking this later
DB::query('UPDATE "GridFieldAction_SortOrder_BaseObject" SET "LastEdited"=\'' . date('Y-m-d 00:00:00', strtotime('yesterday')) . '\'');
/** @var GridFieldAction_SortOrder_TestParent $parent */
$parent = GridFieldAction_SortOrder_TestParent::get()->first();
/** @var DataList $list */
$list = $parent->TestRelation();
$config = GridFieldConfig::create()->addComponent(new GridFieldSortableRows('SortOrder'));
$gridField = new GridField('testfield', 'testfield', $list, $config);
$form = new Form(new SortableGridField_DummyController(), 'mockform', new FieldList(array($gridField)), new FieldList());
$form->loadDataFrom($parent);
/** @var GridFieldSortableRows $sortableRows */
$sortableRows = $gridField->getConfig()->getComponentByType(GridFieldSortableRows::class);
$sortableRows->setAppendToTop(true);
$this->assertEquals(0, $list->last()->SortOrder, 'Auto sort should not have run');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', array(), array('action_gridFieldAlterAction?StateID=' . $stateID => true, $form->getSecurityToken()->getName() => $form->getSecurityToken()->getValue()));
$session = Injector::inst()->create(Session::class, []);
$request->setSession($session);
$session->init($request);
$session->set($stateID, array('grid' => '', 'actionName' => 'sortableRowsToggle', 'args' => array('GridFieldSortableRows' => array('sortableToggle' => true))));
$gridField->gridFieldAlterAction(array('StateID' => $stateID), $form, $request);
//Insure sort ran
$this->assertEquals(3, $list->last()->SortOrder, 'Auto sort should have run');
//Check for duplicates (there shouldn't be any)
$count = $list->Count();
$indexes = count(array_unique($list->column('SortOrder')));
$this->assertEquals(0, $count - $indexes, 'Duplicate indexes detected');
//Make sure the last edited is today for all records
$this->assertEquals(3, $list->filter('LastEdited:GreaterThan', date('Y-m-d 00:00:00'))->count());
}
}
/**
* Class GridFieldAction_SortOrder_Player
*
* @package SortableGridField\Tests
* @property string Name
* @property int SortOrder
*/
class GridFieldAction_SortOrder_Player extends DataObject implements TestOnly
{
private static $table_name = 'GridFieldAction_SortOrder_Player';
private static $db = array(
'Name' => DBVarchar::class,
'SortOrder' => DBInt::class
);
private static $default_sort = 'SortOrder';
}
/**
* Class GridFieldAction_SortOrder_VPlayer
*
* @package SortableGridField\Tests
* @property string Name
* @property int SortOrder
*/
class GridFieldAction_SortOrder_VPlayer extends DataObject implements TestOnly
{
private static $table_name = 'GridFieldAction_SortOrder_VPlayer';
private static $db = array(
'Name' => DBVarchar::class,
'SortOrder' => DBInt::class
);
private static $default_sort = 'SortOrder';
private static $extensions = array(
"SilverStripe\\Versioned\\Versioned('Stage', 'Live')"
);
}
/**
* Class GridFieldAction_SortOrder_TestParent
*
* @package SortableGridField\Tests
* @property string Name
* @method GridFieldAction_SortOrder_ChildObject TestRelation
*/
class GridFieldAction_SortOrder_TestParent extends DataObject implements TestOnly
{
private static $table_name = 'GridFieldAction_SortOrder_TestParent';
private static $db = array(
'Name' => DBVarchar::class
);
private static $has_many = array(
'TestRelation' => GridFieldAction_SortOrder_ChildObject::class
);
}
/**
* Class GridFieldAction_SortOrder_BaseObject
*
* @package SortableGridField\Tests
* @property string Name
*/
class GridFieldAction_SortOrder_BaseObject extends DataObject implements TestOnly
{
private static $table_name = 'GridFieldAction_SortOrder_BaseObject';
private static $db = array(
'Name' => DBVarchar::class
);
}
/**
* Class GridFieldAction_SortOrder_ChildObject
*
* @package SortableGridField\Tests
* @property int SortOrder
* @method GridFieldAction_SortOrder_TestParent Parent
*/
class GridFieldAction_SortOrder_ChildObject extends GridFieldAction_SortOrder_BaseObject implements TestOnly
{
private static $table_name = 'GridFieldAction_SortOrder_ChildObject';
private static $db = array(
'SortOrder' => DBInt::class
);
private static $has_one = array(
'Parent' => GridFieldAction_SortOrder_TestParent::class
);
private static $default_sort = 'SortOrder';
}
/**
* Class SortableGridField_DummyController
*
* @package SortableGridField\Tests
*/
class SortableGridField_DummyController extends Controller
{
private static $url_segment = 'sortable-grid-field';
}

View File

@ -1,39 +0,0 @@
UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_Player:
player1:
Name: Player 1
SortOrder: 0
player2:
Name: Player 2
SortOrder: 0
player3:
Name: Player 3
SortOrder: 0
UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_VPlayer:
player1:
Name: Player 1
SortOrder: 0
player2:
Name: Player 2
SortOrder: 0
player3:
Name: Player 3
SortOrder: 0
UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_TestParent:
testparent:
Name: Test
UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_ChildObject:
testitem1:
Name: Test 1
SortOrder: 0
Parent: =>UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_TestParent.testparent
testitem2:
Name: Test 2
SortOrder: 0
Parent: =>UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_TestParent.testparent
testitem3:
Name: Test 3
SortOrder: 0
Parent: =>UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_TestParent.testparent

View File

@ -1,240 +0,0 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests;
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\Session;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig_Base;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\FieldType\DBInt;
use SilverStripe\ORM\FieldType\DBVarchar;
use SilverStripe\Versioned\Versioned;
use UndefinedOffset\SortableGridField\Forms\GridFieldSortableRows;
/**
* Class GridFieldSortableRowsPageTest
*
* @package SortableGridField\Tests
*/
class GridFieldSortableRowsPageTest extends SapphireTest
{
/** @var ArrayList */
protected $list;
/** @var GridField */
protected $gridField;
/** @var Form */
protected $form;
/** @var string */
public static $fixture_file = 'GridFieldSortableRowsPageTest.yml';
/** @var array */
protected static $extra_dataobjects = array(
GridFieldAction_PageSortOrder_Team::class,
GridFieldAction_PageSortOrder_VTeam::class
);
public function setUp()
{
parent::setUp();
$this->list = GridFieldAction_PageSortOrder_Team::get();
$config = GridFieldConfig_Base::create(5)->addComponent(new GridFieldSortableRows('SortOrder'));
$this->gridField = new GridField('testfield', 'testfield', $this->list, $config);
$this->form = new Form(new SortableGridField_DummyController(), 'mockform', FieldList::create(array($this->gridField)), FieldList::create());
}
public function testSortToNextPage()
{
$this->gridField->State->GridFieldPaginator->currentPage = 1;
$team3 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_PageSortOrder_Team', 'team3');
$this->logInWithPermission('ADMIN');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', array('ItemID' => $team3->ID, 'Target' => 'nextpage'), array('action_gridFieldAlterAction?StateID=' . $stateID => true, $this->form->getSecurityToken()->getName() => $this->form->getSecurityToken()->getValue()));
$session = Injector::inst()->create(Session::class, []);
$request->setSession($session);
$session->init($request);
$session->set($stateID, array('grid' => '', 'actionName' => 'sortToPage', 'args' => array('GridFieldSortableRows' => array('sortableToggle' => true), 'GridFieldPaginator' => array('currentPage' => 1))));
$this->gridField->gridFieldAlterAction(array('StateID' => $stateID), $this->form, $request);
$team6 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_PageSortOrder_Team', 'team6');
$this->assertEquals(5, $team6->SortOrder, 'Team 6 Should have moved to the bottom of the first page');
$team3 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_PageSortOrder_Team', 'team3');
$this->assertEquals(6, $team3->SortOrder, 'Team 3 Should have moved to the top of the second page');
}
public function testSortToPrevPage()
{
$this->gridField->State->GridFieldPaginator->currentPage = 2;
$team7 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_PageSortOrder_Team', 'team7');
$this->logInWithPermission('ADMIN');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', array('ItemID' => $team7->ID, 'Target' => 'previouspage'), array('action_gridFieldAlterAction?StateID=' . $stateID => true, $this->form->getSecurityToken()->getName() => $this->form->getSecurityToken()->getValue()));
$session = Injector::inst()->create(Session::class, []);
$request->setSession($session);
$session->init($request);
$session->set($stateID, array('grid' => '', 'actionName' => 'sortToPage', 'args' => array('GridFieldSortableRows' => array('sortableToggle' => true), 'GridFieldPaginator' => array('currentPage' => 1))));
$this->gridField->gridFieldAlterAction(array('StateID' => $stateID), $this->form, $request);
$team7 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_PageSortOrder_Team', 'team7');
$this->assertEquals(5, $team7->SortOrder, 'Team 7 Should have moved to the bottom of the first page');
$team5 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_PageSortOrder_Team', 'team5');
$this->assertEquals(6, $team5->SortOrder, 'Team 5 Should have moved to the top of the second page');
}
public function testSortToNextPageVersioned()
{
//Force versioned to reset
Versioned::reset();
$list = GridFieldAction_PageSortOrder_VTeam::get();
$this->gridField->setList($list);
/** @var GridFieldSortableRows $sortableGrid */
$sortableGrid = $this->gridField->getConfig()->getComponentByType(GridFieldSortableRows::class);
$sortableGrid->setUpdateVersionedStage('Live');
$this->gridField->State->GridFieldPaginator->currentPage = 1;
//Publish all records
foreach ($list as $item) {
$item->publish('Stage', 'Live');
}
$team3 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_PageSortOrder_VTeam', 'team3');
$this->logInWithPermission('ADMIN');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', array('ItemID' => $team3->ID, 'Target' => 'nextpage'), array('action_gridFieldAlterAction?StateID=' . $stateID => true, $this->form->getSecurityToken()->getName() => $this->form->getSecurityToken()->getValue()));
$session = Injector::inst()->create(Session::class, []);
$request->setSession($session);
$session->init($request);
$session->set($stateID, array('grid' => '', 'actionName' => 'sortToPage', 'args' => array('GridFieldSortableRows' => array('sortableToggle' => true), 'GridFieldPaginator' => array('currentPage' => 1))));
$this->gridField->gridFieldAlterAction(array('StateID' => $stateID), $this->form, $request);
$team6 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_PageSortOrder_VTeam', 'team6');
$this->assertEquals(5, $team6->SortOrder, 'Team 6 Should have moved to the bottom of the first page on Versioned stage "Stage"');
$team3 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_PageSortOrder_VTeam', 'team3');
$this->assertEquals(6, $team3->SortOrder, 'Team 3 Should have moved to the top of the second page on Versioned stage "Stage"');
$list = Versioned::get_by_stage(GridFieldAction_PageSortOrder_VTeam::class, 'Live');
$team6 = $list->byID($team6->ID);
$this->assertEquals(5, $team6->SortOrder, 'Team 6 Should have moved to the bottom of the first page on Versioned stage "Live"');
$team3 = $list->byID($team3->ID);
$this->assertEquals(6, $team3->SortOrder, 'Team 3 Should have moved to the top of the second page on Versioned stage "Live"');
}
public function testSortToPrevPageVersioned()
{
//Force versioned to reset
Versioned::reset();
$list = GridFieldAction_PageSortOrder_VTeam::get();
$this->gridField->setList($list);
/** @var GridFieldSortableRows $sortableGrid */
$sortableGrid = $this->gridField->getConfig()->getComponentByType(GridFieldSortableRows::class);
$sortableGrid->setUpdateVersionedStage('Live');
$this->gridField->State->GridFieldPaginator->currentPage = 2;
//Publish all records
foreach ($list as $item) {
$item->publish('Stage', 'Live');
}
$team7 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_PageSortOrder_VTeam', 'team7');
$this->logInWithPermission('ADMIN');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', array('ItemID' => $team7->ID, 'Target' => 'previouspage'), array('action_gridFieldAlterAction?StateID=' . $stateID => true, $this->form->getSecurityToken()->getName() => $this->form->getSecurityToken()->getValue()));
$session = Injector::inst()->create(Session::class, []);
$request->setSession($session);
$session->init($request);
$session->set($stateID, array('grid' => '', 'actionName' => 'sortToPage', 'args' => array('GridFieldSortableRows' => array('sortableToggle' => true), 'GridFieldPaginator' => array('currentPage' => 1))));
$this->gridField->gridFieldAlterAction(array('StateID' => $stateID), $this->form, $request);
$team7 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_PageSortOrder_VTeam', 'team7');
$this->assertEquals(5, $team7->SortOrder, 'Team 7 Should have moved to the bottom of the first page on Versioned stage "Stage"');
$team5 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_PageSortOrder_VTeam', 'team5');
$this->assertEquals(6, $team5->SortOrder, 'Team 5 Should have moved to the top of the second page on Versioned stage "Stage"');
$list = Versioned::get_by_stage(GridFieldAction_PageSortOrder_VTeam::class, 'Live');
$team7 = $list->byID($team7->ID);
$this->assertEquals(5, $team7->SortOrder, 'Team 7 Should have moved to the bottom of the first page on Versioned stage "Live"');
$team5 = $list->byID($team5->ID);
$this->assertEquals(6, $team5->SortOrder, 'Team 5 Should have moved to the top of the second page on Versioned stage "Live"');
}
}
/**
* Class GridFieldAction_PageSortOrder_Team
*
* @package SortableGridField\Tests
* @property string Name
* @property string City
* @property int SortOrder
*/
class GridFieldAction_PageSortOrder_Team extends DataObject implements TestOnly
{
private static $table_name = 'GridFieldAction_PageSortOrder_Team';
private static $db = array(
'Name' => DBVarchar::class,
'City' => DBVarchar::class,
'SortOrder' => DBInt::class
);
private static $default_sort = 'SortOrder';
}
/**
* Class GridFieldAction_PageSortOrder_VTeam
*
* @package SortableGridField\Tests
* @property string Name
* @property string City
* @property int SortOrder
*/
class GridFieldAction_PageSortOrder_VTeam extends DataObject implements TestOnly
{
private static $table_name = 'GridFieldAction_PageSortOrder_VTeam';
private static $db = array(
'Name' => DBVarchar::class,
'City' => DBVarchar::class,
'SortOrder' => DBInt::class
);
private static $default_sort = 'SortOrder';
private static $extensions = array(
"SilverStripe\\Versioned\\Versioned('Stage', 'Live')"
);
}

View File

@ -1,168 +0,0 @@
<?php
namespace UndefinedOffset\SortableGridField\Tests;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\Session;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\ValidationException;
use SilverStripe\ORM\FieldType\DBInt;
use SilverStripe\ORM\FieldType\DBVarchar;
use SilverStripe\Security\Member;
use SilverStripe\Versioned\Versioned;
use UndefinedOffset\SortableGridField\Forms\GridFieldSortableRows;
class GridFieldSortableRowsTest extends SapphireTest
{
/** @var ArrayList */
protected $list;
/** @var GridField */
protected $gridField;
/** @var Form */
protected $form;
/** @var string */
public static $fixture_file = 'GridFieldSortableRowsTest.yml';
/** @var array */
protected static $extra_dataobjects = array(
GridFieldAction_SortOrder_Team::class,
GridFieldAction_SortOrder_VTeam::class
);
public function setUp()
{
parent::setUp();
$this->list = GridFieldAction_SortOrder_Team::get();
$config = GridFieldConfig::create()->addComponent(new GridFieldSortableRows('SortOrder'));
$this->gridField = new GridField('testfield', 'testfield', $this->list, $config);
$this->form = new Form(new SortableGridField_DummyController(), 'mockform', new FieldList(array($this->gridField)), new FieldList());
}
public function testSortActionWithoutCorrectPermission()
{
if (Member::currentUser()) {
Member::currentUser()->logOut();
}
$this->setExpectedException(ValidationException::class);
$team1 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_Team', 'team1');
$team2 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_Team', 'team2');
$team3 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_Team', 'team3');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', array('ItemIDs' => "$team1->ID, $team3->ID, $team2->ID"), array('action_gridFieldAlterAction?StateID=' . $stateID => true, $this->form->getSecurityToken()->getName() => $this->form->getSecurityToken()->getValue()));
$session = Injector::inst()->create(Session::class, []);
$request->setSession($session);
$session->init($request);
$session->set($stateID, array('grid' => '', 'actionName' => 'saveGridRowSort', 'args' => array('GridFieldSortableRows' => array('sortableToggle' => true))));
$this->gridField->gridFieldAlterAction(array('StateID' => $stateID), $this->form, $request);
$this->assertEquals($team3->ID, $this->list->last()->ID, 'User should\'t be able to sort records without correct permissions.');
}
public function testSortActionWithAdminPermission()
{
$team1 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_Team', 'team1');
$team2 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_Team', 'team2');
$team3 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_Team', 'team3');
$this->logInWithPermission('ADMIN');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', array('ItemIDs' => "$team1->ID, $team3->ID, $team2->ID"), array('action_gridFieldAlterAction?StateID=' . $stateID => true, $this->form->getSecurityToken()->getName() => $this->form->getSecurityToken()->getValue()));
$session = Injector::inst()->create(Session::class, []);
$request->setSession($session);
$session->init($request);
$session->set($stateID, array('grid' => '', 'actionName' => 'saveGridRowSort', 'args' => array('GridFieldSortableRows' => array('sortableToggle' => true))));
$this->gridField->gridFieldAlterAction(array('StateID' => $stateID), $this->form, $request);
$this->assertEquals($team2->ID, $this->list->last()->ID, 'User should be able to sort records with ADMIN permission.');
}
public function testSortActionVersioned()
{
//Force versioned to reset
Versioned::reset();
$list = GridFieldAction_SortOrder_VTeam::get();
$this->gridField->setList($list);
/** @var GridFieldSortableRows $sortableGrid */
$sortableGrid = $this->gridField->getConfig()->getComponentByType(GridFieldSortableRows::class);
$sortableGrid->setUpdateVersionedStage('Live');
//Publish all records
foreach ($list as $item) {
$item->publish('Stage', 'Live');
}
$team1 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_VTeam', 'team1');
$team2 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_VTeam', 'team2');
$team3 = $this->objFromFixture('UndefinedOffset\SortableGridField\Tests\GridFieldAction_SortOrder_VTeam', 'team3');
$this->logInWithPermission('ADMIN');
$stateID = 'testGridStateActionField';
$request = new HTTPRequest('POST', 'url', array('ItemIDs' => "$team1->ID, $team3->ID, $team2->ID"), array('action_gridFieldAlterAction?StateID=' . $stateID => true, $this->form->getSecurityToken()->getName() => $this->form->getSecurityToken()->getValue()));
$session = Injector::inst()->create(Session::class, []);
$request->setSession($session);
$session->init($request);
$session->set($stateID, array('grid' => '', 'actionName' => 'saveGridRowSort', 'args' => array('GridFieldSortableRows' => array('sortableToggle' => true))));
$this->gridField->gridFieldAlterAction(array('StateID' => $stateID), $this->form, $request);
$this->assertEquals($team2->ID, $list->last()->ID, 'Sort should have happened on Versioned stage "Stage"');
$list = Versioned::get_by_stage(GridFieldAction_SortOrder_VTeam::class, 'Live');
$this->assertEquals($team2->ID, $list->last()->ID, 'Sort should have happened on Versioned stage "Live"');
}
}
/**
* Class GridFieldAction_SortOrder_Team
*
* @package SortableGridField\Tests
* @property string Name
* @property string City
* @property int SortOrder
*/
class GridFieldAction_SortOrder_Team extends DataObject implements TestOnly
{
private static $table_name = 'GridFieldAction_SortOrder_Team';
private static $db = array(
'Name' => DBVarchar::class,
'City' => DBVarchar::class,
'SortOrder' => 'Int'
);
private static $default_sort = 'SortOrder';
}
/**
* Class GridFieldAction_SortOrder_VTeam
*
* @package SortableGridField\Tests
* @property string Name
* @property string City
* @property int SortOrder
*/
class GridFieldAction_SortOrder_VTeam extends DataObject implements TestOnly
{
private static $table_name = 'GridFieldAction_SortOrder_VTeam';
private static $db = array(
'Name' => DBVarchar::class,
'City' => DBVarchar::class,
'SortOrder' => DBInt::class
);
private static $default_sort = 'SortOrder';
private static $extensions = array(
"SilverStripe\\Versioned\\Versioned('Stage', 'Live')"
);
}

View File

@ -0,0 +1,15 @@
SS_ENVIRONMENT_TYPE="dev"
SS_TRUSTED_PROXY_IPS="*"
SS_DATABASE_CLASS="MySQLDatabase"
SS_DATABASE_SERVER="127.0.0.1"
SS_DATABASE_USERNAME="root"
SS_DATABASE_PASSWORD="testpassword"
SS_DATABASE_NAME="test_db"
SS_DEFAULT_ADMIN_USERNAME="username"
SS_DEFAULT_ADMIN_PASSWORD="password"
SS_ERROR_LOG="artifacts/silverstripe-errors.log"
TRAVIS_TEST_SESSION="1"