From 6ebfbc59931b6b83411e5c53c235c6017e4e3f99 Mon Sep 17 00:00:00 2001
From: Michael Vogel <icarus@dabo.de>
Date: Fri, 15 Jul 2016 15:37:51 +0200
Subject: [PATCH 1/8] API: Use a generic function to create the XML

---
 include/api.php | 67 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 66 insertions(+), 1 deletion(-)

diff --git a/include/api.php b/include/api.php
index c86a3cbe4b..7a9d91f157 100644
--- a/include/api.php
+++ b/include/api.php
@@ -25,6 +25,7 @@
 	require_once('include/like.php');
 	require_once('include/NotificationsManager.php');
 	require_once('include/plaintext.php');
+	require_once('include/xml.php');
 
 
 	define('API_METHOD_ANY','*');
@@ -286,8 +287,12 @@
 
 					switch($type){
 						case "xml":
-							$r = mb_convert_encoding($r, "UTF-8",mb_detect_encoding($r));
 							header ("Content-Type: text/xml");
+
+							if (substr($r, 0, 5) == "<?xml")
+								return $r;
+
+							$r = mb_convert_encoding($r, "UTF-8",mb_detect_encoding($r));
 							return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$r;
 							break;
 						case "json":
@@ -707,6 +712,63 @@
 		return $res;
 	}
 
+
+	function api_walk_recursive(array &$array, callable $callback) {
+
+		$new_array = array();
+
+		foreach ($array as $k => $v) {
+			if (is_array($v)) {
+				if ($callback($v, $k))
+					$new_array[$k] = api_walk_recursive($v, $callback);
+			} else {
+				if ($callback($v, $k))
+					$new_array[$k] = $v;
+			}
+		}
+		$array = $new_array;
+
+		return $array;
+	}
+
+	function api_reformat_xml(&$item, &$key) {
+		if (is_bool($item))
+			$item = ($item ? "true" : "false");
+
+		if (substr($key, 0, 10) == "statusnet_")
+			$key = "statusnet:".substr($key, 10);
+		elseif (substr($key, 0, 10) == "friendica_")
+			$key = "friendica:".substr($key, 10);
+		elseif (in_array($key, array("like", "dislike", "attendyes", "attendno", "attendmaybe")))
+			$key = "friendica:".$key;
+
+		return ($key != "attachments");
+	}
+
+	function api_create_xml($data, $templatename) {
+		$data2 = array_pop($data);
+		$key = key($data2);
+
+		if (is_array($data2))
+			api_walk_recursive($data2, "api_reformat_xml");
+
+		if ($key == "0") {
+			$data4 = array();
+			$i = 1;
+			foreach ($data2 AS $item)
+				$data4[$i++.":status"] = $item;
+			$data3 = array("statuses" => $data4);
+		} else
+			$data3 = array($templatename => $data2);
+
+		$namespaces = array("statusnet" => "http://status.net/schema/api/1/",
+					"friendica" => "http://friendi.ca/schema/api/1/");
+
+		$ret = xml::from_array($data3, $xml, false, $namespaces);
+
+		return $ret;
+	}
+
 	/**
 	 *  load api $templatename for $type and replace $data array
 	 */
@@ -718,6 +780,9 @@
 			case "atom":
 			case "rss":
 			case "xml":
+				//$ret = api_create_xml($data, $templatename);
+				//break;
+
 				$data = array_xmlify($data);
 				if ($templatename==="<auto>") {
 					$ret = api_array_to_xml($data); 

From bc2c565060086db1ed4e8b26841a916b7843cffa Mon Sep 17 00:00:00 2001
From: Michael Vogel <icarus@dabo.de>
Date: Sat, 16 Jul 2016 12:32:08 +0200
Subject: [PATCH 2/8] Work in progress: API XML output without templates

---
 include/api.php | 164 ++++++++++++++++++------------------------------
 include/xml.php |   7 ++-
 2 files changed, 65 insertions(+), 106 deletions(-)

diff --git a/include/api.php b/include/api.php
index 3f6216c173..9b1d198351 100644
--- a/include/api.php
+++ b/include/api.php
@@ -257,7 +257,6 @@
 		if (strpos($a->query_string, ".json")>0) $type="json";
 		if (strpos($a->query_string, ".rss")>0) $type="rss";
 		if (strpos($a->query_string, ".atom")>0) $type="atom";
-		if (strpos($a->query_string, ".as")>0) $type="as";
 		try {
 			foreach ($API as $p=>$info){
 				if (strpos($a->query_string, $p)===0){
@@ -311,12 +310,6 @@
 							header ("Content-Type: application/atom+xml");
 							return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$r;
 							break;
-						case "as":
-							//header ("Content-Type: application/json");
-							//foreach($r as $rr)
-							//	return json_encode($rr);
-							return json_encode($r);
-							break;
 
 					}
 				}
@@ -717,6 +710,14 @@
 	}
 
 
+	/**
+	 * @brief walks recursively through an array with the possibility to change value and key
+	 *
+	 * @param array $array The array to walk through
+	 * @param string $callback The callback function
+	 *
+	 * @return array the transformed array
+	 */
 	function api_walk_recursive(array &$array, callable $callback) {
 
 		$new_array = array();
@@ -735,6 +736,14 @@
 		return $array;
 	}
 
+	/**
+	 * @brief Callback function to transform the array in an array that can be transformed in a XML file
+	 *
+	 * @param variant $item Array item value
+	 * @param string $key Array key
+	 *
+	 * @return boolean Should the array item be deleted?
+	 */
 	function api_reformat_xml(&$item, &$key) {
 		if (is_bool($item))
 			$item = ($item ? "true" : "false");
@@ -746,28 +755,60 @@
 		elseif (in_array($key, array("like", "dislike", "attendyes", "attendno", "attendmaybe")))
 			$key = "friendica:".$key;
 
-		return ($key != "attachments");
+		return (!in_array($key, array("attachments", "friendica:activities", "coordinates")));
 	}
 
+	/**
+	 * @brief Creates the XML from a JSON style array
+	 *
+	 * @param array $data JSON style array
+	 * @param string $template Name of the root element
+	 *
+	 * @return boolean string The XML data
+	 */
 	function api_create_xml($data, $templatename) {
+
 		$data2 = array_pop($data);
 		$key = key($data2);
 
+		$namespaces = array("statusnet" => "http://status.net/schema/api/1/",
+					"friendica" => "http://friendi.ca/schema/api/1/");
+
+		if ($templatename == "test") {
+			$namespaces = array();
+			$templatename = "ok";
+		}
+
+		if ($templatename == "ratelimit") {
+			$namespaces = array();
+			$templatename = "hash";
+		}
+
 		if (is_array($data2))
 			api_walk_recursive($data2, "api_reformat_xml");
 
 		if ($key == "0") {
 			$data4 = array();
 			$i = 1;
+
+			if ($templatename == "friends") {
+				$childname = "user";
+				$parentname = "users";
+			} elseif ($templatename == "direct_messages") {
+				$childname = "direct_message";
+				$parentname = "direct-messages";
+			} else {
+				$childname = "status";
+				$parentname = "statuses";
+			}
+
 			foreach ($data2 AS $item)
-				$data4[$i++.":status"] = $item;
-			$data3 = array("statuses" => $data4);
+				$data4[$i++.":".$childname] = $item;
+
+			$data3 = array($parentname => $data4);
 		} else
 			$data3 = array($templatename => $data2);
 
-		$namespaces = array("statusnet" => "http://status.net/schema/api/1/",
-					"friendica" => "http://friendi.ca/schema/api/1/");
-
 		$ret = xml::from_array($data3, $xml, false, $namespaces);
 
 		return $ret;
@@ -784,8 +825,8 @@
 			case "atom":
 			case "rss":
 			case "xml":
-				//$ret = api_create_xml($data, $templatename);
-				//break;
+				$ret = api_create_xml($data, $templatename);
+				break;
 
 				$data = array_xmlify($data);
 				if ($templatename==="<auto>") {
@@ -1415,12 +1456,6 @@
 			case "rss":
 				$data = api_rss_extra($a, $data, $user_info);
 				break;
-			case "as":
-				$as = api_format_as($a, $ret, $user_info);
-				$as['title'] = $a->config['sitename']." Home Timeline";
-				$as['link']['url'] = $a->get_baseurl()."/".$user_info["screen_name"]."/all";
-				return($as);
-				break;
 		}
 
 		return  api_apply_template("timeline", $type, $data);
@@ -1483,12 +1518,6 @@
 			case "rss":
 				$data = api_rss_extra($a, $data, $user_info);
 				break;
-			case "as":
-				$as = api_format_as($a, $ret, $user_info);
-				$as['title'] = $a->config['sitename']." Public Timeline";
-				$as['link']['url'] = $a->get_baseurl()."/";
-				return($as);
-				break;
 		}
 
 		return  api_apply_template("timeline", $type, $data);
@@ -1797,12 +1826,6 @@
 			case "rss":
 				$data = api_rss_extra($a, $data, $user_info);
 				break;
-			case "as":
-				$as = api_format_as($a, $ret, $user_info);
-				$as["title"] = $a->config['sitename']." Mentions";
-				$as['link']['url'] = $a->get_baseurl()."/";
-				return($as);
-				break;
 		}
 
 		return  api_apply_template("timeline", $type, $data);
@@ -1846,12 +1869,12 @@
 			`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
 			`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
 			`contact`.`id` AS `cid`
-			FROM `item`, `contact`
+			FROM `item`
+			INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
+				AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
 			WHERE `item`.`uid` = %d AND `verb` = '%s'
 			AND `item`.`contact-id` = %d
-			AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
-			AND `contact`.`id` = `item`.`contact-id`
-			AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
+			AND `item`.`visible` AND NOT `item`.`moderated` AND NOT `item`.`deleted`
 			$sql_extra
 			AND `item`.`id`>%d
 			ORDER BY `item`.`id` DESC LIMIT %d ,%d ",
@@ -2003,73 +2026,6 @@
 	}
 	api_register_func('api/favorites','api_favorites', true);
 
-
-
-
-	function api_format_as($a, $ret, $user_info) {
-		$as = array();
-		$as['title'] = $a->config['sitename']." Public Timeline";
-		$items = array();
-		foreach ($ret as $item) {
-			$singleitem["actor"]["displayName"] = $item["user"]["name"];
-			$singleitem["actor"]["id"] = $item["user"]["contact_url"];
-			$avatar[0]["url"] = $item["user"]["profile_image_url"];
-			$avatar[0]["rel"] = "avatar";
-			$avatar[0]["type"] = "";
-			$avatar[0]["width"] = 96;
-			$avatar[0]["height"] = 96;
-			$avatar[1]["url"] = $item["user"]["profile_image_url"];
-			$avatar[1]["rel"] = "avatar";
-			$avatar[1]["type"] = "";
-			$avatar[1]["width"] = 48;
-			$avatar[1]["height"] = 48;
-			$avatar[2]["url"] = $item["user"]["profile_image_url"];
-			$avatar[2]["rel"] = "avatar";
-			$avatar[2]["type"] = "";
-			$avatar[2]["width"] = 24;
-			$avatar[2]["height"] = 24;
-			$singleitem["actor"]["avatarLinks"] = $avatar;
-
-			$singleitem["actor"]["image"]["url"] = $item["user"]["profile_image_url"];
-			$singleitem["actor"]["image"]["rel"] = "avatar";
-			$singleitem["actor"]["image"]["type"] = "";
-			$singleitem["actor"]["image"]["width"] = 96;
-			$singleitem["actor"]["image"]["height"] = 96;
-			$singleitem["actor"]["type"] = "person";
-			$singleitem["actor"]["url"] = $item["person"]["contact_url"];
-			$singleitem["actor"]["statusnet:profile_info"]["local_id"] = $item["user"]["id"];
-			$singleitem["actor"]["statusnet:profile_info"]["following"] = $item["user"]["following"] ? "true" : "false";
-			$singleitem["actor"]["statusnet:profile_info"]["blocking"] = "false";
-			$singleitem["actor"]["contact"]["preferredUsername"] = $item["user"]["screen_name"];
-			$singleitem["actor"]["contact"]["displayName"] = $item["user"]["name"];
-			$singleitem["actor"]["contact"]["addresses"] = "";
-
-			$singleitem["body"] = $item["text"];
-			$singleitem["object"]["displayName"] = $item["text"];
-			$singleitem["object"]["id"] = $item["url"];
-			$singleitem["object"]["type"] = "note";
-			$singleitem["object"]["url"] = $item["url"];
-			//$singleitem["context"] =;
-			$singleitem["postedTime"] = date("c", strtotime($item["published"]));
-			$singleitem["provider"]["objectType"] = "service";
-			$singleitem["provider"]["displayName"] = "Test";
-			$singleitem["provider"]["url"] = "http://test.tld";
-			$singleitem["title"] = $item["text"];
-			$singleitem["verb"] = "post";
-			$singleitem["statusnet:notice_info"]["local_id"] = $item["id"];
-			$singleitem["statusnet:notice_info"]["source"] = $item["source"];
-			$singleitem["statusnet:notice_info"]["favorite"] = "false";
-			$singleitem["statusnet:notice_info"]["repeated"] = "false";
-			//$singleitem["original"] = $item;
-			$items[] = $singleitem;
-		}
-		$as['items'] = $items;
-		$as['link']['url'] = $a->get_baseurl()."/".$user_info["screen_name"]."/all";
-		$as['link']['rel'] = "alternate";
-		$as['link']['type'] = "text/html";
-		return($as);
-	}
-
 	function api_format_messages($item, $recipient, $sender) {
 		// standard meta information
 		$ret=Array(
diff --git a/include/xml.php b/include/xml.php
index ed2f49fb7f..f32639e3e4 100644
--- a/include/xml.php
+++ b/include/xml.php
@@ -27,8 +27,11 @@ class xml {
 				foreach ($namespaces AS $nskey => $nsvalue)
 					$key .= " xmlns".($nskey == "" ? "":":").$nskey.'="'.$nsvalue.'"';
 
-				$root = new SimpleXMLElement("<".$key."/>");
-				self::from_array($value, $root, $remove_header, $namespaces, false);
+				if (is_array($value)) {
+					$root = new SimpleXMLElement("<".$key."/>");
+					self::from_array($value, $root, $remove_header, $namespaces, false);
+				} else
+					$root = new SimpleXMLElement("<".$key.">".xmlify($value)."</".$key.">");
 
 				$dom = dom_import_simplexml($root)->ownerDocument;
 				$dom->formatOutput = true;

From d7f093cb2e45c81b9501220520634605ccab3526 Mon Sep 17 00:00:00 2001
From: Michael Vogel <icarus@dabo.de>
Date: Sun, 17 Jul 2016 19:42:30 +0200
Subject: [PATCH 3/8] Enhanced XML creation, and so on.

---
 include/api.php | 203 ++++++++++++++++++++++--------------------------
 include/xml.php |  11 ++-
 2 files changed, 103 insertions(+), 111 deletions(-)

diff --git a/include/api.php b/include/api.php
index 9b1d198351..ddc5813d50 100644
--- a/include/api.php
+++ b/include/api.php
@@ -766,23 +766,18 @@
 	 *
 	 * @return boolean string The XML data
 	 */
-	function api_create_xml($data, $templatename) {
+	function api_create_xml($data, $root_element) {
 
+		$childname = key($data);
 		$data2 = array_pop($data);
 		$key = key($data2);
 
 		$namespaces = array("statusnet" => "http://status.net/schema/api/1/",
 					"friendica" => "http://friendi.ca/schema/api/1/");
 
-		if ($templatename == "test") {
+		/// @todo Auto detection of needed namespaces
+		if (in_array($root_element, array("ok", "hash", "config", "version", "ids", "notes", "photos")))
 			$namespaces = array();
-			$templatename = "ok";
-		}
-
-		if ($templatename == "ratelimit") {
-			$namespaces = array();
-			$templatename = "hash";
-		}
 
 		if (is_array($data2))
 			api_walk_recursive($data2, "api_reformat_xml");
@@ -791,26 +786,14 @@
 			$data4 = array();
 			$i = 1;
 
-			if ($templatename == "friends") {
-				$childname = "user";
-				$parentname = "users";
-			} elseif ($templatename == "direct_messages") {
-				$childname = "direct_message";
-				$parentname = "direct-messages";
-			} else {
-				$childname = "status";
-				$parentname = "statuses";
-			}
-
 			foreach ($data2 AS $item)
 				$data4[$i++.":".$childname] = $item;
 
-			$data3 = array($parentname => $data4);
-		} else
-			$data3 = array($templatename => $data2);
+			$data2 = $data4;
+		}
 
+		$data3 = array($root_element => $data2);
 		$ret = xml::from_array($data3, $xml, false, $namespaces);
-
 		return $ret;
 	}
 
@@ -887,7 +870,7 @@
 		unset($user_info["uid"]);
 		unset($user_info["self"]);
 
-		return api_apply_template("user", $type, array('$user' => $user_info));
+		return api_apply_template("user", $type, array('user' => $user_info));
 
 	}
 	api_register_func('api/account/verify_credentials','api_account_verify_credentials', true);
@@ -1244,7 +1227,7 @@
 		if ($type == "raw")
 			return($status_info);
 
-		return  api_apply_template("status", $type, array('$status' => $status_info));
+		return  api_apply_template("statuses", $type, array('status' => $status_info));
 
 	}
 
@@ -1341,7 +1324,7 @@
 		unset($user_info["uid"]);
 		unset($user_info["self"]);
 
-		return  api_apply_template("user", $type, array('$user' => $user_info));
+		return  api_apply_template("user", $type, array('user' => $user_info));
 
 	}
 	api_register_func('api/users/show','api_users_show');
@@ -1361,7 +1344,7 @@
 				foreach ($r AS $user) {
 					$user_info = api_get_user($a, $user["id"]);
 					//echo print_r($user_info, true)."\n";
-					$userdata = api_apply_template("user", $type, array('user' => $user_info));
+					$userdata = api_apply_template("user", $type, array('users' => $user_info));
 					$userlist[] = $userdata["user"];
 				}
 				$userlist = array("users" => $userlist);
@@ -1450,7 +1433,7 @@
 				$r = q("UPDATE `item` SET `unseen` = 0 WHERE `unseen` AND `id` IN (%s)", $idlist);
 		}
 
-		$data = array('$statuses' => $ret);
+		$data = array('status' => $ret);
 		switch($type){
 			case "atom":
 			case "rss":
@@ -1458,7 +1441,7 @@
 				break;
 		}
 
-		return  api_apply_template("timeline", $type, $data);
+		return  api_apply_template("statuses", $type, $data);
 	}
 	api_register_func('api/statuses/home_timeline','api_statuses_home_timeline', true);
 	api_register_func('api/statuses/friends_timeline','api_statuses_home_timeline', true);
@@ -1512,7 +1495,7 @@
 		$ret = api_format_items($r,$user_info);
 
 
-		$data = array('$statuses' => $ret);
+		$data = array('status' => $ret);
 		switch($type){
 			case "atom":
 			case "rss":
@@ -1520,7 +1503,7 @@
 				break;
 		}
 
-		return  api_apply_template("timeline", $type, $data);
+		return  api_apply_template("statuses", $type, $data);
 	}
 	api_register_func('api/statuses/public_timeline','api_statuses_public_timeline', true);
 
@@ -1573,15 +1556,10 @@
 		$ret = api_format_items($r,$user_info);
 
 		if ($conversation) {
-			$data = array('$statuses' => $ret);
-			return api_apply_template("timeline", $type, $data);
+			$data = array('status' => $ret);
+			return api_apply_template("statuses", $type, $data);
 		} else {
-			$data = array('$status' => $ret[0]);
-			/*switch($type){
-				case "atom":
-				case "rss":
-					$data = api_rss_extra($a, $data, $user_info);
-			}*/
+			$data = array('status' => $ret[0]);
 			return  api_apply_template("status", $type, $data);
 		}
 	}
@@ -1652,8 +1630,8 @@
 
 		$ret = api_format_items($r,$user_info);
 
-		$data = array('$statuses' => $ret);
-		return api_apply_template("timeline", $type, $data);
+		$data = array('status' => $ret);
+		return api_apply_template("statuses", $type, $data);
 	}
 	api_register_func('api/conversation/show','api_conversation_show', true);
 	api_register_func('api/statusnet/conversation','api_conversation_show', true);
@@ -1820,7 +1798,7 @@
 		$ret = api_format_items($r,$user_info);
 
 
-		$data = array('$statuses' => $ret);
+		$data = array('status' => $ret);
 		switch($type){
 			case "atom":
 			case "rss":
@@ -1828,7 +1806,7 @@
 				break;
 		}
 
-		return  api_apply_template("timeline", $type, $data);
+		return  api_apply_template("statuses", $type, $data);
 	}
 	api_register_func('api/statuses/mentions','api_statuses_mentions', true);
 	api_register_func('api/statuses/replies','api_statuses_mentions', true);
@@ -1887,14 +1865,14 @@
 
 		$ret = api_format_items($r,$user_info, true);
 
-		$data = array('$statuses' => $ret);
+		$data = array('status' => $ret);
 		switch($type){
 			case "atom":
 			case "rss":
 				$data = api_rss_extra($a, $data, $user_info);
 		}
 
-		return  api_apply_template("timeline", $type, $data);
+		return  api_apply_template("statuses", $type, $data);
 	}
 	api_register_func('api/statuses/user_timeline','api_statuses_user_timeline', true);
 
@@ -1951,7 +1929,7 @@
 		$rets = api_format_items($item,$user_info);
 		$ret = $rets[0];
 
-		$data = array('$status' => $ret);
+		$data = array('status' => $ret);
 		switch($type){
 			case "atom":
 			case "rss":
@@ -2015,14 +1993,14 @@
 
 		}
 
-		$data = array('$statuses' => $ret);
+		$data = array('status' => $ret);
 		switch($type){
 			case "atom":
 			case "rss":
 				$data = api_rss_extra($a, $data, $user_info);
 		}
 
-		return  api_apply_template("timeline", $type, $data);
+		return  api_apply_template("statuses", $type, $data);
 	}
 	api_register_func('api/favorites','api_favorites', true);
 
@@ -2510,16 +2488,27 @@
 
 
 	function api_account_rate_limit_status(&$a,$type) {
-		$hash = array(
-			  'reset_time_in_seconds' => strtotime('now + 1 hour'),
-			  'remaining_hits' => (string) 150,
-			  'hourly_limit' => (string) 150,
-			  'reset_time' => api_date(datetime_convert('UTC','UTC','now + 1 hour',ATOM_TIME)),
-		);
-		if ($type == "xml")
-			$hash['resettime_in_seconds'] = $hash['reset_time_in_seconds'];
 
-		return api_apply_template('ratelimit', $type, array('$hash' => $hash));
+		if ($type == "json")
+			$hash = array(
+					'reset_time_in_seconds' => strtotime('now + 1 hour'),
+					'remaining_hits' => (string) 150,
+					'hourly_limit' => (string) 150,
+					'reset_time' => api_date(datetime_convert('UTC','UTC','now + 1 hour',ATOM_TIME)),
+				);
+		else
+			$hash = array(
+					'remaining-hits' => (string) 150,
+					'@attributes' => array("type" => "integer"),
+					'hourly-limit' => (string) 150,
+					'@attributes2' => array("type" => "integer"),
+					'reset-time' => datetime_convert('UTC','UTC','now + 1 hour',ATOM_TIME),
+					'@attributes3' => array("type" => "datetime"),
+					'reset_time_in_seconds' => strtotime('now + 1 hour'),
+					'@attributes4' => array("type" => "integer"),
+				);
+
+		return api_apply_template('hash', $type, array('hash' => $hash));
 	}
 	api_register_func('api/account/rate_limit_status','api_account_rate_limit_status',true);
 
@@ -2529,19 +2518,19 @@
 		else
 			$ok = "ok";
 
-		return api_apply_template('test', $type, array("$ok" => $ok));
+		return api_apply_template('ok', $type, array("ok" => $ok));
 	}
 	api_register_func('api/help/test','api_help_test',false);
 
 	function api_lists(&$a,$type) {
 		$ret = array();
-		return array($ret);
+		return api_apply_template('lists', $type, array("lists_list" => $ret));
 	}
 	api_register_func('api/lists','api_lists',true);
 
 	function api_lists_list(&$a,$type) {
 		$ret = array();
-		return array($ret);
+		return api_apply_template('lists', $type, array("lists_list" => $ret));
 	}
 	api_register_func('api/lists/list','api_lists_list',true);
 
@@ -2589,18 +2578,18 @@
 				$ret[] = $user;
 		}
 
-		return array('$users' => $ret);
+		return array('user' => $ret);
 
 	}
 	function api_statuses_friends(&$a, $type){
 		$data =  api_statuses_f($a,$type,"friends");
 		if ($data===false) return false;
-		return  api_apply_template("friends", $type, $data);
+		return  api_apply_template("users", $type, $data);
 	}
 	function api_statuses_followers(&$a, $type){
 		$data = api_statuses_f($a,$type,"followers");
 		if ($data===false) return false;
-		return  api_apply_template("friends", $type, $data);
+		return  api_apply_template("users", $type, $data);
 	}
 	api_register_func('api/statuses/friends','api_statuses_friends',true);
 	api_register_func('api/statuses/followers','api_statuses_followers',true);
@@ -2638,7 +2627,7 @@
 			),
 		);
 
-		return api_apply_template('config', $type, array('$config' => $config));
+		return api_apply_template('config', $type, array('config' => $config));
 
 	}
 	api_register_func('api/statusnet/config','api_statusnet_config',false);
@@ -2647,16 +2636,7 @@
 		// liar
 		$fake_statusnet_version = "0.9.7";
 
-		if($type === 'xml') {
-			header("Content-type: application/xml");
-			echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n" . '<version>'.$fake_statusnet_version.'</version>' . "\r\n";
-			killme();
-		}
-		elseif($type === 'json') {
-			header("Content-type: application/json");
-			echo '"'.$fake_statusnet_version.'"';
-			killme();
-		}
+		return api_apply_template('version', $type, array('version' => $fake_statusnet_version));
 	}
 	api_register_func('api/statusnet/version','api_statusnet_version',false);
 
@@ -2682,36 +2662,24 @@
 			intval(api_user())
 		);
 
-		if(is_array($r)) {
+		if(!dbm::is_result($r))
+			return;
 
-			if($type === 'xml') {
-				header("Content-type: application/xml");
-				echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n" . '<ids>' . "\r\n";
-				foreach($r as $rr)
-					echo '<id>' . $rr['id'] . '</id>' . "\r\n";
-				echo '</ids>' . "\r\n";
-				killme();
-			}
-			elseif($type === 'json') {
-				$ret = array();
-				header("Content-type: application/json");
-				foreach($r as $rr)
-					if ($stringify_ids)
-						$ret[] = $rr['id'];
-					else
-						$ret[] = intval($rr['id']);
+		$ids = array();
+		foreach($r as $rr)
+			if ($stringify_ids)
+				$ids[] = $rr['id'];
+			else
+				$ids[] = intval($rr['id']);
 
-				echo json_encode($ret);
-				killme();
-			}
-		}
+		return api_apply_template("ids", $type, array('id' => $ids));
 	}
 
 	function api_friends_ids(&$a,$type) {
-		api_ff_ids($a,$type,'friends');
+		return api_ff_ids($a,$type,'friends');
 	}
 	function api_followers_ids(&$a,$type) {
-		api_ff_ids($a,$type,'followers');
+		return api_ff_ids($a,$type,'followers');
 	}
 	api_register_func('api/friends/ids','api_friends_ids',true);
 	api_register_func('api/followers/ids','api_followers_ids',true);
@@ -2764,7 +2732,7 @@
 			$ret = array("error"=>$id);
 		}
 
-		$data = Array('$messages'=>$ret);
+		$data = Array('direct_message'=>$ret);
 
 		switch($type){
 			case "atom":
@@ -2772,7 +2740,7 @@
 				$data = api_rss_extra($a, $data, $user_info);
 		}
 
-		return  api_apply_template("direct_messages", $type, $data);
+		return  api_apply_template("direct-messages", $type, $data);
 
 	}
 	api_register_func('api/direct_messages/new','api_direct_messages_new',true, API_METHOD_POST);
@@ -2852,14 +2820,14 @@
 		}
 
 
-		$data = array('$messages' => $ret);
+		$data = array('direct_message' => $ret);
 		switch($type){
 			case "atom":
 			case "rss":
 				$data = api_rss_extra($a, $data, $user_info);
 		}
 
-		return  api_apply_template("direct_messages", $type, $data);
+		return  api_apply_template("direct-messages", $type, $data);
 
 	}
 
@@ -2918,7 +2886,7 @@
 		'image/png' => 'png',
 		'image/gif' => 'gif'
 		);
-		$data = array('photos'=>array());
+		$data = array('photo'=>array());
 		if($r) {
 			foreach($r as $rr) {
 				$photo = array();
@@ -2926,11 +2894,17 @@
 				$photo['album'] = $rr['album'];
 				$photo['filename'] = $rr['filename'];
 				$photo['type'] = $rr['type'];
-				$photo['thumb'] = $a->get_baseurl()."/photo/".$rr['resource-id']."-".$rr['scale'].".".$typetoext[$rr['type']];
-				$data['photos'][] = $photo;
+				$thumb = $a->get_baseurl()."/photo/".$rr['resource-id']."-".$rr['scale'].".".$typetoext[$rr['type']];
+
+				if ($type == "json") {
+					$photo['thumb'] = $thumb;
+					$data['photo'][] = $photo;
+				} else {
+					$data['photo'][] = array("@attributes" => $photo, "1" => $thumb);
+				}
 			}
 		}
-		return  api_apply_template("photos_list", $type, $data);
+		return  api_apply_template("photos", $type, $data);
 	}
 
 	function api_fr_photo_detail(&$a,$type) {
@@ -3323,7 +3297,7 @@
 			}
 			$grps[] = array('name' => $rr['name'], 'gid' => $rr['id'], 'user' => $users);
 		}
-		return api_apply_template("group_show", $type, array('$groups' => $grps));
+		return api_apply_template("group_show", $type, array('groups' => $grps));
 	}
 	api_register_func('api/friendica/group_show', 'api_friendica_group_show', true);
 
@@ -3364,7 +3338,7 @@
 		if ($ret) {
 			// return success
 			$success = array('success' => $ret, 'gid' => $gid, 'name' => $name, 'status' => 'deleted', 'wrong users' => array());
-			return api_apply_template("group_delete", $type, array('$result' => $success));
+			return api_apply_template("group_delete", $type, array('result' => $success));
 		}
 		else
 			throw new BadRequestException('other API error');
@@ -3536,7 +3510,16 @@
 		$nm = new NotificationsManager();
 
 		$notes = $nm->getAll(array(), "+seen -date", 50);
-		return api_apply_template("<auto>", $type, array('$notes' => $notes));
+
+		if ($type == "xml") {
+			$xmlnotes = array();
+			foreach ($notes AS $note)
+				$xmlnotes[] = array("@attributes" => $note);
+
+			$notes = $xmlnotes;
+		}
+
+		return api_apply_template("notes", $type, array('note' => $notes));
 	}
 
 	/**
@@ -3569,7 +3552,7 @@
 				// we found the item, return it to the user
 				$user_info = api_get_user($a);
 				$ret = api_format_items($r,$user_info);
-				$data = array('$statuses' => $ret);
+				$data = array('statuses' => $ret);
 				return api_apply_template("timeline", $type, $data);
 			}
 			// the item can't be found, but we set the note as seen, so we count this as a success
diff --git a/include/xml.php b/include/xml.php
index f32639e3e4..133c2b319a 100644
--- a/include/xml.php
+++ b/include/xml.php
@@ -47,6 +47,15 @@ class xml {
 		}
 
 		foreach($array as $key => $value) {
+			if (!isset($element) AND isset($xml))
+				$element = $xml;
+
+			if (is_integer($key)) {
+				if (isset($element))
+					$element[0] = $value;
+				continue;
+			}
+
 			if (substr($key, 0, 11) == "@attributes") {
 				if (!isset($element) OR !is_array($value))
 					continue;
@@ -58,7 +67,7 @@ class xml {
 					else
 						$namespace = NULL;
 
-					$element->addAttribute ($attr_key, $attr_value, $namespace);
+					$element->addAttribute($attr_key, $attr_value, $namespace);
 				}
 
 				continue;

From 838f97671541fc0e3c570f94f8392d618e92e485 Mon Sep 17 00:00:00 2001
From: Michael Vogel <icarus@dabo.de>
Date: Sun, 17 Jul 2016 23:59:35 +0200
Subject: [PATCH 4/8] Some more improvements to xml.php, code cleanup

---
 include/api.php                      | 308 ++++++++++++++-------------
 include/xml.php                      |   4 +
 view/templates/api_timeline_atom.tpl |  91 --------
 3 files changed, 161 insertions(+), 242 deletions(-)
 delete mode 100644 view/templates/api_timeline_atom.tpl

diff --git a/include/api.php b/include/api.php
index ddc5813d50..4796228f9d 100644
--- a/include/api.php
+++ b/include/api.php
@@ -287,12 +287,7 @@
 					switch($type){
 						case "xml":
 							header ("Content-Type: text/xml");
-
-							if (substr($r, 0, 5) == "<?xml")
-								return $r;
-
-							$r = mb_convert_encoding($r, "UTF-8",mb_detect_encoding($r));
-							return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$r;
+							return $r;
 							break;
 						case "json":
 							header ("Content-Type: application/json");
@@ -332,27 +327,29 @@
 	function api_error(&$a, $type, $e) {
 		$error = ($e->getMessage()!==""?$e->getMessage():$e->httpdesc);
 		# TODO:  https://dev.twitter.com/overview/api/response-codes
-		$xmlstr = "<status><error>{$error}</error><code>{$e->httpcode} {$e->httpdesc}</code><request>{$a->query_string}</request></status>";
+
+		$error = array("error" => $error,
+				"code" => $e->httpcode." ".$e->httpdesc,
+				"request" => $a->query_string);
+
+		$ret = api_format_data('status', $type, array('status' => $error));
+
 		switch($type){
 			case "xml":
 				header ("Content-Type: text/xml");
-				return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$xmlstr;
+				return $ret;
 				break;
 			case "json":
 				header ("Content-Type: application/json");
-				return json_encode(array(
-					'error' => $error,
-					'request' => $a->query_string,
-					'code' => $e->httpcode." ".$e->httpdesc
-				));
+				return json_encode($ret);
 				break;
 			case "rss":
 				header ("Content-Type: application/rss+xml");
-				return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$xmlstr;
+				return $ret;
 				break;
 			case "atom":
 				header ("Content-Type: application/atom+xml");
-				return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$xmlstr;
+				return $ret;
 				break;
 		}
 	}
@@ -679,37 +676,6 @@
 		return (array($status_user, $owner_user));
 	}
 
-
-	/**
-	 * @brief transform $data array in xml without a template
-	 *
-	 * @param array $data
-	 * @return string xml string
-	 */
-	function api_array_to_xml($data, $ename="") {
-		$attrs="";
-		$childs="";
-		if (count($data)==1 && !is_array($data[array_keys($data)[0]])) {
-			$ename = array_keys($data)[0];
-			$ename = trim($ename,'$');
-			$v = $data[$ename];
-			return "<$ename>$v</$ename>";
-		}
-		foreach($data as $k=>$v) {
-			$k=trim($k,'$');
-			if (!is_array($v)) {
-				$attrs .= sprintf('%s="%s" ', $k, $v);
-			} else {
-				if (is_numeric($k)) $k=trim($ename,'s');
-				$childs.=api_array_to_xml($v, $k);
-			}
-		}
-		$res = $childs;
-		if ($ename!="") $res = "<$ename $attrs>$res</$ename>";
-		return $res;
-	}
-
-
 	/**
 	 * @brief walks recursively through an array with the possibility to change value and key
 	 *
@@ -752,28 +718,29 @@
 			$key = "statusnet:".substr($key, 10);
 		elseif (substr($key, 0, 10) == "friendica_")
 			$key = "friendica:".substr($key, 10);
-		elseif (in_array($key, array("like", "dislike", "attendyes", "attendno", "attendmaybe")))
-			$key = "friendica:".$key;
+		//else
+		//	$key = "default:".$key;
 
-		return (!in_array($key, array("attachments", "friendica:activities", "coordinates")));
+		return true;
 	}
 
 	/**
 	 * @brief Creates the XML from a JSON style array
 	 *
 	 * @param array $data JSON style array
-	 * @param string $template Name of the root element
+	 * @param string $root_element Name of the root element
 	 *
-	 * @return boolean string The XML data
+	 * @return string The XML data
 	 */
 	function api_create_xml($data, $root_element) {
-
 		$childname = key($data);
 		$data2 = array_pop($data);
 		$key = key($data2);
 
-		$namespaces = array("statusnet" => "http://status.net/schema/api/1/",
-					"friendica" => "http://friendi.ca/schema/api/1/");
+		$namespaces = array("" => "http://api.twitter.com",
+					"statusnet" => "http://status.net/schema/api/1/",
+					"friendica" => "http://friendi.ca/schema/api/1/",
+					"georss" => "http://www.georss.org/georss");
 
 		/// @todo Auto detection of needed namespaces
 		if (in_array($root_element, array("ok", "hash", "config", "version", "ids", "notes", "photos")))
@@ -798,9 +765,15 @@
 	}
 
 	/**
-	 *  load api $templatename for $type and replace $data array
+	 * @brief Formats the data according to the data type
+	 *
+	 * @param string $root_element Name of the root element
+	 * @param string $type Return type (atom, rss, xml, json)
+	 * @param array $data JSON style array
+	 *
+	 * @return (string|object) XML data or JSON data
 	 */
-	function api_apply_template($templatename, $type, $data){
+	function api_format_data($root_element, $type, $data){
 
 		$a = get_app();
 
@@ -808,21 +781,7 @@
 			case "atom":
 			case "rss":
 			case "xml":
-				$ret = api_create_xml($data, $templatename);
-				break;
-
-				$data = array_xmlify($data);
-				if ($templatename==="<auto>") {
-					$ret = api_array_to_xml($data);
-				} else {
-					$tpl = get_markup_template("api_".$templatename."_".$type.".tpl");
-					if(! $tpl) {
-						header ("Content-Type: text/xml");
-						echo '<?xml version="1.0" encoding="UTF-8"?>'."\n".'<status><error>not implemented</error></status>';
-						killme();
-					}
-					$ret = replace_macros($tpl, $data);
-				}
+				$ret = api_create_xml($data, $root_element);
 				break;
 			case "json":
 				$ret = $data;
@@ -870,7 +829,7 @@
 		unset($user_info["uid"]);
 		unset($user_info["self"]);
 
-		return api_apply_template("user", $type, array('user' => $user_info));
+		return api_format_data("user", $type, array('user' => $user_info));
 
 	}
 	api_register_func('api/account/verify_credentials','api_account_verify_credentials', true);
@@ -1178,6 +1137,11 @@
 
 			$converted = api_convert_item($lastwall);
 
+			if ($type == "xml")
+				$geo = "georss:point";
+			else
+				$geo = "geo";
+
 			$status_info = array(
 				'created_at' => api_date($lastwall['created']),
 				'id' => intval($lastwall['id']),
@@ -1191,7 +1155,7 @@
 				'in_reply_to_user_id_str' => $in_reply_to_user_id_str,
 				'in_reply_to_screen_name' => $in_reply_to_screen_name,
 				'user' => $user_info,
-				'geo' => NULL,
+				$geo => NULL,
 				'coordinates' => "",
 				'place' => "",
 				'contributors' => "",
@@ -1227,7 +1191,7 @@
 		if ($type == "raw")
 			return($status_info);
 
-		return  api_apply_template("statuses", $type, array('status' => $status_info));
+		return  api_format_data("statuses", $type, array('status' => $status_info));
 
 	}
 
@@ -1289,6 +1253,11 @@
 
 			$converted = api_convert_item($lastwall);
 
+			if ($type == "xml")
+				$geo = "georss:point";
+			else
+				$geo = "geo";
+
 			$user_info['status'] = array(
 				'text' => $converted["text"],
 				'truncated' => false,
@@ -1301,7 +1270,7 @@
 				'in_reply_to_user_id' => $in_reply_to_user_id,
 				'in_reply_to_user_id_str' => $in_reply_to_user_id_str,
 				'in_reply_to_screen_name' => $in_reply_to_screen_name,
-				'geo' => NULL,
+				$geo => NULL,
 				'favorited' => $lastwall['starred'] ? true : false,
 				'statusnet_html'		=> $converted["html"],
 				'statusnet_conversation_id'	=> $lastwall['parent'],
@@ -1324,7 +1293,7 @@
 		unset($user_info["uid"]);
 		unset($user_info["self"]);
 
-		return  api_apply_template("user", $type, array('user' => $user_info));
+		return  api_format_data("user", $type, array('user' => $user_info));
 
 	}
 	api_register_func('api/users/show','api_users_show');
@@ -1341,11 +1310,14 @@
 				$r = q("SELECT `id` FROM `gcontact` WHERE `nick`='%s'", dbesc($_GET["q"]));
 
 			if (count($r)) {
+				$k = 0;
 				foreach ($r AS $user) {
-					$user_info = api_get_user($a, $user["id"]);
-					//echo print_r($user_info, true)."\n";
-					$userdata = api_apply_template("user", $type, array('users' => $user_info));
-					$userlist[] = $userdata["user"];
+					$user_info = api_get_user($a, $user["id"], "json");
+
+					if ($type == "xml")
+						$userlist[$k++.":user"] = $user_info;
+					else
+						$userlist[] = $user_info;
 				}
 				$userlist = array("users" => $userlist);
 			} else {
@@ -1354,7 +1326,7 @@
 		} else {
 			throw new BadRequestException("User not found.");
 		}
-		return ($userlist);
+		return api_format_data("users", $type, $userlist);
 	}
 
 	api_register_func('api/users/search','api_users_search');
@@ -1417,7 +1389,7 @@
 			intval($start),	intval($count)
 		);
 
-		$ret = api_format_items($r,$user_info);
+		$ret = api_format_items($r,$user_info, false, $type);
 
 		// Set all posts from the query above to seen
 		$idarray = array();
@@ -1441,7 +1413,7 @@
 				break;
 		}
 
-		return  api_apply_template("statuses", $type, $data);
+		return  api_format_data("statuses", $type, $data);
 	}
 	api_register_func('api/statuses/home_timeline','api_statuses_home_timeline', true);
 	api_register_func('api/statuses/friends_timeline','api_statuses_home_timeline', true);
@@ -1492,7 +1464,7 @@
 			intval($start),
 			intval($count));
 
-		$ret = api_format_items($r,$user_info);
+		$ret = api_format_items($r,$user_info, false, $type);
 
 
 		$data = array('status' => $ret);
@@ -1503,7 +1475,7 @@
 				break;
 		}
 
-		return  api_apply_template("statuses", $type, $data);
+		return  api_format_data("statuses", $type, $data);
 	}
 	api_register_func('api/statuses/public_timeline','api_statuses_public_timeline', true);
 
@@ -1553,14 +1525,14 @@
 			throw new BadRequestException("There is no status with this id.");
 		}
 
-		$ret = api_format_items($r,$user_info);
+		$ret = api_format_items($r,$user_info, false, $type);
 
 		if ($conversation) {
 			$data = array('status' => $ret);
-			return api_apply_template("statuses", $type, $data);
+			return api_format_data("statuses", $type, $data);
 		} else {
 			$data = array('status' => $ret[0]);
-			return  api_apply_template("status", $type, $data);
+			return  api_format_data("status", $type, $data);
 		}
 	}
 	api_register_func('api/statuses/show','api_statuses_show', true);
@@ -1628,10 +1600,10 @@
 		if (!$r)
 			throw new BadRequestException("There is no conversation with this id.");
 
-		$ret = api_format_items($r,$user_info);
+		$ret = api_format_items($r,$user_info, false, $type);
 
 		$data = array('status' => $ret);
-		return api_apply_template("statuses", $type, $data);
+		return api_format_data("statuses", $type, $data);
 	}
 	api_register_func('api/conversation/show','api_conversation_show', true);
 	api_register_func('api/statusnet/conversation','api_conversation_show', true);
@@ -1795,7 +1767,7 @@
 			intval($start),	intval($count)
 		);
 
-		$ret = api_format_items($r,$user_info);
+		$ret = api_format_items($r,$user_info, false, $type);
 
 
 		$data = array('status' => $ret);
@@ -1806,7 +1778,7 @@
 				break;
 		}
 
-		return  api_apply_template("statuses", $type, $data);
+		return  api_format_data("statuses", $type, $data);
 	}
 	api_register_func('api/statuses/mentions','api_statuses_mentions', true);
 	api_register_func('api/statuses/replies','api_statuses_mentions', true);
@@ -1863,7 +1835,7 @@
 			intval($start),	intval($count)
 		);
 
-		$ret = api_format_items($r,$user_info, true);
+		$ret = api_format_items($r,$user_info, true, $type);
 
 		$data = array('status' => $ret);
 		switch($type){
@@ -1872,7 +1844,7 @@
 				$data = api_rss_extra($a, $data, $user_info);
 		}
 
-		return  api_apply_template("statuses", $type, $data);
+		return  api_format_data("statuses", $type, $data);
 	}
 	api_register_func('api/statuses/user_timeline','api_statuses_user_timeline', true);
 
@@ -1926,7 +1898,7 @@
 
 
 		$user_info = api_get_user($a);
-		$rets = api_format_items($item,$user_info);
+		$rets = api_format_items($item,$user_info, false, $type);
 		$ret = $rets[0];
 
 		$data = array('status' => $ret);
@@ -1936,7 +1908,7 @@
 				$data = api_rss_extra($a, $data, $user_info);
 		}
 
-		return api_apply_template("status", $type, $data);
+		return api_format_data("status", $type, $data);
 	}
 	api_register_func('api/favorites/create', 'api_favorites_create_destroy', true, API_METHOD_POST);
 	api_register_func('api/favorites/destroy', 'api_favorites_create_destroy', true, API_METHOD_DELETE);
@@ -1989,7 +1961,7 @@
 				intval($start),	intval($count)
 			);
 
-			$ret = api_format_items($r,$user_info);
+			$ret = api_format_items($r,$user_info, false, $type);
 
 		}
 
@@ -2000,7 +1972,7 @@
 				$data = api_rss_extra($a, $data, $user_info);
 		}
 
-		return  api_apply_template("statuses", $type, $data);
+		return  api_format_data("statuses", $type, $data);
 	}
 	api_register_func('api/favorites','api_favorites', true);
 
@@ -2319,7 +2291,7 @@
 	 * 			likes => int count
 	 * 			dislikes => int count
 	 */
-	function api_format_items_activities(&$item) {
+	function api_format_items_activities(&$item, $type = "json") {
 		$activities = array(
 			'like' => array(),
 			'dislike' => array(),
@@ -2335,6 +2307,14 @@
 			builtin_activity_puller($i, $activities);
 		}
 
+		if ($type == "xml") {
+			$xml_activities = array();
+			foreach ($activities as $k => $v)
+				$xml_activities["friendica:".$k] = $v;
+
+			$activities = $xml_activities;
+		}
+
 		$res = array();
 		$uri = $item['uri']."-l";
 		foreach($activities as $k => $v) {
@@ -2351,7 +2331,7 @@
 	 * @param array $user_info
 	 * @param bool $filter_user filter items by $user_info
 	 */
-	function api_format_items($r,$user_info, $filter_user = false) {
+	function api_format_items($r,$user_info, $filter_user = false, $type = "json") {
 
 		$a = get_app();
 		$ret = Array();
@@ -2405,6 +2385,11 @@
 
 			$converted = api_convert_item($item);
 
+			if ($type == "xml")
+				$geo = "georss:point";
+			else
+				$geo = "geo";
+
 			$status = array(
 				'text'		=> $converted["text"],
 				'truncated' => False,
@@ -2417,14 +2402,14 @@
 				'in_reply_to_user_id' => $in_reply_to_user_id,
 				'in_reply_to_user_id_str' => $in_reply_to_user_id_str,
 				'in_reply_to_screen_name' => $in_reply_to_screen_name,
-				'geo' => NULL,
+				$geo => NULL,
 				'favorited' => $item['starred'] ? true : false,
 				'user' =>  $status_user ,
 				'friendica_owner' => $owner_user,
 				//'entities' => NULL,
 				'statusnet_html'		=> $converted["html"],
 				'statusnet_conversation_id'	=> $item['parent'],
-				'friendica_activities' => api_format_items_activities($item),
+				'friendica_activities' => api_format_items_activities($item, $type),
 			);
 
 			if (count($converted["attachments"]) > 0)
@@ -2462,7 +2447,7 @@
 
 					$retweeted_status['text'] = $rt_converted["text"];
 					$retweeted_status['statusnet_html'] = $rt_converted["html"];
-					$retweeted_status['friendica_activities'] = api_format_items_activities($retweeted_item);
+					$retweeted_status['friendica_activities'] = api_format_items_activities($retweeted_item, $type);
 					$retweeted_status['created_at'] =  api_date($retweeted_item['created']);
 					$status['retweeted_status'] = $retweeted_status;
 				}
@@ -2475,12 +2460,14 @@
 			if ($item["coord"] != "") {
 				$coords = explode(' ',$item["coord"]);
 				if (count($coords) == 2) {
-					$status["geo"] = array('type' => 'Point',
-							'coordinates' => array((float) $coords[0],
-										(float) $coords[1]));
+					if ($type == "json")
+						$status["geo"] = array('type' => 'Point',
+								'coordinates' => array((float) $coords[0],
+											(float) $coords[1]));
+					else // Not sure if this is the official format - if someone founds a documentation we can check
+						$status["georss:point"] = $item["coord"];
 				}
 			}
-
 			$ret[] = $status;
 		};
 		return $ret;
@@ -2489,14 +2476,7 @@
 
 	function api_account_rate_limit_status(&$a,$type) {
 
-		if ($type == "json")
-			$hash = array(
-					'reset_time_in_seconds' => strtotime('now + 1 hour'),
-					'remaining_hits' => (string) 150,
-					'hourly_limit' => (string) 150,
-					'reset_time' => api_date(datetime_convert('UTC','UTC','now + 1 hour',ATOM_TIME)),
-				);
-		else
+		if ($type == "xml")
 			$hash = array(
 					'remaining-hits' => (string) 150,
 					'@attributes' => array("type" => "integer"),
@@ -2507,8 +2487,15 @@
 					'reset_time_in_seconds' => strtotime('now + 1 hour'),
 					'@attributes4' => array("type" => "integer"),
 				);
+		else
+			$hash = array(
+					'reset_time_in_seconds' => strtotime('now + 1 hour'),
+					'remaining_hits' => (string) 150,
+					'hourly_limit' => (string) 150,
+					'reset_time' => api_date(datetime_convert('UTC','UTC','now + 1 hour',ATOM_TIME)),
+				);
 
-		return api_apply_template('hash', $type, array('hash' => $hash));
+		return api_format_data('hash', $type, array('hash' => $hash));
 	}
 	api_register_func('api/account/rate_limit_status','api_account_rate_limit_status',true);
 
@@ -2518,19 +2505,19 @@
 		else
 			$ok = "ok";
 
-		return api_apply_template('ok', $type, array("ok" => $ok));
+		return api_format_data('ok', $type, array("ok" => $ok));
 	}
 	api_register_func('api/help/test','api_help_test',false);
 
 	function api_lists(&$a,$type) {
 		$ret = array();
-		return api_apply_template('lists', $type, array("lists_list" => $ret));
+		return api_format_data('lists', $type, array("lists_list" => $ret));
 	}
 	api_register_func('api/lists','api_lists',true);
 
 	function api_lists_list(&$a,$type) {
 		$ret = array();
-		return api_apply_template('lists', $type, array("lists_list" => $ret));
+		return api_format_data('lists', $type, array("lists_list" => $ret));
 	}
 	api_register_func('api/lists/list','api_lists_list',true);
 
@@ -2584,12 +2571,12 @@
 	function api_statuses_friends(&$a, $type){
 		$data =  api_statuses_f($a,$type,"friends");
 		if ($data===false) return false;
-		return  api_apply_template("users", $type, $data);
+		return  api_format_data("users", $type, $data);
 	}
 	function api_statuses_followers(&$a, $type){
 		$data = api_statuses_f($a,$type,"followers");
 		if ($data===false) return false;
-		return  api_apply_template("users", $type, $data);
+		return  api_format_data("users", $type, $data);
 	}
 	api_register_func('api/statuses/friends','api_statuses_friends',true);
 	api_register_func('api/statuses/followers','api_statuses_followers',true);
@@ -2627,7 +2614,7 @@
 			),
 		);
 
-		return api_apply_template('config', $type, array('config' => $config));
+		return api_format_data('config', $type, array('config' => $config));
 
 	}
 	api_register_func('api/statusnet/config','api_statusnet_config',false);
@@ -2636,12 +2623,12 @@
 		// liar
 		$fake_statusnet_version = "0.9.7";
 
-		return api_apply_template('version', $type, array('version' => $fake_statusnet_version));
+		return api_format_data('version', $type, array('version' => $fake_statusnet_version));
 	}
 	api_register_func('api/statusnet/version','api_statusnet_version',false);
 
 	/**
-	 * @todo use api_apply_template() to return data
+	 * @todo use api_format_data() to return data
 	 */
 	function api_ff_ids(&$a,$type,$qtype) {
 		if(! api_user()) throw new ForbiddenException();
@@ -2672,7 +2659,7 @@
 			else
 				$ids[] = intval($rr['id']);
 
-		return api_apply_template("ids", $type, array('id' => $ids));
+		return api_format_data("ids", $type, array('id' => $ids));
 	}
 
 	function api_friends_ids(&$a,$type) {
@@ -2740,7 +2727,7 @@
 				$data = api_rss_extra($a, $data, $user_info);
 		}
 
-		return  api_apply_template("direct-messages", $type, $data);
+		return  api_format_data("direct-messages", $type, $data);
 
 	}
 	api_register_func('api/direct_messages/new','api_direct_messages_new',true, API_METHOD_POST);
@@ -2827,7 +2814,7 @@
 				$data = api_rss_extra($a, $data, $user_info);
 		}
 
-		return  api_apply_template("direct-messages", $type, $data);
+		return  api_format_data("direct-messages", $type, $data);
 
 	}
 
@@ -2896,15 +2883,15 @@
 				$photo['type'] = $rr['type'];
 				$thumb = $a->get_baseurl()."/photo/".$rr['resource-id']."-".$rr['scale'].".".$typetoext[$rr['type']];
 
-				if ($type == "json") {
+				if ($type == "xml")
+					$data['photo'][] = array("@attributes" => $photo, "1" => $thumb);
+				else {
 					$photo['thumb'] = $thumb;
 					$data['photo'][] = $photo;
-				} else {
-					$data['photo'][] = array("@attributes" => $photo, "1" => $thumb);
 				}
 			}
 		}
-		return  api_apply_template("photos", $type, $data);
+		return  api_format_data("photos", $type, $data);
 	}
 
 	function api_fr_photo_detail(&$a,$type) {
@@ -2932,16 +2919,24 @@
 
 		if ($r) {
 			$data = array('photo' => $r[0]);
+			$data['photo']['id'] = $data['photo']['resource-id'];
 			if ($scale !== false) {
 				$data['photo']['data'] = base64_encode($data['photo']['data']);
 			} else {
 				unset($data['photo']['datasize']); //needed only with scale param
 			}
-			$data['photo']['link'] = array();
-			for($k=intval($data['photo']['minscale']); $k<=intval($data['photo']['maxscale']); $k++) {
-				$data['photo']['link'][$k] = $a->get_baseurl()."/photo/".$data['photo']['resource-id']."-".$k.".".$typetoext[$data['photo']['type']];
+			if ($type == "xml") {
+				$data['photo']['links'] = array();
+				for ($k=intval($data['photo']['minscale']); $k<=intval($data['photo']['maxscale']); $k++)
+					$data['photo']['links'][$k.":link"]["@attributes"] = array("type" => $data['photo']['type'],
+											"scale" => $k,
+											"href" => $a->get_baseurl()."/photo/".$data['photo']['resource-id']."-".$k.".".$typetoext[$data['photo']['type']]);
+			} else {
+				$data['photo']['link'] = array();
+				for ($k=intval($data['photo']['minscale']); $k<=intval($data['photo']['maxscale']); $k++) {
+					$data['photo']['link'][$k] = $a->get_baseurl()."/photo/".$data['photo']['resource-id']."-".$k.".".$typetoext[$data['photo']['type']];
+				}
 			}
-			$data['photo']['id'] = $data['photo']['resource-id'];
 			unset($data['photo']['resource-id']);
 			unset($data['photo']['minscale']);
 			unset($data['photo']['maxscale']);
@@ -2950,7 +2945,7 @@
 			throw new NotFoundException();
 		}
 
-		return api_apply_template("photo_detail", $type, $data);
+		return api_format_data("photo_detail", $type, $data);
 	}
 
 	api_register_func('api/friendica/photos/list', 'api_fr_photos_list', true);
@@ -3291,13 +3286,24 @@
 		foreach ($r as $rr) {
 			$members = group_get_members($rr['id']);
 			$users = array();
-			foreach ($members as $member) {
-				$user = api_get_user($a, $member['nurl']);
-				$users[] = $user;
+
+			if ($type == "xml") {
+				$user_element = "users";
+				$k = 0;
+				foreach ($members as $member) {
+					$user = api_get_user($a, $member['nurl']);
+					$users[$k++.":user"] = $user;
+				}
+			} else {
+				$user_element = "user";
+				foreach ($members as $member) {
+					$user = api_get_user($a, $member['nurl']);
+					$users[] = $user;
+				}
 			}
-			$grps[] = array('name' => $rr['name'], 'gid' => $rr['id'], 'user' => $users);
+			$grps[] = array('name' => $rr['name'], 'gid' => $rr['id'], $user_element => $users);
 		}
-		return api_apply_template("group_show", $type, array('groups' => $grps));
+		return api_format_data("groups", $type, array('group' => $grps));
 	}
 	api_register_func('api/friendica/group_show', 'api_friendica_group_show', true);
 
@@ -3338,7 +3344,7 @@
 		if ($ret) {
 			// return success
 			$success = array('success' => $ret, 'gid' => $gid, 'name' => $name, 'status' => 'deleted', 'wrong users' => array());
-			return api_apply_template("group_delete", $type, array('result' => $success));
+			return api_format_data("group_delete", $type, array('result' => $success));
 		}
 		else
 			throw new BadRequestException('other API error');
@@ -3404,7 +3410,7 @@
 		// return success message incl. missing users in array
 		$status = ($erroraddinguser ? "missing user" : ($reactivate_group ? "reactivated" : "ok"));
 		$success = array('success' => true, 'gid' => $gid, 'name' => $name, 'status' => $status, 'wrong users' => $errorusers);
-		return api_apply_template("group_create", $type, array('result' => $success));
+		return api_format_data("group_create", $type, array('result' => $success));
 	}
 	api_register_func('api/friendica/group_create', 'api_friendica_group_create', true, API_METHOD_POST);
 
@@ -3461,7 +3467,7 @@
 		// return success message incl. missing users in array
 		$status = ($erroraddinguser ? "missing user" : "ok");
 		$success = array('success' => true, 'gid' => $gid, 'name' => $name, 'status' => $status, 'wrong users' => $errorusers);
-		return api_apply_template("group_update", $type, array('result' => $success));
+		return api_format_data("group_update", $type, array('result' => $success));
 	}
 	api_register_func('api/friendica/group_update', 'api_friendica_group_update', true, API_METHOD_POST);
 
@@ -3476,11 +3482,11 @@
 		$res = do_like($id, $verb);
 
 		if ($res) {
-			if ($type == 'xml')
+			if ($type == "xml")
 				$ok = "true";
 			else
 				$ok = "ok";
-			return api_apply_template('test', $type, array('ok' => $ok));
+			return api_format_data('ok', $type, array('ok' => $ok));
 		} else {
 			throw new BadRequestException('Error adding activity');
 		}
@@ -3519,7 +3525,7 @@
 			$notes = $xmlnotes;
 		}
 
-		return api_apply_template("notes", $type, array('note' => $notes));
+		return api_format_data("notes", $type, array('note' => $notes));
 	}
 
 	/**
@@ -3551,13 +3557,13 @@
 			if ($r!==false) {
 				// we found the item, return it to the user
 				$user_info = api_get_user($a);
-				$ret = api_format_items($r,$user_info);
-				$data = array('statuses' => $ret);
-				return api_apply_template("timeline", $type, $data);
+				$ret = api_format_items($r,$user_info, false, $type);
+				$data = array('status' => $ret);
+				return api_format_data("status", $type, $data);
 			}
 			// the item can't be found, but we set the note as seen, so we count this as a success
 		}
-		return api_apply_template('<auto>', $type, array('status' => "success"));
+		return api_format_data('result', $type, array('result' => "success"));
 	}
 
 	api_register_func('api/friendica/notification/seen', 'api_friendica_notification_seen', true, API_METHOD_POST);
diff --git a/include/xml.php b/include/xml.php
index 133c2b319a..d2a0f7655b 100644
--- a/include/xml.php
+++ b/include/xml.php
@@ -64,6 +64,8 @@ class xml {
 					$element_parts = explode(":", $attr_key);
 					if ((count($element_parts) > 1) AND isset($namespaces[$element_parts[0]]))
 						$namespace = $namespaces[$element_parts[0]];
+					elseif (isset($namespaces[""]))
+						$namespace = $namespaces[""];
 					else
 						$namespace = NULL;
 
@@ -76,6 +78,8 @@ class xml {
 			$element_parts = explode(":", $key);
 			if ((count($element_parts) > 1) AND isset($namespaces[$element_parts[0]]))
 				$namespace = $namespaces[$element_parts[0]];
+			elseif (isset($namespaces[""]))
+				$namespace = $namespaces[""];
 			else
 				$namespace = NULL;
 
diff --git a/view/templates/api_timeline_atom.tpl b/view/templates/api_timeline_atom.tpl
deleted file mode 100644
index d11b4a3ce3..0000000000
--- a/view/templates/api_timeline_atom.tpl
+++ /dev/null
@@ -1,91 +0,0 @@
-
-<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:georss="http://www.georss.org/georss" xmlns:activity="http://activitystrea.ms/spec/1.0/" xmlns:media="http://purl.org/syndication/atommedia" xmlns:poco="http://portablecontacts.net/spec/1.0" xmlns:ostatus="http://ostatus.org/schema/1.0" xmlns:statusnet="http://status.net/schema/api/1/">
- <generator uri="http://status.net" version="0.9.7">StatusNet</generator>
- <id>{{$rss.self}}</id>
- <title>Friendica</title>
- <subtitle>Friendica API feed</subtitle>
- <logo>{{$rss.logo}}</logo>
- <updated>{{$rss.atom_updated}}</updated>
- <link type="text/html" rel="alternate" href="{{$rss.alternate}}"/>
- <link type="application/atom+xml" rel="self" href="{{$rss.self}}"/>
- 
- 
- <author>
-	<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
-	<uri>{{$user.url}}</uri>
-	<name>{{$user.name}}</name>
-	<link rel="alternate" type="text/html" href="{{$user.url}}"/>
-	<link rel="avatar" type="image/jpeg" media:width="106" media:height="106" href="{{$user.profile_image_url}}"/>
-	<link rel="avatar" type="image/jpeg" media:width="96" media:height="96" href="{{$user.profile_image_url}}"/>
-	<link rel="avatar" type="image/jpeg" media:width="48" media:height="48" href="{{$user.profile_image_url}}"/>
-	<link rel="avatar" type="image/jpeg" media:width="24" media:height="24" href="{{$user.profile_image_url}}"/>
-	<georss:point></georss:point>
-	<poco:preferredUsername>{{$user.screen_name}}</poco:preferredUsername>
-	<poco:displayName>{{$user.name}}</poco:displayName>
-	<poco:urls>
-		<poco:type>homepage</poco:type>
-		<poco:value>{{$user.url}}</poco:value>
-		<poco:primary>true</poco:primary>
-	</poco:urls>
-	<statusnet:profile_info local_id="{{$user.id}}"></statusnet:profile_info>
- </author>
-
- <!--Deprecation warning: activity:subject is present only for backward compatibility. It will be removed in the next version of StatusNet.-->
- <activity:subject>
-	<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
-	<id>{{$user.contact_url}}</id>
-	<title>{{$user.name}}</title>
-	<link rel="alternate" type="text/html" href="{{$user.url}}"/>
-	<link rel="avatar" type="image/jpeg" media:width="106" media:height="106" href="{{$user.profile_image_url}}"/>
-	<link rel="avatar" type="image/jpeg" media:width="96" media:height="96" href="{{$user.profile_image_url}}"/>
-	<link rel="avatar" type="image/jpeg" media:width="48" media:height="48" href="{{$user.profile_image_url}}"/>
-	<link rel="avatar" type="image/jpeg" media:width="24" media:height="24" href="{{$user.profile_image_url}}"/>
-	<poco:preferredUsername>{{$user.screen_name}}</poco:preferredUsername>
-	<poco:displayName>{{$user.name}}</poco:displayName>
-	<poco:urls>
-		<poco:type>homepage</poco:type>
-		<poco:value>{{$user.url}}</poco:value>
-		<poco:primary>true</poco:primary>
-	</poco:urls>
-	<statusnet:profile_info local_id="{{$user.id}}"></statusnet:profile_info>
- </activity:subject>
- 
- 
-  	{{foreach $statuses as $status}}
-	<entry>
-		<activity:object-type>{{$status.objecttype}}</activity:object-type>
-		<id>{{$status.message_id}}</id>
-		<title>{{$status.text}}</title>
-		<content type="html">{{$status.statusnet_html}}</content>
-		<link rel="alternate" type="text/html" href="{{$status.url}}"/>
-		<activity:verb>{{$status.verb}}</activity:verb>
-		<published>{{$status.published}}</published>
-		<updated>{{$status.updated}}</updated>
-
-		<link rel="self" type="application/atom+xml" href="{{$status.self}}"/>
-		<link rel="edit" type="application/atom+xml" href="{{$status.edit}}"/>
-		<statusnet:notice_info local_id="{{$status.id}}" source="{{$status.source}}" >
-		</statusnet:notice_info>
-
-		<author>
-			<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
-			<uri>{{$status.user.url}}</uri>
-			<name>{{$status.user.name}}</name>
-			<link rel="alternate" type="text/html" href="{{$status.user.url}}"/>
-			<link rel="avatar" type="image/jpeg" media:width="48" media:height="48" href="{{$status.user.profile_image_url}}"/>
-
-			<georss:point/>
-			<poco:preferredUsername>{{$status.user.screen_name}}</poco:preferredUsername>
-			<poco:displayName>{{$status.user.name}}</poco:displayName>
-			<poco:address/>
-			<poco:urls>
-				<poco:type>homepage</poco:type>
-				<poco:value>{{$status.user.url}}</poco:value>
-				<poco:primary>true</poco:primary>
-			</poco:urls>
-		</author>
-		<link rel="ostatus:conversation" type="text/html" href="{{$status.url}}"/> 
-
-	</entry>    
-    {{/foreach}}
-</feed>

From 4f07dfb35ae954908e7c0d82c76ed78d96db8e03 Mon Sep 17 00:00:00 2001
From: Michael Vogel <icarus@dabo.de>
Date: Mon, 18 Jul 2016 15:25:42 +0200
Subject: [PATCH 5/8] Optimized queries

---
 include/api.php | 58 ++++++++++++++++++++++++++-----------------------
 include/xml.php |  2 --
 2 files changed, 31 insertions(+), 29 deletions(-)

diff --git a/include/api.php b/include/api.php
index 4796228f9d..ff2d083cc8 100644
--- a/include/api.php
+++ b/include/api.php
@@ -536,7 +536,7 @@
 					'notifications' => false,
 					'statusnet_profile_url' => $r[0]["url"],
 					'uid' => 0,
-					'cid' => 0,
+					'cid' => get_contact($r[0]["url"], api_user()),
 					'self' => 0,
 					'network' => $r[0]["network"],
 				);
@@ -1208,10 +1208,10 @@
 		$user_info = api_get_user($a);
 
 		$lastwall = q("SELECT `item`.*
-				FROM `item`, `contact`
+				FROM `item`
+				INNER JOIN `contact` ON `contact`.`id`=`item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
 				WHERE `item`.`uid` = %d AND `verb` = '%s' AND `item`.`contact-id` = %d
 					AND ((`item`.`author-link` IN ('%s', '%s')) OR (`item`.`owner-link` IN ('%s', '%s')))
-					AND `contact`.`id`=`item`.`contact-id`
 					AND `type`!='activity'
 					AND `item`.`allow_cid`='' AND `item`.`allow_gid`='' AND `item`.`deny_cid`='' AND `item`.`deny_gid`=''
 				ORDER BY `created` DESC
@@ -1224,6 +1224,7 @@
 				dbesc($user_info['url']),
 				dbesc(normalise_link($user_info['url']))
 		);
+
 		if (count($lastwall)>0){
 			$lastwall = $lastwall[0];
 
@@ -1371,15 +1372,15 @@
 		if ($conversation_id > 0)
 			$sql_extra .= ' AND `item`.`parent` = '.intval($conversation_id);
 
-		$r = q("SELECT STRAIGHT_JOIN `item`.*, `item`.`id` AS `item_id`, `item`.`network` AS `item_network`,
+		$r = q("SELECT `item`.*, `item`.`id` AS `item_id`, `item`.`network` AS `item_network`,
 			`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
 			`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
 			`contact`.`id` AS `cid`
-			FROM `item`, `contact`
+			FROM `item`
+			STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
+				AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
 			WHERE `item`.`uid` = %d AND `verb` = '%s'
-			AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
-			AND `contact`.`id` = `item`.`contact-id`
-			AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
+			AND `item`.`visible` AND NOT `item`.`moderated` AND NOT `item`.`deleted`
 			$sql_extra
 			AND `item`.`id`>%d
 			ORDER BY `item`.`id` DESC LIMIT %d ,%d ",
@@ -1449,13 +1450,15 @@
 			`contact`.`network`, `contact`.`thumb`, `contact`.`self`, `contact`.`writable`,
 			`contact`.`id` AS `cid`,
 			`user`.`nickname`, `user`.`hidewall`
-			FROM `item` STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
+			FROM `item`
+			STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
+				AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
 			STRAIGHT_JOIN `user` ON `user`.`uid` = `item`.`uid`
-			WHERE `verb` = '%s' AND `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0
+				AND NOT `user`.`hidewall`
+			WHERE `verb` = '%s' AND `item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated`
 			AND `item`.`allow_cid` = ''  AND `item`.`allow_gid` = ''
 			AND `item`.`deny_cid`  = '' AND `item`.`deny_gid`  = ''
-			AND `item`.`private` = 0 AND `item`.`wall` = 1 AND `user`.`hidewall` = 0
-			AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
+			AND NOT `item`.`private` AND `item`.`wall`
 			$sql_extra
 			AND `item`.`id`>%d
 			ORDER BY `item`.`id` DESC LIMIT %d, %d ",
@@ -1511,10 +1514,11 @@
 			`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
 			`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
 			`contact`.`id` AS `cid`
-			FROM `item`, `contact`
-			WHERE `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
-			AND `contact`.`id` = `item`.`contact-id` AND `item`.`uid` = %d AND `item`.`verb` = '%s'
-			AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
+			FROM `item`
+			INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
+				AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
+			WHERE `item`.`visible` AND NOT `item`.`moderated` AND NOT `item`.`deleted`
+			AND `item`.`uid` = %d AND `item`.`verb` = '%s'
 			$sql_extra",
 			intval(api_user()),
 			dbesc(ACTIVITY_POST),
@@ -1584,11 +1588,11 @@
 			`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
 			`contact`.`id` AS `cid`
 			FROM `item`
-			INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
+			STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
+				AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
 			WHERE `item`.`parent` = %d AND `item`.`visible`
 			AND NOT `item`.`moderated` AND NOT `item`.`deleted`
 			AND `item`.`uid` = %d AND `item`.`verb` = '%s'
-			AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
 			AND `item`.`id`>%d $sql_extra
 			ORDER BY `item`.`id` DESC LIMIT %d ,%d",
 			intval($id), intval(api_user()),
@@ -1635,10 +1639,10 @@
 			`contact`.`name`, `contact`.`photo` as `reply_photo`, `contact`.`url` as `reply_url`, `contact`.`rel`,
 			`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
 			`contact`.`id` AS `cid`
-			FROM `item`, `contact`
-			WHERE `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
-			AND `contact`.`id` = `item`.`contact-id`
-			AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
+			FROM `item`
+			INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
+				AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
+			WHERE `item`.`visible` AND NOT `item`.`moderated` AND NOT `item`.`deleted`
 			AND NOT `item`.`private` AND `item`.`allow_cid` = '' AND `item`.`allow`.`gid` = ''
 			AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = ''
 			$sql_extra
@@ -1748,12 +1752,12 @@
 			`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
 			`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
 			`contact`.`id` AS `cid`
-			FROM `item`  FORCE INDEX (`uid_id`), `contact`
+			FROM `item` FORCE INDEX (`uid_id`)
+			STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
+				AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
 			WHERE `item`.`uid` = %d AND `verb` = '%s'
 			AND NOT (`item`.`author-link` IN ('https://%s', 'http://%s'))
 			AND `item`.`visible` AND NOT `item`.`moderated` AND NOT `item`.`deleted`
-			AND `contact`.`id` = `item`.`contact-id`
-			AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
 			AND `item`.`parent` IN (SELECT `iid` FROM `thread` WHERE `uid` = %d AND `mention` AND !`ignored`)
 			$sql_extra
 			AND `item`.`id`>%d
@@ -1819,8 +1823,8 @@
 			`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
 			`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
 			`contact`.`id` AS `cid`
-			FROM `item`
-			INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
+			FROM `item` FORCE INDEX (`uid_contactid_id`)
+			STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
 				AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
 			WHERE `item`.`uid` = %d AND `verb` = '%s'
 			AND `item`.`contact-id` = %d
diff --git a/include/xml.php b/include/xml.php
index d2a0f7655b..a60d0671d3 100644
--- a/include/xml.php
+++ b/include/xml.php
@@ -64,8 +64,6 @@ class xml {
 					$element_parts = explode(":", $attr_key);
 					if ((count($element_parts) > 1) AND isset($namespaces[$element_parts[0]]))
 						$namespace = $namespaces[$element_parts[0]];
-					elseif (isset($namespaces[""]))
-						$namespace = $namespaces[""];
 					else
 						$namespace = NULL;
 

From 8bf7db06dbd76f63af4ac9f0c84a32ceb20b8119 Mon Sep 17 00:00:00 2001
From: Michael Vogel <icarus@dabo.de>
Date: Tue, 19 Jul 2016 08:43:57 +0200
Subject: [PATCH 6/8] New indexes for the API

---
 boot.php                |  2 +-
 database.sql            |  5 +++--
 include/Contact.php     |  4 ++--
 include/api.php         | 21 +++++++++++++--------
 include/dbstructure.php |  3 ++-
 include/ostatus.php     |  2 +-
 mod/content.php         |  2 +-
 update.php              |  2 +-
 8 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/boot.php b/boot.php
index 298010dd0d..8a92835e68 100644
--- a/boot.php
+++ b/boot.php
@@ -38,7 +38,7 @@ define ( 'FRIENDICA_PLATFORM',     'Friendica');
 define ( 'FRIENDICA_CODENAME',     'Asparagus');
 define ( 'FRIENDICA_VERSION',      '3.5-dev' );
 define ( 'DFRN_PROTOCOL_VERSION',  '2.23'    );
-define ( 'DB_UPDATE_VERSION',      1199      );
+define ( 'DB_UPDATE_VERSION',      1200      );
 
 /**
  * @brief Constant with a HTML line break.
diff --git a/database.sql b/database.sql
index 2b55a896f8..b27f69c40e 100644
--- a/database.sql
+++ b/database.sql
@@ -1,6 +1,6 @@
 -- ------------------------------------------
 -- Friendica 3.5-dev (Asparagus)
--- DB_UPDATE_VERSION 1199
+-- DB_UPDATE_VERSION 1200
 -- ------------------------------------------
 
 
@@ -522,6 +522,7 @@ CREATE TABLE IF NOT EXISTS `item` (
 	 INDEX `uid_title` (`uid`,`title`),
 	 INDEX `uid_thrparent` (`uid`,`thr-parent`),
 	 INDEX `uid_parenturi` (`uid`,`parent-uri`),
+	 INDEX `uid_contactid_id` (`uid`,`contact-id`,`id`),
 	 INDEX `uid_contactid_created` (`uid`,`contact-id`,`created`),
 	 INDEX `gcontactid_uid_created` (`gcontact-id`,`uid`,`created`),
 	 INDEX `authorid_created` (`author-id`,`created`),
@@ -532,7 +533,7 @@ CREATE TABLE IF NOT EXISTS `item` (
 	 INDEX `uid_wall_created` (`uid`,`wall`,`created`),
 	 INDEX `resource-id` (`resource-id`),
 	 INDEX `uid_type` (`uid`,`type`),
-	 INDEX `uid_starred` (`uid`,`starred`),
+	 INDEX `uid_starred_id` (`uid`,`starred`,`id`),
 	 INDEX `contactid_allowcid_allowpid_denycid_denygid` (`contact-id`,`allow_cid`(10),`allow_gid`(10),`deny_cid`(10),`deny_gid`(10)),
 	 INDEX `uid_wall_parent_created` (`uid`,`wall`,`parent`,`created`),
 	 INDEX `uid_type_changed` (`uid`,`type`,`changed`),
diff --git a/include/Contact.php b/include/Contact.php
index 10005d3e3c..9d69a81a4e 100644
--- a/include/Contact.php
+++ b/include/Contact.php
@@ -631,11 +631,11 @@ function posts_from_contact($a, $contact_id) {
 	$r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
 			`author-name` AS `name`, `owner-avatar` AS `photo`,
 			`owner-link` AS `url`, `owner-avatar` AS `thumb`
-		FROM `item` FORCE INDEX (`uid_contactid_created`)
+		FROM `item` FORCE INDEX (`uid_contactid_id`)
 		WHERE `item`.`uid` = %d AND `contact-id` = %d
 			AND `author-link` IN ('%s', '%s')
 			AND NOT `deleted` AND NOT `moderated` AND `visible`
-		ORDER BY `item`.`created` DESC LIMIT %d, %d",
+		ORDER BY `item`.`id` DESC LIMIT %d, %d",
 		intval(local_user()),
 		intval($contact_id),
 		dbesc(str_replace("https://", "http://", $contact["url"])),
diff --git a/include/api.php b/include/api.php
index ff2d083cc8..af0fa60084 100644
--- a/include/api.php
+++ b/include/api.php
@@ -202,8 +202,8 @@
 		else {
 			// process normal login request
 
-			$r = q("SELECT * FROM `user` WHERE ( `email` = '%s' OR `nickname` = '%s' )
-				AND `password` = '%s' AND `blocked` = 0 AND `account_expired` = 0 AND `account_removed` = 0 AND `verified` = 1 LIMIT 1",
+			$r = q("SELECT * FROM `user` WHERE (`email` = '%s' OR `nickname` = '%s')
+				AND `password` = '%s' AND NOT `blocked` AND NOT `account_expired` AND NOT `account_removed` AND `verified` LIMIT 1",
 				dbesc(trim($user)),
 				dbesc(trim($user)),
 				dbesc($encrypted)
@@ -220,7 +220,9 @@
 			throw new UnauthorizedException("This API requires login");
 		}
 
-		authenticate_success($record); $_SESSION["allow_api"] = true;
+		authenticate_success($record);
+
+		$_SESSION["allow_api"] = true;
 
 		call_hooks('logged_in', $a->user);
 
@@ -476,7 +478,7 @@
 				return False;
 			} else {
 				$user = $_SESSION['uid'];
-				$extra_query = "AND `contact`.`uid` = %d AND `contact`.`self` = 1 ";
+				$extra_query = "AND `contact`.`uid` = %d AND `contact`.`self` ";
 			}
 
 		}
@@ -548,6 +550,10 @@
 		}
 
 		if($uinfo[0]['self']) {
+
+			if ($uinfo[0]['network'] == "")
+				$uinfo[0]['network'] = NETWORK_DFRN;
+
 			$usr = q("select * from user where uid = %d limit 1",
 				intval(api_user())
 			);
@@ -1090,7 +1096,7 @@
 					AND ((`item`.`author-link` IN ('%s', '%s')) OR (`item`.`owner-link` IN ('%s', '%s')))
 					AND `i`.`id` = `item`.`parent`
 					AND `item`.`type`!='activity' $privacy_sql
-				ORDER BY `item`.`created` DESC
+				ORDER BY `item`.`id` DESC
 				LIMIT 1",
 				intval($user_info['cid']),
 				intval(api_user()),
@@ -1206,7 +1212,6 @@
 	 */
 	function api_users_show(&$a, $type){
 		$user_info = api_get_user($a);
-
 		$lastwall = q("SELECT `item`.*
 				FROM `item`
 				INNER JOIN `contact` ON `contact`.`id`=`item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
@@ -1214,7 +1219,7 @@
 					AND ((`item`.`author-link` IN ('%s', '%s')) OR (`item`.`owner-link` IN ('%s', '%s')))
 					AND `type`!='activity'
 					AND `item`.`allow_cid`='' AND `item`.`allow_gid`='' AND `item`.`deny_cid`='' AND `item`.`deny_gid`=''
-				ORDER BY `created` DESC
+				ORDER BY `id` DESC
 				LIMIT 1",
 				intval(api_user()),
 				dbesc(ACTIVITY_POST),
@@ -1506,7 +1511,7 @@
 
 		$sql_extra = '';
 		if ($conversation)
-			$sql_extra .= " AND `item`.`parent` = %d ORDER BY `received` ASC ";
+			$sql_extra .= " AND `item`.`parent` = %d ORDER BY `id` ASC ";
 		else
 			$sql_extra .= " AND `item`.`id` = %d";
 
diff --git a/include/dbstructure.php b/include/dbstructure.php
index 10e1e0e625..bd35d0974a 100644
--- a/include/dbstructure.php
+++ b/include/dbstructure.php
@@ -858,6 +858,7 @@ function db_definition() {
 					"uid_title" => array("uid","title"),
 					"uid_thrparent" => array("uid","thr-parent"),
 					"uid_parenturi" => array("uid","parent-uri"),
+					"uid_contactid_id" => array("uid","contact-id","id"),
 					"uid_contactid_created" => array("uid","contact-id","created"),
 					"gcontactid_uid_created" => array("gcontact-id","uid","created"),
 					"authorid_created" => array("author-id","created"),
@@ -868,7 +869,7 @@ function db_definition() {
 					"uid_wall_created" => array("uid","wall","created"),
 					"resource-id" => array("resource-id"),
 					"uid_type" => array("uid","type"),
-					"uid_starred" => array("uid","starred"),
+					"uid_starred_id" => array("uid","starred", "id"),
 					"contactid_allowcid_allowpid_denycid_denygid" => array("contact-id","allow_cid(10)","allow_gid(10)","deny_cid(10)","deny_gid(10)"),
 					"uid_wall_parent_created" => array("uid","wall","parent","created"),
 					"uid_type_changed" => array("uid","type","changed"),
diff --git a/include/ostatus.php b/include/ostatus.php
index 7ac26846d2..ec53141dc7 100644
--- a/include/ostatus.php
+++ b/include/ostatus.php
@@ -1971,7 +1971,7 @@ class ostatus {
 						OR (`item`.`network` = '%s' AND ((`thread`.`network` IN ('%s', '%s')) OR (`thritem`.`network` IN ('%s', '%s')))) AND `thread`.`mention`)
 					AND ((`item`.`owner-link` IN ('%s', '%s') AND (`item`.`parent` = `item`.`id`))
 						OR (`item`.`author-link` IN ('%s', '%s')))
-				ORDER BY `item`.`received` DESC
+				ORDER BY `item`.`id` DESC
 				LIMIT 0, 300",
 				intval($owner["uid"]), dbesc($check_date), dbesc(NETWORK_DFRN),
 				//dbesc(NETWORK_OSTATUS), dbesc(NETWORK_OSTATUS),
diff --git a/mod/content.php b/mod/content.php
index 54d499d401..c4b1f2f68f 100644
--- a/mod/content.php
+++ b/mod/content.php
@@ -224,7 +224,7 @@ function content_content(&$a, $update = 0) {
 			$simple_update
 			AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
 			$sql_extra $sql_nets
-			ORDER BY `item`.`received` DESC $pager_sql ",
+			ORDER BY `item`.`id` DESC $pager_sql ",
 			intval($_SESSION['uid'])
 		);
 
diff --git a/update.php b/update.php
index 41f238e913..8a8d93b1b9 100644
--- a/update.php
+++ b/update.php
@@ -1,6 +1,6 @@
 <?php
 
-define('UPDATE_VERSION' , 1199);
+define('UPDATE_VERSION' , 1200);
 
 /**
  *

From 0e7ff6b4dba501ec0b20b1223e050e16208d86b5 Mon Sep 17 00:00:00 2001
From: Michael Vogel <icarus@dabo.de>
Date: Tue, 19 Jul 2016 08:46:41 +0200
Subject: [PATCH 7/8] Removed (now) unused templates

---
 view/templates/api_config_xml.tpl        | 67 ------------------------
 view/templates/api_friends_xml.tpl       |  6 ---
 view/templates/api_photo_detail_xml.tpl  | 21 --------
 view/templates/api_photos_list_xml.tpl   |  5 --
 view/templates/api_ratelimit_xml.tpl     |  7 ---
 view/templates/api_single_status_xml.tpl | 25 ---------
 view/templates/api_status_xml.tpl        |  8 ---
 view/templates/api_test_xml.tpl          |  2 -
 view/templates/api_timeline_rss.tpl      | 27 ----------
 view/templates/api_timeline_xml.tpl      | 10 ----
 view/templates/api_user_xml.tpl          | 47 -----------------
 11 files changed, 225 deletions(-)
 delete mode 100644 view/templates/api_config_xml.tpl
 delete mode 100644 view/templates/api_friends_xml.tpl
 delete mode 100644 view/templates/api_photo_detail_xml.tpl
 delete mode 100644 view/templates/api_photos_list_xml.tpl
 delete mode 100644 view/templates/api_ratelimit_xml.tpl
 delete mode 100644 view/templates/api_single_status_xml.tpl
 delete mode 100644 view/templates/api_status_xml.tpl
 delete mode 100644 view/templates/api_test_xml.tpl
 delete mode 100644 view/templates/api_timeline_rss.tpl
 delete mode 100644 view/templates/api_timeline_xml.tpl
 delete mode 100644 view/templates/api_user_xml.tpl

diff --git a/view/templates/api_config_xml.tpl b/view/templates/api_config_xml.tpl
deleted file mode 100644
index 3673e2a10e..0000000000
--- a/view/templates/api_config_xml.tpl
+++ /dev/null
@@ -1,67 +0,0 @@
-
-<config>
- <site>
-  <name>{{$config.site.name}}</name>
-  <server>{{$config.site.server}}</server>
-  <theme>default</theme>
-  <path></path>
-  <logo>{{$config.site.logo}}</logo>
-
-  <fancy>true</fancy>
-  <language>en</language>
-  <email>{{$config.site.email}}</email>
-  <broughtby></broughtby>
-  <broughtbyurl></broughtbyurl>
-  <timezone>UTC</timezone>
-  <closed>{{$config.site.closed}}</closed>
-
-  <inviteonly>false</inviteonly>
-  <private>{{$config.site.private}}</private>
-  <textlimit>{{$config.site.textlimit}}</textlimit>
-  <ssl>{{$config.site.ssl}}</ssl>
-  <sslserver>{{$config.site.sslserver}}</sslserver>
-  <shorturllength>30</shorturllength>
-
-</site>
- <license>
-  <type>cc</type>
-  <owner></owner>
-  <url>http://creativecommons.org/licenses/by/3.0/</url>
-  <title>Creative Commons Attribution 3.0</title>
-  <image>http://i.creativecommons.org/l/by/3.0/80x15.png</image>
-
-</license>
- <nickname>
-  <featured></featured>
-</nickname>
- <profile>
-  <biolimit></biolimit>
-</profile>
- <group>
-  <desclimit></desclimit>
-</group>
- <notice>
-
-  <contentlimit></contentlimit>
-</notice>
- <throttle>
-  <enabled>false</enabled>
-  <count>20</count>
-  <timespan>600</timespan>
-</throttle>
- <xmpp>
-
-  <enabled>false</enabled>
-  <server>INVALID SERVER</server>
-  <port>5222</port>
-  <user>update</user>
-</xmpp>
- <integration>
-  <source>StatusNet</source>
-
-</integration>
- <attachments>
-  <uploads>false</uploads>
-  <file_quota>0</file_quota>
-</attachments>
-</config>
diff --git a/view/templates/api_friends_xml.tpl b/view/templates/api_friends_xml.tpl
deleted file mode 100644
index 4c9f7e6287..0000000000
--- a/view/templates/api_friends_xml.tpl
+++ /dev/null
@@ -1,6 +0,0 @@
-{{* used in include/api.php 'api_statuses_friends' and 'api_statuses_followers' *}}
-<users type="array">
-	{{foreach $users as $u}}
-	<user>{{include file="api_user_xml.tpl" user=$u}}</user>
-	{{/foreach}}
-</users>
diff --git a/view/templates/api_photo_detail_xml.tpl b/view/templates/api_photo_detail_xml.tpl
deleted file mode 100644
index 0b0602901b..0000000000
--- a/view/templates/api_photo_detail_xml.tpl
+++ /dev/null
@@ -1,21 +0,0 @@
-
-<photo>
-	<id>{{$photo.id}}</id>
-	<created>{{$photo.created}}</created>
-	<edited>{{$photo.edited}}</edited>
-	<title>{{$photo.title}}</title>
-	<desc>{{$photo.desc}}</desc>
-	<album>{{$photo.album}}</album>
-	<filename>{{$photo.filename}}</filename>
-	<type>{{$photo.type}}</type>
-	<height>{{$photo.height}}</height>
-	<width>{{$photo.width}}</width>
-	<datasize>{{$photo.datasize}}</datasize>
-	<profile>1</profile>
-	<links type="array">{{foreach $photo.link as $scale => $url}}
-		<link type="{{$photo.type}}" scale="{{$scale}}" href="{{$url}}" />
-	{{/foreach}}</links>
-	{{if $photo.data}}
-	<data encode="base64">{{$photo.data}}</data>
-	{{/if}}
-</photo>
diff --git a/view/templates/api_photos_list_xml.tpl b/view/templates/api_photos_list_xml.tpl
deleted file mode 100644
index 1478e02056..0000000000
--- a/view/templates/api_photos_list_xml.tpl
+++ /dev/null
@@ -1,5 +0,0 @@
-
-<photos type="array">
-{{foreach $photos as $photo}}
-	<photo id="{{$photo.id}}" album="{{$photo.album}}" filename="{{$photo.filename}}" type="{{$photo.type}}">{{$photo.thumb}}</photo>
-{{/foreach}}</photos>
diff --git a/view/templates/api_ratelimit_xml.tpl b/view/templates/api_ratelimit_xml.tpl
deleted file mode 100644
index 5c3986bb92..0000000000
--- a/view/templates/api_ratelimit_xml.tpl
+++ /dev/null
@@ -1,7 +0,0 @@
-
-<hash>
- <remaining-hits type="integer">{{$hash.remaining_hits}}</remaining-hits>
- <hourly-limit type="integer">{{$hash.hourly_limit}}</hourly-limit>
- <reset-time type="datetime">{{$hash.reset_time}}</reset-time>
- <reset_time_in_seconds type="integer">{{$hash.resettime_in_seconds}}</reset_time_in_seconds>
-</hash>
diff --git a/view/templates/api_single_status_xml.tpl b/view/templates/api_single_status_xml.tpl
deleted file mode 100644
index 88c56f935b..0000000000
--- a/view/templates/api_single_status_xml.tpl
+++ /dev/null
@@ -1,25 +0,0 @@
-{{* shared structure for statuses. includers must define root element *}}
-  <text>{{$status.text}}</text>
-  <truncated>{{$status.truncated}}</truncated>
-  <created_at>{{$status.created_at}}</created_at>
-  <in_reply_to_status_id>{{$status.in_reply_to_status_id}}</in_reply_to_status_id>
-  <source>{{$status.source}}</source>
-  <id>{{$status.id}}</id>
-  <in_reply_to_user_id>{{$status.in_reply_to_user_id}}</in_reply_to_user_id>
-  <in_reply_to_screen_name>{{$status.in_reply_to_screen_name}}</in_reply_to_screen_name>
-  <geo>{{$status.geo}}</geo>
-  <favorited>{{$status.favorited}}</favorited>
-	<user>{{include file="api_user_xml.tpl" user=$status.user}}</user>
-	<friendica:owner>{{include file="api_user_xml.tpl" user=$status.friendica_owner}}</friendica:owner>
-  <statusnet:html>{{$status.statusnet_html}}</statusnet:html>
-  <statusnet:conversation_id>{{$status.statusnet_conversation_id}}</statusnet:conversation_id>
-  <url>{{$status.url}}</url>
-  <coordinates>{{$status.coordinates}}</coordinates>
-  <place>{{$status.place}}</place>
-  <contributors>{{$status.contributors}}</contributors>
-  {{if $status.retweeted_status}}<retweeted_status>{{include file="api_single_status_xml.tpl" status=$status.retweeted_status}}</retweeted_status>{{/if}}
-  <friendica:activities>
-    {{foreach $status.friendica_activities as $k=>$v}}
-    <friendica:{{$k}}>{{$v|count}}</friendica:{{$k}}>
-    {{/foreach}}
-  </friendica:activities>
\ No newline at end of file
diff --git a/view/templates/api_status_xml.tpl b/view/templates/api_status_xml.tpl
deleted file mode 100644
index a382810ff4..0000000000
--- a/view/templates/api_status_xml.tpl
+++ /dev/null
@@ -1,8 +0,0 @@
-{{* used in api.php to return a single status *}}
-<status
-	xmlns:statusnet="http://status.net/schema/api/1/"
-	xmlns:friendica="http://friendi.ca/schema/api/1/">
-	{{if $status}}
-	{{include file="api_single_status_xml.tpl" status=$status}}
-	{{/if}}
-</status>
diff --git a/view/templates/api_test_xml.tpl b/view/templates/api_test_xml.tpl
deleted file mode 100644
index ad648fc041..0000000000
--- a/view/templates/api_test_xml.tpl
+++ /dev/null
@@ -1,2 +0,0 @@
-
-<ok>{{$ok}}</ok>
diff --git a/view/templates/api_timeline_rss.tpl b/view/templates/api_timeline_rss.tpl
deleted file mode 100644
index 7b08ecd4c8..0000000000
--- a/view/templates/api_timeline_rss.tpl
+++ /dev/null
@@ -1,27 +0,0 @@
-
-<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:georss="http://www.georss.org/georss" xmlns:twitter="http://api.twitter.com">
-  <channel>
-    <title>Friendica</title>
-    <link>{{$rss.alternate}}</link>
-    <atom:link type="application/rss+xml" rel="self" href="{{$rss.self}}"/>
-    <description>Friendica timeline</description>
-    <language>{{$rss.language}}</language>
-    <ttl>40</ttl>
-	<image>
-		<link>{{$user.link}}</link>
-		<title>{{$user.name}}'s items</title>
-		<url>{{$user.profile_image_url}}</url>
-	</image>
-	
-{{foreach $statuses as $status}}
-  <item>
-    <title>{{$status.user.name}}: {{$status.text}}</title>
-    <description>{{$status.text}}</description>
-    <pubDate>{{$status.created_at}}</pubDate>
-    <guid>{{$status.url}}</guid>
-    <link>{{$status.url}}</link>
-    <twitter:source>{{$status.source}}</twitter:source>
-  </item>
-{{/foreach}}
-  </channel>
-</rss>
diff --git a/view/templates/api_timeline_xml.tpl b/view/templates/api_timeline_xml.tpl
deleted file mode 100644
index 01b71c0bcc..0000000000
--- a/view/templates/api_timeline_xml.tpl
+++ /dev/null
@@ -1,10 +0,0 @@
-
-<statuses type="array"
-	xmlns:statusnet="http://status.net/schema/api/1/"
-	xmlns:friendica="http://friendi.ca/schema/api/1/">
-{{foreach $statuses as $status}}
- <status>
-	{{include file="api_single_status_xml.tpl" status=$status}}
- </status>
-{{/foreach}}
-</statuses>
diff --git a/view/templates/api_user_xml.tpl b/view/templates/api_user_xml.tpl
deleted file mode 100644
index 698c5436dd..0000000000
--- a/view/templates/api_user_xml.tpl
+++ /dev/null
@@ -1,47 +0,0 @@
-{{* includer template MUST provide root element *}}
-
-   <id>{{$user.id}}</id>
-   <name>{{$user.name}}</name>
-   <screen_name>{{$user.screen_name}}</screen_name>
-   <location>{{$user.location}}</location>
-   <description>{{$user.description}}</description>
-   <profile_image_url>{{$user.profile_image_url}}</profile_image_url>
-   <url>{{$user.url}}</url>
-   <protected>{{$user.protected}}</protected>
-   <followers_count>{{$user.followers_count}}</followers_count>
-   <friends_count>{{$user.friends_count}}</friends_count>
-   <created_at>{{$user.created_at}}</created_at>
-   <favourites_count>{{$user.favourites_count}}</favourites_count>
-   <utc_offset>{{$user.utc_offset}}</utc_offset>
-   <time_zone>{{$user.time_zone}}</time_zone>
-   <statuses_count>{{$user.statuses_count}}</statuses_count>
-   <following>{{$user.following}}</following>
-   <profile_background_color>{{$user.profile_background_color}}</profile_background_color>
-   <profile_text_color>{{$user.profile_text_color}}</profile_text_color>
-   <profile_link_color>{{$user.profile_link_color}}</profile_link_color>
-   <profile_sidebar_fill_color>{{$user.profile_sidebar_fill_color}}</profile_sidebar_fill_color>
-   <profile_sidebar_border_color>{{$user.profile_sidebar_border_color}}</profile_sidebar_border_color>
-   <profile_background_image_url>{{$user.profile_background_image_url}}</profile_background_image_url>
-   <profile_background_tile>{{$user.profile_background_tile}}</profile_background_tile>
-   <profile_use_background_image>{{$user.profile_use_background_image}}</profile_use_background_image>
-   <notifications>{{$user.notifications}}</notifications>
-   <geo_enabled>{{$user.geo_enabled}}</geo_enabled>
-   <verified>{{$user.verified}}</verified>
-   <lang>{{$user.lang}}</lang>
-   <contributors_enabled>{{$user.contributors_enabled}}</contributors_enabled>
-   <status>{{if $user.status}}
-    <created_at>{{$user.status.created_at}}</created_at>
-    <id>{{$user.status.id}}</id>
-    <text>{{$user.status.text}}</text>
-    <source>{{$user.status.source}}</source>
-    <truncated>{{$user.status.truncated}}</truncated>
-    <in_reply_to_status_id>{{$user.status.in_reply_to_status_id}}</in_reply_to_status_id>
-    <in_reply_to_user_id>{{$user.status.in_reply_to_user_id}}</in_reply_to_user_id>
-    <favorited>{{$user.status.favorited}}</favorited>
-    <in_reply_to_screen_name>{{$user.status.in_reply_to_screen_name}}</in_reply_to_screen_name>
-    <geo>{{$user.status.geo}}</geo>
-    <coordinates>{{$user.status.coordinates}}</coordinates>
-    <place>{{$user.status.place}}</place>
-    <contributors>{{$user.status.contributors}}</contributors>
-  {{/if}}</status>
-  

From 747dc934f73643933fb46a720dd0570069eaf36a Mon Sep 17 00:00:00 2001
From: Michael Vogel <icarus@dabo.de>
Date: Sun, 24 Jul 2016 13:53:26 +0200
Subject: [PATCH 8/8] Avoid warning because $a isn't called by reference

---
 include/api.php | 258 ++++++++++++++++++++++++++++++++----------------
 1 file changed, 171 insertions(+), 87 deletions(-)

diff --git a/include/api.php b/include/api.php
index af0fa60084..14d11f6695 100644
--- a/include/api.php
+++ b/include/api.php
@@ -92,7 +92,7 @@
 	 *
 	 * Register a function to be the endpont for defined API path.
 	 *
-	 * @param string $path API URL path, relative to $a->get_baseurl()
+	 * @param string $path API URL path, relative to App::get_baseurl()
 	 * @param string $func Function name to call on path request
 	 * @param bool $auth API need logged user
 	 * @param string $method
@@ -276,7 +276,7 @@
 					logger('API parameters: ' . print_r($_REQUEST,true));
 
 					$stamp =  microtime(true);
-					$r = call_user_func($info['func'], $a, $type);
+					$r = call_user_func($info['func'], $type);
 					$duration = (float)(microtime(true)-$stamp);
 					logger("API call duration: ".round($duration, 2)."\t".$a->query_string, LOGGER_DEBUG);
 
@@ -314,19 +314,21 @@
 			throw new NotImplementedException();
 		} catch (HTTPException $e) {
 			header("HTTP/1.1 {$e->httpcode} {$e->httpdesc}");
-			return api_error($a, $type, $e);
+			return api_error($type, $e);
 		}
 	}
 
 	/**
 	 * @brief Format API error string
 	 *
-	 * @param Api $a
 	 * @param string $type Return type (xml, json, rss, as)
 	 * @param HTTPException $error Error object
 	 * @return strin error message formatted as $type
 	 */
-	function api_error(&$a, $type, $e) {
+	function api_error($type, $e) {
+
+		$a = get_app();
+
 		$error = ($e->getMessage()!==""?$e->getMessage():$e->httpdesc);
 		# TODO:  https://dev.twitter.com/overview/api/response-codes
 
@@ -369,12 +371,12 @@
 		$arr['$user'] = $user_info;
 		$arr['$rss'] = array(
 			'alternate' => $user_info['url'],
-			'self' => $a->get_baseurl(). "/". $a->query_string,
-			'base' => $a->get_baseurl(),
+			'self' => App::get_baseurl(). "/". $a->query_string,
+			'base' => App::get_baseurl(),
 			'updated' => api_date(null),
 			'atom_updated' => datetime_convert('UTC','UTC','now',ATOM_TIME),
 			'language' => $user_info['language'],
-			'logo'	=> $a->get_baseurl()."/images/friendica-32.png",
+			'logo'	=> App::get_baseurl()."/images/friendica-32.png",
 		);
 
 		return $arr;
@@ -642,7 +644,7 @@
 			'verified' => true,
 			'statusnet_blocking' => false,
 			'notifications' => false,
-			//'statusnet_profile_url' => $a->get_baseurl()."/contacts/".$uinfo[0]['cid'],
+			//'statusnet_profile_url' => App::get_baseurl()."/contacts/".$uinfo[0]['cid'],
 			'statusnet_profile_url' => $uinfo[0]['url'],
 			'uid' => intval($uinfo[0]['uid']),
 			'cid' => intval($uinfo[0]['cid']),
@@ -806,7 +808,10 @@
 	 * returns a 401 status code and an error message if not.
 	 * http://developer.twitter.com/doc/get/account/verify_credentials
 	 */
-	function api_account_verify_credentials(&$a, $type){
+	function api_account_verify_credentials($type){
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		unset($_REQUEST["user_id"]);
@@ -824,7 +829,7 @@
 
 		// - Adding last status
 		if (!$skip_status) {
-			$user_info["status"] = api_status_show($a,"raw");
+			$user_info["status"] = api_status_show("raw");
 			if (!count($user_info["status"]))
 				unset($user_info["status"]);
 			else
@@ -855,7 +860,10 @@
 	}
 
 /*Waitman Gobble Mod*/
-	function api_statuses_mediap(&$a, $type) {
+	function api_statuses_mediap($type) {
+
+		$a = get_app();
+
 		if (api_user()===false) {
 			logger('api_statuses_update: no user');
 			throw new ForbiddenException();
@@ -888,13 +896,16 @@
 		item_post($a);
 
 		// this should output the last post (the one we just posted).
-		return api_status_show($a,$type);
+		return api_status_show($type);
 	}
 	api_register_func('api/statuses/mediap','api_statuses_mediap', true, API_METHOD_POST);
 /*Waitman Gobble Mod*/
 
 
-	function api_statuses_update(&$a, $type) {
+	function api_statuses_update($type) {
+
+		$a = get_app();
+
 		if (api_user()===false) {
 			logger('api_statuses_update: no user');
 			throw new ForbiddenException();
@@ -959,7 +970,7 @@
 
 				if ($posts_day > $throttle_day) {
 					logger('Daily posting limit reached for user '.api_user(), LOGGER_DEBUG);
-					#die(api_error($a, $type, sprintf(t("Daily posting limit of %d posts reached. The post was rejected."), $throttle_day)));
+					#die(api_error($type, sprintf(t("Daily posting limit of %d posts reached. The post was rejected."), $throttle_day)));
 					throw new TooManyRequestsException(sprintf(t("Daily posting limit of %d posts reached. The post was rejected."), $throttle_day));
 				}
 			}
@@ -979,7 +990,7 @@
 
 				if ($posts_week > $throttle_week) {
 					logger('Weekly posting limit reached for user '.api_user(), LOGGER_DEBUG);
-					#die(api_error($a, $type, sprintf(t("Weekly posting limit of %d posts reached. The post was rejected."), $throttle_week)));
+					#die(api_error($type, sprintf(t("Weekly posting limit of %d posts reached. The post was rejected."), $throttle_week)));
 					throw new TooManyRequestsException(sprintf(t("Weekly posting limit of %d posts reached. The post was rejected."), $throttle_week));
 
 				}
@@ -1000,7 +1011,7 @@
 
 				if ($posts_month > $throttle_month) {
 					logger('Monthly posting limit reached for user '.api_user(), LOGGER_DEBUG);
-					#die(api_error($a, $type, sprintf(t("Monthly posting limit of %d posts reached. The post was rejected."), $throttle_month)));
+					#die(api_error($type, sprintf(t("Monthly posting limit of %d posts reached. The post was rejected."), $throttle_month)));
 					throw new TooManyRequestsException(sprintf(t("Monthly posting limit of %d posts reached. The post was rejected."), $throttle_month));
 				}
 			}
@@ -1023,8 +1034,8 @@
 			if ($r) {
 				$phototypes = Photo::supportedTypes();
 				$ext = $phototypes[$r[0]['type']];
-				$_REQUEST['body'] .= "\n\n".'[url='.$a->get_baseurl().'/photos/'.$r[0]['nickname'].'/image/'.$r[0]['resource-id'].']';
-				$_REQUEST['body'] .= '[img]'.$a->get_baseurl()."/photo/".$r[0]['resource-id']."-".$r[0]['scale'].".".$ext."[/img][/url]";
+				$_REQUEST['body'] .= "\n\n".'[url='.App::get_baseurl().'/photos/'.$r[0]['nickname'].'/image/'.$r[0]['resource-id'].']';
+				$_REQUEST['body'] .= '[img]'.App::get_baseurl()."/photo/".$r[0]['resource-id']."-".$r[0]['scale'].".".$ext."[/img][/url]";
 			}
 		}
 
@@ -1040,13 +1051,16 @@
 		item_post($a);
 
 		// this should output the last post (the one we just posted).
-		return api_status_show($a,$type);
+		return api_status_show($type);
 	}
 	api_register_func('api/statuses/update','api_statuses_update', true, API_METHOD_POST);
 	api_register_func('api/statuses/update_with_media','api_statuses_update', true, API_METHOD_POST);
 
 
-	function api_media_upload(&$a, $type) {
+	function api_media_upload($type) {
+
+		$a = get_app();
+
 		if (api_user()===false) {
 			logger('no user');
 			throw new ForbiddenException();
@@ -1079,7 +1093,10 @@
 	}
 	api_register_func('api/media/upload','api_media_upload', true, API_METHOD_POST);
 
-	function api_status_show(&$a, $type){
+	function api_status_show($type){
+
+		$a = get_app();
+
 		$user_info = api_get_user($a);
 
 		logger('api_status_show: user_info: '.print_r($user_info, true), LOGGER_DEBUG);
@@ -1210,7 +1227,10 @@
 	 * The author's most recent status will be returned inline.
 	 * http://developer.twitter.com/doc/get/users/show
 	 */
-	function api_users_show(&$a, $type){
+	function api_users_show($type){
+
+		$a = get_app();
+
 		$user_info = api_get_user($a);
 		$lastwall = q("SELECT `item`.*
 				FROM `item`
@@ -1305,7 +1325,10 @@
 	api_register_func('api/users/show','api_users_show');
 
 
-	function api_users_search(&$a, $type) {
+	function api_users_search($type) {
+
+		$a = get_app();
+
 		$page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
 
 		$userlist = array();
@@ -1344,7 +1367,10 @@
 	 * TODO: Optional parameters
 	 * TODO: Add reply info
 	 */
-	function api_statuses_home_timeline(&$a, $type){
+	function api_statuses_home_timeline($type){
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		unset($_REQUEST["user_id"]);
@@ -1424,7 +1450,10 @@
 	api_register_func('api/statuses/home_timeline','api_statuses_home_timeline', true);
 	api_register_func('api/statuses/friends_timeline','api_statuses_home_timeline', true);
 
-	function api_statuses_public_timeline(&$a, $type){
+	function api_statuses_public_timeline($type){
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		$user_info = api_get_user($a);
@@ -1490,7 +1519,10 @@
 	/**
 	 *
 	 */
-	function api_statuses_show(&$a, $type){
+	function api_statuses_show($type){
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		$user_info = api_get_user($a);
@@ -1550,7 +1582,10 @@
 	/**
 	 *
 	 */
-	function api_conversation_show(&$a, $type){
+	function api_conversation_show($type){
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		$user_info = api_get_user($a);
@@ -1621,9 +1656,11 @@
 	/**
 	 *
 	 */
-	function api_statuses_repeat(&$a, $type){
+	function api_statuses_repeat($type){
 		global $called_api;
 
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		$user_info = api_get_user($a);
@@ -1683,14 +1720,17 @@
 
 		// this should output the last post (the one we just posted).
 		$called_api = null;
-		return(api_status_show($a,$type));
+		return(api_status_show($type));
 	}
 	api_register_func('api/statuses/retweet','api_statuses_repeat', true, API_METHOD_POST);
 
 	/**
 	 *
 	 */
-	function api_statuses_destroy(&$a, $type){
+	function api_statuses_destroy($type){
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		$user_info = api_get_user($a);
@@ -1707,7 +1747,7 @@
 
 		logger('API: api_statuses_destroy: '.$id);
 
-		$ret = api_statuses_show($a, $type);
+		$ret = api_statuses_show($type);
 
 		drop_item($id, false);
 
@@ -1720,7 +1760,10 @@
 	 * http://developer.twitter.com/doc/get/statuses/mentions
 	 *
 	 */
-	function api_statuses_mentions(&$a, $type){
+	function api_statuses_mentions($type){
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		unset($_REQUEST["user_id"]);
@@ -1744,7 +1787,7 @@
 		$start = $page*$count;
 
 		// Ugly code - should be changed
-		$myurl = $a->get_baseurl() . '/profile/'. $a->user['nickname'];
+		$myurl = App::get_baseurl() . '/profile/'. $a->user['nickname'];
 		$myurl = substr($myurl,strpos($myurl,'://')+3);
 		//$myurl = str_replace(array('www.','.'),array('','\\.'),$myurl);
 		$myurl = str_replace('www.','',$myurl);
@@ -1793,7 +1836,10 @@
 	api_register_func('api/statuses/replies','api_statuses_mentions', true);
 
 
-	function api_statuses_user_timeline(&$a, $type){
+	function api_statuses_user_timeline($type){
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		$user_info = api_get_user($a);
@@ -1864,7 +1910,10 @@
 	 *
 	 * api v1 : https://web.archive.org/web/20131019055350/https://dev.twitter.com/docs/api/1/post/favorites/create/%3Aid
 	 */
-	function api_favorites_create_destroy(&$a, $type){
+	function api_favorites_create_destroy($type){
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		// for versioned api.
@@ -1907,7 +1956,7 @@
 
 
 		$user_info = api_get_user($a);
-		$rets = api_format_items($item,$user_info, false, $type);
+		$rets = api_format_items($item, $user_info, false, $type);
 		$ret = $rets[0];
 
 		$data = array('status' => $ret);
@@ -1922,9 +1971,11 @@
 	api_register_func('api/favorites/create', 'api_favorites_create_destroy', true, API_METHOD_POST);
 	api_register_func('api/favorites/destroy', 'api_favorites_create_destroy', true, API_METHOD_DELETE);
 
-	function api_favorites(&$a, $type){
+	function api_favorites($type){
 		global $called_api;
 
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		$called_api= array();
@@ -2255,11 +2306,10 @@
 		return($entities);
 	}
 	function api_format_items_embeded_images(&$item, $text){
-		$a = get_app();
 		$text = preg_replace_callback(
 				"|data:image/([^;]+)[^=]+=*|m",
-				function($match) use ($a, $item) {
-					return $a->get_baseurl()."/display/".$item['guid'];
+				function($match) use ($item) {
+					return App::get_baseurl()."/display/".$item['guid'];
 				},
 				$text);
 		return $text;
@@ -2343,6 +2393,7 @@
 	function api_format_items($r,$user_info, $filter_user = false, $type = "json") {
 
 		$a = get_app();
+
 		$ret = Array();
 
 		foreach($r as $item) {
@@ -2483,7 +2534,7 @@
 	}
 
 
-	function api_account_rate_limit_status(&$a,$type) {
+	function api_account_rate_limit_status($type) {
 
 		if ($type == "xml")
 			$hash = array(
@@ -2508,7 +2559,7 @@
 	}
 	api_register_func('api/account/rate_limit_status','api_account_rate_limit_status',true);
 
-	function api_help_test(&$a,$type) {
+	function api_help_test($type) {
 		if ($type == 'xml')
 			$ok = "true";
 		else
@@ -2518,13 +2569,13 @@
 	}
 	api_register_func('api/help/test','api_help_test',false);
 
-	function api_lists(&$a,$type) {
+	function api_lists($type) {
 		$ret = array();
 		return api_format_data('lists', $type, array("lists_list" => $ret));
 	}
 	api_register_func('api/lists','api_lists',true);
 
-	function api_lists_list(&$a,$type) {
+	function api_lists_list($type) {
 		$ret = array();
 		return api_format_data('lists', $type, array("lists_list" => $ret));
 	}
@@ -2535,7 +2586,10 @@
 	 *  This function is deprecated by Twitter
 	 *  returns: json, xml
 	 **/
-	function api_statuses_f(&$a, $type, $qtype) {
+	function api_statuses_f($type, $qtype) {
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 		$user_info = api_get_user($a);
 
@@ -2577,13 +2631,13 @@
 		return array('user' => $ret);
 
 	}
-	function api_statuses_friends(&$a, $type){
-		$data =  api_statuses_f($a,$type,"friends");
+	function api_statuses_friends($type){
+		$data =  api_statuses_f($type, "friends");
 		if ($data===false) return false;
 		return  api_format_data("users", $type, $data);
 	}
-	function api_statuses_followers(&$a, $type){
-		$data = api_statuses_f($a,$type,"followers");
+	function api_statuses_followers($type){
+		$data = api_statuses_f($type, "followers");
 		if ($data===false) return false;
 		return  api_format_data("users", $type, $data);
 	}
@@ -2595,10 +2649,13 @@
 
 
 
-	function api_statusnet_config(&$a,$type) {
+	function api_statusnet_config($type) {
+
+		$a = get_app();
+
 		$name = $a->config['sitename'];
 		$server = $a->get_hostname();
-		$logo = $a->get_baseurl() . '/images/friendica-64.png';
+		$logo = App::get_baseurl() . '/images/friendica-64.png';
 		$email = $a->config['admin_email'];
 		$closed = (($a->config['register_policy'] == REGISTER_CLOSED) ? 'true' : 'false');
 		$private = (($a->config['system']['block_public']) ? 'true' : 'false');
@@ -2606,7 +2663,7 @@
 		if($a->config['api_import_size'])
 			$texlimit = string($a->config['api_import_size']);
 		$ssl = (($a->config['system']['have_ssl']) ? 'true' : 'false');
-		$sslserver = (($ssl === 'true') ? str_replace('http:','https:',$a->get_baseurl()) : '');
+		$sslserver = (($ssl === 'true') ? str_replace('http:','https:',App::get_baseurl()) : '');
 
 		$config = array(
 			'site' => array('name' => $name,'server' => $server, 'theme' => 'default', 'path' => '',
@@ -2628,7 +2685,7 @@
 	}
 	api_register_func('api/statusnet/config','api_statusnet_config',false);
 
-	function api_statusnet_version(&$a,$type) {
+	function api_statusnet_version($type) {
 		// liar
 		$fake_statusnet_version = "0.9.7";
 
@@ -2639,7 +2696,10 @@
 	/**
 	 * @todo use api_format_data() to return data
 	 */
-	function api_ff_ids(&$a,$type,$qtype) {
+	function api_ff_ids($type,$qtype) {
+
+		$a = get_app();
+
 		if(! api_user()) throw new ForbiddenException();
 
 		$user_info = api_get_user($a);
@@ -2671,17 +2731,20 @@
 		return api_format_data("ids", $type, array('id' => $ids));
 	}
 
-	function api_friends_ids(&$a,$type) {
-		return api_ff_ids($a,$type,'friends');
+	function api_friends_ids($type) {
+		return api_ff_ids($type,'friends');
 	}
-	function api_followers_ids(&$a,$type) {
-		return api_ff_ids($a,$type,'followers');
+	function api_followers_ids($type) {
+		return api_ff_ids($type,'followers');
 	}
 	api_register_func('api/friends/ids','api_friends_ids',true);
 	api_register_func('api/followers/ids','api_followers_ids',true);
 
 
-	function api_direct_messages_new(&$a, $type) {
+	function api_direct_messages_new($type) {
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		if (!x($_POST, "text") OR (!x($_POST,"screen_name") AND !x($_POST,"user_id"))) return;
@@ -2741,7 +2804,10 @@
 	}
 	api_register_func('api/direct_messages/new','api_direct_messages_new',true, API_METHOD_POST);
 
-	function api_direct_messages_box(&$a, $type, $box) {
+	function api_direct_messages_box($type, $box) {
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		// params
@@ -2763,7 +2829,6 @@
 		unset($_GET["screen_name"]);
 
 		$user_info = api_get_user($a);
-		//$profile_url = $a->get_baseurl() . '/profile/' . $a->user['nickname'];
 		$profile_url = $user_info["url"];
 
 
@@ -2827,17 +2892,17 @@
 
 	}
 
-	function api_direct_messages_sentbox(&$a, $type){
-		return api_direct_messages_box($a, $type, "sentbox");
+	function api_direct_messages_sentbox($type){
+		return api_direct_messages_box($type, "sentbox");
 	}
-	function api_direct_messages_inbox(&$a, $type){
-		return api_direct_messages_box($a, $type, "inbox");
+	function api_direct_messages_inbox($type){
+		return api_direct_messages_box($type, "inbox");
 	}
-	function api_direct_messages_all(&$a, $type){
-		return api_direct_messages_box($a, $type, "all");
+	function api_direct_messages_all($type){
+		return api_direct_messages_box($type, "all");
 	}
-	function api_direct_messages_conversation(&$a, $type){
-		return api_direct_messages_box($a, $type, "conversation");
+	function api_direct_messages_conversation($type){
+		return api_direct_messages_box($type, "conversation");
 	}
 	api_register_func('api/direct_messages/conversation','api_direct_messages_conversation',true);
 	api_register_func('api/direct_messages/all','api_direct_messages_all',true);
@@ -2846,7 +2911,7 @@
 
 
 
-	function api_oauth_request_token(&$a, $type){
+	function api_oauth_request_token($type){
 		try{
 			$oauth = new FKOAuth1();
 			$r = $oauth->fetch_request_token(OAuthRequest::from_request());
@@ -2856,7 +2921,7 @@
 		echo $r;
 		killme();
 	}
-	function api_oauth_access_token(&$a, $type){
+	function api_oauth_access_token($type){
 		try{
 			$oauth = new FKOAuth1();
 			$r = $oauth->fetch_access_token(OAuthRequest::from_request());
@@ -2871,7 +2936,7 @@
 	api_register_func('api/oauth/access_token', 'api_oauth_access_token', false);
 
 
-	function api_fr_photos_list(&$a,$type) {
+	function api_fr_photos_list($type) {
 		if (api_user()===false) throw new ForbiddenException();
 		$r = q("select `resource-id`, max(scale) as scale, album, filename, type from photo
 				where uid = %d and album != 'Contact Photos' group by `resource-id`",
@@ -2890,7 +2955,7 @@
 				$photo['album'] = $rr['album'];
 				$photo['filename'] = $rr['filename'];
 				$photo['type'] = $rr['type'];
-				$thumb = $a->get_baseurl()."/photo/".$rr['resource-id']."-".$rr['scale'].".".$typetoext[$rr['type']];
+				$thumb = App::get_baseurl()."/photo/".$rr['resource-id']."-".$rr['scale'].".".$typetoext[$rr['type']];
 
 				if ($type == "xml")
 					$data['photo'][] = array("@attributes" => $photo, "1" => $thumb);
@@ -2903,7 +2968,7 @@
 		return  api_format_data("photos", $type, $data);
 	}
 
-	function api_fr_photo_detail(&$a,$type) {
+	function api_fr_photo_detail($type) {
 		if (api_user()===false) throw new ForbiddenException();
 		if(!x($_REQUEST,'photo_id')) throw new BadRequestException("No photo id.");
 
@@ -2939,11 +3004,11 @@
 				for ($k=intval($data['photo']['minscale']); $k<=intval($data['photo']['maxscale']); $k++)
 					$data['photo']['links'][$k.":link"]["@attributes"] = array("type" => $data['photo']['type'],
 											"scale" => $k,
-											"href" => $a->get_baseurl()."/photo/".$data['photo']['resource-id']."-".$k.".".$typetoext[$data['photo']['type']]);
+											"href" => App::get_baseurl()."/photo/".$data['photo']['resource-id']."-".$k.".".$typetoext[$data['photo']['type']]);
 			} else {
 				$data['photo']['link'] = array();
 				for ($k=intval($data['photo']['minscale']); $k<=intval($data['photo']['maxscale']); $k++) {
-					$data['photo']['link'][$k] = $a->get_baseurl()."/photo/".$data['photo']['resource-id']."-".$k.".".$typetoext[$data['photo']['type']];
+					$data['photo']['link'][$k] = App::get_baseurl()."/photo/".$data['photo']['resource-id']."-".$k.".".$typetoext[$data['photo']['type']];
 				}
 			}
 			unset($data['photo']['resource-id']);
@@ -2973,7 +3038,7 @@
 	 * 		c_url: url of remote contact to auth to
 	 * 		url: string, url to redirect after auth
 	 */
-	function api_friendica_remoteauth(&$a) {
+	function api_friendica_remoteauth() {
 		$url = ((x($_GET,'url')) ? $_GET['url'] : '');
 		$c_url = ((x($_GET,'c_url')) ? $_GET['c_url'] : '');
 
@@ -3270,7 +3335,10 @@
 	}
 
 	// return all or a specified group of the user with the containing contacts
-	function api_friendica_group_show(&$a, $type) {
+	function api_friendica_group_show($type) {
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		// params
@@ -3318,7 +3386,10 @@
 
 
 	// delete the specified group of the user
-	function api_friendica_group_delete(&$a, $type) {
+	function api_friendica_group_delete($type) {
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		// params
@@ -3362,7 +3433,10 @@
 
 
 	// create the specified group with the posted array of contacts
-	function api_friendica_group_create(&$a, $type) {
+	function api_friendica_group_create($type) {
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		// params
@@ -3425,7 +3499,10 @@
 
 
 	// update the specified group with the posted array of contacts
-	function api_friendica_group_update(&$a, $type) {
+	function api_friendica_group_update($type) {
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 
 		// params
@@ -3481,7 +3558,10 @@
 	api_register_func('api/friendica/group_update', 'api_friendica_group_update', true, API_METHOD_POST);
 
 
-	function api_friendica_activity(&$a, $type) {
+	function api_friendica_activity($type) {
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 		$verb = strtolower($a->argv[3]);
 		$verb = preg_replace("|\..*$|", "", $verb);
@@ -3515,11 +3595,13 @@
 	/**
 	 * @brief Returns notifications
 	 *
-	 * @param App $a
 	 * @param string $type Known types are 'atom', 'rss', 'xml' and 'json'
 	 * @return string
 	*/
-	function api_friendica_notification(&$a, $type) {
+	function api_friendica_notification($type) {
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 		if ($a->argc!==3) throw new BadRequestException("Invalid argument count");
 		$nm = new NotificationsManager();
@@ -3542,11 +3624,13 @@
 	 *
 	 * POST request with 'id' param as notification id
 	 *
-	 * @param App $a
 	 * @param string $type Known types are 'atom', 'rss', 'xml' and 'json'
 	 * @return string
 	 */
-	function api_friendica_notification_seen(&$a, $type){
+	function api_friendica_notification_seen($type){
+
+		$a = get_app();
+
 		if (api_user()===false) throw new ForbiddenException();
 		if ($a->argc!==4) throw new BadRequestException("Invalid argument count");