chg: [command] Generic importer improved and added support of value override
parent
35ba595a82
commit
fec6f817f6
|
@ -14,6 +14,7 @@ use Cake\Http\Client;
|
||||||
class ImporterCommand extends Command
|
class ImporterCommand extends Command
|
||||||
{
|
{
|
||||||
protected $modelClass = 'Organisations';
|
protected $modelClass = 'Organisations';
|
||||||
|
private $fieldsNoOverride = [];
|
||||||
|
|
||||||
protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser
|
protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser
|
||||||
{
|
{
|
||||||
|
@ -27,7 +28,7 @@ class ImporterCommand extends Command
|
||||||
'required' => true
|
'required' => true
|
||||||
]);
|
]);
|
||||||
$parser->addArgument('primary_key', [
|
$parser->addArgument('primary_key', [
|
||||||
'help' => 'To avoid duplicates, entries having the value specified by the primary key will be updated instead of inserted. Empty if only insertion should be done',
|
'help' => 'To avoid duplicates, entries having the value specified by the primary key will be updated instead of inserted. Leave empty if only insertion should be done',
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'default' => null,
|
'default' => null,
|
||||||
]);
|
]);
|
||||||
|
@ -43,23 +44,25 @@ class ImporterCommand extends Command
|
||||||
|
|
||||||
$table = $this->modelClass;
|
$table = $this->modelClass;
|
||||||
$this->loadModel($table);
|
$this->loadModel($table);
|
||||||
// $orgs = $this->{$table}->find()->enableHydration(false)->toList();
|
|
||||||
$config = $this->getConfigFromFile($configPath);
|
$config = $this->getConfigFromFile($configPath);
|
||||||
|
$this->processConfig($config);
|
||||||
$sourceData = $this->getDataFromSource($source);
|
$sourceData = $this->getDataFromSource($source);
|
||||||
// $sourceData = ['data' => [['name' => 'Test2', 'uuid' => '28de34ac-e284-495c-ae0e-9f46dd12da35', 'sector' => 'ss']]];
|
|
||||||
$data = $this->extractData($this->{$table}, $config, $sourceData);
|
$data = $this->extractData($this->{$table}, $config, $sourceData);
|
||||||
$entities = $this->marshalData($this->{$table}, $data, $primary_key);
|
$entities = $this->marshalData($this->{$table}, $data, $config, $primary_key);
|
||||||
|
|
||||||
$entitiesSample = array_slice($entities, 0, min(10, count($entities)));
|
$entitiesSample = array_slice($entities, 0, min(10, count($entities)));
|
||||||
$ioTable = $this->transformEntitiesIntoTable($entitiesSample);
|
$ioTable = $this->transformEntitiesIntoTable($entitiesSample);
|
||||||
$io->helper('Table')->output($ioTable);
|
$io->helper('Table')->output($ioTable);
|
||||||
|
|
||||||
$selection = $io->askChoice('A sample of the data you are about to save is provided above. Would you like to proceed?', ['Y', 'N'], 'N');
|
$selection = $io->askChoice('A sample of the data you are about to save is provided above. Would you like to proceed?', ['Y', 'N'], 'N');
|
||||||
if ($selection == 'Y') {
|
if ($selection == 'Y') {
|
||||||
$this->saveData($this->{$table}, $entities);
|
$this->saveData($this->{$table}, $entities);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function marshalData($table, $data, $primary_key=null)
|
private function marshalData($table, $data, $config, $primary_key=null)
|
||||||
{
|
{
|
||||||
|
$this->loadModel('MetaFields');
|
||||||
$entities = [];
|
$entities = [];
|
||||||
if (is_null($primary_key)) {
|
if (is_null($primary_key)) {
|
||||||
$entities = $table->newEntities($data);
|
$entities = $table->newEntities($data);
|
||||||
|
@ -68,10 +71,10 @@ class ImporterCommand extends Command
|
||||||
$query = $table->find('all')
|
$query = $table->find('all')
|
||||||
->where(["${primary_key}" => $item[$primary_key]]);
|
->where(["${primary_key}" => $item[$primary_key]]);
|
||||||
$entity = $query->first();
|
$entity = $query->first();
|
||||||
if ($entity) {
|
if (is_null($entity)) {
|
||||||
$entity->setAccess('uuid', false);
|
|
||||||
} else {
|
|
||||||
$entity = $table->newEmptyEntity();
|
$entity = $table->newEmptyEntity();
|
||||||
|
} else {
|
||||||
|
$this->lockAccess($config, $entity);
|
||||||
}
|
}
|
||||||
$entity = $table->patchEntity($entity, $item);
|
$entity = $table->patchEntity($entity, $item);
|
||||||
$entities[] = $entity;
|
$entities[] = $entity;
|
||||||
|
@ -82,6 +85,29 @@ class ImporterCommand extends Command
|
||||||
if ($entity->hasErrors()) {
|
if ($entity->hasErrors()) {
|
||||||
$hasErrors = true;
|
$hasErrors = true;
|
||||||
$this->io->error(json_encode(['entity' => $entity, 'errors' => $entity->getErrors()], JSON_PRETTY_PRINT));
|
$this->io->error(json_encode(['entity' => $entity, 'errors' => $entity->getErrors()], JSON_PRETTY_PRINT));
|
||||||
|
} else {
|
||||||
|
$metaFields = [];
|
||||||
|
foreach ($entity['metaFields'] as $fieldName => $fieldValue) {
|
||||||
|
$metaEntity = null;
|
||||||
|
if (!$entity->isNew()) {
|
||||||
|
$query = $this->MetaFields->find('all')->where([
|
||||||
|
'parent_id' => $entity->id,
|
||||||
|
'field' => $fieldName
|
||||||
|
]);
|
||||||
|
$metaEntity = $query->first();
|
||||||
|
}
|
||||||
|
if (is_null($metaEntity)) {
|
||||||
|
$metaEntity = $this->MetaFields->newEmptyEntity();
|
||||||
|
$metaEntity->field = $fieldName;
|
||||||
|
$metaEntity->scope = $table->metaFields;
|
||||||
|
$metaEntity->parent_id = $entity->id;
|
||||||
|
}
|
||||||
|
if ($this->canBeOverriden($config, $metaEntity)) {
|
||||||
|
$metaEntity->value = $fieldValue;
|
||||||
|
}
|
||||||
|
$metaFields[] = $metaEntity;
|
||||||
|
}
|
||||||
|
$entities[$i]->metaFields = $metaFields;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!$hasErrors) {
|
if (!$hasErrors) {
|
||||||
|
@ -99,31 +125,25 @@ class ImporterCommand extends Command
|
||||||
$this->io->error('Error while saving data');
|
$this->io->error('Error while saving data');
|
||||||
}
|
}
|
||||||
$this->io->verbose('Saving meta fields');
|
$this->io->verbose('Saving meta fields');
|
||||||
$errorWhileSaving = 0;
|
|
||||||
foreach ($entities as $i => $entity) {
|
foreach ($entities as $i => $entity) {
|
||||||
foreach ($entity['metaFields'] as $fieldName => $fieldValue) {
|
$this->saveMetaFields($entity);
|
||||||
$query = $this->MetaFields->find('all')->where([
|
}
|
||||||
'parent_id' => $entity->id,
|
}
|
||||||
'field' => $fieldName
|
|
||||||
]);
|
private function saveMetaFields($entity)
|
||||||
$metaEntity = $query->first();
|
{
|
||||||
if (is_null($metaEntity)) {
|
$errorWhileSaving = 0;
|
||||||
$metaEntity = $this->MetaFields->newEmptyEntity();
|
foreach ($entity->metaFields as $metaEntity) {
|
||||||
}
|
$metaEntity->parent_id = $entity->id;
|
||||||
$metaEntity->field = $fieldName;
|
$metaEntity = $this->MetaFields->save($metaEntity);
|
||||||
$metaEntity->value = $fieldValue;
|
if ($metaEntity === false) {
|
||||||
$metaEntity->scope = $table->metaFields;
|
$errorWhileSaving++;
|
||||||
$metaEntity->parent_id = $entity->id;
|
$this->io->verbose('Error while saving metafield: ' . PHP_EOL . json_encode($metaEntity, JSON_PRETTY_PRINT));
|
||||||
$metaEntity = $this->MetaFields->save($metaEntity);
|
|
||||||
if ($metaEntity === false) {
|
|
||||||
$errorWhileSaving++;
|
|
||||||
$this->io->verbose('Error while saving metafield: ' . PHP_EOL . json_encode($metaEntity, JSON_PRETTY_PRINT));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($errorWhileSaving) {
|
|
||||||
$this->io->error('Error while saving meta data: ' . (string) $errorWhileSaving);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ($errorWhileSaving) {
|
||||||
|
$this->io->error('Error while saving meta data: ' . (string) $errorWhileSaving);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function extractData($table, $config, $source)
|
private function extractData($table, $config, $source)
|
||||||
|
@ -151,6 +171,18 @@ class ImporterCommand extends Command
|
||||||
return $this->invertArray($data);
|
return $this->invertArray($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function lockAccess($config, &$entity)
|
||||||
|
{
|
||||||
|
foreach ($this->fieldsNoOverride as $fieldName) {
|
||||||
|
$entity->setAccess($fieldName, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function canBeOverriden($config, $metaEntity)
|
||||||
|
{
|
||||||
|
return !in_array($metaEntity->field, $this->fieldsNoOverride);
|
||||||
|
}
|
||||||
|
|
||||||
private function getDataFromSource($source)
|
private function getDataFromSource($source)
|
||||||
{
|
{
|
||||||
$data = $this->getDataFromFile($source);
|
$data = $this->getDataFromFile($source);
|
||||||
|
@ -218,6 +250,18 @@ class ImporterCommand extends Command
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function processConfig($config)
|
||||||
|
{
|
||||||
|
$this->fieldsNoOverride = [];
|
||||||
|
foreach ($config as $fieldName => $fieldConfig) {
|
||||||
|
if (is_array($fieldConfig)) {
|
||||||
|
if (isset($fieldConfig['override']) && $fieldConfig['override'] === false) {
|
||||||
|
$this->fieldsNoOverride[] = $fieldName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function transformResultSetsIntoTable($result, $header=[])
|
private function transformResultSetsIntoTable($result, $header=[])
|
||||||
{
|
{
|
||||||
$table = [[]];
|
$table = [[]];
|
||||||
|
@ -248,8 +292,8 @@ class ImporterCommand extends Command
|
||||||
$tableHeader = array_filter($tableHeader, function($name) {
|
$tableHeader = array_filter($tableHeader, function($name) {
|
||||||
return !in_array('metaFields', explode('.', $name));
|
return !in_array('metaFields', explode('.', $name));
|
||||||
});
|
});
|
||||||
foreach ($entities[0]['metaFields'] as $metaField => $metaValue) {
|
foreach ($entities[0]->metaFields as $metaField) {
|
||||||
$tableHeader[] = "metaFields.$metaField";
|
$tableHeader[] = "metaFields.$metaField->field";
|
||||||
}
|
}
|
||||||
$tableContent = [];
|
$tableContent = [];
|
||||||
foreach ($entities as $entity) {
|
foreach ($entities as $entity) {
|
||||||
|
@ -257,7 +301,17 @@ class ImporterCommand extends Command
|
||||||
foreach ($tableHeader as $key) {
|
foreach ($tableHeader as $key) {
|
||||||
$subKeys = explode('.', $key);
|
$subKeys = explode('.', $key);
|
||||||
if (in_array('metaFields', $subKeys)) {
|
if (in_array('metaFields', $subKeys)) {
|
||||||
$row[] = (string) $entity['metaFields'][$subKeys[1]];
|
$found = false;
|
||||||
|
foreach ($entity->metaFields as $metaField) {
|
||||||
|
if ($metaField->field == $subKeys[1]) {
|
||||||
|
$row[] = (string) $metaField->value;
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$found) {
|
||||||
|
$row[] = '';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$row[] = (string) $entity[$key];
|
$row[] = (string) $entity[$key];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue