[Mapbender-commits] r9758 - in trunk/mapbender/http: classes javascripts php
svn_mapbender at osgeo.org
svn_mapbender at osgeo.org
Wed Aug 9 01:12:37 PDT 2017
Author: armin11
Date: 2017-08-09 01:12:36 -0700 (Wed, 09 Aug 2017)
New Revision: 9758
Modified:
trunk/mapbender/http/classes/class_cswClient.php
trunk/mapbender/http/classes/class_syncCkan.php
trunk/mapbender/http/javascripts/mod_syncCkan_client.php
trunk/mapbender/http/php/mod_syncCkan_server.php
Log:
New possibilities to sync mapbender metadata and external csw sources with ckan instances
Modified: trunk/mapbender/http/classes/class_cswClient.php
===================================================================
--- trunk/mapbender/http/classes/class_cswClient.php 2017-08-01 09:54:15 UTC (rev 9757)
+++ trunk/mapbender/http/classes/class_cswClient.php 2017-08-09 08:12:36 UTC (rev 9758)
@@ -29,6 +29,7 @@
var $cswId;
var $operationName;
var $operationResult;
+ var $additionalFilter;
//var $operationStatus;
var $operationSuccessful;
var $operationException;
@@ -41,7 +42,7 @@
$this->operationSuccessful = false;
}
- public function doRequest($cswId, $operationName, $recordId=false, $record=false, $recordtype=false, $maxrecords=false, $startposition=false) {
+ public function doRequest($cswId, $operationName, $recordId=false, $record=false, $recordtype=false, $maxrecords=false, $startposition=false, $additionalFilter=false) {
$this->cswId = $cswId;
$csw = new csw();
$csw->createCatObjFromDB($this->cswId);
@@ -152,18 +153,37 @@
//wrapped operations for internal usage
case "counthits":
$postRequest = '<?xml version="1.0" encoding="UTF-8"?>';
- $postRequest .= '<csw:GetRecords service="CSW" version="2.0.2" xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:ogc="http://www.opengis.net/ogc" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0">';
+ //TODO check the following: - resultType="hits" seems to be default behaviour
+ $postRequest .= '<csw:GetRecords service="CSW" version="2.0.2" xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:ogc="http://www.opengis.net/ogc" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" ';
+ $postRequest .= 'resultType="hits">';
$postRequest .= '<csw:Query typeNames="csw:Record">';
- $postRequest .= '<csw:ElementSetName>summary</csw:ElementSetName>';
+ $postRequest .= '<csw:ElementSetName>full</csw:ElementSetName>'; //full to get all queryables?
if ($recordtype !== false) {
$postRequest .= '<csw:Constraint version="1.0.0">';
$postRequest .= '<ogc:Filter>';
+ if ($additionalFilter !== false) {
+ $postRequest .= '<ogc:And>';
+ }
$postRequest .= '<ogc:PropertyIsEqualTo>';
$postRequest .= '<ogc:PropertyName>Type</ogc:PropertyName>';
$postRequest .= '<ogc:Literal>'.$recordtype.'</ogc:Literal>';
$postRequest .= '</ogc:PropertyIsEqualTo>';
+ if ($additionalFilter !== false) {
+ $postRequest .= $additionalFilter;
+ }
+ if ($additionalFilter !== false) {
+ $postRequest .= '</ogc:And>';
+ }
$postRequest .= '</ogc:Filter>';
$postRequest .= '</csw:Constraint>';
+ } else {
+ if ($additionalFilter !== false) {
+ $postRequest .= '<csw:Constraint version="1.0.0">';
+ $postRequest .= '<ogc:Filter>';
+ $postRequest .= $additionalFilter;
+ $postRequest .= '</ogc:Filter>';
+ $postRequest .= '</csw:Constraint>';
+ }
}
$postRequest .= '</csw:Query>';
$postRequest .= '</csw:GetRecords>';
@@ -184,12 +204,29 @@
if ($recordtype !== false) {
$postRequest .= '<csw:Constraint version="1.0.0">';
$postRequest .= '<ogc:Filter>';
+ if ($additionalFilter !== false) {
+ $postRequest .= '<ogc:And>';
+ }
$postRequest .= '<ogc:PropertyIsEqualTo>';
$postRequest .= ' <ogc:PropertyName>Type</ogc:PropertyName>';
$postRequest .= '<ogc:Literal>'.$recordtype.'</ogc:Literal>';
$postRequest .= '</ogc:PropertyIsEqualTo>';
+ if ($additionalFilter !== false) {
+ $postRequest .= $additionalFilter;
+ }
+ if ($additionalFilter !== false) {
+ $postRequest .= '</ogc:And>';
+ }
$postRequest .= '</ogc:Filter>';
$postRequest .= '</csw:Constraint>';
+ } else {
+ if ($additionalFilter !== false) {
+ $postRequest .= '<csw:Constraint version="1.0.0">';
+ $postRequest .= '<ogc:Filter>';
+ $postRequest .= $additionalFilter;
+ $postRequest .= '</ogc:Filter>';
+ $postRequest .= '</csw:Constraint>';
+ }
}
$postRequest .= '</csw:Query>';
$postRequest .= '</csw:GetRecords>';
@@ -203,6 +240,7 @@
break;
}
+ //$e = new mb_exception("postdata: ".$postRequest);
//do request and return result
//$e = new mb_exception($csw->cat_op_values[$operationName]['post']);
if (strpos($operationNameCsw, "transaction") === false) {
@@ -211,12 +249,12 @@
} else {
$this->operationResult = $this->getResult($csw->cat_op_values["transaction"]['post'], $postRequest);
}
- //$e = new mb_exception("test: ".$this->operationResult);
+ //$e = new mb_exception("testresponse: ".$this->operationResult);
//parse response
libxml_use_internal_errors(true);
try {
$cswResponseObject = simplexml_load_string($this->operationResult);
- if ($$cswResponseObject === false) {
+ if ($cswResponseObject === false) {
foreach(libxml_get_errors() as $error) {
$err = new mb_exception("class_cswClient:".$error->message);
}
@@ -260,6 +298,8 @@
$this->operationSuccessful = true;
//return $metadataRecord[0]->asXML();
//return "<result>One metadata record with id ".$recordId." found in catalogue</result>";
+ $this->operationResult = $cswResponseObject;
+ //$e = new mb_exception($cswResponseObject->asXML());
return true;
}
break;
@@ -322,7 +362,7 @@
}
private function getResult($url, $postData, $auth=false) {
- $e = new mb_exception("postdata: ".$postData);
+ //$e = new mb_exception("postdata: ".$postData);
$cswInterfaceObject = new connector();
$cswInterfaceObject->set('httpType','POST');
$postData = stripslashes($postData);
Modified: trunk/mapbender/http/classes/class_syncCkan.php
===================================================================
--- trunk/mapbender/http/classes/class_syncCkan.php 2017-08-01 09:54:15 UTC (rev 9757)
+++ trunk/mapbender/http/classes/class_syncCkan.php 2017-08-09 08:12:36 UTC (rev 9758)
@@ -20,7 +20,9 @@
require_once(dirname(__FILE__).'/../classes/class_group.php');
require_once(dirname(__FILE__) . '/../php/mod_getDownloadOptions.php');
require_once(dirname(__FILE__).'/../../conf/ckan.conf');
-
+//classes for csw handling
+require_once(dirname(__FILE__)."/../classes/class_cswClient.php");
+require_once(dirname(__FILE__)."/../classes/class_csw.php");
/**
* Class to provide functions to sync a mapbender metadata repository to a ckan instance, tested with ckan 2.5.3 in 2016
*
@@ -55,43 +57,95 @@
$this->mapbenderUserId = 0;
$this->syncOrgaId = 0;
$this->topicCkanCategoryMap = $topicCkanCategoryMap; //from ckan.conf
+ //Mapping of DCAT-AP categories to iso topic categories
+ $this->topicDataThemeCategoryMap = $topicDataThemeCategoryMap; //from ckan.conf
$this->compareTimestamps = false; //default to update each dataset, because the ckan index for metadata_modified may not be up to date !!!
}
- //TODO: Following function is only needed til php 5.5 - after upgrade to debian 8 it is obsolet - see also class_iso19139.php!
- public function array_column(array $input, $columnKey, $indexKey = null) {
- $array = array();
- foreach ($input as $value) {
- if ( !array_key_exists($columnKey, $value)) {
- trigger_error("Key \"$columnKey\" does not exist in array");
- return false;
- }
- if (is_null($indexKey)) {
- $array[] = $value[$columnKey];
- }
- else {
- if ( !array_key_exists($indexKey, $value)) {
- trigger_error("Key \"$indexKey\" does not exist in array");
- return false;
- }
- if ( ! is_scalar($value[$indexKey])) {
- trigger_error("Key \"$indexKey\" does not contain scalar value");
- return false;
- }
- $array[$value[$indexKey]] = $value[$columnKey];
- }
- }
- return $array;
- }
+ //TODO: Following function is only needed til php 5.5 - after upgrade to debian 8 it is obsolet - see also class_iso19139.php!
+ public function array_column(array $input, $columnKey, $indexKey = null) {
+ $array = array();
+ foreach ($input as $value) {
+ if ( !array_key_exists($columnKey, $value)) {
+ trigger_error("Key \"$columnKey\" does not exist in array");
+ return false;
+ }
+ if (is_null($indexKey)) {
+ $array[] = $value[$columnKey];
+ }
+ else {
+ if ( !array_key_exists($indexKey, $value)) {
+ trigger_error("Key \"$indexKey\" does not exist in array");
+ return false;
+ }
+ if ( ! is_scalar($value[$indexKey])) {
+ trigger_error("Key \"$indexKey\" does not contain scalar value");
+ return false;
+ }
+ $array[$value[$indexKey]] = $value[$columnKey];
+ }
+ }
+ return $array;
+ }
+ public function getCswRecordList($cswId, $orgaName, $recordType) {
+ //function to call external csw with orga filter (filter orga which is responsible for publication!)
+ $recordsPerPage = 20;
+ $csw = new csw();
+ $csw->createCatObjFromDB($cswId);
+ $cswClient = new cswClient();
+ $cswClient->cswId = $cswId;
+ $additionalFilter='<ogc:PropertyIsEqualTo><ogc:PropertyName>apiso:OrganisationName</ogc:PropertyName><ogc:Literal>'.$orgaName.'</ogc:Literal></ogc:PropertyIsEqualTo>';
+ $cswResponseObject = $cswClient->doRequest($cswClient->cswId, 'counthits', false, false, $recordType, false, false, $additionalFilter);
+ //$e = new mb_exception("Number of type ".$recordType." datasets for orga: ".$orgaName." in portal CSW: ".$cswClient->operationResult);
+ $maxRecords = (integer)$cswClient->operationResult;
+ $pages = ceil($maxRecords / $recordsPerPage);
+ $metadataArray = array();
+ $numberOfMetadataRecords = 0;
+ for ($i = 0; $i <= $pages-1 ; $i++) {
+ $cswClient = new cswClient();
+ $cswClient->cswId = $cswId;
+ $result = $cswClient->doRequest($cswClient->cswId, 'getrecordspaging', false, false, $recordType, $recordsPerPage, ($i*$recordsPerPage)+1, $additionalFilter);
+ $page = $i + 1;
+ //$e = new mb_exception("page: ".$page." (".$pages.")");
+ if ($cswClient->operationSuccessful == true) {
+ //$e = new mb_exception("operation successfull");
+ //$e = new mb_exception(gettype($cswClient->operationResult));
+ $metadataRecord = $cswClient->operationResult->xpath('/csw:GetRecordsResponse/csw:SearchResults/gmd:MD_Metadata');
+ //$e = new mb_exception("number of records: ".count($metadataRecord));
+ //what is possible: keywords, categories?, spatial, ...
+ for ($k = 1; $k <= count($metadataRecord) ; $k++) {
+ $fileIdentifier = $cswClient->operationResult->xpath('/csw:GetRecordsResponse/csw:SearchResults/gmd:MD_Metadata['.$k.']/gmd:fileIdentifier/gco:CharacterString');
+ $fileIdentifier = (string)$fileIdentifier[0];
+ $mdDateStamp = $cswClient->operationResult->xpath('/csw:GetRecordsResponse/csw:SearchResults/gmd:MD_Metadata['.$k.']/gmd:dateStamp/gco:Date');
+ $mdDateStamp = (string)$mdDateStamp[0];
+ $datasetIdentifier = $cswClient->operationResult->xpath('/csw:GetRecordsResponse/csw:SearchResults/gmd:MD_Metadata['.$k.']/gmd:identificationInfo/gmd:MD_DataIdentification/@uuid');
+ $datasetidentifier = (string)$datasetidentifier[0];
+ $url = $cswClient->operationResult->xpath('/csw:GetRecordsResponse/csw:SearchResults/gmd:MD_Metadata['.$k.']/gmd:distributionInfo/gmd:MD_Distribution/gmd:transferOptions/gmd:MD_DigitalTransferOptions/gmd:onLine/gmd:CI_OnlineResource/gmd:linkage/gmd:URL');
+ $url = (string)$url[0];
+ if (isset($url) && $url !=="") {
+ //$metadataArray[$numberOfMetadataRecords]['uuid'] = $datasetIdentifier;
+ $metadataArray[$numberOfMetadataRecords]['uuid'] = $fileIdentifier;
+ $metadataArray[$numberOfMetadataRecords]['changedate'] = $mdDateStamp;
+ $numberOfMetadataRecords++;
+ }
+ }
+ }
+ }
+ //$e = new mb_exception(json_encode($metadataArray, true));
+ return $metadataArray;
+ }
+
public function getMapbenderOrganizations() {
+ //$e = new mb_exception("getMapbenderOrganizations-> this->syncOrgaId: ".$this->syncOrgaId);
+
if (isset($this->mapbenderUserId) && (integer)$this->mapbenderUserId > 0) {
if (isset($this->syncOrgaId) && (integer)$this->syncOrgaId > 0) {
- $sql = "SELECT DISTINCT mb_group_id, mb_group_title, mb_group_name, mb_group_title, mb_group_email, mb_group_ckan_uuid, mb_group_ckan_api_key, mb_user_mb_group.mb_user_mb_group_type FROM mb_group JOIN mb_user_mb_group ON mb_group_id = fkey_mb_group_id AND fkey_mb_user_id = $1 AND mb_group_id = $2 AND mb_user_mb_group_type IN (2,3)";
+ $sql = "SELECT DISTINCT mb_group_id, mb_group_title, mb_group_name, mb_group_title, mb_group_email, mb_group_ckan_uuid, mb_group_ckan_api_key, mb_group_csw_catalogues, mb_user_mb_group.mb_user_mb_group_type FROM mb_group JOIN mb_user_mb_group ON mb_group_id = fkey_mb_group_id AND fkey_mb_user_id = $1 AND mb_group_id = $2 AND mb_user_mb_group_type IN (2,3)";
$v = array($this->mapbenderUserId, $this->syncOrgaId);
$t = array('i','i');
} else {
- $sql = "SELECT DISTINCT mb_group_id, mb_group_title, mb_group_name, mb_group_title, mb_group_email, mb_group_ckan_uuid, mb_group_ckan_api_key, mb_user_mb_group.mb_user_mb_group_type FROM mb_group JOIN mb_user_mb_group ON mb_group_id = fkey_mb_group_id AND fkey_mb_user_id = $1 AND mb_user_mb_group_type IN (2,3)";
+ $sql = "SELECT DISTINCT mb_group_id, mb_group_title, mb_group_name, mb_group_title, mb_group_email, mb_group_ckan_uuid, mb_group_ckan_api_key, mb_group_csw_catalogues, mb_user_mb_group.mb_user_mb_group_type FROM mb_group JOIN mb_user_mb_group ON mb_group_id = fkey_mb_group_id AND fkey_mb_user_id = $1 AND mb_user_mb_group_type IN (2,3)";
$v = array($this->mapbenderUserId);
$t = array('i');
}
@@ -110,6 +164,9 @@
}
$departmentsArray[$countDepArray]["ckan_uuid"] = $row["mb_group_ckan_uuid"];
$departmentsArray[$countDepArray]["ckan_api_key"] = $row["mb_group_ckan_api_key"];
+ //if ($row["mb_group_csw_catalogues"] !== null && $row["mb_group_csw_catalogues"] !== '') {
+ $departmentsArray[$countDepArray]["csw_catalogues"] = $row["mb_group_csw_catalogues"];
+ //}
if ($row["mb_user_mb_group_type"] == 2) {
$departmentsArray[$countDepArray]["is_primary_group"] = true;
} else {
@@ -129,6 +186,197 @@
}
}
+ //function to give back a mixed upper/lowercase string array from the input of a lowercase array and the haystack which is mixed upper/and lowercase
+ public function searchUpperLowerCase($lowerCaseStringArray, $mixedStringArray) {
+ $result = array();
+ foreach($lowerCaseStringArray as $lowerCaseString) {
+ if (array_search($lowerCaseString, $mixedStringArray) !== false) {
+ $result[] = $mixedStringArray[array_search($lowerCaseString, $mixedStringArray)];
+ } else {
+ if (array_search(strtoupper($lowerCaseString), $mixedStringArray) !== false) {
+ $result[] = $mixedStringArray[array_search(strtoupper($lowerCaseString), $mixedStringArray)];
+ }
+ }
+ }
+ return $result;
+ }
+
+ public function getSyncListCswJson($departmentsArray, $listAllMetadataInJson = false) {
+ $syncListCsw = new stdClass(); //should handle the returned json object
+ $syncListResultCsw = new stdClass();
+ $syncListCsw->help = "helptext";
+ $syncListCsw->success = false;
+ $syncListCsw->function = "getSyncListCswJson";
+ $numberOfCatalogue = 0;
+ $organization = $departmentsArray[0];
+ $catalogues = json_decode($departmentsArray[0]["csw_catalogues"])->csw_catalogues;
+ foreach ($catalogues as $catalogue) { //only one in this case
+
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->id = $catalogue->catalogue_id;
+
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->orga_filter = $catalogue->organisation_filter;
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->ckan_filter = $catalogue->ckan_filter;
+ //things from mapbender database
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->name = $organization["name"];
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->title = $organization["title"];
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->email = $organization["email"];
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->ckan_orga_ident = $organization["ckan_uuid"];
+
+ if (isset($organization["ckan_uuid"]) && isset($organization["ckan_api_key"])) {
+ //Test if organization with the given external uuid exists in the coupled ckan
+ //show organizations of the authorized user (from geoportal group table) via action api
+ $ckan = new ckanApi($organization["ckan_api_key"], CKAN_SERVER_IP);
+ $ckan->base_url = $this->ckanApiProtocol.'://'.$this->ckanApiUrl.'/api/3/';
+ $ckan->api_version = $this->ckanApiVersion;
+ $result = $ckan->action_organization_list_for_user();
+ foreach($result->result as $orga) {
+ if ($orga->id == $organization["ckan_uuid"]) {
+ //foreach catalogue entry to sync
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->ckan_orga_ident = $organization["ckan_uuid"];
+ //echo "Corresponding ckan organization ".$orga->display_name." found for geoportal group ".$organization["name"]." with id ".$organization["id"]."!<br>";
+ //get list of ids for existing spatial datasets - category spatial should be defined!!!!!!
+ //http://localhost:5000/api/3/action/package_search?fq=transparency_category_de_rp:spatial_data
+ //with org: http://localhost:5000/api/3/action/package_search?fq=transparency_category_de_rp:spatial_data%20AND%20owner_org:81476cf5-6c52-4e99-8b9f-6150d63fcb32
+ //TODO: define standard category filter in ckan.conf!
+ //$queryObject->fq = STANDARD_CKAN_FILTER." AND owner_org:".$organization["ckan_uuid"];
+ $queryObject->fq = $catalogue->ckan_filter." AND owner_org:".$organization["ckan_uuid"];
+ //$queryObject->fq = "transparency_category_de_rp:spatial_data AND owner_org:".$organization["ckan_uuid"];
+ $queryObject->facet = "true";
+ $queryObject->rows = "1000"; //TODO: maybe an problem somewhen
+ $listOfFilteredData = $ckan->action_package_search(json_encode($queryObject));
+ $countCkanMetadataArray = 0;
+ $ckanMetadataArray = array();
+ //echo "List of datasets in ckan instance:"."<br>";
+ $ckanPackageNames = array();
+ if ($listOfFilteredData->success == true) {
+ //TODO - why only 10 records are given back when search?
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->count_ckan_packages = $listOfFilteredData->result->count;
+ //echo json_encode($listOfFilteredData)."<br>";
+ //$e = new mb_exception("Number of results: ".$listOfFilteredData->result->count);
+ foreach ($listOfFilteredData->result->results as $dataset) {
+ $ckanMetadataArray[$countCkanMetadataArray]['id'] = $dataset->id;
+ $ckanMetadataArray[$countCkanMetadataArray]['name'] = $dataset->name;
+ $ckanMetadataArray[$countCkanMetadataArray]['changedate'] = $dataset->metadata_modified;
+ if ($listAllMetadataInJson == true) {
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->ckan_packages[$countCkanMetadataArray]->id = $dataset->name;
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->ckan_packages[$countCkanMetadataArray]->date_time = $dataset->metadata_modified;
+ }
+ //echo $dataset->title." - ".$dataset->name." - ".$dataset->metadata_modified."<br>";
+ $ckanPackageNames[] = $dataset->name;
+ $countCkanMetadataArray++;
+ //$e = new mb_exception("ckan dataset number: ".$countCkanMetadataArray);
+ }
+ } else {
+ $e = new mb_exception("classes/class_syncCkan.php: A problem while searching for datasets in ckan occured!");
+ }
+ // only list http://localhost:5000/api/3/action/package_list?q=owner_org:81476cf5-6c52-4e99-8b9f-6150d63fcb32
+ //pull all relevant information from mapbender database - first pull the resources which are owned by the corresponding group!
+ //only use metadata for which real licenses are defined !!!!!! - what should be done with the other metadata?- DO a left join!!!
+ /*if ($organization['is_primary_group']) {
+ $sql = "SELECT *, f_get_coupled_resources(metadata_id) from mb_metadata JOIN md_termsofuse ON mb_metadata.metadata_id = md_termsofuse.fkey_metadata_id WHERE fkey_mb_user_id = $1 AND (fkey_mb_group_id is null OR fkey_mb_group_id = 0) AND export2csw IS true";
+ $v = array($this->mapbenderUserId);
+ $t = array('i');
+ } else {
+ $sql = "SELECT *, f_get_coupled_resources(metadata_id) from mb_metadata JOIN md_termsofuse ON mb_metadata.metadata_id = md_termsofuse.fkey_metadata_id WHERE fkey_mb_group_id = $1 AND export2csw IS true";
+ $v = array($organization['id']);
+ $t = array('i');
+ }*/
+ //get list of distributed metadata sets with their relevant arributes from csw search!!!!!
+ $cswMetadataArray = $this->getCswRecordList((integer)$catalogue->catalogue_id, $catalogue->organisation_filter, 'nonGeographicDataset');
+ $countMetadataArray = count($cswMetadataArray);
+ if ($countMetadataArray == 0) {
+ //echo "No published metadata found for user with id ".$userId." <br>";
+ //delete all records from external ckan instance
+ /*foreach ($ckanMetadataArray as $ckanPackage) {
+ //echo "Ckan package ".$ckanPackage['name']." should be deleted"."<br>";
+ }*/
+ } else {
+ $numberCswMetadata = 0;
+ $cswUuids = array();
+ foreach($cswMetadataArray as $cswMetadata) {
+ //if (count($layerArray) > 0 || count($featuretypeArray) > 0) {
+ //use only those that have resources!
+ //if ($geoportalMetadata['hasResource']) {
+ if ($listAllMetadataInJson == true) {
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->csw_metadata[$numberCswMetadata]->id = $cswMetadata['uuid'];
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->csw_metadata[$numberCswMetadata]->date_time = $cswMetadata['changedate'];
+ }
+ $cswUuids[] = $cswMetadata['uuid'];
+ $numberCswMetadata++;
+ // }
+ //}
+ }
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->count_csw_packages = $numberCswMetadata;
+ //build diffs for ckan and geoportal
+ //Arrays: ckanPackageNames / cswUuids
+ //Those which are only in ckan: delete them
+
+ //TODO: Problem is that portalu/ingrid mix lowercase and uppercase uuids - to compare them always use lowercase
+ $cswUuidsLower = array_map('strtolower', $cswUuids);
+//$e = new mb_exception(json_encode($cswUuidsLower));
+//$e = new mb_exception(json_encode($ckanPackageNames));
+ $onlyInCkan = array_values(array_diff($ckanPackageNames, $cswUuidsLower)); //every time lowercase names!
+//$e = new mb_exception(json_encode($onlyInCkan));
+ //Those which are only in csw: create them
+ $onlyInCsw = array_values(array_diff($cswUuidsLower, $ckanPackageNames));
+//$e = new mb_exception(json_encode($onlyInCsw));
+ //Those which are in both - update them if geoportal metadata is newer than the package in ckan
+ $inBoth = array_values(array_intersect($ckanPackageNames, $cswUuidsLower));
+//$e = new mb_exception(json_encode($inBoth));
+ //rebuild key arrays to mixed case
+ $onlyInCsw = $this->searchUpperLowerCase($onlyInCsw, $cswUuids);
+ $inBoth = $this->searchUpperLowerCase($inBoth, $cswUuids);
+
+ //if the timestamps should be compared before
+ if ($this->compareTimestamps == true) {
+ foreach ($inBoth as $uuid) {
+ $e = new mb_notice("classes/class_syncCkan.php: search for uuid: ".$uuid."ckan time : ".$ckanMetadataArray[array_search($uuid, $this->array_column($ckanMetadataArray,'name'))]['changedate']. " - csw time: ".$cswMetadataArray[array_search($uuid, $this->array_column($cswMetadataArray,'uuid'))]['changedate']);
+ $dateTimeCkan = new DateTime($ckanMetadataArray[array_search($uuid, $this->array_column($ckanMetadataArray,'name'))]['changedate']);
+ $dateTimeCsw = new DateTime($cswMetadataArray[array_search($uuid, $this->array_column($cswMetadataArray,'uuid'))]['changedate']);
+ if ($dateTimeCkan > $dateTimeCsw) {
+ //delete from $inBoth!
+ $e = new mb_notice("classes/class_syncCkan.php: Ckans package newer than csw metadata!");
+ $inBoth = array_values(array_diff($inBoth, [$uuid]));
+ } else {
+ $e = new mb_notice("classes/class_syncCkan.php: Ckans package older than csw metadata!");
+ }
+ }
+ }
+ //$e = new mb_exception("Number of packages which are only in ckan: ".count($onlyInCkan)." - number of packages which are only in geoportal: ".count($onlyInGeoportal)." - number of packages which are in both catalogues: ".count($inBoth));
+ //$e = new mb_exception("both: ".gettype($inBoth)." number: ".count($inBoth)." json: ".json_encode($inBoth));
+ //$e = new mb_exception("only ckan: ".gettype($onlyInCkan)." number: ".count($onlyInCkan)." json: ".json_encode($onlyInCkan));
+ //$e = new mb_exception("only geoportal: ".gettype($onlyInGeoportal)." number: ".count($onlyInGeoportal)." json: ".json_encode($onlyInGeoportal));
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->update = $inBoth;
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->delete = $onlyInCkan;
+ $syncListResultCsw->external_csw[$numberOfCatalogue]->create = $onlyInCsw;
+ }
+ //then pull the ressources which are owned by the user but have no group defined - only if the primary group of the user is the corresponding group!
+ //maybe the catalogue itself is the best way to pull all relevant data, cause the coupling is resolved already!
+ //filter for datasets:
+ //open data - defined by the licenses
+ //transparency - no filter at all - licenses only of some exists - otherwise none or freetext
+ }
+ }
+ } else {
+ $e = new mb_exception("classes/class_syncCkan.php: Coupled ckan cannot be synchronized, cause the required organization-id and/or API-Key is was not found for ".$organization["name"]);
+ //echo "<br> - ".$numberOfCatalogue."<br>";
+ }
+ $numberOfCatalogue++;
+ }
+ //TODO DEBUG
+ /* foreach($syncListResultCsw->external_csw[0]->create as $cswFileIdentifier) {
+ $e = new mb_exception($cswFileIdentifier);
+ $resultCkanRepresentation = $this->getCkanRepresentationFromCsw($syncListResultCsw->external_csw[0]->id, $cswFileIdentifier, "orga_name", "orga_title", "orga_email", $this->topicDataThemeCategoryMap, "transparency_category_de_rp:environmental_information");
+ }
+ //
+ */
+ if (count($syncListResultCsw->external_csw) >= 1) {
+ $syncList->result = $syncListResultCsw;
+ $syncList->success = true;
+ }
+ return json_encode($syncList);
+ }
+
public function getSyncListJson($departmentsArray, $listAllMetadataInJson = false) {
$syncList = new stdClass(); //should handle the returned json object
$syncListResult = new stdClass();
@@ -142,6 +390,7 @@
$syncListResult->geoportal_organization[$numberGeoportalOrga]->title = $organization["title"];
$syncListResult->geoportal_organization[$numberGeoportalOrga]->email = $organization["email"];
$syncListResult->geoportal_organization[$numberGeoportalOrga]->ckan_orga_ident = false;
+ $syncListResult->geoportal_organization[$numberGeoportalOrga]->csw_catalogues = json_decode($organization["csw_catalogues"])->csw_catalogues;
if (isset($organization["ckan_uuid"]) && isset($organization["ckan_api_key"])) {
//Test if organization with the given external uuid exists in the coupled ckan
//show organizations of the authorized user (from geoportal group table) via action api
@@ -157,18 +406,19 @@
//http://localhost:5000/api/3/action/package_search?fq=transparency_category_de_rp:spatial_data
//with org: http://localhost:5000/api/3/action/package_search?fq=transparency_category_de_rp:spatial_data%20AND%20owner_org:81476cf5-6c52-4e99-8b9f-6150d63fcb32
//TODO: define standard category filter in ckan.conf!
- $queryObject->fq = "transparency_category_de_rp:spatial_data AND owner_org:".$organization["ckan_uuid"];
+ $queryObject->fq = STANDARD_CKAN_FILTER." AND owner_org:".$organization["ckan_uuid"];
+ //$queryObject->fq = "transparency_category_de_rp:spatial_data AND owner_org:".$organization["ckan_uuid"];
$queryObject->facet = "true";
- $listOfSpatialData = $ckan->action_package_search(json_encode($queryObject));
+ $listOfFilteredData = $ckan->action_package_search(json_encode($queryObject));
$countCkanMetadataArray = 0;
$ckanMetadataArray = array();
//echo "List of datasets in ckan instance:"."<br>";
$ckanPackageNames = array();
- if ($listOfSpatialData->success == true) {
- $syncListResult->geoportal_organization[$numberGeoportalOrga]->count_ckan_packages = $listOfSpatialData->result->count;
- //echo json_encode($listOfSpatialData)."<br>";
- //$e = new mb_exception("Number of results: ".$listOfSpatialData->result->count);
- foreach ($listOfSpatialData->result->results as $dataset) {
+ if ($listOfFilteredData->success == true) {
+ $syncListResult->geoportal_organization[$numberGeoportalOrga]->count_ckan_packages = $listOfFilteredData->result->count;
+ //echo json_encode($listOfFilteredData)."<br>";
+ //$e = new mb_exception("Number of results: ".$listOfFilteredData->result->count);
+ foreach ($listOfFilteredData->result->results as $dataset) {
$ckanMetadataArray[$countCkanMetadataArray]['id'] = $dataset->id;
$ckanMetadataArray[$countCkanMetadataArray]['name'] = $dataset->name;
$ckanMetadataArray[$countCkanMetadataArray]['changedate'] = $dataset->metadata_modified;
@@ -185,13 +435,13 @@
}
// only list http://localhost:5000/api/3/action/package_list?q=owner_org:81476cf5-6c52-4e99-8b9f-6150d63fcb32
//pull all relevant information from mapbender database - first pull the resources which are owned by the corresponding group!
- //only use metadata for which real licenses are defined !!!!!!
+ //only use metadata for which real licenses are defined !!!!!! - what should be done with the other metadata?- DO a left join!!!
if ($organization['is_primary_group']) {
- $sql = "SELECT *, f_get_coupled_resources(metadata_id) from mb_metadata JOIN md_termsofuse ON mb_metadata.metadata_id = md_termsofuse.fkey_metadata_id WHERE fkey_mb_user_id = $1 AND (fkey_mb_group_id is null OR fkey_mb_group_id = 0)";
+ $sql = "SELECT *, f_get_coupled_resources(metadata_id) from mb_metadata JOIN md_termsofuse ON mb_metadata.metadata_id = md_termsofuse.fkey_metadata_id WHERE fkey_mb_user_id = $1 AND (fkey_mb_group_id is null OR fkey_mb_group_id = 0) AND export2csw IS true";
$v = array($this->mapbenderUserId);
$t = array('i');
} else {
- $sql = "SELECT *, f_get_coupled_resources(metadata_id) from mb_metadata JOIN md_termsofuse ON mb_metadata.metadata_id = md_termsofuse.fkey_metadata_id WHERE fkey_mb_group_id = $1";
+ $sql = "SELECT *, f_get_coupled_resources(metadata_id) from mb_metadata JOIN md_termsofuse ON mb_metadata.metadata_id = md_termsofuse.fkey_metadata_id WHERE fkey_mb_group_id = $1 AND export2csw IS true";
$v = array($organization['id']);
$t = array('i');
}
@@ -294,6 +544,119 @@
}
return json_encode($syncList);
}
+
+ public function syncSingleCsw($syncListJson) {
+ $resultObject = new stdClass();
+ $resultObject->help = "Syncing external csw with ckan for organization with id: ".$this->syncOrgaId;
+ $syncList = json_decode($syncListJson);
+ //if ($syncList->id == $this->syncOrgaId) { - not relevant for csw sync, cause multiple csw may be synced for one ckan orga
+ $numberOfDeletedPackages = 0;
+ $numberOfCreatedPackages = 0;
+ $numberOfUpdatedPackages = 0;
+ //read ckan api-key from database again, because we wont transfer it via json thru the web ;-)
+ $sql = "SELECT mb_group_ckan_api_key FROM mb_group WHERE mb_group_id = $1";
+ $v = array($this->syncOrgaId);
+ $t = array('s');
+ $res = db_prep_query($sql, $v, $t);
+ if ($res) {
+ $row = db_fetch_assoc($res);
+ $ckanApiKey = $row['mb_group_ckan_api_key'];
+ $ckan = new ckanApi($ckanApiKey, CKAN_SERVER_IP);
+ $ckan->base_url = $this->ckanApiProtocol.'://'.$this->ckanApiUrl.'/api/3/';
+ $ckan->api_version = $this->ckanApiVersion;
+ } else {
+ $e = new mb_exception("classes/class_syncCkan.php: No api-key found for mapbender group: ".$this->syncOrgaId);
+ return false;
+ }
+ foreach($syncList->delete as $ckanNameToDelete) {
+ //TODO - PortalU Problem lowercase/uppercase
+ $ckanNameToDelete = strtolower($ckanNameToDelete);
+
+ $result = $ckan->action_package_delete("{\"id\":\"".$ckanNameToDelete."\"}");
+ if ($result->success == true) {
+ $e = new mb_notice("classes/class_syncCkan.php: Ckan package with name ".$ckanNameToDelete." successfully deleted!");
+ $numberOfDeletedPackages++;
+ } else {
+ $e = new mb_exception("classes/class_syncCkan.php: A problem occured while trying to delete ckan package with name ".$ckanNameToDelete);
+ }
+ }
+ foreach ($syncList->csw_metadata as $datasetMetadata) {
+ if (in_array($datasetMetadata->id, $syncList->update) || in_array($datasetMetadata->id, $syncList->create)) {
+ //build resources array for each metadata
+ /*$layerArrayMetadata = array();
+ $featuretypeArrayMetadata = array();
+ foreach ($datasetMetadata->resources->coupledResources->layerIds as $layerId) {
+ $layerArrayMetadata[] = $layerId;
+ }
+ foreach ($datasetMetadata->resources->coupledResources->featuretypeIds as $featuretypeId) {
+ $featuretypeArrayMetadata[] = $featuretypeId;
+ }*/
+ //check if dataset already exists in ckan - we know this, cause we want to update those
+ //if (in_array($datasetMetadata['uuid'], $ckanMetadataArray['name'])) {
+ //echo $datasetMetadata['uuid']." has to be updated!"."<br>";
+ //} else {
+ //echo $datasetMetadata['uuid']." has to be initial created!"."<br>";
+ //check if deleted package with same uuid already exists, because the deleted packages only have the state deleted!
+ //TODO fix upper/lowercase problem
+ $resourceJson->id = strtolower($datasetMetadata->id); //find by id and name name:http://docs.ckan.org/en/latest/api/
+ $result = $ckan->action_package_show(json_encode($resourceJson));
+ if ($result->success == true) {
+ //update existing package
+ //$resultCkanRepresentation = $this->getCkanRepresentation($datasetMetadata->id, $layerArrayMetadata, $featuretypeArrayMetadata, $syncList->ckan_orga_ident, $syncList->title, $syncList->email, $this->topicCkanCategoryMap);
+ //TODO - define parameter
+ $resultCkanRepresentation = $this->getCkanRepresentationFromCsw($syncList->id, $datasetMetadata->id, $syncList->ckan_orga_ident, $syncList->name, $syncList->email, $this->topicDataThemeCategoryMap, $syncList->ckan_filter);
+ if ($resultCkanRepresentation != false) {
+ $result = $ckan->action_package_update($resultCkanRepresentation['json']);
+ if ($result->success == true) {
+ //echo "Creation of package successful!"."<br>";
+ //recreate views
+ //$viewsUpdateProtocol = $this->recreateResourceViews($ckan, $result, $resultCkanRepresentation);
+ $numberOfUpdatedPackages++;
+ //$e = new mb_exception($viewsUpdateProtocol);
+ } else {
+ //echo "A problem occured while trying to create the ckan package"."<br>";
+ }
+ } else {
+ //echo "A problem occured while trying to create the json object from geoportal metadata!"."<br>";
+ }
+ } else {
+ //create new package
+ //echo "Package ".$datasetMetadata['uuid']." does not exist and has to be created!"."<br>";
+ //$resultCkanRepresentation = $this->getCkanRepresentation($datasetMetadata->id, $layerArrayMetadata, $featuretypeArrayMetadata, $syncList->ckan_orga_ident, $syncList->title, $syncList->email, $this->topicCkanCategoryMap);
+ //TODO
+ $resultCkanRepresentation = $this->getCkanRepresentationFromCsw($syncList->id, $datasetMetadata->id, $syncList->ckan_orga_ident, $syncList->title, $syncList->email, $this->topicDataThemeCategoryMap, $syncList->ckan_filter);
+ if ($resultCkanRepresentation != false) {
+ $result = $ckan->action_package_create($resultCkanRepresentation['json']);
+ if ($result->success == true) {
+ //echo "Creation of package successful!"."<br>";
+ //recreate views
+ //$viewsUpdateProtocol = $this->recreateResourceViews($ckan, $result, $resultCkanRepresentation);
+ $numberOfCreatedPackages++;
+ //$e = new mb_exception($viewsUpdateProtocol);
+ } else {
+ $e = new mb_exception("classes/class_syncCkan.php: A problem occured while trying to create the ckan package");
+ }
+ } else {
+ $e = new mb_exception("classes/class_syncCkan.php: A problem occured while trying to create the json object from csw metadata!");
+ }
+ }
+ //}
+ }
+ }
+ /*} else {
+ $e = new mb_exception("classes/class_syncCkan.php (syncSingleCsw): Id from json is not identical to id from class! Sync will not be started!");
+ $resultObject->success = false;
+ $resultObject->error->message = "Organization id for the invoked sync process could not be obtained - please check the id!";
+ //$resultObject->help = "Sync of metadata for orga ";
+ return json_encode($resultObject);
+ }*/
+ $resultObject->success = true;
+ $resultObject->result->orga_id = $this->syncOrgaId;
+ $resultObject->result->numberOfDeletedPackages = $numberOfDeletedPackages;
+ $resultObject->result->numberOfUpdatedPackages = $numberOfUpdatedPackages;
+ $resultObject->result->numberOfCreatedPackages = $numberOfCreatedPackages;
+ return json_encode($resultObject);
+ }
public function syncSingleOrga($syncListJson) {
$resultObject = new stdClass();
@@ -401,6 +764,100 @@
return json_encode($resultObject);
}
+ //private function getCkanRepresentationFromCsw($syncList->external_csw[0]->id, uuid) {
+ private function getCkanRepresentationFromCsw($cswId, $fileIdentifier, $ckan_orga_ident, $orgaTitle, $orgaEmail, $topicDataThemeCategoryMap, $ckanCategoryFilter) {
+ //getRecordById
+ $csw = new csw();
+ $csw->createCatObjFromDB($cswId);
+ $cswClient = new cswClient();
+ $cswClient->cswId = $cswId;
+ //$e = new mb_exception("invoke get record by id");
+ //$e = new mb_exception("catalogue id = ".$cswId);
+ $cswResponseObject = $cswClient->doRequest($cswClient->cswId, 'getrecordbyid', $fileIdentifier, false, false, false, false, false);
+ //parse XML
+ if ($cswClient->operationSuccessful == true) {
+ $metadataTitle = $cswClient->operationResult->xpath('/csw:GetRecordByIdResponse/gmd:MD_Metadata/gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:title/gco:CharacterString');
+ $metadataTitle = (string)$metadataTitle[0];
+ /*$fileIdentifier = $cswClient->operationResult->xpath('/csw:GetRecordByIdResponse/gmd:MD_Metadata/gmd:fileIdentifier/gco:CharacterString');
+ $fileIdentifier = $fileIdentifier[0];*/
+
+ $metadataAbstract = $cswClient->operationResult->xpath('/csw:GetRecordByIdResponse/gmd:MD_Metadata/gmd:identificationInfo/gmd:MD_DataIdentification/gmd:abstract/gco:CharacterString');
+ $metadataAbstract = (string)$metadataAbstract[0];
+
+ $keywords = $cswClient->operationResult->xpath('/csw:GetRecordByIdResponse/gmd:MD_Metadata/gmd:identificationInfo/gmd:MD_DataIdentification/gmd:descriptiveKeywords/gmd:MD_Keywords/gmd:keyword/gco:CharacterString');
+
+ $url = $cswClient->operationResult->xpath('/csw:GetRecordByIdResponse/gmd:MD_Metadata/gmd:distributionInfo/gmd:MD_Distribution/gmd:transferOptions/gmd:MD_DigitalTransferOptions/gmd:onLine/gmd:CI_OnlineResource/gmd:linkage/gmd:URL');
+ $url = (string)$url[0];
+ $resourceName = $cswClient->operationResult->xpath('/csw:GetRecordByIdResponse/gmd:MD_Metadata/gmd:distributionInfo/gmd:MD_Distribution/gmd:transferOptions/gmd:MD_DigitalTransferOptions/gmd:onLine/gmd:CI_OnlineResource/gmd:name/gco:CharacterString');
+ $resourceName = (string)$resourceName[0];
+ $format = $cswClient->operationResult->xpath('/csw:GetRecordByIdResponse/gmd:MD_Metadata/gmd:distributionInfo/gmd:MD_Distribution/gmd:distributionFormat/gmd:MD_Format/gmd:name/gco:CharacterString');
+ $format = (string)$format[0];
+ //$e = new mb_exception($metadataTitle);
+ //$e = new mb_exception($fileIdentifier);
+
+ //TODO
+
+ //write json object
+ $ckanPackage->title = $metadataTitle;
+ $ckanPackage->notes = $metadataAbstract;
+$ckanPackage->name = strtolower($fileIdentifier);
+ $ckanPackage->author = $orgaTitle;
+ $ckanPackage->author_email = $orgaEmail;
+ $ckanPackage->owner_org = $ckan_orga_ident;
+ $ckanPackage->state = "active";
+ $ckanPackage->private = false;
+ //convert bbox - if available to geojson
+ //TODO - use key of ckan category from conf!
+ $ckanCategoryFilter = explode(":",$ckanCategoryFilter);
+ $ckanPackage->{$ckanCategoryFilter[0]} = $ckanCategoryFilter[1];
+ //$ckanPackage->type = "ckan-govdata-full-1-1";
+ $ckanPackage->type = "dataset";
+ $ckanPackage->tags = array();
+ $keywords = array_unique($keywords);
+ $keywordIndex = 0;
+ for ($i=0; $i < count($keywords); $i++) {
+ if ($keywords[$i] !== "" && isset($keywords[$i]) && strpos($keywords[$i], " ") === false) {
+ $ckanPackage->tags[$keywordIndex]->name = (string)$keywords[$i];
+ $keywordIndex++;
+ }
+ }
+ $resourcesArray = array();
+ if (isset($resourceName) && $resourceName !=="") {
+ $resourcesArray[0]->name = $resourceName;
+ } else {
+ $resourcesArray[0]->name = "Weitere Infos";
+ }
+ $resourcesArray[0]->url = $url;
+ if (isset($format) && $format !=="") {
+ $resourcesArray[0]->format = $format;
+ } else {
+ $resourcesArray[0]->format = "Unbekannt";
+ }
+
+ $ckanPackage->resources = array_unique($resourcesArray);
+ }
+ $returnArray = array();
+ $returnArray['json'] = json_encode($ckanPackage);
+ //$e = new mb_exception("json: ".$returnArray['json']);
+ //$returnArray['views'] = $viewArray;
+ return $returnArray;
+ /*
+ //tags
+ $ckanPackage->type
+ //categories
+ //license - dummy!
+ $ckanPackage->license_id = $row['name'];
+ //$ckanPackage->license_id = "odc_odbl";
+ $ckanPackage->license_title = $row['description'];
+ $ckanPackage->license_url = $row['descriptionlink'];
+ //build resource:
+ $resourcesArray = array();
+ $resourcesArray[0]->name = "";
+ $resourcesArray[0]->url = "";
+ $resourcesArray[0]->format = "";*/
+ //$e = new mb_exception(json_encode($ckanPackage, true));
+ }
+
private function getCkanRepresentation($uuid, $layerArray, $featuretypeArray, $orgaId, $orgaTitle, $orgaEmail, $topicCkanCategoryMap) {
if (defined("MAPBENDER_PATH") && MAPBENDER_PATH != '') {
$mapbenderUrl = MAPBENDER_PATH;
@@ -409,7 +866,7 @@
}
//all or only those which have standardized licenses?
//$sql = "SELECT *, f_get_coupled_resources(metadata_id) from mb_metadata LEFT JOIN md_termsofuse ON mb_metadata.metadata_id = md_termsofuse.fkey_metadata_id WHERE mb_metadata.uuid = $1";
- $sql = "SELECT * from mb_metadata JOIN md_termsofuse ON mb_metadata.metadata_id = md_termsofuse.fkey_metadata_id JOIN termsofuse ON md_termsofuse.fkey_termsofuse_id = termsofuse.termsofuse_id WHERE mb_metadata.uuid = $1";
+ $sql = "SELECT * , st_asgeojson(the_geom) as geojson from mb_metadata JOIN md_termsofuse ON mb_metadata.metadata_id = md_termsofuse.fkey_metadata_id JOIN termsofuse ON md_termsofuse.fkey_termsofuse_id = termsofuse.termsofuse_id WHERE mb_metadata.uuid = $1 AND export2csw IS true";
$v = array($uuid);
$t = array('s');
$res = db_prep_query($sql, $v, $t);
@@ -446,6 +903,7 @@
//$ckanPackage->license_id = "odc_odbl";
$ckanPackage->license_title = $row['description'];
$ckanPackage->license_url = $row['descriptionlink'];
+ $ckanPackage->spatial = $row['geojson'];
//$ckanPackage->url = "";
//special categories
//$ckanPackage->govdata_categories = [];
@@ -469,6 +927,7 @@
$resourcesArray[$indexResourceArray]->description = "Anzeige des Kartenlayers ".$row['layer_title']." im integrierten Kartenviewer (GeoPortal.rlp mobile API).";
$resourcesArray[$indexResourceArray]->url = $mapbenderUrl."/extensions/mobilemap/map.php?layerid=".$row['layer_id'];
$resourcesArray[$indexResourceArray]->format = "Kartenviewer inline";
+ //$resourcesArray[$indexResourceArray]->res_transparency_document_change_classification = "unaltered";
$indexResourceArray++;
//views to generate
$viewArray[$indexViewArray]['view_type'] = "webpage_view";
@@ -514,6 +973,7 @@
$resourcesArray[$indexResourceArray]->description = "Download von Rasterdaten über INSPIRE ATOM Feed: ".$metadataObject->title;
$resourcesArray[$indexResourceArray]->url = $mapbenderUrl."/plugins/mb_downloadFeedClient.php?url=".urlencode($mapbenderUrl."/php/mod_inspireDownloadFeed.php?id=".$metadataUuid."&type=SERVICE&generateFrom=wmslayer&layerid=".$option->resourceId);
$resourcesArray[$indexResourceArray]->format = "ATOM Viewer";
+ //$resourcesArray[$indexResourceArray]->res_transparency_document_change_classification = "unaltered";
$indexResourceArray++;
//views to generate
//build whole json structure
@@ -530,7 +990,8 @@
$resourcesArray[$indexResourceArray]->id = $option->serviceUuid;
$resourcesArray[$indexResourceArray]->description = "Download von verlinkten Daten über INSPIRE ATOM Feed: ".$metadataObject->title;
$resourcesArray[$indexResourceArray]->url = $mapbenderUrl."/plugins/mb_downloadFeedClient.php?url=".urlencode($mapbenderUrl."/php/mod_inspireDownloadFeed.php?id=".$metadataUuid."&type=SERVICE&generateFrom=dataurl&layerid=".$option->resourceId);
- $resourcesArray[$indexResourceArray]->format = "ATOM Viewer";
+ $resourcesArray[$indexResourceArray]->format = "ATOM Viewer";
+ //$resourcesArray[$indexResourceArray]->res_transparency_document_change_classification = "unaltered";
$indexResourceArray++;
//views to generate
//build whole json structure
@@ -548,6 +1009,7 @@
$resourcesArray[$indexResourceArray]->description = "Download von Vektordaten (wfs-basiert) über INSPIRE ATOM Feed: ".$metadataObject->title;
$resourcesArray[$indexResourceArray]->url = $mapbenderUrl."/plugins/mb_downloadFeedClient.php?url=".urlencode($mapbenderUrl."/php/mod_inspireDownloadFeed.php?id=".$metadataUuid."&type=SERVICE&generateFrom=wfs&wfsid=".$option->serviceId);
$resourcesArray[$indexResourceArray]->format = "ATOM Viewer";
+ //$resourcesArray[$indexResourceArray]->res_transparency_document_change_classification = "unaltered";
$indexResourceArray++;
//views to generate
//build whole json structure
@@ -565,6 +1027,7 @@
$resourcesArray[$indexResourceArray]->description = "Download von verlinkten Daten über INSPIRE ATOM Feed: ".$metadataObject->title;
$resourcesArray[$indexResourceArray]->url = $mapbenderUrl."/plugins/mb_downloadFeedClient.php?url=".urlencode($mapbenderUrl."/php/mod_inspireDownloadFeed.php?id=".$metadataUuid."&type=SERVICE&generateFrom=metadata");
$resourcesArray[$indexResourceArray]->format = "ATOM Viewer";
+ //$resourcesArray[$indexResourceArray]->res_transparency_document_change_classification = "unaltered";
$indexResourceArray++;
//views to generate
//build whole json structure
Modified: trunk/mapbender/http/javascripts/mod_syncCkan_client.php
===================================================================
--- trunk/mapbender/http/javascripts/mod_syncCkan_client.php 2017-08-01 09:54:15 UTC (rev 9757)
+++ trunk/mapbender/http/javascripts/mod_syncCkan_client.php 2017-08-09 08:12:36 UTC (rev 9758)
@@ -63,8 +63,105 @@
$title = _mb('Ckan sync module');
?>
<title><?php echo $title;?></title>
-<script src="../extensions/jquery-1.12.0.min.js"></script>
+<!--<script src="../extensions/jquery-1.12.0.min.js"></script> -->
+<!--TODO use newer jquery/ui libs! -->
+<script src="../extensions/jquery-ui-1.8.16.custom/js/jquery-1.6.2.min.js"></script>
+<script src="../extensions/jquery-ui-1.8.16.custom/js/jquery-ui-1.8.16.custom.min.js"></script>
+<!--<script src="../extensions/jquery-ui-1.12.1/external/jquery.js"></script> -->
+<!--<script src="../extensions/jquery-ui-1.12.1/jquery-ui.min.js"></script> -->
+<!--<link rel="stylesheet" href="../extensions/jquery-ui-1.12.1/jquery-ui.min.css"> -->
+<link rel="stylesheet" href="../extensions/jquery-ui-1.8.16.custom/css/ui-lightness/jquery-ui-1.8.16.custom.css">
<script>
+//https://stackoverflow.com/questions/29298462/c-curcss-is-not-a-function-bug-from-jquery
+/*jQuery.curCSS = function(element, prop, val) {
+ return jQuery(element).css(prop, val);
+};*/
+
+function showCatalogues(compareTimestamps, syncDepartment, operation, orgaId) {
+ /*for (csw of csw_catalogues) {
+ console.log(csw);
+ }*/
+ //alert(syncDepartment);
+ $("#load_catalogue_statistics").css("display","block");
+ $.ajax({
+ url: '../php/mod_syncCkan_server.php',
+ type: "post",
+ async: true,
+ data: {compareTimestamps: compareTimestamps, syncDepartment: syncDepartment, operation: operation, orgaId: orgaId},
+ dataType: "json",
+ success: function(result) {
+ if (result.success == true) {
+ //alert(JSON.stringify(result.result));
+ $( "#show_catalogues" ).dialog({
+ height: 200,
+ width: 550,
+ modal: true,
+ close: function(event, ui)
+ {
+ //$(this).destroy().remove();
+ $("#csw_sync_status_table tr:gt(0)").remove();
+ }
+ });
+ //$( "#show_catalogues" ).
+ if (operation == 'listCatalogues') {
+ //initialize table
+ for (orga of result.result.result.external_csw) {
+ //read length of delete, update, create into variables
+ if ("undefined" !== typeof(orga.delete)) {var p_delete = (orga.delete).length;} else {var p_delete = 0;}
+ if ("undefined" !== typeof(orga.update)) {var p_update = (orga.update).length;} else {var p_update = 0;}
+ //alert(JSON.stringify(orga.update));
+ //alert(typeof(orga.update));
+ if ("undefined" !== typeof(orga.create)) {var p_create = (orga.create).length;} else {var p_create = 0;}
+ $('#csw_sync_status_table tr:last').after('<tr id=\'csw_r_id_'+orga.id+'\'>'+'<td id=\'csw_ckanorgauuid_'+orga.id+'\'><a target=\'_blank\' href=\'<?php echo $ckanShowOrgaUrl;?>'+orga.ckan_orga_ident+'\'>'+orga.ckan_orga_ident+' ('+orga.count_ckan_packages+')'+'</a></td>'+'<td id=\'csw_orgatitle_'+orga.id+'\'>'+'<a target=\'_blank\' href=\'../php/mod_showOrganizationInfo.php?id='+orga.id+'\'>'+orga.title+' ('+orga.count_csw_packages+')'+'</a>'+'</td>'+'<td id=\'csw_to_delete_'+orga.id+'\'>'+p_delete+'</td>'+'<td id=\'csw_to_update_'+orga.id+'\'>'+p_update+'</td>'+'<td id=\'csw_to_create_'+orga.id+'\'>'+p_create+'</td>'+'</tr>');
+ //add button for start syncing if something may be done ;-)
+ if ((p_delete+p_update+p_create) > 0) {
+ //alert(p_delete+p_update+p_create);
+ //$form .= "<button class=\"btn btn-primary\" type=\"button\" id=\"maintenance_button\" onclick=\"callServer('".$resourceType."','".$maintenanceFunction."',$('#resource_id_list').val(),"."1".");\">";
+ //the first orga.id is the csw id in case of csw sync!!!!!!!
+ $('#csw_r_id_'+orga.id+' td:last').after('<td id=\'csw_button_column_'+orga.id+'\'><button class=\"btn btn-primary\" type=\"button\" id=\"csw_sync_button_'+orga.id+'\" onclick=\"showCatalogues('+compareTimestamps+','+orga.id+',\'syncCsw\','+orgaId+');\">Start sync via CSW</button></td>');
+ } else {
+ //alert(p_delete+p_update+p_create+' - lower or equal zero');
+ //deactivated button
+ $('#csw_r_id_'+orga.id+' td:last').after('<td id=\'csw_button_column_'+orga.id+'\'><button class=\"btn btn-primary\" type=\"button\" id=\"csw_sync_button_'+orga.id+'\" disabled>Nothing to do</button></td>');
+ }
+ }
+
+ if (operation == 'syncCsw')
+ if (result.success == true) {
+ //update values
+ $('#csw_to_delete_'+result.result.orga_id).text(parseInt($('#csw_to_delete_'+result.result.orga_id).text()) - result.result.numberOfDeletedPackages);
+ $('#csw_to_update_'+result.result.orga_id).text(parseInt($('#csw_to_update_'+result.result.orga_id).text()) - result.result.numberOfUpdatedPackages);
+ $('#csw_to_create_'+result.result.orga_id).text(parseInt($('#csw_to_create_'+result.result.orga_id).text()) - result.result.numberOfCreatedPackages);
+ //check if something more is to be done
+ if ((parseInt($('#csw_to_delete_'+result.result.orga_id).text()) + parseInt($('#csw_to_update_'+result.result.orga_id).text()) + parseInt($('#csw_to_create_'+result.result.orga_id).text())) == 0) {
+ //alert('drop button');
+ $('#csw_button_column_'+result.result.orga_id).remove();
+ } else {
+ //alert((parseInt($('#to_delete_'+result.result.orga_id).text()) + parseInt($('#to_update_'+result.result.orga_id).text()) + parseInt($('#to_create_'+result.result.orga_id).text())));
+ }
+ //$("#csw_sync_status_table tr").remove();
+ //$("#csw_sync_status_table").empty();
+ alert("Packages created: "+result.result.numberOfCreatedPackages+" - Packages updated: "+numberOfUpdatedPackages+" - Packages deleted: "+numberOfDeleteddPackages);
+ }
+ $("#sync_single_csw").css("display","none");
+ }
+
+ //set title
+ //show button with information about the catalogues and the buttons!
+ //show table
+ //foreach catalogue show line
+ //show button to sync
+ } else {
+ alert(result.error.message);
+ }
+ $("#load_catalogue_statistics").css("display","none");
+ //close dialog
+ //$( "#show_catalogues" ).dialog('close');
+ }
+ });
+ return false;
+}
+
function callServer(compareTimestamps, syncDepartment) {
if (syncDepartment == 0) {
$("#get_orga_list_info").css("display","block");
@@ -94,8 +191,26 @@
if ((p_delete+p_update+p_create) > 0) {
//$form .= "<button class=\"btn btn-primary\" type=\"button\" id=\"maintenance_button\" onclick=\"callServer('".$resourceType."','".$maintenanceFunction."',$('#resource_id_list').val(),"."1".");\">";
$('#r_id_'+orga.id+' td:last').after('<td id=\'button_column_'+orga.id+'\'><button class=\"btn btn-primary\" type=\"button\" id=\"sync_button_'+orga.id+'\" onclick=\"callServer('+compareTimestamps+','+orga.id+');\">Start sync</button></td>');
+ } else {
+ //deactivated button
+ $('#r_id_'+orga.id+' td:last').after('<td id=\'button_column_'+orga.id+'\'><button class=\"btn btn-primary\" type=\"button\" id=\"sync_button_'+orga.id+'\" disabled>Nothing to do</button></td>');
}
- //
+ if (orga.csw_catalogues !== null) {
+ //csw_cataloguesObject = Object.assign({}, orga.csw_catalogues);
+ //csw_cataloguesObject = {};
+ /*var i = 0;
+ for (csw of orga.csw_catalogues) {
+ csw_cataloguesObject[i] = csw;
+ }*/
+ $('#r_id_'+orga.id+' td:last').after('<td id=\'external_button_column_'+orga.id+'\'><button class=\"btn btn-primary\" type=\"button\" id=\"external_sync_button_'+orga.id+'\" onclick=\"showCatalogues('+compareTimestamps+','+orga.id+',\'listCatalogues\','+orga.id+');\">Show catalogue status</button></td><td></td>');
+ /*console.log(typeof(orga.csw_catalogues[0].organisation_filter));
+ console.log(orga.csw_catalogues[0].organisation_filter);
+ for (csw of orga.csw_catalogues) {
+ console.log(csw);
+
+ }*/
+ }
+ //onclick=\"showCatalogues('+compareTimestamps+','+orga+');\"
}
} else {
//update row for specific organization
@@ -140,6 +255,24 @@
<div id="title"><?php echo $title; ?></div>
<div id="get_orga_list_info" style="display: none;"><p><img class="loading_symbol" src="../img/loader_lightblue.gif" style="margin-left: auto; margin-right: auto;"/><?php echo _mb("Getting organization info ..."); ?></p></div>
<div id="sync_single_orga" style="display: none;"><p><img class="loading_symbol" src="../img/loader_lightblue.gif" style="margin-left: auto; margin-right: auto;"/><?php echo _mb("Syncing metadata ..."); ?></p></div>
+<div id="sync_single_csw" style="display: none;"><p><img class="loading_symbol" src="../img/loader_lightblue.gif" style="margin-left: auto; margin-right: auto;"/><?php echo _mb("Syncing metadata via CSW ..."); ?></p></div>
+<div id="show_catalogues" style="display: none;">
+<form id="csw_sync_status_form">
+ <table id ="csw_sync_status_table">
+ <tr id="csw_sync_status_table_row_header">
+ <th><?php echo _mb('Ckan instance'); ?></th>
+ <th><?php echo _mb('External CSW'); ?></th>
+ <th><?php echo _mb('# delete'); ?></th>
+ <th><?php echo _mb('# update'); ?></th>
+ <th><?php echo _mb('# create'); ?></th>
+ <th><?php echo _mb('Action'); ?></th>
+ </tr>
+ </table>
+</form>
+</div>
+<div id="load_catalogue_statistics" style="display: none;"><p><img class="loading_symbol" src="../img/loader_lightblue.gif" style="margin-left: auto; margin-right: auto;"/><?php echo _mb("Loading catalogue statistics ..."); ?></p></div>
+<div id="sync_single_catalogue" style="display: none;"><p><img class="loading_symbol" src="../img/loader_lightblue.gif" style="margin-left: auto; margin-right: auto;"/><?php echo _mb("Syncing catalogue metadata ..."); ?></p></div>
+
<form id="sync_status_form">
<table id ="sync_status_table">
<tr id="sync_status_table_row_header">
@@ -148,7 +281,8 @@
<th><?php echo _mb('# delete'); ?></th>
<th><?php echo _mb('# update'); ?></th>
<th><?php echo _mb('# create'); ?></th>
- <th><?php echo _mb('Action'); ?></th>
+ <th><?php echo _mb('Action'); ?></th>
+ <th><?php echo _mb('External catalogues'); ?></th>
</tr>
</table>
</form>
Modified: trunk/mapbender/http/php/mod_syncCkan_server.php
===================================================================
--- trunk/mapbender/http/php/mod_syncCkan_server.php 2017-08-01 09:54:15 UTC (rev 9757)
+++ trunk/mapbender/http/php/mod_syncCkan_server.php 2017-08-09 08:12:36 UTC (rev 9758)
@@ -21,7 +21,7 @@
$listAllMetadataInJson = true;
//initiate resultObject to give back as json
$resultObject->success = false;
-
+$operation = false;
//parse request parameter
if (isset($_REQUEST["registratingDepartments"]) & $_REQUEST["registratingDepartments"] != "") {
//validate to csv integer list
@@ -49,6 +49,29 @@
$testMatch = NULL;
}
+if (isset($_REQUEST["orgaId"]) && $_REQUEST["orgaId"] !== "" && $_REQUEST["orgaId"] !== null) {
+ $testMatch = $_REQUEST["orgaId"];
+ $pattern = '/^[0-9]*$/';
+ if (!preg_match($pattern,$testMatch)){
+ $resultObject->error->message = 'Parameter orgaId is not valid (integer).';
+ echo json_encode($resultObject);
+ die();
+ }
+ $orgaId = (integer)$testMatch;
+ $testMatch = NULL;
+}
+
+if (isset($_REQUEST["operation"]) && $_REQUEST["operation"] !== "" && $_REQUEST["operation"] !== null) {
+ $testMatch = $_REQUEST["operation"];
+ if (!($testMatch == 'listCatalogues' or $testMatch == 'syncCatalogue' or $testMatch == 'syncCsw')){
+ $resultObject->error->message = 'Parameter operation is not valid (listCatalogues, syncCatalogue, syncCsw).';
+ echo json_encode($resultObject);
+ die();
+ }
+ $operation = $testMatch;
+ $testMatch = NULL;
+}
+
if (isset($_REQUEST["userId"]) & $_REQUEST["userId"] != "") {
$testMatch = $_REQUEST["userId"];
$pattern = '/^[0-9]*$/';
@@ -119,9 +142,6 @@
"resultObj": "s.th."
}
}
-
-
-
*/
$syncCkanClass = new SyncCkan();
@@ -133,11 +153,55 @@
$syncCkanClass->syncOrgaId = $syncDepartment;
}
+if ($operation == 'listCatalogues') {
+ //get orga id from mapbender group!! - where from?
+ $departmentsArray = $syncCkanClass->getMapbenderOrganizations();
+ //invoke check for csw
+ $result = new stdClass();
+ //check for datasets - ckan vs. csw
+ $result->result = json_decode($syncCkanClass->getSyncListCswJson($departmentsArray, $listAllMetadataInJson = true));
+ $result->success = true;
+ header('Content-type:application/json;charset=utf-8');
+ echo json_encode($result);
+ die();
+}
+
+if ($operation == 'syncCsw') {
+ //check if user is allowed to sync for requested organisation
+ //TODO - make code better
+ //overwrite organization from cswId with right orgaId
+ $test = $syncCkanClass->syncOrgaId;
+ $syncCkanClass->syncOrgaId = $orgaId;
+ //$e = new mb_exception($syncCkanClass->syncOrgaId);
+ $departmentsArray = $syncCkanClass->getMapbenderOrganizations();
+ //rewind orgaid to cswid to get right synclist
+ $syncCkanClass->syncOrgaId = $test;
+ $syncListJsonCsw = $syncCkanClass->getSyncListCswJson($departmentsArray, true);
+ //for synching use right orga id for getting apikey for invoking $syncCkanClass->syncSingleCsw
+ $syncCkanClass->syncOrgaId = $orgaId;
+ $syncList = json_decode($syncListJsonCsw);
+ if ($syncList->success = true) {
+ foreach ($syncList->result->external_csw as $orga) {
+ //TODO try to sync single orga - the class has already set the syncOrgaId if wished!
+ //if ($syncDepartment == $orga->id) {
+ //overwrite result with result from sync process
+ $syncList = json_decode($syncCkanClass->syncSingleCsw(json_encode($orga)));
+ //}
+ }
+ }
+ //create new syncListJson
+ $syncListJson = json_encode($syncList);
+ header('Content-type:application/json;charset=utf-8');
+ echo $syncListJson;
+ die();
+}
+
$departmentsArray = $syncCkanClass->getMapbenderOrganizations();
//second parameter is listAllMetadataInJson ( = true) - it is needed if we want to sync afterwards. The syncList includes all necessary information about one organization
$syncListJson = $syncCkanClass->getSyncListJson($departmentsArray, true);
+
$syncList = json_decode($syncListJson);
if ($syncList->success = true) {
foreach ($syncList->result->geoportal_organization as $orga) {
@@ -153,5 +217,4 @@
header('Content-type:application/json;charset=utf-8');
echo $syncListJson;
-
?>
More information about the Mapbender_commits
mailing list