Skip to content

Commit

Permalink
Merge pull request #12 from bristol-su/develop
Browse files Browse the repository at this point in the history
v1.3.0
  • Loading branch information
tobytwigger committed Apr 8, 2020
2 parents 18e39da + 18e90af commit 3487816
Show file tree
Hide file tree
Showing 35 changed files with 2,300 additions and 4 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.3.0] - (08/04/2020)

### Added
- Create the exporter framework for exporting control information

## [1.2.4] - (03/04/2020)

### Changed
Expand Down Expand Up @@ -77,7 +82,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- model/repository contracts


[Unreleased]: https://github.com/bristol-su/control/compare/v1.2.4...HEAD
[Unreleased]: https://github.com/bristol-su/control/compare/v1.3.0...HEAD
[1.3.0]: https://github.com/bristol-su/control/compare/v1.2.4...v1.3.0
[1.2.4]: https://github.com/bristol-su/control/compare/v1.2.3...v1.2.4
[1.2.3]: https://github.com/bristol-su/control/compare/v1.2.2...v1.2.3
[1.2.2]: https://github.com/bristol-su/control/compare/v1.2.1...v1.2.2
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
"php": "^7.2",
"ext-json": "*"
},
"require-dev" : {
"require-dev": {
"orchestra/testbench": "^4.0",
"phpstan/phpstan": "^0.12.8"
"phpstan/phpstan": "^0.12.8"
},
"extra": {
"laravel": {
Expand Down
55 changes: 55 additions & 0 deletions config/control.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,60 @@
'api_prefix' => env('CONTROL_API_PREFIX', '/api/control'),
'api_middleware' => [
'api'
],

'export' => [

/*
|--------------------------------------------------------------------------
| Default Export Method
|--------------------------------------------------------------------------
|
| This option defines the default export method for exporting control data.
| The name specified in this option should match one of the configuration options
| listed below.
|
*/
'default' => 'contact-details',

/*
|--------------------------------------------------------------------------
| Log Channels
|--------------------------------------------------------------------------
|
| Here you may configure the export drivers for control. Each option must
| reference a driver to use, and may additionally register any formatters
| or configuration for that driver.
|
| Available Drivers:
| - save-csv Save a csv to a given disk system
| - dump Dump the results using the symfony dumper
|
*/
'local-roles' => [
'driver' => 'save-csv',
'formatters' => [
\BristolSU\ControlDB\Export\Formatter\Role\SimpleRoleFormatter::class => [],
\BristolSU\ControlDB\Export\Formatter\Role\AddGroupInformationToRoles::class => [],
\BristolSU\ControlDB\Export\Formatter\Role\AddPositionInformationToRoles::class => []
],
'disk' => 'local',
'filename' => 'export.csv',
],

'contact-details' => [
'driver' => 'save-csv',
'formatters' => [
\BristolSU\ControlDB\Export\Formatter\Role\SimpleRoleFormatter::class => [],
\BristolSU\ControlDB\Export\Formatter\Role\AddGroupInformationToRoles::class => [],
\BristolSU\ControlDB\Export\Formatter\Role\AddPositionInformationToRoles::class => [],
\BristolSU\ControlDB\Export\Formatter\Role\AddRoleHoldersAsNewItems::class => [],
\BristolSU\ControlDB\Export\Formatter\Shared\SortByColumn::class => [
'column' => 'Group Name'
]
],
'disk' => 'local',
'filename' => 'contact_details.csv',
]
]
];
9 changes: 8 additions & 1 deletion src/ControlDBServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
use BristolSU\ControlDB\Contracts\Repositories\Pivots\Tags\PositionPositionTag as PositionPositionTagContract;
use BristolSU\ControlDB\Contracts\Repositories\Pivots\UserGroup as UserGroupContract;
use BristolSU\ControlDB\Contracts\Repositories\Pivots\UserRole as UserRoleContract;
use BristolSU\ControlDB\Export\ExportControlCommand;
use BristolSU\ControlDB\Export\ExportManager;
use BristolSU\ControlDB\Models\DataUser;
use BristolSU\ControlDB\Models\DataGroup;
use BristolSU\ControlDB\Models\DataRole;
Expand Down Expand Up @@ -99,6 +101,10 @@ public function register()
$this->registerMigrations();
$this->registerConfig();
$this->registerFactories();

$this->app->singleton('control-exporter', function() {
return new ExportManager($this->app);
});
}

public function boot()
Expand Down Expand Up @@ -197,7 +203,8 @@ public function bindContracts()
public function registerCommands()
{
$this->commands([
SeedDatabase::class
SeedDatabase::class,
ExportControlCommand::class
]);
}

Expand Down
73 changes: 73 additions & 0 deletions src/Export/ExportControlCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

namespace BristolSU\ControlDB\Export;

use BristolSU\ControlDB\Contracts\Repositories\Group;
use BristolSU\ControlDB\Contracts\Repositories\Position;
use BristolSU\ControlDB\Contracts\Repositories\Role;
use BristolSU\ControlDB\Contracts\Repositories\User;
use BristolSU\ControlDB\Export\Formatter\Role\SortByGroupName;
use BristolSU\ControlDB\Export\Formatter\Shared\SortByColumn;
use Illuminate\Console\Command;
use Symfony\Component\Console\Exception\InvalidArgumentException;

/**
* Seed the database
*/
class ExportControlCommand extends Command
{
/**
* Signature for the command
*
* @var string
*/
protected $signature = 'control:export
{type : The type of resource to export}
{--exporter= : The name of the exporter to use}';

/**
* Name for the commmand
*
* @var string
*/
protected $name = 'Export Control';

/**
* Description of the command
*
* @var string
*/
protected $description = 'Export control to an external service';

/**
* Handle the command execution
*
* Seed the database with fake data.
*/
public function handle()
{
Exporter::driver($this->option('exporter'))->export($this->exportData());
$this->info('Export complete');
}

private function exportData()
{
switch($this->argument('type')) {
case 'user':
return app(User::class)->all();
break;
case 'group':
return app(Group::class)->all();
break;
case 'role':
return app(Role::class)->all();
break;
case 'position':
return app(Position::class)->all();
break;
default:
throw new InvalidArgumentException(sprintf('The type option %s is not allowed.', $this->argument('type')));
break;
}
}
}
173 changes: 173 additions & 0 deletions src/Export/ExportManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<?php

namespace BristolSU\ControlDB\Export;

use BristolSU\ControlDB\Export\Handler\DumpHandler;
use BristolSU\ControlDB\Export\Handler\Handler;
use BristolSU\ControlDB\Export\Handler\SaveCsvHandler;
use Closure;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Str;
use InvalidArgumentException;

class ExportManager
{

/**
* The container instance.
*
* @var Container
*/
protected $container;

/**
* The registered custom driver creators.
*
* @var array
*/
protected $customCreators = [];

protected $formatters = [];

/**
* Create a new Export manager instance.
*
* @param Container $container
* @return void
*/
public function __construct(Container $container)
{
$this->container = $container;
}

/**
* Get a export driver instance.
*
* @param string|null $driver
* @return mixed
*/
public function driver($driver = null)
{
return $this->resolve($driver ?? $this->getDefaultDriver());
}

/**
* Resolve the given export instance by name.
*
* @param string $name
* @return Handler
*
* @throws \InvalidArgumentException
*/
protected function resolve($name)
{
$config = $this->configurationFor($name);

if (is_null($config)) {
throw new InvalidArgumentException("Exporter [{$name}] is not defined.");
}
if (isset($this->customCreators[$config['driver']])) {
return $this->callCustomCreator($config);
}

$driverMethod = 'create'.Str::studly($config['driver']).'Driver';

if (method_exists($this, $driverMethod)) {
return $this->{$driverMethod}($config);
}

throw new InvalidArgumentException("Driver [{$config['driver']}] is not supported.");
}

/**
* Call a custom driver creator.
*
* @param array $config
* @return mixed
*/
protected function callCustomCreator(array $config)
{
return $this->customCreators[$config['driver']]($this->container, $config);
}

/**
* Get the export connection configuration.
*
* @param string $name
* @return array
*/
protected function configurationFor($name)
{
$config = $this->container['config']["control.export.{$name}"];
if(is_null($config)) {
return null;
}
if(!isset($config['formatters'])) {
$config['formatters'] = [];
}
foreach($this->formatters() as $formatter => $formatterConfig) {
$config['formatters'][$formatter] = $formatterConfig;
}

return $config;
}

/**
* Get the default export driver name.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->container['config']['control.export.default'];
}

/**
* Register a custom driver creator Closure.
*
* @param string $driver
* @param \Closure $callback
* @return $this
*/
public function extend($driver, Closure $callback)
{
$this->customCreators[$driver] = $callback->bindTo($this, $this);

return $this;
}

public function withFormatter(string $formatter, array $config = [])
{
$this->formatters[$formatter] = $config;

return $this;
}

/**
* Dynamically call the default driver instance.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
return $this->driver()->$method(...$parameters);
}

public function createDumpDriver(array $config)
{
return new DumpHandler($config);
}

public function createSaveCsvDriver(array $config)
{
return new SaveCsvHandler($config);
}

protected function formatters()
{
return $this->formatters;
}

}
Loading

0 comments on commit 3487816

Please sign in to comment.