<?php

/* ======================================================================== \
| 	DOCEBO - The E-Learning Suite											|
| 																			|
| 	Copyright (c) 2008 (Docebo)												|
| 	http://www.docebo.com													|
|   License 	http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt		|
\ ======================================================================== */

define("CORE", true);
define("IN_DOCEBO", true);
define("_deeppath_", '../');
require(dirname(__FILE__).'/../base.php');

// start buffer
ob_start();

// initialize
require(_base_.'/lib/lib.bootstrap.php');
Boot::init(BOOT_DATETIME);

// -----------------------------------------------------------------------------

require_once(_base_.'/api/lib/lib.api.php');

$GLOBALS['output'] = '';
function rest_cout($string) { $GLOBALS['output'] .= $string; }


//----- functions and utils ----------------------------------------------------

require_once(_base_.'/api/lib/lib.rest.php');

//utils function
define('_XML_VERSION', '1.0');
define('_XML_ENCODING', 'UTF-8');
define('_GENERIC_ELEMENT', 'element');

function getXML($arr) {
	$output='';

	function _getopentag($tagkey) {
		$output  = '<';
		if (is_numeric($tagkey)) $output.=_GENERIC_ELEMENT; else $output.=$tagkey;
		$output .= '>';
		return $output;
	}

	function _getclosetag($tagkey) {
		$output  = '</';
		if (is_numeric($tagkey)) $output.=_GENERIC_ELEMENT; else $output.=$tagkey;
		$output .= '>';
		return $output;
	}

	function _getstringval(&$value) {
		$output='';
		if (is_bool($value)) {
			switch ($value) {
				case true:  $output.='true';  break;
				case false: $output.='false'; break;
			}
		} else {
			$output.=$value;
		}
		return $output;
	}

	function _convert(&$out, &$data) {
		if (!is_array($data)) return;
		foreach ($data as $key=>$val) {
			$out.=_getopentag($key);//'<'.$key.'>';
			if (is_array($val))
				_convert($out, $val);
			else
				$out.=_getstringval($val);
			$out.=_getclosetag($key);//'</'.$key.'>';
		}
	}

	if (is_array($arr)) {
		$output.='<?xml version="'._XML_VERSION.'" encoding="'._XML_ENCODING.'"?>';
		$output.='<XMLoutput>';
		_convert($output, $arr);
		$output.='</XMLoutput>';
	}
	return $output;
}



/**
 * Error handling
 * @param <string> $error error message to print
 * @param <type> $type error output type
 * @return <type>
 */
function restAPI_HandleError($error=_REST_STANDARD_ERROR, $type=_REST_OUTPUT_XML) {

	$output = '';
	$temp = array('error'=>$error);
	switch ($type) {
		case _REST_OUTPUT_XML:  {	$output .= getXML($temp); } break;
		case _REST_OUTPUT_JSON: {
			$json = new Services_JSON();
			$output .= $json->encode($temp);
		} break;
		default: {
			// handler doesn't know how to format the output, so send raw string
			$output .= $error;
		} break;
	}
	return $output;
}


/**
 * Debug information handling, it's used only in developement context
 * @param <string> $message debug message
 * @param <string> $type output type to use
 * @return <string> formatted error message
 */
function restAPI_HandleDebugInfo($message, $type=_REST_OUTPUT_XML) {

	$output = '';
	$f_msg = $message;
	$temp = array('debug'=>$f_msg);
	switch ($type) {
		case _REST_OUTPUT_XML: { $output .= getXML($temp); } break;
		case _REST_OUTPUT_JSON: {
			$json = new Services_JSON();
			$output .= $json->encode($temp);
		} break;
		default: $output .= $message; break; //handler doesn't know how to format the output, so send raw string
	}
	return $output;
}




 function restAPI_HandleOutput(&$arr, $type=_REST_OUTPUT_XML) {
	$output = '';
	switch ($type) {
		case _REST_OUTPUT_XML: {
			$output .= getXML($arr);
		} break;

		case _REST_OUTPUT_JSON: {
			$json = new Services_JSON();
			$output .= $json->encode($arr);
		} break;

		default: {
			$output .= '<error>Invalid type setting.</error>';
		}
	}
	return $output;
}

//------------------------------------------------------------------------------

//read output

if(!isset($_GET[_REST_PARAM_NAME])) { die('Error: no input parameters.'); }

$rest_method = $_SERVER['REQUEST_METHOD'];
$rest_params = explode('/', $_GET[_REST_PARAM_NAME]);
$numparams = count( $rest_params );
if ($numparams < _REST_MINIMUM_PARAMS) { die('Error: not enough input parameters.'); }
$last_index = $numparams-1;

// check if this is a valid call
if ($rest_params[0]!='' || $rest_params[1]!=_REST_VALIDATOR_PARAM) { die('Error: Invalid request.'); }

// you may force a different REQUEST_METHOD
$matches = array();
if (preg_match('/^(.*)!(DELETE|PUT|GET|POST|OPTIONS|HEAD|TRACE|CONNECT)$/', $rest_params[$last_index], $matches)) {
	//if ($rest_method == 'POST' && preg_match('/^(.*)!(DELETE|PUT|GET|POST|OPTIONS|HEAD|TRACE|CONNECT)$/', $rest_params[$last_index], $matches)) {
	$rest_params[$last_index] = $matches[1];
	if ($rest_method == 'POST') {
		//$rest_params[$last_index] = $matches[1];
		$rest_method = $matches[2];
	}
}

// set the output data type (XML or JSON for now)
$GLOBALS['REST_API_ACCEPT']='';
$matches = array();
if (preg_match('/^(.*)\.(xml|json)$/', $rest_params[$last_index], $matches)) {
	$rest_params[$last_index] = $matches[1];
	$GLOBALS['REST_API_ACCEPT'] = $matches[2];
} else {
	$GLOBALS['REST_API_ACCEPT'] = 'xml';
}

//set MIME type
$content_type = '';
switch ($GLOBALS['REST_API_ACCEPT']) {
	case _REST_OUTPUT_JSON: { $content_type = 'application/json'; } break;
	case _REST_OUTPUT_XML:  { $content_type = 'application/xml';  } break;
	default: {
		$GLOBALS['REST_API_ACCEPT'] = _REST_OUTPUT_XML;
		$content_type = 'application/xml';
	} break;
}
header('Content-type:'.$content_type.'; charset=utf-8');

$rest_obj		= false;
$rest_module	= $rest_params[_REST_APINAME_INDEX]; //the module specification
$rest_function	= $rest_params[_REST_APIMETHOD_INDEX]; //the name of module's method to call

// extract additional parameters from GET string, void and outputtype parameter should be already avoided
$i = _REST_APIMETHOD_INDEX + 1;
$rest_subparams = array();
while ($i<count($rest_params)) {//$numparams) {
	$rest_subparams[] = $rest_params[$i];
	$i++;
}

$auth_code = Get::req('auth', DOTY_STRING, false); //code provided by the user in the request

$res = API_Execute($auth_code, $rest_module, $rest_function, $rest_subparams);

if (!$res['success']) {
	$err_msg = $res['message'];
	rest_cout(restAPI_HandleError($err_msg, $GLOBALS['REST_API_ACCEPT']));
} else {
	rest_cout(restAPI_HandleOutput($res, $GLOBALS['REST_API_ACCEPT']));
}

// -----------------------------------------------------------------------------

// finalize
Boot::finalize();

//clear debug messages and clean buffer for output
$debug = ob_get_contents();
ob_clean();

echo $GLOBALS['output'];

// flush buffer
ob_end_flush();

?>