diff --git a/components/widgets/AnnotationGridViewWidget.php b/components/widgets/AnnotationGridViewWidget.php index b83d3231..5aa8bb31 100644 --- a/components/widgets/AnnotationGridViewWidget.php +++ b/components/widgets/AnnotationGridViewWidget.php @@ -1,4 +1,5 @@ */ class AnnotationGridViewWidget extends Widget { @@ -25,7 +28,7 @@ class AnnotationGridViewWidget extends Widget { CONST ANNOTATIONS = "annotations"; CONST NO_LINKED_ANNOTATIONS = "No linked Annotation(s)"; CONST LINKED_ANNOTATIONS = "Linked Annotation(s)"; - + /** * Define the annotations list which will be showed * @var mixed @@ -50,47 +53,49 @@ public function run() { } else { $htmlRendered = "

" . Yii::t('app', self::LINKED_ANNOTATIONS) . "

"; $htmlRendered .= GridView::widget([ - 'dataProvider' => $this->annotations, - 'columns' => [ - [ - 'label' => Yii::t('app',YiiAnnotationModel::BODY_VALUES_LABEL), - 'attribute' => YiiAnnotationModel::BODY_VALUES, - 'value' => function ($model) { - return implode(("
"), $model->bodyValues); - }, - 'format' => 'raw', - ], - YiiAnnotationModel::CREATOR => - [ - 'label' => Yii::t('app',YiiAnnotationModel::CREATOR_LABEL), - 'attribute' => YiiAnnotationModel::CREATOR, - 'value' => function($model) { - return Vocabulary::prettyUri($model->creator); - }, - ], - YiiAnnotationModel::MOTIVATED_BY => - [ - 'label' => Yii::t('app',YiiAnnotationModel::MOTIVATED_BY_LABEL), - 'attribute' => YiiAnnotationModel::MOTIVATED_BY, - 'value' => function($model) { - return Vocabulary::prettyUri($model->motivatedBy); - } - ], - [ - 'label' => Yii::t('app',YiiAnnotationModel::CREATION_DATE_LABEL), - 'attribute' => YiiAnnotationModel::CREATION_DATE - ], - ['class' => 'yii\grid\ActionColumn', - 'template' => '{view}', - 'buttons' => [ - 'view' => function($url, $model, $key) { - return Html::a(Icon::show('eye-open', [], Icon::BSG), ['annotation/view', 'id' => $model->uri]); - }, - ] - ], - ], + 'dataProvider' => $this->annotations, + 'columns' => [ + [ + 'label' => Yii::t('app', YiiAnnotationModel::BODY_VALUES_LABEL), + 'attribute' => YiiAnnotationModel::BODY_VALUES, + 'value' => function ($model) { + return implode(("
"), $model->bodyValues); + }, + 'format' => 'raw', + ], + YiiAnnotationModel::CREATOR => + [ + 'label' => Yii::t('app', YiiAnnotationModel::CREATOR_LABEL), + 'attribute' => YiiAnnotationModel::CREATOR, + 'value' => function($model) { + return explode("agent/", $model->creator)[1]; + }, + ], + YiiAnnotationModel::MOTIVATED_BY => + [ + 'label' => Yii::t('app', YiiAnnotationModel::MOTIVATED_BY_LABEL), + 'attribute' => YiiAnnotationModel::MOTIVATED_BY, + 'value' => function($model) { + return explode("#", $model->motivatedBy)[1]; + } + ], + [ + 'label' => Yii::t('app', YiiAnnotationModel::CREATION_DATE_LABEL), + 'format' => ['date', 'php:Y-m-d H:i'], + 'attribute' => YiiAnnotationModel::CREATION_DATE + ], + ['class' => 'yii\grid\ActionColumn', + 'template' => '{view}', + 'buttons' => [ + 'view' => function($url, $model, $key) { + return Html::a(Icon::show('eye-open', [], Icon::BSG), ['annotation/view', 'id' => $model->uri]); + }, + ] + ], + ], ]); } return $htmlRendered; } + } diff --git a/components/widgets/PropertyWidgetWithActions.php b/components/widgets/PropertyWidgetWithActions.php index df5f424a..3e58ca60 100644 --- a/components/widgets/PropertyWidgetWithActions.php +++ b/components/widgets/PropertyWidgetWithActions.php @@ -19,4 +19,12 @@ * @author Andréas Garcia */ class PropertyWidgetWithActions extends PropertyWidget { + protected function renderValue($value): string { + + } + + protected function renderValues($values): string { + + } + } diff --git a/components/widgets/event/DetailEventGridViewWidget.php b/components/widgets/event/DetailEventGridViewWidget.php new file mode 100644 index 00000000..5a453b60 --- /dev/null +++ b/components/widgets/event/DetailEventGridViewWidget.php @@ -0,0 +1,111 @@ + + */ +class DetailEventGridViewWidget extends Widget { + + const EVENTS_LABEL = "Events"; + const NO_EVENT_LABEL = "No events"; + const EVENTS_ARE_NOT_SET_LABEL = "Events aren't set"; + const HTML_CLASS = "event-widget"; + + /** + * Defines the list of events to show. + * @var mixed + */ + public $dataProvider; + + const DATA_PROVIDER = "dataProvider"; + + public function init() { + parent::init(); + // must be not null + if ($this->dataProvider === null) { + throw new \Exception(self::EVENTS_ARE_NOT_SET_LABEL); + } + } + + /** + * Renders the list of the concerned items. + * @return string the HTML string rendered + */ + public function run() { + if ($this->dataProvider->getCount() == 0) { + $htmlRendered = "

" . Yii::t('app', self::NO_EVENT_LABEL) . "

"; + } else { + $htmlRendered = "

" . Yii::t('app', self::EVENTS_LABEL) . "

"; + $htmlRendered .= GridView::widget([ + 'dataProvider' => $this->dataProvider, + 'columns' => [ + [ + 'label' => Yii::t('app', 'Type'), + 'attribute' => YiiEventModel::TYPE, + 'value' => function ($model) { + return explode("#", $model->rdfType)[1]; + } + ], + [ + 'label' => Yii::t('app', YiiEventModel::ANNOTATIONS), + 'attribute' => YiiEventModel::ANNOTATIONS, + 'format' => 'html', + 'value' => function ($model) { + + $annotations = $model->annotations; + + $toReturn = ''; + $marginLeft = 0; + foreach ($annotations as $annotation) { + + $toReturn .= '
'; + foreach ($annotation['bodyValues'] as $i => $value) { + $toReturn .= $value . ' '; + } + $marginLeft += 10; + $toReturn .= '
'; + $toReturn .= date('d/m/Y H:i', strtotime($annotation['creationDate'])); + $toReturn .= '
'; + } + return $toReturn; + } + ], + [ + 'format' => ['date', 'php:d/m/Y H:i'], + 'attribute' => YiiEventModel::DATE + ], + [ + 'class' => 'yii\grid\ActionColumn', + 'template' => '{view}', + 'buttons' => [ + 'view' => function($url, $model, $key) { + return Html::a( + Icon::show('eye-open', [], Icon::BSG), ['event/view', 'id' => $model->uri]); + }, + ] + ], + ], + 'options' => ['class' => self::HTML_CLASS] + ]); + } + return $htmlRendered; + } + +} diff --git a/components/widgets/event/EventButtonWidget.php b/components/widgets/event/EventButtonWidget.php index 80ea914e..234a00cf 100644 --- a/components/widgets/event/EventButtonWidget.php +++ b/components/widgets/event/EventButtonWidget.php @@ -45,13 +45,16 @@ class EventButtonWidget extends Widget { const CONCERNED_ITEMS_URIS = "concernedItemsUris"; /** - * Defines the type of object which will be annotated. + * Defines to wich type of model the event will be create ( scientific object, vector, sensor..). * @var array */ public $type; const TYPE = "type"; + public $size=""; + + const SIZE="size"; /** * Renders the event button. * @return string the string rendered @@ -67,10 +70,10 @@ public function run() { EventController::PARAM_RETURN_URL => Url::current() ]; if (!$this->asLink) { - $linkLabel = Icon::show('flag', [], Icon::FA) . " " . Yii::t('app', self::ADD_EVENT_LABEL); + $linkLabel = Icon::show('flag', ['class'=>$this->size], Icon::FA) . " " . Yii::t('app', self::ADD_EVENT_LABEL); } else { - $linkLabel = ''; + $linkLabel =Icon::show('flag', ['class'=>$this->size], Icon::FA); } if(!isset($this->type)){ $linkAttributes = ['class' => 'btn btn-default']; diff --git a/components/widgets/event/EventGridViewWidget.php b/components/widgets/event/EventGridViewWidget.php index d9954bd7..bf74d383 100644 --- a/components/widgets/event/EventGridViewWidget.php +++ b/components/widgets/event/EventGridViewWidget.php @@ -59,7 +59,7 @@ public function run() { 'label' => Yii::t('app', YiiEventModel::TYPE), 'attribute' => YiiEventModel::TYPE, 'value' => function ($model) { - return Vocabulary::prettyUri($model->rdfType); + return explode("#", $model->rdfType)[1]; } ], [ diff --git a/config/params.php b/config/params.php index 96ffe266..85434f5f 100755 --- a/config/params.php +++ b/config/params.php @@ -142,11 +142,14 @@ 'labelView:side90','labelView:side120','labelView:side150','labelView:side180','labelView:side210', 'labelView:side240','labelView:side270','labelView:side300','labelView:side330', ], - ] + ], // // Image filters GENERIC // 'image.filter' => [ // 'metadata.position' => [ // 'label1:value1','label2:value2', 'label3:value3'], // ] + //Highcharts color + 'highchartsColor' =>["#7cb5ec", "#434348", "#90ed7d", "#f7a35c", "#8085e9", "#f15c80", "#e4d354", "#2b908f", + "#f45b5b", "#91e8e1", "#7cb5ec", "#434348", "#90ed7d", "#f7a35c", "#8085e9", "#f15c80", "#e4d354", "#2b908f", "#f45b5b", "#91e8e1"] ]; diff --git a/controllers/AnnotationController.php b/controllers/AnnotationController.php index 9c8f15ea..15ed6a5d 100644 --- a/controllers/AnnotationController.php +++ b/controllers/AnnotationController.php @@ -56,6 +56,7 @@ public function actionCreate($attributes = null) { $dataToSend[] = $annotationModel->attributesToArray(); // Send data $requestRes = $annotationModel->insert($sessionToken, $dataToSend); + if (is_string($requestRes) && $requestRes === \app\models\wsModels\WSConstants::TOKEN_INVALID) { // User must be connected return $this->redirect(Yii::$app->urlManager->createUrl("site/login")); } else { @@ -94,8 +95,7 @@ public function actionIndex() { // Load user instances list $userModel = new YiiUserModel(); $users = $userModel->getPersonsURIAndName(Yii::$app->session[\app\models\wsModels\WSConstants::ACCESS_TOKEN]); - - // Load once motivation instances list + // Load once motivation instances list $motivationInstances = $this->getMotivationInstances(); if (is_string($searchResult)) { if ($searchResult === \app\models\wsModels\WSConstants::TOKEN_INVALID) { diff --git a/controllers/EventController.php b/controllers/EventController.php index 07dc0baf..e3bc220c 100644 --- a/controllers/EventController.php +++ b/controllers/EventController.php @@ -1,4 +1,5 @@ */ -class EventController extends GenericController { - +class EventController extends GenericController { + const PARAM_ANNOTATIONS_DATA_PROVIDER = "paramAnnotations"; const PARAM_UPDATABLE = "paramUpdatable"; - const ANNOTATIONS_PAGE = "annotations-page"; const INFRASTRUCTURES_DATA = "infrastructures"; const INFRASTRUCTURES_DATA_URI = "infrastructureUri"; const INFRASTRUCTURES_DATA_LABEL = "infrastructureLabel"; const INFRASTRUCTURES_DATA_TYPE = "infrastructureType"; const EVENT_TYPES = "eventTypes"; - const SENSORS_DATA = "sensors"; const SENSOR_DATA_URI = "sensorUri"; const SENSOR_DATA_LABEL = "sensorLabel"; const SENSOR_DATA_TYPE = "sensorType"; - const PARAM_CONCERNED_ITEMS_URIS = 'concernedItemsUris'; const TYPE = 'type'; const PARAM_RETURN_URL = "returnUrl"; @@ -52,35 +52,77 @@ class EventController extends GenericController { * @var string */ public $returnUrl; - + /** * Lists the events. * @return mixed */ public function actionIndex() { $searchModel = new EventSearch(); - + $searchParams = Yii::$app->request->queryParams; - + if (isset($searchParams[WSConstants::PAGE])) { $searchParams[WSConstants::PAGE] = $searchParams[WSConstants::PAGE] - 1; } $searchParams[WSConstants::PAGE_SIZE] = Yii::$app->params['indexPageSize']; - + $searchResult = $searchModel->search(Yii::$app->session[WSConstants::ACCESS_TOKEN], $searchParams); - + if (is_string($searchResult)) { if ($searchResult === WSConstants::TOKEN_INVALID) { return $this->redirect(Yii::$app->urlManager->createUrl(SiteMessages::SITE_LOGIN_PAGE_ROUTE)); } else { return $this->render(SiteMessages::SITE_ERROR_PAGE_ROUTE, [ - SiteMessages::SITE_PAGE_NAME => SiteMessages::INTERNAL_ERROR, - SiteMessages::SITE_PAGE_MESSAGE => $searchResult]); + SiteMessages::SITE_PAGE_NAME => SiteMessages::INTERNAL_ERROR, + SiteMessages::SITE_PAGE_MESSAGE => $searchResult]); } } else { return $this->render('index', [ - 'searchModel' => $searchModel, - 'dataProvider' => $searchResult]); + 'searchModel' => $searchModel, + 'dataProvider' => $searchResult]); + } + } + + /** + * Return the detail of an event from an Ajax call. + * @param $id URI of the event + * @return mixed redirect in case of error otherwise return the "view" view + */ + public function actionAjaxView($id) { + // Get request parameters + $searchParams = Yii::$app->request->queryParams; + + // Get event + $event = (new YiiEventModel())->getEvent(Yii::$app->session[WSConstants::ACCESS_TOKEN], $id); + if (is_string($event)) { + if ($event === \app\models\wsModels\WSConstants::TOKEN_INVALID) { + return $this->redirect(Yii::$app->urlManager->createUrl("site/login")); + } else { + return $this->renderAjax('/site/error', [ + 'name' => Yii::t('app/messages', 'Internal error'), + 'message' => $event]); + } + } else { + + // Get documents + $searchDocumentModel = new DocumentSearch(); + $searchDocumentModel->concernedItemFilter = $id; + $documentProvider = $searchDocumentModel->search( + Yii::$app->session[WSConstants::ACCESS_TOKEN], [YiiEventModel::CONCERNED_ITEMS => $id]); + + // Get annotations + $annotationProvider = $event->getEventAnnotations(Yii::$app->session[WSConstants::ACCESS_TOKEN], $searchParams); + $annotationProvider->pagination->pageParam = self::ANNOTATIONS_PAGE; + + // Render the view of the event + + return $this->renderAjax('view', [ + 'model' => $event, + 'dataDocumentsProvider' => $documentProvider, + self::PARAM_ANNOTATIONS_DATA_PROVIDER => $annotationProvider, + self::PARAM_UPDATABLE => !$this->hasUnupdatableProperties($event) + ]); } } @@ -92,51 +134,56 @@ public function actionIndex() { public function actionView($id) { // Get request parameters $searchParams = Yii::$app->request->queryParams; - + // Get event $event = (new YiiEventModel())->getEvent(Yii::$app->session[WSConstants::ACCESS_TOKEN], $id); - - // Get documents - $searchDocumentModel = new DocumentSearch(); - $searchDocumentModel->concernedItemFilter = $id; - $documentProvider = $searchDocumentModel->search( - Yii::$app->session[WSConstants::ACCESS_TOKEN], - [YiiEventModel::CONCERNED_ITEMS => $id]); - - // Get annotations - $annotationProvider = $event->getEventAnnotations(Yii::$app->session[WSConstants::ACCESS_TOKEN], $searchParams); - $annotationProvider->pagination->pageParam = self::ANNOTATIONS_PAGE; - - // Render the view of the event - if (is_array($event) && isset($event[WSConstants::TOKEN_INVALID])) { - return redirectToLoginPage(); + if (is_string($event)) { + if ($event === \app\models\wsModels\WSConstants::TOKEN_INVALID) { + return $this->redirect(Yii::$app->urlManager->createUrl("site/login")); + } else { + return $this->render('/site/error', [ + 'name' => Yii::t('app/messages', 'Internal error'), + 'message' => $event]); + } } else { + + // Get documents + $searchDocumentModel = new DocumentSearch(); + $searchDocumentModel->concernedItemFilter = $id; + $documentProvider = $searchDocumentModel->search( + Yii::$app->session[WSConstants::ACCESS_TOKEN], [YiiEventModel::CONCERNED_ITEMS => $id]); + + // Get annotations + $annotationProvider = $event->getEventAnnotations(Yii::$app->session[WSConstants::ACCESS_TOKEN], $searchParams); + $annotationProvider->pagination->pageParam = self::ANNOTATIONS_PAGE; + + // Render the view of the event + return $this->render('view', [ - 'model' => $event, - 'dataDocumentsProvider' => $documentProvider, - self::PARAM_ANNOTATIONS_DATA_PROVIDER => $annotationProvider, - self::PARAM_UPDATABLE => !$this->hasUnupdatableProperties($event) + 'model' => $event, + 'dataDocumentsProvider' => $documentProvider, + self::PARAM_ANNOTATIONS_DATA_PROVIDER => $annotationProvider, + self::PARAM_UPDATABLE => !$this->hasUnupdatableProperties($event) ]); } } - - private function hasUnupdatableProperties($eventAction) : bool { - foreach($eventAction->properties as $property) { - if($property->relation !== Yii::$app->params['from'] - && $property->relation !== Yii::$app->params['to']) { + + private function hasUnupdatableProperties($eventAction): bool { + foreach ($eventAction->properties as $property) { + if ($property->relation !== Yii::$app->params['from'] && $property->relation !== Yii::$app->params['to']) { return true; } } return false; } - + /** * Gets the event types URIs. * @return event types URIs */ public function getSensorTypes() { $model = new \app\models\yiiModels\YiiSensorModel(); - + $sensorsTypes = []; $model->page = 0; $model->pageSize = Yii::$app->params['webServicePageSizeMax']; @@ -148,17 +195,17 @@ public function getSensorTypes() { $sensorsTypes[$sensorType->uri] = $sensorType->uri; } } - + return $sensorsTypes; } - + /** * Gets the event types URIs. * @return event types URIs */ public function getEventsTypes() { $model = new YiiEventModel(); - + $eventsTypes = []; $model->page = 0; $model->pageSize = Yii::$app->params['webServicePageSizeMax']; @@ -170,10 +217,10 @@ public function getEventsTypes() { $eventsTypes[$eventType->uri] = $eventType->uri; } } - + return $eventsTypes; } - + /** * Gets all infrastructures. * @return experiments @@ -187,18 +234,17 @@ public function getInfrastructuresUrisTypesLabels() { return WSConstants::TOKEN_INVALID; } else { foreach ($infrastructures->models as $infrastructure) { - $infrastructuresUrisTypesLabels[] = - [ - self::INFRASTRUCTURES_DATA_URI => $infrastructure->uri, - self::INFRASTRUCTURES_DATA_LABEL => $infrastructure->label, - self::INFRASTRUCTURES_DATA_TYPE => $infrastructure->rdfType - ]; + $infrastructuresUrisTypesLabels[] = [ + self::INFRASTRUCTURES_DATA_URI => $infrastructure->uri, + self::INFRASTRUCTURES_DATA_LABEL => $infrastructure->label, + self::INFRASTRUCTURES_DATA_TYPE => $infrastructure->rdfType + ]; } } - + return $infrastructuresUrisTypesLabels; } - + /** * Gets all sensors. * @return sensors @@ -213,18 +259,17 @@ public function getSensorsUrisTypesLabels() { 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 - ]; + $sensorsUrisTypesLabels[] = [ + self::SENSOR_DATA_URI => $sensor->uri, + self::SENSOR_DATA_LABEL => $sensor->label, + self::SENSOR_DATA_TYPE => $sensor->rdfType + ]; } } - + return $sensorsUrisTypesLabels; } - + /** * Displays the form to create an event or creates it in case of form submission. * @return mixed redirect in case of error or after successfully create @@ -234,21 +279,24 @@ public function actionCreate() { $sessionToken = Yii::$app->session[WSConstants::ACCESS_TOKEN]; $event = new EventCreation(); $event->isNewRecord = true; - // Display form if (!$event->load(Yii::$app->request->post())) { $event->load(Yii::$app->request->get(), ''); - if(Yii::$app->request->get()['type'] === "scientific-objects"){ - $event->load(array(self::PARAM_CONCERNED_ITEMS_URIS =>array_keys(Yii::$app->session['scientific-object'])),''); + if (Yii::$app->request->get()['type'] === "scientific-objects") { + $event->load(array(self::PARAM_CONCERNED_ITEMS_URIS => array_keys(Yii::$app->session['scientific-object'])), ''); + } + if (isset(Yii::$app->request->get()['dateWithoutTimezone'])) { + $validDate = explode(' ', Yii::$app->request->get()['dateWithoutTimezone'])[0]; + $event->dateWithoutTimezone = $validDate; } $event->creator = $this->getCreatorUri($sessionToken); $this->loadFormParams(); - return $this->render('create', ['model' => $event]); - - // Submit form - } else { - $dataToSend[] = $event->attributesToArray(); - $requestResults = $event->insert($sessionToken, $dataToSend); + return $this->render('create', ['model' => $event]); + + // Submit form + } else { + $dataToSend[] = $event->attributesToArray(); + $requestResults = $event->insert($sessionToken, $dataToSend); return $this->handlePostPutResponse($requestResults, $event->returnUrl); } } @@ -262,21 +310,21 @@ public function actionUpdate($id) { $sessionToken = Yii::$app->session[WSConstants::ACCESS_TOKEN]; $event = new EventUpdate(); $event->isNewRecord = false; - + // Display form if (!$event->load(Yii::$app->request->post())) { $event = $event->getEvent($sessionToken, $id); $this->loadFormParams(); - return $this->render('update', ['model' => $event]); - - // Submit form + return $this->render('update', ['model' => $event]); + + // Submit form } else { - $dataToSend[] = $event->attributesToArray(); - $requestResults = $event->update($sessionToken, $dataToSend); - return $this->handlePostPutResponse($requestResults, ['view', 'id' => $event->uri]); + $dataToSend[] = $event->attributesToArray(); + $requestResults = $event->update($sessionToken, $dataToSend); + return $this->handlePostPutResponse($requestResults, ['view', 'id' => $event->uri]); } } - + /** * Loads params used by the forms (creation or update). */ @@ -284,9 +332,8 @@ private function loadFormParams() { $this->view->params[self::EVENT_TYPES] = $this->getEventsTypes(); $this->view->params[self::INFRASTRUCTURES_DATA] = $this->getInfrastructuresUrisTypesLabels(); $this->view->params[self::SENSORS_DATA] = $this->getSensorsUrisTypesLabels(); - } - + /** * Gets the creator of an event. */ @@ -295,4 +342,5 @@ private function getCreatorUri($sessionToken) { $userModel->findByEmail($sessionToken, Yii::$app->session['email']); return $userModel->uri; } + } diff --git a/controllers/ImageController.php b/controllers/ImageController.php index 1a7690e4..1cdf0647 100755 --- a/controllers/ImageController.php +++ b/controllers/ImageController.php @@ -69,7 +69,7 @@ public function actionSearchFromLayer() { * @throws Exception */ public function actionSearchFromScientificObject() { - $searchModel = new DataFileSearch($pageSize = 100); + $searchModel = new DataFileSearch($pageSize = 8000); if ($searchModel->load(Yii::$app->request->post())) { $searchModel->startDate = Yii::$app->request->post()["startDate"]; $searchModel->endDate = Yii::$app->request->post()["endDate"]; @@ -77,11 +77,13 @@ public function actionSearchFromScientificObject() { $searchModel->jsonValueFilter = Yii::$app->request->post()["jsonValueFilter"]; $searchModel->provenance = Yii::$app->request->post()["provenance"]; $searchResult = $searchModel->search(Yii::$app->session['access_token'], Yii::$app->request->post()); - $imagesCount = Yii::$app->request->post()["imagesCount"]; + $imagesCount = Yii::$app->request->post()["imagesCount"]; return $this->renderAjax('_simple_images_visualization', [ 'model' => $searchModel, 'data' => $searchResult, - 'imagesCount' => $imagesCount + 'serieIndex' => Yii::$app->request->post()["serieIndex"], + 'pointIndex' => Yii::$app->request->post()["pointIndex"], + 'imagesCount' => $imagesCount ]); } return $this->renderAjax('_simple_images_visualization', [ diff --git a/controllers/ScientificObjectController.php b/controllers/ScientificObjectController.php index 8674ec4f..72a81c26 100755 --- a/controllers/ScientificObjectController.php +++ b/controllers/ScientificObjectController.php @@ -17,9 +17,15 @@ use Yii; use yii\web\Controller; use yii\filters\VerbFilter; +use yii\helpers\Url; use app\models\yiiModels\YiiScientificObjectModel; use app\models\yiiModels\ScientificObjectSearch; use app\models\yiiModels\YiiExperimentModel; +use app\models\yiiModels\DataFileSearch; +use app\models\yiiModels\EventSearch; +use app\models\yiiModels\AnnotationSearch; +use app\models\wsModels\WSConstants; +use app\components\helpers\SiteMessages; require_once '../config/config.php'; @@ -426,9 +432,9 @@ public function actionCreateMultipleScientificObjects() { $cpt = 0; $insertionResult = $scientificObjectModel->insert($sessionToken, $forWebService); - + $forWebService = []; - + if ($insertionResult->{\app\models\wsModels\WSConstants::METADATA}->status[0]->exception->type != "Error") { foreach ($insertionResult->{\app\models\wsModels\WSConstants::METADATA}->{\app\models\wsModels\WSConstants::DATA_FILES} as $scientificObjectUri) { $return["objectUris"][] = $scientificObjectUri; @@ -457,7 +463,7 @@ public function actionCreateMultipleScientificObjects() { private function getObjectTypeCompleteUri($objectType) { $objectTypesList = $this->getObjectsTypesUris(); foreach ($objectTypesList as $objectTypeUri) { - if (preg_match("/". $objectType . "\b/", $objectTypeUri)) { + if (preg_match("/" . $objectType . "\b/", $objectTypeUri)) { return $objectTypeUri; } } @@ -808,13 +814,13 @@ public function actionDownloadCsv() { } else { $wktGeometry = ""; } - - $stringToWrite .= $model->uri . Yii::$app->params['csvSeparator'] . - $model->label . Yii::$app->params['csvSeparator'] . - $model->rdfType . Yii::$app->params['csvSeparator'] . - $model->experiment . Yii::$app->params['csvSeparator'] . - '"' . $wktGeometry . '"' . Yii::$app->params['csvSeparator'] . - "\n"; + + $stringToWrite .= $model->uri . Yii::$app->params['csvSeparator'] . + $model->label . Yii::$app->params['csvSeparator'] . + $model->rdfType . Yii::$app->params['csvSeparator'] . + $model->experiment . Yii::$app->params['csvSeparator'] . + '"' . $wktGeometry . '"' . Yii::$app->params['csvSeparator'] . + "\n"; } $totalPage = intval($searchModel->totalPages); @@ -924,14 +930,23 @@ public function actionDataVisualization($uri, $label, $experimentUri = null) { //Get the list of the variables $variables = []; - - //If the experiment URI is empty, we get all the variables. - if (empty($experimentUri)) { + if (empty($experimentUri)) { //If the experiment URI is empty, we get all the variables. $variableModel = new \app\models\yiiModels\YiiVariableModel(); $variables = $variableModel->getInstancesDefinitionsUrisAndLabel($token); } else { //There is an experiment. Get the variables linked to the experiment. $experimentModel = new YiiExperimentModel(); - $variables = $experimentModel->getMeasuredVariables($token, $scientificObject->experiment); + $variablesSearch = $experimentModel->getMeasuredVariables($token, $scientificObject->experiment); + + if (is_string($variablesSearch)) { + if ($variablesSearch === WSConstants::TOKEN_INVALID) { + return $this->redirect(Yii::$app->urlManager->createUrl(SiteMessages::SITE_LOGIN_PAGE_ROUTE)); + } else { + return $this->render(SiteMessages::SITE_ERROR_PAGE_ROUTE, [ + SiteMessages::SITE_PAGE_NAME => SiteMessages::INTERNAL_ERROR, + SiteMessages::SITE_PAGE_MESSAGE => $variablesSearch]); + } + } + $variables = $experimentModel->variables; } // Load existing provenances @@ -944,47 +959,79 @@ public function actionDataVisualization($uri, $label, $experimentUri = null) { //Search data for the scientific object and the given variable. - if (isset($_POST['variable'])) { + if (isset($_GET['variable']) && !empty($_GET['variable'])) { $toReturn = []; - $searchModel = new \app\models\yiiModels\DataSearchLayers(); - $searchModel->pageSize = 80000; - $searchModel->object = $scientificObject->uri; - - $searchModel->variable = $_POST['variable']; - $searchModel->startDate = $_POST['dateStart']; - $searchModel->endDate = $_POST['dateEnd']; - $searchModel->provenance = $_POST['provenances']; - $searchResult = $searchModel->search($token, null); - /* Build array for highChart + /* Build array for highChart with data and photos by provenances * e.g : - * { - * "variable": "http:\/\/www.opensilex.org\/demo\/id\/variable\/v0000001", - * "scientificObjectData": [ - * "label": "Scientific object label", - * "dataFromProvenance": [ - * "provenance":"Data provenance uri", - * "data": ["1,874809","2015-02-10"], - * ["2,313261","2015-03-15"],.. - * ] - * ] + * {"ProvenanceUri1": { + * "data" :[["1500768000000","1,874809"],..], + * "photos":[ + * [{ + * "url":"", + * "date":"", + * "position":""}], + * [{ + * "url":"", + * "date":"", + * "position":""}],... + * + * + * "ProvenanceUri2": { + * "data" :[["1496793600000","2,313261"],..], + * "photos":[ + * [{ + * "url":"", + * "date":"", + * "position":""}], + * [{ * } */ $data = []; - $scientificObjectData["label"] = $label; + /* Step 1: Raw data : data from the data W.S. + * e.g : + * [{ + * "provenanceUri": "http://www.opensilex.org/demo/id/provenance/1563795626162", + * "date":"1500768000000", + * "value":"1,874809" + * }],[{ + * "provenanceUri": "http://www.opensilex.org/demo/id/provenance/1563795626162", + * "date":"1501112228000", + * "value":"1,845209" + * }],[{ + * "provenanceUri": "http://www.opensilex.org/demo/id/provenance/1563795500410", + * "date":"1496793600000", + * "value":"2,313261" + * }],[..... + */ + $searchModel = new \app\models\yiiModels\DataSearchLayers(); + $searchModel->pageSize = 80000; + $searchModel->object = $scientificObject->uri; + + $searchModel->variable = $_GET['variable']; + $searchModel->startDate = $_GET['dateStart']; + $searchModel->endDate = $_GET['dateEnd']; + $searchModel->provenance = $_GET['provenances']; + $searchModel->dateSortAsc = 'true'; //FIX HIGHCHARTS WHEN FLAGS IS ATTACHED TO A SERIE + $searchResult = $searchModel->search($token, null); foreach ($searchResult->getModels() as $model) { if (!empty($model->value)) { $dataToSave = null; - $provenanceLabel = $provenances[$model->provenanceUri]->label; - $dataToSave["provenanceUri"] = $provenanceLabel . " (prov:" . explode("id/provenance/", $model->provenanceUri)[1] . ")"; + $dataToSave["provenanceUri"] = $model->provenanceUri; $dataToSave["date"] = (strtotime($model->date)) * 1000; $dataToSave["value"] = doubleval($model->value); $data[] = $dataToSave; } } - // Transform to map based to the provenance value $dataByProvenance = array(); + /* Step 2: Transformed Raw data + * e.g : + * { + * "ProvenanceUri1":[["1498262400000","1,874809"],[],..] + * "ProvenanceUri2":[["1496793600000","2,313261"],..], + * } + */ foreach ($data as $dataEl) { $dataByProvenanceToSave = null; $dataByProvenanceToSave[] = $dataEl['date']; @@ -992,38 +1039,159 @@ public function actionDataVisualization($uri, $label, $experimentUri = null) { $dataByProvenance[$dataEl['provenanceUri']][] = $dataByProvenanceToSave; } - if (!empty($data)) { - $toReturn["variable"] = $searchModel->variable; - $scientificObjectData["dataFromProvenance"] = $dataByProvenance; - $toReturn["scientificObjectData"][] = $scientificObjectData; - } + /* Step 3: Add photos serie to each provenance or null + * e.g : + * {"ProvenanceUri1": { + * "data" :[["1500768000000","1,874809"],..], + * "photosSerie":[ + * [{ + * "date":"1500768000000", + * "photos": [[url,filtre],[],[],....] }], + * [{ + * "date":"1404896300000", + * "photos": [[url,filtre],[],[],....] }],.., + * ] + * }, + * "ProvenanceUri2": { + * "data" :[["1500768000000","2,313261"],..], + * "photosSerie": ...... + * } + */ + $isPhotos = false; + if (isset($_GET['show']) && isset($_GET['imageType'])) { + + if (isset($_GET['filter']) && $_GET['filter'] !== "") { + $selectedPositionIndex = $_GET['filter']; + $attribut = explode(":", Yii::$app->params['image.filter']['metadata.position'][$selectedPositionIndex]); + $filterToSend = "{'metadata." . $attribut[0] . "':'" . $attribut[1] . "'}"; + } + + $photosArray = null; + $photosArray = $this->searchImagesByObject($scientificObject->uri, $_GET['imageType'], $filterToSend ? $filterToSend : null, $_GET['dateStart'], $_GET['dateEnd']); + if (isset($photosArray) && !$isPhotos) { + $isPhotos = true; + } + + foreach ($dataByProvenance as $dataFromProvenanceKey => $dataFromProvenanceValue) { + + $toReturn[$dataFromProvenanceKey] = [ + 'data' => $dataFromProvenanceValue, + 'photosSerie' => $photosArray, + ]; + } + } else { + foreach ($dataByProvenance as $dataFromProvenanceKey => $dataFromProvenanceValue) { + + $toReturn[$dataFromProvenanceKey] = [ + 'data' => $dataFromProvenanceValue, + 'photosSerie' => null, + ]; + } + } + //Get the events associate to the sci. obj. to put on the Highcharts Graph + $searchModel = new EventSearch(); + $searchModel->pageSize = 800; + $searchModel->searchConcernedItemUri = $uri; + $searchModel->searchDateRangeStart = $_GET['dateStart']; + $searchModel->searchDateRangeEnd = $_GET['dateEnd']; + //$searchModel->dateSortAsc = 'true'; + $searchResult = $searchModel->search($token, null); + if (is_string($searchResult)) { + if ($searchResult === WSConstants::TOKEN_INVALID) { + return $this->redirect(Yii::$app->urlManager->createUrl(SiteMessages::SITE_LOGIN_PAGE_ROUTE)); + } else { + return $this->render(SiteMessages::SITE_ERROR_PAGE_ROUTE, [ + SiteMessages::SITE_PAGE_NAME => SiteMessages::INTERNAL_ERROR, + SiteMessages::SITE_PAGE_MESSAGE => $searchResult]); + } + } else { + foreach ($searchResult->getModels() as $model) { + + $annotationObjects = $searchModel->getAnnotations($token, ["uri" => $model->uri]); + $annotations = array(); + foreach ($annotationObjects as $annotationObject) { + $annotations[] = [ + "creationDate" => $annotationObject->creationDate, + "bodyValues" => $annotationObject->bodyValues + ]; + } + uasort($annotations, function($item1, $item2) { + return strtotime($item1['creationDate']) > strtotime($item2['creationDate']); + }); + + $events[] = [ + 'date' => (strtotime($model->date)) * 1000, + 'title' => explode('#', $model->rdfType)[1], + 'annotations' => $annotations + ]; + } + } + $eventsByTitle = $this->group_by('title', $events); + $eventCategories = array_keys($eventsByTitle); + $highchartsColorArray = Yii::$app->params['highchartsColor']; + $i = 0; + foreach ($eventCategories as $categorie) { + $colorByEventCategorie[$categorie] = $highchartsColorArray[$i]; + $i++; + } - //on FORM submitted: - //check if image visualization is activated - $show = isset($_POST['show']) ? $_POST['show'] : null; - $selectedVariable = isset($_POST['variable']) ? $_POST['variable'] : null; - $imageTypeSelected = isset($_POST['imageType']) ? $_POST['imageType'] : null; - $selectedProvenance = isset($_POST['provenances']) ? $_POST['provenances'] : null; - if (isset($_POST['filter']) && $_POST['filter'] !== "") { - $selectedPositionIndex = $_POST['filter']; - $attribut=explode(":",Yii::$app->params['image.filter']['metadata.position'][$selectedPositionIndex]); - $filterToSend = "{'metadata." . $attribut[0] . "':'" . $attribut[1] . "'}"; + //info of the variable + if (!empty($experimentUri)) { + $variableModel = new \app\models\yiiModels\YiiVariableModel(); + } + $variableModel->findByURI($token, $_GET['variable']); + + $variableInfo = [ + 'label' => $variableModel->label, + 'comment' => $variableModel->comment + ]; + + $searchParams = Yii::$app->request->queryParams; + + + // Get events associated to the table widget + $searchEventModel = new EventSearch(); + $searchEventModel->searchConcernedItemUri = $uri; + $eventSearchParameters = []; + if (isset($searchParams[WSConstants::EVENT_WIDGET_PAGE])) { + $eventSearchParameters[WSConstants::PAGE] = $searchParams[WSConstants::EVENT_WIDGET_PAGE] - 1; + } + $eventSearchParameters[WSConstants::PAGE_SIZE] = Yii::$app->params['eventWidgetPageSize']; + $eventsProvider = $searchEventModel->searchWithAnnotationsDescription($token, $eventSearchParameters); + $eventsProvider->pagination->pageParam = WSConstants::EVENT_WIDGET_PAGE; // multiple gridview pagination + + + // Get annotations associated to the table widget + $searchAnnotationModel = new AnnotationSearch(); + $annotationSearchParameters = []; + if (isset($searchParams[WSConstants::ANNOTATION_WIDGET_PAGE])) { + $annotationSearchParameters[WSConstants::PAGE] = $searchParams[WSConstants::ANNOTATION_WIDGET_PAGE] - 1; } + $searchAnnotationModel->targets[0] = $uri; + $annotationSearchParameters[WSConstants::PAGE_SIZE] = Yii::$app->params['annotationWidgetPageSize']; + $annotationsProvider = $searchAnnotationModel->search($token, $annotationSearchParameters); + $annotationsProvider->pagination->pageParam = WSConstants::ANNOTATION_WIDGET_PAGE; // multiple gridview pagination + return $this->render('data_visualization', [ 'model' => $scientificObject, 'variables' => $variables, 'data' => $toReturn, - 'show' => $show, - 'dateStart' => $searchModel->startDate, - 'dateEnd' => $searchModel->endDate, - 'selectedVariable' => $selectedVariable, - 'imageTypeSelected' => $imageTypeSelected, - 'selectedProvenance' => $selectedProvenance, + 'show' => $_GET['show'], + 'isPhotos' => $isPhotos, + 'dateStart' => $_GET['dateStart'], + 'dateEnd' => $_GET['dateEnd'], + 'selectedVariable' => $_GET['variable'], + 'imageTypeSelected' => $_GET['imageType'], + 'selectedProvenance' => $_GET['provenances'], 'selectedPosition' => $selectedPositionIndex, // seems that select widget use index when they are selectable number values 'filterToSend' => $filterToSend, - 'test' => $selectedPosition, + 'events' => $events, + 'colorByEventCategorie' => $colorByEventCategorie, + 'variableInfo' => $variableInfo, + 'annotationsProvider' => $annotationsProvider, + 'eventsProvider' => $eventsProvider, ]); } else { //If there is no variable given, just redirect to the visualization page. return $this->render('data_visualization', [ @@ -1033,6 +1201,100 @@ public function actionDataVisualization($uri, $label, $experimentUri = null) { } } + /** + * Function that split the sentence from the annotation body to show, on the highcharts serie, on hover in the tooltip. + * + * @param {String} $longString the sentence to split + * @param {String} $maxLineLength the length of the cut + * @return {Array} array of short sentences + */ + public function splitLongueSentence($longString, $maxLineLength) { + + $words = explode(' ', $longString); + $currentLength = 0; + $index = 0; + foreach ($words as $word) { + // +1 because the word will receive back the space in the end that it loses in explode() + $wordLength = strlen($word) + 1; + if (($currentLength + $wordLength) <= $maxLineLength) { + $output[$index] .= $word . ' '; + $currentLength += $wordLength; + } else { + $index += 1; + $currentLength = $wordLength; + $output[$index] = $word; + } + } + return $output; + } + + /** + * Create an associative array of imagesUri[]/date from an scientific object for a specified object + * [ + { + "date":"1500768000000", + "photos": [[url,filtre],[],[],....] }, + { + "date":"1404896300000", + "photos": [[url,filtre],[],[],....] },.., + * ] + * @param type $objectUri + * @param type $rdfType + * @param type $filter + * @param type $date + * @return associative array + */ + private function searchImagesByObject($objectUri, $rdfType, $filter, $startDate, $endDate) { + + $searchImagesModel = new DataFileSearch($pageSize = 8000); + $searchImagesModel->rdfType = $rdfType; + $searchImagesModel->startDate = $startDate; + $searchImagesModel->endDate = $endDate; + $searchImagesModel->concernedItems = [$objectUri]; + $searchImagesModel->jsonValueFilter = $filter; + $searchResult = $searchImagesModel->search(Yii::$app->session['access_token'], null); + foreach ($searchResult->getModels() as $image) { + $images[] = [ + 'url' => Url::to(['image/get', 'imageUri' => urlencode($image->uri)]), + 'date' => (strtotime($image->date)) * 1000, + 'position' => $image->metadata->position + ]; + } + /* Transformed Raw data + * e.g : + * { + * "Date1":[["url1","1"],["url2","2"],..] + * "Date2":.... + * } + */ + foreach ($images as $imagesEl) { + $imagesByDateToSave = null; + $imagesByDateToSave[] = $imagesEl['url']; + $imagesByDateToSave[] = $imagesEl['position']; + $imagesByDate[$imagesEl['date']][] = $imagesByDateToSave; + } + return $imagesByDate; + } + + /** + * Function that groups an array of associative arrays by some key. + * + * @param {String} $key Property to sort by. + * @param {Array} $data Array that stores multiple associative arrays. + */ + function group_by($key, $array) { + + $result = array(); + foreach ($array as $val) { + if (array_key_exists($key, $val)) { + $result[$val[$key]][] = $val; + } else { + $result[""][] = $val; + } + } + return $result; + } + /** * Create an associative array of the provenances objects indexed by their URI * @param type $provenances diff --git a/models/yiiModels/AnnotationSearch.php b/models/yiiModels/AnnotationSearch.php index f2d57b5e..f7be3dcc 100644 --- a/models/yiiModels/AnnotationSearch.php +++ b/models/yiiModels/AnnotationSearch.php @@ -1,4 +1,5 @@ */ class AnnotationSearch extends YiiAnnotationModel { const DESCRIPTION = "description"; - + public function __construct($pageSize = null, $page = null) { - parent::__construct($pageSize,$page); - $this->creationDate = null; + parent::__construct($pageSize, $page); + $this->creationDate = null; } /** @@ -43,26 +45,33 @@ public function rules() { */ public function search($sessionToken, $params) { //1. load the searched params + $this->load($params); if (isset($params[YiiModelsConstants::PAGE])) { $this->page = $params[YiiModelsConstants::PAGE]; } - + + if (isset($params[YiiModelsConstants::PAGE_SIZE])) { + $this->pageSize = $params[YiiModelsConstants::PAGE_SIZE]; + } + + //2. Check validity of search data if (!$this->validate()) { return new \yii\data\ArrayDataProvider(); } - //3. Request to the web service and return result $findResult = $this->find($sessionToken, $this->attributesToArray()); - + if (is_string($findResult)) { return $findResult; - } else if (isset($findResult->{'metadata'}->{'status'}[0]->{'exception'}->{'details'}) - && $findResult->{'metadata'}->{'status'}[0]->{'exception'}->{'details'} === \app\models\wsModels\WSConstants::TOKEN_INVALID) { + } else if (isset($findResult->{'metadata'}->{'status'}[0]->{'exception'}->{'details'}) && $findResult->{'metadata'}->{'status'}[0]->{'exception'}->{'details'} === \app\models\wsModels\WSConstants::TOKEN_INVALID) { return \app\models\wsModels\WSConstants::TOKEN_INVALID; } else { $resultSet = $this->jsonListOfArraysToArray($findResult); + uasort($resultSet, function($item1, $item2) { + return strtotime($item1->creationDate) < strtotime($item2->creationDate); + }); return new \yii\data\ArrayDataProvider([ 'models' => $resultSet, 'pagination' => [ @@ -72,7 +81,7 @@ public function search($sessionToken, $params) { //SILEX:info //totalCount must be there too to get the pagination in GridView 'totalCount' => $this->totalCount - //\SILEX:info + //\SILEX:info ]); } } @@ -83,6 +92,8 @@ public function search($sessionToken, $params) { * @return array */ public function attributesToArray() { + + $elementForWebService = parent::attributesToArray(); $elementForWebService[YiiAnnotationModel::CREATOR] = $this->creator; $elementForWebService[YiiAnnotationModel::MOTIVATED_BY] = $this->motivatedBy; $elementForWebService[YiiAnnotationModel::CREATION_DATE] = $this->creationDate; @@ -95,4 +106,5 @@ public function attributesToArray() { } return $elementForWebService; } + } diff --git a/models/yiiModels/DataFileSearch.php b/models/yiiModels/DataFileSearch.php index f130c219..017951b3 100644 --- a/models/yiiModels/DataFileSearch.php +++ b/models/yiiModels/DataFileSearch.php @@ -18,7 +18,7 @@ * @author Vincent Migot */ class DataFileSearch extends YiiDataFileModel { - + /** * @param string $pageSize number of elements per page * (limited to 150 000) @@ -27,18 +27,18 @@ class DataFileSearch extends YiiDataFileModel { public function __construct($pageSize = null, $page = null) { parent::__construct($pageSize, $page); } - + /** * * @return array the rules of the attributes */ public function rules() { return [ - [['rdfType'], 'required'], - [['concernedItems','jsonValueFilter'], 'safe'] + [['rdfType'], 'required'], + [['concernedItems', 'jsonValueFilter'], 'safe'] ]; } - + /** * * @param array $sessionToken used for the data access @@ -47,12 +47,14 @@ public function rules() { * or string \app\models\wsModels\WSConstants::TOKEN if the user needs to log in */ public function search($sessionToken, $params) { - //1. this load the searched data - $this->load($params); + //1. this load the searched data + if (isset($params)) { + $this->load($params); + } if (isset($params[YiiModelsConstants::PAGE])) { $this->page = $params[YiiModelsConstants::PAGE]; } - + //2. Check validity of search data if (!$this->validate()) { return new ArrayDataProvider(); @@ -62,13 +64,13 @@ public function search($sessionToken, $params) { $params = $this->attributesToArray(); unset($params['uri']); $findResult = $this->find($sessionToken, $params); - if (is_string($findResult)) { return $findResult; - } else if (isset($findResult->{'metadata'}->{'status'}[0]->{'exception'}->{'details'}) - && $findResult->{'metadata'}->{'status'}[0]->{'exception'}->{'details'} === WSConstants::TOKEN_INVALID) { + } else if (isset($findResult->{'metadata'}->{'status'}[0]->{'exception'}->{'details'}) && $findResult->{'metadata'}->{'status'}[0]->{'exception'}->{'details'} === WSConstants::TOKEN_INVALID) { return WSConstants::TOKEN_INVALID; } else { + + return new ArrayDataProvider([ 'models' => $findResult, 'pagination' => [ @@ -78,8 +80,9 @@ public function search($sessionToken, $params) { //SILEX:info //totalCount must be there too to get the pagination in GridView 'totalCount' => $this->totalCount - //\SILEX:info + //\SILEX:info ]); } } + } diff --git a/models/yiiModels/DataSearchLayers.php b/models/yiiModels/DataSearchLayers.php index 59fdaf53..d3514deb 100644 --- a/models/yiiModels/DataSearchLayers.php +++ b/models/yiiModels/DataSearchLayers.php @@ -26,13 +26,20 @@ class DataSearchLayers extends \app\models\yiiModels\YiiDataModel { */ public $endDate; + /** + * Parameter to sort result by date. + * @var string expected values: true or false + */ + public $dateSortAsc; + /** * @inheritdoc */ + public function rules() { return [ - [['variable', 'startDate', 'endDate', 'provenance', 'object'], 'safe'] + [['variable', 'startDate', 'endDate', 'provenance', 'object','dateSortAsc'], 'safe'] ]; } @@ -89,6 +96,7 @@ public function attributesToArray() { $toReturn["endDate"] = $this->endDate; $toReturn["provenance"] = $this->provenance; $toReturn["pageSize"] = $this->pageSize; + $toReturn["dateSortAsc"] = $this->dateSortAsc; return $toReturn; } diff --git a/models/yiiModels/EventCreation.php b/models/yiiModels/EventCreation.php index 8c91b3a8..ffcfd18b 100644 --- a/models/yiiModels/EventCreation.php +++ b/models/yiiModels/EventCreation.php @@ -32,11 +32,6 @@ class EventCreation extends EventAction { public $creator; const CREATOR = 'creator'; - /** - * To kind of object ? Vector, sensor, scientific object (link to the cart functionnality) - * proposition name: target/ category .. - */ - public $category; /** * @inheritdoc */ diff --git a/models/yiiModels/EventSearch.php b/models/yiiModels/EventSearch.php index e615697b..0fbbd6fe 100644 --- a/models/yiiModels/EventSearch.php +++ b/models/yiiModels/EventSearch.php @@ -1,4 +1,5 @@ + * */ class EventSearch extends YiiEventModel { - + /** * Type filter. * @example MoveFrom * @var string */ public $searchType; + const SEARCH_TYPE = 'searchType'; const SEARCH_TYPE_WS_FIELD = 'rdfType'; - + /** * Concerned item's label filter. * @example Plot 445 * @var string */ public $searchConcernedItemLabel; + const SEARCH_CONCERNED_ITEM_LABEL = 'searchConcernedItemLabel'; const SEARCH_CONCERNED_ITEM_LABEL_WS_FIELD = 'concernedItemLabel'; - + /** * Concerned item's URI filter. * @example Plot 445 * @var string */ public $searchConcernedItemUri; + const SEARCH_CONCERNED_ITEM_URI = 'searchItemUri'; const SEARCH_CONCERNED_ITEM_URI_WS_FIELD = 'concernedItemUri'; - + /** * Date range filter. * @example 2019-01-02T00:00:00+01:00 - 2019-01-03T23:00:00+01:00 * @var string */ public $searchDateRange; + const SEARCH_DATE_RANGE = 'searchDateRange'; - + /** * Date range start filter. * @example 2019-01-02T00:00:00+01:00 * @var string */ public $searchDateRangeStart; + const SEARCH_DATE_RANGE_START = 'searchStartDate'; const SEARCH_DATE_RANGE_START_WS_FIELD = 'startDate'; - + /** * Date range end filter. * @example 2019-01-02T00:00:00+01:00 * @var string */ public $searchDateRangeEnd; + const SEARCH_DATE_RANGE_END = 'searchEndDate'; const SEARCH_DATE_RANGE_END_WS_FIELD = 'endDate'; - + + /** + * Parameter to sort result by date. + * @var string expected values: true or false + */ + public $dateSortAsc; + + const SEARCH_SORT_DATE = 'dateSortAsc'; + /** * @inheritdoc */ public function rules() { return [[ - [ - self::SEARCH_TYPE, - self::SEARCH_CONCERNED_ITEM_LABEL, - self::SEARCH_CONCERNED_ITEM_URI, - self::SEARCH_DATE_RANGE, - self::SEARCH_DATE_RANGE_START, - self::SEARCH_DATE_RANGE_END - ], 'safe']]; + [ + self::SEARCH_TYPE, + self::SEARCH_CONCERNED_ITEM_LABEL, + self::SEARCH_CONCERNED_ITEM_URI, + self::SEARCH_DATE_RANGE, + self::SEARCH_DATE_RANGE_START, + self::SEARCH_DATE_RANGE_END, + self::SEARCH_SORT_DATE + ], 'safe']]; } - + /** * @return array the labels of the attributes */ public function attributeLabels() { return array_merge( - parent::attributeLabels(), - [ - self::SEARCH_TYPE => Yii::t('app', self::TYPE_LABEL), - self::SEARCH_CONCERNED_ITEM_LABEL => Yii::t('app', self::CONCERNED_ITEMS_LABEL), - self::SEARCH_DATE_RANGE => Yii::t('app', self::DATE_LABEL) - ] + parent::attributeLabels(), [ + self::SEARCH_TYPE => Yii::t('app', self::TYPE_LABEL), + self::SEARCH_CONCERNED_ITEM_LABEL => Yii::t('app', self::CONCERNED_ITEMS_LABEL), + self::SEARCH_DATE_RANGE => Yii::t('app', self::DATE_LABEL) + ] ); } - + + public function searchWithAnnotationsDescription($sessionToken, $searchParams) { + + $this->load($searchParams); + if (isset($searchParams[YiiModelsConstants::PAGE])) { + $this->page = $searchParams[YiiModelsConstants::PAGE]; + } + if (isset($searchParams[YiiModelsConstants::PAGE_SIZE])) { + $this->pageSize = $searchParams[YiiModelsConstants::PAGE_SIZE]; + } + if (isset($searchParams[EventSearch::SEARCH_DATE_RANGE])) { + $this->searchDateRange = $searchParams[EventSearch::SEARCH_DATE_RANGE]; + } + + $results = $this->find($sessionToken, $this->attributesToArray()); + if (is_string($results)) { + return $results; + } else if (isset($results->{'metadata'}->{'status'}[0]->{'exception'}->{'details'}) && $results->{'metadata'}->{'status'}[0]->{'exception'}->{'details'} === \app\models\wsModels\WSConstants::TOKEN_INVALID) { + return \app\models\wsModels\WSConstants::TOKEN_INVALID; + } else if (isset($results->{'metadata'}->{'status'}[0]->{'exception'}->{'details'})) { + return $results->{'metadata'}->{'status'}[0]->{'exception'}->{'details'}; + } else { + + $events = $this->jsonListOfArraysToArray($results); + $eventsWithAnnotations = $this->linkAnnotationsToEvents($sessionToken, $events); + uasort($eventsWithAnnotations, function($item1, $item2) { + return strtotime($item1->date) < strtotime($item2->date); + }); + + return new ArrayDataProvider([ + 'models' => $eventsWithAnnotations, + 'pagination' => [ + 'pageSize' => $this->pageSize, + 'totalCount' => $this->totalCount + ], + 'totalCount' => $this->totalCount + ]); + } + } + + public function linkAnnotationsToEvents($sessionToken, $events) { + $toReturn = []; + foreach ($events as $event) { + $eventURI = $event->uri; + $annotationObjects = $this->wsModel->getEventAnnotations($sessionToken, [YiiEventModel::URI => $eventURI]); + $annotations = array(); + foreach ($annotationObjects as $annotationObject) { + $annotations[] = [ + "creationDate" => $annotationObject->creationDate, + "bodyValues" => $annotationObject->bodyValues + ]; + } + uasort($annotations, function($item1, $item2) { + return strtotime($item1['creationDate']) > strtotime($item2['creationDate']); + }); + + $event->annotations = $annotations; + $toReturn[] = $event; + } + + return $toReturn; + } + /** * @param array $sessionToken * @param string $searchParams @@ -111,40 +192,68 @@ public function attributeLabels() { */ public function search($sessionToken, $searchParams) { $this->load($searchParams); - + if (!$this->validate()) { return new ArrayDataProvider(); - } + } return $this->getEventProvider($sessionToken, $searchParams); } - + /** * Requests to WS and returns result. * @param $sessionToken * @return request result */ private function getEventProvider($sessionToken, $searchParams) { - $results = $this->find($sessionToken, array_merge($this->attributesToArray(), $searchParams)); - + + + if (isset($searchParams[YiiModelsConstants::PAGE])) { + $this->page = $searchParams[YiiModelsConstants::PAGE]; + } + + if (isset($searchParams[YiiModelsConstants::PAGE_SIZE])) { + $this->pageSize = $searchParams[YiiModelsConstants::PAGE_SIZE]; + } + $results = $this->find($sessionToken, $this->attributesToArray()); if (is_string($results)) { return $results; - } else if (isset($results->{WSConstants::DATA}->{WSConstants::STATUS}[0]->{WSConstants::EXCEPTION}->{WSConstants::DETAILS}) - && $results->{WSConstants::METADATA}->{WSConstants::STATUS}[0]->{WSConstants::EXCEPTION}->{WSConstants::DETAILS} === WSConstants::TOKEN_INVALID) { - return WSConstants::TOKEN_INVALID; + } else if (isset($results->{'metadata'}->{'status'}[0]->{'exception'}->{'details'}) && $results->{'metadata'}->{'status'}[0]->{'exception'}->{'details'} === \app\models\wsModels\WSConstants::TOKEN_INVALID) { + return \app\models\wsModels\WSConstants::TOKEN_INVALID; + } else if (isset($results->{'metadata'}->{'status'}[0]->{'exception'}->{'details'})) { + return $results->{'metadata'}->{'status'}[0]->{'exception'}->{'details'}; } else { - $events = $this->jsonListOfArraysToArray($results); return new ArrayDataProvider([ 'models' => $events, 'pagination' => [ - 'pageSize' => $searchParams[WSConstants::PAGE_SIZE], + 'pageSize' => $this->pageSize, 'totalCount' => $this->totalCount ], 'totalCount' => $this->totalCount ]); } } - + + /** + * Get the event's annotations + * @param type $sessionToken + * @param type $searchParams + * @return the event's annotations array + */ + public function getAnnotations($sessionToken, $searchParams) { + $response = $this->wsModel->getEventAnnotations($sessionToken, $searchParams); + if (!is_string($response)) { + if (isset($response[WSConstants::TOKEN_INVALID])) { + return $response; + } else { + $annotationWidgetPageSize = Yii::$app->params['annotationWidgetPageSize']; + return $response; + } + } else { + return $response; + } + } + /** * @inheritdoc * @param type $values @@ -152,11 +261,11 @@ private function getEventProvider($sessionToken, $searchParams) { */ public function setAttributes($values, $safeOnly = true) { parent::setAttributes($values, $safeOnly); - + if (is_array($values)) { if (isset($values[self::SEARCH_DATE_RANGE])) { $dateRange = $values[self::SEARCH_DATE_RANGE]; - + //SILEX:info // We shouldn't control the date range format because the WS // already implements it but as the webapp doesn't handle WS @@ -169,16 +278,16 @@ public function setAttributes($values, $safeOnly = true) { } } } - + /** * Validates the date range format and set the dates attributes. The accepted * date range format is defined in the application parameter * standardDateTimeFormatPhp. * @param type $dateRangeString */ - private function validateDateRangeFormatAndSetDatesAttributes($dateRangeString) { + private function validateDateRangeFormatAndSetDatesAttributes($dateRangeString) { $dateRangeArray = explode(Yii::$app->params['dateRangeSeparator'], $dateRangeString); - + $isSubmittedStartDateFormatValid = true; $isSubmittedEndDateFormatValid = true; @@ -189,21 +298,21 @@ private function validateDateRangeFormatAndSetDatesAttributes($dateRangeString) if ($isSubmittedStartDateFormatValid) { $this->searchDateRangeStart = $submittedStartDateString; // validate end date - if (isset($dateRangeArray[1])) { + if (isset($dateRangeArray[1])) { $submittedEndDateString = $dateRangeArray[1]; $isSubmittedEndDateFormatValid = $this->validateSubmittedDateFormat($submittedEndDateString); if ($isSubmittedEndDateFormatValid) { $this->searchDateRangeEnd = $submittedEndDateString; } - } + } } } - + if (!$isSubmittedStartDateFormatValid || !$isSubmittedEndDateFormatValid) { $this->resetDateRangeFilterValues(); } } - + /** * Validates the submitted date format. The accepted date format is defined * in the application parameter standardDateTimeFormatPhp @@ -232,32 +341,30 @@ private function validateSubmittedDateFormat($dateString) { */ $dateStringWithoutT = str_replace("T", " ", $dateString); $date = DateTime::createFromFormat(Yii::$app->params['dateTimeFormatPhp'], $dateStringWithoutT); - $dateRangeStartParseErrorCount = DateTime::getLastErrors()['error_count']; + $dateRangeStartParseErrorCount = DateTime::getLastErrors()['error_count']; if ($dateRangeStartParseErrorCount >= 1) { - error_log("dateRangeStartParseErrorMessages ".print_r(DateTime::getLastErrors()['errors'], true)); + error_log("dateRangeStartParseErrorMessages " . print_r(DateTime::getLastErrors()['errors'], true)); return false; - } - else if ($date->format(Yii::$app->params['dateTimeFormatPhp']) == $dateStringWithoutT) { + } else if ($date->format(Yii::$app->params['dateTimeFormatPhp']) == $dateStringWithoutT) { return true; - } - else { + } else { return false; } - } catch (Exception $exception) { + } catch (Exception $exception) { error_log($exception->getMessage()); return false; } } - + /** * Resets the date range filter values */ - private function resetDateRangeFilterValues(){ + private function resetDateRangeFilterValues() { $this->searchDateRangeStart = null; $this->searchDateRangeEnd = null; $this->searchDateRange = null; } - + /** * @inheritdoc */ @@ -269,7 +376,9 @@ public function attributesToArray() { self::SEARCH_CONCERNED_ITEM_LABEL_WS_FIELD => $this->searchConcernedItemLabel, self::SEARCH_CONCERNED_ITEM_URI_WS_FIELD => $this->searchConcernedItemUri, self::SEARCH_DATE_RANGE_START_WS_FIELD => $this->searchDateRangeStart, - self::SEARCH_DATE_RANGE_END_WS_FIELD => $this->searchDateRangeEnd + self::SEARCH_DATE_RANGE_END_WS_FIELD => $this->searchDateRangeEnd, + self::SEARCH_SORT_DATE => $this->dateSortAsc ]; } + } diff --git a/models/yiiModels/YiiAnnotationModel.php b/models/yiiModels/YiiAnnotationModel.php index 67363318..f5311550 100644 --- a/models/yiiModels/YiiAnnotationModel.php +++ b/models/yiiModels/YiiAnnotationModel.php @@ -48,7 +48,7 @@ class YiiAnnotationModel extends WSActiveRecord { public $creationDate; const CREATION_DATE = "creationDate"; - const CREATION_DATE_LABEL = "Annotation Date"; + const CREATION_DATE_LABEL = "Date"; /** * The creator of the annotation @@ -114,7 +114,7 @@ public function rules() { [[self::URI, self::CREATOR, self::MOTIVATED_BY, self::BODY_VALUES, self::TARGETS], 'required'], [[self::URI, self::RETURN_URL, self::CREATOR, self::MOTIVATED_BY, self::BODY_VALUES, self::TARGETS], 'safe'], [[self::BODY_VALUES], 'string'], - [[self::URI, self::RETURN_URL, self::CREATOR, self::TARGETS], 'string', 'max' => 300] + [[self::URI, self::RETURN_URL, self::CREATOR, self::TARGETS], 'string', 'max' => 1500] ]; } diff --git a/models/yiiModels/YiiDataFileModel.php b/models/yiiModels/YiiDataFileModel.php index 49b42448..0377cd14 100644 --- a/models/yiiModels/YiiDataFileModel.php +++ b/models/yiiModels/YiiDataFileModel.php @@ -78,7 +78,7 @@ class YiiDataFileModel extends WSActiveRecord { const PROVENANCE = "provenance"; - + /** * Initialize wsModel. In this class, wsModel is a WSImageModel @@ -159,7 +159,6 @@ public function attributesToArray() { if ($this->provenance != null) { $attributesArray[self::PROVENANCE] = $this->provenance; } - return $attributesArray; } diff --git a/models/yiiModels/YiiDataModel.php b/models/yiiModels/YiiDataModel.php index cd44dd5b..9d6d035c 100644 --- a/models/yiiModels/YiiDataModel.php +++ b/models/yiiModels/YiiDataModel.php @@ -43,6 +43,7 @@ class YiiDataModel extends WSActiveRecord { */ public $provenance; + /** * * @param string $pageSize number of elements per page diff --git a/models/yiiModels/YiiEventModel.php b/models/yiiModels/YiiEventModel.php index 947219f6..37b5858b 100644 --- a/models/yiiModels/YiiEventModel.php +++ b/models/yiiModels/YiiEventModel.php @@ -67,6 +67,14 @@ class YiiEventModel extends WSActiveRecord { public $properties; const PROPERTIES = "properties"; + /** + * Annotations of the event + * @var array + */ + public $annotations; + const ANNOTATIONS = "Annotations"; + + public function __construct($pageSize = null, $page = null) { $this->wsModel = new WSEventModel(); ($pageSize !== null || $pageSize !== "") ? $this->pageSize = $pageSize @@ -140,9 +148,10 @@ protected function arrayToAttributes($array) { public function getEvent($sessionToken, $uri) { $event = $this->wsModel->getEvent($sessionToken, $uri); if (!is_string($event)) { - if (isset($event[WSConstants::TOKEN_INVALID])) { - return $event; - } else { + if (isset($event->{'metadata'}->{'status'}[0]->{'exception'}->{'details'}) + && $event->{'metadata'}->{'status'}[0]->{'exception'}->{'details'} === \app\models\wsModels\WSConstants::TOKEN_INVALID) { + return \app\models\wsModels\WSConstants::TOKEN_INVALID; + } else { $this->arrayToAttributes($event); $this->uri = $uri; return $this; @@ -151,7 +160,8 @@ public function getEvent($sessionToken, $uri) { return $event; } } - + + /** * Get the event's annotations * @param type $sessionToken @@ -177,6 +187,8 @@ public function getEventAnnotations($sessionToken, $searchParams) { return $response; } } + + /** * Calls the web service and returns the list of events types diff --git a/models/yiiModels/YiiExperimentModel.php b/models/yiiModels/YiiExperimentModel.php index 0fd11a3b..02b40e0c 100755 --- a/models/yiiModels/YiiExperimentModel.php +++ b/models/yiiModels/YiiExperimentModel.php @@ -16,7 +16,6 @@ use app\models\wsModels\WSActiveRecord; use app\models\wsModels\WSExperimentModel; - use Yii; /** @@ -25,6 +24,7 @@ * (WSActiveRecord, for the web services access) * @see app\models\wsModels\WSExperimentModel * @see app\models\wsModels\WSActiveRecord + * @update [Bonnefont Julien] 3 octobre, 2019: return exception or token on findByURI * @author Morgane Vidal */ class YiiExperimentModel extends WSActiveRecord { @@ -35,77 +35,99 @@ class YiiExperimentModel extends WSActiveRecord { * @var string */ public $uri; + const URI = "uri"; + /** * the start date of the experiment * (e.g 2017-01-01) * @var string */ public $startDate; + const START_DATE = "startDate"; + /** * the end date of the experiment * (e.g 2017-07-01) * @var string */ public $endDate; + const END_DATE = "endDate"; + /** * the field * (e.g Epoisses - plot F) * @var string */ public $field; + const FIELD = "field"; + /** * the campaign (corresponds to the flowering date) * (e.g 2017) * @var string */ public $campaign; + const CAMPAIGN = "campaign"; + /** * the place of the experiment * (e.g. Bretenière) * @var string */ public $place; + const PLACE = "place"; + /** * the experiment's alias used in the platform * @var string */ public $alias; + const ALIAS = "alias"; + /** * the experiment's comments * (e.g. C17RAP) * @var string */ public $comment; + const COMMENT = "comment"; + /** * the experiment's description keywords * (e.g Colza, azote, phénotypage, capteurs, images, variables agronomiques) * @var string */ public $keywords; + const KEYWORDS = "keywords"; + /** * the experiment's objectives * (e.g Rapsodyn- phénotypage) * @var string */ public $objective; + const OBJECTIVE = "objective"; + /** * the groups (uris) in which the experiment is. * (e.g http://www.phenome-fppn.fr/diaphen/INRA-LEPSE-DROPS) * @var array */ public $groups; + const GROUPS = "groups"; const GROUPS_URIS = "groupsUris"; + /** * the experiment's crop species. It is a string but will be replace by an * array of species uri when the crop species service will be done. @@ -113,54 +135,64 @@ class YiiExperimentModel extends WSActiveRecord { * @var string */ public $cropSpecies; + const CROP_SPECIES = "cropSpecies"; + /** * the projects (uri => acronyme) in which the experiment is. * (e.g http://www.phenome-fppn.fr/phenovia/RAPSODYN => RAPSODYN) * @var array */ public $projects; + const PROJECTS = "projects"; const PROJECTS_URIS = "projectsUris"; - + /** * the project uri where the experiment is searched. * (e.g http://www.phenome-fppn.fr/phenovia/RAPSODYN) * @var string */ public $projectUri; + const PROJECT_URI = "projectUri"; - + /** * the experiment's scientific supervisors contacts (email). * (e.g john.doe[at]inra.fr) * @var array */ public $scientificSupervisorContacts; + const CONTACT_SCIENTIFIC_SUPERVISOR = "http://www.opensilex.org/vocabulary/oeso/#ScientificSupervisor"; const CONTACT_TECHNICAL_SUPERVISOR = "http://www.opensilex.org/vocabulary/oeso/#TechnicalSupervisor"; + /** * the experiment's technical supervisor contacts (email). * (e.g. john.doe[at]inra.fr) * @var array */ public $technicalSupervisorContacts; - + const CONTACTS = "contacts"; const CONTACT_TYPE = "type"; + /** * The list of the variables measured by the experiment * @var array */ public $variables; + const VARIABLES = "variables"; + /** * The list of sensors which participates in the experiment * @var array */ public $sensors; + const SENSORS = "sensors"; - + /** * Initialize wsModel. In this class, wsModel is a WSExperimentModel * @param string $pageSize number of elements per page @@ -172,21 +204,21 @@ public function __construct($pageSize = null, $page = null) { ($pageSize !== null || $pageSize !== "") ? $this->pageSize = $pageSize : $this->pageSize = null; ($page !== null || $page !== "") ? $this->page = $page : $this->page = null; } - + /** * * @return array the rules of the attributes */ public function rules() { return [ - [['uri', 'startDate', 'endDate', 'projects', 'campaign'], 'required'], - [['startDate', 'endDate', 'projects', 'groups', 'scientificSupervisorContacts', 'technicalSupervisorContacts'], 'safe'], - [['comment', 'cropSpecies'], 'string'], - [['uri', 'alias', 'keywords', 'objective'], 'string', 'max' => 255], - [['field', 'campaign', 'place'], 'string', 'max' => 50], + [['uri', 'startDate', 'endDate', 'projects', 'campaign'], 'required'], + [['startDate', 'endDate', 'projects', 'groups', 'scientificSupervisorContacts', 'technicalSupervisorContacts'], 'safe'], + [['comment', 'cropSpecies'], 'string'], + [['uri', 'alias', 'keywords', 'objective'], 'string', 'max' => 255], + [['field', 'campaign', 'place'], 'string', 'max' => 50], ]; } - + /** * * @return array the labels of the attributes @@ -212,13 +244,13 @@ public function attributeLabels() { 'sensors' => Yii::t('app', 'Sensors which participates in') ]; } - + /** * allows to fill the attributes with the informations in the array given * @param array $array array key => value which contains the metadata of * an experiment */ - public function arrayToAttributes($array) { + public function arrayToAttributes($array) { $this->uri = $array[YiiExperimentModel::URI]; $this->startDate = $array[YiiExperimentModel::START_DATE]; $this->endDate = $array[YiiExperimentModel::END_DATE]; @@ -230,15 +262,15 @@ public function arrayToAttributes($array) { $this->keywords = $array[YiiExperimentModel::KEYWORDS]; $this->objective = $array[YiiExperimentModel::OBJECTIVE]; $this->cropSpecies = $array[YiiExperimentModel::CROP_SPECIES]; - + if (isset($array[YiiExperimentModel::PROJECTS])) { foreach ($array[YiiExperimentModel::PROJECTS] as $project) { $experimentProject[YiiProjectModel::URI] = $project->{YiiProjectModel::URI}; $experimentProject[YiiProjectModel::SHORTNAME] = $project->{YiiProjectModel::SHORTNAME}; - $this->projects[] = $experimentProject; + $this->projects[] = $experimentProject; } } - + if (isset($array[YiiExperimentModel::GROUPS])) { foreach ($array[YiiExperimentModel::GROUPS] as $group) { $experimentGroup[YiiGroupModel::URI] = $group->{YiiGroupModel::URI}; @@ -246,13 +278,13 @@ public function arrayToAttributes($array) { $this->groups[] = $experimentGroup; } } - + if (isset($array[YiiExperimentModel::CONTACTS])) { foreach ($array[YiiExperimentModel::CONTACTS] as $contact) { $experimentContact[YiiUserModel::FIRST_NAME] = $contact->{YiiUserModel::FIRST_NAME}; $experimentContact[YiiUserModel::FAMILY_NAME] = $contact->{YiiUserModel::FAMILY_NAME}; $experimentContact[YiiUserModel::EMAIL] = $contact->{YiiUserModel::EMAIL}; - + if ($contact->{YiiExperimentModel::CONTACT_TYPE} === YiiExperimentModel::CONTACT_SCIENTIFIC_SUPERVISOR) { $this->scientificSupervisorContacts[] = $experimentContact; } else { @@ -260,16 +292,16 @@ public function arrayToAttributes($array) { } } } - + foreach ($array[YiiExperimentModel::VARIABLES] as $variableUri => $variableLabel) { - $this->variables[$variableUri] = $variableLabel; + $this->variables[$variableUri] = $variableLabel; } - + foreach ($array[YiiExperimentModel::SENSORS] as $sensorUri => $sensorLabel) { - $this->sensors[$sensorUri] = $sensorLabel; + $this->sensors[$sensorUri] = $sensorLabel; } } - + /** * get experiment's informations by uri * @param string $sessionToken user session token @@ -278,25 +310,30 @@ public function arrayToAttributes($array) { public function findByURI($sessionToken, $uri) { $params = []; if ($this->pageSize !== null) { - $params[\app\models\wsModels\WSConstants::PAGE_SIZE] = $this->pageSize; + $params[\app\models\wsModels\WSConstants::PAGE_SIZE] = $this->pageSize; } if ($this->page !== null) { $params[\app\models\wsModels\WSConstants::PAGE] = $this->page; } $requestRes = $this->wsModel->getExperimentByURI($sessionToken, $uri, $params); + if (!is_string($requestRes)) { - if (isset($requestRes[\app\models\wsModels\WSConstants::TOKEN_INVALID])) { - return $requestRes; + if (isset($requestRes->{'metadata'}->{'status'}[0]->{'exception'}->{'details'}) && $requestRes->{'metadata'}->{'status'}[0]->{'exception'}->{'details'} === \app\models\wsModels\WSConstants::TOKEN_INVALID) { + + return \app\models\wsModels\WSConstants::TOKEN_INVALID; + } else if (isset($requestRes->{'metadata'}->{'status'}[0]->{'exception'}->{'details'})) { + return $requestRes->{'metadata'}->{'status'}[0]->{'exception'}->{'details'}; } else { $this->arrayToAttributes($requestRes); return true; } } else { + return $requestRes; } } - + /** * Get the list of uri of the experiments. * @param string $sessionToken @@ -309,25 +346,25 @@ public function findByURI($sessionToken, $uri) { public function getExperimentsURIList($sessionToken) { $experiments = $this->find($sessionToken, $this->attributesToArray()); $experimentsToReturn = []; - + if ($experiments !== null) { //1. get the URIs - foreach($experiments as $experiment) { + foreach ($experiments as $experiment) { $experimentsToReturn[] = $experiment->uri; } - + //2. if there are other pages, get the other experiments if ($this->totalPages > $this->page) { $this->page++; //next page $nextExperiments = $this->getExperimentsURIList($sessionToken); - + $experimentsToReturn = array_merge($experimentsToReturn, $nextExperiments); } - + return $experimentsToReturn; } } - + /** * Get the list of uri of the experiments. * @param string $sessionToken @@ -340,26 +377,26 @@ public function getExperimentsURIList($sessionToken) { public function getExperimentsURIAndLabelList($sessionToken) { $experiments = $this->find($sessionToken, $this->attributesToArray()); $experimentsToReturn = []; - + if ($experiments !== null) { //1. get the URIs - foreach($experiments as $experiment) { + foreach ($experiments as $experiment) { $experimentsToReturn[$experiment->uri] = $experiment->alias; } - + //2. if there are other pages, get the other experiments if ($this->totalPages > $this->page) { $this->page++; //next page $nextExperiments = $this->getExperimentsURIAndLabelList($sessionToken); - + $experimentsToReturn = array_merge($experimentsToReturn, $nextExperiments); } - + return $experimentsToReturn; } } - - /** + + /** * Create an array representing the experiment * Used for the web service for example * @return array with the attributes. @@ -372,25 +409,25 @@ public function attributesToArray() { $elementForWebService[YiiExperimentModel::FIELD] = $this->field; $elementForWebService[YiiExperimentModel::CAMPAIGN] = $this->campaign; $elementForWebService[YiiExperimentModel::PLACE] = $this->place; - $elementForWebService[YiiExperimentModel::ALIAS]= $this->alias; + $elementForWebService[YiiExperimentModel::ALIAS] = $this->alias; $elementForWebService[YiiExperimentModel::COMMENT] = $this->comment; $elementForWebService[YiiExperimentModel::KEYWORDS] = $this->keywords; - $elementForWebService[YiiExperimentModel::OBJECTIVE] = $this->objective; + $elementForWebService[YiiExperimentModel::OBJECTIVE] = $this->objective; $elementForWebService[YiiExperimentModel::GROUPS] = $this->groups; - $elementForWebService[YiiExperimentModel::PROJECTS_URIS] = $this->projects; + $elementForWebService[YiiExperimentModel::PROJECTS_URIS] = $this->projects; $elementForWebService[YiiExperimentModel::CROP_SPECIES] = $this->cropSpecies; // Project Uri is only used in case of search and not in case of posting data if ($this->projectUri != null) { - $elementForWebService[YiiExperimentModel::PROJECT_URI] = $this->projectUri; + $elementForWebService[YiiExperimentModel::PROJECT_URI] = $this->projectUri; } - + if ($this->groups != null) { foreach ($this->groups as $groupUri) { $elementForWebService[YiiExperimentModel::GROUPS_URIS][] = $groupUri; } } - + if ($this->scientificSupervisorContacts != null) { foreach ($this->scientificSupervisorContacts as $scientificSupervisor) { $contact[YiiExperimentModel::CONTACT_TYPE] = YiiExperimentModel::CONTACT_SCIENTIFIC_SUPERVISOR; @@ -398,7 +435,7 @@ public function attributesToArray() { $elementForWebService[YiiExperimentModel::CONTACTS][] = $contact; } } - + if ($this->technicalSupervisorContacts != null) { foreach ($this->technicalSupervisorContacts as $technicalSupervisor) { $contact[YiiExperimentModel::CONTACT_TYPE] = YiiExperimentModel::CONTACT_TECHNICAL_SUPERVISOR; @@ -406,10 +443,10 @@ public function attributesToArray() { $elementForWebService[YiiExperimentModel::CONTACTS][] = $contact; } } - + return $elementForWebService; } - + /** * Update variables measured by an experiment * @param string $sessionToken @@ -419,7 +456,7 @@ public function attributesToArray() { */ public function updateVariables($sessionToken, $experimentUri, $variablesUri) { $requestRes = $this->wsModel->putExperimentVariables($sessionToken, $experimentUri, $variablesUri); - + if (is_string($requestRes) && $requestRes === "token") { return $requestRes; } else if (isset($requestRes->{\app\models\wsModels\WSConstants::METADATA}->{\app\models\wsModels\WSConstants::STATUS})) { @@ -428,7 +465,7 @@ public function updateVariables($sessionToken, $experimentUri, $variablesUri) { return $requestRes; } } - + /** * Update sensors which participates in an experiment * @param string $sessionToken @@ -438,7 +475,7 @@ public function updateVariables($sessionToken, $experimentUri, $variablesUri) { */ public function updateSensors($sessionToken, $experimentUri, $sensorsUris) { $requestRes = $this->wsModel->putExperimentSensors($sessionToken, $experimentUri, $sensorsUris); - + if (is_string($requestRes) && $requestRes === "token") { return $requestRes; } else if (isset($requestRes->{\app\models\wsModels\WSConstants::METADATA}->{\app\models\wsModels\WSConstants::STATUS})) { @@ -447,7 +484,7 @@ public function updateSensors($sessionToken, $experimentUri, $sensorsUris) { return $requestRes; } } - + /** * Get the variables measured by the given experiment * @param string $sessionToken @@ -462,10 +499,11 @@ public function getMeasuredVariables($sessionToken, $experimentUri) { $variables = []; if (!empty($experimentUri)) { if ($this->findByURI($sessionToken, $experimentUri)) { - return $this->variables; + return $this->findByURI($sessionToken, $experimentUri); } } - + return $variables; } + } diff --git a/models/yiiModels/YiiVariableModel.php b/models/yiiModels/YiiVariableModel.php index b55f508a..724ec1d3 100755 --- a/models/yiiModels/YiiVariableModel.php +++ b/models/yiiModels/YiiVariableModel.php @@ -130,7 +130,7 @@ public function findByURI($sessionToken, $uri) { $params[\app\models\wsModels\WSConstants::PAGE] = $this->page; } $requestRes = $this->wsModel->getVariableByURI($sessionToken, $uri, $params); - + if (!is_string($requestRes)) { if (isset($requestRes[\app\models\wsModels\WSConstants::TOKEN_INVALID])) { return $requestRes; diff --git a/translations/fr/app.php b/translations/fr/app.php index 495e201a..5600ead6 100755 --- a/translations/fr/app.php +++ b/translations/fr/app.php @@ -46,6 +46,7 @@ // A 'Acquisition session template' => 'Gabarit de session d\'aquisition', + 'Add an event'=>'Ajouter un événement', 'Add Dataset' => 'Importer un jeu de données', 'Add Document' => 'Ajouter un document', 'Add Document Script' => 'Ajouter un script', @@ -259,8 +260,8 @@ // S 'Scientific Contacts' => 'Contacts scientifiques', 'scientific objects' =>'objets scientifiques', + 'Scientific object metadata'=>'Métadonnées de l\'objet scientifique', 'Scientific Supervisors' => 'Superviseurs scientifiques', - 'Search Criteria' =>'Critères de recherche', 'See' => 'Voir', 'Select all the' =>'Sélectionnez l\'ensemble des', 'Select method alias...' => 'Sélectionnez l\'alias de la méthode', diff --git a/translations/fr/messages.php b/translations/fr/messages.php index c44a0538..c02621bd 100755 --- a/translations/fr/messages.php +++ b/translations/fr/messages.php @@ -36,7 +36,8 @@ 'Be carefull to write all the new and the former properties of the updated object.' => 'Attention, veillez à écrire toutes les nouvelles et les anciennes propriétés de l\'objet mis à jour.', // C - 'Click and drag in the plot area to zoom in!' =>'Cliquer et faire glisser pour zoomer sur le graphique!', + 'Click on a serie to add an event or annotate the scientific object.' =>'Cliquer sur une série pour ajouter un évenement ou annoter l\'object scientifique.', + 'Click on the circle up to the serie to see images.' =>'Cliquer sur le cercle au dessus de la serie pour voir l\'image.', 'CSV file headers does not match selected variables' => 'Les en-têtes du fichier CSV ne correspondent pas aux variables sélectionnées', 'CSV separator must be' => 'Le séparateur de champs CSV doit être', @@ -139,7 +140,6 @@ 'You cannot modify already existing traits, methods and units.' => 'Vous ne pouvez pas modifier de traits, méthodes et unités déjà existantes.','Your session has expired' => 'Votre session a expirée', 'You are on PHIS, the Hybrid Information System about Phenotyping!' => 'Bienvenue dans PHIS, le Système d\'Information Hybride pour le Phénotypage !', 'You are on OpenSILEX, the Hybrid Information System about Life Science!' => 'Bienvenue dans OpenSILEX, le Système d\'Information Hybride pour les Sciences de la Vie !', - 'You have to click a graphic point to see images on that date.' => 'Vous devez clicker sur un point du graphique pour voir les images à cette date.', 'You wish to get notified when new developments are available ? You can follow us on' => 'Vous souhaitez vous tenir informé des derniers développements disponibles ? Vous pouvez nous suivre sur', 'You wish to report a bug or to get help ? OpenSILEX development team can be contacted through the email address' => 'Vous souhaitez nous signaler une erreur ou bien nous demander de l\'aide ? L\'équipe de développement d\'OpenSILEX peut être contactée via l\'adresse' ]; diff --git a/views/event/_form.php b/views/event/_form.php index cfaa6bf8..7071006d 100644 --- a/views/event/_form.php +++ b/views/event/_form.php @@ -36,7 +36,7 @@ if (!$model->isNewRecord) { echo $form->field($model, EventAction::URI)->textInput(['readonly' => true]); } - + foreach ($this->params[EventController::EVENT_TYPES] as $eventPossibleType) { $eventPossibleTypes[$eventPossibleType] = Html::encode(Vocabulary::prettyUri($eventPossibleType)); } diff --git a/views/event/view.php b/views/event/view.php index a43c7f4a..260efc6d 100644 --- a/views/event/view.php +++ b/views/event/view.php @@ -28,7 +28,7 @@ $this->params['breadcrumbs'][] = ['label' => Yii::t('app', '{n, plural, =1{Event} other{Events}}', ['n' => 2]), 'url' => ['index']]; $this->params['breadcrumbs'][] = $this->title; ?> -
+

rdfType)) ?>

$model->uri] : false, diff --git a/views/image/_simple_images_visualization.php b/views/image/_simple_images_visualization.php index c5765be7..82775299 100644 --- a/views/image/_simple_images_visualization.php +++ b/views/image/_simple_images_visualization.php @@ -54,6 +54,8 @@ 'title' => 'Position: ' . $position . '
Date: ' . $date, 'data-toggle' => 'tooltip', 'data-placement' => 'bottom', + 'data-serie'=>$serieIndex, + 'data-point'=>$pointIndex, ]) . ''; $first = false; diff --git a/views/scientific-object/data_visualization.php b/views/scientific-object/data_visualization.php index 193a1870..dc592ae1 100644 --- a/views/scientific-object/data_visualization.php +++ b/views/scientific-object/data_visualization.php @@ -5,14 +5,19 @@ // PHIS-SILEX // Copyright © INRA 2019 // Creation date: 24 mai 2019 -// Contact: morgane.vidal@inra.fr, anne.tireau@inra.fr, pascal.neveu@inra.fr +// Contact: julien.bonnefont@inra.fr, anne.tireau@inra.fr, pascal.neveu@inra.fr //****************************************************************************** use Yii; use yii\widgets\ActiveForm; use yii\helpers\Html; -use miloschuman\highcharts\Highcharts; +use yii\widgets\Pjax; +use miloschuman\highcharts\Highstock; use yii\web\JsExpression; use yii\helpers\Url; +use app\controllers\EventController; +use app\models\yiiModels\YiiAnnotationModel; +use app\components\widgets\AnnotationGridViewWidget; +use app\components\widgets\event\DetailEventGridViewWidget; $this->title = $model->label; $this->params['breadcrumbs'][] = ['label' => Yii::t('app', '{n, plural, =1{Scientific Object} other{Scientific Objects}}', ['n' => 2]), 'url' => ['index']]; @@ -27,26 +32,30 @@ ?>
- - + + +
'get', + 'action' => Url::to(['data-visualization', 'uri' => $model->uri, 'label' => $model->label, 'experimentUri' => $model->experiment]), //ensure you don't repeat get parameters + ]); + if (empty($variables)) { echo "

" . Yii::t('app/messages', 'No variables linked to the experiment of the scientific object.') . "

"; } else { ?>
-
- + -
-
- +
+ 'variable', @@ -93,6 +102,7 @@ ]); ?>
+
@@ -135,9 +145,7 @@
- 'showWidget', 'label' => Yii::t('app', 'Show Images'), 'onchange' => 'onShow(this);']) ?> -
@@ -146,11 +154,12 @@ -
+
- + 'imageType', @@ -169,10 +178,10 @@ ]); ?>
-
- - +
+ 'filter', @@ -201,46 +210,47 @@
-
- -
-

".Yii::t('app/messages', 'You have to click a graphic point to see images on that date.')."

"; - } - ?> - -
    - -
- -