Skip to content

Commit

Permalink
Merge pull request #1 from Jeremuelle/dev
Browse files Browse the repository at this point in the history
chore(Export) Move export feature to the module  + move some configs to be configured on a yml for ss sites
  • Loading branch information
nyeholt authored Jan 26, 2022
2 parents aad2eea + fb412ef commit aa0631d
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 33 deletions.
19 changes: 13 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# [Module Title]
# Data transfer

(Find + Replace the below badge links from "symbiote/silverstripe-gridfieldextensions" to your packagist name)

Expand All @@ -8,11 +8,10 @@
[![Total Downloads](https://poser.pugx.org/symbiote/silverstripe-datatransfer/downloads.svg)](https://packagist.org/packages/symbiote/silverstripe-datatransfer)
[![License](https://poser.pugx.org/symbiote/silverstripe-datatransfer/license.svg)](https://github.com/symbiote/silverstripe-datatransfer/blob/master/LICENSE.md)

[Short Description, 2-4 sentences]
Data transfer is a data management module for developers and content authors. It uses JSON format to import and export data to keep your data synchronised from production site to test site. With Data Transfer, you no longer need to redo rebuilding your pages and elemental blocks on your site.

![TODO_CHANGE_THIS](docs/images/main.png)

## Composer Install
## Installation

```
composer require symbiote/silverstripe-datatransfer:~1.0
Expand All @@ -21,10 +20,18 @@ composer require symbiote/silverstripe-datatransfer:~1.0
## Requirements

* SilverStripe 4+
* [Multi Value Field](https://github.com/symbiote/silverstripe-multivaluefield)] ^5

## Documentation
## Basic Usage

### Data Export
Head to data transfer > Data export tab, as image below suggests:

<p align="center">
<img width="588" height="424" src="/docs/en/assets/data-export.gif">
</p>

## Documentation
* [Quick Start](docs/en/quick-start.md)
* [Advanced Usage](docs/en/advanced-usage.md)
* [License](LICENSE.md)
* [Contributing](CONTRIBUTING.md)
8 changes: 4 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
}
],
"require": {
"silverstripe/framework": "^4.0"
"silverstripe/framework": "^4.0",
"symbiote/silverstripe-multivaluefield": "^5.1"
},
"require-dev": {
"squizlabs/php_codesniffer": "^3.0",
Expand All @@ -40,9 +41,8 @@
"branch-alias": {
"dev-master": "1.1.x-dev"
},
"expose": [
]
"expose": []
},
"prefer-stable": true,
"minimum-stability": "dev"
}
}
Binary file added docs/en/assets/data-export.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions docs/en/quick-start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## Quick Start

### How to use data export
* Create new export, set title
* Choose which type you want to export
* If there is a particular page you wanted to export, use Filter to specify export
* Tick 'Do export'
* Hit Save
* Copy the exported JSON to import to your test site.

### Limitations
*
48 changes: 29 additions & 19 deletions src/DataExport.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,24 @@ class DataExport extends DataObject
'ExportedData' => 'Text',
];

/**
* Max object can execute
* @var int
*/
private static $max_export = 100;

/**
* Increase the time limit of this script
* @var int seconds
*/
private static $execution_time_limit = 300;

/**
* Store object types
* @var string[]
*/
private static $config_cache = [];

/**
* The fields and relationships to export for a given type
*
Expand Down Expand Up @@ -87,10 +103,6 @@ class DataExport extends DataObject
]
];

private static $export_cache;

private static $config_cache = [];

/**
* Classes listed in here won't be affected by the `IncludeAllFields` flag.
* They will either need a configured list of fields to be exported, or will
Expand All @@ -109,23 +121,21 @@ class DataExport extends DataObject
public function getCMSFields()
{
$fields = parent::getCMSFields();
$fields->replaceField('Filter', KeyValueField::create('Filter'));

$types = ClassInfo::subclassesFor(DataObject::class);

// Making search by class name easier since `DropdownField` doesn't
// support partial matches
$types = array_map(function ($type) {
$segments = explode('\\', $type);

return $segments[count($segments) - 1] . " ({$type})";
}, $types);

asort($types);

$fields->replaceField('Filter', KeyValueField::create('Filter')->setDescription('Fields, i.e ID -> 1'));
$fields->replaceField('Type', DropdownField::create('Type', 'Data type', $types)->setEmptyString('Please select'));

$fields->dataFieldByName('IncludeRelations')->setRightTitle('Setting this false will exclude any related object being exported regardless of configuration');
$fields->dataFieldByName('IncludeAllFields')->setRightTitle('Setting this will overwrite configs and export the objects with all the properties. (Does not apply to protected classes.)');

$fields->dataFieldByName('IncludeRelations')->setDescription('Setting this false will exclude any related object being exported regardless of configuration');
$fields->dataFieldByName('IncludeAllFields')->setDescription('Setting this will overwrite configs and export the objects with all the properties. (Does not apply to protected classes.)');
$fields->dataFieldByName('ExportedData')->setReadonly(true);

return $fields;
Expand All @@ -137,7 +147,6 @@ public function onBeforeWrite()

if ($this->DoExport) {
$this->DoExport = false;

if ($this->Type) {
$this->ExportedData = $this->export();
}
Expand All @@ -146,7 +155,7 @@ public function onBeforeWrite()

public function export()
{
Environment::increaseTimeLimitTo(300);
Environment::increaseTimeLimitTo(self::config()->execution_time_limit);

$list = DataList::create($this->Type);
$filter = $this->Filter->getValues();
Expand All @@ -155,8 +164,6 @@ public function export()
}

$ex = [];
// $dependent = [];

if ($list->count() > self::config()->max_export) {
return json_encode(['error' => 'More than ' . self::config()->max_export . ' items found, please supply a filter'], JSON_PRETTY_PRINT);
}
Expand All @@ -168,7 +175,7 @@ public function export()
}
}

// reverse the order of creation so dependent items get created first
// Reverse the order of creation so dependent items get created first
$ex = array_reverse($ex);

return json_encode(['items' => $ex], JSON_PRETTY_PRINT);
Expand Down Expand Up @@ -223,7 +230,7 @@ public function exportObject(DataObject $item, &$dependent)
}

foreach ($props as $name) {
// check for multivalue fields explicitly
// Check for multivalue fields explicitly
$obj = $item->dbObject($name);
if ($obj instanceof MultiValueField) {
$v = $obj->getValues();
Expand All @@ -242,8 +249,9 @@ public function exportObject(DataObject $item, &$dependent)
if ($ones) {
$properties['one'] = [];
foreach ($ones as $name => $expand) {
// get the object
$object = $item->hasMethod($name) ? $item->$name() : null;
// If there is no object, let the export continue
if (!$object) break;
if ($object && $object->exists()) {
$properties['one'][$name] = array('id' => $this->makeContentId($object));
}
Expand All @@ -259,6 +267,7 @@ public function exportObject(DataObject $item, &$dependent)
$properties['many'] = [];
foreach ($many as $name => $expand) {
$rel = $item->hasMethod($name) ? $item->$name() : null;
if (!$rel) break;
foreach ($rel as $object) {
if ($object && $object->exists()) {
$properties['many'][$name][] = array('id' => $this->makeContentId($object));
Expand Down Expand Up @@ -299,14 +308,15 @@ protected function configForType($type)
if (isset(self::$config_cache[$type])) {
return self::$config_cache[$type];
}

$config = [];
foreach (self::config()->export_fields as $typeInfo => $data) {
if (is_a($type, $typeInfo, true)) {
$config = array_merge_recursive($config, $data);
}
}

// ensure classname is there, it's used for loading later!
// Ensure classname is there, it's used for loading later!
if (isset($config['id']) && !in_array('ClassName', $config['id'])) {
$config['id'][] = 'ClassName';
}
Expand Down
24 changes: 20 additions & 4 deletions src/SeedWebsiteTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,37 @@

class SeedWebsiteTask extends BuildTask
{
private static $segment = 'SeedWebsiteTask';

/**
* Array of glob strings for matching import locations
*
* @var string[]
*/
private static $import_paths = [];

private static $tester_pass = '';
private static $tester_email = '[email protected]';
/**
* Set test email to reset password
* @var string
*/
private static $tester_email = '';

private static $segment = 'SeedWebsiteTask';
/**
* Set new password
* @var string
*/
private static $tester_pass = '';

/**
* Don't run the task in production site, set production host
* @var string
*/
private static $production_host = '';

/**
* For Multisite hosts, set an array of strings
* @var string[]
*/
private static $host_aliases = [];

public function run($request)
Expand Down Expand Up @@ -91,7 +108,6 @@ public function run($request)
$object->write();
}


if ($object && !($object instanceof BaseElement)) {
if ($object->hasMethod('publishRecursive')) {
Debug::message("Publishing $object->Title", false);
Expand Down

0 comments on commit aa0631d

Please sign in to comment.