diff --git a/security/GroupCsvBulkLoader.php b/security/GroupCsvBulkLoader.php new file mode 100644 index 000000000..bf134754c --- /dev/null +++ b/security/GroupCsvBulkLoader.php @@ -0,0 +1,64 @@ +Arg and Permission->Type values + * + * @package sapphire + * @subpackage security + */ +class GroupCsvBulkLoader extends CsvBulkLoader { + + public $duplicateChecks = array( + 'Code' => 'Code', + ); + + function __construct($objectClass = null) { + if(!$objectClass) $objectClass = 'Group'; + + parent::__construct($objectClass); + } + + function processRecord($record, $columnMap, &$results, $preview = false) { + // We match by 'Code', the ID property is confusing the importer + if(isset($record['ID'])) unset($record['ID']); + + $objID = parent::processRecord($record, $columnMap, $results, $preview); + + $group = DataObject::get_by_id($this->objectClass, $objID); + // set group hierarchies - we need to do this after all records + // are imported to avoid missing "early" references to parents + // which are imported later on in the CSV file. + if(isset($record['ParentCode']) && $record['ParentCode']) { + $parentGroup = DataObject::get_one( + 'Group', + sprintf('"Code" = \'%s\'', Convert::raw2sql($record['ParentCode'])) + ); + if($parentGroup) { + $group->ParentID = $parentGroup->ID; + $group->write(); + } + } + + // set permission codes - these are all additive, meaning + // existing permissions arent cleared. + if(isset($record['PermissionCodes']) && $record['PermissionCodes']) { + foreach(explode(',', $record['PermissionCodes']) as $code) { + $p = DataObject::get_one( + 'Permission', + sprintf( + '"Code" = \'%s\' AND "GroupID" = %d', + Convert::raw2sql($code), + $group->ID + ) + ); + if(!$p) { + $p = new Permission(array('Code' => $code)); + $p->write(); + } + $group->Permissions()->add($p); + } + } + + return $objID; + } + +} \ No newline at end of file diff --git a/tests/security/GroupCsvBulkLoaderTest.csv b/tests/security/GroupCsvBulkLoaderTest.csv new file mode 100644 index 000000000..460f65c61 --- /dev/null +++ b/tests/security/GroupCsvBulkLoaderTest.csv @@ -0,0 +1,3 @@ +ID,ClassName,Title,Code,IPRestrictions,HtmlEditorConfig,ParentID,ParentCode,PermissionCodes +2,Group,New Group 1,newgroup1,1.2.3.4,NULL,0,,"CODE1,CODE2" +3,Group,New Child Group 1,newchildgroup1,1.2.3.5,NULL,2,newgroup1,"CODE1" \ No newline at end of file diff --git a/tests/security/GroupCsvBulkLoaderTest.php b/tests/security/GroupCsvBulkLoaderTest.php new file mode 100644 index 000000000..6e03eb28f --- /dev/null +++ b/tests/security/GroupCsvBulkLoaderTest.php @@ -0,0 +1,54 @@ +load('sapphire/tests/security/GroupCsvBulkLoaderTest.csv'); + $created = $results->Created()->toArray(); + $this->assertEquals(count($created), 2); + $this->assertEquals($created[0]->Code, 'newgroup1'); + $this->assertEquals($created[0]->ParentID, 0); + $this->assertEquals($created[1]->Code, 'newchildgroup1'); + $this->assertEquals($created[1]->ParentID, $created[0]->ID); + } + + function testOverwriteExistingImport() { + $existinggroup = new Group(); + $existinggroup->Title = 'Old Group Title'; + $existinggroup->Code = 'newgroup1'; + $existinggroup->write(); + + $loader = new GroupCsvBulkLoader(); + $results = $loader->load('sapphire/tests/security/GroupCsvBulkLoaderTest.csv'); + + $created = $results->Created()->toArray(); + $this->assertEquals(count($created), 1); + $this->assertEquals($created[0]->Code, 'newchildgroup1'); + + $updated = $results->Updated()->toArray(); + $this->assertEquals(count($updated), 1); + $this->assertEquals($updated[0]->Code, 'newgroup1'); + $this->assertEquals($updated[0]->Title, 'New Group 1'); + } + + function testImportPermissions() { + $loader = new GroupCsvBulkLoader(); + $results = $loader->load('sapphire/tests/security/GroupCsvBulkLoaderTest_withExisting.csv'); + + $created = $results->Created()->toArray(); + $this->assertEquals(count($created), 1); + $this->assertEquals($created[0]->Code, 'newgroup1'); + $this->assertEquals($created[0]->Permissions()->column('Code'), array('CODE1')); + + $updated = $results->Updated()->toArray(); + $this->assertEquals(count($updated), 1); + $this->assertEquals($updated[0]->Code, 'existinggroup'); + $this->assertEquals($updated[0]->Permissions()->column('Code'), array('CODE1', 'CODE2')); + } + +} \ No newline at end of file diff --git a/tests/security/GroupCsvBulkLoaderTest.yml b/tests/security/GroupCsvBulkLoaderTest.yml new file mode 100644 index 000000000..30d849722 --- /dev/null +++ b/tests/security/GroupCsvBulkLoaderTest.yml @@ -0,0 +1,7 @@ +Permission: + permission1: + Code: CODE1 +Group: + existinggroup: + Code: existinggroup + Permissions: =>Permission.permission1 \ No newline at end of file diff --git a/tests/security/GroupCsvBulkLoaderTest_withExisting.csv b/tests/security/GroupCsvBulkLoaderTest_withExisting.csv new file mode 100644 index 000000000..1f4a13473 --- /dev/null +++ b/tests/security/GroupCsvBulkLoaderTest_withExisting.csv @@ -0,0 +1,3 @@ +ID,ClassName,Title,Code,IPRestrictions,HtmlEditorConfig,ParentID,ParentCode,PermissionCodes +2,Group,New Group 1,newgroup1,1.2.3.4,NULL,0,,"CODE1" +3,Group,Existing Group,existinggroup,1.2.3.5,NULL,2,,"CODE1,CODE2" \ No newline at end of file