From f7a602137a6fb25f4f5a70d7be53d8879557a442 Mon Sep 17 00:00:00 2001 From: Dileep Ratnayake Date: Tue, 27 Aug 2019 11:49:17 +1200 Subject: [PATCH 01/11] add html_entity_decode to breadcrumbs --- src/Security/Group.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Security/Group.php b/src/Security/Group.php index 403f92819..c0b0dfee7 100755 --- a/src/Security/Group.php +++ b/src/Security/Group.php @@ -115,6 +115,11 @@ class Group extends DataObject */ public function getCMSFields() { + $list = Group::get()->exclude('ID', $this->ID); + $groups = new ArrayList(); + foreach($list as $grp){ + $groups->push(['ID' => $grp->ID, 'Title' => html_entity_decode($grp->Breadcrumbs)]); + } $fields = new FieldList( new TabSet( "Root", @@ -125,7 +130,7 @@ class Group extends DataObject $parentidfield = DropdownField::create( 'ParentID', $this->fieldLabel('Parent'), - Group::get()->exclude('ID', $this->ID)->map('ID', 'Breadcrumbs') + $groups )->setEmptyString(' '), new TextareaField('Description', $this->fieldLabel('Description')) ), From d2a07b10478ddc57d798e9c96f057973e6e4de68 Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Tue, 27 Aug 2019 11:37:21 +1200 Subject: [PATCH 02/11] FIX Remove error when exporting a column that is not displayed in a GridField --- src/Forms/GridField/GridFieldDataColumns.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Forms/GridField/GridFieldDataColumns.php b/src/Forms/GridField/GridFieldDataColumns.php index c8dd223da..3c6d49afc 100644 --- a/src/Forms/GridField/GridFieldDataColumns.php +++ b/src/Forms/GridField/GridFieldDataColumns.php @@ -154,7 +154,7 @@ class GridFieldDataColumns implements GridField_ColumnProvider { // Find the data column for the given named column $columns = $this->getDisplayFields($gridField); - $columnInfo = $columns[$columnName]; + $columnInfo = array_key_exists($columnName, $columns) ? $columns[$columnName] : null; // Allow callbacks if (is_array($columnInfo) && isset($columnInfo['callback'])) { From 4f8240bd48e181d933fc9b252c37877fcb5834d7 Mon Sep 17 00:00:00 2001 From: Dileep Ratnayake Date: Tue, 27 Aug 2019 12:19:03 +1200 Subject: [PATCH 03/11] Update src/Security/Group.php Co-Authored-By: Andre Kiste --- src/Security/Group.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Security/Group.php b/src/Security/Group.php index c0b0dfee7..a2577c479 100755 --- a/src/Security/Group.php +++ b/src/Security/Group.php @@ -117,7 +117,7 @@ class Group extends DataObject { $list = Group::get()->exclude('ID', $this->ID); $groups = new ArrayList(); - foreach($list as $grp){ + foreach ($list as $grp) { $groups->push(['ID' => $grp->ID, 'Title' => html_entity_decode($grp->Breadcrumbs)]); } $fields = new FieldList( From 40e5c4ec59260bfe2f3497f31fae1dd6c80e24a3 Mon Sep 17 00:00:00 2001 From: Dileep Ratnayake Date: Tue, 27 Aug 2019 16:19:40 +1200 Subject: [PATCH 04/11] Update Group.php use of convert::raw2xml, rename $grp to $group --- src/Security/Group.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Security/Group.php b/src/Security/Group.php index a2577c479..0755dc884 100755 --- a/src/Security/Group.php +++ b/src/Security/Group.php @@ -105,6 +105,8 @@ class Group extends DataObject return $doSet; } + + private function getGroups /** * Caution: Only call on instances, not through a singleton. @@ -116,9 +118,9 @@ class Group extends DataObject public function getCMSFields() { $list = Group::get()->exclude('ID', $this->ID); - $groups = new ArrayList(); - foreach ($list as $grp) { - $groups->push(['ID' => $grp->ID, 'Title' => html_entity_decode($grp->Breadcrumbs)]); + $groups = ArrayList::create(); + foreach ($list as $group) { + $groups->push(['ID' => $group->ID, 'Title' => Convert::xml2raw($group->Breadcrumbs)]); } $fields = new FieldList( new TabSet( From a976a1688bd43c022e40e91422f630afece8ddc4 Mon Sep 17 00:00:00 2001 From: Dileep Ratnayake Date: Tue, 27 Aug 2019 16:21:08 +1200 Subject: [PATCH 05/11] Update Group.php move to private method --- src/Security/Group.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Security/Group.php b/src/Security/Group.php index 0755dc884..0f3acd26d 100755 --- a/src/Security/Group.php +++ b/src/Security/Group.php @@ -106,7 +106,15 @@ class Group extends DataObject return $doSet; } - private function getGroups + private function getDecodedBreadcrumbs() + { + $list = Group::get()->exclude('ID', $this->ID); + $groups = ArrayList::create(); + foreach ($list as $group) { + $groups->push(['ID' => $group->ID, 'Title' => Convert::xml2raw($group->Breadcrumbs)]); + } + return $groups; + } /** * Caution: Only call on instances, not through a singleton. @@ -117,11 +125,7 @@ class Group extends DataObject */ public function getCMSFields() { - $list = Group::get()->exclude('ID', $this->ID); - $groups = ArrayList::create(); - foreach ($list as $group) { - $groups->push(['ID' => $group->ID, 'Title' => Convert::xml2raw($group->Breadcrumbs)]); - } + $groups = $this->getDecodedBreadcrumbs(); $fields = new FieldList( new TabSet( "Root", From 9b7075ed5d3000444ef174ff910d2aa56f0879e2 Mon Sep 17 00:00:00 2001 From: Dileep Ratnayake Date: Tue, 27 Aug 2019 16:22:00 +1200 Subject: [PATCH 06/11] Update Group.php --- src/Security/Group.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Security/Group.php b/src/Security/Group.php index 0f3acd26d..f6a67032f 100755 --- a/src/Security/Group.php +++ b/src/Security/Group.php @@ -125,7 +125,6 @@ class Group extends DataObject */ public function getCMSFields() { - $groups = $this->getDecodedBreadcrumbs(); $fields = new FieldList( new TabSet( "Root", @@ -136,7 +135,7 @@ class Group extends DataObject $parentidfield = DropdownField::create( 'ParentID', $this->fieldLabel('Parent'), - $groups + $this->getDecodedBreadcrumbs() )->setEmptyString(' '), new TextareaField('Description', $this->fieldLabel('Description')) ), From 73f43c6f428dc92ee2c9a5f932c63ed8a04c8230 Mon Sep 17 00:00:00 2001 From: Maxime Rainville Date: Wed, 28 Aug 2019 17:14:19 +1200 Subject: [PATCH 07/11] BUG Remove placeholder text on new group form --- src/Security/Group.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/Security/Group.php b/src/Security/Group.php index 403f92819..cfa57c237 100755 --- a/src/Security/Group.php +++ b/src/Security/Group.php @@ -83,15 +83,6 @@ class Group extends DataObject private static $table_name = "Group"; - public function populateDefaults() - { - parent::populateDefaults(); - - if (!$this->Title) { - $this->Title = _t(__CLASS__ . '.NEWGROUP', "New Group"); - } - } - public function getAllChildren() { $doSet = new ArrayList(); From e07bcee182f42b12f62a741e2862729db0cc139e Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Thu, 29 Aug 2019 09:10:03 +1200 Subject: [PATCH 08/11] Add missing upgrade rules for Email class --- .upgrade.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.upgrade.yml b/.upgrade.yml index 59cccbf43..a2d4baa0e 100644 --- a/.upgrade.yml +++ b/.upgrade.yml @@ -1100,6 +1100,32 @@ warnings: 'SilverStripe\Control\Email\Email->setTemplate()': message: 'Renamed to setHTMLTemplate()' replacement: 'setHTMLTemplate' + 'SilverStripe\Control\Email\Email->replyTo()': + message: 'Renamed to setReplyTo()' + replacement: 'setReplyTo' + 'SilverStripe\Control\Email\Email->attachFile()': + message: 'Renamed to addAttachment()' + replacement: 'addAttachment' + 'SilverStripe\Control\Email\Email->Subject()': + message: 'Renamed to getSubject()' + replacement: 'getSubject' + 'SilverStripe\Control\Email\Email->Body()': + message: 'Renamed to getBody()' + replacement: 'getBody' + 'SilverStripe\Control\Email\Email->From()': + message: 'Renamed to getFrom()' + replacement: 'getFrom' + 'SilverStripe\Control\Email\Email->To()': + message: 'Renamed to getTo()' + replacement: 'getTo' + 'SilverStripe\Control\Email\Email->Cc()': + message: 'Renamed to getCc()' + replacement: 'getCc' + 'SilverStripe\Control\Email\Email->Bcc()': + message: 'Renamed to getBcc()' + replacement: 'getBcc' + 'SilverStripe\Control\Email\Email->addCustomHeader()': + message: 'addCustomHeader() is removed' 'SilverStripe\i18n\i18n::get_language_name()': message: 'moved to SilverStripe\i18n\Data\Locales::languageName()' replacement: 'getData()->languageName' From 77ba8391c40278930873301d50ee3c1168da4cef Mon Sep 17 00:00:00 2001 From: Robbie Averill Date: Thu, 29 Aug 2019 14:54:16 +1200 Subject: [PATCH 09/11] FIX Byte Order Marks (BOM) are now stripped when importing CSV files --- src/Dev/CsvBulkLoader.php | 1 + tests/php/Dev/CsvBulkLoaderTest.php | 15 +++++++++++++++ .../csv/PlayersWithHeaderAndBOM.csv | 4 ++++ 3 files changed, 20 insertions(+) create mode 100644 tests/php/Dev/CsvBulkLoaderTest/csv/PlayersWithHeaderAndBOM.csv diff --git a/src/Dev/CsvBulkLoader.php b/src/Dev/CsvBulkLoader.php index be6ea4c9c..3b95fa2fd 100644 --- a/src/Dev/CsvBulkLoader.php +++ b/src/Dev/CsvBulkLoader.php @@ -76,6 +76,7 @@ class CsvBulkLoader extends BulkLoader $filepath = Director::getAbsFile($filepath); $csvReader = Reader::createFromPath($filepath, 'r'); $csvReader->setDelimiter($this->delimiter); + $csvReader->stripBom(true); $tabExtractor = function ($row, $rowOffset, $iterator) { foreach ($row as &$item) { diff --git a/tests/php/Dev/CsvBulkLoaderTest.php b/tests/php/Dev/CsvBulkLoaderTest.php index 8885e58a9..f00f15f32 100644 --- a/tests/php/Dev/CsvBulkLoaderTest.php +++ b/tests/php/Dev/CsvBulkLoaderTest.php @@ -2,6 +2,7 @@ namespace SilverStripe\Dev\Tests; +use League\Csv\Writer; use SilverStripe\Dev\Tests\CsvBulkLoaderTest\CustomLoader; use SilverStripe\Dev\Tests\CsvBulkLoaderTest\Player; use SilverStripe\Dev\Tests\CsvBulkLoaderTest\PlayerContract; @@ -300,6 +301,20 @@ class CsvBulkLoaderTest extends SapphireTest $this->assertEquals($player->FirstName, "John. He's a good guy. "); } + public function testLoadWithByteOrderMark() + { + $loader = new CsvBulkLoader(Player::class); + $loader->load($this->csvPath . 'PlayersWithHeaderAndBOM.csv'); + + $players = Player::get(); + + $this->assertCount(3, $players); + $this->assertListContains([ + ['FirstName' => 'Jamie', 'Birthday' => '1882-01-31'], + ['FirstName' => 'Järg', 'Birthday' => '1982-06-30'], + ['FirstName' => 'Jacob', 'Birthday' => '2000-04-30'], + ], $players); + } protected function getLineCount(&$file) { diff --git a/tests/php/Dev/CsvBulkLoaderTest/csv/PlayersWithHeaderAndBOM.csv b/tests/php/Dev/CsvBulkLoaderTest/csv/PlayersWithHeaderAndBOM.csv new file mode 100644 index 000000000..93a871931 --- /dev/null +++ b/tests/php/Dev/CsvBulkLoaderTest/csv/PlayersWithHeaderAndBOM.csv @@ -0,0 +1,4 @@ +FirstName,Biography,Birthday,IsRegistered +Jamie,"Pretty old\, with an escaped comma",1882-01-31,1 +Järg,"Unicode FTW",1982-06-30,1 +Jacob," Likes leading tabs in his biography",2000-04-30,0 From fe4eb5dd2ad2039c48e9b6c31e5966416fa01ab0 Mon Sep 17 00:00:00 2001 From: Dileep Ratnayake Date: Thu, 29 Aug 2019 15:44:41 +1200 Subject: [PATCH 10/11] Update src/Security/Group.php Co-Authored-By: Maxime Rainville --- src/Security/Group.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Security/Group.php b/src/Security/Group.php index f6a67032f..35de94206 100755 --- a/src/Security/Group.php +++ b/src/Security/Group.php @@ -111,7 +111,7 @@ class Group extends DataObject $list = Group::get()->exclude('ID', $this->ID); $groups = ArrayList::create(); foreach ($list as $group) { - $groups->push(['ID' => $group->ID, 'Title' => Convert::xml2raw($group->Breadcrumbs)]); + $groups->push(['ID' => $group->ID, 'Title' => $group->getBreadcrumbs(' » ')]); } return $groups; } From 2f8d847a10fcef45a49e1d96d407b84b99221637 Mon Sep 17 00:00:00 2001 From: bergice Date: Tue, 27 Aug 2019 17:20:50 +1200 Subject: [PATCH 11/11] FIX make the grid field actions consistent to what they look like on pages Resolves https://github.com/silverstripe/silverstripe-admin/issues/904 --- .../GridFieldDetailForm_ItemRequest.php | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Forms/GridField/GridFieldDetailForm_ItemRequest.php b/src/Forms/GridField/GridFieldDetailForm_ItemRequest.php index 4b58032e4..188bac218 100644 --- a/src/Forms/GridField/GridFieldDetailForm_ItemRequest.php +++ b/src/Forms/GridField/GridFieldDetailForm_ItemRequest.php @@ -350,15 +350,23 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler { $actions = FieldList::create(); + $majorActions = CompositeField::create()->setName('MajorActions'); + $majorActions->setFieldHolderTemplate(get_class($majorActions) . '_holder_buttongroup'); + $actions->push($majorActions); + if ($this->record->ID !== 0) { // existing record if ($this->record->canEdit()) { - $actions->push(FormAction::create('doSave', _t('SilverStripe\\Forms\\GridField\\GridFieldDetailForm.Save', 'Save')) + $noChangesClasses = 'btn-outline-primary font-icon-tick'; + $majorActions->push(FormAction::create('doSave', _t('SilverStripe\\Forms\\GridField\\GridFieldDetailForm.Save', 'Save')) + ->addExtraClass($noChangesClasses) + ->setAttribute('data-btn-alternate-add', 'btn-primary font-icon-save') + ->setAttribute('data-btn-alternate-remove', $noChangesClasses) ->setUseButtonTag(true) - ->addExtraClass('btn-primary font-icon-save')); + ->setAttribute('data-text-alternate', _t('SilverStripe\\CMS\\Controllers\\CMSMain.SAVEDRAFT', 'Save'))); } if ($this->record->canDelete()) { - $actions->push(FormAction::create('doDelete', _t('SilverStripe\\Forms\\GridField\\GridFieldDetailForm.Delete', 'Delete')) + $actions->insertAfter('MajorActions', FormAction::create('doDelete', _t('SilverStripe\\Forms\\GridField\\GridFieldDetailForm.Delete', 'Delete')) ->setUseButtonTag(true) ->addExtraClass('btn-outline-danger btn-hide-outline font-icon-trash-bin action--delete')); } @@ -370,7 +378,7 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler $actions->push($this->getRightGroupField()); } else { // adding new record //Change the Save label to 'Create' - $actions->push(FormAction::create('doSave', _t('SilverStripe\\Forms\\GridField\\GridFieldDetailForm.Create', 'Create')) + $majorActions->push(FormAction::create('doSave', _t('SilverStripe\\Forms\\GridField\\GridFieldDetailForm.Create', 'Create')) ->setUseButtonTag(true) ->addExtraClass('btn-primary font-icon-plus-thin')); @@ -384,7 +392,7 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler $oneLevelUp->Link, // url _t('SilverStripe\\Forms\\GridField\\GridFieldDetailForm.CancelBtn', 'Cancel') // label ); - $actions->push(new LiteralField('cancelbutton', $text)); + $actions->insertAfter('MajorActions', new LiteralField('cancelbutton', $text)); } }