[Mapbender-commits] r9629 - trunk/mapbender/http/classes

svn_mapbender at osgeo.org svn_mapbender at osgeo.org
Thu Dec 29 06:20:25 PST 2016


Author: armin11
Date: 2016-12-29 06:20:25 -0800 (Thu, 29 Dec 2016)
New Revision: 9629

Added:
   trunk/mapbender/http/classes/class_syncCkan.php
Modified:
   trunk/mapbender/http/classes/class_ckanApi.php
Log:
Adoptions for syncing mapbender metadata catalogue with ckan > 2.5

Modified: trunk/mapbender/http/classes/class_ckanApi.php
===================================================================
--- trunk/mapbender/http/classes/class_ckanApi.php	2016-12-13 16:09:17 UTC (rev 9628)
+++ trunk/mapbender/http/classes/class_ckanApi.php	2016-12-29 14:20:25 UTC (rev 9629)
@@ -59,7 +59,7 @@
 	 * @var		string
 	 * @link	http://knowledgeforge.net/ckan/doc/ckan/api.html#api-versions
 	 */
-	private $api_version = '2';
+	public $api_version = '2';
 
 	/**
 	 * URI to the CKAN web service.
@@ -128,14 +128,21 @@
 		'package_show' => 'action/package_show',
 		'package_update' => 'action/package_update',
 		'package_delete' => 'action/package_delete',
+                'package_search' => 'action/package_search',
 		'resource_create' => 'action/resource_create',
 		'resource_show' => 'action/resource_show',
 		'resource_update' => 'action/resource_update',
 		'resource_delete' => 'action/resource_delete',
+		'resource_view_show' => 'action/resource_view_show',
+		'resource_view_create' => 'action/resource_view_create',
+		'resource_view_update' => 'action/resource_view_update',
+		'resource_view_list' => 'action/resource_view_list',
+		'resource_view_delete' => 'action/resource_view_delete',
 		'organization_create' => 'action/organization_create',
 		'organization_show' => 'action/organization_show',
 		'organization_update' => 'action/organization_update',
 		'organization_delete' => 'action/organization_delete',
+		'organization_list_for_user' => 'action/organization_list_for_user',
 		'group_create' => 'action/group_create',
 		'group_update' => 'action/group_update',
 		'group_delete' => 'action/group_delete',
@@ -178,7 +185,7 @@
 		// If provided, set the Name of host to call - needed for decide if proxy should be used.
 		if ($host_name)
 		{
-			$e = new mb_exception($host_name);
+			//$e = new mb_exception($host_name);
 			$this->set_host_name($host_name);
 		}
 		// Set base URI and Ckan_client user agent string.
@@ -186,7 +193,7 @@
 		$this->set_user_agent();
 		// Create cURL object.
 		$this->ch = curl_init();
-		$e = new mb_exception($this->host_name);
+		//$e = new mb_exception($this->host_name);
 	    	$NOT_PROXY_HOSTS_array = explode(",", NOT_PROXY_HOSTS);
 
 		if(CONNECTION_PROXY != "" AND (in_array($this->host_name, $NOT_PROXY_HOSTS_array)!= true)){
@@ -378,6 +385,20 @@
 			$id);
 	}
 
+	// package search
+
+	/**
+	 * @access	public
+	 * @param  	string query (q and qf parameters)
+	 * @return	?
+	 * @link	http://docs.ckan.org/en/latest/api/#ckan.logic.action.get.package_search
+	 */
+	public function action_package_search($query)
+	{
+		return $this->make_request('POST', 
+			$this->actionList['package_search'], 
+			$query);
+	}
 	// group create 
 
 	/**
@@ -386,6 +407,7 @@
 	 * @return	the newly created group as dictionary
 	 * @link	http://docs.ckan.org/en/latest/apiv3.html#ckan.logic.action.create.group_create
 	 */
+
 	public function action_group_create($data)
 	{
 		return $this->make_request('POST', 
@@ -438,6 +460,153 @@
 			$data);
 	}
 	
+	// organization create 
+
+	/**
+	 * @access	public
+	 * @param  	string organization
+	 * @return	the newly created organization as dictionary
+	 * @link	http://docs.ckan.org/en/latest/api/index.html
+	 */
+	public function action_organization_create($data)
+	{
+		return $this->make_request('POST', 
+			$this->actionList['organization_create'], 
+			$data);
+	}
+
+	// organization show
+
+	/**
+	 * @access	public
+	 * @param  	string organization
+	 * @return	the organization to show as dictionary
+	 * @link	http://docs.ckan.org/en/latest/api/index.html
+	 */
+	public function action_organization_show($id)
+	{
+		return $this->make_request('POST', 
+			$this->actionList['organization_show'], 
+			$id);
+	}
+
+	// organization list for user
+
+	/**
+	 * @access	public
+	 * @param  	user name or id
+	 * @return	the organizations of the user to show as dictionary
+	 * @link	http://docs.ckan.org/en/latest/api/index.html
+	 */
+	public function action_organization_list_for_user($id)
+	{
+		return $this->make_request('POST', 
+			$this->actionList['organization_list_for_user'], 
+			$id);
+	}
+
+	// organization delete
+
+	/**
+	 * @access	public
+	 * @param  	string  id
+	 * @return	the organization
+	 * @link	http://docs.ckan.org/en/latest/api/index.html
+	 */
+	public function action_organization_delete($id)
+	{
+		return $this->make_request('POST', 
+			$this->actionList['organization_delete'], 
+			$id);
+	}
+
+	// organization update
+
+	/**
+	 * @access	public
+	 * @param  	string organization
+	 * @return	the updated organization as dictionary
+	 * @link	http://docs.ckan.org/en/latest/api/index.html
+	 */
+	public function action_organization_update($data)
+	{
+		return $this->make_request('POST', 
+			$this->actionList['organization_update'], 
+			$data);
+	}
+
+	// resource_view show
+
+	/**
+	 * @access	public
+	 * @param  	string resource_view
+	 * @return	the resource_view to show as dictionary
+	 * @link	http://docs.ckan.org/en/latest/api/index.html
+	 */
+	public function action_resource_view_show($id)
+	{
+		return $this->make_request('POST', 
+			$this->actionList['resource_view_show'], 
+			$id);
+	}
+
+	// resource_view create
+
+	/**
+	 * @access	public
+	 * @param  	string resource_view
+	 * @return	the resource_view to be created as dictionary
+	 * @link	http://docs.ckan.org/en/latest/api/index.html
+	 */
+	public function action_resource_view_create($resource_view)
+	{
+		return $this->make_request('POST', 
+			$this->actionList['resource_view_create'], 
+			$resource_view);
+	}
+
+	// resource_view update
+
+	/**
+	 * @access	public
+	 * @param  	string resource_view
+	 * @return	the resource_view to be created as dictionary
+	 * @link	http://docs.ckan.org/en/latest/api/index.html
+	 */
+	public function action_resource_view_update($resource_view)
+	{
+		return $this->make_request('POST', 
+			$this->actionList['resource_view_update'], 
+			$resource_view);
+	}
+
+	/**
+	 * @access	public
+	 * @param  	string resource_id
+	 * @return	the resource_views for the given resource_id as dictionary
+	 * @link	http://docs.ckan.org/en/latest/api/index.html
+	 */
+	public function action_resource_view_list($resource_id)
+	{
+		return $this->make_request('POST', 
+			$this->actionList['resource_view_list'], 
+			$resource_id);
+	}
+
+	/**
+	 * @access	public
+	 * @param  	string resource_view_id
+	 * @return	the resource_view_id for the given resource_view as dictionary
+	 * @link	http://docs.ckan.org/en/latest/api/index.html
+	 */
+	public function action_resource_view_delete($resource_view_id)
+	{
+		return $this->make_request('POST', 
+			$this->actionList['resource_view_delete'], 
+			$resource_view_id);
+	}
+
+
 	//group_package_show
 
 	/**
@@ -497,7 +666,7 @@
 
 	public function get_group_by_name($name)
 	{
-		$e = new mb_exception("testckan: get group: ".$this->resources['group_register'] . "/" . urlencode($name));
+		//$e = new mb_exception("testckan: get group: ".$this->resources['group_register'] . "/" . urlencode($name));
 		return $this->make_request('GET', 
 		$this->resources['group_register'] . "/" . urlencode($name));
 	}
@@ -845,45 +1014,57 @@
 	 * @return	mixed	If success, either an array or object. Otherwise FALSE.
 
 	 */
-	private function make_request($method, $url, $data = FALSE)
-	{
+	private function make_request($method, $url, $data = FALSE) {
 		// Set cURL method.
 		curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, strtoupper($method));
 		// Set cURL URI.
-		$e = new mb_exception("testckan: ckan url to request: ".$this->base_url . $url);
+		//$e = new mb_exception("testckan: ckan url to request: ".$this->base_url . $url);
 		$curlUrl = $this->base_url . $url;
 		curl_setopt($this->ch, CURLOPT_URL, $curlUrl);
 		// If POST or PUT, add Authorization: header and request body
-		if ($method === 'POST' || $method === 'PUT')
-		{
+		if ($method === 'POST' || $method === 'PUT') {
 			// We needs a key and some data, yo!
-			//$e = new mb_exception("method: ".$method." new url: ".$this->base_url . $url." data: ".$data);
-			if ( ! ($this->api_key && $data))
-			{
-				// throw exception
-				throw new Exception('Missing either an API key or POST data.');
+			//don't need post data for organization_list_for_user, api_key may be enough
+			if (strpos($url,"organization_list_for_user") !== false) {
+				if ( !($this->api_key)) {
+					// throw exception
+					$e = new mb_exception("Missing an API key.");
+				} else {
+					// Add Authorization: header.
+					$this->ch_headers = $this->setApiKeyInHeader($this->ch_headers, $this->api_key);
+					// Add data to request body.
+					curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
+				}
+			} else {
+				if ( !($this->api_key) && !($data)) {
+					// throw exception
+					$e = new mb_exception("Missing either an API key or POST data or both.");
+				} else {
+					// Add Authorization: header.
+					$this->ch_headers = $this->setApiKeyInHeader($this->ch_headers, $this->api_key);
+					// Add data to request body.
+					curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
+				}
 			}
-			else
-			{
-				// Add Authorization: header.
-				$this->ch_headers[] = 'X-CKAN-API-Key: ' . $this->api_key;
-				$e = new mb_notice("added following to headers: ".'X-CKAN-API-Key: ' . $this->api_key);
-				// Add data to request body.
-				curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
-			}
-		}
-		else
-		{
+		//other method than post or put
+		} else {
 			// Since we can't use HTTPS,
 			 // if it's in there, remove Authorization: header
-			$key = array_search('Authorization: ' . $this->api_key, 
+			$key1 = array_search('Authorization: ' . $this->api_key, 
 				$this->ch_headers);
-			if ($key !== FALSE)
-			{
+			$key2 = array_search('X-CKAN-API-Key: ' . $this->api_key, 
+				$this->ch_headers);
+			if ($key1 !== FALSE) {
 				unset($this->ch_headers[$key]);
 			}
+			if ($key2 !== FALSE) {
+				unset($this->ch_headers[$key]);
+			}
 			curl_setopt($this->ch, CURLOPT_POSTFIELDS, NULL);
 		}
+		/*foreach ($this->ch_headers as $header) {
+			$e = new mb_exception("header: ".$header);
+		}*/
 		// Set headers.
 		curl_setopt($this->ch, CURLOPT_HTTPHEADER, $this->ch_headers);
 		// Execute request and get response headers.
@@ -892,25 +1073,51 @@
 		// Check HTTP response code
 		if ($info['http_code'] !== 200)
 		{
-			throw new Exception($info['http_code'] . ': ' . 
-				$this->http_status_codes[$info['http_code']]);
+			$e = new mb_exception("CKAN API request returned ".$info['http_code'] . ': ' . $this->http_status_codes[$info['http_code']]);
 		} else {
-			$e = new mb_exception("Returned 200 - OK");
-			//$e = new mb_exception($response);
+			$e = new mb_notice("CKAN API request returned 200 - OK");
 		}
+		//$e = new mb_exception("response: ".$response);
+		//$e = new mb_exception("content_type: ".$info['content_type']);
+		//$e = new mb_exception("send data: ".$data);
 		// Determine how to parse
-		if (isset($info['content_type']) && $info['content_type'])
-		{
+		if (isset($info['content_type']) && $info['content_type']) {
 			$content_type = str_replace('application/', '', 
 				substr($info['content_type'], 0, 
 				strpos($info['content_type'], ';')));
 			//return $response;
+			//$e = new mb_exception("content_type: ".$content_type);
 			return $this->parse_response($response, $content_type);
+		} else {
+			$e = new mb_exception("CKAN API request returned unknown content type!");
 		}
-		else
-		{
-			throw new Exception('Unknown content type.');
+	}
+
+	/**
+	 * SET API KEY in HTTP header array
+	 *
+	 * @access	private
+	 * @param	array  HTTP header array
+	 * @param	string API key
+	 * @return	mixed  If success, returns changed http header array . Otherwise FALSE.
+
+	 */
+	private function setApiKeyInHeader($headerArray, $apiKey) {
+		$keyFound = false;
+		//check if some key is already set
+		$index = 0;
+		foreach ($headerArray as $header) {
+			if (strpos($header, "X-CKAN-API-Key:") !== false){
+				$keyFound = $index;
+			}
+			$index++;
 		}
+		if ($keyFound !== false) {
+			$headerArray[$index] = $apiKey;
+		} else {
+			$headerArray[] = 'X-CKAN-API-Key: ' . $apiKey;
+		}
+		return $headerArray;
 	}
 
 	/**
@@ -926,7 +1133,7 @@
 	{
 		if ($data)
 		{
-			if ('json' === $format)
+			if ($format == 'json')
 			{
 				return json_decode($data);
 			}

Added: trunk/mapbender/http/classes/class_syncCkan.php
===================================================================
--- trunk/mapbender/http/classes/class_syncCkan.php	                        (rev 0)
+++ trunk/mapbender/http/classes/class_syncCkan.php	2016-12-29 14:20:25 UTC (rev 9629)
@@ -0,0 +1,664 @@
+<?php
+/**
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2, or (at your option)
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+require_once(dirname(__FILE__) . '/../../core/globalSettings.php');
+require_once(dirname(__FILE__).'/../classes/class_connector.php');
+require_once(dirname(__FILE__).'/../classes/class_ckanApi25.php');
+require_once(dirname(__FILE__).'/../classes/class_group.php');
+require_once(dirname(__FILE__) . '/../php/mod_getDownloadOptions.php');
+require_once(dirname(__FILE__).'/../../conf/ckan.conf');
+
+/**
+ * Class to provide functions to sync a mapbender metadata repository to a ckan instance, tested with ckan 2.5.3 in 2016
+ *
+ * @return syncCkan object
+ */
+
+class syncCkan {
+    var $ckanApiKey;
+    var $ckanApiUrl;
+    var $ckanApiVersion;
+    var $syncOrgaId;
+    var $mapbenderUserId;
+    var $topicCkanCategoryMap;
+    var $compareTimestamps;
+
+    public function __construct() {
+        if (defined("CKAN_SERVER_PORT") && CKAN_SERVER_PORT !== '') {
+	    $this->ckanApiUrl = CKAN_SERVER_IP.":".CKAN_SERVER_PORT;
+	} else {
+	    $this->ckanApiUrl = CKAN_SERVER_IP;
+        }
+        //$this->ckanApiKey;
+	if (defined("CKAN_API_VERSION") && CKAN_API_VERSION !== '') {
+	    $this->ckanApiVersion = CKAN_API_VERSION;
+	} else {
+	    $this->ckanApiVersion = 3;
+        }
+	$this->mapbenderUserId = 0;
+	$this->syncOrgaId = 0;
+	$this->topicCkanCategoryMap = $topicCkanCategoryMap; //from ckan.conf
+	$this->compareTimestamps = false; //default to update each dataset, because the ckan index for metadata_modified may not be up to date !!!
+    }
+
+    public function getMapbenderOrganizations() {
+        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)";
+	        $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)";
+	        $v = array($this->mapbenderUserId);
+	        $t = array('i');
+            }
+            $res = db_prep_query($sql, $v, $t);
+            $countDepArray = 0;
+            while($row = db_fetch_array($res)){
+                $departmentsArray[$countDepArray]["id"] = $row["mb_group_id"];
+                $departmentsArray[$countDepArray]["name"] = $row["mb_group_name"];
+                $departmentsArray[$countDepArray]["email"] = $row["mb_group_email"];
+                $departmentsArray[$countDepArray]["title"] = $row["mb_group_title"];
+                if ($departmentsArray[$countDepArray]["email"] == "" || $departmentsArray[$countDepArray]["email"] == null) {
+                    $departmentsArray[$countDepArray]["email"] = "dummy at geoportal.rlp.de";
+                }
+                if ($departmentsArray[$countDepArray]["title"] == "" || $departmentsArray[$countDepArray]["title"] == null) {
+                    $departmentsArray[$countDepArray]["title"] = "dummy contact title";
+                }
+                $departmentsArray[$countDepArray]["ckan_uuid"] = $row["mb_group_ckan_uuid"];
+                $departmentsArray[$countDepArray]["ckan_api_key"] = $row["mb_group_ckan_api_key"];
+                if ($row["mb_user_mb_group_type"] == 2) {
+                    $departmentsArray[$countDepArray]["is_primary_group"] = true;
+                } else {
+                    $departmentsArray[$countDepArray]["is_primary_group"] = false;
+                }
+                $countDepArray = $countDepArray + 1; 
+            }
+            //TODO: get user information about the registrating person for metadata contact!
+            if ($countDepArray == 0) {
+	        $e = new mb_exception("classes/class_syncCkan.php:No organization found for which the user with id ".$this->mapbenderUserId." is allowed to publish metadata!");
+                return false;
+            }
+            return $departmentsArray;
+        } else {
+            $e = new mb_exception("classes/class_syncCkan.php: No mapbenderUserId is given for the class!");
+            return false;
+        }
+    }
+
+    public function getSyncListJson($departmentsArray, $listAllMetadataInJson = false) {
+        $syncList = new stdClass();
+        $numberGeoportalOrga = 0;
+        foreach ($departmentsArray as $organization) {
+            $syncList->geoportal_organization[$numberGeoportalOrga]->name = $organization["name"];
+            $syncList->geoportal_organization[$numberGeoportalOrga]->id = $organization["id"];
+            $syncList->geoportal_organization[$numberGeoportalOrga]->title = $organization["title"];
+            $syncList->geoportal_organization[$numberGeoportalOrga]->email = $organization["email"];
+            $syncList->geoportal_organization[$numberGeoportalOrga]->ckan_orga_ident = false;
+            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='http://'.$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"]) {
+                        $syncList->geoportal_organization[$numberGeoportalOrga]->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 = "transparency_category_de_rp:spatial_data AND owner_org:".$organization["ckan_uuid"];
+                        $queryObject->facet = "true";
+                        $listOfSpatialData = $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) {
+                            $syncList->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) {
+                                $ckanMetadataArray[$countCkanMetadataArray]['id'] = $dataset->id;
+                                $ckanMetadataArray[$countCkanMetadataArray]['name'] = $dataset->name;
+                                $ckanMetadataArray[$countCkanMetadataArray]['changedate'] = $dataset->metadata_modified;
+                                if ($listAllMetadataInJson == true) {
+                                    $syncList->geoportal_organization[$numberGeoportalOrga]->ckan_packages[$countCkanMetadataArray]->id = $dataset->name;
+                                    $syncList->geoportal_organization[$numberGeoportalOrga]->ckan_packages[$countCkanMetadataArray]->date_time = $dataset->metadata_modified;
+                                }
+                                //echo $dataset->title." - ".$dataset->name." - ".$dataset->metadata_modified."<br>";
+                                $ckanPackageNames[] = $dataset->name;
+                                $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 !!!!!!
+                        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)";
+                            $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";
+                            $v = array($organization['id']);
+                            $t = array('i');
+                        }
+                        $res = db_prep_query($sql, $v, $t);
+                        $countMetadataArray = 0;
+                        $featuretypeArray = array();
+                        $layerArray = array();
+                        //echo "List of datasets in geoportal instance:"."<br>";
+                        while($row = db_fetch_array($res)){
+                            $metadataArray[$countMetadataArray]["hasResource"] = false;
+                            $metadataArray[$countMetadataArray]["id"] = $row["metadata_id"];
+                            $metadataArray[$countMetadataArray]["uuid"] = $row["uuid"];
+                            $metadataArray[$countMetadataArray]["title"] = $row["title"];
+                            $metadataArray[$countMetadataArray]["changedate"] = $row["lastchanged"];
+                            $metadataArray[$countMetadataArray]["license_id"] = $row["fkey_termsofuse_id"];
+                            $metadataArray[$countMetadataArray]["resources"] = $row["f_get_coupled_resources"];
+                            foreach (json_decode($metadataArray[$countMetadataArray]["resources"])->coupledResources->layerIds as $layerId) {
+                                $layerArray[] = $layerId;
+                                $metadataArray[$countMetadataArray]["hasResource"] = true;
+                            }
+                            foreach (json_decode($metadataArray[$countMetadataArray]["resources"])->coupledResources->featuretypeIds as $featuretypeId) {
+                                $featuretypeArray[] = $featuretypeId;
+                                $metadataArray[$countMetadataArray]["hasResource"] = true;
+                            }
+                            //echo $metadataArray[$countMetadataArray]["title"]." - ".$metadataArray[$countMetadataArray]["uuid"]." - ".$metadataArray[$countMetadataArray]["changedate"]." - ".$metadataArray[$countMetadataArray]["license_id"]." - ".$metadataArray[$countMetadataArray]["resources"]."<br>";
+                            $countMetadataArray = $countMetadataArray + 1; 
+                        }
+                        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 {
+                            $numberGeoportalMetadata = 0;
+                            $geoportalUuids = array();
+                            foreach($metadataArray as $geoportalMetadata) {
+                                if (count($layerArray) > 0  || count($featuretypeArray) > 0) {
+                                    //use only those that have resources!
+                                    if ($geoportalMetadata['hasResource']) {
+                                        if ($listAllMetadataInJson == true) {
+                                            $syncList->geoportal_organization[$numberGeoportalOrga]->geoportal_metadata[$numberGeoportalMetadata]->id = $geoportalMetadata['uuid'];
+                                            $syncList->geoportal_organization[$numberGeoportalOrga]->geoportal_metadata[$numberGeoportalMetadata]->date_time = $geoportalMetadata['changedate'];
+                                            $syncList->geoportal_organization[$numberGeoportalOrga]->geoportal_metadata[$numberGeoportalMetadata]->resources = json_decode($geoportalMetadata['resources']);
+                                        }
+                                        $geoportalUuids[] = $geoportalMetadata['uuid'];
+                                        $numberGeoportalMetadata++;
+                                    }
+                                }
+                            }
+                            $syncList->geoportal_organization[$numberGeoportalOrga]->count_geoportal_packages = $numberGeoportalMetadata;
+                            //build diffs for ckan and geoportal
+                            //Arrays: ckanPackageNames / geoportalUuids
+                            //Those which are only in ckan: delete them
+                            $onlyInCkan = array_diff($ckanPackageNames, $geoportalUuids);
+                            //Those which are only in geoportal: create them
+                            $onlyInGeoportal = array_diff($geoportalUuids, $ckanPackageNames);
+                            //Those which are in both - update them if geoportal metadata is newer than the package in ckan
+                            $inBoth = array_intersect($ckanPackageNames, $geoportalUuids);
+                            //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, array_column($ckanMetadataArray,'name'))]['changedate']. " - geoportal time: ".$metadataArray[array_search($uuid, array_column($metadataArray,'uuid'))]['changedate']);
+                                    $dateTimeCkan = new DateTime($ckanMetadataArray[array_search($uuid, array_column($ckanMetadataArray,'name'))]['changedate']);
+                                    $dateTimeGeoportal = new DateTime($metadataArray[array_search($uuid, array_column($metadataArray,'uuid'))]['changedate']);
+                                    if ($dateTimeCkan > $dateTimeGeoportal) {
+                                        //delete from $inBoth!
+                                        $e = new mb_notice("classes/class_syncCkan.php: Ckans package newer than geoportals metadata!");
+                                        $inBoth = array_diff($inBoth, [$uuid]);
+                                    } else {
+                                        $e = new mb_notice("classes/class_syncCkan.php: Ckans package older than geoportals 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));
+                            $syncList->geoportal_organization[$numberGeoportalOrga]->update = $inBoth;
+                            $syncList->geoportal_organization[$numberGeoportalOrga]->delete = $onlyInCkan;
+                            $syncList->geoportal_organization[$numberGeoportalOrga]->create = $onlyInGeoportal;
+                        }
+                        //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> - ".$numberGeoportalOrga."<br>";
+            }
+        $numberGeoportalOrga++;
+        }
+        return json_encode($syncList);    
+    }
+	
+    public function syncSingleOrga($syncListJson) {
+	$syncList = json_decode($syncListJson);
+        if ($syncList->id == $this->syncOrgaId) {
+	    //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='http://'.$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;
+	    }
+            //echo "Synchronize metadata catalogues:"."<br>";
+            foreach($syncList->delete as $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!");
+                } else {
+                    $e = new mb_exception("classes/class_syncCkan.php: A problem occured while trying to delete ckan package with name ".$ckanNameToDelete);
+                }
+            }
+            foreach ($syncList->geoportal_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!
+			
+                        $resourceJson->id = $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);
+                            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);
+                                    //$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);
+                            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);
+                                    //$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 geoportal metadata!");
+                            }
+                        }
+                    //}
+                }
+            }
+        } else {
+            $e = new mb_exception("classes/class_syncCkan.php (syncSingleOrga): Id from json is not identical to id from class! Sync will not be started!");
+            return false;
+        }
+        return true;
+    }
+
+    private function getCkanRepresentation($uuid, $layerArray, $featuretypeArray, $orgaId, $orgaTitle, $orgaEmail, $topicCkanCategoryMap) {
+        if (defined("MAPBENDER_PATH") && MAPBENDER_PATH != '') { 
+	    $mapbenderUrl = MAPBENDER_PATH;
+	} else {
+	    $mapbenderUrl = "http://www.geoportal.rlp.de/mapbender";
+	}
+	//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";
+	$v = array($uuid);
+	$t = array('s');
+	$res = db_prep_query($sql, $v, $t);
+	if ($res) {
+	    $row = db_fetch_assoc($res);
+	} else {
+	    $e = new mb_exception("classes/class_syncCkan.php: No metadata found for uuid: ".$uuid);
+	    return false;
+	}
+	//title
+	$metadataId = $row['metadata_id'];
+	$metadataUuid = $row['uuid'];
+	$ckanPackage->title = $row['title'];
+	$ckanPackage->notes = $row['abstract'];
+	//build groups
+	//$ckanPackage->groups = ""; //[{"name":"opendatagesetz"},{"name":"transparenzgesetz"}]
+	$ckanPackage->groups[0]->name = "transparenzgesetz";
+        if ($row['is_open'] == 1) {
+	    $ckanPackage->groups[0]->name = "opendatagesetz";
+	    $ckanPackage->isopen = true;
+        } else {
+	    $ckanPackage->isopen = false;
+	}
+	$ckanPackage->name = $row['uuid'];
+	$ckanPackage->owner_org = $orgaId;
+	//$ckanPackage->maintainer = "";
+	//$ckanPackage->maintainer_email = "";
+	$ckanPackage->private = false;
+	//$ckanPackage->id = $row['uuid'];
+	$ckanPackage->author = $orgaTitle;
+	$ckanPackage->author_email = $orgaEmail;
+	$ckanPackage->state = "active";
+	$ckanPackage->license_id = $row['name'];
+	//$ckanPackage->license_id = "odc_odbl";
+	$ckanPackage->license_title = $row['description'];
+	$ckanPackage->license_url = $row['descriptionlink'];
+        //$ckanPackage->url = "";
+	//special categories
+	//$ckanPackage->govdata_categories = [];
+	$ckanPackage->transparency_category_de_rp = "spatial_data";
+	$ckanPackage->type = "ckan-govdata-full-1-1";
+	//build resources:
+	$resourcesArray = array();
+	//initialize views - things for which a preview should be available 
+	$viewArray = array();
+	$indexResourceArray = 0;
+	$indexViewArray = 0;
+	if (count($layerArray) > 0) {
+	    //select relevant layer information
+	    $sql = "SELECT layer_id, layer_title, uuid from layer WHERE layer_id IN (".implode(",", $layerArray).")";
+	    $res = db_query($sql);
+	    if ($res) {
+	        while($row = db_fetch_array($res)) {
+	            //generate "Kartenviewer intern" resource
+	            $resourcesArray[$indexResourceArray]->name = "Integrierte Kartenanzeige";//: ".$row['layer_title'];
+	            $resourcesArray[$indexResourceArray]->id = $row['uuid']."_geoportalrlp_mobile";
+	            $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";
+	            $indexResourceArray++;
+	            //views to generate
+	            $viewArray[$indexViewArray]['view_type'] = "webpage_view";
+	            $viewArray[$indexViewArray]['resource_id'] = $row['uuid']."_geoportalrlp_mobile";
+	            //build whole json structure
+	            $viewJson->resource_id = $row['uuid']."_geoportalrlp_mobile";
+	            //$viewJson->id = $row['uuid']."_geoportalrlp_mobile_view";
+	            $viewJson->title = "Integrierte Kartenanzeige";
+	            $viewJson->description = "Integrierte Kartenanzeige ... description";
+	            $viewJson->view_type = "webpage_view";
+	            $viewArray[$indexViewArray]['json'] = json_encode($viewJson);
+	            $indexViewArray++;
+	            //generate "Kartenviewer extern" resource
+	            $resourcesArray[$indexResourceArray]->name = "Anzeige im GeoPortal.rlp";//: ".$row['layer_title'];
+	            $resourcesArray[$indexResourceArray]->id = $row['uuid']."_geoportalrlp";
+	            $resourcesArray[$indexResourceArray]->description = "Anzeige des Kartenlayers ".$row['layer_title']." im orginären System (GeoPortal.rlp).";
+	            $resourcesArray[$indexResourceArray]->url = $mapbenderUrl."/../portal/karten.html?LAYER[zoom]=1&LAYER[id]=".$row['layer_id'];
+	            $resourcesArray[$indexResourceArray]->format = "Kartenviewer extern";				
+	            $indexResourceArray++;
+	            //generate wms capabilities resource 
+	            $resourcesArray[$indexResourceArray]->name = "WMS Capabilities";// für ".$row['layer_title'];
+	            $resourcesArray[$indexResourceArray]->id = $row['uuid']."_capabilities";
+	            $resourcesArray[$indexResourceArray]->description = "Kartenebene: ".$row['layer_title'];
+	            $resourcesArray[$indexResourceArray]->url = $mapbenderUrl."/php/wms.php?layer_id=".$row['layer_id']."&REQUEST=GetCapabilities&VERSION=1.1.1&SERVICE=WMS";
+	            $resourcesArray[$indexResourceArray]->format = "WMS";
+	            $indexResourceArray++;
+	        }
+	    }
+        }
+        //for INSPIRE ATOM Feed implementations
+        //$e = new mb_exception("Download options for: ".$metadataUuid);
+        $downloadOptionsMetadataArray = array();
+        $downloadOptionsMetadataArray[0] = $metadataUuid;
+        $downloadOptionsJson = getDownloadOptions($downloadOptionsMetadataArray);
+        $metadataObject = json_decode($downloadOptionsJson)->{$metadataUuid};
+        if ($downloadOptionsJson !== null) {
+            foreach ($metadataObject->option as $option) {
+            //$e = new mb_exception("option: ".json_encode($option));	
+            switch ($option->type) {
+                case "wmslayergetmap":
+                    $resourcesArray[$indexResourceArray]->name = "INSPIRE ATOM Feed Viewer";//: ".$metadataObject->title;
+                    $resourcesArray[$indexResourceArray]->id = $option->serviceUuid;
+                    $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";
+                    $indexResourceArray++;
+                    //views to generate
+                    //build whole json structure
+                    $viewJson->resource_id = $option->serviceUuid;
+                    //$viewJson->id = $option->serviceUuid."_view";
+                    $viewJson->title = "INSPIRE ATOM Feed Viewer";
+                    $viewJson->description = "Integrierter INSPIRE ATOM Feed Viewer ... description";
+                    $viewJson->view_type = "webpage_view";
+                    $viewArray[$indexViewArray]['json'] = json_encode($viewJson);
+                    $indexViewArray++;
+                    break;
+                case "wmslayerdataurl":
+                    $resourcesArray[$indexResourceArray]->name = "INSPIRE ATOM Feed Viewer";//: ".$metadataObject->title;
+                    $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";
+                    $indexResourceArray++;
+                    //views to generate
+                    //build whole json structure
+                    $viewJson->resource_id = $option->serviceUuid;
+                    //$viewJson->id = $option->serviceUuid."_view";
+                    $viewJson->title = "INSPIRE ATOM Feed Viewer";
+                    $viewJson->description = "Integrierter INSPIRE ATOM Feed Viewer dataurl ... description";
+                    $viewJson->view_type = "webpage_view";
+                    $viewArray[$indexViewArray]['json'] = json_encode($viewJson);
+                    $indexViewArray++;
+                    break;
+                case "wfsrequest":
+                    $resourcesArray[$indexResourceArray]->name = "INSPIRE ATOM Feed Viewer";//: ".$metadataObject->title;
+                    $resourcesArray[$indexResourceArray]->id = $option->serviceUuid;
+                    $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";
+                    $indexResourceArray++;
+                    //views to generate
+                    //build whole json structure
+                    $viewJson->resource_id = $option->serviceUuid;
+                    //$viewJson->id = $option->serviceUuid."_view";
+                    $viewJson->title = "INSPIRE ATOM Feed Viewer";
+                    $viewJson->description = "Integrierter INSPIRE ATOM Feed Viewer wfs ... description";
+                    $viewJson->view_type = "webpage_view";
+                    $viewArray[$indexViewArray]['json'] = json_encode($viewJson);
+                    $indexViewArray++;
+                    break;
+                case "downloadlink":
+                    $resourcesArray[$indexResourceArray]->name = "INSPIRE ATOM Feed Viewer";//: ".$metadataObject->title;
+                    $resourcesArray[$indexResourceArray]->id = $metadataObject->uuid."_downloadlink"; //TODO - no uuid for service known in this case
+                    $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";
+                    $indexResourceArray++;
+                    //views to generate
+                    //build whole json structure
+                    $viewJson->resource_id = $metadataObject->uuid."_downloadlink";
+                    //$viewJson->id = $metadataObject->uuid."_downloadlink"."_view";
+                    $viewJson->title = "INSPIRE ATOM Feed Viewer";
+                    $viewJson->description = "Integrierter INSPIRE ATOM Feed Viewer wfs ... description";
+                    $viewJson->view_type = "webpage_view";
+                    $viewArray[$indexViewArray]['json'] = json_encode($viewJson);
+                    $indexViewArray++;
+                    break;
+                }	
+            }
+        }
+        //$e = new mb_exception($downloadOptionsJson);
+        //TODO - for all coupled wfs interfaces
+        foreach($featuretypeArray as $featuretypeId) {
+        
+        }
+        $ckanPackage->resources = $resourcesArray;
+        //arrays
+        //$ckanPackage->tags = [];
+        $ckanPackage->govdata_categories[] = "geo";
+        //and further categories and keywords
+        $keywordIdArray = array();
+        $topicIdArray = array();
+        //TODO: check if it easier to pull aggregated information from search table! Keywords and categories!
+        //get iso categories and all keywords from metadata and coupled layers / featuretypes
+        //categories
+        if (count($layerArray) > 0) {
+            $sql = "SELECT fkey_md_topic_category_id FROM layer_md_topic_category WHERE (fkey_metadata_id = ".$metadataId." OR fkey_layer_id IN (".implode(",", $layerArray).") ) UNION SELECT fkey_md_topic_category_id FROM mb_metadata_md_topic_category WHERE fkey_metadata_id = ".$metadataId;
+        } else {
+            $sql = "SELECT fkey_md_topic_category_id FROM layer_md_topic_category WHERE (fkey_metadata_id = ".$metadataId.") UNION SELECT fkey_md_topic_category_id FROM mb_metadata_md_topic_category WHERE fkey_metadata_id = ".$metadataId;
+        }
+        $res = db_query($sql);
+        while($row = db_fetch_array($res)){
+            $topicIdArray[] = $row['fkey_md_topic_category_id'];
+        }
+        //push govdata categories into ckan package
+        $numberOfCategories = 0;
+        for ($i=0; $i < count($topicIdArray); $i++){
+            if (array_key_exists((string)$topicIdArray[$i],$topicCkanCategoryMap)) {
+            //check if categories should be exploded
+            //check if one comma is in string
+                if (strpos($topicCkanCategoryMap[$topicIdArray[$i]], ",") !== false) {
+                    $newCategories = explode(",",$topicCkanCategoryMap[$topicIdArray[$i]]);
+                } else {
+                    //single category
+                    $newCategories[0] = $topicCkanCategoryMap[$topicIdArray[$i]];
+                }
+                foreach ($newCategories as $cat) {
+                    //explode categories if 
+                    $categories[$numberOfCategories] = $cat;
+                    $numberOfCategories++;
+                }
+            } else {
+                $e = new mb_notice("classes/class_syncCkan.php: Topic id not found in mapping hash!");
+            }
+        }
+        if (count($categories) > 0) {
+            $categories = array_unique($categories);
+            for ($i=0; $i < count($categories); $i++){
+                if ($categories[$i] !== "geo" && $categories[$i] !== null) {
+                    $ckanPackage->govdata_categories[] = $categories[$i];
+                }
+            }
+        }
+        //keywords / tags	
+        if (count($layerArray) > 0) {
+            $sql = "SELECT fkey_keyword_id FROM layer_keyword WHERE (fkey_layer_id IN (".implode(",", $layerArray).") ) UNION SELECT fkey_keyword_id FROM mb_metadata_keyword WHERE fkey_metadata_id = ".$metadataId;
+        } else {
+            $sql = "SELECT fkey_keyword_id FROM mb_metadata_keyword WHERE fkey_metadata_id = ".$metadataId;
+        }
+        $res = db_query($sql);
+        while($row = db_fetch_array($res)){
+            $keywordIdArray[] = $row['fkey_keyword_id'];
+        }
+        //make array unique
+        $keywordIdArray = array_unique($keywordIdArray);
+        $topicIdArray = array_unique($topicIdArray);
+        //generate tags TODO - check for one single select above!
+        if (count($keywordIdArray) > 0) {
+            $keywordArray = array();
+            $sql = "SELECT keyword FROM keyword WHERE keyword_id in (".implode(",", $keywordIdArray).")";
+            $res = db_query($sql);
+            while($row = db_fetch_array($res)) {
+                //don't allow blanks in keywords!
+                if ($row['keyword'] !== "" && strpos($row['keyword'], " ") === false) {
+                    $keywordArray[] = $row['keyword'];
+                }
+            }
+            for ($i=0; $i < count($keywordArray); $i++) {
+                $ckanPackage->tags[$i]->name = $keywordArray[$i];
+            }
+        }
+        if (count($layerArray) == 0 && count($featuretypeArray) == 0) {
+            return false;
+        }
+        $returnArray = array();
+        $returnArray['json'] = json_encode($ckanPackage);
+        //$e = new mb_exception("json: ".$returnArray['json']);
+        $returnArray['views'] = $viewArray;
+        return $returnArray;
+    }
+     
+    private function recreateResourceViews($ckan, $result, $resultCkanRepresentation) {
+        $returnObject = new stdClass();
+        //delete all existing resource_views an recreate them afterwards
+        $numberOfResources = 0;
+        foreach ($result->result->resources as $resource) {
+            $returnObject->resources[$numberOfResources]->id = $resource->id;
+            $result = $ckan->action_resource_view_list("{\"id\":\"".$resource->id."\"}");
+            if ($result->success == true) {
+                $returnObject->resources[$numberOfResources]->exists = true;
+                //delete each resource view
+                $numberOfViews = 0;
+                $returnObject->resources[$numberOfResources]->has_view = false;
+                foreach ($result->result as $resourceView) {
+                    $returnObject->resources[$numberOfResources]->has_view = true;
+                    $returnObject->resources[$numberOfResources]->resource_view[$numberOfViews]->id = $resourceView->id;
+                    $result = $ckan->action_resource_view_delete("{\"id\":\"".$resourceView->id."\"}");
+                    if ($result->success == true) {
+                        $e = new mb_notice("classes/class_syncCkan.php: view ".$resourceView->id." successfully deleted!");
+                        $returnObject->resources[$numberOfResources]->resource_view[$numberOfViews]->deleted = true;
+                    } else {
+                        $e = new mb_exception("classes/class_syncCkan.php: An error occured while deleting resource_view!");
+                        $returnObject->resources[$numberOfResources]->resource_view[$numberOfViews]->deleted = false;
+                    }
+                    $numberOfViews++;
+                    //$e = new mb_exception("found resource views: ".json_encode($result));
+                }
+            }
+            $numberOfResources++;										
+        }			
+        //create new views	
+        $numberOfViewsToCreate = 0;						
+        foreach ($resultCkanRepresentation['views'] as $resourceView) {
+            $returnObject->resources[$numberOfResources]->createView->resource_view[$numberOfViewsToCreate]->id = $numberOfViewsToCreate;
+            //$e = new mb_exception("try to create view for resource: ".$resourceView['json']);
+            $result = $ckan->action_resource_view_create($resourceView['json']);
+            if ($result->success == true) {
+                $e = new mb_notice("classes/class_syncCkan.php: Resource_view successfully created!");
+                $returnObject->resources[$numberOfResources]->createView->resource_view[$numberOfViewsToCreate]->created = true;
+                $returnObject->resources[$numberOfResources]->createView->resource_view[$numberOfViewsToCreate]->id = $result->result->id;
+            } else {
+                $e = new mb_exception("classes/class_syncCkan.php: An error occured while creating resource_view!");
+                $returnObject->resources[$numberOfResources]->create->resource_view[$numberOfViewsToCreate]->created = false;
+            }
+            $numberOfViewsToCreate++;
+        }
+        return json_encode($returnObject);
+    }
+}
+?>



More information about the Mapbender_commits mailing list