From 1cb667df49f6ab3fd6dc847fc243bbd722f39b16 Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Wed, 30 Oct 2019 11:35:59 +0100 Subject: [PATCH 01/35] Update provenance by adding agent and sensors --- config/params.php | 6 ++ controllers/DatasetController.php | 101 +++++++++++++++++++++++---- models/yiiModels/YiiDatasetModel.php | 20 +++++- views/dataset/_form.php | 74 +++++++++++++++++++- 4 files changed, 184 insertions(+), 17 deletions(-) diff --git a/config/params.php b/config/params.php index 96ffe266..fdceacdf 100755 --- a/config/params.php +++ b/config/params.php @@ -38,6 +38,12 @@ 'webServicePageSizeMax' => 2097152, // ONTOLOGY ----------------------------------------------------------------- + //-------- Provenance NameSpaces + 'provenanceNamespaces' => [ + "prov"=>"http://www.w3.org/ns/prov#", + "oeso"=>"http://www.opensilex.org/vocabulary/oeso#", + "rdf"=>"http://www.w3.org/1999/02/22-rdf-syntax-ns#" + ], //-------- Concepts 'Actuator' => 'http://www.opensilex.org/vocabulary/oeso#Actuator', 'Lens' => 'http://www.opensilex.org/vocabulary/oeso#Lens', diff --git a/controllers/DatasetController.php b/controllers/DatasetController.php index 03c22cf0..232f3819 100755 --- a/controllers/DatasetController.php +++ b/controllers/DatasetController.php @@ -19,14 +19,14 @@ use yii\web\Controller; use yii\web\UploadedFile; use yii\filters\VerbFilter; -use Exception; use app\models\yiiModels\YiiDocumentModel; use app\models\wsModels\WSProvenanceModel; -use app\models\yiiModels\VariableSearch; use app\models\wsModels\WSDataModel; use app\models\yiiModels\YiiConcernedItemModel; use openSILEX\handsontablePHP\adapter\HandsontableSimple; use openSILEX\handsontablePHP\classes\ColumnConfig; +use app\models\wsModels\WSConstants; +use app\components\helpers\Vocabulary; require_once '../config/config.php'; @@ -50,7 +50,13 @@ class DatasetController extends Controller { const ERRORS_LINE = "Line"; const ERRORS_COLUMN = "Column"; const ERRORS_MESSAGE = "Message"; + + const SENSORS_DATA = "sensors"; + const SENSOR_DATA_URI = "sensorUri"; + const SENSOR_DATA_LABEL = "sensorLabel"; + const SENSOR_DATA_TYPE = "sensorType"; + const PROVENANCE_PARAMS_VALUES = "provenanceNamespaces"; /** * define the behaviors * @return array @@ -311,7 +317,7 @@ public function actionCreate() { $datasetModel = new \app\models\yiiModels\YiiDatasetModel(); $variablesModel = new \app\models\yiiModels\YiiVariableModel(); - $token = Yii::$app->session['access_token']; + $token = Yii::$app->session[WSConstants::ACCESS_TOKEN]; // Load existing variables $variables = $variablesModel->getInstancesDefinitionsUrisAndLabel($token); @@ -321,7 +327,15 @@ public function actionCreate() { $provenanceService = new WSProvenanceModel(); $provenances = $this->mapProvenancesByUri($provenanceService->getAllProvenances($token)); $this->view->params["provenances"] = $provenances; - + + // Load existing sensors + $sensors = $this->getSensorsUrisTypesLabels($token); + $this->view->params["sensingDevices"] = $this->getSensorListToShowFromSensorList($sensors); + + // Load existing agents + $userModel = new \app\models\yiiModels\YiiUserModel(); + $users = $userModel->getPersonsMailsAndName($token); + $this->view->params['agents'] = $users; //If the form is complete, register data if ($datasetModel->load(Yii::$app->request->post())) { //Store uploaded CSV file @@ -339,12 +353,13 @@ public function actionCreate() { // Check CSV header with variables if (array_slice($csvHeaders, 2) === $givenVariables) { - // Get selected or create Provenance URI if (!array_key_exists($datasetModel->provenanceUri, $provenances)) { $provenanceUri = $this->createProvenance( $datasetModel->provenanceUri, - $datasetModel->provenanceComment + $datasetModel->provenanceComment, + $datasetModel->provenanceSensingDevices, + $datasetModel->provenanceAgents ); $datasetModel->provenanceUri = $provenanceUri; $provenances = $this->mapProvenancesByUri($provenanceService->getAllProvenances($token)); @@ -435,20 +450,36 @@ public function actionCreate() { /** * Create provenance from an alias and a comment - * @param type $alias - * @param type $comment + * @param type $alias label of the provenance + * @param type $comment comment linked to the provenance + * @param type $sensingDevice uri of the sensor + * @param String $agent uri of the agent * @return boolean */ - private function createProvenance($alias, $comment) { + private function createProvenance($alias, $comment,$sensingDevice = null, $agent =null) { $provenanceService = new WSProvenanceModel(); $date = new \DateTime(); + $metadata = [ + "namespaces" => Yii::$app->params[self::PROVENANCE_PARAMS_VALUES], + "creationDate" => $date->format("Y-m-d\TH:i:sO"), + "prov:Agent" =>[ + "oeso:SensingDevice" => [ + ], + "oeso:Operator" => [ + ] + ], + ]; + if($sensingDevice != null){ + $metadata["prov:Agent"]["oeso:SensingDevice"] = $sensingDevice; + } + if($sensingDevice != null){ + $metadata["prov:Agent"]["oeso:Operator"] = $agent; + } $provenanceUri = $provenanceService->createProvenance( Yii::$app->session['access_token'], $alias, $comment, - [ - "creationDate" => $date->format("Y-m-d\TH:i:sO") - ] + $metadata ); if (is_string($provenanceUri) && $provenanceUri != "token") { @@ -492,5 +523,49 @@ private function linkDocumentsToProvenance($provenanceUri, $documents) { return true; } } - + + /** + * Gets all sensors. + * @return sensors + */ + public function getSensorsUrisTypesLabels() { + $model = new \app\models\yiiModels\SensorSearch(); + $model->page = 0; + $model->pageSize = 10000; + $sensorsUrisTypesLabels = []; + $sensors = $model->search(Yii::$app->session[WSConstants::ACCESS_TOKEN], null); + if ($sensors === WSConstants::TOKEN_INVALID) { + return WSConstants::TOKEN_INVALID; + } else { + foreach ($sensors->models as $sensor) { + $sensorsUrisTypesLabels[] = + [ + self::SENSOR_DATA_URI => $sensor->uri, + self::SENSOR_DATA_LABEL => $sensor->label, + self::SENSOR_DATA_TYPE => $sensor->rdfType + ]; + } + } + return $sensorsUrisTypesLabels; + } + + /** + * + * @param type $sensorsUriTypesLabel + * @return array + */ + public function getSensorListToShowFromSensorList($sensorsUriTypesLabel) { + $sensorLabelListToShow = []; + foreach ($sensorsUriTypesLabel as $sensorUriTypesLabel) { + $sensorType = Vocabulary::prettyUri($sensorUriTypesLabel[self::SENSOR_DATA_TYPE]); + if (isset($sensorLabelListToShow[$sensorType])) { + $sensorLabelListToShow[$sensorType][$sensorUriTypesLabel[self::SENSOR_DATA_URI]] = $sensorUriTypesLabel[self::SENSOR_DATA_LABEL]; + } else { + $sensorLabelListToShow[$sensorType] = [ + $sensorUriTypesLabel[self::SENSOR_DATA_URI] => $sensorUriTypesLabel[self::SENSOR_DATA_LABEL] + ]; + } + } + return $sensorLabelListToShow; + } } diff --git a/models/yiiModels/YiiDatasetModel.php b/models/yiiModels/YiiDatasetModel.php index 2cb084af..ae03f17b 100755 --- a/models/yiiModels/YiiDatasetModel.php +++ b/models/yiiModels/YiiDatasetModel.php @@ -25,8 +25,8 @@ class YiiDatasetModel extends WSActiveRecord { /** - * Uri de la provenance - * @var type + * Provenance uri + * @var string */ public $provenanceUri; @@ -73,6 +73,18 @@ class YiiDatasetModel extends WSActiveRecord { * @var file */ public $file; + + /** + * Sensor uris + * @var array + */ + public $provenanceSensingDevices; + + /** + * Agent uris + * @var array + */ + public $provenanceAgents; const PROVENANCE = "provenance"; const DATA = "data"; @@ -95,6 +107,8 @@ public function __construct($pageSize = null, $page = null) { public function rules() { return [ [['variables', 'provenanceAlias', 'file', 'provenanceUri'], 'required'], + [['provenanceSensingDevices'], 'safe'], + [['provenanceAgents'], 'safe'], [['provenanceComment'], 'string'], [['provenanceUri', 'provenanceComment', 'documentsURIs', 'data', 'file'], 'safe'], [['file'], 'file', 'extensions' => 'csv'] @@ -109,6 +123,8 @@ public function attributeLabels() { return [ 'provenanceUri' => Yii::t('app', 'Provenance (URI)'), 'provenanceComment' => Yii::t('app', 'Provenance comment'), + 'provenanceSensingDevices' => Yii::t('app', 'Sensor'), + 'provenanceAgents' => Yii::t('app', 'Agent'), 'variables' => Yii::t('app', 'Variable(s)'), 'file' => Yii::t('app', 'Data file'), 'documentsUris' => Yii::t('app', 'Documents') diff --git a/views/dataset/_form.php b/views/dataset/_form.php index b9215a2a..e59aeb1e 100755 --- a/views/dataset/_form.php +++ b/views/dataset/_form.php @@ -111,11 +111,16 @@ echo 'var documentsLoadUri = "' . Url::to(['document/get-documents-widget']) . '";'; // Inject provenances list indexed by URI echo 'var provenances = ' . json_encode($this->params['provenances']) . ';'; + // Inject sensingDevices list indexed by URI + echo 'var sensingDevices = ' . json_encode($this->params['sensingDevices']) . ';'; + // Inject agents list indexed by URI + echo 'var agents = ' . json_encode($this->params['agents']) . ';'; ?> // Function to update provenance comment field depending of selected URI var updateProvenanceFields = function(uri) { if (provenances.hasOwnProperty(uri)) { +// console.log(provenances[uri]); // If selected provenance is known get its comment var comment = provenances[uri]["comment"]; @@ -125,12 +130,54 @@ .removeClass("has-error") .removeClass("has-success"); $(".field-yiidatasetmodel-provenancecomment .help-block").empty(); - + + // Set provenance provenanceSensingDevices, disable input and remove validation messages + try { + var provenanceSensingDevices = provenances[uri]["metadata"]["prov:Agent"]["oeso:SensingDevice"]; + $("#yiidatasetmodel-provenancesensingdevices").val(provenanceSensingDevices); + $("#yiidatasetmodel-provenancesensingdevices").trigger("change"); +// console.log(provenanceSensingDevices); + } + catch(error) { + $("#yiidatasetmodel-provenancesensingdevices").val([]); + $("#yiidatasetmodel-provenancesensingdevices").trigger("change"); + console.log("No sensing device set"); + }finally { + $("#yiidatasetmodel-provenancesensingdevices").val(provenanceSensingDevices).attr("disabled", "disabled"); + $(".field-yiidatasetmodel-provenancesensingdevices, .field-yiidatasetmodel-provenancesensingdevices *") + .removeClass("has-error") + .removeClass("has-success"); + $(".field-yiidatasetmodel-provenancesensingdevices .help-block").empty(); + } + // Set provenance provenanceSensingDevices, disable input and remove validation messages + try { + var provenanceAgents = provenances[uri]["metadata"]["prov:Agent"]["oeso:Operator"]; + $("#yiidatasetmodel-provenanceagents").val(provenanceAgents); + $("#yiidatasetmodel-provenanceagents").trigger("change"); +// console.log(provenanceAgents); + } + catch(error) { + $("#yiidatasetmodel-provenanceagents").val([]); + $("#yiidatasetmodel-provenanceagents").trigger("change"); + console.log("No agents set"); + }finally { + $("#yiidatasetmodel-provenanceagents").val(agents).attr("disabled", "disabled"); + $(".field-yiidatasetmodel-provenanceagents, .field-yiidatasetmodel-provenanceagents *") + .removeClass("has-error") + .removeClass("has-success"); + $(".field-yiidatasetmodel-provenanceagents .help-block").empty(); + } // Load linked documents $("#already-linked-documents").load(documentsLoadUri, { "uri": uri }) } else { + // Otherwise clear provenance comment and enable input + $("#yiidatasetmodel-provenancesensingdevices").val(sensingDevices).removeAttr("disabled").trigger("change"); + + // Otherwise clear provenance comment and enable input + $("#yiidatasetmodel-provenanceagents").val(agents).removeAttr("disabled").trigger("change"); + // Otherwise clear provenance comment and enable input $("#yiidatasetmodel-provenancecomment").val("").removeAttr("disabled"); @@ -160,9 +207,32 @@ 'tags' => true ], ]); ?> + + field($model, 'provenanceSensingDevices')->widget(\kartik\select2\Select2::classname(),[ + 'data' => $this->params['sensingDevices'], + 'options' => [ + 'placeholder' => Yii::t('app/messages', 'Select existing device') . ' ...', + 'multiple' => true + ], + 'pluginOptions' => [ + 'allowClear' => false, + 'tags' => true + ], + ]); ?> - field($model, 'provenanceComment')->textarea(['rows' => 6]) ?> + field($model, 'provenanceAgents')->widget(\kartik\select2\Select2::classname(),[ + 'data' => $this->params['agents'], + 'options' => [ + 'placeholder' => 'Select operator ...', + 'multiple' => true + ], + 'pluginOptions' => [ + 'allowClear' => true + ], + ]); ?> + field($model, 'provenanceComment')->textarea(['rows' => 6]) ?> +

field($model, 'documentsURIs')->widget(MultipleInput::className(), [ From fff143a4395a51eb8d24def34dba011daa320941 Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Wed, 6 Nov 2019 18:23:26 +0100 Subject: [PATCH 02/35] Update add sensor data --- controllers/ActuatorController.php | 2 +- controllers/DatasetController.php | 163 +++++++ controllers/SensorController.php | 6 +- models/wsModels/WSDataModel.php | 6 + models/wsModels/WSProvenanceModel.php | 40 ++ models/wsModels/WSSensorModel.php | 71 +++ models/yiiModels/DeviceDataSearch.php | 38 +- views/dataset/_form_on_sensor.php | 428 ++++++++++++++++++ views/dataset/create.php | 0 views/dataset/create_on_sensor.php | 35 ++ views/layouts/main.php | 6 +- views/sensor/_view_sensor_graph.php | 25 +- .../DatasetFiles/coma/datasetExemple.csv | 0 .../coma/datasetSensorExemple.csv | 1 + .../coma/datasetSensorTemplate.csv | 1 + .../semicolon/datasetSensorExemple.csv | 8 + .../semicolon/datasetSensorTemplate.csv | 1 + 17 files changed, 809 insertions(+), 22 deletions(-) create mode 100644 views/dataset/_form_on_sensor.php mode change 100755 => 100644 views/dataset/create.php create mode 100755 views/dataset/create_on_sensor.php mode change 100644 => 100755 web/documents/DatasetFiles/coma/datasetExemple.csv create mode 100644 web/documents/DatasetFiles/coma/datasetSensorExemple.csv create mode 100644 web/documents/DatasetFiles/coma/datasetSensorTemplate.csv create mode 100644 web/documents/DatasetFiles/semicolon/datasetSensorExemple.csv create mode 100644 web/documents/DatasetFiles/semicolon/datasetSensorTemplate.csv diff --git a/controllers/ActuatorController.php b/controllers/ActuatorController.php index abfa54c1..100758a7 100644 --- a/controllers/ActuatorController.php +++ b/controllers/ActuatorController.php @@ -354,7 +354,7 @@ public function actionSearchData() { // Get data $sessionToken = Yii::$app->session['access_token']; - $actuatorGraphData = $searchModel->getEnvironmentData($sessionToken); + $actuatorGraphData = $searchModel->getSensorData($sessionToken); // Render data return $this->renderAjax('_view_actuator_graph', [ diff --git a/controllers/DatasetController.php b/controllers/DatasetController.php index 232f3819..6d30fece 100755 --- a/controllers/DatasetController.php +++ b/controllers/DatasetController.php @@ -141,6 +141,30 @@ public function actionGenerateAndDownloadDatasetCreationFile() { fputcsv($file, $fileColumns, $delimiter = Yii::$app->params['csvSeparator']); fclose($file); } + + /** + * generate the csv file for the sensor dataset creation action. The csv file is + * generated with a column for each variable + * @param array variables list of the variables to add to the + * file uri => alias + * @return mixed + */ + public function actionGenerateAndDownloadDatasetSensorCreationFile() { + $fileColumns[] = DatasetController::DATE; + $variables = Yii::$app->request->post('variables'); + foreach ($variables as $variableAlias) { + $fileColumns[] = $variableAlias; + } + + $csvPath = "coma"; + if (Yii::$app->params['csvSeparator'] == ";") { + $csvPath = "semicolon"; + } + + $file = fopen('./documents/DatasetFiles/' . $csvPath . '/datasetSensorTemplate.csv', 'w'); + fputcsv($file, $fileColumns, $delimiter = Yii::$app->params['csvSeparator']); + fclose($file); + } /** * @@ -447,6 +471,145 @@ public function actionCreate() { ]); } } + + /** + * register the sensor data with the associated provenance and documents + * @return mixed + */ + public function actionCreateOnSensor() { + $datasetModel = new \app\models\yiiModels\YiiDatasetModel(); + $variablesModel = new \app\models\yiiModels\YiiVariableModel(); + + $token = Yii::$app->session[WSConstants::ACCESS_TOKEN]; + + // Load existing variables + $variables = $variablesModel->getInstancesDefinitionsUrisAndLabel($token); + $this->view->params["variables"] = $this->getVariablesListLabelToShowFromVariableList($variables); + + // Load existing provenances + $provenanceService = new WSProvenanceModel(); + $provenances = $this->mapProvenancesByUri($provenanceService->getAllProvenances($token)); + $this->view->params["provenances"] = $provenances; + + // Load existing sensors + $sensors = $this->getSensorsUrisTypesLabels($token); + $this->view->params["sensingDevices"] = $this->getSensorListToShowFromSensorList($sensors); + + // Load existing agents + $userModel = new \app\models\yiiModels\YiiUserModel(); + $users = $userModel->getPersonsMailsAndName($token); + $this->view->params['agents'] = $users; + //If the form is complete, register data + if ($datasetModel->load(Yii::$app->request->post())) { + //Store uploaded CSV file + $document = UploadedFile::getInstance($datasetModel, 'file'); + $serverFilePath = \config::path()['documentsUrl'] . "DatasetFiles/" . $document->name; + $document->saveAs($serverFilePath); + + //Read CSV file content + $fileContent = str_getcsv(file_get_contents($serverFilePath), "\n"); + $csvHeaders = str_getcsv(array_shift($fileContent), Yii::$app->params['csvSeparator']); + unlink($serverFilePath); + + //Loaded given variables + $givenVariables = $datasetModel->variables; + + // Check CSV header with variables + if (array_slice($csvHeaders, 1) === $givenVariables) { + // Get selected or create Provenance URI + if (!array_key_exists($datasetModel->provenanceUri, $provenances)) { + $provenanceUri = $this->createProvenance( + $datasetModel->provenanceUri, + $datasetModel->provenanceComment, + $datasetModel->provenanceSensingDevices, + $datasetModel->provenanceAgents + ); + $datasetModel->provenanceUri = $provenanceUri; + $provenances = $this->mapProvenancesByUri($provenanceService->getAllProvenances($token)); + $this->view->params["provenances"] = $provenances; + } else { + $provenanceUri = $datasetModel->provenanceUri; + } + + // If provenance sucessfully created + if ($provenanceUri) { + // Link uploaded documents to provenance URI + $linkDocuments = true; + if (is_array($datasetModel->documentsURIs) && is_array($datasetModel->documentsURIs["documentURI"])) { + $linkDocuments = $this->linkDocumentsToProvenance( + $provenanceUri, + $datasetModel->documentsURIs["documentURI"] + ); + } + + $datasetModel->documentsURIs = null; + + if ($linkDocuments === true) { + // Save CSV data linked to provenance URI + $values = []; + $scientifObjectUri = null; + foreach ($fileContent as $rowStr) { + $row = str_getcsv($rowStr, Yii::$app->params['csvSeparator']); + $date = $row[0]; + for ($i = 1; $i < count($row); $i++) { + $values[] = [ + "provenanceUri" => $provenanceUri, + "objectUri" => $scientifObjectUri, + "variableUri" => array_search($givenVariables[$i - 1], $variables), + "date" => $date, + "value" => $row[$i] + ]; + } + } + + $dataService = new WSDataModel(); + $result = $dataService->post($token, "/", $values); +// var_dump($result);exit; + // If data successfully saved + if (is_array($result->metadata->datafiles) && count($result->metadata->datafiles) > 0) { + $arrayData = $this->csvToArray($fileContent); + return $this->render('_form_dataset_created', [ + 'model' => $datasetModel, + 'handsontable' => $this->generateHandsontableDataset($csvHeaders, $arrayData), + 'insertedDataNumber' => count($arrayData) + ]); + } else { + + return $this->render('create_on_sensor', [ + 'model' => $datasetModel, + 'errors' => $result->metadata->status + ]); + } + } else { + return $this->render('create_on_sensor', [ + 'model' => $datasetModel, + 'errors' => [ + Yii::t("app/messages", "Error while creating linked documents") + ] + ]); + } + } else { + return $this->render('create_on_sensor', [ + 'model' => $datasetModel, + 'errors' => [ + Yii::t("app/messages", "Error while creating provenance") + ] + ]); + } + } else { + return $this->render('create_on_sensor', [ + 'model' => $datasetModel, + 'errors' => [ + Yii::t("app/messages", "CSV file headers does not match selected variables") + ] + ]); + } + } else { + return $this->render('create_on_sensor', [ + 'model' => $datasetModel, + ]); + } + } /** * Create provenance from an alias and a comment diff --git a/controllers/SensorController.php b/controllers/SensorController.php index d5b781a8..67e3bba1 100644 --- a/controllers/SensorController.php +++ b/controllers/SensorController.php @@ -33,6 +33,7 @@ * @update [Vincent Migot] 7 November, 2018: Add sensor/variables link * @update [Vincent Migot] 19 November, 2018: Add visualization of environmental data * @update [Andréas Garcia] 11 March, 2019: Add event widget + * @update [Arnaud Charleroy] 30 October, 2019: Add sensor data by data service * @author Morgane Vidal * @author Arnaud Charleroy */ @@ -312,7 +313,7 @@ public function actionView($id) { //get sensor's linked documents $searchDocumentModel = new DocumentSearch(); $searchDocumentModel->concernedItemFilter = $id; - $documents = $searchDocumentModel->search(Yii::$app->session['access_token'], ["concernedItem" => $id]); + $documents = $searchDocumentModel->search(Yii::$app->session[WSConstants::ACCESS_TOKEN], ["concernedItem" => $id]); //3. get sensor annotations $searchAnnotationModel = new AnnotationSearch(); @@ -541,8 +542,7 @@ public function actionSearchData() { // Get data $sessionToken = Yii::$app->session[WSConstants::ACCESS_TOKEN]; - $sensorGraphData = $searchModel->getEnvironmentData($sessionToken); - + $sensorGraphData = $searchModel->getSensorData($sessionToken); // Render data return $this->renderAjax('_view_sensor_graph', [ 'sensorGraphData' => $sensorGraphData diff --git a/models/wsModels/WSDataModel.php b/models/wsModels/WSDataModel.php index 8cdbc79b..00ffada8 100644 --- a/models/wsModels/WSDataModel.php +++ b/models/wsModels/WSDataModel.php @@ -19,6 +19,12 @@ */ class WSDataModel extends\openSILEX\guzzleClientPHP\WSModel { + /** + * Date format for the webservice filters with timezone + * @example: 2017-05-03T12:35:00+2000 + */ + const DATE_FORMAT = "Y-m-d\TH:i:sO"; + /** * initialize access to the projects service. Calls super constructor */ diff --git a/models/wsModels/WSProvenanceModel.php b/models/wsModels/WSProvenanceModel.php index e1e7c13c..5d06a79e 100644 --- a/models/wsModels/WSProvenanceModel.php +++ b/models/wsModels/WSProvenanceModel.php @@ -54,6 +54,46 @@ public function createProvenance($sessionToken, $label, $comment, $metadata) { } } + /** + * Return an array of existing provenances match with criteria + * + * @param string $sessionToken + * @param array $userCriteria array of citeria + * @return type + */ + public function getSpecificProvenancesByCriteria($sessionToken,$userCriteria = []) { + $pageSize = 200; + $subService = "/"; + $params = array_merge($userCriteria,[ + WSConstants::PAGE => 0, + WSConstants::PAGE_SIZE => $pageSize + ]); + + $provenanceResult = $this->get($sessionToken, $subService, $params); + + if (isset($provenanceResult->{WSConstants::METADATA}->{WSConstants::PAGINATION}) && isset($provenanceResult->{WSConstants::METADATA}->{WSConstants::PAGINATION}->{WSConstants::TOTAL_COUNT}) && $provenanceResult->{WSConstants::METADATA}->{WSConstants::PAGINATION}->{WSConstants::TOTAL_COUNT} > 0) { + + $result = $provenanceResult->{WSConstants::RESULT}->{WSConstants::DATA}; + + $totalPages = $provenanceResult->{WSConstants::METADATA}->{WSConstants::PAGINATION}->{WSConstants::TOTAL_PAGES}; + + for ($currentPage = 1; $currentPage < $totalPages; $currentPage++) { + $params[WSConstants::PAGE] = $currentPage; + $params[WSConstants::PAGE_SIZE] = $pageSize; + + $provenanceResult = $this->get($sessionToken, $subService, $params); + + $result = array_merge($result, $provenanceResult->{WSConstants::RESULT}->{WSConstants::DATA}); + } + + return $result; + }elseif(isset($provenanceResult->{WSConstants::RESULT}->{WSConstants::DATA})){ + return $provenanceResult->{WSConstants::RESULT}->{WSConstants::DATA}; + }else{ + return []; + } + } + /** * Return an array of all existing provenances * diff --git a/models/wsModels/WSSensorModel.php b/models/wsModels/WSSensorModel.php index ed50d656..317764a3 100644 --- a/models/wsModels/WSSensorModel.php +++ b/models/wsModels/WSSensorModel.php @@ -117,4 +117,75 @@ public function putSensorVariables($sessionToken, $sensorUri, $variablesUri) { return $requestRes; } } + + /** + * Return the latest measured value for a variable and a sensor + * @param string $sessionToken + * @param string $provenanceUri + * @param string $variableUri + * @return mixed data or the error message + */ + public function getLastSensorVariableData($sessionToken,$variableUri, $sensorUri) { + // Define the parameter array + $params = [ + "pageSize" => 1, + "page" => 0, + "variable" => $variableUri, + "dateSortAsc" => "false" + ]; + $subService = "/" . urlencode($sensorUri) . "/data"; + // Send the request + $requestRes = $this->get($sessionToken, $subService, $params); + // Return the first result data or null + if (isset($requestRes->{WSConstants::RESULT}->{WSConstants::DATA})) { + if (count($requestRes->{WSConstants::RESULT}->{WSConstants::DATA}) > 0) { + return (array) $requestRes->{WSConstants::RESULT}->{WSConstants::DATA}[0]; + } else { + return null; + } + + } else { + return $requestRes; + } + } + + + /** + * Return the 80000 first measured variable corresponding to the given parameters + * @param string $sessionToken + * @param string $sensorUri + * @param string $variableUri + * @param \DateTime $startDate + * @param \DateTime $endDate + * @return mixed data or the error message + */ + public function getAllSensorData($sessionToken, $sensorUri, $variableUri, $startDate, $endDate) { + // Define the parameter array + $params = [ + "pageSize" => 80000, + "page" => 0, + "variable" => $variableUri, + ]; + $subService = "/" . urlencode($sensorUri) . "/data"; + + if ($startDate != null) { + $params["startDate"] = $startDate->format(WSDataModel::DATE_FORMAT); + } + + if ($endDate != null) { + $params["endDate"] = $endDate->format(WSDataModel::DATE_FORMAT); + } + + $params["dateSortAsc"] = "true"; + + // Send the request + $requestRes = $this->get($sessionToken, $subService, $params); + + // Return the result data + if (isset($requestRes->{WSConstants::RESULT}->{WSConstants::DATA})) { + return (array) $requestRes->{WSConstants::RESULT}->{WSConstants::DATA}; + } else { + return $requestRes; + } + } } \ No newline at end of file diff --git a/models/yiiModels/DeviceDataSearch.php b/models/yiiModels/DeviceDataSearch.php index 04fceba6..341cd04c 100644 --- a/models/yiiModels/DeviceDataSearch.php +++ b/models/yiiModels/DeviceDataSearch.php @@ -10,7 +10,6 @@ namespace app\models\yiiModels; use Yii; -use \app\models\wsModels\WSEnvironmentModel; /** * implements the search action for the sensor data @@ -47,6 +46,11 @@ class DeviceDataSearch extends \yii\base\Model { */ public $graphName; + /** + * Store provenance data to prevent multiple calls to WS + */ + const SESSION_PROVENANCES = 'store_provenances_infos'; + /** * @inheritdoc */ @@ -90,18 +94,25 @@ public function attributeLabels() { * ] * ] */ - public function getEnvironmentData($sessionToken) { + public function getSensorData($sessionToken) { + // Session provenance + $sessionProvenances = Yii::$app->session[self::SESSION_PROVENANCES]; + if(!isset($sessionProvenances)){ + $sessionProvenances = []; + } // Create webservice instance - $ws = new WSEnvironmentModel(); + $wsData = new \app\models\wsModels\WSSensorModel(); + $wsProv = new \app\models\wsModels\WSProvenanceModel(); // Define start and end time period $dateTimeStart = null; $dateTimeEnd = null; if ($this->dateStart == null && $this->dateEnd == null) { + $date = null; + $lastData = $wsData->getLastSensorVariableData($sessionToken, $this->variableURI, $this->sensorURI); // If no dates are defined get the last data for this sensor and variable - $lastData = $ws->getLastSensorVariableData($sessionToken, $this->sensorURI, $this->variableURI); - + // Get the last date if exists $lastDate = null; if ($lastData['date']) { @@ -121,6 +132,7 @@ public function getEnvironmentData($sessionToken) { } else { return null; } + } else if ($this->dateStart == null) { // If only dateEnd is defined $dateTimeEnd = new \DateTime($this->dateEnd); @@ -132,10 +144,17 @@ public function getEnvironmentData($sessionToken) { $dateTimeStart = new \DateTime($this->dateStart); $dateTimeEnd = new \DateTime($this->dateEnd); } - + // Get all data - $data = $ws->getAllSensorData($sessionToken, $this->sensorURI, $this->variableURI, $dateTimeStart, $dateTimeEnd); - + $data = $wsData->getAllSensorData($sessionToken, $this->sensorURI, $this->variableURI, $dateTimeStart, $dateTimeEnd); + // Get specific associated provenance + foreach ($data as $d){ + if(!isset($sessionProvenances[$d->provenanceUri])){ + $specificProvenancesData = $wsProv->getSpecificProvenancesByCriteria($sessionToken,['uri' => $d->provenanceUri] ); + $sessionProvenances[$d->provenanceUri] = $specificProvenancesData[0]; + $d->provenanceLabel = $specificProvenancesData[0]->label; + } + } // Construct result $result = [ "graphName" => $this->graphName, @@ -143,7 +162,8 @@ public function getEnvironmentData($sessionToken) { "sensorUri" => $this->sensorURI, "dateStart" => $dateTimeStart, "dateEnd" => $dateTimeEnd, - "data" => $data + "data" => $data, + "provenances" => $sessionProvenances ]; return $result; diff --git a/views/dataset/_form_on_sensor.php b/views/dataset/_form_on_sensor.php new file mode 100644 index 00000000..831e76fb --- /dev/null +++ b/views/dataset/_form_on_sensor.php @@ -0,0 +1,428 @@ +loadJSLibraries(true); + echo $handsontable->loadCSSLibraries(); + } + +?> + +
+ ['enctype' => 'multipart/form-data']]); ?> + + session->getFlash('renderArray'); ?> + + +
+

Errors found in dataset :

+
    + exception->details; + } + } + + $errorMessages = array_unique($errorMessages); + foreach ($errorMessages as $errorMessage) { + echo '
  • ' . $errorMessage . '
  • '; + } + + ?> +
+
+ + +
+ +

Errors found in dataset

+ +
+
+ + +
+ +

Add dataset form

+ + + field($model, 'variables')->widget(\kartik\select2\Select2::classname(),[ + 'data' => $this->params['variables'], + 'options' => [ + 'placeholder' => Yii::t('app/messages', 'Select one or many variables') . ' ...', + 'id' => 'uriVariable-selector', + 'multiple' => true + ], + 'pluginOptions' => [ + 'allowClear' => true, + 'tags' => true + ], + ]); ?> + +
+

+ + + field($model, 'provenanceUri')->widget(\kartik\select2\Select2::classname(),[ + 'data' => $provenancesArray, + 'options' => [ + 'placeholder' => Yii::t('app/messages', 'Select existing provenance or create a new one') . ' ...', + 'id' => 'provenance-selector', + 'multiple' => false + ], + 'pluginOptions' => [ + 'allowClear' => true, + 'tags' => true + ], + ]); ?> + + field($model, 'provenanceSensingDevices')->widget(\kartik\select2\Select2::classname(),[ + 'data' => $this->params['sensingDevices'], + 'options' => [ + 'placeholder' => Yii::t('app/messages', 'Select existing device') . ' ...', + 'multiple' => true + ], + 'pluginOptions' => [ + 'allowClear' => false, + 'tags' => true + ], + ]); ?> + + field($model, 'provenanceAgents')->widget(\kartik\select2\Select2::classname(),[ + 'data' => $this->params['agents'], + 'options' => [ + 'placeholder' => 'Select operator ...', + 'multiple' => true + ], + 'pluginOptions' => [ + 'allowClear' => true + ], + ]); ?> + + field($model, 'provenanceComment')->textarea(['rows' => 6]) ?> + +

+
+ field($model, 'documentsURIs')->widget(MultipleInput::className(), [ + 'max' => 6, + 'allowEmptyList' => true, + 'enableGuessTitle' => true, + 'columns' => [ + [ + 'name' => 'documentURI', + 'options' => [ + 'readonly' => true, + 'style' => 'background-color:#C4DAE7;', + ] + ] + ], + 'addButtonOptions' => [ + 'class' => 'btn btn-primary buttonDocuments', + 'label' => Yii::t('app', 'Add Document') + ], + ])->label(false) + ?> + + + +
+ + + +

+ params['csvSeparator'] == ";") { + $csvPath = "semicolon"; + } + ?> + " . Yii::t('app', 'Download Template'), \config::path()['basePath'] . 'documents/DatasetFiles/' . $csvPath . '/datasetSensorTemplate.csv', ['id' => 'datasetSensorTemplate']) ?> + " . Yii::t('app', 'Download Example'), \config::path()['basePath'] . 'documents/DatasetFiles/' . $csvPath . '/datasetSensorExemple.csv') ?> +

+ field($model, 'file')->widget(FileInput::classname(), [ + 'options' => [ + 'maxFileSize' => 2000, + 'pluginOptions'=>['allowedFileExtensions'=>['csv'],'showUpload' => false], + ] + ]); + ?> + +
+ 'btn btn-success']) ?> +
+ + + + + + +
diff --git a/views/dataset/create.php b/views/dataset/create.php old mode 100755 new mode 100644 diff --git a/views/dataset/create_on_sensor.php b/views/dataset/create_on_sensor.php new file mode 100755 index 00000000..f68c659c --- /dev/null +++ b/views/dataset/create_on_sensor.php @@ -0,0 +1,35 @@ +title = Yii::t('app', 'Add Data on sensor'); +//$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Dataset', ['n' => 2]), 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

title) ?>

+ render('_form_on_sensor', [ + 'model' => $model, + 'errors' => $errors, + 'handsontable' => isset($handsontable) ? $handsontable : null, + 'handsontableErrorsCellsSettings' => isset($handsontableErrorsCellsSettings) ? $handsontableErrorsCellsSettings : null + ]) ?> +
diff --git a/views/layouts/main.php b/views/layouts/main.php index 1b7efcd6..63c8b882 100644 --- a/views/layouts/main.php +++ b/views/layouts/main.php @@ -107,9 +107,13 @@ 'label' => Yii::t('app', 'Data'), 'items' => [ [ - 'label' => Icon::show('plus', ['class' => 'fa-large'], Icon::FA) . " " . Yii::t('app', 'Add'), + 'label' => Icon::show('plus', ['class' => 'fa-large'], Icon::FA) . " " . Yii::t('app', 'Add on scientific object'), 'url' => ['/dataset/create'] ], + [ + 'label' => Icon::show('plus', ['class' => 'fa-large'], Icon::FA) . " " . Yii::t('app', 'Add only on sensor'), + 'url' => ['/dataset/create-on-sensor'] + ], [ 'label' => Icon::show('search', ['class' => 'fa-large'], Icon::FA) . " " . Yii::t('app', 'View'), 'url' => ['/data/index'] diff --git a/views/sensor/_view_sensor_graph.php b/views/sensor/_view_sensor_graph.php index a7037aa5..908b467d 100644 --- a/views/sensor/_view_sensor_graph.php +++ b/views/sensor/_view_sensor_graph.php @@ -23,19 +23,28 @@ * ] * ] */ -$serie = [ - "name" => $sensorGraphData["graphName"], - "data" => [] -]; +$series = []; + +foreach( $sensorGraphData["provenances"] as $provenance) { + $series[$provenance->uri]= [ + "name" => $provenance->label, + "data" => [] + ]; +} + +//Create an array of data to store serie data by uri +//array(1) { ["http://www.opensilex.org/sunagri/id/provenance/1572430583192"]=> array(2) { +//["name"]=> string(25) "new provs agent + sensor2" ["data"]=> array(0) { } } } if (is_array($sensorGraphData['data'])) { foreach ($sensorGraphData['data'] as $data) { - $serie['data'][] = [(strtotime($data->date))*1000, $data->value ]; + $series[$data->provenanceUri]['data'][] = [(strtotime($data->date))*1000, $data->value ]; } - + //format data - remove uri key + $series = array_values($series); + // Display Hightchart widget echo Highcharts::widget([ - // Create a unique ID for each graph based on variable URI 'id' => base64_encode($sensorGraphData["variableUri"]), 'options' => [ @@ -54,7 +63,7 @@ 'tooltip' => [ 'xDateFormat' => '%Y-%m-%d %H:%M' ], - 'series' => [$serie], + 'series' => $series, ] ]); } diff --git a/web/documents/DatasetFiles/coma/datasetExemple.csv b/web/documents/DatasetFiles/coma/datasetExemple.csv old mode 100644 new mode 100755 diff --git a/web/documents/DatasetFiles/coma/datasetSensorExemple.csv b/web/documents/DatasetFiles/coma/datasetSensorExemple.csv new file mode 100644 index 00000000..9a90a77c --- /dev/null +++ b/web/documents/DatasetFiles/coma/datasetSensorExemple.csv @@ -0,0 +1 @@ +Date,GlobalRadiation_InstantGlobalRadiation_WattPerSquareMeter,WindSpeed_TenMinutesMaxWindSpeed_MeterPerSecond diff --git a/web/documents/DatasetFiles/coma/datasetSensorTemplate.csv b/web/documents/DatasetFiles/coma/datasetSensorTemplate.csv new file mode 100644 index 00000000..8b823655 --- /dev/null +++ b/web/documents/DatasetFiles/coma/datasetSensorTemplate.csv @@ -0,0 +1 @@ +Date,Variable diff --git a/web/documents/DatasetFiles/semicolon/datasetSensorExemple.csv b/web/documents/DatasetFiles/semicolon/datasetSensorExemple.csv new file mode 100644 index 00000000..d5701a87 --- /dev/null +++ b/web/documents/DatasetFiles/semicolon/datasetSensorExemple.csv @@ -0,0 +1,8 @@ +Date;trait-1_method-A_dimensionless-unit;trait-2_method-B_dimensionless-unit;trait-3_method-C_dimensionless-unit +2019-09-12T15:51:00Z;2019-09-12;"red";-12 +2019-09-13T12:51:00Z;2019-09-13;"red";13e12 +2019-09-14T18:51:00Z;2019-09-14;"red";-0.000000000000000141 +2019-09-15T10:51:00Z;2019-09-15;"blue";-0.15 +2019-09-16T09:51:00Z;2019-09-16;"red";16 +2019-09-17T08:51:30Z;2019-09-17;"blue";17 + diff --git a/web/documents/DatasetFiles/semicolon/datasetSensorTemplate.csv b/web/documents/DatasetFiles/semicolon/datasetSensorTemplate.csv new file mode 100644 index 00000000..a9e4e9dd --- /dev/null +++ b/web/documents/DatasetFiles/semicolon/datasetSensorTemplate.csv @@ -0,0 +1 @@ +Date;Value \ No newline at end of file From 1b49226da07aa27683ebb57ae85e2643b25fc3e5 Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Fri, 8 Nov 2019 09:43:41 +0100 Subject: [PATCH 03/35] Update dataset form --- controllers/DatasetController.php | 41 +++++++++++++++++++++++++--- models/yiiModels/YiiDatasetModel.php | 16 ++++++++--- views/dataset/_form.php | 18 ++++++++++-- 3 files changed, 64 insertions(+), 11 deletions(-) diff --git a/controllers/DatasetController.php b/controllers/DatasetController.php index 6d30fece..063f73fa 100755 --- a/controllers/DatasetController.php +++ b/controllers/DatasetController.php @@ -27,6 +27,7 @@ use openSILEX\handsontablePHP\classes\ColumnConfig; use app\models\wsModels\WSConstants; use app\components\helpers\Vocabulary; +use app\models\yiiModels\YiiExperimentModel; require_once '../config/config.php'; @@ -42,7 +43,7 @@ class DatasetController extends Controller { //create a global configuration file for the csv files //\SILEX:TODO - const AGRONOMICAL_OBJECT_URI = "ScientificObjectURI"; + const AGRONOMICAL_OBJECT_URI = "ScientificObjectAlias"; const DATE = "Date"; const VALUE = "Value"; const ERRORS_MISSING_COLUMN = "Missing Columns"; @@ -360,6 +361,12 @@ public function actionCreate() { $userModel = new \app\models\yiiModels\YiiUserModel(); $users = $userModel->getPersonsMailsAndName($token); $this->view->params['agents'] = $users; + + // Load experiments + $experimentModel = new YiiExperimentModel(); + $experiments = $experimentModel->getExperimentsURIAndLabelList($token); + $this->view->params['experiments'] = $experiments; + //If the form is complete, register data if ($datasetModel->load(Yii::$app->request->post())) { //Store uploaded CSV file @@ -402,15 +409,32 @@ public function actionCreate() { $datasetModel->documentsURIs["documentURI"] ); } - + // Load all objectsl inked to an experiment + + $SciencitificObjectSearch = new \app\models\yiiModels\ScientificObjectSearch(); + $SciencitificObjectSearch->experiment = $datasetModel->experiment; + $result = $SciencitificObjectSearch->search($token, [WSConstants::PAGE_SIZE => 50000]); + + $objectUris = []; + foreach ($result->getModels() as $object){ + $objectUris[$object->uri]=$object->label; + } $datasetModel->documentsURIs = null; if ($linkDocuments === true) { + $objectsErrors = []; // Save CSV data linked to provenance URI $values = []; foreach ($fileContent as $rowStr) { $row = str_getcsv($rowStr, Yii::$app->params['csvSeparator']); - $scientifObjectUri = $row[0]; + $scientifObjectAlias = $row[0]; + if(!array_search($scientifObjectAlias, $objectUris)){ + $objectsErrors[] = $scientifObjectAlias . Yii::t("app/messages", " Object doesn't not exists in this experiment"); + $scientifObjectUri = null; + }else{ + $scientifObjectUri = array_search($scientifObjectAlias, $objectUris); + } + var_dump($datasetModel->experiment,$scientifObjectAlias,$scientifObjectUri); $date = $row[1]; for ($i = 2; $i < count($row); $i++) { $values[] = [ @@ -422,7 +446,16 @@ public function actionCreate() { ]; } } - + + if(!empty($objectsErrors)){ + return $this->render('create', [ + 'model' => $datasetModel, + 'errors' => $objectsErrors + ] + ); + } + + $dataService = new WSDataModel(); $result = $dataService->post($token, "/", $values); diff --git a/models/yiiModels/YiiDatasetModel.php b/models/yiiModels/YiiDatasetModel.php index ae03f17b..1d8f96ef 100755 --- a/models/yiiModels/YiiDatasetModel.php +++ b/models/yiiModels/YiiDatasetModel.php @@ -74,17 +74,23 @@ class YiiDatasetModel extends WSActiveRecord { */ public $file; - /** + /** * Sensor uris * @var array */ public $provenanceSensingDevices; - /** + /** * Agent uris * @var array */ public $provenanceAgents; + + /** + * Experiment uri + * @var string + */ + public $experiment; const PROVENANCE = "provenance"; const DATA = "data"; @@ -106,10 +112,11 @@ public function __construct($pageSize = null, $page = null) { */ public function rules() { return [ - [['variables', 'provenanceAlias', 'file', 'provenanceUri'], 'required'], + [['variables', 'provenanceAlias', 'file', 'provenanceUri','experiment'], 'required'], [['provenanceSensingDevices'], 'safe'], [['provenanceAgents'], 'safe'], [['provenanceComment'], 'string'], + [['experiment'], 'string'], [['provenanceUri', 'provenanceComment', 'documentsURIs', 'data', 'file'], 'safe'], [['file'], 'file', 'extensions' => 'csv'] ]; @@ -127,7 +134,8 @@ public function attributeLabels() { 'provenanceAgents' => Yii::t('app', 'Agent'), 'variables' => Yii::t('app', 'Variable(s)'), 'file' => Yii::t('app', 'Data file'), - 'documentsUris' => Yii::t('app', 'Documents') + 'documentsUris' => Yii::t('app', 'Documents'), + 'experiment' => Yii::t('app', 'Experiment') ]; } diff --git a/views/dataset/_form.php b/views/dataset/_form.php index e59aeb1e..42407d5a 100755 --- a/views/dataset/_form.php +++ b/views/dataset/_form.php @@ -83,7 +83,19 @@

Add dataset form

- + field($model, 'experiment')->widget(\kartik\select2\Select2::classname(),[ + 'data' => $this->params['experiments'], + 'options' => [ + 'placeholder' => Yii::t('app/messages', 'Select one experiment') . ' ...', + 'id' => 'experiment-selector', + 'multiple' => false + ], + 'pluginOptions' => [ + 'allowClear' => true, + 'tags' => true + ], + ]); ?> + field($model, 'variables')->widget(\kartik\select2\Select2::classname(),[ 'data' => $this->params['variables'], 'options' => [ @@ -269,8 +281,8 @@ : - - + + From ad60e23eb9a6a38133e0c31cb7eb0ed2f88f1cb2 Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Fri, 8 Nov 2019 14:40:15 +0100 Subject: [PATCH 04/35] User uri saved into provenance --- controllers/DatasetController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/DatasetController.php b/controllers/DatasetController.php index 063f73fa..979e3e3a 100755 --- a/controllers/DatasetController.php +++ b/controllers/DatasetController.php @@ -359,7 +359,7 @@ public function actionCreate() { // Load existing agents $userModel = new \app\models\yiiModels\YiiUserModel(); - $users = $userModel->getPersonsMailsAndName($token); + $users = $userModel->getPersonsURIAndName($token); $this->view->params['agents'] = $users; // Load experiments From 2989c3b7cf88a94c09ce4be638a4b556dfe3f2cf Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Fri, 8 Nov 2019 14:42:39 +0100 Subject: [PATCH 05/35] rename operator --- models/yiiModels/YiiDatasetModel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/yiiModels/YiiDatasetModel.php b/models/yiiModels/YiiDatasetModel.php index 1d8f96ef..23f02d62 100755 --- a/models/yiiModels/YiiDatasetModel.php +++ b/models/yiiModels/YiiDatasetModel.php @@ -131,7 +131,7 @@ public function attributeLabels() { 'provenanceUri' => Yii::t('app', 'Provenance (URI)'), 'provenanceComment' => Yii::t('app', 'Provenance comment'), 'provenanceSensingDevices' => Yii::t('app', 'Sensor'), - 'provenanceAgents' => Yii::t('app', 'Agent'), + 'provenanceAgents' => Yii::t('app', 'Operator'), 'variables' => Yii::t('app', 'Variable(s)'), 'file' => Yii::t('app', 'Data file'), 'documentsUris' => Yii::t('app', 'Documents'), From 9ef8f43833b87529281da94828e18a0ec601ed67 Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Tue, 12 Nov 2019 15:43:20 +0100 Subject: [PATCH 06/35] Correct sensor data contorller --- controllers/DatasetController.php | 2 +- models/yiiModels/YiiDataSensorModel.php | 37 +++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 models/yiiModels/YiiDataSensorModel.php diff --git a/controllers/DatasetController.php b/controllers/DatasetController.php index 6d30fece..2d00ad01 100755 --- a/controllers/DatasetController.php +++ b/controllers/DatasetController.php @@ -477,7 +477,7 @@ public function actionCreate() { * @return mixed */ public function actionCreateOnSensor() { - $datasetModel = new \app\models\yiiModels\YiiDatasetModel(); + $datasetModel = new \app\models\yiiModels\YiiDataSensorModel(); $variablesModel = new \app\models\yiiModels\YiiVariableModel(); $token = Yii::$app->session[WSConstants::ACCESS_TOKEN]; diff --git a/models/yiiModels/YiiDataSensorModel.php b/models/yiiModels/YiiDataSensorModel.php new file mode 100644 index 00000000..486c4f18 --- /dev/null +++ b/models/yiiModels/YiiDataSensorModel.php @@ -0,0 +1,37 @@ + + */ +class YiiDataSensorModel extends YiiDatasetModel { + + /** + * + * @return array the rules of the attributes + */ + public function rules() { + $rules = parent::rules(); + $rules[] =[['provenanceSensingDevices'], 'required']; + return $rules; + } + +} From 4c6260f48ed36db24c4e253d9243b10b05dfd4bc Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Tue, 12 Nov 2019 15:51:46 +0100 Subject: [PATCH 07/35] Remove sensor from dataset update --- controllers/DatasetController.php | 2 +- views/dataset/_form.php | 37 ++----------------------------- 2 files changed, 3 insertions(+), 36 deletions(-) diff --git a/controllers/DatasetController.php b/controllers/DatasetController.php index fccd94db..60f16e21 100755 --- a/controllers/DatasetController.php +++ b/controllers/DatasetController.php @@ -668,7 +668,7 @@ private function createProvenance($alias, $comment,$sensingDevice = null, $agent if($sensingDevice != null){ $metadata["prov:Agent"]["oeso:SensingDevice"] = $sensingDevice; } - if($sensingDevice != null){ + if($agent != null){ $metadata["prov:Agent"]["oeso:Operator"] = $agent; } $provenanceUri = $provenanceService->createProvenance( diff --git a/views/dataset/_form.php b/views/dataset/_form.php index 42407d5a..6638b397 100755 --- a/views/dataset/_form.php +++ b/views/dataset/_form.php @@ -143,25 +143,7 @@ .removeClass("has-success"); $(".field-yiidatasetmodel-provenancecomment .help-block").empty(); - // Set provenance provenanceSensingDevices, disable input and remove validation messages - try { - var provenanceSensingDevices = provenances[uri]["metadata"]["prov:Agent"]["oeso:SensingDevice"]; - $("#yiidatasetmodel-provenancesensingdevices").val(provenanceSensingDevices); - $("#yiidatasetmodel-provenancesensingdevices").trigger("change"); -// console.log(provenanceSensingDevices); - } - catch(error) { - $("#yiidatasetmodel-provenancesensingdevices").val([]); - $("#yiidatasetmodel-provenancesensingdevices").trigger("change"); - console.log("No sensing device set"); - }finally { - $("#yiidatasetmodel-provenancesensingdevices").val(provenanceSensingDevices).attr("disabled", "disabled"); - $(".field-yiidatasetmodel-provenancesensingdevices, .field-yiidatasetmodel-provenancesensingdevices *") - .removeClass("has-error") - .removeClass("has-success"); - $(".field-yiidatasetmodel-provenancesensingdevices .help-block").empty(); - } - // Set provenance provenanceSensingDevices, disable input and remove validation messages + // Set provenance provenanceAgents, disable input and remove validation messages try { var provenanceAgents = provenances[uri]["metadata"]["prov:Agent"]["oeso:Operator"]; $("#yiidatasetmodel-provenanceagents").val(provenanceAgents); @@ -184,10 +166,7 @@ "uri": uri }) } else { - // Otherwise clear provenance comment and enable input - $("#yiidatasetmodel-provenancesensingdevices").val(sensingDevices).removeAttr("disabled").trigger("change"); - - // Otherwise clear provenance comment and enable input + // Otherwise clear provenance agents and enable input $("#yiidatasetmodel-provenanceagents").val(agents).removeAttr("disabled").trigger("change"); // Otherwise clear provenance comment and enable input @@ -219,18 +198,6 @@ 'tags' => true ], ]); ?> - - field($model, 'provenanceSensingDevices')->widget(\kartik\select2\Select2::classname(),[ - 'data' => $this->params['sensingDevices'], - 'options' => [ - 'placeholder' => Yii::t('app/messages', 'Select existing device') . ' ...', - 'multiple' => true - ], - 'pluginOptions' => [ - 'allowClear' => false, - 'tags' => true - ], - ]); ?> field($model, 'provenanceAgents')->widget(\kartik\select2\Select2::classname(),[ 'data' => $this->params['agents'], From 1e6d3bc5acb6a7140b7884d5bde8bb23ecb6ae04 Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Wed, 13 Nov 2019 18:31:35 +0100 Subject: [PATCH 08/35] Remove var_dump --- controllers/DatasetController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/controllers/DatasetController.php b/controllers/DatasetController.php index 60f16e21..0c94cd60 100755 --- a/controllers/DatasetController.php +++ b/controllers/DatasetController.php @@ -434,7 +434,6 @@ public function actionCreate() { }else{ $scientifObjectUri = array_search($scientifObjectAlias, $objectUris); } - var_dump($datasetModel->experiment,$scientifObjectAlias,$scientifObjectUri); $date = $row[1]; for ($i = 2; $i < count($row); $i++) { $values[] = [ From d7398e24f285f792bea565642a3073eaba10d155 Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Wed, 13 Nov 2019 19:01:45 +0100 Subject: [PATCH 09/35] Add pageSizeLimit to 30000 --- controllers/DatasetController.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/controllers/DatasetController.php b/controllers/DatasetController.php index 0c94cd60..bb592c73 100755 --- a/controllers/DatasetController.php +++ b/controllers/DatasetController.php @@ -413,8 +413,9 @@ public function actionCreate() { $SciencitificObjectSearch = new \app\models\yiiModels\ScientificObjectSearch(); $SciencitificObjectSearch->experiment = $datasetModel->experiment; - $result = $SciencitificObjectSearch->search($token, [WSConstants::PAGE_SIZE => 50000]); - + $SciencitificObjectSearch->pageSize = 30000; + $result = $SciencitificObjectSearch->search($token); + $objectUris = []; foreach ($result->getModels() as $object){ $objectUris[$object->uri]=$object->label; From 3f01b976b180753da2954204d45a1569e589c938 Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Mon, 18 Nov 2019 14:20:41 +0100 Subject: [PATCH 10/35] Remove add on sensor layouts --- views/dataset/_form_on_sensor.php | 428 ----------------------------- views/dataset/create_on_sensor.php | 35 --- views/layouts/main.php | 4 - 3 files changed, 467 deletions(-) delete mode 100644 views/dataset/_form_on_sensor.php delete mode 100755 views/dataset/create_on_sensor.php diff --git a/views/dataset/_form_on_sensor.php b/views/dataset/_form_on_sensor.php deleted file mode 100644 index 831e76fb..00000000 --- a/views/dataset/_form_on_sensor.php +++ /dev/null @@ -1,428 +0,0 @@ -loadJSLibraries(true); - echo $handsontable->loadCSSLibraries(); - } - -?> - -
- ['enctype' => 'multipart/form-data']]); ?> - - session->getFlash('renderArray'); ?> - - -
-

Errors found in dataset :

-
    - exception->details; - } - } - - $errorMessages = array_unique($errorMessages); - foreach ($errorMessages as $errorMessage) { - echo '
  • ' . $errorMessage . '
  • '; - } - - ?> -
-
- - -
- -

Errors found in dataset

- -
-
- - -
- -

Add dataset form

- - - field($model, 'variables')->widget(\kartik\select2\Select2::classname(),[ - 'data' => $this->params['variables'], - 'options' => [ - 'placeholder' => Yii::t('app/messages', 'Select one or many variables') . ' ...', - 'id' => 'uriVariable-selector', - 'multiple' => true - ], - 'pluginOptions' => [ - 'allowClear' => true, - 'tags' => true - ], - ]); ?> - -
-

- - - field($model, 'provenanceUri')->widget(\kartik\select2\Select2::classname(),[ - 'data' => $provenancesArray, - 'options' => [ - 'placeholder' => Yii::t('app/messages', 'Select existing provenance or create a new one') . ' ...', - 'id' => 'provenance-selector', - 'multiple' => false - ], - 'pluginOptions' => [ - 'allowClear' => true, - 'tags' => true - ], - ]); ?> - - field($model, 'provenanceSensingDevices')->widget(\kartik\select2\Select2::classname(),[ - 'data' => $this->params['sensingDevices'], - 'options' => [ - 'placeholder' => Yii::t('app/messages', 'Select existing device') . ' ...', - 'multiple' => true - ], - 'pluginOptions' => [ - 'allowClear' => false, - 'tags' => true - ], - ]); ?> - - field($model, 'provenanceAgents')->widget(\kartik\select2\Select2::classname(),[ - 'data' => $this->params['agents'], - 'options' => [ - 'placeholder' => 'Select operator ...', - 'multiple' => true - ], - 'pluginOptions' => [ - 'allowClear' => true - ], - ]); ?> - - field($model, 'provenanceComment')->textarea(['rows' => 6]) ?> - -

-
- field($model, 'documentsURIs')->widget(MultipleInput::className(), [ - 'max' => 6, - 'allowEmptyList' => true, - 'enableGuessTitle' => true, - 'columns' => [ - [ - 'name' => 'documentURI', - 'options' => [ - 'readonly' => true, - 'style' => 'background-color:#C4DAE7;', - ] - ] - ], - 'addButtonOptions' => [ - 'class' => 'btn btn-primary buttonDocuments', - 'label' => Yii::t('app', 'Add Document') - ], - ])->label(false) - ?> - - - -
- -
ScientificObjectURI *ScientificObjectAlias *
Date *
- - - - - - - - -
Date *

(format ISO 8601: YYYY-MM-DD or YYYY-MM-DDTHH:mm:ssZ)

Value * ()
- - -

- params['csvSeparator'] == ";") { - $csvPath = "semicolon"; - } - ?> - " . Yii::t('app', 'Download Template'), \config::path()['basePath'] . 'documents/DatasetFiles/' . $csvPath . '/datasetSensorTemplate.csv', ['id' => 'datasetSensorTemplate']) ?> - " . Yii::t('app', 'Download Example'), \config::path()['basePath'] . 'documents/DatasetFiles/' . $csvPath . '/datasetSensorExemple.csv') ?> -

- field($model, 'file')->widget(FileInput::classname(), [ - 'options' => [ - 'maxFileSize' => 2000, - 'pluginOptions'=>['allowedFileExtensions'=>['csv'],'showUpload' => false], - ] - ]); - ?> - -
- 'btn btn-success']) ?> -
- - - - - - - diff --git a/views/dataset/create_on_sensor.php b/views/dataset/create_on_sensor.php deleted file mode 100755 index f68c659c..00000000 --- a/views/dataset/create_on_sensor.php +++ /dev/null @@ -1,35 +0,0 @@ -title = Yii::t('app', 'Add Data on sensor'); -//$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Dataset', ['n' => 2]), 'url' => ['index']]; -$this->params['breadcrumbs'][] = $this->title; -?> -
- -

title) ?>

- render('_form_on_sensor', [ - 'model' => $model, - 'errors' => $errors, - 'handsontable' => isset($handsontable) ? $handsontable : null, - 'handsontableErrorsCellsSettings' => isset($handsontableErrorsCellsSettings) ? $handsontableErrorsCellsSettings : null - ]) ?> -
diff --git a/views/layouts/main.php b/views/layouts/main.php index 63c8b882..fb14e23f 100644 --- a/views/layouts/main.php +++ b/views/layouts/main.php @@ -110,10 +110,6 @@ 'label' => Icon::show('plus', ['class' => 'fa-large'], Icon::FA) . " " . Yii::t('app', 'Add on scientific object'), 'url' => ['/dataset/create'] ], - [ - 'label' => Icon::show('plus', ['class' => 'fa-large'], Icon::FA) . " " . Yii::t('app', 'Add only on sensor'), - 'url' => ['/dataset/create-on-sensor'] - ], [ 'label' => Icon::show('search', ['class' => 'fa-large'], Icon::FA) . " " . Yii::t('app', 'View'), 'url' => ['/data/index'] From 77cdfbb3e6c2fc3016a8175fd9559fd16a60a7f0 Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Mon, 18 Nov 2019 14:50:17 +0100 Subject: [PATCH 11/35] Fix write access --- web/documents/DatasetFiles/coma/datasetSensorExemple.csv | 0 web/documents/DatasetFiles/coma/datasetSensorTemplate.csv | 0 web/documents/DatasetFiles/coma/datasetTemplate.csv | 0 web/documents/DatasetFiles/semicolon/datasetExemple.csv | 0 web/documents/DatasetFiles/semicolon/datasetSensorExemple.csv | 0 web/documents/DatasetFiles/semicolon/datasetSensorTemplate.csv | 0 web/documents/DatasetFiles/semicolon/datasetTemplate.csv | 0 7 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 web/documents/DatasetFiles/coma/datasetSensorExemple.csv mode change 100644 => 100755 web/documents/DatasetFiles/coma/datasetSensorTemplate.csv mode change 100644 => 100755 web/documents/DatasetFiles/coma/datasetTemplate.csv mode change 100644 => 100755 web/documents/DatasetFiles/semicolon/datasetExemple.csv mode change 100644 => 100755 web/documents/DatasetFiles/semicolon/datasetSensorExemple.csv mode change 100644 => 100755 web/documents/DatasetFiles/semicolon/datasetSensorTemplate.csv mode change 100644 => 100755 web/documents/DatasetFiles/semicolon/datasetTemplate.csv diff --git a/web/documents/DatasetFiles/coma/datasetSensorExemple.csv b/web/documents/DatasetFiles/coma/datasetSensorExemple.csv old mode 100644 new mode 100755 diff --git a/web/documents/DatasetFiles/coma/datasetSensorTemplate.csv b/web/documents/DatasetFiles/coma/datasetSensorTemplate.csv old mode 100644 new mode 100755 diff --git a/web/documents/DatasetFiles/coma/datasetTemplate.csv b/web/documents/DatasetFiles/coma/datasetTemplate.csv old mode 100644 new mode 100755 diff --git a/web/documents/DatasetFiles/semicolon/datasetExemple.csv b/web/documents/DatasetFiles/semicolon/datasetExemple.csv old mode 100644 new mode 100755 diff --git a/web/documents/DatasetFiles/semicolon/datasetSensorExemple.csv b/web/documents/DatasetFiles/semicolon/datasetSensorExemple.csv old mode 100644 new mode 100755 diff --git a/web/documents/DatasetFiles/semicolon/datasetSensorTemplate.csv b/web/documents/DatasetFiles/semicolon/datasetSensorTemplate.csv old mode 100644 new mode 100755 diff --git a/web/documents/DatasetFiles/semicolon/datasetTemplate.csv b/web/documents/DatasetFiles/semicolon/datasetTemplate.csv old mode 100644 new mode 100755 From ad9f3fcb1a8fa169dc7de3511624072db43f9c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9as?= Date: Mon, 18 Nov 2019 15:02:55 +0100 Subject: [PATCH 12/35] Improve English translation --- translations/fr/messages.php | 2 +- views/dataset/_form.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/translations/fr/messages.php b/translations/fr/messages.php index c44a0538..f73110c6 100755 --- a/translations/fr/messages.php +++ b/translations/fr/messages.php @@ -98,7 +98,7 @@ 'Select image view...' => 'Sélectionnez la vue de l\'image...', 'Select provenance...'=>'Sélectionnez la provenance...', 'Select type...' => 'Sélectionnez le type...', - 'Select one or many variables' => 'Sélectionnez une ou plusieurs variables', + 'Select one or more variables' => 'Sélectionnez une ou plusieurs variables', 'Select existing provenance or create a new one' => 'Selectionnez une provenance existante où créez en une nouvelle', 'Software is licensed under AGPL-3.0 and data under CC BY-NC-SA 4.0' => 'Le logiciel est sous licence AGPL-3.0 et les données sous CC BY-NC-SA 4.0', 'Some required fields are missings' => 'Des champs requis sont manquants.', diff --git a/views/dataset/_form.php b/views/dataset/_form.php index 6638b397..a6154f7e 100755 --- a/views/dataset/_form.php +++ b/views/dataset/_form.php @@ -99,7 +99,7 @@ field($model, 'variables')->widget(\kartik\select2\Select2::classname(),[ 'data' => $this->params['variables'], 'options' => [ - 'placeholder' => Yii::t('app/messages', 'Select one or many variables') . ' ...', + 'placeholder' => Yii::t('app/messages', 'Select one or more variables') . ' ...', 'id' => 'uriVariable-selector', 'multiple' => true ], From 8ea68364fd42cfa89de67ac6be311e575816dfdf Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Wed, 20 Nov 2019 16:34:04 +0100 Subject: [PATCH 13/35] Update dataset controller and view --- controllers/DatasetController.php | 234 ++-------- models/yiiModels/YiiDataSensorModel.php | 37 -- models/yiiModels/YiiDatasetModel.php | 5 +- views/dataset/_form.php | 546 +++++++++++++----------- 4 files changed, 339 insertions(+), 483 deletions(-) delete mode 100644 models/yiiModels/YiiDataSensorModel.php diff --git a/controllers/DatasetController.php b/controllers/DatasetController.php index bb592c73..ed6cb35f 100755 --- a/controllers/DatasetController.php +++ b/controllers/DatasetController.php @@ -166,7 +166,39 @@ public function actionGenerateAndDownloadDatasetSensorCreationFile() { fputcsv($file, $fileColumns, $delimiter = Yii::$app->params['csvSeparator']); fclose($file); } - + + /** + * + * @param type $experimentUri + */ + public function actionGetExperimentMesuredVariablesSelectList($experimentUri){ + + Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; + $variables = []; + $variables["data"] = []; + $experimentVariable = $this->getExperimentMesuredVariablesSelectList($experimentUri); + foreach ($experimentVariable as $key => $value) { + $variables["data"][] = ["id" => $key, "text" => $value]; + } + + return($variables); + } + + private function getExperimentMesuredVariablesSelectList($experimentUri) { + if(!isset($experimentUri) || empty($experimentUri)){ + return []; + } + $experimentModel = new YiiExperimentModel(); + $variables = $experimentModel->getMeasuredVariables( + Yii::$app->session[WSConstants::ACCESS_TOKEN], + $experimentUri + ); + if(isset($variables) && is_array($variables)){ + return $variables; + } + return []; + } + /** * * @param array $csvErrors the errors founded. @@ -344,18 +376,10 @@ public function actionCreate() { $token = Yii::$app->session[WSConstants::ACCESS_TOKEN]; - // Load existing variables - $variables = $variablesModel->getInstancesDefinitionsUrisAndLabel($token); - $this->view->params["variables"] = $this->getVariablesListLabelToShowFromVariableList($variables); - // Load existing provenances $provenanceService = new WSProvenanceModel(); $provenances = $this->mapProvenancesByUri($provenanceService->getAllProvenances($token)); $this->view->params["provenances"] = $provenances; - - // Load existing sensors - $sensors = $this->getSensorsUrisTypesLabels($token); - $this->view->params["sensingDevices"] = $this->getSensorListToShowFromSensorList($sensors); // Load existing agents $userModel = new \app\models\yiiModels\YiiUserModel(); @@ -380,10 +404,12 @@ public function actionCreate() { unlink($serverFilePath); //Loaded given variables - $givenVariables = $datasetModel->variables; - + $experimentVariables = $this->getExperimentMesuredVariablesSelectList($datasetModel->experiment) ; + $csvVariables = array_slice($csvHeaders, 2); + // select all variables that don"t exist in experiment variables + $variablesNotInExperiment = array_diff($csvVariables, $experimentVariables); // Check CSV header with variables - if (array_slice($csvHeaders, 2) === $givenVariables) { + if (count($variablesNotInExperiment) === 0) { // Get selected or create Provenance URI if (!array_key_exists($datasetModel->provenanceUri, $provenances)) { $provenanceUri = $this->createProvenance( @@ -494,7 +520,7 @@ public function actionCreate() { return $this->render('create', [ 'model' => $datasetModel, 'errors' => [ - Yii::t("app/messages", "CSV file headers does not match selected variables") + Yii::t("app/messages", "CSV file headers does not match selected variables (" . implode(",", $variablesNotInExperiment) . ")") ] ]); } @@ -505,144 +531,6 @@ public function actionCreate() { } } - /** - * register the sensor data with the associated provenance and documents - * @return mixed - */ - public function actionCreateOnSensor() { - $datasetModel = new \app\models\yiiModels\YiiDataSensorModel(); - $variablesModel = new \app\models\yiiModels\YiiVariableModel(); - - $token = Yii::$app->session[WSConstants::ACCESS_TOKEN]; - - // Load existing variables - $variables = $variablesModel->getInstancesDefinitionsUrisAndLabel($token); - $this->view->params["variables"] = $this->getVariablesListLabelToShowFromVariableList($variables); - - // Load existing provenances - $provenanceService = new WSProvenanceModel(); - $provenances = $this->mapProvenancesByUri($provenanceService->getAllProvenances($token)); - $this->view->params["provenances"] = $provenances; - - // Load existing sensors - $sensors = $this->getSensorsUrisTypesLabels($token); - $this->view->params["sensingDevices"] = $this->getSensorListToShowFromSensorList($sensors); - - // Load existing agents - $userModel = new \app\models\yiiModels\YiiUserModel(); - $users = $userModel->getPersonsMailsAndName($token); - $this->view->params['agents'] = $users; - //If the form is complete, register data - if ($datasetModel->load(Yii::$app->request->post())) { - //Store uploaded CSV file - $document = UploadedFile::getInstance($datasetModel, 'file'); - $serverFilePath = \config::path()['documentsUrl'] . "DatasetFiles/" . $document->name; - $document->saveAs($serverFilePath); - - //Read CSV file content - $fileContent = str_getcsv(file_get_contents($serverFilePath), "\n"); - $csvHeaders = str_getcsv(array_shift($fileContent), Yii::$app->params['csvSeparator']); - unlink($serverFilePath); - - //Loaded given variables - $givenVariables = $datasetModel->variables; - - // Check CSV header with variables - if (array_slice($csvHeaders, 1) === $givenVariables) { - // Get selected or create Provenance URI - if (!array_key_exists($datasetModel->provenanceUri, $provenances)) { - $provenanceUri = $this->createProvenance( - $datasetModel->provenanceUri, - $datasetModel->provenanceComment, - $datasetModel->provenanceSensingDevices, - $datasetModel->provenanceAgents - ); - $datasetModel->provenanceUri = $provenanceUri; - $provenances = $this->mapProvenancesByUri($provenanceService->getAllProvenances($token)); - $this->view->params["provenances"] = $provenances; - } else { - $provenanceUri = $datasetModel->provenanceUri; - } - - // If provenance sucessfully created - if ($provenanceUri) { - // Link uploaded documents to provenance URI - $linkDocuments = true; - if (is_array($datasetModel->documentsURIs) && is_array($datasetModel->documentsURIs["documentURI"])) { - $linkDocuments = $this->linkDocumentsToProvenance( - $provenanceUri, - $datasetModel->documentsURIs["documentURI"] - ); - } - - $datasetModel->documentsURIs = null; - - if ($linkDocuments === true) { - // Save CSV data linked to provenance URI - $values = []; - $scientifObjectUri = null; - foreach ($fileContent as $rowStr) { - $row = str_getcsv($rowStr, Yii::$app->params['csvSeparator']); - $date = $row[0]; - for ($i = 1; $i < count($row); $i++) { - $values[] = [ - "provenanceUri" => $provenanceUri, - "objectUri" => $scientifObjectUri, - "variableUri" => array_search($givenVariables[$i - 1], $variables), - "date" => $date, - "value" => $row[$i] - ]; - } - } - - $dataService = new WSDataModel(); - $result = $dataService->post($token, "/", $values); -// var_dump($result);exit; - // If data successfully saved - if (is_array($result->metadata->datafiles) && count($result->metadata->datafiles) > 0) { - $arrayData = $this->csvToArray($fileContent); - return $this->render('_form_dataset_created', [ - 'model' => $datasetModel, - 'handsontable' => $this->generateHandsontableDataset($csvHeaders, $arrayData), - 'insertedDataNumber' => count($arrayData) - ]); - } else { - - return $this->render('create_on_sensor', [ - 'model' => $datasetModel, - 'errors' => $result->metadata->status - ]); - } - } else { - return $this->render('create_on_sensor', [ - 'model' => $datasetModel, - 'errors' => [ - Yii::t("app/messages", "Error while creating linked documents") - ] - ]); - } - } else { - return $this->render('create_on_sensor', [ - 'model' => $datasetModel, - 'errors' => [ - Yii::t("app/messages", "Error while creating provenance") - ] - ]); - } - } else { - return $this->render('create_on_sensor', [ - 'model' => $datasetModel, - 'errors' => [ - Yii::t("app/messages", "CSV file headers does not match selected variables") - ] - ]); - } - } else { - return $this->render('create_on_sensor', [ - 'model' => $datasetModel, - ]); - } - } /** * Create provenance from an alias and a comment @@ -720,48 +608,4 @@ private function linkDocumentsToProvenance($provenanceUri, $documents) { } } - /** - * Gets all sensors. - * @return sensors - */ - public function getSensorsUrisTypesLabels() { - $model = new \app\models\yiiModels\SensorSearch(); - $model->page = 0; - $model->pageSize = 10000; - $sensorsUrisTypesLabels = []; - $sensors = $model->search(Yii::$app->session[WSConstants::ACCESS_TOKEN], null); - if ($sensors === WSConstants::TOKEN_INVALID) { - return WSConstants::TOKEN_INVALID; - } else { - foreach ($sensors->models as $sensor) { - $sensorsUrisTypesLabels[] = - [ - self::SENSOR_DATA_URI => $sensor->uri, - self::SENSOR_DATA_LABEL => $sensor->label, - self::SENSOR_DATA_TYPE => $sensor->rdfType - ]; - } - } - return $sensorsUrisTypesLabels; - } - - /** - * - * @param type $sensorsUriTypesLabel - * @return array - */ - public function getSensorListToShowFromSensorList($sensorsUriTypesLabel) { - $sensorLabelListToShow = []; - foreach ($sensorsUriTypesLabel as $sensorUriTypesLabel) { - $sensorType = Vocabulary::prettyUri($sensorUriTypesLabel[self::SENSOR_DATA_TYPE]); - if (isset($sensorLabelListToShow[$sensorType])) { - $sensorLabelListToShow[$sensorType][$sensorUriTypesLabel[self::SENSOR_DATA_URI]] = $sensorUriTypesLabel[self::SENSOR_DATA_LABEL]; - } else { - $sensorLabelListToShow[$sensorType] = [ - $sensorUriTypesLabel[self::SENSOR_DATA_URI] => $sensorUriTypesLabel[self::SENSOR_DATA_LABEL] - ]; - } - } - return $sensorLabelListToShow; - } } diff --git a/models/yiiModels/YiiDataSensorModel.php b/models/yiiModels/YiiDataSensorModel.php deleted file mode 100644 index 486c4f18..00000000 --- a/models/yiiModels/YiiDataSensorModel.php +++ /dev/null @@ -1,37 +0,0 @@ - - */ -class YiiDataSensorModel extends YiiDatasetModel { - - /** - * - * @return array the rules of the attributes - */ - public function rules() { - $rules = parent::rules(); - $rules[] =[['provenanceSensingDevices'], 'required']; - return $rules; - } - -} diff --git a/models/yiiModels/YiiDatasetModel.php b/models/yiiModels/YiiDatasetModel.php index 23f02d62..e4121ca2 100755 --- a/models/yiiModels/YiiDatasetModel.php +++ b/models/yiiModels/YiiDatasetModel.php @@ -112,9 +112,8 @@ public function __construct($pageSize = null, $page = null) { */ public function rules() { return [ - [['variables', 'provenanceAlias', 'file', 'provenanceUri','experiment'], 'required'], - [['provenanceSensingDevices'], 'safe'], - [['provenanceAgents'], 'safe'], + [['provenanceAlias', 'file', 'provenanceUri','experiment'], 'required'], + [['variables','provenanceSensingDevices','provenanceAgents'], 'safe'], [['provenanceComment'], 'string'], [['experiment'], 'string'], [['provenanceUri', 'provenanceComment', 'documentsURIs', 'data', 'file'], 'safe'], diff --git a/views/dataset/_form.php b/views/dataset/_form.php index 6638b397..20c71692 100755 --- a/views/dataset/_form.php +++ b/views/dataset/_form.php @@ -25,11 +25,10 @@ /* @var $handsontable openSILEX\handsontablePHP\adapter\HandsontableSimple */ /* @var $handsontableErrorsCellsSettings string */ - if ($handsontable !== null) { - echo $handsontable->loadJSLibraries(true); - echo $handsontable->loadCSSLibraries(); - } - +if ($handsontable !== null) { + echo $handsontable->loadJSLibraries(true); + echo $handsontable->loadCSSLibraries(); +} ?>
@@ -38,127 +37,121 @@ session->getFlash('renderArray'); ?> -
-

Errors found in dataset :

-
    - exception->details; - } - } - - $errorMessages = array_unique($errorMessages); - foreach ($errorMessages as $errorMessage) { - echo '
  • ' . $errorMessage . '
  • '; - } - + if (isset($errors) && $errors !== null): ?> -
-
+
+

Errors found in dataset :

+
    + exception->details; + } + } + + $errorMessages = array_unique($errorMessages); + foreach ($errorMessages as $errorMessage) { + echo '
  • ' . $errorMessage . '
  • '; + } + ?> +
+
+endif; +?> + if (isset($handsontable) && $handsontable !== null): + ?>

Errors found in dataset

-
-
- +
+
+

Add dataset form

- - field($model, 'experiment')->widget(\kartik\select2\Select2::classname(),[ - 'data' => $this->params['experiments'], - 'options' => [ - 'placeholder' => Yii::t('app/messages', 'Select one experiment') . ' ...', - 'id' => 'experiment-selector', - 'multiple' => false - ], - 'pluginOptions' => [ - 'allowClear' => true, - 'tags' => true - ], - ]); ?> - - field($model, 'variables')->widget(\kartik\select2\Select2::classname(),[ - 'data' => $this->params['variables'], - 'options' => [ - 'placeholder' => Yii::t('app/messages', 'Select one or many variables') . ' ...', - 'id' => 'uriVariable-selector', - 'multiple' => true - ], - 'pluginOptions' => [ - 'allowClear' => true, - 'tags' => true - ], - ]); ?> + +

+ +field($model, 'experiment')->widget(\kartik\select2\Select2::classname(), [ + 'data' => $this->params['experiments'], + 'options' => [ + 'placeholder' => Yii::t('app/messages', 'Select one experiment') . ' ...', + 'id' => 'experiment-selector', + 'multiple' => false + ], + 'pluginOptions' => [ + 'allowClear' => true, + 'tags' => true + ], + 'pluginEvents' => [ + 'select2:select' => 'function(e) { populateVariableList(e.params.data.id); }', + ] +]); +?> + +
-

+

- field($model, 'provenanceUri')->widget(\kartik\select2\Select2::classname(),[ - 'data' => $provenancesArray, - 'options' => [ - 'placeholder' => Yii::t('app/messages', 'Select existing provenance or create a new one') . ' ...', - 'id' => 'provenance-selector', - 'multiple' => false - ], - 'pluginOptions' => [ - 'allowClear' => true, - 'tags' => true - ], - ]); ?> - - field($model, 'provenanceAgents')->widget(\kartik\select2\Select2::classname(),[ - 'data' => $this->params['agents'], - 'options' => [ - 'placeholder' => 'Select operator ...', - 'multiple' => true - ], - 'pluginOptions' => [ - 'allowClear' => true - ], - ]); ?> + field($model, 'provenanceUri')->widget(\kartik\select2\Select2::classname(), [ + 'data' => $provenancesArray, + 'options' => [ + 'placeholder' => Yii::t('app/messages', 'Select existing provenance or create a new one') . ' ...', + 'id' => 'provenance-selector', + 'multiple' => false + ], + 'pluginOptions' => [ + 'allowClear' => true, + 'tags' => true + ], + ]); + ?> + + field($model, 'provenanceAgents')->widget(\kartik\select2\Select2::classname(), [ + 'data' => $this->params['agents'], + 'options' => [ + 'placeholder' => 'Select operator ...', + 'multiple' => true + ], + 'pluginOptions' => [ + 'allowClear' => true + ], + ]); + ?> field($model, 'provenanceComment')->textarea(['rows' => 6]) ?> - +

- field($model, 'documentsURIs')->widget(MultipleInput::className(), [ - 'max' => 6, - 'allowEmptyList' => true, - 'enableGuessTitle' => true, + field($model, 'documentsURIs')->widget(MultipleInput::className(), [ + 'max' => 6, + 'allowEmptyList' => true, + 'enableGuessTitle' => true, 'columns' => [ [ 'name' => 'documentURI', 'options' => [ - 'readonly' => true, - 'style' => 'background-color:#C4DAE7;', - ] + 'readonly' => true, + 'style' => 'background-color:#C4DAE7;', + ] ] ], 'addButtonOptions' => [ @@ -233,58 +231,84 @@ ], ])->label(false) ?> + - - -
- - - +

+ Yii::t('app/messages', 'Select one or many variables') . ' ...', + 'id' => 'uriVariable-selector', + 'multiple' => true + ]; + ?> + + + field($model, 'variables')->widget(\kartik\select2\Select2::classname(), [ + 'data' => $this->params['variables'], + 'options' => $select2VariablesOptions, + 'pluginOptions' => [ + 'allowClear' => true, + 'tags' => true + ], + ]); + ?>

- params['csvSeparator'] == ";") { - $csvPath = "semicolon"; - } - ?> +params['csvSeparator'] == ";") { + $csvPath = "semicolon"; +} +?> " . Yii::t('app', 'Download Template'), \config::path()['basePath'] . 'documents/DatasetFiles/' . $csvPath . '/datasetTemplate.csv', ['id' => 'downloadDatasetTemplate']) ?> - " . Yii::t('app', 'Download Example'), \config::path()['basePath'] . 'documents/DatasetFiles/' . $csvPath . '/datasetExemple.csv') ?>

- field($model, 'file')->widget(FileInput::classname(), [ - 'options' => [ - 'maxFileSize' => 2000, - 'pluginOptions'=>['allowedFileExtensions'=>['csv'],'showUpload' => false], - ] - ]); - ?> + +
+
+ " . Yii::t('app', 'Download Example'), \config::path()['basePath'] . 'documents/DatasetFiles/' . $csvPath . '/datasetExemple.csv') ?> + +

+ +
+

+ +field($model, 'file')->widget(FileInput::classname(), [ + 'options' => [ + 'maxFileSize' => 2000, + 'pluginOptions' => ['allowedFileExtensions' => ['csv'], 'showUpload' => false], + ] +]); +?>
- 'btn btn-success']) ?> + 'btn btn-success']) ?>
- +
From 3dc258c209fe74dcacf8052f18ee80067178d7e1 Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Thu, 21 Nov 2019 08:50:58 +0100 Subject: [PATCH 14/35] Update view controller and Dataset --- controllers/DatasetController.php | 37 +----- models/yiiModels/YiiDatasetModel.php | 4 +- views/dataset/_form.php | 121 +++++++++++------- .../DatasetFiles/coma/datasetExemple.csv | 14 +- .../coma/datasetSensorExemple.csv | 1 - .../coma/datasetSensorTemplate.csv | 1 - .../DatasetFiles/coma/datasetTemplate.csv | 2 +- .../DatasetFiles/semicolon/datasetExemple.csv | 14 +- .../semicolon/datasetSensorExemple.csv | 8 -- .../semicolon/datasetSensorTemplate.csv | 1 - .../semicolon/datasetTemplate.csv | 2 +- 11 files changed, 94 insertions(+), 111 deletions(-) delete mode 100755 web/documents/DatasetFiles/coma/datasetSensorExemple.csv delete mode 100755 web/documents/DatasetFiles/coma/datasetSensorTemplate.csv delete mode 100755 web/documents/DatasetFiles/semicolon/datasetSensorExemple.csv delete mode 100755 web/documents/DatasetFiles/semicolon/datasetSensorTemplate.csv diff --git a/controllers/DatasetController.php b/controllers/DatasetController.php index ed6cb35f..e7c63216 100755 --- a/controllers/DatasetController.php +++ b/controllers/DatasetController.php @@ -52,11 +52,6 @@ class DatasetController extends Controller { const ERRORS_COLUMN = "Column"; const ERRORS_MESSAGE = "Message"; - const SENSORS_DATA = "sensors"; - const SENSOR_DATA_URI = "sensorUri"; - const SENSOR_DATA_LABEL = "sensorLabel"; - const SENSOR_DATA_TYPE = "sensorType"; - const PROVENANCE_PARAMS_VALUES = "provenanceNamespaces"; /** * define the behaviors @@ -143,30 +138,6 @@ public function actionGenerateAndDownloadDatasetCreationFile() { fclose($file); } - /** - * generate the csv file for the sensor dataset creation action. The csv file is - * generated with a column for each variable - * @param array variables list of the variables to add to the - * file uri => alias - * @return mixed - */ - public function actionGenerateAndDownloadDatasetSensorCreationFile() { - $fileColumns[] = DatasetController::DATE; - $variables = Yii::$app->request->post('variables'); - foreach ($variables as $variableAlias) { - $fileColumns[] = $variableAlias; - } - - $csvPath = "coma"; - if (Yii::$app->params['csvSeparator'] == ";") { - $csvPath = "semicolon"; - } - - $file = fopen('./documents/DatasetFiles/' . $csvPath . '/datasetSensorTemplate.csv', 'w'); - fputcsv($file, $fileColumns, $delimiter = Yii::$app->params['csvSeparator']); - fclose($file); - } - /** * * @param type $experimentUri @@ -407,7 +378,7 @@ public function actionCreate() { $experimentVariables = $this->getExperimentMesuredVariablesSelectList($datasetModel->experiment) ; $csvVariables = array_slice($csvHeaders, 2); // select all variables that don"t exist in experiment variables - $variablesNotInExperiment = array_diff($csvVariables, $experimentVariables); + $variablesNotInExperiment = array_diff($csvVariables, array_values($experimentVariables)); // Check CSV header with variables if (count($variablesNotInExperiment) === 0) { // Get selected or create Provenance URI @@ -456,7 +427,7 @@ public function actionCreate() { $row = str_getcsv($rowStr, Yii::$app->params['csvSeparator']); $scientifObjectAlias = $row[0]; if(!array_search($scientifObjectAlias, $objectUris)){ - $objectsErrors[] = $scientifObjectAlias . Yii::t("app/messages", " Object doesn't not exists in this experiment"); + $objectsErrors[] = $scientifObjectAlias . Yii::t("app/messages", " Object does not exists in this experiment"); $scientifObjectUri = null; }else{ $scientifObjectUri = array_search($scientifObjectAlias, $objectUris); @@ -466,7 +437,7 @@ public function actionCreate() { $values[] = [ "provenanceUri" => $provenanceUri, "objectUri" => $scientifObjectUri, - "variableUri" => array_search($givenVariables[$i - 2], $variables), + "variableUri" => array_search($csvVariables[$i - 2], $experimentVariables), "date" => $date, "value" => $row[$i] ]; @@ -520,7 +491,7 @@ public function actionCreate() { return $this->render('create', [ 'model' => $datasetModel, 'errors' => [ - Yii::t("app/messages", "CSV file headers does not match selected variables (" . implode(",", $variablesNotInExperiment) . ")") + Yii::t("app/messages", "CSV file headers does not match variables used in this experiment. The following Variables are not associated to this experiment " ) . "(" . implode(",", $variablesNotInExperiment) . ")" ] ]); } diff --git a/models/yiiModels/YiiDatasetModel.php b/models/yiiModels/YiiDatasetModel.php index e4121ca2..97f2f0f4 100755 --- a/models/yiiModels/YiiDatasetModel.php +++ b/models/yiiModels/YiiDatasetModel.php @@ -127,11 +127,11 @@ public function rules() { */ public function attributeLabels() { return [ - 'provenanceUri' => Yii::t('app', 'Provenance (URI)'), + 'provenanceUri' => Yii::t('app', 'Provenance label'), 'provenanceComment' => Yii::t('app', 'Provenance comment'), 'provenanceSensingDevices' => Yii::t('app', 'Sensor'), 'provenanceAgents' => Yii::t('app', 'Operator'), - 'variables' => Yii::t('app', 'Variable(s)'), + 'variables' => Yii::t('app', 'Experiment associated variable(s)'), 'file' => Yii::t('app', 'Data file'), 'documentsUris' => Yii::t('app', 'Documents'), 'experiment' => Yii::t('app', 'Experiment') diff --git a/views/dataset/_form.php b/views/dataset/_form.php index aa0d79f3..73b85d7a 100755 --- a/views/dataset/_form.php +++ b/views/dataset/_form.php @@ -101,15 +101,17 @@ ]); ?> - - -
+ +

+

+ +
diff --git a/web/documents/DatasetFiles/coma/datasetExemple.csv b/web/documents/DatasetFiles/coma/datasetExemple.csv index 0f00b05b..9c670954 100755 --- a/web/documents/DatasetFiles/coma/datasetExemple.csv +++ b/web/documents/DatasetFiles/coma/datasetExemple.csv @@ -1,8 +1,8 @@ -ScientificObjectURI,Date,trait-1_method-A_dimensionless-unit,trait-2_method-B_dimensionless-unit,trait-3_method-C_dimensionless-unit -http://www.phenome-fppn.fr/mtpvm/2019/o19000035,2019-09-12T15:51:00Z,2019-09-12,"red",-12 -http://www.phenome-fppn.fr/mtpvm/2019/o19000035,2019-09-13T12:51:00Z,2019-09-13,"red",13e12 -http://www.phenome-fppn.fr/mtpvm/2019/o19000035,2019-09-14T18:51:00Z,2019-09-14,"red",-0.000000000000000141 -http://www.phenome-fppn.fr/mtpvm/2019/o19000035,2019-09-15T10:51:00Z,2019-09-15,"blue",-0.15 -http://www.phenome-fppn.fr/mtpvm/2019/o19000035,2019-09-16T09:51:00Z,2019-09-16,"red",16 -http://www.phenome-fppn.fr/mtpvm/2019/o19000035,2019-09-17T08:51:30Z,2019-09-17,"blue",17 +ScientificObjectAlias,Date,trait-1_method-A_dimensionless-unit,trait-2_method-B_dimensionless-unit,trait-3_method-C_dimensionless-unit +7/DKC4590/XXXX/WW/1/DIA2017-05-19,2019-09-12T15:51:00Z,2019-09-12,"red",-12 +7/DKC4590/XXXX/WW/1/DIA2017-05-19,2019-09-13T12:51:00Z,2019-09-13,"red",13e12 +7/DKC4590/XXXX/WW/1/DIA2017-05-19,2019-09-14T18:51:00Z,2019-09-14,"red",-0.000000000000000141 +7/DKC4590/XXXX/WW/1/DIA2017-05-19,2019-09-15T10:51:00Z,2019-09-15,"blue",-0.15 +7/DKC4590/XXXX/WW/1/DIA2017-05-19,2019-09-16T09:51:00Z,2019-09-16,"red",16 +7/DKC4590/XXXX/WW/1/DIA2017-05-19,2019-09-17T08:51:30Z,2019-09-17,"blue",17 diff --git a/web/documents/DatasetFiles/coma/datasetSensorExemple.csv b/web/documents/DatasetFiles/coma/datasetSensorExemple.csv deleted file mode 100755 index 9a90a77c..00000000 --- a/web/documents/DatasetFiles/coma/datasetSensorExemple.csv +++ /dev/null @@ -1 +0,0 @@ -Date,GlobalRadiation_InstantGlobalRadiation_WattPerSquareMeter,WindSpeed_TenMinutesMaxWindSpeed_MeterPerSecond diff --git a/web/documents/DatasetFiles/coma/datasetSensorTemplate.csv b/web/documents/DatasetFiles/coma/datasetSensorTemplate.csv deleted file mode 100755 index 8b823655..00000000 --- a/web/documents/DatasetFiles/coma/datasetSensorTemplate.csv +++ /dev/null @@ -1 +0,0 @@ -Date,Variable diff --git a/web/documents/DatasetFiles/coma/datasetTemplate.csv b/web/documents/DatasetFiles/coma/datasetTemplate.csv index a84d9634..cee1bbd3 100755 --- a/web/documents/DatasetFiles/coma/datasetTemplate.csv +++ b/web/documents/DatasetFiles/coma/datasetTemplate.csv @@ -1 +1 @@ -ScientificObjectURI,Date,Value +ScientificObjectAlias,Date,Variable value diff --git a/web/documents/DatasetFiles/semicolon/datasetExemple.csv b/web/documents/DatasetFiles/semicolon/datasetExemple.csv index 00876924..1fe6a76e 100755 --- a/web/documents/DatasetFiles/semicolon/datasetExemple.csv +++ b/web/documents/DatasetFiles/semicolon/datasetExemple.csv @@ -1,8 +1,8 @@ -ScientificObjectURI;Date;trait-1_method-A_dimensionless-unit;trait-2_method-B_dimensionless-unit;trait-3_method-C_dimensionless-unit -http://www.phenome-fppn.fr/mtpvm/2019/o19000035;2019-09-12T15:51:00Z;2019-09-12;"red";-12 -http://www.phenome-fppn.fr/mtpvm/2019/o19000035;2019-09-13T12:51:00Z;2019-09-13;"red";13e12 -http://www.phenome-fppn.fr/mtpvm/2019/o19000035;2019-09-14T18:51:00Z;2019-09-14;"red";-0.000000000000000141 -http://www.phenome-fppn.fr/mtpvm/2019/o19000035;2019-09-15T10:51:00Z;2019-09-15;"blue";-0.15 -http://www.phenome-fppn.fr/mtpvm/2019/o19000035;2019-09-16T09:51:00Z;2019-09-16;"red";16 -http://www.phenome-fppn.fr/mtpvm/2019/o19000035;2019-09-17T08:51:30Z;2019-09-17;"blue";17 +ScientificObjectAlias;Date;trait-1_method-A_dimensionless-unit;trait-2_method-B_dimensionless-unit;trait-3_method-C_dimensionless-unit +7/DKC4590/XXXX/WW/1/DIA2017-05-19;2019-09-12T15:51:00Z;2019-09-12;"red";-12 +7/DKC4590/XXXX/WW/1/DIA2017-05-19;2019-09-13T12:51:00Z;2019-09-13;"red";13e12 +7/DKC4590/XXXX/WW/1/DIA2017-05-19;2019-09-14T18:51:00Z;2019-09-14;"red";-0.000000000000000141 +7/DKC4590/XXXX/WW/1/DIA2017-05-19;2019-09-15T10:51:00Z;2019-09-15;"blue";-0.15 +7/DKC4590/XXXX/WW/1/DIA2017-05-19;2019-09-16T09:51:00Z;2019-09-16;"red";16 +7/DKC4590/XXXX/WW/1/DIA2017-05-19;2019-09-17T08:51:30Z;2019-09-17;"blue";17 diff --git a/web/documents/DatasetFiles/semicolon/datasetSensorExemple.csv b/web/documents/DatasetFiles/semicolon/datasetSensorExemple.csv deleted file mode 100755 index d5701a87..00000000 --- a/web/documents/DatasetFiles/semicolon/datasetSensorExemple.csv +++ /dev/null @@ -1,8 +0,0 @@ -Date;trait-1_method-A_dimensionless-unit;trait-2_method-B_dimensionless-unit;trait-3_method-C_dimensionless-unit -2019-09-12T15:51:00Z;2019-09-12;"red";-12 -2019-09-13T12:51:00Z;2019-09-13;"red";13e12 -2019-09-14T18:51:00Z;2019-09-14;"red";-0.000000000000000141 -2019-09-15T10:51:00Z;2019-09-15;"blue";-0.15 -2019-09-16T09:51:00Z;2019-09-16;"red";16 -2019-09-17T08:51:30Z;2019-09-17;"blue";17 - diff --git a/web/documents/DatasetFiles/semicolon/datasetSensorTemplate.csv b/web/documents/DatasetFiles/semicolon/datasetSensorTemplate.csv deleted file mode 100755 index a9e4e9dd..00000000 --- a/web/documents/DatasetFiles/semicolon/datasetSensorTemplate.csv +++ /dev/null @@ -1 +0,0 @@ -Date;Value \ No newline at end of file diff --git a/web/documents/DatasetFiles/semicolon/datasetTemplate.csv b/web/documents/DatasetFiles/semicolon/datasetTemplate.csv index 1e17cded..2091cc97 100755 --- a/web/documents/DatasetFiles/semicolon/datasetTemplate.csv +++ b/web/documents/DatasetFiles/semicolon/datasetTemplate.csv @@ -1 +1 @@ -ScientificObjectURI;Date;Value +ScientificObjectAlias;Date;Variable value From 7ece67fdb621f885cee77ecbd7d99a82cfa35f25 Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Thu, 21 Nov 2019 09:00:34 +0100 Subject: [PATCH 15/35] Cleaning sensor code --- controllers/ActuatorController.php | 2 +- models/wsModels/WSSensorModel.php | 70 --------------------------- models/yiiModels/DeviceDataSearch.php | 30 +++--------- views/sensor/_view_sensor_graph.php | 19 +++----- 4 files changed, 15 insertions(+), 106 deletions(-) diff --git a/controllers/ActuatorController.php b/controllers/ActuatorController.php index 100758a7..abfa54c1 100644 --- a/controllers/ActuatorController.php +++ b/controllers/ActuatorController.php @@ -354,7 +354,7 @@ public function actionSearchData() { // Get data $sessionToken = Yii::$app->session['access_token']; - $actuatorGraphData = $searchModel->getSensorData($sessionToken); + $actuatorGraphData = $searchModel->getEnvironmentData($sessionToken); // Render data return $this->renderAjax('_view_actuator_graph', [ diff --git a/models/wsModels/WSSensorModel.php b/models/wsModels/WSSensorModel.php index 317764a3..99522b9d 100644 --- a/models/wsModels/WSSensorModel.php +++ b/models/wsModels/WSSensorModel.php @@ -118,74 +118,4 @@ public function putSensorVariables($sessionToken, $sensorUri, $variablesUri) { } } - /** - * Return the latest measured value for a variable and a sensor - * @param string $sessionToken - * @param string $provenanceUri - * @param string $variableUri - * @return mixed data or the error message - */ - public function getLastSensorVariableData($sessionToken,$variableUri, $sensorUri) { - // Define the parameter array - $params = [ - "pageSize" => 1, - "page" => 0, - "variable" => $variableUri, - "dateSortAsc" => "false" - ]; - $subService = "/" . urlencode($sensorUri) . "/data"; - // Send the request - $requestRes = $this->get($sessionToken, $subService, $params); - // Return the first result data or null - if (isset($requestRes->{WSConstants::RESULT}->{WSConstants::DATA})) { - if (count($requestRes->{WSConstants::RESULT}->{WSConstants::DATA}) > 0) { - return (array) $requestRes->{WSConstants::RESULT}->{WSConstants::DATA}[0]; - } else { - return null; - } - - } else { - return $requestRes; - } - } - - - /** - * Return the 80000 first measured variable corresponding to the given parameters - * @param string $sessionToken - * @param string $sensorUri - * @param string $variableUri - * @param \DateTime $startDate - * @param \DateTime $endDate - * @return mixed data or the error message - */ - public function getAllSensorData($sessionToken, $sensorUri, $variableUri, $startDate, $endDate) { - // Define the parameter array - $params = [ - "pageSize" => 80000, - "page" => 0, - "variable" => $variableUri, - ]; - $subService = "/" . urlencode($sensorUri) . "/data"; - - if ($startDate != null) { - $params["startDate"] = $startDate->format(WSDataModel::DATE_FORMAT); - } - - if ($endDate != null) { - $params["endDate"] = $endDate->format(WSDataModel::DATE_FORMAT); - } - - $params["dateSortAsc"] = "true"; - - // Send the request - $requestRes = $this->get($sessionToken, $subService, $params); - - // Return the result data - if (isset($requestRes->{WSConstants::RESULT}->{WSConstants::DATA})) { - return (array) $requestRes->{WSConstants::RESULT}->{WSConstants::DATA}; - } else { - return $requestRes; - } - } } \ No newline at end of file diff --git a/models/yiiModels/DeviceDataSearch.php b/models/yiiModels/DeviceDataSearch.php index 341cd04c..621b9583 100644 --- a/models/yiiModels/DeviceDataSearch.php +++ b/models/yiiModels/DeviceDataSearch.php @@ -94,23 +94,16 @@ public function attributeLabels() { * ] * ] */ - public function getSensorData($sessionToken) { - // Session provenance - $sessionProvenances = Yii::$app->session[self::SESSION_PROVENANCES]; - if(!isset($sessionProvenances)){ - $sessionProvenances = []; - } - // Create webservice instance - $wsData = new \app\models\wsModels\WSSensorModel(); - $wsProv = new \app\models\wsModels\WSProvenanceModel(); + public function getEnvironmentData($sessionToken) { + $ws = new WSEnvironmentModel(); // Define start and end time period $dateTimeStart = null; $dateTimeEnd = null; if ($this->dateStart == null && $this->dateEnd == null) { - $date = null; - $lastData = $wsData->getLastSensorVariableData($sessionToken, $this->variableURI, $this->sensorURI); + // If no dates are defined get the last data for this sensor and variable + $lastData = $ws->getLastSensorVariableData($sessionToken, $this->sensorURI, $this->variableURI); // If no dates are defined get the last data for this sensor and variable // Get the last date if exists @@ -118,7 +111,6 @@ public function getSensorData($sessionToken) { if ($lastData['date']) { $lastDate = $lastData["date"]; } - // If last date found, compute the latest week period if ($lastDate != null) { $dateTimeEnd = new \DateTime($lastDate); @@ -146,15 +138,8 @@ public function getSensorData($sessionToken) { } // Get all data - $data = $wsData->getAllSensorData($sessionToken, $this->sensorURI, $this->variableURI, $dateTimeStart, $dateTimeEnd); - // Get specific associated provenance - foreach ($data as $d){ - if(!isset($sessionProvenances[$d->provenanceUri])){ - $specificProvenancesData = $wsProv->getSpecificProvenancesByCriteria($sessionToken,['uri' => $d->provenanceUri] ); - $sessionProvenances[$d->provenanceUri] = $specificProvenancesData[0]; - $d->provenanceLabel = $specificProvenancesData[0]->label; - } - } + $data = $ws->getAllSensorData($sessionToken, $this->sensorURI, $this->variableURI, $dateTimeStart, $dateTimeEnd); + // Construct result $result = [ "graphName" => $this->graphName, @@ -162,8 +147,7 @@ public function getSensorData($sessionToken) { "sensorUri" => $this->sensorURI, "dateStart" => $dateTimeStart, "dateEnd" => $dateTimeEnd, - "data" => $data, - "provenances" => $sessionProvenances + "data" => $data ]; return $result; diff --git a/views/sensor/_view_sensor_graph.php b/views/sensor/_view_sensor_graph.php index 908b467d..73dbd926 100644 --- a/views/sensor/_view_sensor_graph.php +++ b/views/sensor/_view_sensor_graph.php @@ -24,27 +24,22 @@ * ] */ -$series = []; - -foreach( $sensorGraphData["provenances"] as $provenance) { - $series[$provenance->uri]= [ - "name" => $provenance->label, - "data" => [] - ]; -} +$serie = [ + "name" => $sensorGraphData["graphName"], + "data" => [] +]; //Create an array of data to store serie data by uri //array(1) { ["http://www.opensilex.org/sunagri/id/provenance/1572430583192"]=> array(2) { //["name"]=> string(25) "new provs agent + sensor2" ["data"]=> array(0) { } } } if (is_array($sensorGraphData['data'])) { foreach ($sensorGraphData['data'] as $data) { - $series[$data->provenanceUri]['data'][] = [(strtotime($data->date))*1000, $data->value ]; + $serie['data'][] = [(strtotime($data->date))*1000, $data->value ]; } - //format data - remove uri key - $series = array_values($series); // Display Hightchart widget echo Highcharts::widget([ + // Create a unique ID for each graph based on variable URI 'id' => base64_encode($sensorGraphData["variableUri"]), 'options' => [ @@ -63,7 +58,7 @@ 'tooltip' => [ 'xDateFormat' => '%Y-%m-%d %H:%M' ], - 'series' => $series, + 'series' => [$serie], ] ]); } From 20f2fa12edffc94650fceff91fa7d9ddd55b76db Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Thu, 21 Nov 2019 09:05:18 +0100 Subject: [PATCH 16/35] Clean sensor data --- controllers/SensorController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/controllers/SensorController.php b/controllers/SensorController.php index 67e3bba1..6ab2f88c 100644 --- a/controllers/SensorController.php +++ b/controllers/SensorController.php @@ -313,7 +313,7 @@ public function actionView($id) { //get sensor's linked documents $searchDocumentModel = new DocumentSearch(); $searchDocumentModel->concernedItemFilter = $id; - $documents = $searchDocumentModel->search(Yii::$app->session[WSConstants::ACCESS_TOKEN], ["concernedItem" => $id]); + $documents = $searchDocumentModel->search(Yii::$app->session['access_token'], ["concernedItem" => $id]); //3. get sensor annotations $searchAnnotationModel = new AnnotationSearch(); @@ -542,7 +542,7 @@ public function actionSearchData() { // Get data $sessionToken = Yii::$app->session[WSConstants::ACCESS_TOKEN]; - $sensorGraphData = $searchModel->getSensorData($sessionToken); + $sensorGraphData = $searchModel->getEnvironmentData($sessionToken); // Render data return $this->renderAjax('_view_sensor_graph', [ 'sensorGraphData' => $sensorGraphData From 1608775b9f19454ca997db0f92f9b0c2bcc63f5e Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Thu, 21 Nov 2019 09:09:17 +0100 Subject: [PATCH 17/35] Cleanning code --- controllers/SensorController.php | 1 + models/wsModels/WSSensorModel.php | 1 - models/yiiModels/DeviceDataSearch.php | 15 +++++++-------- views/sensor/_view_sensor_graph.php | 8 ++------ 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/controllers/SensorController.php b/controllers/SensorController.php index 6ab2f88c..15491d73 100644 --- a/controllers/SensorController.php +++ b/controllers/SensorController.php @@ -543,6 +543,7 @@ public function actionSearchData() { // Get data $sessionToken = Yii::$app->session[WSConstants::ACCESS_TOKEN]; $sensorGraphData = $searchModel->getEnvironmentData($sessionToken); + // Render data return $this->renderAjax('_view_sensor_graph', [ 'sensorGraphData' => $sensorGraphData diff --git a/models/wsModels/WSSensorModel.php b/models/wsModels/WSSensorModel.php index 99522b9d..ed50d656 100644 --- a/models/wsModels/WSSensorModel.php +++ b/models/wsModels/WSSensorModel.php @@ -117,5 +117,4 @@ public function putSensorVariables($sessionToken, $sensorUri, $variablesUri) { return $requestRes; } } - } \ No newline at end of file diff --git a/models/yiiModels/DeviceDataSearch.php b/models/yiiModels/DeviceDataSearch.php index 621b9583..f02cd208 100644 --- a/models/yiiModels/DeviceDataSearch.php +++ b/models/yiiModels/DeviceDataSearch.php @@ -10,6 +10,8 @@ namespace app\models\yiiModels; use Yii; +use \app\models\wsModels\WSEnvironmentModel; + /** * implements the search action for the sensor data @@ -46,11 +48,6 @@ class DeviceDataSearch extends \yii\base\Model { */ public $graphName; - /** - * Store provenance data to prevent multiple calls to WS - */ - const SESSION_PROVENANCES = 'store_provenances_infos'; - /** * @inheritdoc */ @@ -95,6 +92,7 @@ public function attributeLabels() { * ] */ public function getEnvironmentData($sessionToken) { + // Create webservice instance $ws = new WSEnvironmentModel(); // Define start and end time period @@ -104,6 +102,7 @@ public function getEnvironmentData($sessionToken) { if ($this->dateStart == null && $this->dateEnd == null) { // If no dates are defined get the last data for this sensor and variable $lastData = $ws->getLastSensorVariableData($sessionToken, $this->sensorURI, $this->variableURI); + // If no dates are defined get the last data for this sensor and variable // Get the last date if exists @@ -111,6 +110,7 @@ public function getEnvironmentData($sessionToken) { if ($lastData['date']) { $lastDate = $lastData["date"]; } + // If last date found, compute the latest week period if ($lastDate != null) { $dateTimeEnd = new \DateTime($lastDate); @@ -124,7 +124,6 @@ public function getEnvironmentData($sessionToken) { } else { return null; } - } else if ($this->dateStart == null) { // If only dateEnd is defined $dateTimeEnd = new \DateTime($this->dateEnd); @@ -136,10 +135,10 @@ public function getEnvironmentData($sessionToken) { $dateTimeStart = new \DateTime($this->dateStart); $dateTimeEnd = new \DateTime($this->dateEnd); } - + // Get all data $data = $ws->getAllSensorData($sessionToken, $this->sensorURI, $this->variableURI, $dateTimeStart, $dateTimeEnd); - + // Construct result $result = [ "graphName" => $this->graphName, diff --git a/views/sensor/_view_sensor_graph.php b/views/sensor/_view_sensor_graph.php index 73dbd926..a7037aa5 100644 --- a/views/sensor/_view_sensor_graph.php +++ b/views/sensor/_view_sensor_graph.php @@ -23,20 +23,16 @@ * ] * ] */ - $serie = [ "name" => $sensorGraphData["graphName"], "data" => [] ]; -//Create an array of data to store serie data by uri -//array(1) { ["http://www.opensilex.org/sunagri/id/provenance/1572430583192"]=> array(2) { -//["name"]=> string(25) "new provs agent + sensor2" ["data"]=> array(0) { } } } if (is_array($sensorGraphData['data'])) { foreach ($sensorGraphData['data'] as $data) { - $serie['data'][] = [(strtotime($data->date))*1000, $data->value ]; + $serie['data'][] = [(strtotime($data->date))*1000, $data->value ]; } - + // Display Hightchart widget echo Highcharts::widget([ From 671b9a73bfc3a7800fb5d70c3ccfd3f8f3bf7e9d Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Thu, 21 Nov 2019 09:13:45 +0100 Subject: [PATCH 18/35] Cleaning files --- controllers/SensorController.php | 1 - models/yiiModels/DeviceDataSearch.php | 9 +++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/controllers/SensorController.php b/controllers/SensorController.php index 15491d73..d5b781a8 100644 --- a/controllers/SensorController.php +++ b/controllers/SensorController.php @@ -33,7 +33,6 @@ * @update [Vincent Migot] 7 November, 2018: Add sensor/variables link * @update [Vincent Migot] 19 November, 2018: Add visualization of environmental data * @update [Andréas Garcia] 11 March, 2019: Add event widget - * @update [Arnaud Charleroy] 30 October, 2019: Add sensor data by data service * @author Morgane Vidal * @author Arnaud Charleroy */ diff --git a/models/yiiModels/DeviceDataSearch.php b/models/yiiModels/DeviceDataSearch.php index f02cd208..73809508 100644 --- a/models/yiiModels/DeviceDataSearch.php +++ b/models/yiiModels/DeviceDataSearch.php @@ -12,7 +12,6 @@ use Yii; use \app\models\wsModels\WSEnvironmentModel; - /** * implements the search action for the sensor data * @author Vincent Migot @@ -102,15 +101,13 @@ public function getEnvironmentData($sessionToken) { if ($this->dateStart == null && $this->dateEnd == null) { // If no dates are defined get the last data for this sensor and variable $lastData = $ws->getLastSensorVariableData($sessionToken, $this->sensorURI, $this->variableURI); - - // If no dates are defined get the last data for this sensor and variable - + // Get the last date if exists $lastDate = null; if ($lastData['date']) { $lastDate = $lastData["date"]; } - + // If last date found, compute the latest week period if ($lastDate != null) { $dateTimeEnd = new \DateTime($lastDate); @@ -151,4 +148,4 @@ public function getEnvironmentData($sessionToken) { return $result; } -} +} \ No newline at end of file From e6c6ef044780d3e062c3d900903c1cc8c9c3126d Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Thu, 21 Nov 2019 09:15:30 +0100 Subject: [PATCH 19/35] Remove new line --- models/yiiModels/DeviceDataSearch.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/yiiModels/DeviceDataSearch.php b/models/yiiModels/DeviceDataSearch.php index 73809508..04fceba6 100644 --- a/models/yiiModels/DeviceDataSearch.php +++ b/models/yiiModels/DeviceDataSearch.php @@ -148,4 +148,4 @@ public function getEnvironmentData($sessionToken) { return $result; } -} \ No newline at end of file +} From b30aea0b61589f277e72021dac545f18cc17588d Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Thu, 21 Nov 2019 13:19:52 +0100 Subject: [PATCH 20/35] Update dataset from view --- views/dataset/_form.php | 58 +++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/views/dataset/_form.php b/views/dataset/_form.php index 73b85d7a..0a2cec9d 100755 --- a/views/dataset/_form.php +++ b/views/dataset/_form.php @@ -18,6 +18,7 @@ use kartik\form\ActiveForm; use kartik\file\FileInput; use yii\helpers\Url; +use kartik\icons\Icon; /* @var $this yii\web\View */ /* @var $model app\models\YiiDatasetModel */ @@ -37,32 +38,33 @@ session->getFlash('renderArray'); ?> -
-

Errors found in dataset :

-
    - exception->details; - } - } - - $errorMessages = array_unique($errorMessages); - foreach ($errorMessages as $errorMessage) { - echo '
  • ' . $errorMessage . '
  • '; + if (isset($errors) && $errors !== null): + ?> +
    +

    Errors found in datasensor :

    +
      + exception->details; } - ?> -
    -
    + } + + $errorMessages = array_unique($errorMessages); + foreach ($errorMessages as $errorMessage) { + echo '
  • ' . $errorMessage . '
  • '; + } + + ?> +
+
+ endif; + ?> @@ -102,12 +104,8 @@ ?> -

-

- -
field($model, 'provenanceUri')->widget(\kartik\select2\Select2::classname(), [ @@ -233,98 +259,30 @@ ], ])->label(false) ?> + 'btn btn-success','onclick' => 'saveProvenance()']) ?> +
-

-
-
-
-

-

- Yii::t('app/messages', 'Select one or many experiment associated variables') . ' ...', - 'id' => 'uriVariable-selector', - 'multiple' => true - ]; - ?> - - field($model, 'variables')->widget(\kartik\select2\Select2::classname(), [ - 'data' => [], - 'options' => $select2VariablesOptions, - 'pluginOptions' => [ - 'allowClear' => true, - 'tags' => true - ], - ]); - ?> -

-params['csvSeparator'] == ";") { - $csvPath = "semicolon"; -} -?> - - " . Yii::t('app', 'Download generated template'), - \config::path()['basePath'] . 'documents/DatasetFiles/' . $csvPath . '/datasetTemplate.csv', - ['id' => 'downloadDatasetTemplate'] - ); - ?> - -

- -
-
- " . Yii::t('app', 'Download Example'), \config::path()['basePath'] . 'documents/DatasetFiles/' . $csvPath . '/datasetExemple.csv') ?> -
- -
-

-
+

+

-field($model, 'file')->widget(FileInput::classname(), [ - 'options' => [ - 'maxFileSize' => 2000, - 'pluginOptions' => ['allowedFileExtensions' => ['csv'], 'showUpload' => false], - ] -]); -?> + field($model, 'file')->widget(FileInput::classname(), [ + 'options' => [ + 'maxFileSize' => 2000, + 'pluginOptions' => ['allowedFileExtensions' => ['csv'], 'showUpload' => false], + ] + ]); + ?>
- 'btn btn-success']) ?> + 'btn btn-success']) ?> +
- -
+

+

@@ -263,7 +263,7 @@

+

diff --git a/views/dataset/create.php b/views/dataset/create.php index ba9d5592..6b79a8d5 100644 --- a/views/dataset/create.php +++ b/views/dataset/create.php @@ -19,7 +19,7 @@ /* @var $handsontable openSILEX\handsontablePHP\adapter\HandsontableSimple */ /* @var $handsontableErrorsCellsSettings string */ -$this->title = Yii::t('app', 'Add Dataset'); +$this->title = Yii::t('app', 'Add Dataset on scientific object'); //$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Dataset', ['n' => 2]), 'url' => ['index']]; $this->params['breadcrumbs'][] = $this->title; ?> diff --git a/web/documents/DatasetFiles/coma/datasetTemplate.csv b/web/documents/DatasetFiles/coma/datasetTemplate.csv index cee1bbd3..5ddeb877 100755 --- a/web/documents/DatasetFiles/coma/datasetTemplate.csv +++ b/web/documents/DatasetFiles/coma/datasetTemplate.csv @@ -1 +1 @@ -ScientificObjectAlias,Date,Variable value +ScientificObjectAlias,Date From be989cd48ece6166e455333e429260bde64d755b Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Mon, 2 Dec 2019 14:46:45 +0100 Subject: [PATCH 24/35] Update dataset with vue.js --- composer.json | 3 +- composer.lock | 116 +++- controllers/DatasetController.php | 35 +- models/wsModels/WSProvenanceModel.php | 4 +- views/dataset/_form.php | 781 +++++++++++++++----------- 5 files changed, 604 insertions(+), 335 deletions(-) diff --git a/composer.json b/composer.json index 8b4b565b..abee2773 100755 --- a/composer.json +++ b/composer.json @@ -40,7 +40,8 @@ "fortawesome/font-awesome": "v4.7.0", "opensilex/opencpu-client-php": "dev-master", "himiklab/yii2-handsontable-widget" : "v1.1.1", - "phayes/geophp": "1.2" + "phayes/geophp": "1.2", + "antkaz/yii2-vue": "^1.0" }, "require-dev": { "yiisoft/yii2-debug": "2.0.14", diff --git a/composer.lock b/composer.lock index 5b1dfd05..76d673e7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,9 +4,51 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a81ff6872bbd8b0fdf3f387ebc99092a", - "content-hash": "05c766297ee7a05e6c5a1c1b8da57159", + "content-hash": "c1a3ce2e444177eef1da5e0ce5a3cb00", "packages": [ + { + "name": "antkaz/yii2-vue", + "version": "v1.0", + "source": { + "type": "git", + "url": "https://github.com/antkaz/yii2-vue.git", + "reference": "ba341bdbcfffa96662f49fe83152a867191d3b72" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/antkaz/yii2-vue/zipball/ba341bdbcfffa96662f49fe83152a867191d3b72", + "reference": "ba341bdbcfffa96662f49fe83152a867191d3b72", + "shasum": "" + }, + "require": { + "npm-asset/vue": "~2.5.13", + "yiisoft/yii2": "~2.0.14" + }, + "type": "yii2-extension", + "autoload": { + "psr-4": { + "antkaz\\vue\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anton Kazarinov", + "email": "askazarinov@gmail.com" + } + ], + "description": "The Vue.js extension for the Yii framework", + "homepage": "https://github.com/antkaz/yii2-vue", + "keywords": [ + "Vue.js", + "vue", + "yii2" + ], + "time": "2018-03-01T19:37:33+00:00" + }, { "name": "borales/yii2-phone-input", "version": "0.1.2", @@ -2213,6 +2255,76 @@ ], "time": "2019-01-21T22:06:44+00:00" }, + { + "name": "npm-asset/vue", + "version": "2.5.22", + "dist": { + "type": "tar", + "url": "https://registry.npmjs.org/vue/-/vue-2.5.22.tgz", + "shasum": "3bf88041af08b8539c37b268b70ca79245e9cc30" + }, + "type": "npm-asset-library", + "extra": { + "npm-asset-bugs": { + "url": "https://github.com/vuejs/vue/issues" + }, + "npm-asset-main": "dist/vue.runtime.common.js", + "npm-asset-directories": [], + "npm-asset-repository": { + "type": "git", + "url": "git+https://github.com/vuejs/vue.git" + }, + "npm-asset-scripts": { + "dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev", + "dev:cjs": "rollup -w -c scripts/config.js --environment TARGET:web-runtime-cjs", + "dev:esm": "rollup -w -c scripts/config.js --environment TARGET:web-runtime-esm", + "dev:test": "karma start test/unit/karma.dev.config.js", + "dev:ssr": "rollup -w -c scripts/config.js --environment TARGET:web-server-renderer", + "dev:compiler": "rollup -w -c scripts/config.js --environment TARGET:web-compiler ", + "dev:weex": "rollup -w -c scripts/config.js --environment TARGET:weex-framework", + "dev:weex:factory": "rollup -w -c scripts/config.js --environment TARGET:weex-factory", + "dev:weex:compiler": "rollup -w -c scripts/config.js --environment TARGET:weex-compiler ", + "build": "node scripts/build.js", + "build:ssr": "npm run build -- web-runtime-cjs,web-server-renderer", + "build:weex": "npm run build -- weex", + "test": "npm run lint && flow check && npm run test:types && npm run test:cover && npm run test:e2e -- --env phantomjs && npm run test:ssr && npm run test:weex", + "test:unit": "karma start test/unit/karma.unit.config.js", + "test:cover": "karma start test/unit/karma.cover.config.js", + "test:e2e": "npm run build -- web-full-prod,web-server-basic-renderer && node test/e2e/runner.js", + "test:weex": "npm run build:weex && jasmine JASMINE_CONFIG_PATH=test/weex/jasmine.js", + "test:ssr": "npm run build:ssr && jasmine JASMINE_CONFIG_PATH=test/ssr/jasmine.js", + "test:sauce": "npm run sauce -- 0 && npm run sauce -- 1 && npm run sauce -- 2", + "test:types": "tsc -p ./types/test/tsconfig.json", + "lint": "eslint src scripts test", + "flow": "flow check", + "sauce": "karma start test/unit/karma.sauce.config.js", + "bench:ssr": "npm run build:ssr && node benchmarks/ssr/renderToString.js && node benchmarks/ssr/renderToStream.js", + "release": "bash scripts/release.sh", + "release:weex": "bash scripts/release-weex.sh", + "release:note": "node scripts/gen-release-note.js", + "commit": "git-cz" + }, + "npm-asset-config": { + "commitizen": { + "path": "./node_modules/cz-conventional-changelog" + } + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Evan You" + } + ], + "description": "Reactive, component-oriented view layer for modern web interfaces.", + "homepage": "https://github.com/vuejs/vue#readme", + "keywords": [ + "vue" + ], + "time": "2019-01-11T23:18:40+00:00" + }, { "name": "oomphinc/composer-installers-extender", "version": "v1.1.2", diff --git a/controllers/DatasetController.php b/controllers/DatasetController.php index 607fce7b..0344f95d 100755 --- a/controllers/DatasetController.php +++ b/controllers/DatasetController.php @@ -143,12 +143,16 @@ public function actionGenerateAndDownloadDatasetCreationFile() { * @param type $experimentUri */ public function actionCreateProvenanceFromDataset(){ - $token = Yii::$app->session[WSConstants::ACCESS_TOKEN]; Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; - $provenance = Yii::$app->request->post(); - - $provenanceService = new WSProvenanceModel(); + $data = Yii::$app->request->post(); + + $documents = []; + + $provenance = $data["provenance"]; + if(isset($data["documents"])){ + $documents = $data["documents"]; + } $provenanceUri = $this->createProvenance( $provenance['label'], $provenance['comment'], @@ -156,10 +160,23 @@ public function actionCreateProvenanceFromDataset(){ $provenance['agents'] ); + $this->linkDocumentsToProvenance($provenanceUri, $documents); + + if($provenanceUri != false){ + return $provenanceUri; + } + return false; + } + + public function actionGetProvenancesSelectList(){ + $token = Yii::$app->session[WSConstants::ACCESS_TOKEN]; + + Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; + $provenanceService = new WSProvenanceModel(); + + $provenances= []; $provenances = $this->mapProvenancesByUri($provenanceService->getAllProvenances($token)); - $result = []; - $provenancesArray =[]; - $result['newProvenanceUri'] = $provenanceUri; + foreach ($provenances as $uri => $provenance) { $provenancesArray[$uri] = $provenance->label . " (" . $uri . ")"; } @@ -499,9 +516,10 @@ public function actionCreate() { private function createProvenance($alias, $comment,$sensingDevice = null, $agent =null) { $provenanceService = new WSProvenanceModel(); $date = new \DateTime(); + $createdDate = $date->format("Y-m-d\TH:i:sO"); $metadata = [ "namespaces" => Yii::$app->params[self::PROVENANCE_PARAMS_VALUES], - "creationDate" => $date->format("Y-m-d\TH:i:sO"), + "created" => $date->format("Y-m-d\TH:i:sO"), "prov:Agent" =>[ "oeso:SensingDevice" => [ ], @@ -519,6 +537,7 @@ private function createProvenance($alias, $comment,$sensingDevice = null, $agent Yii::$app->session['access_token'], $alias, $comment, + $createdDate, $metadata ); diff --git a/models/wsModels/WSProvenanceModel.php b/models/wsModels/WSProvenanceModel.php index 5d06a79e..fafc413b 100644 --- a/models/wsModels/WSProvenanceModel.php +++ b/models/wsModels/WSProvenanceModel.php @@ -34,14 +34,16 @@ public function __construct() { * @param type $sessionToken * @param type $label * @param type $comment + * @param type $createdDate Description * @param type $metadata * @return type */ - public function createProvenance($sessionToken, $label, $comment, $metadata) { + public function createProvenance($sessionToken, $label, $comment,$createdDate, $metadata) { $subService = "/"; $provenance = $this->post($sessionToken, $subService, [[ "label" => $label, "comment" => $comment, + "created" => $createdDate, "metadata" => $metadata, ]]); diff --git a/views/dataset/_form.php b/views/dataset/_form.php index bfc0d1b6..604a1712 100644 --- a/views/dataset/_form.php +++ b/views/dataset/_form.php @@ -29,8 +29,214 @@ echo $handsontable->loadJSLibraries(true); echo $handsontable->loadCSSLibraries(); } +use antkaz\vue\VueAsset; +VueAsset::register($this); +$this->registerJsFile("https://rawgit.com/cristijora/vue-form-wizard/master/dist/vue-form-wizard.js"); +$this->registerCssFile("https://rawgit.com/cristijora/vue-form-wizard/master/dist/vue-form-wizard.min.css"); +$this->registerCssFile("https://rawgit.com/lykmapipo/themify-icons/master/css/themify-icons.css"); ?> + +
['enctype' => 'multipart/form-data']]); ?> @@ -82,38 +288,48 @@

Add dataset form

-

-

-
- field($model, 'experiment')->widget(\kartik\select2\Select2::classname(), [ - 'data' => $this->params['experiments'], - 'options' => [ - 'placeholder' => Yii::t('app/messages', 'Select one experiment') . ' ...', - 'id' => 'experiment-selector', - 'multiple' => false - ], - 'pluginOptions' => [ - 'allowClear' => true, - 'tags' => true - ], - 'pluginEvents' => [ - 'select2:select' => 'function(e) { populateVariableList(e.params.data.id); }', - ] - ]); - ?> -
- -

-
-
-
-

-

+
+
+
-
+
+ +
- + + + +
+ + +
\ No newline at end of file From 9aa0d1f2ab1d30d60cd7c9ec8da98de7db610d66 Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Mon, 2 Dec 2019 14:49:23 +0100 Subject: [PATCH 25/35] Move created date to provenance fu=ield --- controllers/DatasetController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/controllers/DatasetController.php b/controllers/DatasetController.php index 0344f95d..9ab2dcf4 100755 --- a/controllers/DatasetController.php +++ b/controllers/DatasetController.php @@ -519,7 +519,6 @@ private function createProvenance($alias, $comment,$sensingDevice = null, $agent $createdDate = $date->format("Y-m-d\TH:i:sO"); $metadata = [ "namespaces" => Yii::$app->params[self::PROVENANCE_PARAMS_VALUES], - "created" => $date->format("Y-m-d\TH:i:sO"), "prov:Agent" =>[ "oeso:SensingDevice" => [ ], From dfdd4ed515684b59742c2176aaceccf3ae787b05 Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Mon, 2 Dec 2019 18:19:51 +0100 Subject: [PATCH 26/35] Add vocabulary --- models/yiiModels/YiiDatasetModel.php | 4 +-- translations/fr/app.php | 20 +++++++++++-- translations/fr/messages.php | 1 + views/dataset/_form.php | 43 +++++++++++++++------------- 4 files changed, 44 insertions(+), 24 deletions(-) diff --git a/models/yiiModels/YiiDatasetModel.php b/models/yiiModels/YiiDatasetModel.php index 97f2f0f4..ab754348 100755 --- a/models/yiiModels/YiiDatasetModel.php +++ b/models/yiiModels/YiiDatasetModel.php @@ -129,8 +129,8 @@ public function attributeLabels() { return [ 'provenanceUri' => Yii::t('app', 'Provenance label'), 'provenanceComment' => Yii::t('app', 'Provenance comment'), - 'provenanceSensingDevices' => Yii::t('app', 'Sensor'), - 'provenanceAgents' => Yii::t('app', 'Operator'), + 'provenanceSensingDevices' => Yii::t('app', 'Provenance sensor(s)'), + 'provenanceAgents' => Yii::t('app', 'Provenance operator(s)'), 'variables' => Yii::t('app', 'Experiment associated variable(s)'), 'file' => Yii::t('app', 'Data file'), 'documentsUris' => Yii::t('app', 'Documents'), diff --git a/translations/fr/app.php b/translations/fr/app.php index 495e201a..aa8cecec 100755 --- a/translations/fr/app.php +++ b/translations/fr/app.php @@ -49,6 +49,7 @@ 'Add Dataset' => 'Importer un jeu de données', 'Add Document' => 'Ajouter un document', 'Add Document Script' => 'Ajouter un script', + 'Add on scientific object' => 'Importer pour un objet scientifique', 'Add row' => 'Ajouter une ligne', 'Add Sensors' => 'Ajouter des Capteurs', 'Add Vectors' => 'Ajouter des Vecteurs', @@ -66,6 +67,7 @@ 'Availability' => 'Disponibilité', // B + 'Back' => 'Retour', 'Back to sensor view' => 'Retour à la vue du capteur', 'Brand' => 'Marque', 'BRDF coefficient P1' => 'Coefficient BRDF P1', @@ -80,6 +82,7 @@ 'Characterize Sensor' => 'Caractériser un Capteur', 'Characterize' => 'Caractériser', 'Circular' => 'Circulaire', + 'Choose experiment' => 'Choisir une expérimentation' , 'Contact' => 'Contact', 'Contact / Help' => 'Contact / Aide', 'Column' => 'Colonne', @@ -96,6 +99,7 @@ 'Comment' => 'Commentaire', 'Creation Date' => 'Date de Création', 'Creator' => 'Auteur', + 'Create provenance' => 'Créer la provenance', 'Creator of the annotation' => 'Auteur de l\'annotation', 'Crop Species' => 'Espèce', @@ -105,12 +109,14 @@ 'Data Search'=>'Recherche de données', 'Dataset' => 'Jeux de données', 'Dataset Creation Date' => 'Données Insérées', + 'Dataset input file' => 'Fichier de jeu de données', 'Date' => 'Date', 'Date End' => 'Date de fin', 'Date Of Last Calibration' => 'Date de Dernier Étalonnage', 'Date Of Purchase' => 'Date d\'Achat', 'Date Start' => 'Date de début', 'Description' => 'Description', + 'Describe the produced dataset' => 'Décrire le jeu de données', 'Diameter' => 'Diamètre', 'Diameter (m)' => 'Diamètre (m)', 'Document Type' => 'Type du Document', @@ -130,6 +136,7 @@ 'Experimental Organization' => 'Organisation expérimentale', 'Experiment'=>'Expérimentation', 'Experiment Modalities' => 'Modalités Expérimentales', + 'Experiment associated variable(s)' => 'Variable(s) associées à l\'expérimentation', EventAction::EVENT_UNUPDATABLE_DUE_TO_UNUPDATABLE_PROPRTY_LABEL => "L'événement ne peut être mis à jour que via le web service car une de " . "ses propriétés spécifiques n'est actuellement pas compatible avec la webapp.", @@ -159,6 +166,8 @@ 'Generate Layer' => 'Générer la Couche', 'Generate Map' => 'Générer la Carte', 'Generated URI' => 'URI générée', + 'Generate dataset template' => 'Générer le gabarit du jeux de données', + 'Generate dataset template (Optional)' => 'Generer le gabarit du jeu de données (Optionnel)', 'Geographic Location' => 'Localisation géographique', 'Geometry' => 'Géométrie', 'Graphic visualization' => 'Visualisation graphique', @@ -210,6 +219,8 @@ // N 'Name' => 'Nom', + 'Need a dataset template ? (Optional)'=> 'Besoin d\'un gabarit jeu de données ? (Optionnel)', + 'Next' => 'Suivant', 'No' => 'Non', 'No item concerned' => 'Aucun élément concerné', 'No Specific Property' => 'Aucune Propriété Spécifique', @@ -236,7 +247,10 @@ 'Properties'=>'Propriétés', PropertyWidget::NO_PROPERTY_LABEL => 'Aucune propriété spécifique', 'Provenance comment' => 'Commentaire de la provenance', - 'Provenance (URI)' => 'Provenance (URI)', + 'Provenance (URI)' => 'Identifiant de la provenance', + 'Provenance label' => 'Label de la provenance', + 'Provenance operator(s)' => 'Opérateur(s) lié(s) à la provenance', + 'Provenance sensor(s)' => 'Capteur(s) lié(s) à la provenance', 'Public Access' => 'Accès Public', // Q @@ -302,7 +316,8 @@ 'Update event' => 'Modifier l\'événement', 'Update sensors' => 'Mise à jour des capteurs', 'Update measured variables' => 'Mise à jour des variables mesurées', - + 'Upload dataset' => 'Soumettre le jeu de données', + // V 'Value' => 'Valeur', 'Value Labels' => 'Labels de la Valeur', @@ -312,6 +327,7 @@ 'Variety' => 'Variété', 'Verification Code' => 'Code de vérification', 'View / Download' => 'Visualiser / Télécharger', + 'View' => 'Visualiser', // W 'Was Generated By' => 'Généré Par', diff --git a/translations/fr/messages.php b/translations/fr/messages.php index f73110c6..1599f842 100755 --- a/translations/fr/messages.php +++ b/translations/fr/messages.php @@ -119,6 +119,7 @@ 'The variety used in the plot (e.g. apache)' => 'La variété du plot (ex. apache)', 'To assign scientific objects to two experiments: (1) create the scientific objects on one of the experiments and (2) update them with the uri of the second experiment.' => 'Pour affecter des objets scientifiques à deux expériences: (1) créez les objets scientifiques sur l\'une des expériences et (2) mettez-les à jour avec l\'uri de la deuxième expérience.', 'to get more information about the columns content' => 'pour obtenir davantage d\'information sur le contenu de chaque colonne', + 'The variables associated to the choosen experiment' => 'Les variables associées à l\'expérimentation choisie', // U 'Unknown error' => 'Erreur inconnue', diff --git a/views/dataset/_form.php b/views/dataset/_form.php index 604a1712..7c9d758e 100644 --- a/views/dataset/_form.php +++ b/views/dataset/_form.php @@ -296,12 +296,12 @@ function updateProvenanceFields(uri) { @on-loading="setLoading" shape="square" color="#3498db" - back-button-text="" - next-button-text="" - finish-button-text="" + back-button-text="" + next-button-text="" + finish-button-text="" >
- -

-

+

Yii::t('app/messages', 'Select one or many experiment associated variables') . ' ...', + 'placeholder' => Yii::t('app/messages', 'Select one or more variables') . ' ...', 'id' => 'uriVariable-selector', 'multiple' => true ]; @@ -346,20 +346,20 @@ function updateProvenanceFields(uri) { ], ]); ?> -

- params['csvSeparator'] == ";") { - $csvPath = "semicolon"; - } - ?> - + +

+ params['csvSeparator'] == ";") { + $csvPath = "semicolon"; + } + ?> +


-
" . Yii::t('app', 'Download Example'), \config::path()['basePath'] . 'documents/DatasetFiles/' . $csvPath . '/datasetExemple.csv') ?>
" . Yii::t('app', 'Download generated template') . "", + Html::a("", \config::path()['basePath'] . 'documents/DatasetFiles/' . $csvPath . '/datasetTemplate.csv', ['id' => 'downloadDatasetTemplate'] ); ?>

-

@@ -452,10 +452,13 @@ function updateProvenanceFields(uri) { ], ])->label(false) ?> - 'btn btn-success','onclick' => 'saveProvenance()']) ?> +
+ 'btn btn-success','onclick' => 'saveProvenance()']) ?> +
+
-

From 5bee9c25834c979c5e0ec7800edac70396d4f2e0 Mon Sep 17 00:00:00 2001 From: Arnaud Charleroy Date: Mon, 2 Dec 2019 21:06:06 +0100 Subject: [PATCH 27/35] Update dataset --- controllers/DatasetController.php | 22 +- views/dataset/_form.php | 460 +++++++++++++++--------------- 2 files changed, 245 insertions(+), 237 deletions(-) diff --git a/controllers/DatasetController.php b/controllers/DatasetController.php index 9ab2dcf4..aaa1f65d 100755 --- a/controllers/DatasetController.php +++ b/controllers/DatasetController.php @@ -139,8 +139,11 @@ public function actionGenerateAndDownloadDatasetCreationFile() { /** - * - * @param type $experimentUri + * Create a provenance from post data with documents Uri associated + * [ + * provenance : { label, comment, metadata:{ ... } }, + * documents : { uri1,uri2} + * ] */ public function actionCreateProvenanceFromDataset(){ @@ -168,13 +171,17 @@ public function actionCreateProvenanceFromDataset(){ return false; } + /** + * Return an array with provenance list with all characteristics + * and provenance label mapped with provenance uri + * @return array + */ public function actionGetProvenancesSelectList(){ $token = Yii::$app->session[WSConstants::ACCESS_TOKEN]; Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $provenanceService = new WSProvenanceModel(); - $provenances= []; $provenances = $this->mapProvenancesByUri($provenanceService->getAllProvenances($token)); foreach ($provenances as $uri => $provenance) { @@ -186,8 +193,8 @@ public function actionGetProvenancesSelectList(){ } /** - * - * @param type $experimentUri + * Return an array of variable label mapped with variable uri + * @return array */ public function actionGetExperimentMesuredVariablesSelectList($experimentUri){ @@ -202,6 +209,11 @@ public function actionGetExperimentMesuredVariablesSelectList($experimentUri){ return($variables); } + /** + * Prepare a variable list associated to an experiment + * @param string $experimentUri + * @return array + */ private function getExperimentMesuredVariablesSelectList($experimentUri) { if(!isset($experimentUri) || empty($experimentUri)){ return []; diff --git a/views/dataset/_form.php b/views/dataset/_form.php index 7c9d758e..1a4419fa 100644 --- a/views/dataset/_form.php +++ b/views/dataset/_form.php @@ -217,6 +217,68 @@ function updateProvenanceFields(uri) { $("#already-linked-documents").empty(); } } + + /** + * + * @returns void */ + function refreshRules(){ + $(".dataset-variables").remove(); + if($("#uriVariable-selector :selected").length > 0){ + $("#uriVariable-selector :selected").each(function (i, sel) { + $('#dataset-csv-columns-desc').append( + '' + + '' + + $(sel).text() + ' *' + + '' + + '' + + ' ()' + + '' + + ''); + }); + }else{ + $('#dataset-csv-columns-desc').append( + '' + + 'Variable value *' + + ' ()' + + '' + + ''); + } + } + + function saveDocument(){ + // On save get document form values + var formData = new FormData(); + var file_data = $('#document-content #yiidocumentmodel-file').prop('files')[0]; + formData.append('file', file_data); + var other_data = $('form').serializeArray(); + $.each(other_data, function (key, input) { + formData.append(input.name, input.value); + }); + + // Send documents form + $.ajax({ + url: 'index.php?r=document%2Fcreate-from-dataset', + type: 'POST', + processData: false, + datatype: 'json', + contentType: false, + data: formData + + }) + .done(function (data) { + // Add document URI and close document add form + $('#yiidatasetmodel-documentsuris-documenturi-' + nbDocuments).val(data); + documentUploaded = true; + $('#document-modal').modal('toggle'); + + }) + .fail(function (jqXHR, textStatus) { + // Disaply errors + $('#document-save-msg').parent().removeClass('alert-info'); + $('#document-save-msg').parent().addClass('alert-danger'); + $('#document-save-msg').html('Request failed: ' + textStatus); + }); + }