From aa2b64180edbaeef899774567e0e68c46a0594c7 Mon Sep 17 00:00:00 2001 From: mak001 Date: Wed, 29 May 2019 17:33:42 -0500 Subject: [PATCH 1/2] SilverStripe 4 compatibility - now a vendor module - exposes css and js directories - updated requirements - added namespace - formatted --- _config.php | 4 - composer.json | 23 ++- {code => src}/GridFieldGroupable.php | 255 ++++++++++++++++----------- 3 files changed, 168 insertions(+), 114 deletions(-) rename {code => src}/GridFieldGroupable.php (51%) diff --git a/_config.php b/_config.php index 40fe94d..b3d9bbc 100644 --- a/_config.php +++ b/_config.php @@ -1,5 +1 @@ groupsAvailable = $groupsAvailable; } - /** - * Sets a config option. - * - * @param string $option [groupUnassignedName, groupFieldLabel, groupField, groupsAvailable] - * @param mixed $value (string/array) - * @return GridFieldGroupable $this - */ - public function setOption($option, $value) - { - $this->$option = $value; - return $this; - } - - /** - * @param string $option [groupUnassignedName, groupFieldLabel, groupField, groupsAvailable] - * @return mixed - */ - public function getOption($option) - { - return $this->$option; - } + /** + * Sets a config option. + * + * @param string $option [groupUnassignedName, groupFieldLabel, groupField, groupsAvailable] + * @param mixed $value (string/array) + * @return GridFieldGroupable $this + */ + public function setOption($option, $value) + { + $this->$option = $value; + return $this; + } + + /** + * @param string $option [groupUnassignedName, groupFieldLabel, groupField, groupsAvailable] + * @return mixed + */ + public function getOption($option) + { + return $this->$option; + } /** * Convenience function to have the requirements included */ - public static function include_requirements() { + public static function include_requirements() + { + Requirements::javascript('micschk/silverstripe-groupable-gridfield: js/groupable.js'); + Requirements::css('micschk/silverstripe-groupable-gridfield: css/groupable.css'); - $moduleDir = GROUPABLE_DIR; - - Requirements::javascript($moduleDir.'/js/groupable.js'); - Requirements::css($moduleDir.'/css/groupable.css'); - - } + } - public function getURLHandlers($grid) { - return array( - 'POST group_assignment' => 'handleGroupAssignment', - ); - } + public function getURLHandlers($grid) + { + return array( + 'POST group_assignment' => 'handleGroupAssignment', + ); + } - /** - * @param GridField $field - */ - public function getHTMLFragments($field) { + /** + * @param \SilverStripe\Forms\GridField\GridField $field + */ + public function getHTMLFragments($field) + { - if( ! $field->getConfig()->getComponentByType('GridFieldOrderableRows')) { + if (!$field->getConfig()->getComponentByType(GridFieldOrderableRows::class)) { user_error("GridFieldGroupable requires a GridFieldOrderableRows component", E_USER_WARNING); } - + self::include_requirements(); - + // set ajax urls / vars - $field->addExtraClass('ss-gridfield-groupable'); - $field->setAttribute('data-url-group-assignment', $field->Link('group_assignment')); + $field->addExtraClass('ss-gridfield-groupable'); + $field->setAttribute('data-url-group-assignment', $field->Link('group_assignment')); // setoptions [groupUnassignedName, groupFieldLabel, groupField, groupsAvailable] - $field->setAttribute('data-groupable-unassigned', $this->getOption('groupUnassignedName')); - $field->setAttribute('data-groupable-role', $this->getOption('groupFieldLabel')); - $field->setAttribute('data-groupable-itemfield', $this->getOption('groupField')); - $field->setAttribute('data-groupable-groups', json_encode( $this->getOption('groupsAvailable') ) ); - - } - - /** - * Handles requests to assign a new block area to a block item - * - * @param GridField $grid - * @param SS_HTTPRequest $request - * @return SS_HTTPResponse - */ - public function handleGroupAssignment($grid, $request) { - $list = $grid->getList(); - + $field->setAttribute('data-groupable-unassigned', $this->getOption('groupUnassignedName')); + $field->setAttribute('data-groupable-role', $this->getOption('groupFieldLabel')); + $field->setAttribute('data-groupable-itemfield', $this->getOption('groupField')); + $field->setAttribute('data-groupable-groups', json_encode($this->getOption('groupsAvailable'))); + + } + + /** + * Handles requests to assign a new block area to a block item + * + * @param \SilverStripe\Forms\GridField\GridField $grid + * @param \SilverStripe\Control\HTTPRequest $request + * @return \SilverStripe\Control\HTTPResponse|string + * @throws \SilverStripe\Control\HTTPResponse_Exception + * + * @throws \SilverStripe\ORM\ValidationException + * @throws \Exception + */ + public function handleGroupAssignment($grid, $request) + { + $list = $grid->getList(); + // (copied from GridFieldOrderableRows::handleReorder) - $modelClass = $grid->getModelClass(); - if ($list instanceof ManyManyList && !singleton($modelClass)->canView()) { - $this->httpError(403); - } else if(!($list instanceof ManyManyList) && !singleton($modelClass)->canEdit()) { - $this->httpError(403); - } + $modelClass = $grid->getModelClass(); + if ($list instanceof ManyManyList && !singleton($modelClass)->canView()) { + $this->httpError(403); + } else { + if (!($list instanceof ManyManyList) && !singleton($modelClass)->canEdit()) { + $this->httpError(403); + } + } // - $item_id = $request->postVar('groupable_item_id'); - $group_key = $request->postVar('groupable_group_key'); - if($group_key=='none') $group_key = ''; - $item = $list->byID($item_id); + $item_id = $request->postVar('groupable_item_id'); + $group_key = $request->postVar('groupable_group_key'); + if ($group_key == 'none') { + $group_key = ''; + } + $item = $list->byID($item_id); $groupField = $this->getOption('groupField'); - // Update item with correct Group assigned (custom query required to write m_m_extraField) + // Update item with correct Group assigned (custom query required to write m_m_extraField) // DB::query(sprintf( // "UPDATE `%s` SET `%s` = '%s' WHERE `BlockID` = %d", // 'SiteTree_Blocks', @@ -170,16 +198,17 @@ public function handleGroupAssignment($grid, $request) { } $this->extend('onAfterAssignGroupItems', $list); - + // Forward the request to GridFieldOrderableRows::handleReorder (if GridFieldOrderableRows) - $orderableRowsComponent = $grid->getConfig()->getComponentByType('GridFieldOrderableRows'); - if($orderableRowsComponent) { + /** @var $orderableRowsComponent GridFieldOrderableRows */ + $orderableRowsComponent = $grid->getConfig()->getComponentByType(GridFieldOrderableRows::class); + if ($orderableRowsComponent) { return $orderableRowsComponent->handleReorder($grid, $request); } else { return $grid->FieldHolder(); } - } + } /** * Gets the table which contains the group field. @@ -187,23 +216,26 @@ public function handleGroupAssignment($grid, $request) { * * @param DataList $list * @return string + * + * @throws \Exception */ - public function getGroupTable(DataList $list) { + public function getGroupTable(DataList $list) + { $field = $this->getOption('groupField'); - if($list instanceof ManyManyList) { + if ($list instanceof ManyManyList) { $extra = $list->getExtraFields(); $table = $list->getJoinTable(); - if($extra && array_key_exists($field, $extra)) { + if ($extra && array_key_exists($field, $extra)) { return $table; } } $classes = ClassInfo::dataClassesFor($list->dataClass()); - foreach($classes as $class) { - if(singleton($class)->hasOwnTableDatabaseField($field)) { + foreach ($classes as $class) { + if (singleton($class)->hasOwnTableDatabaseField($field)) { return $class; } } @@ -212,20 +244,21 @@ public function getGroupTable(DataList $list) { } // (adapted from GridFieldOrderableRows) - protected function getGroupTableClauseForIds(DataList $list, $ids) { - if(is_array($ids)) { + protected function getGroupTableClauseForIds(DataList $list, $ids) + { + if (is_array($ids)) { $value = 'IN (' . implode(', ', array_map('intval', $ids)) . ')'; } else { - $value = '= ' . (int) $ids; + $value = '= ' . (int)$ids; } - if($list instanceof ManyManyList) { + if ($list instanceof ManyManyList) { $extra = $list->getExtraFields(); - $key = $list->getLocalKey(); + $key = $list->getLocalKey(); $foreignKey = $list->getForeignKey(); - $foreignID = (int) $list->getForeignID(); + $foreignID = (int)$list->getForeignID(); - if($extra && array_key_exists($this->getOption('groupField'), $extra)) { + if ($extra && array_key_exists($this->getOption('groupField'), $extra)) { return sprintf( '"%s" %s AND "%s" = %d', $key, @@ -252,57 +285,65 @@ protected function getGroupTableClauseForIds(DataList $list, $ids) { /** * Modify the list of columns displayed in the table. * - * @see {@link GridFieldDataColumns->getDisplayFields()} + * @param \SilverStripe\Forms\GridField\GridField $gridField + * @param array $columns List of columns + * @param array - List reference of all column names. * @see {@link GridFieldDataColumns}. * - * @param GridField $gridField - * @param arary $columns List of columns - * @param array - List reference of all column names. + * @see {@link GridFieldDataColumns->getDisplayFields()} */ - public function augmentColumns($gridField, &$columns){ } + public function augmentColumns($gridField, &$columns) + { + } /** * Names of all columns which are affected by this component. * - * @param GridField $gridField + * @param \SilverStripe\Forms\GridField\GridField $gridField * @return array */ - public function getColumnsHandled($gridField){ + public function getColumnsHandled($gridField) + { return array('Reorder'); } /** * HTML for the column, content of the element. * - * @param GridField $gridField - * @param DataObject $record - Record displayed in this row - * @param string $columnName + * @param \SilverStripe\Forms\GridField\GridField $gridField + * @param \SilverStripe\ORM\DataObject $record - Record displayed in this row + * @param string $columnName * @return string - HTML for the column. Return NULL to skip. */ - public function getColumnContent($gridField, $record, $columnName){ } + public function getColumnContent($gridField, $record, $columnName) + { + return null; + } /** * Attributes for the element containing the content returned by {@link getColumnContent()}. * - * @param GridField $gridField - * @param DataObject $record displayed in this row - * @param string $columnName + * @param \SilverStripe\Forms\GridField\GridField $gridField + * @param \SilverStripe\ORM\DataObject $record displayed in this row + * @param string $columnName * @return array */ - public function getColumnAttributes($gridField, $record, $columnName){ + public function getColumnAttributes($gridField, $record, $columnName) + { $groupField = $this->getOption('groupField'); - return array('data-groupable-group'=>$record->$groupField); + return array('data-groupable-group' => $record->$groupField); } /** * Additional metadata about the column which can be used by other components, * e.g. to set a title for a search column header. * - * @param GridField $gridField + * @param \SilverStripe\Forms\GridField\GridField $gridField * @param string $columnName * @return array - Map of arbitrary metadata identifiers to their values. */ - public function getColumnMetadata($gridField, $columnName){ + public function getColumnMetadata($gridField, $columnName) + { return array(); } From 523eaa7e6d1373576e8bee324d55f56812d74e37 Mon Sep 17 00:00:00 2001 From: mak001 Date: Thu, 30 May 2019 09:34:55 -0500 Subject: [PATCH 2/2] Added testing files --- .travis.yml | 34 ++++++++++++++++++ README.md | 4 ++- composer.json | 8 +++-- phpcs.xml.dist | 24 +++++++++++++ phpunit.xml.dist | 14 ++++++++ tests/GridFieldGroupableTest.php | 62 ++++++++++++++++++++++++++++++++ 6 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 .travis.yml create mode 100644 phpcs.xml.dist create mode 100644 phpunit.xml.dist create mode 100644 tests/GridFieldGroupableTest.php diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..32919e0 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,34 @@ +language: php + +env: + global: + - COMPOSER_ROOT_VERSION=4.0.x-dev + - CODECOV_TOKEN= + - SCRUT_TOKEN= + +matrix: + include: + - php: 7.1 + env: DB=MYSQL PHPUNIT_TEST=1 + - php: 7.2 + env: DB=MYSQL PHPUNIT_COVERAGE_TEST=1 + - php: 7.3 + env: DB=MYSQL PHPCS_TEST=1 PHPUNIT_TEST=1 + +before_script: + # Init PHP + - phpenv rehash + - phpenv config-rm xdebug.ini + - echo 'memory_limit = 2048M' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini + + # Install composer dependencies + - composer require --prefer-dist --no-update silverstripe-themes/simple:~3.2 + - composer update --no-suggest --prefer-dist + +script: + - if [[ $PHPUNIT_TEST ]]; then vendor/bin/phpunit; fi + - if [[ $PHPUNIT_COVERAGE_TEST ]]; then phpdbg -qrr vendor/bin/phpunit --coverage-clover=coverage.xml && wget https://scrutinizer-ci.com/ocular.phar; fi + - if [[ $PHPCS_TEST ]]; then vendor/bin/phpcs src/ tests/; fi + +after_success: + - if [[ $PHPUNIT_COVERAGE_TEST ]]; then bash <(curl -s https://codecov.io/bash) -f coverage.xml -t $CODECOV_TOKEN && travis_retry php ocular.phar code-coverage:upload --format=php-clover --access-token=$SCRUT_TOKEN coverage.xml; fi \ No newline at end of file diff --git a/README.md b/README.md index 3488df9..85bd3a5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ # SilverStripe GridField Groupable +[![Build Status](https://travis-ci.org/micschk/silverstripe-groupable-gridfield.svg?branch=master)](https://travis-ci.org/micschk/silverstripe-groupable-gridfield) +[![codecov.io](https://codecov.io/github/micschk/silverstripe-groupable-gridfield/coverage.svg?branch=master)](https://codecov.io/github/micschk/silverstripe-groupable-gridfield?branch=master) This module allows drag & drop grouping of items in a GridField. It bolts on top of- and depends on GridFieldOrderableRows for the drag & drop sorting functionality @@ -17,7 +19,7 @@ Example application (Block Enhancements module): assign content blocks to block- ### Requirements (all pulled in by composer) -* SilverStripe CMS ~3.1 +* SilverStripe Framework ~4.0 * SilverStripe GridFieldExtensions ## Usage: diff --git a/composer.json b/composer.json index 373c549..7e03feb 100644 --- a/composer.json +++ b/composer.json @@ -16,10 +16,12 @@ ], "license": "MIT", "require": { - "silverstripe/framework": "^4.0", "silverstripe/vendor-plugin": "^1.0", - "symbiote/silverstripe-gridfieldextensions": "^3", - "ext-json": "*" + "symbiote/silverstripe-gridfieldextensions": "^3" + }, + "require-dev": { + "phpunit/phpunit": "^5.7", + "squizlabs/php_codesniffer": "*" }, "suggest": { "micschk/silverstripe-block_enhancements": "Enhancements to the Silverstripe Blocks module" diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..2a111dc --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,24 @@ + + + Coding standard for SilverStripe 4.x + + + */vendor/* + */thirdparty/* + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..a63f213 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,14 @@ + + + tests + + + + + src/ + + tests/ + + + + \ No newline at end of file diff --git a/tests/GridFieldGroupableTest.php b/tests/GridFieldGroupableTest.php new file mode 100644 index 0000000..ffe889e --- /dev/null +++ b/tests/GridFieldGroupableTest.php @@ -0,0 +1,62 @@ +assertInternalType('array', $groupable->getURLHandlers(null)); + } + + /** + * + */ + public function testGetColumnsHandled() + { + $groupable = new GridFieldGroupable(); + $this->assertInternalType('array', $groupable->getColumnsHandled(null)); + } + + /** + * + */ + public function testGetColumnContent() + { + $groupable = new GridFieldGroupable(); + $this->assertNull($groupable->getColumnContent(null, null, '')); + } + + /** + * + */ + public function testGetColumnAttributes() + { + $groupable = new GridFieldGroupable('ID'); + $record = DataObject::create(); + $attributes = $groupable->getColumnAttributes(null, $record, null); + $this->assertInternalType('array', $attributes); + $this->assertArrayHasKey('data-groupable-group', $attributes); + } + + /** + * + */ + public function testGetColumnMetadata() + { + $groupable = new GridFieldGroupable(); + $this->assertInternalType('array', $groupable->getColumnMetadata(null,'')); + } +} \ No newline at end of file