mirror of
				https://github.com/pierre42100/ComunicAPI
				synced 2025-10-31 02:04:53 +00:00 
			
		
		
		
	Implemented RestServer controller
This commit is contained in:
		
							
								
								
									
										1
									
								
								3rdparty/.htaccess
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								3rdparty/.htaccess
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1 @@ | ||||
| Deny from all | ||||
							
								
								
									
										36
									
								
								3rdparty/RestServer/RestException.php
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										36
									
								
								3rdparty/RestServer/RestException.php
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| <?php | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // | ||||
| // Copyright (c) 2009 Jacob Wright | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
| // | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| namespace Jacwright\RestServer; | ||||
|  | ||||
| use Exception; | ||||
|  | ||||
| class RestException extends Exception | ||||
| { | ||||
|     public function __construct($code, $message = null) | ||||
|     { | ||||
|         parent::__construct($message, $code); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										46
									
								
								3rdparty/RestServer/RestFormat.php
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										46
									
								
								3rdparty/RestServer/RestFormat.php
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| <?php | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // | ||||
| // Copyright (c) 2009 Jacob Wright | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
| // | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| namespace Jacwright\RestServer; | ||||
|  | ||||
| /** | ||||
|  * Constants used in RestServer Class. | ||||
|  */ | ||||
| class RestFormat | ||||
| { | ||||
| 	const PLAIN = 'text/plain'; | ||||
| 	const HTML  = 'text/html'; | ||||
| 	const JSON  = 'application/json'; | ||||
| 	const XML   = 'application/xml'; | ||||
|  | ||||
|     /** @var array */ | ||||
| 	static public $formats = array( | ||||
| 		'plain' => RestFormat::PLAIN, | ||||
| 		'txt'   => RestFormat::PLAIN, | ||||
| 		'html'  => RestFormat::HTML, | ||||
| 		'json'  => RestFormat::JSON, | ||||
| 		'xml'   => RestFormat::XML, | ||||
| 	); | ||||
| } | ||||
							
								
								
									
										526
									
								
								3rdparty/RestServer/RestServer.php
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										526
									
								
								3rdparty/RestServer/RestServer.php
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,526 @@ | ||||
| <?php | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // | ||||
| // Copyright (c) 2009 Jacob Wright | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
| // | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| namespace Jacwright\RestServer; | ||||
|  | ||||
| require(__DIR__ . '/RestFormat.php'); | ||||
| require(__DIR__ . '/RestException.php'); | ||||
|  | ||||
| use Exception; | ||||
| use ReflectionClass; | ||||
| use ReflectionObject; | ||||
| use ReflectionMethod; | ||||
| use DOMDocument; | ||||
|  | ||||
| /** | ||||
|  * Description of RestServer | ||||
|  * | ||||
|  * @author jacob | ||||
|  */ | ||||
| class RestServer | ||||
| { | ||||
| 	//@todo add type hint | ||||
| 	public $url; | ||||
| 	public $method; | ||||
| 	public $params; | ||||
| 	public $format; | ||||
| 	public $cacheDir = __DIR__; | ||||
| 	public $realm; | ||||
| 	public $mode; | ||||
| 	public $root; | ||||
| 	public $rootPath; | ||||
| 	public $jsonAssoc = false; | ||||
|  | ||||
| 	protected $map = array(); | ||||
| 	protected $errorClasses = array(); | ||||
| 	protected $cached; | ||||
|  | ||||
| 	/** | ||||
| 	 * The constructor. | ||||
| 	 * | ||||
| 	 * @param string $mode The mode, either debug or production | ||||
| 	 */ | ||||
| 	public function  __construct($mode = 'debug', $realm = 'Rest Server') | ||||
| 	{ | ||||
| 		$this->mode = $mode; | ||||
| 		$this->realm = $realm; | ||||
| 		// Set the root | ||||
| 		$dir = str_replace('\\', '/', dirname(str_replace($_SERVER['DOCUMENT_ROOT'], '', $_SERVER['SCRIPT_FILENAME']))); | ||||
| 		if ($dir == '.') { | ||||
| 			$dir = '/'; | ||||
| 		} else { | ||||
| 			// add a slash at the beginning and end | ||||
| 			if (substr($dir, -1) != '/') $dir .= '/'; | ||||
| 			if (substr($dir, 0, 1) != '/') $dir = '/' . $dir; | ||||
| 		} | ||||
| 		$this->root = $dir; | ||||
| 	} | ||||
|  | ||||
| 	public function  __destruct() | ||||
| 	{ | ||||
| 		if ($this->mode == 'production' && !$this->cached) { | ||||
| 			if (function_exists('apc_store')) { | ||||
| 				apc_store('urlMap', $this->map); | ||||
| 			} else { | ||||
| 				file_put_contents($this->cacheDir . '/urlMap.cache', serialize($this->map)); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public function refreshCache() | ||||
| 	{ | ||||
| 		$this->map = array(); | ||||
| 		$this->cached = false; | ||||
| 	} | ||||
|  | ||||
| 	public function unauthorized($ask = false) | ||||
| 	{ | ||||
| 		if ($ask) { | ||||
| 			header("WWW-Authenticate: Basic realm=\"$this->realm\""); | ||||
| 		} | ||||
| 		throw new RestException(401, "You are not authorized to access this resource."); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	public function handle() | ||||
| 	{ | ||||
| 		$this->url = $this->getPath(); | ||||
| 		$this->method = $this->getMethod(); | ||||
| 		$this->format = $this->getFormat(); | ||||
|  | ||||
| 		if ($this->method == 'PUT' || $this->method == 'POST' || $this->method == 'PATCH') { | ||||
| 			$this->data = $this->getData(); | ||||
| 		} | ||||
|  | ||||
| 		list($obj, $method, $params, $this->params, $noAuth) = $this->findUrl(); | ||||
|  | ||||
| 		if ($obj) { | ||||
| 			if (is_string($obj)) { | ||||
| 				if (class_exists($obj)) { | ||||
| 					$obj = new $obj(); | ||||
| 				} else { | ||||
| 					throw new Exception("Class $obj does not exist"); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			$obj->server = $this; | ||||
|  | ||||
| 			try { | ||||
| 				if (method_exists($obj, 'init')) { | ||||
| 					$obj->init(); | ||||
| 				} | ||||
|  | ||||
| 				if (!$noAuth && method_exists($obj, 'authorize')) { | ||||
| 					if (!$obj->authorize()) { | ||||
| 						$this->sendData($this->unauthorized(true)); //@todo unauthorized returns void | ||||
| 						exit; | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 				$result = call_user_func_array(array($obj, $method), $params); | ||||
|  | ||||
| 				if ($result !== null) { | ||||
| 					$this->sendData($result); | ||||
| 				} | ||||
| 			} catch (RestException $e) { | ||||
| 				$this->handleError($e->getCode(), $e->getMessage()); | ||||
| 			} | ||||
|  | ||||
| 		} else { | ||||
| 			$this->handleError(404); | ||||
| 		} | ||||
| 	} | ||||
| 	public function setRootPath($path) | ||||
| 	{ | ||||
| 		$this->rootPath = '/'.trim($path, '/').'/'; | ||||
| 	} | ||||
| 	public function setJsonAssoc($value) | ||||
| 	{ | ||||
| 		$this->jsonAssoc = ($value === true); | ||||
| 	} | ||||
|  | ||||
| 	public function addClass($class, $basePath = '') | ||||
| 	{ | ||||
| 		$this->loadCache(); | ||||
|  | ||||
| 		if (!$this->cached) { | ||||
| 			if (is_string($class) && !class_exists($class)){ | ||||
| 				throw new Exception('Invalid method or class'); | ||||
| 			} elseif (!is_string($class) && !is_object($class)) { | ||||
| 				throw new Exception('Invalid method or class; must be a classname or object'); | ||||
| 			} | ||||
|  | ||||
| 			if (substr($basePath, 0, 1) == '/') { | ||||
| 				$basePath = substr($basePath, 1); | ||||
| 			} | ||||
| 			if ($basePath && substr($basePath, -1) != '/') { | ||||
| 				$basePath .= '/'; | ||||
| 			} | ||||
|  | ||||
| 			$this->generateMap($class, $basePath); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public function addErrorClass($class) | ||||
| 	{ | ||||
| 		$this->errorClasses[] = $class; | ||||
| 	} | ||||
|  | ||||
| 	public function handleError($statusCode, $errorMessage = null) | ||||
| 	{ | ||||
| 		$method = "handle$statusCode"; | ||||
| 		foreach ($this->errorClasses as $class) { | ||||
| 			if (is_object($class)) { | ||||
| 				$reflection = new ReflectionObject($class); | ||||
| 			} elseif (class_exists($class)) { | ||||
| 				$reflection = new ReflectionClass($class); | ||||
| 			} | ||||
|  | ||||
| 			if (isset($reflection)) | ||||
| 			{ | ||||
| 				if ($reflection->hasMethod($method)) | ||||
| 				{ | ||||
| 					$obj = is_string($class) ? new $class() : $class; | ||||
| 					$obj->$method(); | ||||
| 					return; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if (!$errorMessage) | ||||
| 		{ | ||||
| 			$errorMessage = $this->codes[$statusCode]; | ||||
| 		} | ||||
|  | ||||
| 		$this->setStatus($statusCode); | ||||
| 		$this->sendData(array('error' => array('code' => $statusCode, 'message' => $errorMessage))); | ||||
| 	} | ||||
|  | ||||
| 	protected function loadCache() | ||||
| 	{ | ||||
| 		if ($this->cached !== null) { | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		$this->cached = false; | ||||
|  | ||||
| 		if ($this->mode == 'production') { | ||||
| 			if (function_exists('apc_fetch')) { | ||||
| 				$map = apc_fetch('urlMap'); | ||||
| 			} elseif (file_exists($this->cacheDir . '/urlMap.cache')) { | ||||
| 				$map = unserialize(file_get_contents($this->cacheDir . '/urlMap.cache')); | ||||
| 			} | ||||
| 			if (isset($map) && is_array($map)) { | ||||
| 				$this->map = $map; | ||||
| 				$this->cached = true; | ||||
| 			} | ||||
| 		} else { | ||||
| 			if (function_exists('apc_delete')) { | ||||
| 				apc_delete('urlMap'); | ||||
| 			} else { | ||||
| 				@unlink($this->cacheDir . '/urlMap.cache'); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	protected function findUrl() | ||||
| 	{ | ||||
| 		$urls = $this->map[$this->method]; | ||||
| 		if (!$urls) return null; | ||||
|  | ||||
| 		foreach ($urls as $url => $call) { | ||||
| 			$args = $call[2]; | ||||
|  | ||||
| 			if (!strstr($url, '$')) { | ||||
| 				if ($url == $this->url) { | ||||
| 					if (isset($args['data'])) { | ||||
| 						$params = array_fill(0, $args['data'] + 1, null); | ||||
| 						$params[$args['data']] = $this->data;   //@todo data is not a property of this class | ||||
| 						$call[2] = $params; | ||||
| 					} else { | ||||
| 						$call[2] = array(); | ||||
| 					} | ||||
| 					return $call; | ||||
| 				} | ||||
| 			} else { | ||||
| 				$regex = preg_replace('/\\\\\$([\w\d]+)\.\.\./', '(?P<$1>.+)', str_replace('\.\.\.', '...', preg_quote($url))); | ||||
| 				$regex = preg_replace('/\\\\\$([\w\d]+)/', '(?P<$1>[^\/]+)', $regex); | ||||
| 				if (preg_match(":^$regex$:", urldecode($this->url), $matches)) { | ||||
| 					$params = array(); | ||||
| 					$paramMap = array(); | ||||
| 					if (isset($args['data'])) { | ||||
| 						$params[$args['data']] = $this->data; | ||||
| 					} | ||||
|  | ||||
| 					foreach ($matches as $arg => $match) { | ||||
| 						if (is_numeric($arg)) continue; | ||||
| 						$paramMap[$arg] = $match; | ||||
|  | ||||
| 						if (isset($args[$arg])) { | ||||
| 							$params[$args[$arg]] = $match; | ||||
| 						} | ||||
| 					} | ||||
| 					ksort($params); | ||||
| 					// make sure we have all the params we need | ||||
| 					end($params); | ||||
| 					$max = key($params); | ||||
| 					for ($i = 0; $i < $max; $i++) { | ||||
| 						if (!array_key_exists($i, $params)) { | ||||
| 							$params[$i] = null; | ||||
| 						} | ||||
| 					} | ||||
| 					ksort($params); | ||||
| 					$call[2] = $params; | ||||
| 					$call[3] = $paramMap; | ||||
| 					return $call; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	protected function generateMap($class, $basePath) | ||||
| 	{ | ||||
| 		if (is_object($class)) { | ||||
| 			$reflection = new ReflectionObject($class); | ||||
| 		} elseif (class_exists($class)) { | ||||
| 			$reflection = new ReflectionClass($class); | ||||
| 		} | ||||
|  | ||||
| 		$methods = $reflection->getMethods(ReflectionMethod::IS_PUBLIC);    //@todo $reflection might not be instantiated | ||||
|  | ||||
| 		foreach ($methods as $method) { | ||||
| 			$doc = $method->getDocComment(); | ||||
| 			$noAuth = strpos($doc, '@noAuth') !== false; | ||||
| 			if (preg_match_all('/@url[ \t]+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)[ \t]+\/?(\S*)/s', $doc, $matches, PREG_SET_ORDER)) { | ||||
|  | ||||
| 				$params = $method->getParameters(); | ||||
|  | ||||
| 				foreach ($matches as $match) { | ||||
| 					$httpMethod = $match[1]; | ||||
| 					$url = $basePath . $match[2]; | ||||
| 					if ($url && $url[strlen($url) - 1] == '/') { | ||||
| 						$url = substr($url, 0, -1); | ||||
| 					} | ||||
| 					$call = array($class, $method->getName()); | ||||
| 					$args = array(); | ||||
| 					foreach ($params as $param) { | ||||
| 						$args[$param->getName()] = $param->getPosition(); | ||||
| 					} | ||||
| 					$call[] = $args; | ||||
| 					$call[] = null; | ||||
| 					$call[] = $noAuth; | ||||
|  | ||||
| 					$this->map[$httpMethod][$url] = $call; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public function getPath() | ||||
| 	{ | ||||
| 		$path = preg_replace('/\?.*$/', '', $_SERVER['REQUEST_URI']); | ||||
| 		// remove root from path | ||||
| 		if ($this->root) $path = preg_replace('/^' . preg_quote($this->root, '/') . '/', '', $path); | ||||
| 		// remove trailing format definition, like /controller/action.json -> /controller/action | ||||
| 		$path = preg_replace('/\.(\w+)$/i', '', $path); | ||||
| 		// remove root path from path, like /root/path/api -> /api | ||||
| 		if ($this->rootPath) $path = str_replace($this->rootPath, '', $path); | ||||
| 		return $path; | ||||
| 	} | ||||
|  | ||||
| 	public function getMethod() | ||||
| 	{ | ||||
| 		$method = $_SERVER['REQUEST_METHOD']; | ||||
| 		$override = isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']) ? $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] : (isset($_GET['method']) ? $_GET['method'] : ''); | ||||
| 		if ($method == 'POST' && strtoupper($override) == 'PUT') { | ||||
| 			$method = 'PUT'; | ||||
| 		} elseif ($method == 'POST' && strtoupper($override) == 'DELETE') { | ||||
| 			$method = 'DELETE'; | ||||
| 		} elseif ($method == 'POST' && strtoupper($override) == 'PATCH') { | ||||
|             $method = 'PATCH'; | ||||
|         } | ||||
| 		return $method; | ||||
| 	} | ||||
|  | ||||
| 	public function getFormat() | ||||
| 	{ | ||||
| 		$format = RestFormat::PLAIN; | ||||
| 		$accept_mod = null; | ||||
| 		if(isset($_SERVER["HTTP_ACCEPT"])) { | ||||
| 			$accept_mod = preg_replace('/\s+/i', '', $_SERVER['HTTP_ACCEPT']); // ensures that exploding the HTTP_ACCEPT string does not get confused by whitespaces | ||||
| 		} | ||||
| 		$accept = explode(',', $accept_mod); | ||||
| 		$override = ''; | ||||
|  | ||||
| 		if (isset($_REQUEST['format']) || isset($_SERVER['HTTP_FORMAT'])) { | ||||
| 			// give GET/POST precedence over HTTP request headers | ||||
| 			$override = isset($_SERVER['HTTP_FORMAT']) ? $_SERVER['HTTP_FORMAT'] : ''; | ||||
| 			$override = isset($_REQUEST['format']) ? $_REQUEST['format'] : $override; | ||||
| 			$override = trim($override); | ||||
| 		} | ||||
|  | ||||
| 		// Check for trailing dot-format syntax like /controller/action.format -> action.json | ||||
| 		if(preg_match('/\.(\w+)$/i', strtok($_SERVER["REQUEST_URI"],'?'), $matches)) { | ||||
| 			$override = $matches[1]; | ||||
| 		} | ||||
|  | ||||
| 		// Give GET parameters precedence before all other options to alter the format | ||||
| 		$override = isset($_GET['format']) ? $_GET['format'] : $override; | ||||
| 		if (isset(RestFormat::$formats[$override])) { | ||||
| 			$format = RestFormat::$formats[$override]; | ||||
| 		} elseif (in_array(RestFormat::JSON, $accept)) { | ||||
| 			$format = RestFormat::JSON; | ||||
| 		} | ||||
| 		return $format; | ||||
| 	} | ||||
|  | ||||
| 	public function getData() | ||||
| 	{ | ||||
| 		$data = file_get_contents('php://input'); | ||||
| 		$data = json_decode($data, $this->jsonAssoc); | ||||
|  | ||||
| 		return $data; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	public function sendData($data) | ||||
| 	{ | ||||
| 		header("Cache-Control: no-cache, must-revalidate"); | ||||
| 		header("Expires: 0"); | ||||
| 		header('Content-Type: ' . $this->format); | ||||
|  | ||||
| 		if ($this->format == RestFormat::XML) { | ||||
|  | ||||
| 		if (is_object($data) && method_exists($data, '__keepOut')) { | ||||
| 				$data = clone $data; | ||||
| 				foreach ($data->__keepOut() as $prop) { | ||||
| 					unset($data->$prop); | ||||
| 				} | ||||
| 			} | ||||
| 			$this->xml_encode($data); | ||||
| 		} else { | ||||
| 			if (is_object($data) && method_exists($data, '__keepOut')) { | ||||
| 				$data = clone $data; | ||||
| 				foreach ($data->__keepOut() as $prop) { | ||||
| 					unset($data->$prop); | ||||
| 				} | ||||
| 			} | ||||
| 			$options = 0; | ||||
| 			if ($this->mode == 'debug') { | ||||
| 				$options = JSON_PRETTY_PRINT; | ||||
| 			} | ||||
| 			$options = $options | JSON_UNESCAPED_UNICODE; | ||||
| 			echo json_encode($data, $options); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public function setStatus($code) | ||||
| 	{ | ||||
| 		if (function_exists('http_response_code')) { | ||||
| 			http_response_code($code); | ||||
| 		} else { | ||||
| 			$protocol = $_SERVER['SERVER_PROTOCOL'] ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0'; | ||||
| 			$code .= ' ' . $this->codes[strval($code)]; | ||||
| 			header("$protocol $code"); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	private function xml_encode($mixed, $domElement=null, $DOMDocument=null) {  //@todo add type hint for $domElement and $DOMDocument | ||||
| 		if (is_null($DOMDocument)) { | ||||
| 			$DOMDocument =new DOMDocument; | ||||
| 			$DOMDocument->formatOutput = true; | ||||
| 			$this->xml_encode($mixed, $DOMDocument, $DOMDocument); | ||||
| 			echo $DOMDocument->saveXML(); | ||||
| 		} | ||||
| 		else { | ||||
| 			if (is_array($mixed)) { | ||||
| 				foreach ($mixed as $index => $mixedElement) { | ||||
| 					if (is_int($index)) { | ||||
| 						if ($index === 0) { | ||||
| 							$node = $domElement; | ||||
| 						} | ||||
| 						else { | ||||
| 							$node = $DOMDocument->createElement($domElement->tagName); | ||||
| 							$domElement->parentNode->appendChild($node); | ||||
| 						} | ||||
| 					} | ||||
| 					else { | ||||
| 						$plural = $DOMDocument->createElement($index); | ||||
| 						$domElement->appendChild($plural); | ||||
| 						$node = $plural; | ||||
| 						if (!(rtrim($index, 's') === $index)) { | ||||
| 							$singular = $DOMDocument->createElement(rtrim($index, 's')); | ||||
| 							$plural->appendChild($singular); | ||||
| 							$node = $singular; | ||||
| 						} | ||||
| 					} | ||||
|  | ||||
| 					$this->xml_encode($mixedElement, $node, $DOMDocument); | ||||
| 				} | ||||
| 			} | ||||
| 			else { | ||||
| 				$domElement->appendChild($DOMDocument->createTextNode($mixed)); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	private $codes = array( | ||||
| 		'100' => 'Continue', | ||||
| 		'200' => 'OK', | ||||
| 		'201' => 'Created', | ||||
| 		'202' => 'Accepted', | ||||
| 		'203' => 'Non-Authoritative Information', | ||||
| 		'204' => 'No Content', | ||||
| 		'205' => 'Reset Content', | ||||
| 		'206' => 'Partial Content', | ||||
| 		'300' => 'Multiple Choices', | ||||
| 		'301' => 'Moved Permanently', | ||||
| 		'302' => 'Found', | ||||
| 		'303' => 'See Other', | ||||
| 		'304' => 'Not Modified', | ||||
| 		'305' => 'Use Proxy', | ||||
| 		'307' => 'Temporary Redirect', | ||||
| 		'400' => 'Bad Request', | ||||
| 		'401' => 'Unauthorized', | ||||
| 		'402' => 'Payment Required', | ||||
| 		'403' => 'Forbidden', | ||||
| 		'404' => 'Not Found', | ||||
| 		'405' => 'Method Not Allowed', | ||||
| 		'406' => 'Not Acceptable', | ||||
| 		'409' => 'Conflict', | ||||
| 		'410' => 'Gone', | ||||
| 		'411' => 'Length Required', | ||||
| 		'412' => 'Precondition Failed', | ||||
| 		'413' => 'Request Entity Too Large', | ||||
| 		'414' => 'Request-URI Too Long', | ||||
| 		'415' => 'Unsupported Media Type', | ||||
| 		'416' => 'Requested Range Not Satisfiable', | ||||
| 		'417' => 'Expectation Failed', | ||||
| 		'500' => 'Internal Server Error', | ||||
| 		'501' => 'Not Implemented', | ||||
| 		'503' => 'Service Unavailable' | ||||
| 	); | ||||
| } | ||||
| @@ -1,28 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Changes Rest Controller | ||||
|  * | ||||
|  * @author Pierre HUBERT | ||||
|  */ | ||||
| class changesController { | ||||
| 	/** | ||||
| 	 * Get the changes of a specified period | ||||
| 	 *  | ||||
| 	 * @url GET /changes/get/$from/$to | ||||
| 	 */ | ||||
| 	public function getChanges($from, $to){ | ||||
|  | ||||
| 		//Check values | ||||
| 		if($from*1 > $to*1) | ||||
| 			Rest_fatal_error(401, "Please specify a valid interval !"); | ||||
|  | ||||
|  | ||||
| 		//We try to get changes of the specified period | ||||
| 		$changes = DW::get()->changes->get($from*1, $to*1); | ||||
| 		if($changes === false) | ||||
| 			Rest_fatal_error(500, "Couldn't get changes of the specified period !"); | ||||
| 		 | ||||
| 		//Return the informations | ||||
| 		return $changes; | ||||
| 	} | ||||
| } | ||||
| @@ -1,82 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Lists management controller | ||||
|  * | ||||
|  * @author Pierre HUBERT | ||||
|  */ | ||||
|  | ||||
| class listsController { | ||||
|  | ||||
| 	/** | ||||
| 	 * Get the complete list | ||||
| 	 * | ||||
| 	 * @url GET /list/get | ||||
| 	 * @url GET /list/get/ | ||||
| 	 * @url GET /list/get/$time | ||||
| 	 */ | ||||
| 	public function getList($time="current"){ | ||||
| 		 | ||||
| 		//We check if we want the current list or another one | ||||
| 		if($time === "current"){ | ||||
| 			//Try to get the current list | ||||
| 			if(!$list = DW::get()->lists->getCurrent()) | ||||
| 				Rest_fatal_error(500, "Couldn't get current list !"); | ||||
| 		} | ||||
| 		else { | ||||
| 			//Get the list of the specified timestamp | ||||
| 			if(!$list = DW::get()->lists->getOnTimestamp($time*1)) | ||||
| 				Rest_fatal_error(500, "Couldn't get the list on specified timestamp !"); | ||||
| 		} | ||||
|  | ||||
| 		//Return the list | ||||
| 		return $list; | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| 	/** | ||||
| 	 * Update the current list | ||||
| 	 * | ||||
| 	 * @url POST /list/update | ||||
| 	 */ | ||||
| 	public function updateList(){ | ||||
| 		 | ||||
| 		//Authentication required (protected method) | ||||
| 		if(!DW::get()->auth->restAuth()) | ||||
| 			Rest_fatal_error(401, "Authentication required !"); | ||||
| 		 | ||||
| 		//Try to update list | ||||
| 		if(!DW::get()->lists->update()) | ||||
| 			Rest_fatal_error(500, "Couldn't update Decodex list !"); | ||||
| 		 | ||||
| 		//Else it is a success | ||||
| 		return array("success" => "This list was successfully updated !"); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Get the list of available websites using urls | ||||
| 	 * | ||||
| 	 * @url GET /list/urls | ||||
| 	 */ | ||||
| 	public function getListSites(){ | ||||
| 		//We try to get the list of urls | ||||
| 		if(!$list = DW::get()->lists->getListUrls()) | ||||
| 			Rest_fatal_error(500, "Couldn't get the list of urls !"); | ||||
| 		 | ||||
| 		//Return the list | ||||
| 		return $list; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Get the list of URLs only | ||||
| 	 * | ||||
| 	 * @url GET /list/urls/only | ||||
| 	 */ | ||||
| 	public function getURLsOnly(){ | ||||
| 		//We try to get the list of urls | ||||
| 		if(!$list = DW::get()->lists->getListUrls(true)) | ||||
| 			Rest_fatal_error(500, "Couldn't get the list of urls !"); | ||||
| 		 | ||||
| 		//Return the list | ||||
| 		return $list; | ||||
| 	} | ||||
| } | ||||
| @@ -1,56 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Sites informations controller | ||||
|  * | ||||
|  * @author Pierre HUBERT | ||||
|  */ | ||||
|  | ||||
| class sitesController{ | ||||
| 	/** | ||||
| 	 * Get the informations about a website given a URL | ||||
| 	 * | ||||
| 	 * @url GET /site/$url/infos | ||||
| 	 * @url POST /site/infos | ||||
| 	 */ | ||||
| 	public function getInfosURL($url=false){ | ||||
|  | ||||
| 		//We check if the URL was passed in $_POST mode | ||||
| 		if(!$url){ | ||||
| 			if(!isset($_POST['url'])) | ||||
| 				Rest_fatal_error(401, "Please specify an URL !"); | ||||
| 			 | ||||
| 			$url = $_POST['url']; | ||||
| 		} | ||||
|  | ||||
| 		//We try to get informations about a websites using its URL | ||||
| 		if(!$infos = DW::get()->sites->getInfosFromURL($url)) | ||||
| 			Rest_fatal_error(500, "Couldn't get informations about the URL !"); | ||||
| 		 | ||||
| 		//Return the informations | ||||
| 		return $infos; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Get the informations history about a website given a URL | ||||
| 	 * | ||||
| 	 * @url GET /site/$url/history | ||||
| 	 * @url POST /site/history | ||||
| 	 */ | ||||
| 	public function getInfosURLHistory($url=false){ | ||||
|  | ||||
| 		//We check if the URL was passed in $_POST mode | ||||
| 		if(!$url){ | ||||
| 			if(!isset($_POST['url'])) | ||||
| 				Rest_fatal_error(401, "Please specify an URL !"); | ||||
| 			 | ||||
| 			$url = $_POST['url']; | ||||
| 		} | ||||
|  | ||||
| 		//We try to get informations about a websites using its URL | ||||
| 		if(!$infos = DW::get()->sites->getInfosFromURL($url, 0)) | ||||
| 			Rest_fatal_error(500, "Couldn't get history informations about the URL !"); | ||||
| 		 | ||||
| 		//Return the informations | ||||
| 		return $infos; | ||||
| 	} | ||||
| } | ||||
| @@ -15,10 +15,8 @@ class welcomeController { | ||||
| 	 */ | ||||
| 	public function getInfos(){ | ||||
| 		return array( | ||||
| 			"serviceDescription" => "This service watches DecodexList evolutions, stores them and let its client access them.", | ||||
| 			"githubURL" => "https://github.com/pierre42100/decodexwatcherapi/", | ||||
| 			"clientURL" => "https://decodexwatcher.communiquons.org/", | ||||
| 			"apiSchema" => "https://swagger.decodexwatcher.communiquons.org/" | ||||
| 			"serviceDescription" => "This is the Comunic API Server.", | ||||
| 			"clientURL" => "https://communiquons.org/", | ||||
| 		); | ||||
| 	} | ||||
|  | ||||
|   | ||||
							
								
								
									
										31
									
								
								index.php
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								index.php
									
									
									
									
									
								
							| @@ -12,3 +12,34 @@ | ||||
|  */ | ||||
| include(__DIR__."/init.php"); | ||||
|  | ||||
| //Include RestControllers | ||||
| foreach(glob(PROJECT_PATH."RestControllers/*.php") as $restControllerFile){ | ||||
|     require_once $restControllerFile; | ||||
| } | ||||
|  | ||||
| //Include RestServer library | ||||
| require PROJECT_PATH."3rdparty/RestServer/RestServer.php"; | ||||
|  | ||||
| //Allow remote requests | ||||
| header("Access-Control-Allow-Origin: *"); | ||||
|  | ||||
| //By default format is json | ||||
| if(!isset($_GET["format"])) | ||||
|     $_GET['format'] = "json"; | ||||
|  | ||||
| /** | ||||
|  * Handle Rest requests | ||||
|  */ | ||||
| $server = new \Jacwright\RestServer\RestServer($cs->config->get("site_mode")); | ||||
|  | ||||
| //Include controllers | ||||
| foreach(get_included_files() as $filePath){ | ||||
|     if(preg_match("<RestControllers>", $filePath)){ | ||||
|         $className = strstr($filePath, "RestControllers/"); | ||||
|         $className = str_replace(array("RestControllers/", ".php"), "", $className); | ||||
|         $server->addClass($className); | ||||
|     } | ||||
| } | ||||
|  | ||||
| //Hanlde | ||||
| $server->handle(); | ||||
		Reference in New Issue
	
	Block a user
	 Pierre
					Pierre