summaryrefslogtreecommitdiffstats
path: root/lib/api.php
blob: 515bab6714e042d1d69b70ff77161568254dd815 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<?php
/**
* ownCloud
*
* @author Tom Needham
* @author Michael Gapczynski
* @author Bart Visscher
* @copyright 2012 Tom Needham tom@owncloud.com
* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
* @copyright 2012 Bart Visscher bartv@thisnet.nl
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
*
*/
	
class OC_API {
	
	/**
	* api actions
	*/
	protected static $actions = array();
	
	/**
	* registers an api call
	* @param string $method the http method
	* @param string $url the url to match
	* @param callable $action the function to run
	* @param string $app the id of the app registering the call
	*/
	public static function register($method, $url, $action, $app){
		$name = strtolower($method).$url;
		$name = str_replace(array('/', '{', '}'), '_', $name);
		if(!isset(self::$actions[$name])){
			OC::$router->create($name, $url.'.{_format}')
				->defaults(array('_format' => 'xml'))
				->requirements(array('_format' => 'xml|json'))
				->action('OC_API', 'call');
			self::$actions[$name] = array();
		}
		self::$actions[$name][] = array('app' => $app, 'action' => $action);
	}
	
	/**
	* handles an api call
	* @param array $parameters
	*/
	public static function call($parameters){
		$name = $parameters['_route'];
		// Loop through registered actions
		foreach(self::$actions[$name] as $action){
			$app = $action['app'];
			if(is_callable($action['action'])){
				$responses[] = array('app' => $app, 'response' => call_user_func($action['action'], $parameters));
			} else {
				$responses[] = array('app' => $app, 'response' => 501);
			}
		}
		// Merge the responses
		$response = self::mergeResponses($responses);
		// Send the response
		if(isset($parameters['_format'])){
			self::respond($response, $parameters['_format']);
		} else {
			self::respond($response);
		}
	}
	
	/**
	 * intelligently merges the different responses
	 * @param array $responses
	 * @return array the final merged response
	 */
	private static function mergeResponses($responses){
		$finalresponse = array();
		$numresponses = count($responses);
		
		foreach($responses as $response){
			if(is_int($response) && empty($finalresponse)){
				$finalresponse = $response;
				continue;
			}
			if(is_array($response)){
				// Shipped apps win
				if(OC_App::isShipped($response['app'])){
					$finalresponse = array_merge_recursive($finalresponse, $response);
				} else {
					$finalresponse = array_merge_recursive($response, $finalresponse);
				}
			}
		}

		return $finalresponse;
	}
	
	/**
	* respond to a call
	* @param int|array $response the response
	* @param string $format the format xml|json
	*/
	private static function respond($response, $format='json'){
		if ($format == 'json') {
			echo json_encode($response);
		} else if ($format == 'xml') {
			// TODO array to xml
		} else {
			var_dump($format, $response);
		}
	}
	
}