PageRenderTime 37ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/website/application/controllers/AbstractQueryController.php

https://bitbucket.org/efdac/e-forest_platform
PHP | 1725 lines | 1094 code | 286 blank | 345 comment | 253 complexity | 8fabc22224dba3498cd4a368cfcf2633 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /*
  3. * Copyright 2008-2012 European Union
  4. *
  5. * Licensed under the EUPL, Version 1.1 or – as soon they
  6. * will be approved by the European Commission - subsequent
  7. * versions of the EUPL (the "Licence");
  8. * You may not use this work except in compliance with the
  9. * Licence.
  10. * You may obtain a copy of the Licence at:
  11. *
  12. * http://joinup.ec.europa.eu/software/page/eupl/licence-eupl
  13. *
  14. * Unless required by applicable law or agreed to in
  15. * writing, software distributed under the Licence is
  16. * distributed on an "AS IS" basis,
  17. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  18. * express or implied.
  19. * See the Licence for the specific language governing
  20. * permissions and limitations under the Licence.
  21. */
  22. require_once 'AbstractEforestController.php';
  23. require_once APPLICATION_PATH.'/models/metadata/Metadata.php';
  24. require_once APPLICATION_PATH.'/models/raw_data/Generic.php';
  25. require_once APPLICATION_PATH.'/models/mapping/ResultLocation.php';
  26. require_once APPLICATION_PATH.'/models/website/PredefinedRequest.php';
  27. /**
  28. * AbstractQueryController is the controller that manages the query module.
  29. * @package controllers
  30. */
  31. abstract class AbstractQueryController extends AbstractEforestController {
  32. /**
  33. * The name of the schema where the data is stored.
  34. * @var String
  35. */
  36. protected $schema;
  37. /**
  38. * The system of projection for the visualisation.
  39. */
  40. protected $visualisationSRS;
  41. /**
  42. * The system of projection for the storage.
  43. */
  44. protected $databaseSRS;
  45. /**
  46. * Name of the layer used to display the images in the details panel.
  47. */
  48. protected $detailsLayers;
  49. /**
  50. * Initialise the controler
  51. */
  52. public function init() {
  53. parent::init();
  54. // Initialise the logger
  55. $this->logger = Zend_Registry::get('logger');
  56. // Load the redirector helper
  57. $this->_redirector = $this->_helper->getHelper('Redirector');
  58. // Initialise the models
  59. $this->metadataModel = new Model_Metadata();
  60. $this->genericModel = new Model_Generic();
  61. $this->resultLocationModel = new Model_ResultLocation();
  62. $this->predefinedRequestModel = new Model_PredefinedRequest();
  63. // Reinit the activated layers
  64. $mappingSession = new Zend_Session_Namespace('mapping');
  65. $mappingSession->activatedLayers = array();
  66. }
  67. /**
  68. * Return the name of the location table (the table containing the the_geom column)
  69. */
  70. abstract protected function getLocationTable();
  71. /**
  72. * Return the name of the plot table (the table containing the plot data)
  73. */
  74. abstract protected function getPlotTable();
  75. /**
  76. * The "index" action is the default action for all controllers.
  77. *
  78. * @return the default View
  79. */
  80. public function indexAction() {
  81. $this->logger->debug('Query index');
  82. return $this->showQueryFormAction();
  83. }
  84. /**
  85. * Show the main query page.
  86. */
  87. public function showQueryFormAction() {
  88. $this->logger->debug('showQueryFormAction');
  89. // Clean previous results
  90. $sessionId = session_id();
  91. $this->resultLocationModel->cleanPreviousResults($sessionId);
  92. $this->render('show-query-form');
  93. }
  94. /**
  95. * AJAX function : Get the predefined request.
  96. *
  97. * @param String $requestName The request name
  98. * @return Forms
  99. */
  100. private function _ajaxgetpredefinedrequest($requestName) {
  101. $this->logger->debug('_ajaxgetpredefinedrequest');
  102. // Get the saved values for the forms
  103. $savedRequest = $this->predefinedRequestModel->getPredefinedRequest($requestName);
  104. // Get the default values for the forms
  105. $forms = $this->metadataModel->getForms($savedRequest->datasetID, $savedRequest->schemaCode);
  106. foreach ($forms as $form) {
  107. // Fill each form with the list of criterias and results
  108. $form->criteriaList = $this->metadataModel->getFormFields($savedRequest->datasetID, $form->format, $this->schema, 'criteria');
  109. $form->resultsList = $this->metadataModel->getFormFields($savedRequest->datasetID, $form->format, $this->schema, 'result');
  110. }
  111. // Update the default values with the saved values.
  112. foreach ($forms as $form) {
  113. foreach ($form->criteriaList as $criteria) {
  114. $criteria->isDefaultCriteria = '0';
  115. $criteria->defaultValue = '';
  116. if (array_key_exists($criteria->format.'__'.$criteria->data, $savedRequest->criteriaList)) {
  117. $criteria->isDefaultCriteria = '1';
  118. $criteria->defaultValue = $savedRequest->criteriaList[$criteria->format.'__'.$criteria->data]->value;
  119. }
  120. }
  121. foreach ($form->resultsList as $result) {
  122. $result->isDefaultResult = '0';
  123. if (array_key_exists($result->format.'__'.$result->data, $savedRequest->resultsList)) {
  124. $result->isDefaultResult = '1';
  125. }
  126. }
  127. }
  128. // return the forms
  129. return $forms;
  130. }
  131. /**
  132. * AJAX function : Get the list of available predefined requests.
  133. */
  134. public function ajaxgetpredefinedrequestlistAction() {
  135. $this->logger->debug('ajaxgetpredefinedrequestlist');
  136. $dir = $this->_getParam('dir');
  137. $sort = $this->_getParam('sort');
  138. // Get the predefined values for the forms
  139. $predefinedRequestList = $this->predefinedRequestModel->getPredefinedRequestList($dir, $sort);
  140. // Generate the JSON string
  141. $total = count($predefinedRequestList);
  142. echo '{success:true, total:'.$total.',rows:[';
  143. $json ="";
  144. foreach ($predefinedRequestList as $predefinedRequest) {
  145. $json .= $predefinedRequest->toJSON().",";
  146. }
  147. if (strlen($json) > 1) {
  148. $json = substr($json, 0, -1); // remove the last colon
  149. }
  150. echo $json;
  151. echo ']}';
  152. // No View, we send directly the JSON
  153. $this->_helper->layout()->disableLayout();
  154. $this->_helper->viewRenderer->setNoRender();
  155. }
  156. /**
  157. * AJAX function : Get the criteria of a predefined requests.
  158. */
  159. public function ajaxgetpredefinedrequestcriteriaAction() {
  160. $this->logger->debug('ajaxgetpredefinedrequestcriteria');
  161. $requestName = $this->_getParam('request_name');
  162. // Get the predefined values for the forms
  163. $predefinedRequestCriterias = $this->predefinedRequestModel->getPredefinedRequestCriteria($requestName);
  164. // Generate the JSON string
  165. $total = count($predefinedRequestCriterias);
  166. $json = '{success:true, criteria:[';
  167. foreach ($predefinedRequestCriterias as $criteria) {
  168. $json .= '[';
  169. $json .= $criteria->toJSON();
  170. // add some specific options
  171. if ($criteria->type == "CODE") {
  172. $options = $this->metadataModel->getOptions($criteria->data);
  173. $json .= ',{options:[';
  174. foreach ($options as $option) {
  175. $json .= '["'.$option->code.'","'.$option->label.'"],';
  176. }
  177. $json = substr($json, 0, -1);
  178. $json .= ']}';
  179. } else if ($criteria->type == "RANGE") {
  180. // For the RANGE field, get the min and max values
  181. $range = $this->metadataModel->getRange($criteria->data);
  182. $json .= ',{min:'.$range->min.',max:'.$range->max.'}';
  183. } else {
  184. $json .= ',{}'; // no options
  185. }
  186. $json .= '],';
  187. }
  188. if ($total != 0) {
  189. $json = substr($json, 0, -1);
  190. }
  191. $json .= ']}';
  192. echo $json;
  193. // No View, we send directly the JSON
  194. $this->_helper->layout()->disableLayout();
  195. $this->_helper->viewRenderer->setNoRender();
  196. }
  197. /**
  198. * AJAX function : Save the parameters of the current query as a new predefined request.
  199. *
  200. * @return JSON
  201. */
  202. public function ajaxsavepredefinedrequestAction() {
  203. $this->logger->debug('ajaxsavepredefinedrequest');
  204. $json = "";
  205. // Check the validity of the POST
  206. if (!$this->getRequest()->isPost()) {
  207. $this->logger->debug('form is not a POST');
  208. return $this->_forward('index');
  209. }
  210. $datasetId = $this->getRequest()->getPost('datasetId');
  211. try {
  212. // Create the predefined request object
  213. $predefinedRequest = new PredefinedRequest();
  214. $predefinedRequest->datasetID = $datasetId;
  215. $predefinedRequest->schemaCode = $this->schema;
  216. $predefinedRequest->requestName = 'TEST REQUEST'; // TODO : get from FORM
  217. $predefinedRequest->description = 'TEST REQUEST'; // TODO : get from FORM
  218. // Parse the input parameters
  219. foreach ($_POST as $inputName => $inputValues) {
  220. if (strpos($inputName, "criteria__") === 0) {
  221. foreach ($inputValues as $inputValue) {
  222. // This is a criteria
  223. $criteriaName = substr($inputName, strlen("criteria__"));
  224. $pos = strpos($criteriaName, "__");
  225. $criteriaFormat = substr($criteriaName, 0, $pos);
  226. $criteriaData = substr($criteriaName, $pos + 2);
  227. $field = new PredefinedField();
  228. $field->format = $criteriaFormat;
  229. $field->data = $criteriaData;
  230. $field->value = $inputValue;
  231. if (isset($predefinedRequest->criteriaList[$criteriaFormat.'__'.$criteriaData])) {
  232. $predefinedRequest->criteriaList[$criteriaFormat.'__'.$criteriaData]->value .= ";".$field->value;
  233. } else {
  234. $predefinedRequest->criteriaList[$criteriaFormat.'__'.$criteriaData] = $field;
  235. }
  236. }
  237. }
  238. if (strpos($inputName, "column__") === 0) {
  239. // This is a result column
  240. $columnName = substr($inputName, strlen("column__"));
  241. $pos = strpos($columnName, "__");
  242. $columnFormat = substr($columnName, 0, $pos);
  243. $columnData = substr($columnName, $pos + 2);
  244. $field = new PredefinedField();
  245. $field->format = $columnFormat;
  246. $field->data = $columnData;
  247. $predefinedRequest->resultsList[$columnFormat.'__'.$columnData] = $field;
  248. }
  249. }
  250. // Save the request
  251. $this->predefinedRequestModel->savePredefinedRequest($predefinedRequest);
  252. } catch (Exception $e) {
  253. $this->logger->err('Error while getting result : '.$e);
  254. $json = "{success:false,errorMessage:'".json_encode($e->getMessage())."'}";
  255. }
  256. echo $json;
  257. // No View, we send directly the JSON
  258. $this->_helper->layout()->disableLayout();
  259. $this->_helper->viewRenderer->setNoRender();
  260. }
  261. /**
  262. * Generate the JSON structure corresponding to a list of result and criteria columns.
  263. *
  264. * @param Array[FormFormat] $forms the list of FormFormat elements
  265. */
  266. private function _generateFormsJSON($forms) {
  267. $json = '{success:true,data:[';
  268. foreach ($forms as $form) {
  269. // Add the criteria
  270. $json .= "{".$form->toJSON().',criteria:[';
  271. foreach ($form->criteriaList as $field) {
  272. $json .= '{'.$field->toCriteriaJSON();
  273. // For the SELECT field, get the list of options
  274. if ($field->type == "CODE") {
  275. $options = $this->metadataModel->getOptions($field->data);
  276. $json .= ',p:{options:[';
  277. foreach ($options as $option) {
  278. $json .= '['.json_encode($option->code).','.json_encode($option->label).'],';
  279. }
  280. $json = substr($json, 0, -1);
  281. $json .= ']}';
  282. }
  283. // For the RANGE field, get the min and max values
  284. if ($field->type == "RANGE") {
  285. $range = $this->metadataModel->getRange($field->data);
  286. $json .= ',p:{min:'.$range->min.',max:'.$range->max.'}';
  287. }
  288. $json .= '},';
  289. }
  290. if (count($form->criteriaList) > 0) {
  291. $json = substr($json, 0, -1);
  292. }
  293. // Add the columns
  294. $json .= '],columns:[';
  295. foreach ($form->resultsList as $field) {
  296. $json .= '{'.$field->toResultJSON().'},';
  297. }
  298. if (count($form->resultsList) > 0) {
  299. $json = substr($json, 0, -1);
  300. }
  301. $json .= ']},';
  302. }
  303. if (count($forms) > 0) {
  304. $json = substr($json, 0, -1);
  305. }
  306. $json = $json.']}';
  307. return $json;
  308. }
  309. /**
  310. * AJAX function : Get the list of available forms and criterias for the dataset
  311. */
  312. public function ajaxgetformsAction() {
  313. $this->logger->debug('ajaxgetformsAction');
  314. $datasetId = $this->getRequest()->getPost('datasetId');
  315. $requestName = $this->getRequest()->getPost('requestName');
  316. $this->logger->debug('datasetId : '.$datasetId, $this->schema);
  317. $this->logger->debug('requestName : '.$requestName, $this->schema);
  318. if (!empty($requestName)) {
  319. $forms = $this->_ajaxgetpredefinedrequest($requestName);
  320. } else {
  321. $forms = $this->metadataModel->getForms($datasetId, $this->schema);
  322. foreach ($forms as $form) {
  323. // Fill each form with the list of criterias and results
  324. $form->criteriaList = $this->metadataModel->getFormFields($datasetId, $form->format, $this->schema, 'criteria');
  325. $form->resultsList = $this->metadataModel->getFormFields($datasetId, $form->format, $this->schema, 'result');
  326. }
  327. }
  328. echo $this->_generateFormsJSON($forms);
  329. // No View, we send directly the JSON
  330. $this->_helper->layout()->disableLayout();
  331. $this->_helper->viewRenderer->setNoRender();
  332. }
  333. /**
  334. * AJAX function : Get the list of available datasets
  335. *
  336. * @return JSON The list of forms
  337. */
  338. public function ajaxgetdatasetsAction() {
  339. $datasetIds = $this->metadataModel->getDatasets();
  340. echo "{";
  341. echo "metaData:{";
  342. echo "root:'rows',";
  343. echo "fields:[";
  344. echo "'id',";
  345. echo "'label',";
  346. echo "'is_default'";
  347. echo "]";
  348. echo "},";
  349. echo "rows:".json_encode($datasetIds).'}';
  350. // No View, we send directly the JSON
  351. $this->_helper->layout()->disableLayout();
  352. $this->_helper->viewRenderer->setNoRender();
  353. }
  354. /**
  355. * AJAX function : Get the description of the columns of the result of the query.
  356. *
  357. * @return JSON
  358. */
  359. public function ajaxgetgridcolumnsAction() {
  360. $configuration = Zend_Registry::get("configuration");
  361. ini_set("max_execution_time", $configuration->max_execution_time);
  362. $this->logger->debug('ajaxgetgridcolumns');
  363. $json = "";
  364. // Check the validity of the POST
  365. if (!$this->getRequest()->isPost()) {
  366. $this->logger->debug('form is not a POST');
  367. return $this->_forward('index');
  368. }
  369. $datasetId = $this->getRequest()->getPost('datasetId');
  370. try {
  371. // Parse the input parameters
  372. $criterias = array();
  373. $columns = array();
  374. foreach ($_POST as $inputName => $inputValue) {
  375. if (strpos($inputName, "criteria__") === 0) {
  376. $criteriaName = substr($inputName, strlen("criteria__"));
  377. $criterias[$criteriaName] = $inputValue;
  378. }
  379. if (strpos($inputName, "column__") === 0) {
  380. $columnName = substr($inputName, strlen("column__"));
  381. $columns[$columnName] = $columnName;
  382. }
  383. }
  384. if (sizeof($columns) == 0) {
  385. $json = "{ success: false, errorMessage: 'At least one result column should be selected'}";
  386. } else {
  387. // Generate the SQL Request
  388. $sql = $this->_generateSQLRequest($datasetId, $criterias, $columns);
  389. // Get the website session
  390. $websiteSession = new Zend_Session_Namespace('website');
  391. $where = $websiteSession->SQLWhere;
  392. // Clean previously stored results
  393. $sessionId = session_id();
  394. $this->logger->debug('SessionId : '.$sessionId);
  395. $this->resultLocationModel->cleanPreviousResults($sessionId);
  396. // Run the request to store a temporary result table (for the web mapping)
  397. $this->resultLocationModel->fillLocationResult($where, $sessionId, $this->getLocationTable(), $this->visualisationSRS);
  398. // Calculate the number of lines of result
  399. $countResult = $this->genericModel->executeRequest("SELECT COUNT(*) as count ".$where);
  400. $websiteSession->count = $countResult[0]['count'];
  401. // Prepare the metadata information
  402. $metadata = array();
  403. $traductions = array();
  404. $i = 0;
  405. foreach ($columns as $column) {
  406. $split = explode("__", $column);
  407. $format = $split[0];
  408. $field = $split[1];
  409. $formField = $this->metadataModel->getFormField($format, $field);
  410. $metadata[$i] = $formField;
  411. // Prepare the traduction of the code lists
  412. if ($formField->type == "CODE") {
  413. $traductions[$i] = $this->metadataModel->getModeFromUnit($formField->unit);
  414. }
  415. $i++;
  416. }
  417. // Store the metadata in session
  418. $websiteSession->metadata = $metadata;
  419. $websiteSession->traductions = $traductions;
  420. $websiteSession->datasetId = $datasetId;
  421. // Send the result as a JSON String
  422. $json = '{success:true,';
  423. // Metadata
  424. $json .= '"columns":[';
  425. // Get the titles of the columns
  426. foreach ($metadata as $formField) {
  427. $json .= '{'.$formField->toJSON().', hidden:false},';
  428. }
  429. // Add the plot location in WKT
  430. $json .= '{name:"id",label:"Identifier of the line",inputType:"TEXT",definition:"The plot identifier", hidden:true},';
  431. $json .= '{name:"location_centroid",label:"Location centroid",inputType:"TEXT",definition:"The plot location", hidden:true}';
  432. $json .= ']}';
  433. }
  434. } catch (Exception $e) {
  435. $this->logger->err('Error while getting result : '.$e);
  436. $json = "{success:false,errorMessage:'".json_encode($e->getMessage())."'}";
  437. }
  438. echo $json;
  439. // Activate the result layer
  440. $mappingSession->activatedLayers[] = 'result_locations';
  441. // No View, we send directly the JSON
  442. $this->_helper->layout()->disableLayout();
  443. $this->_helper->viewRenderer->setNoRender();
  444. }
  445. /**
  446. * AJAX function : Get a page of query result data.
  447. *
  448. * @return JSON
  449. */
  450. public function ajaxgetgridrowsAction() {
  451. $this->logger->debug('ajaxgetgridrows');
  452. $json = "";
  453. try {
  454. // Retrieve the SQL request from the session
  455. $websiteSession = new Zend_Session_Namespace('website');
  456. $sql = $websiteSession->SQLQuery;
  457. $where = $websiteSession->SQLWhere;
  458. $countResult = $websiteSession->count;
  459. // Retrive the metadata
  460. $metadata = $websiteSession->metadata;
  461. $traductions = $websiteSession->traductions;
  462. // Get the datatable parameters
  463. $start = $this->getRequest()->getPost('start');
  464. $length = $this->getRequest()->getPost('limit');
  465. $sort = $this->getRequest()->getPost('sort');
  466. $sortDir = $this->getRequest()->getPost('dir');
  467. $filter = "";
  468. if ($sort != "") {
  469. $filter .= " ORDER BY ".$sort." ".$sortDir;
  470. }
  471. if (!empty($length)) {
  472. $filter .= " LIMIT ".$length;
  473. }
  474. if (!empty($start)) {
  475. $filter .= " OFFSET ".$start;
  476. }
  477. // Execute the request
  478. $result = $this->genericModel->executeRequest($sql.$filter);
  479. // Send the result as a JSON String
  480. $json = '{success:true,';
  481. $json .= 'total:'.$countResult.',';
  482. $json .= 'rows:[';
  483. foreach ($result as $line) {
  484. $json .= '[';
  485. $nbcol = sizeof($line);
  486. $keys = array_keys($line);
  487. for ($i = 0; $i < $nbcol - 2; $i++) {
  488. // the last 5 result columns are reserved
  489. $colName = $keys[$i]; // get the name of the column
  490. $value = $line[$colName];
  491. $formField = $metadata[$i];
  492. if ($formField->type == "CODE" && $value != "") {
  493. // Manage code traduction
  494. $label = isset($traductions[$i][$value]) ? $traductions[$i][$value] : '';
  495. $json .= json_encode($label == null ? '' : $label).',';
  496. } else {
  497. $json .= json_encode($value).',';
  498. }
  499. }
  500. // Add the line id
  501. $json .= json_encode($line['id']).',';
  502. // Add the plot location in WKT
  503. $json .= json_encode($line['location_center']); // The last column is the location center
  504. $json .= '],';
  505. }
  506. if (sizeof($result) != 0) {
  507. $json = substr($json, 0, -1);
  508. }
  509. $json .= ']}';
  510. } catch (Exception $e) {
  511. $this->logger->err('Error while getting result : '.$e);
  512. $json = "{success:false,errorMessage:'".json_encode($e->getMessage())."'}";
  513. }
  514. echo $json;
  515. // No View, we send directly the JSON
  516. $this->_helper->layout()->disableLayout();
  517. $this->_helper->viewRenderer->setNoRender();
  518. }
  519. /**
  520. * Generate the SQL request to get the detailed information about a plot or a line of result.
  521. *
  522. * @param String $id The unique identifier of the plot or line (a concatenation of the primary keys of all involved tables)
  523. * @param String $leafTable The leaf table
  524. * @param String $mode if 'LINE', will generate a request corresponding to a single line of result
  525. * else it will generate a SQL query with no where clause.
  526. */
  527. private function _generateSQLDetailRequest($id, $leafTable, $mode = 'LINE') {
  528. $this->logger->debug('__generateSQLDetailRequest leafTable : '.$leafTable);
  529. $select = "SELECT ";
  530. $from = " FROM ";
  531. $where = " WHERE (1 = 1) ";
  532. $uniqueId = ""; // The concatenation of columns used as an unique ID for the line
  533. $detailFields = array(); // the list of fields in the detail request
  534. $userSession = new Zend_Session_Namespace('user');
  535. $role = $userSession->role;
  536. $countryCode = $userSession->user->countryCode;
  537. //
  538. // Get the Tree associed with the leaf table
  539. //
  540. $tables = array();
  541. // Get the ancestors of the table and the foreign keys
  542. $ancestors = $this->metadataModel->getTablesTree($leafTable, null, $this->schema);
  543. // Reverse the order of the list and store by indexing with the table name
  544. // If the table is already used it will be overriden
  545. // The root table (Location) should appear first
  546. $ancestors = array_reverse($ancestors);
  547. foreach ($ancestors as $ancestor) {
  548. $tables[$ancestor->getLogicalName()] = $ancestor;
  549. }
  550. //
  551. // Prepare the SELECT clause
  552. //
  553. foreach ($tables as $table) {
  554. // Get the list of fields of the table
  555. $tableFields = $this->metadataModel->getTableColumnsForDisplay($table->tableFormat, $this->schema);
  556. foreach ($tableFields as $tableField) {
  557. // Get the form field corresponding to the data field.
  558. $formfield = $this->metadataModel->getFormField($tableField->sourceFormName, $tableField->sourceFieldName);
  559. $columnName = $tableField->columnName;
  560. if ($formfield->inputType == "DATE") {
  561. $select .= "to_char(".$table->getLogicalName().".".$columnName.", 'YYYY/MM/DD')";
  562. } else if ($formfield->inputType == "GEOM") {
  563. $select .= "asText(".$table->getLogicalName().".".$columnName.")";
  564. } else {
  565. $select .= $table->getLogicalName().".".$columnName;
  566. }
  567. // Build the SELECT
  568. $select .= " AS ".$tableField->sourceFormName."__".$tableField->sourceFieldName.", ";
  569. // Store the field
  570. $detailFields[] = $formfield;
  571. }
  572. }
  573. $select = substr($select, 0, -2);
  574. $websiteSession = new Zend_Session_Namespace('website');
  575. $websiteSession->detailFields = $detailFields;
  576. //
  577. // Prepare the FROM clause
  578. //
  579. // Get the root table;
  580. $rootTable = array_shift($tables);
  581. $from .= $rootTable->tableName." ".$rootTable->getLogicalName();
  582. if ($role->isEuropeLevel != '1') {
  583. // Check the user country code
  584. $where .= " AND ".$rootTable->tableFormat.".COUNTRY_CODE = '".trim($countryCode)."'";
  585. }
  586. // Add the joined tables
  587. foreach ($tables as $tableFormat => $tableTreeData) {
  588. // Join the table
  589. if ($tableTreeData->isColumnOriented == '1') {
  590. $from .= " LEFT JOIN ";
  591. } else {
  592. $from .= " JOIN ";
  593. }
  594. $from .= $tableTreeData->tableName." ".$tableTreeData->getLogicalName()." on (";
  595. // Add the foreign key
  596. $keys = explode(',', $tableTreeData->keys);
  597. foreach ($keys as $key) {
  598. $from .= $tableTreeData->getLogicalName().".".trim($key)." = ".$tableTreeData->parentTable.".".trim($key)." AND ";
  599. }
  600. $from = substr($from, 0, -5);
  601. // Create an unique Id.
  602. $identifiers = explode(',', $tableTreeData->identifiers);
  603. foreach ($identifiers as $identifier) {
  604. if ($uniqueId != "") {
  605. $uniqueId .= " || '_' || ";
  606. }
  607. $uniqueId .= $tableTreeData->getLogicalName().".".trim($identifier);
  608. }
  609. // Check the user country code
  610. if ($role->isEuropeLevel != '1') {
  611. $countryCode = $userSession->user->countryCode;
  612. $from .= " AND ".$tableTreeData->getLogicalName().".country_code = '".trim($countryCode)."'";
  613. }
  614. // Check is the table is column-oriented
  615. if ($tableTreeData->isColumnOriented == '1') {
  616. $from .= " AND ".$tableTreeData->getLogicalName().".variable_name = '".$tableTreeData->fieldName."'";
  617. }
  618. $from .= ") ";
  619. }
  620. // Add some hard-coded, needed fields
  621. $select .= ", ".$this->getLocationTable().".country_code as loc_country_code, "; // The country code (used for the mapping view)
  622. $select .= $this->getLocationTable().".plot_code as loc_plot_code, "; // The plot code (used for the mapping view)
  623. $select .= $this->getLocationTable().".the_geom as the_geom, "; // The geom (used for the mapping view)
  624. $select .= 'ymin(box2d(transform('.$this->getLocationTable().'.the_geom,'.$this->visualisationSRS.'))) as location_y_min, '; // The location boundingbox (for zooming in javascript)
  625. $select .= 'ymax(box2d(transform('.$this->getLocationTable().'.the_geom,'.$this->visualisationSRS.'))) as location_y_max, ';
  626. $select .= 'xmin(box2d(transform('.$this->getLocationTable().'.the_geom,'.$this->visualisationSRS.'))) as location_x_min, ';
  627. $select .= 'xmax(box2d(transform('.$this->getLocationTable().'.the_geom,'.$this->visualisationSRS.'))) as location_x_max';
  628. // Add the identifier of the line or plot
  629. if ($mode == 'LINE') {
  630. $where .= " AND ".$uniqueId." = '".$id."'";
  631. }
  632. $sql = $select.$from.$where;
  633. $this->logger->debug('SQL DETAIL '.$sql);
  634. // Return the completed SQL request
  635. return $sql;
  636. }
  637. /**
  638. * Generate the SQL request corresponding to a list of parameters
  639. *
  640. * @param String $datasetId The selected dataset
  641. * @param Array[String => String] $criterias The list of criterias with their value
  642. * @param Array[String => String] $columns The result columns to display
  643. */
  644. private function _generateSQLRequest($datasetId, $criterias, $columns) {
  645. $this->logger->debug('_generateSQLRequest');
  646. // Get an access to the session
  647. $userSession = new Zend_Session_Namespace('user');
  648. $websiteSession = new Zend_Session_Namespace('website');
  649. // Store the criterias in session for a future use
  650. $websiteSession->criterias = $criterias;
  651. $select = "SELECT ";
  652. $from = " FROM ";
  653. $where = "WHERE (1 = 1) ";
  654. $firstJoinedTable = ""; // The logical name of the first table in the join
  655. $uniqueId = ""; // The concatenation of columns used as an unique ID for the line, for use in the detail view
  656. $leafTable = ""; // The logical name of the last table (leaf), for use in the detail view
  657. $sort = ""; // The concatenation of columns used as an unique sort order
  658. $role = $userSession->role;
  659. $countryCode = $userSession->user->countryCode;
  660. //
  661. // Get the mapping for each field
  662. //
  663. $dataCols = array();
  664. $dataCrits = array();
  665. foreach ($columns as $column) {
  666. $split = explode("__", $column);
  667. $format = $split[0];
  668. $field = $split[1];
  669. $tableField = $this->metadataModel->getFieldMapping($format, $field, $this->schema);
  670. $dataCols[] = $tableField;
  671. }
  672. foreach ($criterias as $criteriaName => $value) {
  673. $split = explode("__", $criteriaName);
  674. $format = $split[0];
  675. $field = $split[1];
  676. $tableField = $this->metadataModel->getFieldMapping($format, $field, $this->schema);
  677. $tableField->value = $value;
  678. $dataCrits[] = $tableField;
  679. }
  680. //
  681. // Build the list of needed tables and associate each field with its source table
  682. //
  683. $tables = array();
  684. foreach ($dataCols as $field) {
  685. // Get the ancestors of the table and the foreign keys
  686. $this->logger->debug('table : '.$field->format);
  687. $ancestors = $this->metadataModel->getTablesTree($field->format, $field->sourceFieldName, $this->schema);
  688. // Associate the field with its source table
  689. $field->sourceTable = $ancestors[0];
  690. // Reverse the order of the list and store by indexing with the table name
  691. // If the table is already used it will be overriden
  692. // The root table (Location should appear first)
  693. $ancestors = array_reverse($ancestors);
  694. foreach ($ancestors as $ancestor) {
  695. $tables[$ancestor->getLogicalName()] = $ancestor;
  696. }
  697. }
  698. foreach ($dataCrits as $field) {
  699. // Get the ancestors of the table and the foreign keys
  700. $ancestors = $this->metadataModel->getTablesTree($field->format, $field->sourceFieldName, $this->schema);
  701. // Associate the field with its source table
  702. $field->sourceTable = $ancestors[0];
  703. // Reverse the order of the list and store by indexing with the table name
  704. // If the table is already used it will be overriden
  705. // The root table (Location should appear first)
  706. $ancestors = array_reverse($ancestors);
  707. foreach ($ancestors as $ancestor) {
  708. $tables[$ancestor->getLogicalName()] = $ancestor;
  709. }
  710. }
  711. //
  712. // Prepare the SELECT clause
  713. //
  714. foreach ($dataCols as $tableField) {
  715. $formfield = $this->metadataModel->getFormField($tableField->sourceFormName, $tableField->sourceFieldName);
  716. if ($tableField->sourceTable->isColumnOriented == '1') {
  717. // For complementary values, stored in column_oriented tables
  718. if ($formfield->type == "NUMERIC") {
  719. $columnName = "float_value";
  720. } else if ($formfield->type == "INTEGER") {
  721. $columnName = "int_value";
  722. } else {
  723. $columnName = "text_value";
  724. }
  725. } else {
  726. $columnName = $tableField->columnName;
  727. }
  728. if ($formfield->inputType == "DATE") {
  729. $select .= "to_char(".$tableField->sourceTable->getLogicalName().".".$columnName.", 'YYYY/MM/DD')";
  730. } else if ($formfield->inputType == "GEOM") {
  731. $select .= "asText(st_transform(".$tableField->sourceTable->getLogicalName().".".$columnName.",".$this->visualisationSRS."))";
  732. } else {
  733. $select .= $tableField->sourceTable->getLogicalName().".".$columnName;
  734. }
  735. $select .= " AS ".$tableField->sourceFormName."__".$tableField->sourceFieldName.", ";
  736. }
  737. $select = substr($select, 0, -2);
  738. //
  739. // Prepare the FROM clause
  740. //
  741. // Get the root table;
  742. $rootTable = array_shift($tables);
  743. $from .= $rootTable->tableName." ".$rootTable->getLogicalName();
  744. if ($role->isEuropeLevel != '1') {
  745. // Check the user country code
  746. $where .= " AND ".$rootTable->tableFormat.".COUNTRY_CODE = '".trim($countryCode)."'";
  747. }
  748. // Add the joined tables
  749. foreach ($tables as $tableFormat => $tableTreeData) {
  750. // We store the table name of the firstly joined table for a later use
  751. if ($firstJoinedTable == "") {
  752. $firstJoinedTable = $tableTreeData->getLogicalName();
  753. }
  754. // We store the name of the last joined table
  755. $leafTable = $tableTreeData->getLogicalName();
  756. // Join the table
  757. if ($tableTreeData->isColumnOriented == '1') {
  758. $from .= " LEFT JOIN ";
  759. } else {
  760. $from .= " JOIN ";
  761. }
  762. $from .= $tableTreeData->tableName." ".$tableTreeData->getLogicalName()." on (";
  763. // Add the foreign keys
  764. $keys = explode(',', $tableTreeData->keys);
  765. foreach ($keys as $key) {
  766. $from .= $tableTreeData->getLogicalName().".".trim($key)." = ".$tableTreeData->parentTable.".".trim($key)." AND ";
  767. }
  768. $from = substr($from, 0, -5);
  769. // Create an unique Id.
  770. $identifiers = explode(',', $tableTreeData->identifiers);
  771. foreach ($identifiers as $identifier) {
  772. // Concatenate the column to create a unique Id
  773. if ($uniqueId != "") {
  774. $uniqueId .= " || '_' || ";
  775. }
  776. $uniqueId .= $tableTreeData->getLogicalName().".".trim($identifier);
  777. // Create a unique sort order
  778. if ($sort != "") {
  779. $sort .= ", ";
  780. }
  781. $sort .= $tableTreeData->getLogicalName().".".trim($identifier);
  782. }
  783. // Check the user country code
  784. if ($role->isEuropeLevel != '1') {
  785. $countryCode = $userSession->user->countryCode;
  786. $from .= " AND ".$tableTreeData->getLogicalName().".country_code = '".trim($countryCode)."'";
  787. }
  788. // Check is the table is column-oriented
  789. if ($tableTreeData->isColumnOriented == '1') {
  790. $from .= " AND ".$tableTreeData->getLogicalName().".variable_name = '".$tableTreeData->fieldName."'";
  791. }
  792. $from .= ") ";
  793. }
  794. //
  795. // Prepare the WHERE clause
  796. //
  797. foreach ($dataCrits as $tableField) {
  798. $formfield = $this->metadataModel->getFormField($tableField->sourceFormName, $tableField->sourceFieldName);
  799. if ($tableField->sourceTable->isColumnOriented == '1') {
  800. // For complementary values, stored in column_oriented tables
  801. if ($formfield->type == "NUMERIC") {
  802. $columnName = "float_value";
  803. } else if ($formfield->type == "INTEGER") {
  804. $columnName = "int_value";
  805. } else {
  806. $columnName = "text_value";
  807. }
  808. } else {
  809. $columnName = $tableField->columnName;
  810. }
  811. if ($formfield->inputType == "SELECT") {
  812. $optionsList = "";
  813. // We go thru the list of selected values (a criteria can be added more than once)
  814. foreach ($tableField->value as $option) {
  815. if ($option != "") {
  816. $optionsList .= "'".$option."', ";
  817. }
  818. }
  819. if ($optionsList != "") {
  820. $optionsList = substr($optionsList, 0, -2);
  821. $where .= " AND ".$tableField->sourceTable->getLogicalName().".".$columnName." IN (".$optionsList.")";
  822. }
  823. } else if ($formfield->inputType == "NUMERIC") {
  824. $numericcrit = "";
  825. // We go thru the list of selected values (a criteria can be added more than once)
  826. foreach ($tableField->value as $crit) {
  827. if ($crit != "") {
  828. // Two values separated by a dash, we make a min / max comparison
  829. $pos = strpos($crit, " - ");
  830. if ($pos != false) {
  831. $minValue = substr($crit, 0, $pos);
  832. $maxValue = substr($crit, $pos + 3);
  833. $numericcrit .= '(';
  834. $isBegin = 0;
  835. if (!empty($minValue)) {
  836. $isBegin = 1;
  837. $numericcrit .= $tableField->sourceTable->getLogicalName().".".$columnName." >= ".$minValue." ";
  838. }
  839. if (!empty($maxValue)) {
  840. if ($isBegin) {
  841. $numericcrit .= ' AND ';
  842. }
  843. $numericcrit .= $tableField->sourceTable->getLogicalName().".".$columnName." <= ".$maxValue." ";
  844. }
  845. $numericcrit .= ') OR ';
  846. } else {
  847. // One value, we make an equel comparison
  848. $numericcrit .= "(".$tableField->sourceTable->getLogicalName().".".$columnName." = ".$crit.") OR ";
  849. }
  850. }
  851. }
  852. if ($numericcrit != "") {
  853. $numericcrit = substr($numericcrit, 0, -4);
  854. $where .= " AND( ".$numericcrit.")";
  855. }
  856. } else if ($formfield->inputType == "DATE") {
  857. // Four formats are possible:
  858. // "YYYY/MM/DD" : for equal value
  859. // ">= YYYY/MM/DD" : for the superior value
  860. // "<= YYYY/MM/DD" : for the inferior value
  861. // "YYYY/MM/DD - YYYY/MM/DD" : for the interval
  862. $optionsList = "";
  863. // We go thru the list of selected values (a criteria can be added more than once)
  864. foreach ($tableField->value as $option) {
  865. if (!empty($option)) {
  866. if (strlen($option) == 10) {
  867. // Case "YYYY/MM/DD"
  868. if (Zend_Date::isDate($option, 'YYYY/MM/DD')) {
  869. // One value, we make an equel comparison
  870. $optionsList .= '(';
  871. $optionsList .= $tableField->sourceTable->getLogicalName().".".$columnName." = to_date('".$option."', 'YYYY/MM/DD') ";
  872. $optionsList .= ') OR ';
  873. }
  874. } else if (strlen($option) == 13 && substr($option, 0, 2) == '>=') {
  875. // Case ">= YYYY/MM/DD"
  876. $beginDate = substr($option, 3, 10);
  877. if (Zend_Date::isDate($beginDate, 'YYYY/MM/DD')) {
  878. $optionsList .= '(';
  879. $optionsList .= $tableField->sourceTable->getLogicalName().".".$columnName." >= to_date('".$beginDate."', 'YYYY/MM/DD') ";
  880. $optionsList .= ') OR ';
  881. }
  882. } else if (strlen($option) == 13 && substr($option, 0, 2) == '<=') {
  883. // Case "<= YYYY/MM/DD"
  884. $endDate = substr($option, 3, 10);
  885. if (Zend_Date::isDate($endDate, 'YYYY/MM/DD')) {
  886. $optionsList .= '(';
  887. $optionsList .= $tableField->sourceTable->getLogicalName().".".$columnName." <= to_date('".$endDate."', 'YYYY/MM/DD') ";
  888. $optionsList .= ') OR ';
  889. }
  890. } else if (strlen($option) == 23) {
  891. // Case "YYYY/MM/DD - YYYY/MM/DD"
  892. $beginDate = substr($option, 0, 10);
  893. $endDate = substr($option, 13, 10);
  894. if (Zend_Date::isDate($beginDate, 'YYYY/MM/DD') && Zend_Date::isDate($endDate, 'YYYY/MM/DD')) {
  895. $optionsList .= '(';
  896. $optionsList .= $tableField->sourceTable->getLogicalName().".".$columnName." >= to_date('".$beginDate."', 'YYYY/MM/DD') ";
  897. $optionsList .= ' AND ';
  898. $optionsList .= $tableField->sourceTable->getLogicalName().".".$columnName." <= to_date('".$endDate."', 'YYYY/MM/DD') ";
  899. $optionsList .= ') OR ';
  900. }
  901. }
  902. }
  903. }
  904. if (!empty($optionsList)) {
  905. $optionsList = substr($optionsList, 0, -4);
  906. $where .= " AND (".$optionsList.")";
  907. }
  908. } else if ($formfield->inputType == "CHECKBOX") {
  909. $optionsList = "";
  910. // We go thru the list of selected values (a criteria can be added more than once)
  911. foreach ($tableField->value as $option) {
  912. $optionsList .= $tableField->sourceTable->getLogicalName().".".$columnName;
  913. if ($option == "1") {
  914. $optionsList .= " = '1'";
  915. } else {
  916. $optionsList .= " = '0'";
  917. }
  918. $optionsList .= ' OR ';
  919. }
  920. $optionsList = substr($optionsList, 0, -3);
  921. $where .= " AND (".$optionsList.")";
  922. } else if ($formfield->inputType == "GEOM") {
  923. $optionsList = "";
  924. // We go thru the list of selected values (a criteria can be added more than once)
  925. foreach ($tableField->value as $option) {
  926. if ($option != "") {
  927. $optionsList .= "(ST_intersects(".$tableField->sourceTable->getLogicalName().".".$columnName.", transform(ST_GeomFromText('".$option."', ".$this->visualisationSRS."), ".$this->databaseSRS.")))";
  928. $optionsList .= ' OR ';
  929. }
  930. }
  931. if ($optionsList != "") {
  932. $optionsList = substr($optionsList, 0, -3);
  933. $where .= " AND (".$optionsList.")";
  934. }
  935. } else { // Default case is a STRING, we search with a ilike %%
  936. $optionsList = "";
  937. foreach ($tableField->value as $option) {
  938. $optionsList .= $tableField->sourceTable->getLogicalName().".".$columnName." ILIKE '%".trim($option)."%' OR ";
  939. }
  940. $optionsList = substr($optionsList, 0, -4);
  941. $where .= " AND (".$optionsList.")";
  942. }
  943. }
  944. // If needed we check on the data submission type
  945. if (!empty($datasetId) && $firstJoinedTable != "") {
  946. if ($this->schema == 'RAW_DATA') {
  947. $from .= " JOIN data_submission ON (data_submission.submission_id = ".$firstJoinedTable.".submission_id) ";
  948. $where .= " AND data_submission.request_id = '".$datasetId."' ";
  949. } else {
  950. $where .= " AND ".$firstJoinedTable.".request_id = '".$datasetId."' ";
  951. }
  952. }
  953. // Add some hard-coded, needed fields
  954. $select .= ", ".$uniqueId." as id, "; // The identifier of the line (for the details view in javascript)
  955. $select .= "astext(centroid(st_transform(".$this->getLocationTable().".the_geom,".$this->visualisationSRS."))) as location_center "; // The location center (for zooming in javascript)
  956. $sql = $select.$from.$where;
  957. // Store the SQL Request in session
  958. $websiteSession->SQLQuery = $sql;
  959. $websiteSession->SQLWhere = $from.$where;
  960. $websiteSession->leafTable = $leafTable;
  961. $websiteSession->sort = $sort;
  962. // Return the completed SQL request
  963. return $sql;
  964. }
  965. /**
  966. * Get the parameters used to initialise the result grid.
  967. */
  968. public function getgridparametersAction() {
  969. $this->logger->debug('getgridparametersAction');
  970. // Get the parameters from configuration file
  971. $configuration = Zend_Registry::get("configuration");
  972. $this->view->pagesize = $configuration->pagesize; // Number of lines on a page
  973. $userSession = new Zend_Session_Namespace('user');
  974. $permissions = $userSession->permissions;
  975. $this->view->hideExportCSV = 'true'; // By defaut the export is hidden
  976. $this->view->hideInterpolationMenuItem = 'true';
  977. $this->view->hideAggregationCsvExportMenuItem = 'true';
  978. $this->view->hideAggregationButton = 'true';
  979. if (!empty($permissions)) {
  980. if ($this->schema == 'RAW_DATA' && array_key_exists('EXPORT_RAW_DATA', $permissions)) {
  981. $this->view->hideExportCSV = 'false';
  982. }
  983. if ($this->schema == 'HARMONIZED_DATA' && array_key_exists('EXPORT_HARMONIZED_DATA', $permissions)) {
  984. $this->view->hideExportCSV = 'false';
  985. }
  986. if ($this->schema == 'HARMONIZED_DATA' && array_key_exists('DATA_QUERY_AGGREGATED', $permissions)) {
  987. $this->view->hideAggregationButton = 'false';
  988. $this->view->hideAggregationCsvExportMenuItem = 'false';
  989. }
  990. if ($this->schema == 'HARMONIZED_DATA' && array_key_exists('DATA_INTERPOLATION', $permissions)) {
  991. $this->view->hideInterpolationMenuItem = 'false';
  992. }
  993. }
  994. $this->_helper->layout()->disableLayout();
  995. $this->render('grid-parameters');
  996. }
  997. /**
  998. * Get the details associed with a result location (clic on the map).
  999. * @return JSON representing the detail of the result line.
  1000. */
  1001. public function getmapdetailsAction() {
  1002. $this->logger->debug('getMapDetailsAction');
  1003. // The request is a click coming from the map
  1004. // We get back the identifier of the location
  1005. // id = country_code + '_' + plot_code;
  1006. $id = $this->getRequest()->getPost('id');
  1007. // Parse the elements of the identifier
  1008. $split = explode("__", $id);
  1009. $countryCode = $split[0];
  1010. $plotCode = $split[1];
  1011. // We get the current dataset from the session
  1012. $websiteSession = new Zend_Session_Namespace('website');
  1013. $datasetId = $websiteSession->datasetId;
  1014. // Get the leaf table for the current dataset
  1015. $leafTable = $websiteSession->leafTable;
  1016. // Get the detailled data
  1017. $sql = $this->_generateSQLDetailRequest($id, $leafTable, 'ALL');
  1018. $this->logger->debug('$this->schema : '.$this->schema);
  1019. if ($this->schema == 'HARMONIZED_DATA') {
  1020. $sql .= " AND HARMONIZED_LOCATION_DATA.COUNTRY_CODE = '".$countryCode."'";
  1021. $sql .= " AND HARMONIZED_LOCATION_DATA.PLOT_CODE = '".$plotCode."'";
  1022. } else {
  1023. $sql .= " AND LOCATION_DATA.COUNTRY_CODE = '".$countryCode."'";
  1024. $sql .= " AND LOCATION_DATA.PLOT_CODE = '".$plotCode."'";
  1025. }
  1026. $result = $this->genericModel->executeRequest($sql);
  1027. // Get back the list of fields in the detail view
  1028. $detailFields = $websiteSession->detailFields;
  1029. // Prepare the metadata information
  1030. $metadata = array();
  1031. $traductions = array();
  1032. $i = 0;
  1033. foreach ($detailFields as $detailField) {
  1034. $metadata[$i] = $detailField;
  1035. // Prepare the traduction of the code lists
  1036. if ($detailField->type == "CODE") {
  1037. $traductions[$i] = $this->metadataModel->getModeFromUnit($detailField->unit);
  1038. }
  1039. $i++;
  1040. }
  1041. // Return the detailled information about the plot
  1042. $fields = "";
  1043. // Run thru the resultset one time to get the content of the first table values
  1044. $line = $result[0]; // Get only the first line
  1045. $nbcol = sizeof($line);
  1046. $keys = array_keys($line);
  1047. $col0 = $metadata[0]; // Get the name of the first form
  1048. $firstFormName = $col0->format;
  1049. $hasdetailledInfo = false; // Indicate that the resultset has more columns than those of the root table
  1050. $fields .= "{title:'Plot data', is_array:false, fields:[";
  1051. for ($i = 0; $i < $nbcol - 7; $i++) {
  1052. // the last 7 result columns are reserved
  1053. $colName = $keys[$i]; // get the name of the column
  1054. $value = $line[$colName];
  1055. $formField = $metadata[$i];
  1056. if ($formField->format == $firstFormName) {
  1057. if ($formField->type == "CODE" && $value != "") {
  1058. // Manage code traduction
  1059. $label = $traductions[$i][$value];
  1060. $fields .= "{label:".json_encode($formField->label).", value : ".json_encode($label)."}, ";
  1061. } else {
  1062. $fields .= "{label:".json_encode($formField->label).", value : ".json_encode($value)."}, ";
  1063. }
  1064. } else {
  1065. $hasdetailledInfo = true;
  1066. }
  1067. }
  1068. $fields = substr($fields, 0, -2);
  1069. $fields .= "]}";
  1070. // Run thru the resultset a second time to get other values
  1071. if ($hasdetailledInfo) {
  1072. $isFirstTime = true;
  1073. foreach ($result as $line) {
  1074. $nbcol = sizeof($line);
  1075. $keys = array_keys($line);
  1076. $col0 = $metadata[0]; // Get the name of the first form
  1077. $firstFormName = $col0->format;
  1078. if ($isFirstTime) {
  1079. // Add the column definition
  1080. $fields .= ",{title:'Detailled info', is_array:true, columns:[";
  1081. for ($i = 0; $i < $nbcol - 7; $i++) {
  1082. // the last 7 result columns are reserved
  1083. $colName = $keys[$i]; // get the name of the column
  1084. $value = $line[$colName];
  1085. $formField = $metadata[$i];
  1086. if ($formField->format != $firstFormName) {
  1087. // Add he column only if not from the root table
  1088. $fields .= "{name:".json_encode($colName).", label:".json_encode($formField->label)."}, ";
  1089. }
  1090. }
  1091. $fields = substr($fields, 0, -2);
  1092. $fields .= "], rows:[";
  1093. $isFirstTime = false;
  1094. }
  1095. $fields .= "[";
  1096. for ($i = 0; $i < $nbcol - 7; $i++) {
  1097. // the last 7 result columns are reserved
  1098. $colName = $keys[$i]; // get the name of the column
  1099. $value = $line[$colName];
  1100. $formField = $metadata[$i];
  1101. if ($formField->format != $firstFormName) {
  1102. if ($formField->type == "CODE" && $value != "") {
  1103. // Manage code traduction
  1104. $label = $traductions[$i][$value];
  1105. $fields .= json_encode($label).", ";
  1106. } else {
  1107. $fields .= json_encode($value).", ";
  1108. }
  1109. }
  1110. }
  1111. $fields = substr($fields, 0, -2); // remove the last comma
  1112. $fields .= "],";
  1113. }
  1114. if ($fields != "") {
  1115. $fields = substr($fields, 0, -1); // remove the last comma
  1116. }
  1117. $fields .= ']}';
  1118. }
  1119. $bb = $this->_setupBoundingBox($line);
  1120. $bb2 = $this->_setupBoundingBox($line, 200000); // Prepare an overview bbox
  1121. $locationPlotCode = $line['loc_plot_code'];
  1122. $json = "{title:'Plot ".$locationPlotCode."', formats:[";
  1123. $json .= $fields;
  1124. $json .= "],";
  1125. $json .= "map:[{title:'image',";
  1126. $json .= "url:'".$this->baseUrl."/proxy/gettile?";
  1127. $json .= "&LAYERS=".(empty($this->detailsLayers) ? '' : $this->detailsLayers[0]);
  1128. $json .= "&TRANSPARENT=true";
  1129. $json .= "&FORMAT=image%2FPNG";
  1130. $json .= "&SERVICE=WMS";
  1131. $json .= "&VERSION=1.1.1";
  1132. $json .= "&REQUEST=GetMap";
  1133. $json .= "&STYLES=";
  1134. $json .= "&EXCEPTIONS=application%2Fvnd.ogc.se_inimage";
  1135. $json .= "&SRS=EPSG%3A".$this->visualisationSRS;
  1136. $json .= "&BBOX=".$bb['location_x_min'].",".$bb['location_y_min'].",".$bb['location_x_max'].",".$bb['location_y_max'];
  1137. $json .= "&WIDTH=300";
  1138. $json .= "&HEIGHT=300";
  1139. $json .= "&map.scalebar=STATUS+embed";
  1140. $json .= "&sessionid=".session_id();
  1141. $json .= "&plot_code=".$locationPlotCode."'},";
  1142. $json .= "{title:'image',";
  1143. $json .= "url:'".$this->baseUrl."/proxy/gettile?";
  1144. $json .= "&LAYERS=".(empty($this->detailsLayers) ? '' : $this->detailsLayers[1]);
  1145. $json .= "&TRANSPARENT=true";
  1146. $json .= "&FORMAT=image%2FPNG";
  1147. $json .= "&SERVICE=WMS";
  1148. $json .= "&VERSION=1.1.1";
  1149. $json .= "&REQUEST=GetMap";
  1150. $json .= "&STYLES=";
  1151. $json .= "&EXCEPTIONS=application%2Fvnd.ogc.se_inimage";
  1152. $json .= "&SRS=EPSG%3A".$this->visualisationSRS;
  1153. $json .= "&BBOX=".$bb2['location_x_min'].",".$bb2['location_y_min'].",".$bb2['location_x_max'].",".$bb2['location_y_max'];
  1154. $json .= "&WIDTH=300";
  1155. $json .= "&HEIGHT=300";
  1156. $json .= "&sessionid=".session_id();
  1157. $json .= "&CLASS=REDSTAR";
  1158. $json .= "&map.scalebar=STATUS+embed";
  1159. $json .= "&plot_code=".$locationPlotCode."'}]}";
  1160. echo $json;
  1161. // No View, we send directly the JSON
  1162. $this->_helper->layout()->disableLayout();
  1163. $this->_helper->viewRenderer->setNoRender();
  1164. }
  1165. /**
  1166. * Get the details associed with a result line (clic on the "detail button").
  1167. *
  1168. * @param String $id The identifier of the line
  1169. * @param String $leafTable The name of the lowest table in the hierarchy
  1170. * @return JSON representing the detail of the result line.
  1171. */
  1172. public function getdetailsAction($id = null, $leafTable = null) {
  1173. $this->logger->debug('getDetailsAction : '.$id."_".$leafTable);
  1174. // Get the identifier of the line from the session
  1175. if ($id == null) {
  1176. $id = $this->getRequest()->getPost('id');
  1177. }
  1178. // Get the identifier of the leaf table from the session
  1179. $websiteSession = new Zend_Session_Namespace('website');
  1180. if ($leafTable == null) {
  1181. $leafTable = $websiteSession->leafTable;
  1182. }
  1183. $this->logger->debug('getDetailsAction : '.$id."_".$leafTable);
  1184. // Get the detailled data
  1185. $sql = $this->_generateSQLDetailRequest($id, $leafTable);
  1186. $result = $this->genericModel->executeRequest($sql);
  1187. // Get back the list of fields in the detail view
  1188. $detailFields = $websiteSession->detailFields;
  1189. // Prepare the metadata information
  1190. $metadata = array();
  1191. $traductions = array();
  1192. $i = 0;
  1193. foreach ($detailFields as $detailField) {
  1194. $metadata[$i] = $detailField;
  1195. // Prepare the traduction of the code lists
  1196. if ($detailField->type == "CODE") {
  1197. $traductions[$i] = $this->metadataModel->getModeFromUnit($detailField->unit);
  1198. }
  1199. $i++;
  1200. }
  1201. // Return the detailled information about the plot
  1202. $fields = "";
  1203. $line = $result[0];
  1204. $nbcol = sizeof($line);
  1205. $keys = array_keys($line);
  1206. for ($i = 0; $i < $nbcol - 7; $i++) {
  1207. // the last 4 result columns are reserved
  1208. $colName = $keys[$i]; // get the name of the column
  1209. $value = $line[$colName];
  1210. $formField = $metadata[$i];
  1211. if ($formField->type == "CODE" && $value != "") {
  1212. // Manage code traduction
  1213. $label = $traductions[$i][$value];
  1214. $fields .= "{label:".json_encode($formField->label).", value : ".json_encode($label)."}, ";
  1215. } else {
  1216. $fields .= "{label:".json_encode($formField->label).", value : ".json_encode($value)."}, ";
  1217. }
  1218. }
  1219. $fields = substr($fields, 0, -2);
  1220. $bb = $this->_setupBoundingBox($line);
  1221. $bb2 = $this->_setupBoundingBox($line, 200000); // Prepare an overview bbox
  1222. $locationPlotCode = $line['loc_plot_code'];
  1223. $json = "{title:'".$locationPlotCode."', formats:[{title:'Résultats détaillés', is_array:false, fields:[";
  1224. $json .= $fields;
  1225. $json .= "]}], ";
  1226. $json .= "map:[{title:'image',";
  1227. $json .= "url:'".$this->baseUrl."/proxy/gettile?";
  1228. $json .= "&LAYERS=".(empty($this->detailsLayers) ? '' : $this->detailsLayers[0]);
  1229. $json .= "&TRANSPARENT=true";
  1230. $json .= "&FORMAT=image%2FPNG";
  1231. $json .= "&SERVICE=WMS";
  1232. $json .= "&VERSION=1.1.1";
  1233. $json .= "&REQUEST=GetMap";
  1234. $json .= "&STYLES=";
  1235. $json .= "&EXCEPTIONS=application%2Fvnd.ogc.se_inimage";
  1236. $json .= "&SRS=EPSG%3A".$this->visualisationSRS;
  1237. $json .= "&BBOX=".$bb['location_x_min'].",".$bb['location_y_min'].",".$bb['location_x_max'].",".$bb['location_y_max'];
  1238. $json .= "&WIDTH=300";
  1239. $json .= "&HEIGHT=300";
  1240. $json .= "&map.scalebar=STATUS+embed";
  1241. $json .= "&sessionid=".session_id();
  1242. $json .= "&plot_code=".$locationPlotCode."'},";
  1243. $json .= "{title:'image',";
  1244. $json .= "url:'".$this->baseUrl."/proxy/gettile?";
  1245. $json .= "&LAYERS=".(empty($this->detailsLayers) ? '' : $this->detailsLayers[1]);
  1246. $json .= "&TRANSPARENT=true";
  1247. $json .= "&FORMAT=image%2FPNG";
  1248. $json .= "&SERVICE=WMS";
  1249. $json .= "&VERSION=1.1.1";
  1250. $json .= "&REQUEST=GetMap";
  1251. $json .= "&STYLES=";
  1252. $json .= "&EXCEPTIONS=application%2Fvnd.ogc.se_inimage";
  1253. $json .= "&SRS=EPSG%3A".$this->visualisationSRS;
  1254. $json .= "&BBOX=".$bb2['location_x_min'].",".$bb2['location_y_min'].",…

Large files files are truncated, but you can click here to view the full file