0) {
- $bytes = 0;
- $chunk_size = 1024;
- $json = '';
- while($s = fgets($stdin, $chunk_size)) {
- $bytes += $chunk_size;
- if($bytes > constant('UPLOAD_MAX_FILE_SIZE')) {
- throw new Exception('max_size_exceeded', QN_ERROR_INVALID_PARAM);
- }
- $json .= $s;
- }
+ $model = $orm->getModel($entity);
+ if(!$model) {
+ throw new Exception('unknown_entity', QN_ERROR_INVALID_PARAM);
}
-}
-$data = [];
+ return [$entity, $model->getSchema()];
+};
-if(strlen($json)) {
- $data = json_decode($json, true, 512, JSON_BIGINT_AS_STRING);
- if(is_null($data)) {
- throw new Exception('invalid json: '.json_last_error_msg(), QN_ERROR_INVALID_PARAM);
+$extractData = function(array $params) {
+ if(isset($params['entity'])) {
+ $data = $params['data'];
+ }
+ else {
+ $data = $params['data']['data'] ?? null;
}
-}
-
-if(empty($data)) {
- throw new Exception('missing_data', QN_ERROR_INVALID_PARAM);
-}
-/** @var \equal\data\adapt\DataAdapter */
-$adapter = $dap->get('json');
+ if(is_null($data)) {
+ throw new Exception('missing_data', EQ_ERROR_INVALID_PARAM);
+ }
-foreach($data as $class) {
+ return $data;
+};
- if(!isset($class['name']) || !isset($class['data'])) {
- throw new Exception('invalid_schema', QN_ERROR_INVALID_PARAM);
+$extractLang = function($params) {
+ if(isset($params['entity'])) {
+ return $params['lang'] ?? constant('DEFAULT_LANG');
}
- $entity = $class['name'];
- $lang = $class['lang'];
- $model = $orm->getModel($entity);
- $schema = $model->getSchema();
+ return $params['data']['lang'] ?? constant('DEFAULT_LANG');
+};
- $objects_ids = [];
+/**
+ * Action
+ */
- foreach($class['data'] as $odata) {
- foreach($odata as $field => $value) {
- /** @var equal\orm\Field */
- $f = $model->getField($field);
- $odata[$field] = $adapter->adaptIn($value, $f->getUsage());
- }
- if(isset($odata['id'])) {
- $res = $orm->search($entity, ['id', '=', $odata['id']]);
- if($res > 0 && count($res)) {
- // object already exist, but either values or language differs
- $id = $odata['id'];
- $res = $orm->update($entity, $id, $odata, $lang);
- $objects_ids[] = $id;
- }
- else {
- $objects_ids[] = $orm->create($entity, $odata, $lang);
- }
- }
- else {
- $objects_ids[] = $orm->create($entity, $odata, $lang);
+[$entity, $schema] = $extractEntityAndSchema($params);
+$data = $extractData($params);
+$lang = $extractLang($params);
+
+$object_ids = [];
+foreach($data as $entity_data) {
+ foreach($entity_data as $field => $value) {
+ if(!isset($schema[$field])) {
+ $reporter->warning("ORM::unknown field $field for entity $entity in given data.");
+ continue;
}
+ $f = new Field($schema[$field]);
+ $entity_data[$field] = $adapter->adaptIn($value, $f->getUsage());
}
- // force a first generation of computed fields, if any
- $computed_fields = [];
- foreach($schema as $field => $def) {
- if($def['type'] == 'computed') {
- $computed_fields[] = $field;
+ if(isset($entity_data['id'])) {
+ $ids = $orm->search($entity, ['id', '=', $entity_data['id']]);
+ if($ids < 0 || !count($ids)) {
+ $orm->create($entity, ['id' => $entity_data['id']], $lang, false);
}
+
+ $id = $entity_data['id'];
+ unset($entity_data['id']);
+ }
+ else {
+ $id = $orm->create($entity, [], $lang);
}
- $orm->read($entity, $objects_ids, $computed_fields, $lang);
+
+ $orm->update($entity, $id, $entity_data, $lang);
+
+ $object_ids[] = $id;
+}
+
+$computed_fields = [];
+foreach($schema as $field => $def) {
+ if($def['type'] === 'computed') {
+ $computed_fields[] = $field;
+ }
+}
+
+if(!empty($computed_fields)) {
+ $orm->read($entity, $object_ids, $computed_fields, $lang);
}
+
+$result = array_map(
+ function($id) {
+ return ['id' => $id];
+ },
+ $object_ids
+);
+
+$context->httpResponse()
+ ->body($result)
+ ->status(200)
+ ->send();
diff --git a/packages/core/apps/app/version b/packages/core/apps/app/version
index 5c2ec90ca..0560e438d 100644
--- a/packages/core/apps/app/version
+++ b/packages/core/apps/app/version
@@ -1 +1 @@
-4c2eb0b70677e149774fd5e3008f1edf
+1e04a408428f762c33e905e7ac4ea188
diff --git a/packages/core/apps/app/web.app b/packages/core/apps/app/web.app
index 8586fa331..2f3e76f03 100644
Binary files a/packages/core/apps/app/web.app and b/packages/core/apps/app/web.app differ
diff --git a/packages/core/classes/Mail.class.php b/packages/core/classes/Mail.class.php
index 21c57d8ee..1032d0af5 100644
--- a/packages/core/classes/Mail.class.php
+++ b/packages/core/classes/Mail.class.php
@@ -154,12 +154,14 @@ public static function send(Email $email, string $object_class = '', int $object
if($mailer->send($envelope) == 0) {
throw new \Exception('failed_sending_email', EQ_ERROR_UNKNOWN);
}
+ trigger_error("PHP::Mail::send() successfully sent email message {$mail['id']}", EQ_REPORT_INFO);
// update the core\Mail object status
self::id($mail['id'])->update(['status' => 'sent', 'response_status' => 250]);
}
catch(\Exception $e) {
+ trigger_error("PHP::Mail::send() failed: ".$e->getMessage(), EQ_REPORT_ERROR);
self::id($mail['id'])->update(['status' => 'failing', 'response_status' => 500, 'response' => $e->getMessage()]);
- throw new \Exception($e->getMessage(), $e->getCode());
+ throw new \Exception($e->getMessage(), EQ_ERROR_UNKNOWN);
}
return $mail['id'];
@@ -237,6 +239,8 @@ public static function flush() {
throw new \Exception('failed_sending_email', EQ_ERROR_UNKNOWN);
}
+ trigger_error("APP::Mail::send() successfully sent email message {$message['id']}", EQ_REPORT_INFO);
+
// upon successful sending, remove the mail from the outbox
$filename = self::MESSAGE_FOLDER.'/'.$file;
unlink($filename);
@@ -252,6 +256,7 @@ public static function flush() {
}
catch(\Exception $e) {
// sending failed
+ trigger_error("APP::Mail::flush() failed: ".$e->getMessage(), EQ_REPORT_ERROR);
// if the message is linked to a core\Mail object, update the latter's status
if(isset($message['id'])) {
self::id($message['id'])->update(['status' => 'failing', 'response_status' => 500, 'response' => $e->getMessage()]);
@@ -411,7 +416,7 @@ function ($matches) use (&$envelope) {
}
}
catch(\Exception $e) {
- trigger_error("ORM::createEnvelope: ".$e->getMessage(), QN_REPORT_ERROR);
+ trigger_error("ORM::createEnvelope: ".$e->getMessage(), EQ_REPORT_ERROR);
}
return $envelope;
diff --git a/packages/core/classes/User.class.php b/packages/core/classes/User.class.php
index 4cc235f3e..fff04181c 100644
--- a/packages/core/classes/User.class.php
+++ b/packages/core/classes/User.class.php
@@ -39,13 +39,13 @@ public static function getColumns() {
'usage' => 'email',
'required' => true,
'unique' => true,
- 'dependencies' => ['name']
+ 'dependents' => ['name']
],
'username' => [
'type' => 'string',
'unique' => true,
- 'dependencies' => ['name']
+ 'dependents' => ['name']
],
'password' => [
@@ -62,18 +62,20 @@ public static function getColumns() {
'firstname' => [
'type' => 'string',
- 'dependencies' => ['fullname', 'name']
+ 'dependents' => ['fullname', 'name']
],
'lastname' => [
'type' => 'string',
- 'dependencies' => ['fullname', 'name']
+ 'dependents' => ['fullname', 'name'],
+ 'sensitive' => true
],
'fullname' => [
'type' => 'computed',
'result_type' => 'string',
- 'function' => 'calcFullname'
+ 'function' => 'calcFullname',
+ 'sensitive' => true
],
// #todo - add a distinct field for 'locale'
diff --git a/packages/core/classes/import/ColumnMapping.class.php b/packages/core/classes/import/ColumnMapping.class.php
new file mode 100644
index 000000000..bd40c7693
--- /dev/null
+++ b/packages/core/classes/import/ColumnMapping.class.php
@@ -0,0 +1,94 @@
+
+ Some Rights Reserved, Cedric Francoys, 2010-2021
+ Licensed under GNU GPL 3 license
+*/
+namespace core\import;
+
+use equal\orm\Model;
+
+class ColumnMapping extends Model {
+
+ public static function getDescription(): string {
+ return 'Mapping configuration that allows to import a specific column of an entity.';
+ }
+
+ public static function getColumns(): array {
+ return [
+
+ 'entity_mapping_id' => [
+ 'type' => 'many2one',
+ 'foreign_object' => 'core\import\EntityMapping',
+ 'description' => 'The parent EntityMapping this ColumnMapping is part of.',
+ 'required' => true
+ ],
+
+ 'mapping_type' => [
+ 'type' => 'computed',
+ 'result_type' => 'string',
+ 'description' => 'Is the column data mapped by index or by name.',
+ 'store' => true,
+ 'instant' => true,
+ 'function' => 'calcMappingType'
+ ],
+
+ 'origin_name' => [
+ 'type' => 'string',
+ 'description' => 'Name of the column where the data is to be found.',
+ 'visible' => ['mapping_type', '=', 'name']
+ ],
+
+ 'origin_index' => [
+ 'type' => 'integer',
+ 'usage' => 'number/integer{0,255}',
+ 'description' => 'Index of the column where the data is to be found.',
+ 'visible' => ['mapping_type', '=', 'index']
+ ],
+
+ 'origin' => [
+ 'type' => 'computed',
+ 'result_type' => 'string',
+ 'description' => 'Index or name of the column where the data is to be found.',
+ 'store' => false,
+ 'function' => 'calcOrigin'
+ ],
+
+ 'target_name' => [
+ 'type' => 'string',
+ 'description' => 'Name of the target entity\'s column.',
+ 'required' => true
+ ],
+
+ 'data_transformers_ids' => [
+ 'type' => 'one2many',
+ 'foreign_object' => 'core\import\DataTransformer',
+ 'foreign_field' => 'column_mapping_id',
+ 'description' => 'Mapping configurations defining how to import data to eQual entity.'
+ ]
+
+ ];
+ }
+
+ public static function calcMappingType($self): array {
+ $result = [];
+ $self->read(['entity_mapping_id' => ['mapping_type']]);
+
+ foreach($self as $id => $column_mapping) {
+ $result[$id] = $column_mapping['entity_mapping_id']['mapping_type'];
+ }
+
+ return $result;
+ }
+
+ public static function calcOrigin($self): array {
+ $result = [];
+ $self->read(['mapping_type', 'origin_name', 'origin_index']);
+
+ foreach($self as $id => $column_mapping) {
+ $result[$id] = $column_mapping['mapping_type'] === 'index' ? $column_mapping['origin_index'] : $column_mapping['origin_name'];
+ }
+
+ return $result;
+ }
+}
diff --git a/packages/core/classes/import/DataTransformer.class.php b/packages/core/classes/import/DataTransformer.class.php
new file mode 100644
index 000000000..f7ce0452e
--- /dev/null
+++ b/packages/core/classes/import/DataTransformer.class.php
@@ -0,0 +1,140 @@
+
+ Some Rights Reserved, Cedric Francoys, 2010-2021
+ Licensed under GNU GPL 3 license
+*/
+namespace core\import;
+
+use equal\orm\Model;
+
+class DataTransformer extends Model {
+
+ public static function getDescription(): string {
+ return 'Transform step to adapt external data to eQual entity.';
+ }
+
+ public static function getColumns(): array {
+ return [
+
+ 'column_mapping_id' => [
+ 'type' => 'many2one',
+ 'foreign_object' => 'core\import\ColumnMapping',
+ 'description' => 'The parent ColumnMapping this DataTransformer is part of.',
+ 'required' => true
+ ],
+
+ 'transformer_type' => [
+ 'type' => 'string',
+ 'selection' => [
+ 'value' => 'Value',
+ 'cast' => 'Cast',
+ 'round' => 'Round',
+ 'multiply' => 'Multiply',
+ 'divide' => 'Divide',
+ 'field-contains' => 'Field contains',
+ 'field-does-not-contain' => 'Field does not contain',
+ 'map-value' => 'Map value'
+ ],
+ 'description' => 'The type of transform operation to be applied on a column data to import.',
+ 'default' => 'value'
+ ],
+
+ 'order' => [
+ 'type' => 'integer',
+ 'description' => 'For sorting the moments within a day.',
+ 'default' => 1
+ ],
+
+ 'value' => [
+ 'type' => 'string',
+ 'description' => 'A static value to set',
+ 'visible' => ['transformer_type', '=', 'value']
+ ],
+
+ 'cast_to' => [
+ 'type' => 'string',
+ 'selection' => [
+ 'string' => 'String',
+ 'integer' => 'Integer',
+ 'float' => 'Float',
+ 'boolean' => 'Boolean'
+ ],
+ 'visible' => ['transformer_type', '=', 'cast']
+ ],
+
+ 'transform_by' => [
+ 'type' => 'integer',
+ 'description' => 'Value to multiply or divide by.',
+ 'visible' => ['transformer_type', 'in', ['multiply', 'divide']]
+ ],
+
+ 'field_contains_value' => [
+ 'type' => 'string',
+ 'description' => 'Value that must be found or not.',
+ 'visible' => ['transformer_type', 'in', ['field-contains', 'field-does-not-contain']]
+ ],
+
+ 'map_values_ids' => [
+ 'type' => 'one2many',
+ 'foreign_object' => 'core\import\DataTransformerMapValue',
+ 'foreign_field' => 'data_transformer_id',
+ 'description' => 'List a map values to replace a value by another.',
+ 'visible' => ['transformer_type', '=', 'map-value']
+ ]
+
+ ];
+ }
+
+ public static function transformValue(array $data_transformer, $value) {
+ switch($data_transformer['transformer_type']) {
+ case 'value':
+ $value = $data_transformer['value'];
+ break;
+ case 'cast':
+ switch($data_transformer['cast_to']) {
+ case 'string':
+ $value = (string) $value;
+ break;
+ case 'integer':
+ $value = (int) $value;
+ break;
+ case 'float':
+ $value = (float) $value;
+ break;
+ case 'boolean':
+ $value = (boolean) $value;
+ break;
+ }
+ break;
+ case 'round':
+ $value = round($value);
+ break;
+ case 'multiply':
+ $value = $value * $data_transformer['transform_by'];
+ break;
+ case 'divide':
+ $value = $value / $data_transformer['transform_by'];
+ break;
+ case 'field-contains':
+ $value = strpos($value, $data_transformer['field_contains_value']) !== false;
+ break;
+ case 'field-does-not-contain':
+ $value = strpos($value, $data_transformer['field_contains_value']) === false;
+ break;
+ case 'map-value':
+ foreach($data_transformer['map_values_ids'] as $map_value) {
+ if($map_value['old_value'] != $value) {
+ continue;
+ }
+
+ $value = $map_value['new_value'];
+ break;
+ }
+
+ break;
+ }
+
+ return $value;
+ }
+}
diff --git a/packages/core/classes/import/DataTransformerMapValue.class.php b/packages/core/classes/import/DataTransformerMapValue.class.php
new file mode 100644
index 000000000..05c598f86
--- /dev/null
+++ b/packages/core/classes/import/DataTransformerMapValue.class.php
@@ -0,0 +1,41 @@
+
+ Some Rights Reserved, Cedric Francoys, 2010-2021
+ Licensed under GNU GPL 3 license
+*/
+namespace core\import;
+
+use equal\orm\Model;
+
+class DataTransformerMapValue extends Model {
+
+ public static function getDescription(): string {
+ return 'Transform step to adapt external data to eQual entity.';
+ }
+
+ public static function getColumns(): array {
+ return [
+
+ 'data_transformer_id' => [
+ 'type' => 'many2one',
+ 'foreign_object' => 'core\import\DataTransformer',
+ 'description' => 'The data transformer this map value is part of.',
+ 'required' => true
+ ],
+
+ 'old_value' => [
+ 'type' => 'string',
+ 'description' => 'Old value that needs to be replaced.',
+ 'required' => true
+ ],
+
+ 'new_value' => [
+ 'type' => 'string',
+ 'description' => 'New value that needs to be replace the old value.',
+ 'required' => true
+ ]
+
+ ];
+ }
+}
diff --git a/packages/core/classes/import/EntityMapping.class.php b/packages/core/classes/import/EntityMapping.class.php
new file mode 100644
index 000000000..56d8d76ce
--- /dev/null
+++ b/packages/core/classes/import/EntityMapping.class.php
@@ -0,0 +1,52 @@
+
+ Some Rights Reserved, Cedric Francoys, 2010-2021
+ Licensed under GNU GPL 3 license
+*/
+namespace core\import;
+
+use equal\orm\Model;
+
+class EntityMapping extends Model {
+
+ public static function getDescription(): string {
+ return 'Mapping configuration that allows to import a specific entity.';
+ }
+
+ public static function getColumns(): array {
+ return [
+
+ 'name' => [
+ 'type' => 'string',
+ 'description' => 'Import configuration mapping\'s name.',
+ 'required' => true
+ ],
+
+ 'entity' => [
+ 'type' => 'string',
+ 'description' => 'Namespace of the concerned entity.',
+ 'required' => true
+ ],
+
+ 'mapping_type' => [
+ 'type' => 'string',
+ 'selection' => [
+ 'index' => 'Index',
+ 'name' => 'Name'
+ ],
+ 'description' => 'Are the columns data mapped by index or by name.',
+ 'default' => 'index',
+ 'dependents' => ['column_mappings_ids' => ['mapping_type']]
+ ],
+
+ 'column_mappings_ids' => [
+ 'type' => 'one2many',
+ 'foreign_object' => 'core\import\ColumnMapping',
+ 'foreign_field' => 'entity_mapping_id',
+ 'description' => 'Mapping configurations defining how to import data to eQual entity.'
+ ]
+
+ ];
+ }
+}
diff --git a/packages/core/tests/adapters.php b/packages/core/tests/adapters.php
index 3b084213e..6ccc8c11b 100644
--- a/packages/core/tests/adapters.php
+++ b/packages/core/tests/adapters.php
@@ -472,7 +472,7 @@
return $result;
},
'assert' => function($result) {
- return ($result === '10:00');
+ return ($result === '10:00:00');
}
],
'4108' => [
diff --git a/packages/core/views/import/ColumnMapping.form.default.json b/packages/core/views/import/ColumnMapping.form.default.json
new file mode 100644
index 000000000..31d987af0
--- /dev/null
+++ b/packages/core/views/import/ColumnMapping.form.default.json
@@ -0,0 +1,88 @@
+{
+ "name": "Column Mapping",
+ "description": "Default form for Column Mapping.",
+ "layout": {
+ "groups": [
+ {
+ "sections": [
+ {
+ "rows": [
+ {
+ "columns": [
+ {
+ "width": "100%",
+ "items": [
+ {
+ "type": "field",
+ "value": "entity_mapping_id",
+ "width": "25%"
+ },
+ {
+ "type": "field",
+ "value": "mapping_type",
+ "visible": false
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "columns": [
+ {
+ "width": "100%",
+ "items": [
+ {
+ "type": "field",
+ "value": "origin_name",
+ "width": "25%"
+ },
+ {
+ "type": "field",
+ "value": "origin_index",
+ "width": "25%"
+ },
+ {
+ "type": "field",
+ "value": "",
+ "width": "25%"
+ },
+ {
+ "type": "field",
+ "value": "target_name",
+ "width": "25%"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "sections": [
+ {
+ "id": "section.data-transformers",
+ "label": "Data transformers",
+ "rows": [
+ {
+ "columns": [
+ {
+ "width": "100%",
+ "items": [
+ {
+ "type": "field",
+ "value": "data_transformers_ids",
+ "width": "100%"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/packages/core/views/import/ColumnMapping.list.default.json b/packages/core/views/import/ColumnMapping.list.default.json
new file mode 100644
index 000000000..9c4f4f2cf
--- /dev/null
+++ b/packages/core/views/import/ColumnMapping.list.default.json
@@ -0,0 +1,39 @@
+{
+ "name": "Column Mappings",
+ "description": "Listing view for Column Mapping items.",
+ "layout": {
+ "items": [
+ {
+ "type": "field",
+ "value": "id",
+ "width": "10%",
+ "sortable": true,
+ "readonly": true
+ },
+ {
+ "type": "field",
+ "value": "entity_mapping_id",
+ "width": "20%",
+ "sortable": true
+ },
+ {
+ "type": "field",
+ "value": "mapping_type",
+ "width": "20%",
+ "sortable": true
+ },
+ {
+ "type": "field",
+ "value": "origin",
+ "width": "20%",
+ "sortable": true
+ },
+ {
+ "type": "field",
+ "value": "target_name",
+ "width": "20%",
+ "sortable": true
+ }
+ ]
+ }
+}
diff --git a/packages/core/views/import/DataTransformer.form.default.json b/packages/core/views/import/DataTransformer.form.default.json
new file mode 100644
index 000000000..2f81ea03e
--- /dev/null
+++ b/packages/core/views/import/DataTransformer.form.default.json
@@ -0,0 +1,99 @@
+{
+ "name": "Data Transformer",
+ "description": "Default form for Data Transformer.",
+ "layout": {
+ "groups": [
+ {
+ "sections": [
+ {
+ "rows": [
+ {
+ "columns": [
+ {
+ "width": "100%",
+ "items": [
+ {
+ "type": "field",
+ "value": "column_mapping_id",
+ "width": "25%"
+ },
+ {
+ "type": "field",
+ "value": "transformer_type",
+ "width": "25%"
+ },
+ {
+ "type": "field",
+ "value": "",
+ "width": "25%"
+ },
+ {
+ "type": "field",
+ "value": "order",
+ "width": "25%"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "columns": [
+ {
+ "width": "100%",
+ "items": [
+ {
+ "type": "field",
+ "value": "value",
+ "width": "25%"
+ },
+ {
+ "type": "field",
+ "value": "cast_to",
+ "width": "25%"
+ },
+ {
+ "type": "field",
+ "value": "transform_by",
+ "width": "25%"
+ },
+ {
+ "type": "field",
+ "value": "field_contains_value",
+ "width": "25%"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "visible": ["transformer_type", "=", "map-value"],
+ "sections": [
+ {
+ "id": "section.map-values",
+ "label": "Map values",
+ "rows": [
+ {
+ "columns": [
+ {
+ "width": "100%",
+ "items": [
+ {
+ "type": "field",
+ "value": "map_values_ids",
+ "width": "100%"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/packages/core/views/import/DataTransformer.list.default.json b/packages/core/views/import/DataTransformer.list.default.json
new file mode 100644
index 000000000..696bc64b7
--- /dev/null
+++ b/packages/core/views/import/DataTransformer.list.default.json
@@ -0,0 +1,33 @@
+{
+ "name": "Data Transformers",
+ "description": "Listing view for Data Transformer items.",
+ "layout": {
+ "items": [
+ {
+ "type": "field",
+ "value": "id",
+ "width": "10%",
+ "sortable": true,
+ "readonly": true
+ },
+ {
+ "type": "field",
+ "value": "column_mapping_id",
+ "width": "40%",
+ "sortable": true
+ },
+ {
+ "type": "field",
+ "value": "transformer_type",
+ "width": "40%",
+ "sortable": true
+ },
+ {
+ "type": "field",
+ "value": "order",
+ "width": "10%",
+ "sortable": true
+ }
+ ]
+ }
+}
diff --git a/packages/core/views/import/DataTransformerMapValue.form.default.json b/packages/core/views/import/DataTransformerMapValue.form.default.json
new file mode 100644
index 000000000..4df21a037
--- /dev/null
+++ b/packages/core/views/import/DataTransformerMapValue.form.default.json
@@ -0,0 +1,49 @@
+{
+ "name": "Data Transformer",
+ "description": "Default form for Data Transformer.",
+ "layout": {
+ "groups": [
+ {
+ "sections": [
+ {
+ "rows": [
+ {
+ "columns": [
+ {
+ "width": "100%",
+ "items": [
+ {
+ "type": "field",
+ "value": "data_transformer_id",
+ "width": "33%"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "columns": [
+ {
+ "width": "100%",
+ "items": [
+ {
+ "type": "field",
+ "value": "old_value",
+ "width": "25%"
+ },
+ {
+ "type": "field",
+ "value": "new_value",
+ "width": "25%"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/packages/core/views/import/DataTransformerMapValue.list.default.json b/packages/core/views/import/DataTransformerMapValue.list.default.json
new file mode 100644
index 000000000..9d282a500
--- /dev/null
+++ b/packages/core/views/import/DataTransformerMapValue.list.default.json
@@ -0,0 +1,33 @@
+{
+ "name": "Data Transformer Map Value",
+ "description": "Listing view for Data Transformer Map Value items.",
+ "layout": {
+ "items": [
+ {
+ "type": "field",
+ "value": "id",
+ "width": "10%",
+ "sortable": true,
+ "readonly": true
+ },
+ {
+ "type": "field",
+ "value": "data_transformer_id",
+ "width": "25%",
+ "sortable": true
+ },
+ {
+ "type": "field",
+ "value": "old_value",
+ "width": "25%",
+ "sortable": true
+ },
+ {
+ "type": "field",
+ "value": "new_value",
+ "width": "25%",
+ "sortable": true
+ }
+ ]
+ }
+}
diff --git a/packages/core/views/import/EntityMapping.form.default.json b/packages/core/views/import/EntityMapping.form.default.json
new file mode 100644
index 000000000..72a28826c
--- /dev/null
+++ b/packages/core/views/import/EntityMapping.form.default.json
@@ -0,0 +1,69 @@
+{
+ "name": "Entity Mapping",
+ "description": "Default form for Entity Mapping.",
+ "layout": {
+ "groups": [
+ {
+ "sections": [
+ {
+ "rows": [
+ {
+ "columns": [
+ {
+ "width": "100%",
+ "items": [
+ {
+ "type": "field",
+ "value": "name",
+ "width": "33%"
+ },
+ {
+ "type": "field",
+ "value": "",
+ "width": "33%"
+ },
+ {
+ "type": "field",
+ "value": "entity",
+ "width": "33%"
+ },
+ {
+ "type": "field",
+ "value": "mapping_type",
+ "width": "25%"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "sections": [
+ {
+ "id": "section.column-mappings",
+ "label": "Column mappings",
+ "rows": [
+ {
+ "columns": [
+ {
+ "width": "100%",
+ "items": [
+ {
+ "type": "field",
+ "value": "column_mappings_ids",
+ "width": "100%"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/packages/core/views/import/EntityMapping.list.default.json b/packages/core/views/import/EntityMapping.list.default.json
new file mode 100644
index 000000000..3f4fedf11
--- /dev/null
+++ b/packages/core/views/import/EntityMapping.list.default.json
@@ -0,0 +1,36 @@
+{
+ "name": "Entity Mappings",
+ "description": "Listing view for Entity Mapping items.",
+ "layout": {
+ "items": [
+ {
+ "type": "field",
+ "value": "id",
+ "width": "10%",
+ "sortable": true,
+ "readonly": true
+ },
+ {
+ "type": "field",
+ "value": "name",
+ "width": "33%",
+ "sortable": true,
+ "readonly": false
+ },
+ {
+ "type": "field",
+ "value": "entity",
+ "width": "33%",
+ "sortable": true,
+ "readonly": false
+ },
+ {
+ "type": "field",
+ "value": "mapping_type",
+ "width": "25%",
+ "sortable": true,
+ "readonly": false
+ }
+ ]
+ }
+}
diff --git a/packages/core/views/menu.settings.left.json b/packages/core/views/menu.settings.left.json
index 1afc748b6..9cc19b7f1 100644
--- a/packages/core/views/menu.settings.left.json
+++ b/packages/core/views/menu.settings.left.json
@@ -164,6 +164,26 @@
}
]
},
+ {
+ "id": "settings.import",
+ "label": "Import",
+ "description": "",
+ "icon": "settings_applications",
+ "type": "parent",
+ "children": [
+ {
+ "id": "settings.import.entity-mappings",
+ "label": "Entity mappings",
+ "description": "",
+ "icon": "device_hub",
+ "type": "entry",
+ "context": {
+ "entity": "core\\import\\EntityMapping",
+ "view": "list.default"
+ }
+ }
+ ]
+ },
{
"id": "settings.settings",
"label": "Settings",
diff --git a/public/assets/img/equal_summary.png b/public/assets/img/equal_summary.png
index 385b06f68..a52e1a869 100644
Binary files a/public/assets/img/equal_summary.png and b/public/assets/img/equal_summary.png differ
diff --git a/public/console.php b/public/console.php
index 95bf3a362..88b45b85f 100644
--- a/public/console.php
+++ b/public/console.php
@@ -1,13 +1,15 @@
- Some Rights Reserved, Cedric Francoys, 2010-2023
- Licensed under GNU LGPL 3 license
+ Some Rights Reserved, The eQual Framework, 2010-2024
+ Author: The eQual Framework Contributors
+ Original Author: Cedric Francoys
+ License: GNU LGPL 3 license
*/
error_reporting(0);
// get log file, using variation from URL, if any
-$log_file = (isset($_GET['f']) && strlen($_GET['f']))?$_GET['f']:'equal.log';
+$log_file = (isset($_GET['f']) && strlen($_GET['f'])) ? $_GET['f'] : 'equal.log';
// retrieve logs history (variations on filename)
$log_variations = [];
@@ -310,7 +312,7 @@
bottom: 20px;
opacity: 1;
}
- div.no-result {
+ div.feedback {
margin-left: 20px;
}
div.no-result::before {
@@ -495,6 +497,11 @@ classname = "text";
query = "a=1";
}
const response = await fetch("console.php?"+query);
+
+ if(response.status != 200) {
+ throw new Error(response.status);
+ }
+
const data = await response.json();
return data;
}
@@ -629,14 +636,20 @@ function createTraceElement(trace, i) {
list.style.display = "none";
list.innerHTML = "";
document.getElementById("loader").style.display = "block";
- const threads = await get_threads(params);
+ try {
+ const threads = await get_threads(params);
- for(const thread of threads) {
- let element = createThreadElement(thread, params);
- list.prepend(element);
+ for(const thread of threads) {
+ let element = createThreadElement(thread, params);
+ list.prepend(element);
+ }
+ if(!threads.length) {
+ list.innerHTML = "";
+ }
}
- if(!threads.length) {
- list.innerHTML = "";
+ catch(status) {
+ console.log("an error occurred", status);
+ list.innerHTML = "Filesize over limit. Parsing blocked to prevent overload.
";
}
document.getElementById("loader").style.display = "none";
list.style.display = "block";
@@ -810,6 +823,15 @@ function createTraceElement(trace, i) {
unset($_GET['date']);
}
+ $filesize = filesize('../log/'.$log_file);
+ $MAX_FILESIZE = 100 * 1000 * 1000;
+ // limit processing base on filesize to prevent overload
+ if($filesize > $MAX_FILESIZE) {
+ // set response as 'no content'
+ http_response_code(204);
+ die();
+ }
+
// read raw data from log file
if($f = fopen('../log/'.$log_file, 'r')) {
diff --git a/public/index.php b/public/index.php
index 36174aa06..39b771818 100644
--- a/public/index.php
+++ b/public/index.php
@@ -1,8 +1,9 @@
- Some Rights Reserved, Cedric Francoys, 2010-2023
- Licensed under GNU LGPL 3 license
+ Some Rights Reserved, The eQual Framework, 2010-2024
+ Original Author: Cedric Francoys
+ License: GNU LGPL 3 license
*/
/*
diff --git a/run.php b/run.php
index cab99b372..3ae3110cf 100644
--- a/run.php
+++ b/run.php
@@ -3,8 +3,9 @@
* This file is part of the eQual framework.
* https://github.com/equalframework/equal
*
-* Some Rights Reserved, Cedric Francoys, 2010-2024
-* Licensed under GNU LGPL 3 license
+* Some Rights Reserved, The eQual Framework, 2010-2024
+* Original Author: Cedric Francoys
+* License: GNU LGPL 3 license
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by