Commit 21c142adbdda82f552f58e9d5dedbb4d671eb9ea
Merge branch 'master' of git@github.com:ktgit/knowledgetree into edge
Showing
54 changed files
with
6064 additions
and
0 deletions
webservice/classes/rest/Abstract.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | + | |
| 4 | +/** Rest_Interface */ | |
| 5 | +require_once 'classes/rest/Interface.php'; | |
| 6 | + | |
| 7 | +/** | |
| 8 | + * Rest_Definition | |
| 9 | + */ | |
| 10 | +require_once 'classes/rest/Definition.php'; | |
| 11 | + | |
| 12 | +/** | |
| 13 | + * Rest_Method_Definition | |
| 14 | + */ | |
| 15 | +require_once 'classes/rest/method/Definition.php'; | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * Rest_Method_Callback | |
| 19 | + */ | |
| 20 | +require_once 'classes/rest/method/Callback.php'; | |
| 21 | + | |
| 22 | +/** | |
| 23 | + * Rest_Method_Prototype | |
| 24 | + */ | |
| 25 | +require_once 'classes/rest/method/Prototype.php'; | |
| 26 | + | |
| 27 | +/** | |
| 28 | + * Rest_Method_Parameter | |
| 29 | + */ | |
| 30 | +require_once 'classes/rest/method/Parameter.php'; | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * Rest_Abstract | |
| 34 | + * | |
| 35 | + * | |
| 36 | + */ | |
| 37 | +abstract class Rest_Abstract implements Rest_Interface | |
| 38 | +{ | |
| 39 | + /** | |
| 40 | + * @deprecated | |
| 41 | + * @var array List of PHP magic methods (lowercased) | |
| 42 | + */ | |
| 43 | + protected static $magic_methods = array( | |
| 44 | + '__call', | |
| 45 | + '__clone', | |
| 46 | + '__construct', | |
| 47 | + '__destruct', | |
| 48 | + '__get', | |
| 49 | + '__isset', | |
| 50 | + '__set', | |
| 51 | + '__set_state', | |
| 52 | + '__sleep', | |
| 53 | + '__tostring', | |
| 54 | + '__unset', | |
| 55 | + '__wakeup', | |
| 56 | + ); | |
| 57 | + | |
| 58 | + /** | |
| 59 | + * @var bool Flag; whether or not overwriting existing methods is allowed | |
| 60 | + */ | |
| 61 | + protected $_overwriteExistingMethods = false; | |
| 62 | + | |
| 63 | + /** | |
| 64 | + * @var Rest_Definition | |
| 65 | + */ | |
| 66 | + protected $_table; | |
| 67 | + | |
| 68 | + /** | |
| 69 | + * Constructor | |
| 70 | + * | |
| 71 | + * Setup server description | |
| 72 | + * | |
| 73 | + * @return void | |
| 74 | + */ | |
| 75 | + public function __construct() | |
| 76 | + { | |
| 77 | + $this->_table = new Rest_Definition(); | |
| 78 | + $this->_table->setOverwriteExistingMethods($this->_overwriteExistingMethods); | |
| 79 | + } | |
| 80 | + | |
| 81 | + /** | |
| 82 | + * Returns a list of registered methods | |
| 83 | + * | |
| 84 | + * Returns an array of method definitions. | |
| 85 | + * | |
| 86 | + * @return Rest_Definition | |
| 87 | + */ | |
| 88 | + public function getFunctions() | |
| 89 | + { | |
| 90 | + return $this->_table; | |
| 91 | + } | |
| 92 | + | |
| 93 | + /** | |
| 94 | + * Lowercase a string | |
| 95 | + * | |
| 96 | + * Lowercase's a string by reference | |
| 97 | + * | |
| 98 | + * @deprecated | |
| 99 | + * @param string $string value | |
| 100 | + * @param string $key | |
| 101 | + * @return string Lower cased string | |
| 102 | + */ | |
| 103 | + public static function lowerCase(&$value, &$key) | |
| 104 | + { | |
| 105 | + trigger_error(__CLASS__ . '::' . __METHOD__ . '() is deprecated and will be removed in a future version', E_USER_NOTICE); | |
| 106 | + return $value = strtolower($value); | |
| 107 | + } | |
| 108 | + | |
| 109 | + /** | |
| 110 | + * Build callback for method signature | |
| 111 | + * | |
| 112 | + * @param Rest_Reflection_Function_Abstract $reflection | |
| 113 | + * @return Rest_Method_Callback | |
| 114 | + */ | |
| 115 | + protected function _buildCallback(Rest_Reflection_Function_Abstract $reflection) | |
| 116 | + { | |
| 117 | + $callback = new Rest_Method_Callback(); | |
| 118 | + if ($reflection instanceof Rest_Reflection_Method) { | |
| 119 | + $callback->setType($reflection->isStatic() ? 'static' : 'instance') | |
| 120 | + ->setClass($reflection->getDeclaringClass()->getName()) | |
| 121 | + ->setMethod($reflection->getName()); | |
| 122 | + } elseif ($reflection instanceof Rest_Reflection_Function) { | |
| 123 | + $callback->setType('function') | |
| 124 | + ->setFunction($reflection->getName()); | |
| 125 | + } | |
| 126 | + return $callback; | |
| 127 | + } | |
| 128 | + | |
| 129 | + /** | |
| 130 | + * Build a method signature | |
| 131 | + * | |
| 132 | + * @param Rest_Reflection_Function_Abstract $reflection | |
| 133 | + * @param null|string|object $class | |
| 134 | + * @return Rest_Method_Definition | |
| 135 | + * @throws Rest_Exception on duplicate entry | |
| 136 | + */ | |
| 137 | + protected function _buildSignature(Rest_Reflection_Function_Abstract $reflection, $class = null) | |
| 138 | + { | |
| 139 | + $ns = $reflection->getNamespace(); | |
| 140 | + $name = $reflection->getName(); | |
| 141 | + $method = empty($ns) ? $name : $ns . '.' . $name; | |
| 142 | + | |
| 143 | + if (!$this->_overwriteExistingMethods && $this->_table->hasMethod($method)) { | |
| 144 | + require_once 'Exception.php'; | |
| 145 | + throw new Rest_Exception('Duplicate method registered: ' . $method); | |
| 146 | + } | |
| 147 | + | |
| 148 | + $definition = new Rest_Method_Definition(); | |
| 149 | + $definition->setName($method) | |
| 150 | + ->setCallback($this->_buildCallback($reflection)) | |
| 151 | + ->setMethodHelp($reflection->getDescription()) | |
| 152 | + ->setInvokeArguments($reflection->getInvokeArguments()); | |
| 153 | + | |
| 154 | + foreach ($reflection->getPrototypes() as $proto) { | |
| 155 | + $prototype = new Rest_Method_Prototype(); | |
| 156 | + $prototype->setReturnType($this->_fixType($proto->getReturnType())); | |
| 157 | + foreach ($proto->getParameters() as $parameter) { | |
| 158 | + $param = new Rest_Method_Parameter(array( | |
| 159 | + 'type' => $this->_fixType($parameter->getType()), | |
| 160 | + 'name' => $parameter->getName(), | |
| 161 | + 'optional' => $parameter->isOptional(), | |
| 162 | + )); | |
| 163 | + if ($parameter->isDefaultValueAvailable()) { | |
| 164 | + $param->setDefaultValue($parameter->getDefaultValue()); | |
| 165 | + } | |
| 166 | + $prototype->addParameter($param); | |
| 167 | + } | |
| 168 | + $definition->addPrototype($prototype); | |
| 169 | + } | |
| 170 | + if (is_object($class)) { | |
| 171 | + $definition->setObject($class); | |
| 172 | + } | |
| 173 | + $this->_table->addMethod($definition); | |
| 174 | + return $definition; | |
| 175 | + } | |
| 176 | + | |
| 177 | + /** | |
| 178 | + * Dispatch method | |
| 179 | + * | |
| 180 | + * @param Rest_Method_Definition $invocable | |
| 181 | + * @param array $params | |
| 182 | + * @return mixed | |
| 183 | + */ | |
| 184 | + protected function _dispatch(Rest_Method_Definition $invocable, array $params) | |
| 185 | + { | |
| 186 | + $callback = $invocable->getCallback(); | |
| 187 | + $type = $callback->getType(); | |
| 188 | + | |
| 189 | + if ('function' == $type) { | |
| 190 | + $function = $callback->getFunction(); | |
| 191 | + return call_user_func_array($function, $params); | |
| 192 | + } | |
| 193 | + | |
| 194 | + $class = $callback->getClass(); | |
| 195 | + $method = $callback->getMethod(); | |
| 196 | + | |
| 197 | + if ('static' == $type) { | |
| 198 | + return call_user_func_array(array($class, $method), $params); | |
| 199 | + } | |
| 200 | + | |
| 201 | + $object = $invocable->getObject(); | |
| 202 | + if (!is_object($object)) { | |
| 203 | + $invokeArgs = $invocable->getInvokeArguments(); | |
| 204 | + if (!empty($invokeArgs)) { | |
| 205 | + $reflection = new ReflectionClass($class); | |
| 206 | + $object = $reflection->newInstanceArgs($invokeArgs); | |
| 207 | + } else { | |
| 208 | + $object = new $class; | |
| 209 | + } | |
| 210 | + } | |
| 211 | + return call_user_func_array(array($object, $method), $params); | |
| 212 | + } | |
| 213 | + | |
| 214 | + /** | |
| 215 | + * Map PHP type to protocol type | |
| 216 | + * | |
| 217 | + * @param string $type | |
| 218 | + * @return string | |
| 219 | + */ | |
| 220 | + abstract protected function _fixType($type); | |
| 221 | +} | ... | ... |
webservice/classes/rest/Definition.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Server methods metadata | |
| 5 | + * | |
| 6 | + */ | |
| 7 | +class Rest_Definition implements Countable, Iterator | |
| 8 | +{ | |
| 9 | + /** | |
| 10 | + * @var array Array of Rest_Method_Definition objects | |
| 11 | + */ | |
| 12 | + protected $_methods = array(); | |
| 13 | + | |
| 14 | + /** | |
| 15 | + * @var bool Whether or not overwriting existing methods is allowed | |
| 16 | + */ | |
| 17 | + protected $_overwriteExistingMethods = false; | |
| 18 | + | |
| 19 | + /** | |
| 20 | + * Constructor | |
| 21 | + * | |
| 22 | + * @param null|array $methods | |
| 23 | + * @return void | |
| 24 | + */ | |
| 25 | + public function __construct($methods = null) | |
| 26 | + { | |
| 27 | + if (is_array($methods)) { | |
| 28 | + $this->setMethods($methods); | |
| 29 | + } | |
| 30 | + } | |
| 31 | + | |
| 32 | + /** | |
| 33 | + * Set flag indicating whether or not overwriting existing methods is allowed | |
| 34 | + * | |
| 35 | + * @param mixed $flag | |
| 36 | + * @return void | |
| 37 | + */ | |
| 38 | + public function setOverwriteExistingMethods($flag) | |
| 39 | + { | |
| 40 | + $this->_overwriteExistingMethods = (bool) $flag; | |
| 41 | + return $this; | |
| 42 | + } | |
| 43 | + | |
| 44 | + /** | |
| 45 | + * Add method to definition | |
| 46 | + * | |
| 47 | + * @param array|Rest_Method_Definition $method | |
| 48 | + * @param null|string $name | |
| 49 | + * @return Rest_Definition | |
| 50 | + * @throws Rest_Exception if duplicate or invalid method provided | |
| 51 | + */ | |
| 52 | + public function addMethod($method, $name = null) | |
| 53 | + { | |
| 54 | + if (is_array($method)) { | |
| 55 | + require_once 'classes/rest/method/Definition.php'; | |
| 56 | + $method = new Rest_Method_Definition($method); | |
| 57 | + } elseif (!$method instanceof Rest_Method_Definition) { | |
| 58 | + require_once 'Exception.php'; | |
| 59 | + throw new Rest_Exception('Invalid method provided'); | |
| 60 | + } | |
| 61 | + | |
| 62 | + if (is_numeric($name)) { | |
| 63 | + $name = null; | |
| 64 | + } | |
| 65 | + if (null !== $name) { | |
| 66 | + $method->setName($name); | |
| 67 | + } else { | |
| 68 | + $name = $method->getName(); | |
| 69 | + } | |
| 70 | + if (null === $name) { | |
| 71 | + require_once 'Exception.php'; | |
| 72 | + throw new Rest_Exception('No method name provided'); | |
| 73 | + } | |
| 74 | + | |
| 75 | + if (!$this->_overwriteExistingMethods && array_key_exists($name, $this->_methods)) { | |
| 76 | + require_once 'Exception.php'; | |
| 77 | + throw new Rest_Exception(sprintf('Method by name of "%s" already exists', $name)); | |
| 78 | + } | |
| 79 | + $this->_methods[$name] = $method; | |
| 80 | + return $this; | |
| 81 | + } | |
| 82 | + | |
| 83 | + /** | |
| 84 | + * Add multiple methods | |
| 85 | + * | |
| 86 | + * @param array $methods Array of Rest_Method_Definition objects or arrays | |
| 87 | + * @return Rest_Definition | |
| 88 | + */ | |
| 89 | + public function addMethods(array $methods) | |
| 90 | + { | |
| 91 | + foreach ($methods as $key => $method) { | |
| 92 | + $this->addMethod($method, $key); | |
| 93 | + } | |
| 94 | + return $this; | |
| 95 | + } | |
| 96 | + | |
| 97 | + /** | |
| 98 | + * Set all methods at once (overwrite) | |
| 99 | + * | |
| 100 | + * @param array $methods Array of Rest_Method_Definition objects or arrays | |
| 101 | + * @return Rest_Definition | |
| 102 | + */ | |
| 103 | + public function setMethods(array $methods) | |
| 104 | + { | |
| 105 | + $this->clearMethods(); | |
| 106 | + $this->addMethods($methods); | |
| 107 | + return $this; | |
| 108 | + } | |
| 109 | + | |
| 110 | + /** | |
| 111 | + * Does the definition have the given method? | |
| 112 | + * | |
| 113 | + * @param string $method | |
| 114 | + * @return bool | |
| 115 | + */ | |
| 116 | + public function hasMethod($method) | |
| 117 | + { | |
| 118 | + return array_key_exists($method, $this->_methods); | |
| 119 | + } | |
| 120 | + | |
| 121 | + /** | |
| 122 | + * Get a given method definition | |
| 123 | + * | |
| 124 | + * @param string $method | |
| 125 | + * @return null|Rest_Method_Definition | |
| 126 | + */ | |
| 127 | + public function getMethod($method) | |
| 128 | + { | |
| 129 | + if ($this->hasMethod($method)) { | |
| 130 | + return $this->_methods[$method]; | |
| 131 | + } | |
| 132 | + return false; | |
| 133 | + } | |
| 134 | + | |
| 135 | + /** | |
| 136 | + * Get all method definitions | |
| 137 | + * | |
| 138 | + * @return array Array of Rest_Method_Definition objects | |
| 139 | + */ | |
| 140 | + public function getMethods() | |
| 141 | + { | |
| 142 | + return $this->_methods; | |
| 143 | + } | |
| 144 | + | |
| 145 | + /** | |
| 146 | + * Remove a method definition | |
| 147 | + * | |
| 148 | + * @param string $method | |
| 149 | + * @return Rest_Definition | |
| 150 | + */ | |
| 151 | + public function removeMethod($method) | |
| 152 | + { | |
| 153 | + if ($this->hasMethod($method)) { | |
| 154 | + unset($this->_methods[$method]); | |
| 155 | + } | |
| 156 | + return $this; | |
| 157 | + } | |
| 158 | + | |
| 159 | + /** | |
| 160 | + * Clear all method definitions | |
| 161 | + * | |
| 162 | + * @return Rest_Definition | |
| 163 | + */ | |
| 164 | + public function clearMethods() | |
| 165 | + { | |
| 166 | + $this->_methods = array(); | |
| 167 | + return $this; | |
| 168 | + } | |
| 169 | + | |
| 170 | + /** | |
| 171 | + * Cast definition to an array | |
| 172 | + * | |
| 173 | + * @return array | |
| 174 | + */ | |
| 175 | + public function toArray() | |
| 176 | + { | |
| 177 | + $methods = array(); | |
| 178 | + foreach ($this->getMethods() as $key => $method) { | |
| 179 | + $methods[$key] = $method->toArray(); | |
| 180 | + } | |
| 181 | + return $methods; | |
| 182 | + } | |
| 183 | + | |
| 184 | + /** | |
| 185 | + * Countable: count of methods | |
| 186 | + * | |
| 187 | + * @return int | |
| 188 | + */ | |
| 189 | + public function count() | |
| 190 | + { | |
| 191 | + return count($this->_methods); | |
| 192 | + } | |
| 193 | + | |
| 194 | + /** | |
| 195 | + * Iterator: current item | |
| 196 | + * | |
| 197 | + * @return mixed | |
| 198 | + */ | |
| 199 | + public function current() | |
| 200 | + { | |
| 201 | + return current($this->_methods); | |
| 202 | + } | |
| 203 | + | |
| 204 | + /** | |
| 205 | + * Iterator: current item key | |
| 206 | + * | |
| 207 | + * @return int|string | |
| 208 | + */ | |
| 209 | + public function key() | |
| 210 | + { | |
| 211 | + return key($this->_methods); | |
| 212 | + } | |
| 213 | + | |
| 214 | + /** | |
| 215 | + * Iterator: advance to next method | |
| 216 | + * | |
| 217 | + * @return void | |
| 218 | + */ | |
| 219 | + public function next() | |
| 220 | + { | |
| 221 | + return next($this->_methods); | |
| 222 | + } | |
| 223 | + | |
| 224 | + /** | |
| 225 | + * Iterator: return to first method | |
| 226 | + * | |
| 227 | + * @return void | |
| 228 | + */ | |
| 229 | + public function rewind() | |
| 230 | + { | |
| 231 | + return reset($this->_methods); | |
| 232 | + } | |
| 233 | + | |
| 234 | + /** | |
| 235 | + * Iterator: is the current index valid? | |
| 236 | + * | |
| 237 | + * @return bool | |
| 238 | + */ | |
| 239 | + public function valid() | |
| 240 | + { | |
| 241 | + return (bool) $this->current(); | |
| 242 | + } | |
| 243 | +} | ... | ... |
webservice/classes/rest/Exception.php
0 → 100644
webservice/classes/rest/Interface.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Rest_Interface | |
| 5 | + * These are all public functions that implemented in the | |
| 6 | + * Rest Interface | |
| 7 | + * | |
| 8 | + */ | |
| 9 | +interface Rest_Interface | |
| 10 | +{ | |
| 11 | + /** | |
| 12 | + * Attach a function as a server method | |
| 13 | + * | |
| 14 | + * Namespacing is primarily for xmlrpc, but may be used with other | |
| 15 | + * implementations to prevent naming collisions. | |
| 16 | + * | |
| 17 | + * @param string $function | |
| 18 | + * @param string $namespace | |
| 19 | + * @param null|array Optional array of arguments to pass to callbacks at | |
| 20 | + * dispatch. | |
| 21 | + * @return void | |
| 22 | + */ | |
| 23 | + public function addFunction($function, $namespace = ''); | |
| 24 | + | |
| 25 | + /** | |
| 26 | + * Attach a class to a server | |
| 27 | + * | |
| 28 | + * The individual implementations should probably allow passing a variable | |
| 29 | + * number of arguments in, so that developers may define custom runtime | |
| 30 | + * arguments to pass to server methods. | |
| 31 | + * | |
| 32 | + * Namespacing is primarily for xmlrpc, but could be used for other | |
| 33 | + * implementations as well. | |
| 34 | + * | |
| 35 | + * @param mixed $class Class name or object instance to examine and attach | |
| 36 | + * to the server. | |
| 37 | + * @param string $namespace Optional namespace with which to prepend method | |
| 38 | + * names in the dispatch table. | |
| 39 | + * methods in the class will be valid callbacks. | |
| 40 | + * @param null|array Optional array of arguments to pass to callbacks at | |
| 41 | + * dispatch. | |
| 42 | + * @return void | |
| 43 | + */ | |
| 44 | + public function setClass($class, $namespace = '', $argv = null); | |
| 45 | + | |
| 46 | + /** | |
| 47 | + * Generate a server fault | |
| 48 | + * | |
| 49 | + * @param mixed $fault | |
| 50 | + * @param int $code | |
| 51 | + * @return mixed | |
| 52 | + */ | |
| 53 | + public function fault($fault = null, $code = 404); | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * Handle a request | |
| 57 | + * | |
| 58 | + * Requests may be passed in, or the server may automagically determine the | |
| 59 | + * request based on defaults. Dispatches server request to appropriate | |
| 60 | + * method and returns a response | |
| 61 | + * | |
| 62 | + * @param mixed $request | |
| 63 | + * @return mixed | |
| 64 | + */ | |
| 65 | + public function handle($request = false); | |
| 66 | + | |
| 67 | + /** | |
| 68 | + * Return a server definition array | |
| 69 | + * | |
| 70 | + * Returns a server definition array as created using | |
| 71 | + * {@link * Rest_Reflection}. Can be used for server introspection, | |
| 72 | + * documentation, or persistence. | |
| 73 | + * | |
| 74 | + * @access public | |
| 75 | + * @return array | |
| 76 | + */ | |
| 77 | + public function getFunctions(); | |
| 78 | + | |
| 79 | + /** | |
| 80 | + * Load server definition | |
| 81 | + * | |
| 82 | + * Used for persistence; loads a construct as returned by {@link getFunctions()}. | |
| 83 | + * | |
| 84 | + * @param array $array | |
| 85 | + * @return void | |
| 86 | + */ | |
| 87 | + public function loadFunctions($definition); | |
| 88 | + | |
| 89 | + /** | |
| 90 | + * Set server persistence | |
| 91 | + * | |
| 92 | + * @param int $mode | |
| 93 | + * @return void | |
| 94 | + */ | |
| 95 | + public function setPersistence($mode); | |
| 96 | +} | ... | ... |
webservice/classes/rest/Reflection.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Rest_Reflection_Function | |
| 5 | + */ | |
| 6 | +require_once 'classes/rest/reflection/Function.php'; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * Rest_Reflection_Class | |
| 10 | + */ | |
| 11 | +require_once 'classes/rest/reflection/Class.php'; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * Reflection for determining method signatures to use with server classes | |
| 15 | + * | |
| 16 | + */ | |
| 17 | +class Rest_Reflection | |
| 18 | +{ | |
| 19 | + /** | |
| 20 | + * Perform class reflection to create dispatch signatures | |
| 21 | + * | |
| 22 | + * Creates a {@link Rest_Reflection_Class} object for the class or | |
| 23 | + * object provided. | |
| 24 | + * | |
| 25 | + * If extra arguments should be passed to dispatchable methods, these may | |
| 26 | + * be provided as an array to $argv. | |
| 27 | + * | |
| 28 | + * @param string|object $class Class name or object | |
| 29 | + * @param null|array $argv Optional arguments to be used during the method call | |
| 30 | + * @param string $namespace Optional namespace with which to prefix the | |
| 31 | + * method name (used for the signature key). Primarily to avoid collisions, | |
| 32 | + * also for XmlRpc namespacing | |
| 33 | + * @return Rest_Reflection_Class | |
| 34 | + * @throws Rest_Exception | |
| 35 | + * | |
| 36 | + * | |
| 37 | + */ | |
| 38 | + | |
| 39 | + public static function reflectClass($class, $argv = false, $namespace = '') | |
| 40 | + { | |
| 41 | + $reflection = new ReflectionClass($class); | |
| 42 | + | |
| 43 | + //require_once 'Exception.php'; | |
| 44 | + //throw new Rest_Exception('Invalid class or object passed to attachClass()'); | |
| 45 | + | |
| 46 | + if ($argv && !is_array($argv)) { | |
| 47 | + require_once 'Exception.php'; | |
| 48 | + throw new Rest_Exception('Invalid argv argument passed to reflectClass'); | |
| 49 | + } | |
| 50 | + | |
| 51 | + return new Rest_Reflection_Class($reflection, $namespace, $argv); | |
| 52 | + } | |
| 53 | + | |
| 54 | + /** | |
| 55 | + * Perform function reflection to create dispatch signatures | |
| 56 | + * | |
| 57 | + * Creates dispatch prototypes for a function. It returns a | |
| 58 | + * {@link Rest_Reflection_Function} object. | |
| 59 | + * | |
| 60 | + * If extra arguments should be passed to the dispatchable function, these | |
| 61 | + * may be provided as an array to $argv. | |
| 62 | + * | |
| 63 | + * @param string $function Function name | |
| 64 | + * @param null|array $argv Optional arguments to be used during the method call | |
| 65 | + * @param string $namespace Optional namespace with which to prefix the | |
| 66 | + * function name (used for the signature key). Primarily to avoid | |
| 67 | + * collisions, also for XmlRpc namespacing | |
| 68 | + * @return Rest_Reflection_Function | |
| 69 | + * @throws Rest_Exception | |
| 70 | + */ | |
| 71 | + public static function reflectFunction($function, $argv = false, $namespace = '') | |
| 72 | + { | |
| 73 | + if (!is_string($function) || !function_exists($function)) { | |
| 74 | + require_once 'Exception.php'; | |
| 75 | + throw new Rest_Exception('Invalid function "' . $function . '" passed to reflectFunction'); | |
| 76 | + } | |
| 77 | + | |
| 78 | + | |
| 79 | + if ($argv && !is_array($argv)) { | |
| 80 | + require_once 'Exception.php'; | |
| 81 | + throw new Rest_Exception('Invalid argv argument passed to reflectClass'); | |
| 82 | + } | |
| 83 | + | |
| 84 | + return new Rest_Reflection_Function(new ReflectionFunction($function), $namespace, $argv); | |
| 85 | + } | |
| 86 | +} | ... | ... |
webservice/classes/rest/Server.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | +* Invokes Rest Service API for KnowledgeTree. | |
| 5 | +* | |
| 6 | +* | |
| 7 | +* KnowledgeTree Community Edition | |
| 8 | +* Document Management Made Simple | |
| 9 | +* Copyright (C) 2008,2009 KnowledgeTree Inc. | |
| 10 | +* Portions copyright The Jam Warehouse Software (Pty) Limited | |
| 11 | +* | |
| 12 | +* This program is free software; you can redistribute it and/or modify it under | |
| 13 | +* the terms of the GNU General Public License version 3 as published by the | |
| 14 | +* Free Software Foundation. | |
| 15 | +* | |
| 16 | +* This program is distributed in the hope that it will be useful, but WITHOUT | |
| 17 | +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
| 18 | +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
| 19 | +* details. | |
| 20 | +* | |
| 21 | +* You should have received a copy of the GNU General Public License | |
| 22 | +* along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 23 | +* | |
| 24 | +* You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco, | |
| 25 | +* California 94120-7775, or email info@knowledgetree.com. | |
| 26 | +* | |
| 27 | +* The interactive user interfaces in modified source and object code versions | |
| 28 | +* of this program must display Appropriate Legal Notices, as required under | |
| 29 | +* Section 5 of the GNU General Public License version 3. | |
| 30 | +* | |
| 31 | +* In accordance with Section 7(b) of the GNU General Public License version 3, | |
| 32 | +* these Appropriate Legal Notices must retain the display of the "Powered by | |
| 33 | +* KnowledgeTree" logo and retain the original copyright notice. If the display of the | |
| 34 | +* logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices | |
| 35 | +* must display the words "Powered by KnowledgeTree" and retain the original | |
| 36 | +* copyright notice. | |
| 37 | +* | |
| 38 | +* @copyright 2008-2009, KnowledgeTree Inc. | |
| 39 | +* @license GNU General Public License version 3 | |
| 40 | +* @author KnowledgeTree Team | |
| 41 | +* @package Webservice | |
| 42 | +* @version Version 0.1 | |
| 43 | +*/ | |
| 44 | + | |
| 45 | +/** | |
| 46 | + * Rest_Interface | |
| 47 | + */ | |
| 48 | +require_once 'classes/rest/Interface.php'; | |
| 49 | + | |
| 50 | +/** | |
| 51 | + * Rest_Reflection | |
| 52 | + */ | |
| 53 | +require_once 'classes/rest/Reflection.php'; | |
| 54 | + | |
| 55 | +/** | |
| 56 | + * Rest_Abstract | |
| 57 | + */ | |
| 58 | +require_once 'classes/rest/Abstract.php'; | |
| 59 | + | |
| 60 | +/** | |
| 61 | + * Rest_Exception | |
| 62 | + * | |
| 63 | + */ | |
| 64 | +require_once 'classes/rest/Exception.php'; | |
| 65 | + | |
| 66 | +class Rest_Server implements Rest_Interface | |
| 67 | +{ | |
| 68 | + /** | |
| 69 | + * Class Constructor Args | |
| 70 | + * @var array | |
| 71 | + */ | |
| 72 | + protected $_args = array(); | |
| 73 | + | |
| 74 | + /** | |
| 75 | + * @var string Encoding | |
| 76 | + */ | |
| 77 | + protected $_encoding = 'UTF-8'; | |
| 78 | + | |
| 79 | + /** | |
| 80 | + * @var array An array of Rest_Reflect_Method | |
| 81 | + */ | |
| 82 | + protected $_functions = array(); | |
| 83 | + | |
| 84 | + /** | |
| 85 | + * @var array Array of headers to send | |
| 86 | + */ | |
| 87 | + protected $_headers = array(); | |
| 88 | + | |
| 89 | + /** | |
| 90 | + * @var array PHP's Magic Methods, these are ignored | |
| 91 | + */ | |
| 92 | + protected static $magicMethods = array( | |
| 93 | + '__construct', | |
| 94 | + '__destruct', | |
| 95 | + '__get', | |
| 96 | + '__set', | |
| 97 | + '__call', | |
| 98 | + '__sleep', | |
| 99 | + '__wakeup', | |
| 100 | + '__isset', | |
| 101 | + '__unset', | |
| 102 | + '__tostring', | |
| 103 | + '__clone', | |
| 104 | + '__set_state', | |
| 105 | + ); | |
| 106 | + | |
| 107 | + /** | |
| 108 | + * @var string Current Method | |
| 109 | + */ | |
| 110 | + protected $_method; | |
| 111 | + | |
| 112 | + /** | |
| 113 | + * @var Rest_Reflection | |
| 114 | + */ | |
| 115 | + protected $_reflection = null; | |
| 116 | + | |
| 117 | + /** | |
| 118 | + * Whether or not {@link handle()} should send output or return the response. | |
| 119 | + * @var boolean Defaults to false | |
| 120 | + */ | |
| 121 | + protected $_returnResponse = false; | |
| 122 | + | |
| 123 | + /** | |
| 124 | + * Constructor | |
| 125 | + */ | |
| 126 | + public function __construct() | |
| 127 | + { | |
| 128 | + set_exception_handler(array($this, "fault")); | |
| 129 | + $this->_reflection = new Rest_Reflection(); | |
| 130 | + } | |
| 131 | + | |
| 132 | + /** | |
| 133 | + * Set XML encoding | |
| 134 | + * | |
| 135 | + * @param string $encoding | |
| 136 | + * @return Rest_Server | |
| 137 | + */ | |
| 138 | + public function setEncoding($encoding) | |
| 139 | + { | |
| 140 | + $this->_encoding = (string) $encoding; | |
| 141 | + return $this; | |
| 142 | + } | |
| 143 | + | |
| 144 | + /** | |
| 145 | + * Get XML encoding | |
| 146 | + * | |
| 147 | + * @return string | |
| 148 | + */ | |
| 149 | + public function getEncoding() | |
| 150 | + { | |
| 151 | + return $this->_encoding; | |
| 152 | + } | |
| 153 | + | |
| 154 | + /** | |
| 155 | + * Lowercase a string | |
| 156 | + * | |
| 157 | + * Lowercase's a string by reference | |
| 158 | + * | |
| 159 | + * @param string $value | |
| 160 | + * @param string $key | |
| 161 | + * @return string Lower cased string | |
| 162 | + */ | |
| 163 | + public static function lowerCase(&$value, &$key) | |
| 164 | + { | |
| 165 | + return $value = strtolower($value); | |
| 166 | + } | |
| 167 | + | |
| 168 | + /** | |
| 169 | + * Whether or not to return a response | |
| 170 | + * | |
| 171 | + * If called without arguments, returns the value of the flag. If called | |
| 172 | + * with an argument, sets the flag. | |
| 173 | + * | |
| 174 | + * When 'return response' is true, {@link handle()} will not send output, | |
| 175 | + * but will instead return the response from the dispatched function/method. | |
| 176 | + * | |
| 177 | + * @param boolean $flag | |
| 178 | + * @return boolean|Rest_Server Returns Rest_Server when used to set the flag; returns boolean flag value otherwise. | |
| 179 | + */ | |
| 180 | + public function returnResponse($flag = null) | |
| 181 | + { | |
| 182 | + if (null == $flag) { | |
| 183 | + return $this->_returnResponse; | |
| 184 | + } | |
| 185 | + | |
| 186 | + $this->_returnResponse = ($flag) ? true : false; | |
| 187 | + return $this; | |
| 188 | + } | |
| 189 | + | |
| 190 | + /** | |
| 191 | + * Implement Rest_Interface::handle() | |
| 192 | + * | |
| 193 | + * @param array $request | |
| 194 | + * @throws Rest_Server_Exception | |
| 195 | + * @return string|void | |
| 196 | + */ | |
| 197 | + public function handle($request = false) | |
| 198 | + { | |
| 199 | + $this->_headers = array('Content-Type: text/xml'); | |
| 200 | + if (!$request) { | |
| 201 | + $request = $_REQUEST; | |
| 202 | + } | |
| 203 | + if (isset($request['method'])) { | |
| 204 | + $this->_method = $request['method']; | |
| 205 | + if (isset($this->_functions[$this->_method])) { | |
| 206 | + if ($this->_functions[$this->_method] instanceof Rest_Reflection_Function || $this->_functions[$this->_method] instanceof Rest_Reflection_Method && $this->_functions[$this->_method]->isPublic()) { | |
| 207 | + $request_keys = array_keys($request); | |
| 208 | + array_walk($request_keys, array(__CLASS__, "lowerCase")); | |
| 209 | + $request = array_combine($request_keys, $request); | |
| 210 | + | |
| 211 | + $func_args = $this->_functions[$this->_method]->getParameters(); | |
| 212 | + | |
| 213 | + $calling_args = array(); | |
| 214 | + foreach ($func_args as $arg) { | |
| 215 | + if (isset($request[strtolower($arg->getName())])) { | |
| 216 | + $calling_args[] = $request[strtolower($arg->getName())]; | |
| 217 | + } elseif ($arg->isOptional()) { | |
| 218 | + $calling_args[] = $arg->getDefaultValue(); | |
| 219 | + } | |
| 220 | + } | |
| 221 | + | |
| 222 | + foreach ($request as $key => $value) { | |
| 223 | + if (substr($key, 0, 3) == 'arg') { | |
| 224 | + $key = str_replace('arg', '', $key); | |
| 225 | + $calling_args[$key] = $value; | |
| 226 | + } | |
| 227 | + } | |
| 228 | + | |
| 229 | + // Sort arguments by key -- @see ZF-2279 | |
| 230 | + ksort($calling_args); | |
| 231 | + | |
| 232 | + $result = false; | |
| 233 | + if (count($calling_args) < count($func_args)) { | |
| 234 | + $result = $this->fault(new Rest_Exception('Invalid Method Call to ' . $this->_method . '. Requires ' . count($func_args) . ', ' . count($calling_args) . ' given.'), 400); | |
| 235 | + } | |
| 236 | + | |
| 237 | + if (!$result && $this->_functions[$this->_method] instanceof Rest_Reflection_Method) { | |
| 238 | + // Get class | |
| 239 | + $class = $this->_functions[$this->_method]->getDeclaringClass()->getName(); | |
| 240 | + | |
| 241 | + if ($this->_functions[$this->_method]->isStatic()) { | |
| 242 | + // for some reason, invokeArgs() does not work the same as | |
| 243 | + // invoke(), and expects the first argument to be an object. | |
| 244 | + // So, using a callback if the method is static. | |
| 245 | + $result = $this->_callStaticMethod($class, $calling_args); | |
| 246 | + } else { | |
| 247 | + // Object method | |
| 248 | + $result = $this->_callObjectMethod($class, $calling_args); | |
| 249 | + } | |
| 250 | + } elseif (!$result) { | |
| 251 | + try { | |
| 252 | + $result = call_user_func_array($this->_functions[$this->_method]->getName(), $calling_args); //$this->_functions[$this->_method]->invokeArgs($calling_args); | |
| 253 | + } catch (Exception $e) { | |
| 254 | + $result = $this->fault($e); | |
| 255 | + } | |
| 256 | + } | |
| 257 | + } else { | |
| 258 | + | |
| 259 | + $result = $this->fault( | |
| 260 | + new Rest_Exception("Unknown Method '$this->_method'."), | |
| 261 | + 404 | |
| 262 | + ); | |
| 263 | + } | |
| 264 | + } else { | |
| 265 | + $result = $this->fault( | |
| 266 | + new Rest_Exception("Unknown Method '$this->_method'."), | |
| 267 | + 404 | |
| 268 | + ); | |
| 269 | + } | |
| 270 | + } else { | |
| 271 | + $result = $this->fault( | |
| 272 | + new Rest_Exception("No Method Specified."), | |
| 273 | + 404 | |
| 274 | + ); | |
| 275 | + } | |
| 276 | + | |
| 277 | + if ($result instanceof SimpleXMLElement) { | |
| 278 | + $response = $result->asXML(); | |
| 279 | + } elseif ($result instanceof DOMDocument) { | |
| 280 | + $response = $result->saveXML(); | |
| 281 | + } elseif ($result instanceof DOMNode) { | |
| 282 | + $response = $result->ownerDocument->saveXML($result); | |
| 283 | + } elseif (is_array($result) || is_object($result)) { | |
| 284 | + $response = $this->_handleStruct($result); | |
| 285 | + } else { | |
| 286 | + $response = $this->_handleScalar($result); | |
| 287 | + } | |
| 288 | + | |
| 289 | + if (!$this->returnResponse()) { | |
| 290 | + if (!headers_sent()) { | |
| 291 | + foreach ($this->_headers as $header) { | |
| 292 | + header($header); | |
| 293 | + } | |
| 294 | + } | |
| 295 | + | |
| 296 | + echo $response; | |
| 297 | + return; | |
| 298 | + } | |
| 299 | + | |
| 300 | + return $response; | |
| 301 | + } | |
| 302 | + | |
| 303 | + /** | |
| 304 | + * Implement Rest_Interface::setClass() | |
| 305 | + * | |
| 306 | + * @param string $classname Class name | |
| 307 | + * @param string $namespace Class namespace (unused) | |
| 308 | + * @param array $argv An array of Constructor Arguments | |
| 309 | + */ | |
| 310 | + public function setClass($classname, $namespace = '', $argv = array()) | |
| 311 | + { | |
| 312 | + $this->_args = $argv; | |
| 313 | + foreach ($this->_reflection->reflectClass($classname, $argv)->getMethods() as $method) { | |
| 314 | + $this->_functions[$method->getName()] = $method; | |
| 315 | + } | |
| 316 | + } | |
| 317 | + | |
| 318 | + /** | |
| 319 | + * Handle an array or object result | |
| 320 | + * | |
| 321 | + * @param array|object $struct Result Value | |
| 322 | + * @return string XML Response | |
| 323 | + */ | |
| 324 | + protected function _handleStruct($struct) | |
| 325 | + { | |
| 326 | + $function = $this->_functions[$this->_method]; | |
| 327 | + if ($function instanceof Rest_Reflection_Method) { | |
| 328 | + $class = $function->getDeclaringClass()->getName(); | |
| 329 | + } else { | |
| 330 | + $class = false; | |
| 331 | + } | |
| 332 | + | |
| 333 | + $method = $function->getName(); | |
| 334 | + | |
| 335 | + $dom = new DOMDocument('1.0', $this->getEncoding()); | |
| 336 | + if ($class) { | |
| 337 | + $root = $dom->createElement($class); | |
| 338 | + $method = $dom->createElement($method); | |
| 339 | + $root->appendChild($method); | |
| 340 | + } else { | |
| 341 | + $root = $dom->createElement($method); | |
| 342 | + $method = $root; | |
| 343 | + } | |
| 344 | + $root->setAttribute('generator', 'Knowledgetree'); | |
| 345 | + $root->setAttribute('version', '1.0'); | |
| 346 | + $dom->appendChild($root); | |
| 347 | + | |
| 348 | + $this->_structValue($struct, $dom, $method); | |
| 349 | + | |
| 350 | + $struct = (array) $struct; | |
| 351 | + if (!isset($struct['status'])) { | |
| 352 | + $status = $dom->createElement('status', 'success'); | |
| 353 | + $method->appendChild($status); | |
| 354 | + } | |
| 355 | + | |
| 356 | + return $dom->saveXML(); | |
| 357 | + } | |
| 358 | + | |
| 359 | + /** | |
| 360 | + * Recursively iterate through a struct | |
| 361 | + * | |
| 362 | + * Recursively iterates through an associative array or object's properties | |
| 363 | + * to build XML response. | |
| 364 | + * | |
| 365 | + * @param mixed $struct | |
| 366 | + * @param DOMDocument $dom | |
| 367 | + * @param DOMElement $parent | |
| 368 | + * @return void | |
| 369 | + */ | |
| 370 | + protected function _structValue($struct, DOMDocument $dom, DOMElement $parent) | |
| 371 | + { | |
| 372 | + $struct = (array) $struct; | |
| 373 | + | |
| 374 | + foreach ($struct as $key => $value) { | |
| 375 | + if ($value === false) { | |
| 376 | + $value = 0; | |
| 377 | + } elseif ($value === true) { | |
| 378 | + $value = 1; | |
| 379 | + } | |
| 380 | + | |
| 381 | + if (ctype_digit((string) $key)) { | |
| 382 | + $key = 'key_' . $key; | |
| 383 | + } | |
| 384 | + | |
| 385 | + if (is_array($value) || is_object($value)) { | |
| 386 | + $element = $dom->createElement($key); | |
| 387 | + $this->_structValue($value, $dom, $element); | |
| 388 | + } else { | |
| 389 | + $element = $dom->createElement($key); | |
| 390 | + $element->appendChild($dom->createTextNode($value)); | |
| 391 | + } | |
| 392 | + | |
| 393 | + $parent->appendChild($element); | |
| 394 | + } | |
| 395 | + } | |
| 396 | + | |
| 397 | + /** | |
| 398 | + * Handle a single value | |
| 399 | + * | |
| 400 | + * @param string|int|boolean $value Result value | |
| 401 | + * @return string XML Response | |
| 402 | + */ | |
| 403 | + protected function _handleScalar($value) | |
| 404 | + { | |
| 405 | + $function = $this->_functions[$this->_method]; | |
| 406 | + if ($function instanceof Rest_Reflection_Method) { | |
| 407 | + $class = $function->getDeclaringClass()->getName(); | |
| 408 | + } else { | |
| 409 | + $class = false; | |
| 410 | + } | |
| 411 | + | |
| 412 | + $method = $function->getName(); | |
| 413 | + | |
| 414 | + $dom = new DOMDocument('1.0', $this->getEncoding()); | |
| 415 | + if ($class) { | |
| 416 | + $xml = $dom->createElement($class); | |
| 417 | + $methodNode = $dom->createElement($method); | |
| 418 | + $xml->appendChild($methodNode); | |
| 419 | + } else { | |
| 420 | + $xml = $dom->createElement($method); | |
| 421 | + $methodNode = $xml; | |
| 422 | + } | |
| 423 | + $xml->setAttribute('generator', 'KnowledgeTree'); | |
| 424 | + $xml->setAttribute('version', '1.0'); | |
| 425 | + $dom->appendChild($xml); | |
| 426 | + | |
| 427 | + if ($value === false) { | |
| 428 | + $value = 0; | |
| 429 | + } elseif ($value === true) { | |
| 430 | + $value = 1; | |
| 431 | + } | |
| 432 | + | |
| 433 | + if (isset($value)) { | |
| 434 | + $element = $dom->createElement('response'); | |
| 435 | + $element->appendChild($dom->createTextNode($value)); | |
| 436 | + $methodNode->appendChild($element); | |
| 437 | + } else { | |
| 438 | + $methodNode->appendChild($dom->createElement('response')); | |
| 439 | + } | |
| 440 | + | |
| 441 | + $methodNode->appendChild($dom->createElement('status', 'success')); | |
| 442 | + | |
| 443 | + return $dom->saveXML(); | |
| 444 | + } | |
| 445 | + | |
| 446 | + /** | |
| 447 | + * Implement Rest_Interface::fault() | |
| 448 | + * | |
| 449 | + * Creates XML error response, returning DOMDocument with response. | |
| 450 | + * | |
| 451 | + * @param string|Exception $fault Message | |
| 452 | + * @param int $code Error Code | |
| 453 | + * @return DOMDocument | |
| 454 | + */ | |
| 455 | + public function fault($exception = null, $code = null) | |
| 456 | + { | |
| 457 | + if (isset($this->_functions[$this->_method])) { | |
| 458 | + $function = $this->_functions[$this->_method]; | |
| 459 | + } elseif (isset($this->_method)) { | |
| 460 | + $function = $this->_method; | |
| 461 | + } else { | |
| 462 | + $function = 'rest'; | |
| 463 | + } | |
| 464 | + | |
| 465 | + if ($function instanceof Rest_Reflection_Method) { | |
| 466 | + $class = $function->getDeclaringClass()->getName(); | |
| 467 | + } else { | |
| 468 | + $class = false; | |
| 469 | + } | |
| 470 | + | |
| 471 | + if ($function instanceof Rest_Reflection_Function_Abstract) { | |
| 472 | + $method = $function->getName(); | |
| 473 | + } else { | |
| 474 | + $method = $function; | |
| 475 | + } | |
| 476 | + | |
| 477 | + $dom = new DOMDocument('1.0', $this->getEncoding()); | |
| 478 | + if ($class) { | |
| 479 | + $xml = $dom->createElement($class); | |
| 480 | + $xmlMethod = $dom->createElement($method); | |
| 481 | + $xml->appendChild($xmlMethod); | |
| 482 | + } else { | |
| 483 | + $xml = $dom->createElement($method); | |
| 484 | + $xmlMethod = $xml; | |
| 485 | + } | |
| 486 | + $xml->setAttribute('generator', 'KnowledgeTree'); | |
| 487 | + $xml->setAttribute('version', '1.0'); | |
| 488 | + $dom->appendChild($xml); | |
| 489 | + | |
| 490 | + $xmlResponse = $dom->createElement('response'); | |
| 491 | + $xmlMethod->appendChild($xmlResponse); | |
| 492 | + | |
| 493 | + if ($exception instanceof Exception) { | |
| 494 | + $element = $dom->createElement('message'); | |
| 495 | + $element->appendChild($dom->createTextNode($exception->getMessage())); | |
| 496 | + $xmlResponse->appendChild($element); | |
| 497 | + $code = $exception->getCode(); | |
| 498 | + } elseif (($exception !== null) || 'rest' == $function) { | |
| 499 | + $xmlResponse->appendChild($dom->createElement('message', 'An unknown error occured. Please try again.')); | |
| 500 | + } else { | |
| 501 | + $xmlResponse->appendChild($dom->createElement('message', 'Call to ' . $method . ' failed.')); | |
| 502 | + } | |
| 503 | + | |
| 504 | + $xmlMethod->appendChild($xmlResponse); | |
| 505 | + $xmlMethod->appendChild($dom->createElement('status', 'failed')); | |
| 506 | + | |
| 507 | + // Headers to send | |
| 508 | + if ($code === null || (404 != $code)) { | |
| 509 | + $this->_headers[] = 'HTTP/1.0 400 Bad Request'; | |
| 510 | + } else { | |
| 511 | + $this->_headers[] = 'HTTP/1.0 404 File Not Found'; | |
| 512 | + } | |
| 513 | + | |
| 514 | + return $dom; | |
| 515 | + } | |
| 516 | + | |
| 517 | + /** | |
| 518 | + * Retrieve any HTTP extra headers set by the server | |
| 519 | + * | |
| 520 | + * @return array | |
| 521 | + */ | |
| 522 | + public function getHeaders() | |
| 523 | + { | |
| 524 | + return $this->_headers; | |
| 525 | + } | |
| 526 | + | |
| 527 | + /** | |
| 528 | + * Implement Rest_Interface::addFunction() | |
| 529 | + * | |
| 530 | + * @param string $function Function Name | |
| 531 | + * @param string $namespace Function namespace (unused) | |
| 532 | + */ | |
| 533 | + public function addFunction($function, $namespace = '') | |
| 534 | + { | |
| 535 | + if (!is_array($function)) { | |
| 536 | + $function = (array) $function; | |
| 537 | + } | |
| 538 | + | |
| 539 | + foreach ($function as $func) { | |
| 540 | + if (is_callable($func) && !in_array($func, self::$magicMethods)) { | |
| 541 | + $this->_functions[$func] = $this->_reflection->reflectFunction($func); | |
| 542 | + } else { | |
| 543 | + throw new Rest_Exception("Invalid Method Added to Service."); | |
| 544 | + } | |
| 545 | + } | |
| 546 | + } | |
| 547 | + | |
| 548 | + /** | |
| 549 | + * Implement Rest_Interface::getFunctions() | |
| 550 | + * | |
| 551 | + * @return array An array of Rest_Reflection_Method's | |
| 552 | + */ | |
| 553 | + public function getFunctions() | |
| 554 | + { | |
| 555 | + return $this->_functions; | |
| 556 | + } | |
| 557 | + | |
| 558 | + /** | |
| 559 | + * Implement Rest_Interface::loadFunctions() | |
| 560 | + * | |
| 561 | + * @todo Implement | |
| 562 | + * @param array $functions | |
| 563 | + */ | |
| 564 | + public function loadFunctions($functions) | |
| 565 | + { | |
| 566 | + } | |
| 567 | + | |
| 568 | + /** | |
| 569 | + * Implement Rest_Interface::setPersistence() | |
| 570 | + * | |
| 571 | + * @todo Implement | |
| 572 | + * @param int $mode | |
| 573 | + */ | |
| 574 | + public function setPersistence($mode) | |
| 575 | + { | |
| 576 | + } | |
| 577 | + | |
| 578 | + /** | |
| 579 | + * Call a static class method and return the result | |
| 580 | + * | |
| 581 | + * @param string $class | |
| 582 | + * @param array $args | |
| 583 | + * @return mixed | |
| 584 | + */ | |
| 585 | + protected function _callStaticMethod($class, array $args) | |
| 586 | + { | |
| 587 | + try { | |
| 588 | + $result = call_user_func_array(array($class, $this->_functions[$this->_method]->getName()), $args); | |
| 589 | + } catch (Exception $e) { | |
| 590 | + $result = $this->fault($e); | |
| 591 | + } | |
| 592 | + return $result; | |
| 593 | + } | |
| 594 | + | |
| 595 | + /** | |
| 596 | + * Call an instance method of an object | |
| 597 | + * | |
| 598 | + * @param string $class | |
| 599 | + * @param array $args | |
| 600 | + * @return mixed | |
| 601 | + * @throws Rest_Exception For invalid class name | |
| 602 | + */ | |
| 603 | + protected function _callObjectMethod($class, array $args) | |
| 604 | + { | |
| 605 | + try { | |
| 606 | + if ($this->_functions[$this->_method]->getDeclaringClass()->getConstructor()) { | |
| 607 | + $object = $this->_functions[$this->_method]->getDeclaringClass()->newInstanceArgs($this->_args); | |
| 608 | + } else { | |
| 609 | + $object = $this->_functions[$this->_method]->getDeclaringClass()->newInstance(); | |
| 610 | + } | |
| 611 | + } catch (Exception $e) { | |
| 612 | + echo $e->getMessage(); | |
| 613 | + throw new Rest_Exception('Error instantiating class ' . $class . ' to invoke method ' . $this->_functions[$this->_method]->getName(), 500); | |
| 614 | + } | |
| 615 | + | |
| 616 | + try { | |
| 617 | + $result = $this->_functions[$this->_method]->invokeArgs($object, $args); | |
| 618 | + } catch (Exception $e) { | |
| 619 | + $result = $this->fault($e); | |
| 620 | + } | |
| 621 | + | |
| 622 | + return $result; | |
| 623 | + } | |
| 624 | +} | ... | ... |
webservice/classes/rest/method/Callback.php
0 → 100644
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * Method callback metadata | |
| 4 | + * | |
| 5 | + */ | |
| 6 | +class Rest_Method_Callback | |
| 7 | +{ | |
| 8 | + /** | |
| 9 | + * @var string Class name for class method callback | |
| 10 | + */ | |
| 11 | + protected $_class; | |
| 12 | + | |
| 13 | + /** | |
| 14 | + * @var string Function name for function callback | |
| 15 | + */ | |
| 16 | + protected $_function; | |
| 17 | + | |
| 18 | + /** | |
| 19 | + * @var string Method name for class method callback | |
| 20 | + */ | |
| 21 | + protected $_method; | |
| 22 | + | |
| 23 | + /** | |
| 24 | + * @var string Callback type | |
| 25 | + */ | |
| 26 | + protected $_type; | |
| 27 | + | |
| 28 | + /** | |
| 29 | + * @var array Valid callback types | |
| 30 | + */ | |
| 31 | + protected $_types = array('function', 'static', 'instance'); | |
| 32 | + | |
| 33 | + /** | |
| 34 | + * Constructor | |
| 35 | + * | |
| 36 | + * @param null|array $options | |
| 37 | + * @return void | |
| 38 | + */ | |
| 39 | + public function __construct($options = null) | |
| 40 | + { | |
| 41 | + if ((null !== $options) && is_array($options)) { | |
| 42 | + $this->setOptions($options); | |
| 43 | + } | |
| 44 | + } | |
| 45 | + | |
| 46 | + /** | |
| 47 | + * Set object state from array of options | |
| 48 | + * | |
| 49 | + * @param array $options | |
| 50 | + * @return Rest_Method_Callback | |
| 51 | + */ | |
| 52 | + public function setOptions(array $options) | |
| 53 | + { | |
| 54 | + foreach ($options as $key => $value) { | |
| 55 | + $method = 'set' . ucfirst($key); | |
| 56 | + if (method_exists($this, $method)) { | |
| 57 | + $this->$method($value); | |
| 58 | + } | |
| 59 | + } | |
| 60 | + return $this; | |
| 61 | + } | |
| 62 | + | |
| 63 | + /** | |
| 64 | + * Set callback class | |
| 65 | + * | |
| 66 | + * @param string $class | |
| 67 | + * @return Rest_Method_Callback | |
| 68 | + */ | |
| 69 | + public function setClass($class) | |
| 70 | + { | |
| 71 | + if (is_object($class)) { | |
| 72 | + $class = get_class($class); | |
| 73 | + } | |
| 74 | + $this->_class = $class; | |
| 75 | + return $this; | |
| 76 | + } | |
| 77 | + | |
| 78 | + /** | |
| 79 | + * Get callback class | |
| 80 | + * | |
| 81 | + * @return string|null | |
| 82 | + */ | |
| 83 | + public function getClass() | |
| 84 | + { | |
| 85 | + return $this->_class; | |
| 86 | + } | |
| 87 | + | |
| 88 | + /** | |
| 89 | + * Set callback function | |
| 90 | + * | |
| 91 | + * @param string $function | |
| 92 | + * @return Rest_Method_Callback | |
| 93 | + */ | |
| 94 | + public function setFunction($function) | |
| 95 | + { | |
| 96 | + $this->_function = (string) $function; | |
| 97 | + $this->setType('function'); | |
| 98 | + return $this; | |
| 99 | + } | |
| 100 | + | |
| 101 | + /** | |
| 102 | + * Get callback function | |
| 103 | + * | |
| 104 | + * @return null|string | |
| 105 | + */ | |
| 106 | + public function getFunction() | |
| 107 | + { | |
| 108 | + return $this->_function; | |
| 109 | + } | |
| 110 | + | |
| 111 | + /** | |
| 112 | + * Set callback class method | |
| 113 | + * | |
| 114 | + * @param string $method | |
| 115 | + * @return Rest_Method_Callback | |
| 116 | + */ | |
| 117 | + public function setMethod($method) | |
| 118 | + { | |
| 119 | + $this->_method = $method; | |
| 120 | + return $this; | |
| 121 | + } | |
| 122 | + | |
| 123 | + /** | |
| 124 | + * Get callback class method | |
| 125 | + * | |
| 126 | + * @return null|string | |
| 127 | + */ | |
| 128 | + public function getMethod() | |
| 129 | + { | |
| 130 | + return $this->_method; | |
| 131 | + } | |
| 132 | + | |
| 133 | + /** | |
| 134 | + * Set callback type | |
| 135 | + * | |
| 136 | + * @param string $type | |
| 137 | + * @return Rest_Method_Callback | |
| 138 | + * @throws Exception | |
| 139 | + */ | |
| 140 | + public function setType($type) | |
| 141 | + { | |
| 142 | + if (!in_array($type, $this->_types)) { | |
| 143 | + require_once 'classes/rest/Exception.php'; | |
| 144 | + throw new Rest_Exception('Invalid method callback type passed to ' . __CLASS__ . '::' . __METHOD__); | |
| 145 | + } | |
| 146 | + $this->_type = $type; | |
| 147 | + return $this; | |
| 148 | + } | |
| 149 | + | |
| 150 | + /** | |
| 151 | + * Get callback type | |
| 152 | + * | |
| 153 | + * @return string | |
| 154 | + */ | |
| 155 | + public function getType() | |
| 156 | + { | |
| 157 | + return $this->_type; | |
| 158 | + } | |
| 159 | + | |
| 160 | + /** | |
| 161 | + * Cast callback to array | |
| 162 | + * | |
| 163 | + * @return array | |
| 164 | + */ | |
| 165 | + public function toArray() | |
| 166 | + { | |
| 167 | + $type = $this->getType(); | |
| 168 | + $array = array( | |
| 169 | + 'type' => $type, | |
| 170 | + ); | |
| 171 | + if ('function' == $type) { | |
| 172 | + $array['function'] = $this->getFunction(); | |
| 173 | + } else { | |
| 174 | + $array['class'] = $this->getClass(); | |
| 175 | + $array['method'] = $this->getMethod(); | |
| 176 | + } | |
| 177 | + return $array; | |
| 178 | + } | |
| 179 | +} | ... | ... |
webservice/classes/rest/method/Definition.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Method definition metadata | |
| 5 | + * | |
| 6 | + */ | |
| 7 | +class Rest_Method_Definition | |
| 8 | +{ | |
| 9 | + /** | |
| 10 | + * @var Rest_Method_Callback | |
| 11 | + */ | |
| 12 | + protected $_callback; | |
| 13 | + | |
| 14 | + /** | |
| 15 | + * @var array | |
| 16 | + */ | |
| 17 | + protected $_invokeArguments = array(); | |
| 18 | + | |
| 19 | + /** | |
| 20 | + * @var string | |
| 21 | + */ | |
| 22 | + protected $_methodHelp = ''; | |
| 23 | + | |
| 24 | + /** | |
| 25 | + * @var string | |
| 26 | + */ | |
| 27 | + protected $_name; | |
| 28 | + | |
| 29 | + /** | |
| 30 | + * @var null|object | |
| 31 | + */ | |
| 32 | + protected $_object; | |
| 33 | + | |
| 34 | + /** | |
| 35 | + * @var array Array of Rest_Method_Prototype objects | |
| 36 | + */ | |
| 37 | + protected $_prototypes = array(); | |
| 38 | + | |
| 39 | + /** | |
| 40 | + * Constructor | |
| 41 | + * | |
| 42 | + * @param null|array $options | |
| 43 | + * @return void | |
| 44 | + */ | |
| 45 | + public function __construct($options = null) | |
| 46 | + { | |
| 47 | + if ((null !== $options) && is_array($options)) { | |
| 48 | + $this->setOptions($options); | |
| 49 | + } | |
| 50 | + } | |
| 51 | + | |
| 52 | + /** | |
| 53 | + * Set object state from options | |
| 54 | + * | |
| 55 | + * @param array $options | |
| 56 | + * @return Rest_Method_Definition | |
| 57 | + */ | |
| 58 | + public function setOptions(array $options) | |
| 59 | + { | |
| 60 | + foreach ($options as $key => $value) { | |
| 61 | + $method = 'set' . ucfirst($key); | |
| 62 | + if (method_exists($this, $method)) { | |
| 63 | + $this->$method($value); | |
| 64 | + } | |
| 65 | + } | |
| 66 | + return $this; | |
| 67 | + } | |
| 68 | + | |
| 69 | + /** | |
| 70 | + * Set method name | |
| 71 | + * | |
| 72 | + * @param string $name | |
| 73 | + * @return Rest_Method_Definition | |
| 74 | + */ | |
| 75 | + public function setName($name) | |
| 76 | + { | |
| 77 | + $this->_name = (string) $name; | |
| 78 | + return $this; | |
| 79 | + } | |
| 80 | + | |
| 81 | + /** | |
| 82 | + * Get method name | |
| 83 | + * | |
| 84 | + * @return string | |
| 85 | + */ | |
| 86 | + public function getName() | |
| 87 | + { | |
| 88 | + return $this->_name; | |
| 89 | + } | |
| 90 | + | |
| 91 | + /** | |
| 92 | + * Set method callback | |
| 93 | + * | |
| 94 | + * @param array|Rest_Method_Callback $callback | |
| 95 | + * @return Rest_Method_Definition | |
| 96 | + */ | |
| 97 | + public function setCallback($callback) | |
| 98 | + { | |
| 99 | + if (is_array($callback)) { | |
| 100 | + $callback = new Rest_Method_Callback($callback); | |
| 101 | + } elseif (!$callback instanceof Rest_Method_Callback) { | |
| 102 | + require_once 'classes/rest/Exception.php'; | |
| 103 | + throw new Rest_Exception('Invalid method callback provided'); | |
| 104 | + } | |
| 105 | + $this->_callback = $callback; | |
| 106 | + return $this; | |
| 107 | + } | |
| 108 | + | |
| 109 | + /** | |
| 110 | + * Get method callback | |
| 111 | + * | |
| 112 | + * @return Rest_Method_Callback | |
| 113 | + */ | |
| 114 | + public function getCallback() | |
| 115 | + { | |
| 116 | + return $this->_callback; | |
| 117 | + } | |
| 118 | + | |
| 119 | + /** | |
| 120 | + * Add prototype to method definition | |
| 121 | + * | |
| 122 | + * @param array|Rest_Method_Prototype $prototype | |
| 123 | + * @return Rest_Method_Definition | |
| 124 | + */ | |
| 125 | + public function addPrototype($prototype) | |
| 126 | + { | |
| 127 | + if (is_array($prototype)) { | |
| 128 | + require_once 'Prototype.php'; | |
| 129 | + $prototype = new Rest_Method_Prototype($prototype); | |
| 130 | + } elseif (!$prototype instanceof Rest_Method_Prototype) { | |
| 131 | + require_once 'classes/rest/Exception.php'; | |
| 132 | + throw new Rest_Exception('Invalid method prototype provided'); | |
| 133 | + } | |
| 134 | + $this->_prototypes[] = $prototype; | |
| 135 | + return $this; | |
| 136 | + } | |
| 137 | + | |
| 138 | + /** | |
| 139 | + * Add multiple prototypes at once | |
| 140 | + * | |
| 141 | + * @param array $prototypes Array of Rest_Method_Prototype objects or arrays | |
| 142 | + * @return Rest_Method_Definition | |
| 143 | + */ | |
| 144 | + public function addPrototypes(array $prototypes) | |
| 145 | + { | |
| 146 | + foreach ($prototypes as $prototype) { | |
| 147 | + $this->addPrototype($prototype); | |
| 148 | + } | |
| 149 | + return $this; | |
| 150 | + } | |
| 151 | + | |
| 152 | + /** | |
| 153 | + * Set all prototypes at once (overwrites) | |
| 154 | + * | |
| 155 | + * @param array $prototypes Array of Rest_Method_Prototype objects or arrays | |
| 156 | + * @return Rest_Method_Definition | |
| 157 | + */ | |
| 158 | + public function setPrototypes(array $prototypes) | |
| 159 | + { | |
| 160 | + $this->_prototypes = array(); | |
| 161 | + $this->addPrototypes($prototypes); | |
| 162 | + return $this; | |
| 163 | + } | |
| 164 | + | |
| 165 | + /** | |
| 166 | + * Get all prototypes | |
| 167 | + * | |
| 168 | + * @return array $prototypes Array of Rest_Method_Prototype objects or arrays | |
| 169 | + */ | |
| 170 | + public function getPrototypes() | |
| 171 | + { | |
| 172 | + return $this->_prototypes; | |
| 173 | + } | |
| 174 | + | |
| 175 | + /** | |
| 176 | + * Set method help | |
| 177 | + * | |
| 178 | + * @param string $methodHelp | |
| 179 | + * @return Rest_Method_Definition | |
| 180 | + */ | |
| 181 | + public function setMethodHelp($methodHelp) | |
| 182 | + { | |
| 183 | + $this->_methodHelp = (string) $methodHelp; | |
| 184 | + return $this; | |
| 185 | + } | |
| 186 | + | |
| 187 | + /** | |
| 188 | + * Get method help | |
| 189 | + * | |
| 190 | + * @return string | |
| 191 | + */ | |
| 192 | + public function getMethodHelp() | |
| 193 | + { | |
| 194 | + return $this->_methodHelp; | |
| 195 | + } | |
| 196 | + | |
| 197 | + /** | |
| 198 | + * Set object to use with method calls | |
| 199 | + * | |
| 200 | + * @param object $object | |
| 201 | + * @return Rest_Method_Definition | |
| 202 | + */ | |
| 203 | + public function setObject($object) | |
| 204 | + { | |
| 205 | + if (!is_object($object) && (null !== $object)) { | |
| 206 | + require_once 'classes/rest/Exception.php'; | |
| 207 | + throw new Rest_Exception('Invalid object passed to ' . __CLASS__ . '::' . __METHOD__); | |
| 208 | + } | |
| 209 | + $this->_object = $object; | |
| 210 | + return $this; | |
| 211 | + } | |
| 212 | + | |
| 213 | + /** | |
| 214 | + * Get object to use with method calls | |
| 215 | + * | |
| 216 | + * @return null|object | |
| 217 | + */ | |
| 218 | + public function getObject() | |
| 219 | + { | |
| 220 | + return $this->_object; | |
| 221 | + } | |
| 222 | + | |
| 223 | + /** | |
| 224 | + * Set invoke arguments | |
| 225 | + * | |
| 226 | + * @param array $invokeArguments | |
| 227 | + * @return Rest_Method_Definition | |
| 228 | + */ | |
| 229 | + public function setInvokeArguments(array $invokeArguments) | |
| 230 | + { | |
| 231 | + $this->_invokeArguments = $invokeArguments; | |
| 232 | + return $this; | |
| 233 | + } | |
| 234 | + | |
| 235 | + /** | |
| 236 | + * Retrieve invoke arguments | |
| 237 | + * | |
| 238 | + * @return array | |
| 239 | + */ | |
| 240 | + public function getInvokeArguments() | |
| 241 | + { | |
| 242 | + return $this->_invokeArguments; | |
| 243 | + } | |
| 244 | + | |
| 245 | + /** | |
| 246 | + * Serialize to array | |
| 247 | + * | |
| 248 | + * @return array | |
| 249 | + */ | |
| 250 | + public function toArray() | |
| 251 | + { | |
| 252 | + $prototypes = $this->getPrototypes(); | |
| 253 | + $signatures = array(); | |
| 254 | + foreach ($prototypes as $prototype) { | |
| 255 | + $signatures[] = $prototype->toArray(); | |
| 256 | + } | |
| 257 | + | |
| 258 | + return array( | |
| 259 | + 'name' => $this->getName(), | |
| 260 | + 'callback' => $this->getCallback()->toArray(), | |
| 261 | + 'prototypes' => $signatures, | |
| 262 | + 'methodHelp' => $this->getMethodHelp(), | |
| 263 | + 'invokeArguments' => $this->getInvokeArguments(), | |
| 264 | + 'object' => $this->getObject(), | |
| 265 | + ); | |
| 266 | + } | |
| 267 | +} | ... | ... |
webservice/classes/rest/method/Parameter.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | + | |
| 4 | +/** | |
| 5 | + * Method parameter metadata | |
| 6 | + * | |
| 7 | + * | |
| 8 | + */ | |
| 9 | +class Rest_Method_Parameter | |
| 10 | +{ | |
| 11 | + /** | |
| 12 | + * @var mixed Default parameter value | |
| 13 | + */ | |
| 14 | + protected $_defaultValue; | |
| 15 | + | |
| 16 | + /** | |
| 17 | + * @var string Parameter description | |
| 18 | + */ | |
| 19 | + protected $_description = ''; | |
| 20 | + | |
| 21 | + /** | |
| 22 | + * @var string Parameter variable name | |
| 23 | + */ | |
| 24 | + protected $_name; | |
| 25 | + | |
| 26 | + /** | |
| 27 | + * @var bool Is parameter optional? | |
| 28 | + */ | |
| 29 | + protected $_optional = false; | |
| 30 | + | |
| 31 | + /** | |
| 32 | + * @var string Parameter type | |
| 33 | + */ | |
| 34 | + protected $_type = 'mixed'; | |
| 35 | + | |
| 36 | + /** | |
| 37 | + * Constructor | |
| 38 | + * | |
| 39 | + * @param null|array $options | |
| 40 | + * @return void | |
| 41 | + */ | |
| 42 | + public function __construct($options = null) | |
| 43 | + { | |
| 44 | + if (is_array($options)) { | |
| 45 | + $this->setOptions($options); | |
| 46 | + } | |
| 47 | + } | |
| 48 | + | |
| 49 | + /** | |
| 50 | + * Set object state from array of options | |
| 51 | + * | |
| 52 | + * @param array $options | |
| 53 | + * @return Rest_Method_Parameter | |
| 54 | + */ | |
| 55 | + public function setOptions(array $options) | |
| 56 | + { | |
| 57 | + foreach ($options as $key => $value) { | |
| 58 | + $method = 'set' . ucfirst($key); | |
| 59 | + if (method_exists($this, $method)) { | |
| 60 | + $this->$method($value); | |
| 61 | + } | |
| 62 | + } | |
| 63 | + return $this; | |
| 64 | + } | |
| 65 | + | |
| 66 | + /** | |
| 67 | + * Set default value | |
| 68 | + * | |
| 69 | + * @param mixed $defaultValue | |
| 70 | + * @return Rest_Method_Parameter | |
| 71 | + */ | |
| 72 | + public function setDefaultValue($defaultValue) | |
| 73 | + { | |
| 74 | + $this->_defaultValue = $defaultValue; | |
| 75 | + return $this; | |
| 76 | + } | |
| 77 | + | |
| 78 | + /** | |
| 79 | + * Retrieve default value | |
| 80 | + * | |
| 81 | + * @return mixed | |
| 82 | + */ | |
| 83 | + public function getDefaultValue() | |
| 84 | + { | |
| 85 | + return $this->_defaultValue; | |
| 86 | + } | |
| 87 | + | |
| 88 | + /** | |
| 89 | + * Set description | |
| 90 | + * | |
| 91 | + * @param string $description | |
| 92 | + * @return Rest_Method_Parameter | |
| 93 | + */ | |
| 94 | + public function setDescription($description) | |
| 95 | + { | |
| 96 | + $this->_description = (string) $description; | |
| 97 | + return $this; | |
| 98 | + } | |
| 99 | + | |
| 100 | + /** | |
| 101 | + * Retrieve description | |
| 102 | + * | |
| 103 | + * @return string | |
| 104 | + */ | |
| 105 | + public function getDescription() | |
| 106 | + { | |
| 107 | + return $this->_description; | |
| 108 | + } | |
| 109 | + | |
| 110 | + /** | |
| 111 | + * Set name | |
| 112 | + * | |
| 113 | + * @param string $name | |
| 114 | + * @return Rest_Method_Parameter | |
| 115 | + */ | |
| 116 | + public function setName($name) | |
| 117 | + { | |
| 118 | + $this->_name = (string) $name; | |
| 119 | + return $this; | |
| 120 | + } | |
| 121 | + | |
| 122 | + /** | |
| 123 | + * Retrieve name | |
| 124 | + * | |
| 125 | + * @return string | |
| 126 | + */ | |
| 127 | + public function getName() | |
| 128 | + { | |
| 129 | + return $this->_name; | |
| 130 | + } | |
| 131 | + | |
| 132 | + /** | |
| 133 | + * Set optional flag | |
| 134 | + * | |
| 135 | + * @param bool $flag | |
| 136 | + * @return Rest_Method_Parameter | |
| 137 | + */ | |
| 138 | + public function setOptional($flag) | |
| 139 | + { | |
| 140 | + $this->_optional = (bool) $flag; | |
| 141 | + return $this; | |
| 142 | + } | |
| 143 | + | |
| 144 | + /** | |
| 145 | + * Is the parameter optional? | |
| 146 | + * | |
| 147 | + * @return bool | |
| 148 | + */ | |
| 149 | + public function isOptional() | |
| 150 | + { | |
| 151 | + return $this->_optional; | |
| 152 | + } | |
| 153 | + | |
| 154 | + /** | |
| 155 | + * Set parameter type | |
| 156 | + * | |
| 157 | + * @param string $type | |
| 158 | + * @return Rest_Method_Parameter | |
| 159 | + */ | |
| 160 | + public function setType($type) | |
| 161 | + { | |
| 162 | + $this->_type = (string) $type; | |
| 163 | + return $this; | |
| 164 | + } | |
| 165 | + | |
| 166 | + /** | |
| 167 | + * Retrieve parameter type | |
| 168 | + * | |
| 169 | + * @return string | |
| 170 | + */ | |
| 171 | + public function getType() | |
| 172 | + { | |
| 173 | + return $this->_type; | |
| 174 | + } | |
| 175 | + | |
| 176 | + /** | |
| 177 | + * Cast to array | |
| 178 | + * | |
| 179 | + * @return array | |
| 180 | + */ | |
| 181 | + public function toArray() | |
| 182 | + { | |
| 183 | + return array( | |
| 184 | + 'type' => $this->getType(), | |
| 185 | + 'name' => $this->getName(), | |
| 186 | + 'optional' => $this->isOptional(), | |
| 187 | + 'defaultValue' => $this->getDefaultValue(), | |
| 188 | + 'description' => $this->getDescription(), | |
| 189 | + ); | |
| 190 | + } | |
| 191 | +} | ... | ... |
webservice/classes/rest/method/Prototype.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | + | |
| 4 | +/** | |
| 5 | + * Method prototype metadata | |
| 6 | + * | |
| 7 | + * | |
| 8 | + */ | |
| 9 | +class Rest_Method_Prototype | |
| 10 | +{ | |
| 11 | + /** | |
| 12 | + * @var string Return type | |
| 13 | + */ | |
| 14 | + protected $_returnType = 'void'; | |
| 15 | + | |
| 16 | + /** | |
| 17 | + * @var array Map parameter names to parameter index | |
| 18 | + */ | |
| 19 | + protected $_parameterNameMap = array(); | |
| 20 | + | |
| 21 | + /** | |
| 22 | + * @var array Method parameters | |
| 23 | + */ | |
| 24 | + protected $_parameters = array(); | |
| 25 | + | |
| 26 | + /** | |
| 27 | + * Constructor | |
| 28 | + * | |
| 29 | + * @param null|array $options | |
| 30 | + * @return void | |
| 31 | + */ | |
| 32 | + public function __construct($options = null) | |
| 33 | + { | |
| 34 | + if ((null !== $options) && is_array($options)) { | |
| 35 | + $this->setOptions($options); | |
| 36 | + } | |
| 37 | + } | |
| 38 | + | |
| 39 | + /** | |
| 40 | + * Set return value | |
| 41 | + * | |
| 42 | + * @param string $returnType | |
| 43 | + * @return Rest_Method_Prototype | |
| 44 | + */ | |
| 45 | + public function setReturnType($returnType) | |
| 46 | + { | |
| 47 | + $this->_returnType = $returnType; | |
| 48 | + return $this; | |
| 49 | + } | |
| 50 | + | |
| 51 | + /** | |
| 52 | + * Retrieve return type | |
| 53 | + * | |
| 54 | + * @return string | |
| 55 | + */ | |
| 56 | + public function getReturnType() | |
| 57 | + { | |
| 58 | + return $this->_returnType; | |
| 59 | + } | |
| 60 | + | |
| 61 | + /** | |
| 62 | + * Add a parameter | |
| 63 | + * | |
| 64 | + * @param string $parameter | |
| 65 | + * @return Rest_Method_Prototype | |
| 66 | + */ | |
| 67 | + public function addParameter($parameter) | |
| 68 | + { | |
| 69 | + if ($parameter instanceof Rest_Method_Parameter) { | |
| 70 | + $this->_parameters[] = $parameter; | |
| 71 | + if (null !== ($name = $parameter->getName())) { | |
| 72 | + $this->_parameterNameMap[$name] = count($this->_parameters) - 1; | |
| 73 | + } | |
| 74 | + } else { | |
| 75 | + $parameter = new Rest_Method_Parameter(array( | |
| 76 | + 'type' => (string) $parameter, | |
| 77 | + )); | |
| 78 | + $this->_parameters[] = $parameter; | |
| 79 | + } | |
| 80 | + return $this; | |
| 81 | + } | |
| 82 | + | |
| 83 | + /** | |
| 84 | + * Add parameters | |
| 85 | + * | |
| 86 | + * @param array $parameter | |
| 87 | + * @return Rest_Method_Prototype | |
| 88 | + */ | |
| 89 | + public function addParameters(array $parameters) | |
| 90 | + { | |
| 91 | + foreach ($parameters as $parameter) { | |
| 92 | + $this->addParameter($parameter); | |
| 93 | + } | |
| 94 | + return $this; | |
| 95 | + } | |
| 96 | + | |
| 97 | + /** | |
| 98 | + * Set parameters | |
| 99 | + * | |
| 100 | + * @param array $parameters | |
| 101 | + * @return Rest_Method_Prototype | |
| 102 | + */ | |
| 103 | + public function setParameters(array $parameters) | |
| 104 | + { | |
| 105 | + $this->_parameters = array(); | |
| 106 | + $this->_parameterNameMap = array(); | |
| 107 | + $this->addParameters($parameters); | |
| 108 | + return $this; | |
| 109 | + } | |
| 110 | + | |
| 111 | + /** | |
| 112 | + * Retrieve parameters as list of types | |
| 113 | + * | |
| 114 | + * @return array | |
| 115 | + */ | |
| 116 | + public function getParameters() | |
| 117 | + { | |
| 118 | + $types = array(); | |
| 119 | + foreach ($this->_parameters as $parameter) { | |
| 120 | + $types[] = $parameter->getType(); | |
| 121 | + } | |
| 122 | + return $types; | |
| 123 | + } | |
| 124 | + | |
| 125 | + /** | |
| 126 | + * Get parameter objects | |
| 127 | + * | |
| 128 | + * @return array | |
| 129 | + */ | |
| 130 | + public function getParameterObjects() | |
| 131 | + { | |
| 132 | + return $this->_parameters; | |
| 133 | + } | |
| 134 | + | |
| 135 | + /** | |
| 136 | + * Retrieve a single parameter by name or index | |
| 137 | + * | |
| 138 | + * @param string|int $index | |
| 139 | + * @return null Rest_Server_Method_Parameter | |
| 140 | + */ | |
| 141 | + public function getParameter($index) | |
| 142 | + { | |
| 143 | + if (!is_string($index) && !is_numeric($index)) { | |
| 144 | + return null; | |
| 145 | + } | |
| 146 | + if (array_key_exists($index, $this->_parameterNameMap)) { | |
| 147 | + $index = $this->_parameterNameMap[$index]; | |
| 148 | + } | |
| 149 | + if (array_key_exists($index, $this->_parameters)) { | |
| 150 | + return $this->_parameters[$index]; | |
| 151 | + } | |
| 152 | + return null; | |
| 153 | + } | |
| 154 | + | |
| 155 | + /** | |
| 156 | + * Set object state from array | |
| 157 | + * | |
| 158 | + * @param array $options | |
| 159 | + * @return Rest_Method_Prototype | |
| 160 | + */ | |
| 161 | + public function setOptions(array $options) | |
| 162 | + { | |
| 163 | + foreach ($options as $key => $value) { | |
| 164 | + $method = 'set' . ucfirst($key); | |
| 165 | + if (method_exists($this, $method)) { | |
| 166 | + $this->$method($value); | |
| 167 | + } | |
| 168 | + } | |
| 169 | + return $this; | |
| 170 | + } | |
| 171 | + | |
| 172 | + /** | |
| 173 | + * Serialize to array | |
| 174 | + * | |
| 175 | + * @return array | |
| 176 | + */ | |
| 177 | + public function toArray() | |
| 178 | + { | |
| 179 | + return array( | |
| 180 | + 'returnType' => $this->getReturnType(), | |
| 181 | + 'parameters' => $this->getParameters(), | |
| 182 | + ); | |
| 183 | + } | |
| 184 | +} | ... | ... |
webservice/classes/rest/model/RestService.class.php
0 → 100755
| 1 | +<?php | |
| 2 | +/** | |
| 3 | +* Implements a cleaner wrapper restservice and webservice API for KnowledgeTree. | |
| 4 | +* | |
| 5 | +* KnowledgeTree Community Edition | |
| 6 | +* Document Management Made Simple | |
| 7 | +* Copyright (C) 2008,2009 KnowledgeTree Inc. | |
| 8 | +* Portions copyright The Jam Warehouse Software (Pty) Limited | |
| 9 | +* | |
| 10 | +* This program is free software; you can redistribute it and/or modify it under | |
| 11 | +* the terms of the GNU General Public License version 3 as published by the | |
| 12 | +* Free Software Foundation. | |
| 13 | +* | |
| 14 | +* This program is distributed in the hope that it will be useful, but WITHOUT | |
| 15 | +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
| 16 | +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
| 17 | +* details. | |
| 18 | +* | |
| 19 | +* You should have received a copy of the GNU General Public License | |
| 20 | +* along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 21 | +* | |
| 22 | +* You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco, | |
| 23 | +* California 94120-7775, or email info@knowledgetree.com. | |
| 24 | +* | |
| 25 | +* The interactive user interfaces in modified source and object code versions | |
| 26 | +* of this program must display Appropriate Legal Notices, as required under | |
| 27 | +* Section 5 of the GNU General Public License version 3. | |
| 28 | +* | |
| 29 | +* In accordance with Section 7(b) of the GNU General Public License version 3, | |
| 30 | +* these Appropriate Legal Notices must retain the display of the "Powered by | |
| 31 | +* KnowledgeTree" logo and retain the original copyright notice. If the display of the | |
| 32 | +* logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices | |
| 33 | +* must display the words "Powered by KnowledgeTree" and retain the original | |
| 34 | +* copyright notice. | |
| 35 | +* | |
| 36 | +* @copyright 2008-2009, KnowledgeTree Inc. | |
| 37 | +* @license GNU General Public License version 3 | |
| 38 | +* @author KnowledgeTree Team | |
| 39 | +* @package Webservice | |
| 40 | +* @version Version 0.1 | |
| 41 | +*/ | |
| 42 | + | |
| 43 | + | |
| 44 | +/** | |
| 45 | + * Class Service - will act as a switch between | |
| 46 | + * SOAP requests and REST requests | |
| 47 | + *@author KnowledgeTree Team | |
| 48 | + *@package Webservice | |
| 49 | + *@version Version 0.9 | |
| 50 | + */ | |
| 51 | +class RestService | |
| 52 | +{ | |
| 53 | + /** | |
| 54 | + * Class construct | |
| 55 | + * | |
| 56 | + * @param object_type $object | |
| 57 | + * @return jason encoded string | |
| 58 | + */ | |
| 59 | + public function __construct($object) | |
| 60 | + { | |
| 61 | + try { | |
| 62 | + | |
| 63 | + $result = $this->runAsService($object); | |
| 64 | + echo jason_encode(array('status_code' => 0,'result' => $result)); | |
| 65 | + | |
| 66 | + } catch (Exception $e) { | |
| 67 | + echo json_encode(array('status_code' => 1,'result' => $e->getMessage())); | |
| 68 | + } | |
| 69 | + } | |
| 70 | + | |
| 71 | + /** | |
| 72 | + * Constructor for invoking a reflection object | |
| 73 | + * Initiates the object as a service | |
| 74 | + * @param class $object | |
| 75 | + * @access private | |
| 76 | + * @return class instance | |
| 77 | + */ | |
| 78 | + | |
| 79 | + public function getJason() | |
| 80 | + { | |
| 81 | + $result = $this->runAsService($object); | |
| 82 | + return $result; | |
| 83 | + | |
| 84 | + } | |
| 85 | + | |
| 86 | + private function runAsService($object) | |
| 87 | + { | |
| 88 | + | |
| 89 | + if (!isset($_GET['class'])) { | |
| 90 | + | |
| 91 | + throw new Exception('Method name not specified.'); | |
| 92 | + } | |
| 93 | + | |
| 94 | + $reflObject = new ReflectionObject($object); | |
| 95 | + | |
| 96 | + if (!$reflObject->hasMethod($_GET['class'])) { | |
| 97 | + | |
| 98 | + throw new Exception('There is no method with this name.'); | |
| 99 | + | |
| 100 | + } | |
| 101 | + | |
| 102 | + $reflMethod = $reflObject->getMethod($_GET['method']); | |
| 103 | + | |
| 104 | + if ( !$reflMethod->isPublic() || $reflMethod->isStatic() || $reflMethod->isInternal() ) { | |
| 105 | + | |
| 106 | + throw new Exception('Invalid method name specified.'); | |
| 107 | + | |
| 108 | + } | |
| 109 | + | |
| 110 | + $reflParameters = $reflMethod->getParameters(); | |
| 111 | + | |
| 112 | + $args = array(); | |
| 113 | + | |
| 114 | + | |
| 115 | + foreach ($reflParameters as $param) { | |
| 116 | + | |
| 117 | + $paramName = $param->getName(); | |
| 118 | + | |
| 119 | + if (!isset($_GET[$paramName])) { | |
| 120 | + | |
| 121 | + if ($param->isDefaultValueAvailable()) { | |
| 122 | + | |
| 123 | + $paramValue = $param->getDefaultValue(); | |
| 124 | + | |
| 125 | + } else { | |
| 126 | + | |
| 127 | + throw new Exception('Required parameter "'.$paramName.'" is not specified.'); | |
| 128 | + | |
| 129 | + } | |
| 130 | + | |
| 131 | + } else { | |
| 132 | + | |
| 133 | + $paramValue = $_GET[$paramName]; | |
| 134 | + | |
| 135 | + } | |
| 136 | + | |
| 137 | + | |
| 138 | + if ($param->getClass()) { | |
| 139 | + | |
| 140 | + throw new Exception('The method contains unsupported parameter type: class object.'); | |
| 141 | + | |
| 142 | + } | |
| 143 | + | |
| 144 | + | |
| 145 | + if ($param->isArray() && !is_array($paramValue)) { | |
| 146 | + | |
| 147 | + throw new Exception('Array expected for parameter "'.$paramName.'", but scalar found.'); | |
| 148 | + | |
| 149 | + } | |
| 150 | + | |
| 151 | + | |
| 152 | + $args[$param->getPosition()] = $paramValue; | |
| 153 | + | |
| 154 | + } | |
| 155 | + | |
| 156 | + return $reflMethod->invokeArgs($object, $args); | |
| 157 | + | |
| 158 | + } | |
| 159 | + | |
| 160 | +} | |
| 161 | + | |
| 162 | +?> | |
| 0 | 163 | \ No newline at end of file | ... | ... |
webservice/classes/rest/model/address.class.php
0 → 100755
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Stores an address | |
| 5 | + * | |
| 6 | + * An address consists of a street, number, zipcode and city. | |
| 7 | + * This class is for example purposes only, just to | |
| 8 | + * show how to create a webservice | |
| 9 | + * | |
| 10 | + */ | |
| 11 | +class address{ | |
| 12 | + /** @var string */ | |
| 13 | + public $street; | |
| 14 | + | |
| 15 | + /** @var string */ | |
| 16 | + public $nr; | |
| 17 | + | |
| 18 | + /** @var string */ | |
| 19 | + public $zipcode; | |
| 20 | + | |
| 21 | + /** @var string */ | |
| 22 | + public $city; | |
| 23 | +} | |
| 24 | +?> | |
| 0 | 25 | \ No newline at end of file | ... | ... |
webservice/classes/rest/model/contact.class.php
0 → 100755
| 1 | +<?php | |
| 2 | + | |
| 3 | + | |
| 4 | +/** | |
| 5 | + * The contact details for a person | |
| 6 | + * | |
| 7 | + * Stores the person's name, address and e-mail | |
| 8 | + * This class is for example purposes only, just to | |
| 9 | + * show how to create a webservice | |
| 10 | + * | |
| 11 | + */ | |
| 12 | +class contact{ | |
| 13 | + /** @var int */ | |
| 14 | + public $id; | |
| 15 | + | |
| 16 | + /** @var string */ | |
| 17 | + public $name; | |
| 18 | + | |
| 19 | + /** @var address */ | |
| 20 | + public $address; | |
| 21 | + | |
| 22 | + /** @var string */ | |
| 23 | + public $email; | |
| 24 | + | |
| 25 | + /** | |
| 26 | + * saves a contact | |
| 27 | + * | |
| 28 | + * @return void | |
| 29 | + */ | |
| 30 | + public function save() { | |
| 31 | + //save contact 2 db | |
| 32 | + } | |
| 33 | +} | |
| 34 | +?> | |
| 0 | 35 | \ No newline at end of file | ... | ... |
webservice/classes/rest/model/contactManager.class.php
0 → 100755
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Keeps track of the people in our contact list. | |
| 5 | + * | |
| 6 | + * Starts with a standard contact list and can add | |
| 7 | + * new people to our list or change existing contacts. | |
| 8 | + * This class is for example purposes only, just to | |
| 9 | + * show how to create a webservice | |
| 10 | + */ | |
| 11 | + | |
| 12 | +require('classes/rest/model/contact.class.php'); | |
| 13 | +require('classes/rest/model/address.class.php'); | |
| 14 | +class contactManager{ | |
| 15 | + | |
| 16 | + /** | |
| 17 | + * Gets the current contact list. | |
| 18 | + * @return contact[] | |
| 19 | + */ | |
| 20 | + public function getContacts() { | |
| 21 | + $contact = new contact(); | |
| 22 | + $contact->address = new Address(); | |
| 23 | + $contact->address->city ="sesamcity"; | |
| 24 | + $contact->address->street ="sesamstreet"; | |
| 25 | + $contact->email = "me@you.com"; | |
| 26 | + $contact->id = 1; | |
| 27 | + $contact->name ="me"; | |
| 28 | + | |
| 29 | + $ret[] = $contact; | |
| 30 | + return $ret; | |
| 31 | + } | |
| 32 | + | |
| 33 | + /** | |
| 34 | + * Gets the contact with the given id. | |
| 35 | + * @param int The id | |
| 36 | + * @return contact | |
| 37 | + */ | |
| 38 | + public function getContact($id) { | |
| 39 | + //get contact from db | |
| 40 | + //might wanna throw an exception when it does not exists | |
| 41 | + throw new Exception("Contact '$id' not found"); | |
| 42 | + } | |
| 43 | + /** | |
| 44 | + * Generates an new, empty contact template | |
| 45 | + * @return contact | |
| 46 | + */ | |
| 47 | + public function newContact() { | |
| 48 | + return new contact(); | |
| 49 | + } | |
| 50 | + | |
| 51 | + /** | |
| 52 | + * Saves a given contact | |
| 53 | + * @param contact | |
| 54 | + * @return void | |
| 55 | + */ | |
| 56 | + public function saveContact(contact $contact) { | |
| 57 | + $contact->save(); | |
| 58 | + } | |
| 59 | + | |
| 60 | +} | |
| 61 | +?> | |
| 0 | 62 | \ No newline at end of file | ... | ... |
webservice/classes/rest/reflection/Class.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Rest_Reflection_Method | |
| 5 | + */ | |
| 6 | +require_once 'classes/rest/reflection/Method.php'; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * Class/Object reflection | |
| 10 | + * | |
| 11 | + */ | |
| 12 | +class Rest_Reflection_Class | |
| 13 | +{ | |
| 14 | + /** | |
| 15 | + * Optional configuration parameters; accessible via {@link __get} and | |
| 16 | + * {@link __set()} | |
| 17 | + * @var array | |
| 18 | + */ | |
| 19 | + protected $_config = array(); | |
| 20 | + | |
| 21 | + /** | |
| 22 | + * Array of {@link Rest_Reflection_Method}s | |
| 23 | + * @var array | |
| 24 | + */ | |
| 25 | + protected $_methods = array(); | |
| 26 | + | |
| 27 | + /** | |
| 28 | + * Namespace | |
| 29 | + * @var string | |
| 30 | + */ | |
| 31 | + protected $_namespace = null; | |
| 32 | + | |
| 33 | + /** | |
| 34 | + * ReflectionClass object | |
| 35 | + * @var ReflectionClass | |
| 36 | + */ | |
| 37 | + protected $_reflection; | |
| 38 | + | |
| 39 | + /** | |
| 40 | + * Constructor | |
| 41 | + * | |
| 42 | + * Create array of dispatchable methods, each a | |
| 43 | + * {@link Rest_Reflection_Method}. Sets reflection object property. | |
| 44 | + * | |
| 45 | + * @param ReflectionClass $reflection | |
| 46 | + * @param string $namespace | |
| 47 | + * @param mixed $argv | |
| 48 | + * @return void | |
| 49 | + */ | |
| 50 | + public function __construct(ReflectionClass $reflection, $namespace = null, $argv = false) | |
| 51 | + { | |
| 52 | + $this->_reflection = $reflection; | |
| 53 | + $this->setNamespace($namespace); | |
| 54 | + | |
| 55 | + foreach ($reflection->getMethods() as $method) { | |
| 56 | + // Don't aggregate magic methods | |
| 57 | + if ('__' == substr($method->getName(), 0, 2)) { | |
| 58 | + continue; | |
| 59 | + } | |
| 60 | + | |
| 61 | + if ($method->isPublic()) { | |
| 62 | + // Get signatures and description | |
| 63 | + $this->_methods[] = new Rest_Reflection_Method($this, $method, $this->getNamespace(), $argv); | |
| 64 | + } | |
| 65 | + } | |
| 66 | + } | |
| 67 | + | |
| 68 | + /** | |
| 69 | + * Proxy reflection calls | |
| 70 | + * | |
| 71 | + * @param string $method | |
| 72 | + * @param array $args | |
| 73 | + * @return mixed | |
| 74 | + */ | |
| 75 | + public function __call($method, $args) | |
| 76 | + { | |
| 77 | + if (method_exists($this->_reflection, $method)) { | |
| 78 | + return call_user_func_array(array($this->_reflection, $method), $args); | |
| 79 | + } | |
| 80 | + | |
| 81 | + require_once 'classes/rest/Exception.php'; | |
| 82 | + throw new Rest_Exception('Invalid reflection method'); | |
| 83 | + } | |
| 84 | + | |
| 85 | + /** | |
| 86 | + * Retrieve configuration parameters | |
| 87 | + * | |
| 88 | + * Values are retrieved by key from {@link $_config}. Returns null if no | |
| 89 | + * value found. | |
| 90 | + * | |
| 91 | + * @param string $key | |
| 92 | + * @return mixed | |
| 93 | + */ | |
| 94 | + public function __get($key) | |
| 95 | + { | |
| 96 | + if (isset($this->_config[$key])) { | |
| 97 | + return $this->_config[$key]; | |
| 98 | + } | |
| 99 | + | |
| 100 | + return null; | |
| 101 | + } | |
| 102 | + | |
| 103 | + /** | |
| 104 | + * Set configuration parameters | |
| 105 | + * | |
| 106 | + * Values are stored by $key in {@link $_config}. | |
| 107 | + * | |
| 108 | + * @param string $key | |
| 109 | + * @param mixed $value | |
| 110 | + * @return void | |
| 111 | + */ | |
| 112 | + public function __set($key, $value) | |
| 113 | + { | |
| 114 | + $this->_config[$key] = $value; | |
| 115 | + } | |
| 116 | + | |
| 117 | + /** | |
| 118 | + * Return array of dispatchable {@link Rest_Reflection_Method}s. | |
| 119 | + * | |
| 120 | + * @access public | |
| 121 | + * @return array | |
| 122 | + */ | |
| 123 | + public function getMethods() | |
| 124 | + { | |
| 125 | + return $this->_methods; | |
| 126 | + } | |
| 127 | + | |
| 128 | + /** | |
| 129 | + * Get namespace for this class | |
| 130 | + * | |
| 131 | + * @return string | |
| 132 | + */ | |
| 133 | + public function getNamespace() | |
| 134 | + { | |
| 135 | + return $this->_namespace; | |
| 136 | + } | |
| 137 | + | |
| 138 | + /** | |
| 139 | + * Set namespace for this class | |
| 140 | + * | |
| 141 | + * @param string $namespace | |
| 142 | + * @return void | |
| 143 | + */ | |
| 144 | + public function setNamespace($namespace) | |
| 145 | + { | |
| 146 | + if (empty($namespace)) { | |
| 147 | + $this->_namespace = ''; | |
| 148 | + return; | |
| 149 | + } | |
| 150 | + | |
| 151 | + if (!is_string($namespace) || !preg_match('/[a-z0-9_\.]+/i', $namespace)) { | |
| 152 | + require_once 'classes/rest/Exception.php'; | |
| 153 | + throw new Rest_Exception('Invalid namespace'); | |
| 154 | + } | |
| 155 | + | |
| 156 | + $this->_namespace = $namespace; | |
| 157 | + } | |
| 158 | + | |
| 159 | + /** | |
| 160 | + * Wakeup from serialization | |
| 161 | + * | |
| 162 | + * Reflection needs explicit instantiation to work correctly. Re-instantiate | |
| 163 | + * reflection object on wakeup. | |
| 164 | + * | |
| 165 | + * @return void | |
| 166 | + */ | |
| 167 | + public function __wakeup() | |
| 168 | + { | |
| 169 | + $this->_reflection = new ReflectionClass($this->getName()); | |
| 170 | + } | |
| 171 | +} | ... | ... |
webservice/classes/rest/reflection/Function.php
0 → 100644
webservice/classes/rest/reflection/Method.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Rest_Reflection_Function_Abstract | |
| 5 | + */ | |
| 6 | +require_once 'classes/rest/reflection/function/Abstract.php'; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * Method Reflection | |
| 10 | + * | |
| 11 | + * | |
| 12 | + */ | |
| 13 | +class Rest_Reflection_Method extends Rest_Reflection_Function_Abstract | |
| 14 | +{ | |
| 15 | + /** | |
| 16 | + * Parent class name | |
| 17 | + * @var string | |
| 18 | + */ | |
| 19 | + protected $_class; | |
| 20 | + | |
| 21 | + /** | |
| 22 | + * Parent class reflection | |
| 23 | + * @var Rest_Reflection_Class | |
| 24 | + */ | |
| 25 | + protected $_classReflection; | |
| 26 | + | |
| 27 | + /** | |
| 28 | + * Constructor | |
| 29 | + * | |
| 30 | + * @param Rest_Reflection_Class $class | |
| 31 | + * @param ReflectionMethod $r | |
| 32 | + * @param string $namespace | |
| 33 | + * @param array $argv | |
| 34 | + * @return void | |
| 35 | + */ | |
| 36 | + public function __construct(Rest_Reflection_Class $class, ReflectionMethod $r, $namespace = null, $argv = array()) | |
| 37 | + { | |
| 38 | + $this->_classReflection = $class; | |
| 39 | + $this->_reflection = $r; | |
| 40 | + | |
| 41 | + $classNamespace = $class->getNamespace(); | |
| 42 | + | |
| 43 | + // Determine namespace | |
| 44 | + if (!empty($namespace)) { | |
| 45 | + $this->setNamespace($namespace); | |
| 46 | + } elseif (!empty($classNamespace)) { | |
| 47 | + $this->setNamespace($classNamespace); | |
| 48 | + } | |
| 49 | + | |
| 50 | + // Determine arguments | |
| 51 | + if (is_array($argv)) { | |
| 52 | + $this->_argv = $argv; | |
| 53 | + } | |
| 54 | + | |
| 55 | + // If method call, need to store some info on the class | |
| 56 | + $this->_class = $class->getName(); | |
| 57 | + | |
| 58 | + // Perform some introspection | |
| 59 | + $this->_reflect(); | |
| 60 | + } | |
| 61 | + | |
| 62 | + /** | |
| 63 | + * Return the reflection for the class that defines this method | |
| 64 | + * | |
| 65 | + * @return Rest_Reflection_Class | |
| 66 | + */ | |
| 67 | + public function getDeclaringClass() | |
| 68 | + { | |
| 69 | + return $this->_classReflection; | |
| 70 | + } | |
| 71 | + | |
| 72 | + /** | |
| 73 | + * Wakeup from serialization | |
| 74 | + * | |
| 75 | + * Reflection needs explicit instantiation to work correctly. Re-instantiate | |
| 76 | + * reflection object on wakeup. | |
| 77 | + * | |
| 78 | + * @return void | |
| 79 | + */ | |
| 80 | + public function __wakeup() | |
| 81 | + { | |
| 82 | + $this->_classReflection = new Rest_Reflection_Class(new ReflectionClass($this->_class), $this->getNamespace(), $this->getInvokeArguments()); | |
| 83 | + $this->_reflection = new ReflectionMethod($this->_classReflection->getName(), $this->getName()); | |
| 84 | + } | |
| 85 | + | |
| 86 | +} | ... | ... |
webservice/classes/rest/reflection/Node.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Node Tree class for Rest reflection operations | |
| 5 | + * | |
| 6 | + * | |
| 7 | + */ | |
| 8 | +class Rest_Reflection_Node | |
| 9 | +{ | |
| 10 | + /** | |
| 11 | + * Node value | |
| 12 | + * @var mixed | |
| 13 | + */ | |
| 14 | + protected $_value = null; | |
| 15 | + | |
| 16 | + /** | |
| 17 | + * Array of child nodes (if any) | |
| 18 | + * @var array | |
| 19 | + */ | |
| 20 | + protected $_children = array(); | |
| 21 | + | |
| 22 | + /** | |
| 23 | + * Parent node (if any) | |
| 24 | + * @var Rest_Reflection_Node | |
| 25 | + */ | |
| 26 | + protected $_parent = null; | |
| 27 | + | |
| 28 | + /** | |
| 29 | + * Constructor | |
| 30 | + * | |
| 31 | + * @param mixed $value | |
| 32 | + * @param Rest_Reflection_Node $parent Optional | |
| 33 | + * @return Rest_Reflection_Node | |
| 34 | + */ | |
| 35 | + public function __construct($value, Rest_Reflection_Node $parent = null) | |
| 36 | + { | |
| 37 | + $this->_value = $value; | |
| 38 | + if (null !== $parent) { | |
| 39 | + $this->setParent($parent, true); | |
| 40 | + } | |
| 41 | + | |
| 42 | + return $this; | |
| 43 | + } | |
| 44 | + | |
| 45 | + /** | |
| 46 | + * Set parent node | |
| 47 | + * | |
| 48 | + * @param Rest_Reflection_Node $node | |
| 49 | + * @param boolean $new Whether or not the child node is newly created | |
| 50 | + * and should always be attached | |
| 51 | + * @return void | |
| 52 | + */ | |
| 53 | + public function setParent(Rest_Reflection_Node $node, $new = false) | |
| 54 | + { | |
| 55 | + $this->_parent = $node; | |
| 56 | + | |
| 57 | + if ($new) { | |
| 58 | + $node->attachChild($this); | |
| 59 | + return; | |
| 60 | + } | |
| 61 | + } | |
| 62 | + | |
| 63 | + /** | |
| 64 | + * Create and attach a new child node | |
| 65 | + * | |
| 66 | + * @param mixed $value | |
| 67 | + * @access public | |
| 68 | + * @return Rest_Reflection_Node New child node | |
| 69 | + */ | |
| 70 | + public function createChild($value) | |
| 71 | + { | |
| 72 | + $child = new self($value, $this); | |
| 73 | + | |
| 74 | + return $child; | |
| 75 | + } | |
| 76 | + | |
| 77 | + /** | |
| 78 | + * Attach a child node | |
| 79 | + * | |
| 80 | + * @param Rest_Reflection_Node $node | |
| 81 | + * @return void | |
| 82 | + */ | |
| 83 | + public function attachChild(Rest_Reflection_Node $node) | |
| 84 | + { | |
| 85 | + $this->_children[] = $node; | |
| 86 | + | |
| 87 | + if ($node->getParent() !== $this) { | |
| 88 | + $node->setParent($this); | |
| 89 | + } | |
| 90 | + } | |
| 91 | + | |
| 92 | + /** | |
| 93 | + * Return an array of all child nodes | |
| 94 | + * | |
| 95 | + * @return array | |
| 96 | + */ | |
| 97 | + public function getChildren() | |
| 98 | + { | |
| 99 | + return $this->_children; | |
| 100 | + } | |
| 101 | + | |
| 102 | + /** | |
| 103 | + * Does this node have children? | |
| 104 | + * | |
| 105 | + * @return boolean | |
| 106 | + */ | |
| 107 | + public function hasChildren() | |
| 108 | + { | |
| 109 | + return count($this->_children) > 0; | |
| 110 | + } | |
| 111 | + | |
| 112 | + /** | |
| 113 | + * Return the parent node | |
| 114 | + * | |
| 115 | + * @return null|Rest_Reflection_Node | |
| 116 | + */ | |
| 117 | + public function getParent() | |
| 118 | + { | |
| 119 | + return $this->_parent; | |
| 120 | + } | |
| 121 | + | |
| 122 | + /** | |
| 123 | + * Return the node's current value | |
| 124 | + * | |
| 125 | + * @return mixed | |
| 126 | + */ | |
| 127 | + public function getValue() | |
| 128 | + { | |
| 129 | + return $this->_value; | |
| 130 | + } | |
| 131 | + | |
| 132 | + /** | |
| 133 | + * Set the node value | |
| 134 | + * | |
| 135 | + * @param mixed $value | |
| 136 | + * @return void | |
| 137 | + */ | |
| 138 | + public function setValue($value) | |
| 139 | + { | |
| 140 | + $this->_value = $value; | |
| 141 | + } | |
| 142 | + | |
| 143 | + /** | |
| 144 | + * Retrieve the bottommost nodes of this node's tree | |
| 145 | + * | |
| 146 | + * Retrieves the bottommost nodes of the tree by recursively calling | |
| 147 | + * getEndPoints() on all children. If a child is null, it returns the parent | |
| 148 | + * as an end point. | |
| 149 | + * | |
| 150 | + * @return array | |
| 151 | + */ | |
| 152 | + public function getEndPoints() | |
| 153 | + { | |
| 154 | + $endPoints = array(); | |
| 155 | + if (!$this->hasChildren()) { | |
| 156 | + return $endPoints; | |
| 157 | + } | |
| 158 | + | |
| 159 | + foreach ($this->_children as $child) { | |
| 160 | + $value = $child->getValue(); | |
| 161 | + | |
| 162 | + if (null === $value) { | |
| 163 | + $endPoints[] = $this; | |
| 164 | + } elseif ((null !== $value) | |
| 165 | + && $child->hasChildren()) | |
| 166 | + { | |
| 167 | + $childEndPoints = $child->getEndPoints(); | |
| 168 | + if (!empty($childEndPoints)) { | |
| 169 | + $endPoints = array_merge($endPoints, $childEndPoints); | |
| 170 | + } | |
| 171 | + } elseif ((null !== $value) && !$child->hasChildren()) { | |
| 172 | + $endPoints[] = $child; | |
| 173 | + } | |
| 174 | + } | |
| 175 | + | |
| 176 | + return $endPoints; | |
| 177 | + } | |
| 178 | +} | ... | ... |
webservice/classes/rest/reflection/Parameter.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Parameter Reflection | |
| 5 | + * | |
| 6 | + * Decorates a ReflectionParameter to allow setting the parameter type | |
| 7 | + * | |
| 8 | + * | |
| 9 | + */ | |
| 10 | +class Rest_Reflection_Parameter | |
| 11 | +{ | |
| 12 | + /** | |
| 13 | + * @var ReflectionParameter | |
| 14 | + */ | |
| 15 | + protected $_reflection; | |
| 16 | + | |
| 17 | + /** | |
| 18 | + * Parameter position | |
| 19 | + * @var int | |
| 20 | + */ | |
| 21 | + protected $_position; | |
| 22 | + | |
| 23 | + /** | |
| 24 | + * Parameter type | |
| 25 | + * @var string | |
| 26 | + */ | |
| 27 | + protected $_type; | |
| 28 | + | |
| 29 | + /** | |
| 30 | + * Parameter description | |
| 31 | + * @var string | |
| 32 | + */ | |
| 33 | + protected $_description; | |
| 34 | + | |
| 35 | + /** | |
| 36 | + * Constructor | |
| 37 | + * | |
| 38 | + * @param ReflectionParameter $r | |
| 39 | + * @param string $type Parameter type | |
| 40 | + * @param string $description Parameter description | |
| 41 | + */ | |
| 42 | + public function __construct(ReflectionParameter $r, $type = 'mixed', $description = '') | |
| 43 | + { | |
| 44 | + $this->_reflection = $r; | |
| 45 | + $this->setType($type); | |
| 46 | + $this->setDescription($description); | |
| 47 | + } | |
| 48 | + | |
| 49 | + /** | |
| 50 | + * Proxy reflection calls | |
| 51 | + * | |
| 52 | + * @param string $method | |
| 53 | + * @param array $args | |
| 54 | + * @return mixed | |
| 55 | + */ | |
| 56 | + public function __call($method, $args) | |
| 57 | + { | |
| 58 | + if (method_exists($this->_reflection, $method)) { | |
| 59 | + return call_user_func_array(array($this->_reflection, $method), $args); | |
| 60 | + } | |
| 61 | + | |
| 62 | + require_once 'classes/rest/Exception.php'; | |
| 63 | + throw new Rest_Exception('Invalid reflection method'); | |
| 64 | + } | |
| 65 | + | |
| 66 | + /** | |
| 67 | + * Retrieve parameter type | |
| 68 | + * | |
| 69 | + * @return string | |
| 70 | + */ | |
| 71 | + public function getType() | |
| 72 | + { | |
| 73 | + return $this->_type; | |
| 74 | + } | |
| 75 | + | |
| 76 | + /** | |
| 77 | + * Set parameter type | |
| 78 | + * | |
| 79 | + * @param string|null $type | |
| 80 | + * @return void | |
| 81 | + */ | |
| 82 | + public function setType($type) | |
| 83 | + { | |
| 84 | + if (!is_string($type) && (null !== $type)) { | |
| 85 | + require_once 'classes/rest/Exception.php'; | |
| 86 | + throw new Rest_Exception('Invalid parameter type'); | |
| 87 | + } | |
| 88 | + | |
| 89 | + $this->_type = $type; | |
| 90 | + } | |
| 91 | + | |
| 92 | + /** | |
| 93 | + * Retrieve parameter description | |
| 94 | + * | |
| 95 | + * @return string | |
| 96 | + */ | |
| 97 | + public function getDescription() | |
| 98 | + { | |
| 99 | + return $this->_description; | |
| 100 | + } | |
| 101 | + | |
| 102 | + /** | |
| 103 | + * Set parameter description | |
| 104 | + * | |
| 105 | + * @param string|null $description | |
| 106 | + * @return void | |
| 107 | + */ | |
| 108 | + public function setDescription($description) | |
| 109 | + { | |
| 110 | + if (!is_string($description) && (null !== $description)) { | |
| 111 | + require_once 'classes/rest/Exception.php'; | |
| 112 | + throw new Rest_Exception('Invalid parameter description'); | |
| 113 | + } | |
| 114 | + | |
| 115 | + $this->_description = $description; | |
| 116 | + } | |
| 117 | + | |
| 118 | + /** | |
| 119 | + * Set parameter position | |
| 120 | + * | |
| 121 | + * @param int $index | |
| 122 | + * @return void | |
| 123 | + */ | |
| 124 | + public function setPosition($index) | |
| 125 | + { | |
| 126 | + $this->_position = (int) $index; | |
| 127 | + } | |
| 128 | + | |
| 129 | + /** | |
| 130 | + * Return parameter position | |
| 131 | + * | |
| 132 | + * @return int | |
| 133 | + */ | |
| 134 | + public function getPosition() | |
| 135 | + { | |
| 136 | + return $this->_position; | |
| 137 | + } | |
| 138 | +} | ... | ... |
webservice/classes/rest/reflection/Prototype.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Rest_Reflection_ReturnValue | |
| 5 | + */ | |
| 6 | +require_once 'classes/rest/reflection/ReturnValue.php'; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * Rest_Reflection_Parameter | |
| 10 | + */ | |
| 11 | +require_once 'classes/rest/reflection/Parameter.php'; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * Method/Function prototypes | |
| 15 | + * | |
| 16 | + * Contains accessors for the return value and all method arguments. | |
| 17 | + * | |
| 18 | + */ | |
| 19 | +class Rest_Reflection_Prototype | |
| 20 | +{ | |
| 21 | + /** | |
| 22 | + * Constructor | |
| 23 | + * | |
| 24 | + * @param Reflection_ReturnValue $return | |
| 25 | + * @param array $params | |
| 26 | + * @return void | |
| 27 | + */ | |
| 28 | + public function __construct(Rest_Reflection_ReturnValue $return, $params = null) | |
| 29 | + { | |
| 30 | + $this->_return = $return; | |
| 31 | + | |
| 32 | + if (!is_array($params) && (null !== $params)) { | |
| 33 | + require_once 'rest/Exception.php'; | |
| 34 | + throw new Rest_Exception('Invalid parameters'); | |
| 35 | + } | |
| 36 | + | |
| 37 | + if (is_array($params)) { | |
| 38 | + foreach ($params as $param) { | |
| 39 | + if (!$param instanceof Rest_Reflection_Parameter) { | |
| 40 | + require_once 'rest/Exception.php'; | |
| 41 | + throw new Rest_Exception('One or more params are invalid'); | |
| 42 | + } | |
| 43 | + } | |
| 44 | + } | |
| 45 | + | |
| 46 | + $this->_params = $params; | |
| 47 | + } | |
| 48 | + | |
| 49 | + /** | |
| 50 | + * Retrieve return type | |
| 51 | + * | |
| 52 | + * @return string | |
| 53 | + */ | |
| 54 | + public function getReturnType() | |
| 55 | + { | |
| 56 | + return $this->_return->getType(); | |
| 57 | + } | |
| 58 | + | |
| 59 | + /** | |
| 60 | + * Retrieve the return value object | |
| 61 | + * | |
| 62 | + * @access public | |
| 63 | + * @return Reflection_ReturnValue | |
| 64 | + */ | |
| 65 | + public function getReturnValue() | |
| 66 | + { | |
| 67 | + return $this->_return; | |
| 68 | + } | |
| 69 | + | |
| 70 | + /** | |
| 71 | + * Retrieve method parameters | |
| 72 | + * | |
| 73 | + * @return array Array of {@link Reflection_Parameter}s | |
| 74 | + */ | |
| 75 | + public function getParameters() | |
| 76 | + { | |
| 77 | + return $this->_params; | |
| 78 | + } | |
| 79 | +} | ... | ... |
webservice/classes/rest/reflection/ReturnValue.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Return value reflection | |
| 5 | + * | |
| 6 | + * Stores the return value type and description | |
| 7 | + * | |
| 8 | + * | |
| 9 | + */ | |
| 10 | +class Rest_Reflection_ReturnValue | |
| 11 | +{ | |
| 12 | + /** | |
| 13 | + * Return value type | |
| 14 | + * @var string | |
| 15 | + */ | |
| 16 | + protected $_type; | |
| 17 | + | |
| 18 | + /** | |
| 19 | + * Return value description | |
| 20 | + * @var string | |
| 21 | + */ | |
| 22 | + protected $_description; | |
| 23 | + | |
| 24 | + /** | |
| 25 | + * Constructor | |
| 26 | + * | |
| 27 | + * @param string $type Return value type | |
| 28 | + * @param string $description Return value type | |
| 29 | + */ | |
| 30 | + public function __construct($type = 'mixed', $description = '') | |
| 31 | + { | |
| 32 | + $this->setType($type); | |
| 33 | + $this->setDescription($description); | |
| 34 | + } | |
| 35 | + | |
| 36 | + /** | |
| 37 | + * Retrieve parameter type | |
| 38 | + * | |
| 39 | + * @return string | |
| 40 | + */ | |
| 41 | + public function getType() | |
| 42 | + { | |
| 43 | + return $this->_type; | |
| 44 | + } | |
| 45 | + | |
| 46 | + /** | |
| 47 | + * Set parameter type | |
| 48 | + * | |
| 49 | + * @param string|null $type | |
| 50 | + * @return void | |
| 51 | + */ | |
| 52 | + public function setType($type) | |
| 53 | + { | |
| 54 | + if (!is_string($type) && (null !== $type)) { | |
| 55 | + require_once 'classes/rest/Exception.php'; | |
| 56 | + throw new Rest_Exception('Invalid parameter type'); | |
| 57 | + } | |
| 58 | + | |
| 59 | + $this->_type = $type; | |
| 60 | + } | |
| 61 | + | |
| 62 | + /** | |
| 63 | + * Retrieve parameter description | |
| 64 | + * | |
| 65 | + * @return string | |
| 66 | + */ | |
| 67 | + public function getDescription() | |
| 68 | + { | |
| 69 | + return $this->_description; | |
| 70 | + } | |
| 71 | + | |
| 72 | + /** | |
| 73 | + * Set parameter description | |
| 74 | + * | |
| 75 | + * @param string|null $description | |
| 76 | + * @return void | |
| 77 | + */ | |
| 78 | + public function setDescription($description) | |
| 79 | + { | |
| 80 | + if (!is_string($description) && (null !== $description)) { | |
| 81 | + require_once 'classes/rest/Exception.php'; | |
| 82 | + throw new Rest_Exception('Invalid parameter description'); | |
| 83 | + } | |
| 84 | + | |
| 85 | + $this->_description = $description; | |
| 86 | + } | |
| 87 | +} | ... | ... |
webservice/classes/rest/reflection/function/Abstract.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | + | |
| 4 | +/** | |
| 5 | + * Rest_Reflection_Node | |
| 6 | + */ | |
| 7 | +require_once 'classes/rest/reflection/Node.php'; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * Rest_Reflection_Parameter | |
| 11 | + */ | |
| 12 | +require_once 'classes/rest/reflection/Parameter.php'; | |
| 13 | + | |
| 14 | +/** | |
| 15 | + * Rest_Reflection_Prototype | |
| 16 | + */ | |
| 17 | +require_once 'classes/rest/reflection/Prototype.php'; | |
| 18 | + | |
| 19 | +/** | |
| 20 | + * Function/Method Reflection | |
| 21 | + * | |
| 22 | + * Decorates a ReflectionFunction. Allows setting and retrieving an alternate | |
| 23 | + * 'service' name (i.e., the name to be used when calling via a service), | |
| 24 | + * setting and retrieving the description (originally set using the docblock | |
| 25 | + * contents), retrieving the callback and callback type, retrieving additional | |
| 26 | + * method invocation arguments, and retrieving the | |
| 27 | + * method | |
| 28 | + * | |
| 29 | + */ | |
| 30 | +abstract class Rest_Reflection_Function_Abstract | |
| 31 | +{ | |
| 32 | + /** | |
| 33 | + * @var ReflectionFunction | |
| 34 | + */ | |
| 35 | + protected $_reflection; | |
| 36 | + | |
| 37 | + /** | |
| 38 | + * Additional arguments to pass to method on invocation | |
| 39 | + * @var array | |
| 40 | + */ | |
| 41 | + protected $_argv = array(); | |
| 42 | + | |
| 43 | + /** | |
| 44 | + * Used to store extra configuration for the method (typically done by the | |
| 45 | + * server class, e.g., to indicate whether or not to instantiate a class). | |
| 46 | + * Associative array; access is as properties via {@link __get()} and | |
| 47 | + * {@link __set()} | |
| 48 | + * @var array | |
| 49 | + */ | |
| 50 | + protected $_config = array(); | |
| 51 | + | |
| 52 | + /** | |
| 53 | + * Declaring class (needed for when serialization occurs) | |
| 54 | + * @var string | |
| 55 | + */ | |
| 56 | + protected $_class; | |
| 57 | + | |
| 58 | + /** | |
| 59 | + * Function/method description | |
| 60 | + * @var string | |
| 61 | + */ | |
| 62 | + protected $_description = ''; | |
| 63 | + | |
| 64 | + /** | |
| 65 | + * Namespace with which to prefix function/method name | |
| 66 | + * @var string | |
| 67 | + */ | |
| 68 | + protected $_namespace; | |
| 69 | + | |
| 70 | + /** | |
| 71 | + * Prototypes | |
| 72 | + * @var array | |
| 73 | + */ | |
| 74 | + protected $_prototypes = array(); | |
| 75 | + | |
| 76 | + private $_return; | |
| 77 | + private $_returnDesc; | |
| 78 | + private $_paramDesc; | |
| 79 | + private $_sigParams; | |
| 80 | + private $_sigParamsDepth; | |
| 81 | + | |
| 82 | + /** | |
| 83 | + * Constructor | |
| 84 | + * | |
| 85 | + * @param ReflectionFunction $r | |
| 86 | + */ | |
| 87 | + public function __construct(Reflector $r, $namespace = null, $argv = array()) | |
| 88 | + { | |
| 89 | + // In PHP 5.1.x, ReflectionMethod extends ReflectionFunction. In 5.2.x, | |
| 90 | + // both extend ReflectionFunctionAbstract. So, we can't do normal type | |
| 91 | + // hinting in the prototype, but instead need to do some explicit | |
| 92 | + // testing here. | |
| 93 | + if ((!$r instanceof ReflectionFunction) | |
| 94 | + && (!$r instanceof ReflectionMethod)) { | |
| 95 | + require_once 'classes/rest/Exception.php'; | |
| 96 | + throw new Rest_Exception('Invalid reflection class'); | |
| 97 | + } | |
| 98 | + $this->_reflection = $r; | |
| 99 | + | |
| 100 | + // Determine namespace | |
| 101 | + if (null !== $namespace){ | |
| 102 | + $this->setNamespace($namespace); | |
| 103 | + } | |
| 104 | + | |
| 105 | + // Determine arguments | |
| 106 | + if (is_array($argv)) { | |
| 107 | + $this->_argv = $argv; | |
| 108 | + } | |
| 109 | + | |
| 110 | + // If method call, need to store some info on the class | |
| 111 | + if ($r instanceof ReflectionMethod) { | |
| 112 | + $this->_class = $r->getDeclaringClass()->getName(); | |
| 113 | + } | |
| 114 | + | |
| 115 | + // Perform some introspection | |
| 116 | + $this->_reflect(); | |
| 117 | + } | |
| 118 | + | |
| 119 | + /** | |
| 120 | + * Create signature node tree | |
| 121 | + * | |
| 122 | + * Recursive method to build the signature node tree. Increments through | |
| 123 | + * each array in {@link $_sigParams}, adding every value of the next level | |
| 124 | + * to the current value (unless the current value is null). | |
| 125 | + * | |
| 126 | + * @param Rest_Reflection_Node $parent | |
| 127 | + * @param int $level | |
| 128 | + * @return void | |
| 129 | + */ | |
| 130 | + protected function _addTree(Rest_Reflection_Node $parent, $level = 0) | |
| 131 | + { | |
| 132 | + if ($level >= $this->_sigParamsDepth) { | |
| 133 | + return; | |
| 134 | + } | |
| 135 | + | |
| 136 | + foreach ($this->_sigParams[$level] as $value) { | |
| 137 | + $node = new Rest_Reflection_Node($value, $parent); | |
| 138 | + if ((null !== $value) && ($this->_sigParamsDepth > $level + 1)) { | |
| 139 | + $this->_addTree($node, $level + 1); | |
| 140 | + } | |
| 141 | + } | |
| 142 | + } | |
| 143 | + | |
| 144 | + /** | |
| 145 | + * Build the signature tree | |
| 146 | + * | |
| 147 | + * Builds a signature tree starting at the return values and descending | |
| 148 | + * through each method argument. Returns an array of | |
| 149 | + * {@link Rest_Reflection_Node}s. | |
| 150 | + * | |
| 151 | + * @return array | |
| 152 | + */ | |
| 153 | + protected function _buildTree() | |
| 154 | + { | |
| 155 | + $returnTree = array(); | |
| 156 | + foreach ((array) $this->_return as $value) { | |
| 157 | + $node = new Rest_Reflection_Node($value); | |
| 158 | + $this->_addTree($node); | |
| 159 | + $returnTree[] = $node; | |
| 160 | + } | |
| 161 | + | |
| 162 | + return $returnTree; | |
| 163 | + } | |
| 164 | + | |
| 165 | + /** | |
| 166 | + * Build method signatures | |
| 167 | + * | |
| 168 | + * Builds method signatures using the array of return types and the array of | |
| 169 | + * parameters types | |
| 170 | + * | |
| 171 | + * @param array $return Array of return types | |
| 172 | + * @param string $returnDesc Return value description | |
| 173 | + * @param array $params Array of arguments (each an array of types) | |
| 174 | + * @param array $paramDesc Array of parameter descriptions | |
| 175 | + * @return array | |
| 176 | + */ | |
| 177 | + protected function _buildSignatures($return, $returnDesc, $paramTypes, $paramDesc) | |
| 178 | + { | |
| 179 | + $this->_return = $return; | |
| 180 | + $this->_returnDesc = $returnDesc; | |
| 181 | + $this->_paramDesc = $paramDesc; | |
| 182 | + $this->_sigParams = $paramTypes; | |
| 183 | + $this->_sigParamsDepth = count($paramTypes); | |
| 184 | + $signatureTrees = $this->_buildTree(); | |
| 185 | + $signatures = array(); | |
| 186 | + | |
| 187 | + $endPoints = array(); | |
| 188 | + foreach ($signatureTrees as $root) { | |
| 189 | + $tmp = $root->getEndPoints(); | |
| 190 | + if (empty($tmp)) { | |
| 191 | + $endPoints = array_merge($endPoints, array($root)); | |
| 192 | + } else { | |
| 193 | + $endPoints = array_merge($endPoints, $tmp); | |
| 194 | + } | |
| 195 | + } | |
| 196 | + | |
| 197 | + foreach ($endPoints as $node) { | |
| 198 | + if (!$node instanceof Rest_Reflection_Node) { | |
| 199 | + continue; | |
| 200 | + } | |
| 201 | + | |
| 202 | + $signature = array(); | |
| 203 | + do { | |
| 204 | + array_unshift($signature, $node->getValue()); | |
| 205 | + $node = $node->getParent(); | |
| 206 | + } while ($node instanceof Rest_Reflection_Node); | |
| 207 | + | |
| 208 | + $signatures[] = $signature; | |
| 209 | + } | |
| 210 | + | |
| 211 | + // Build prototypes | |
| 212 | + $params = $this->_reflection->getParameters(); | |
| 213 | + foreach ($signatures as $signature) { | |
| 214 | + $return = new Rest_Reflection_ReturnValue(array_shift($signature), $this->_returnDesc); | |
| 215 | + $tmp = array(); | |
| 216 | + foreach ($signature as $key => $type) { | |
| 217 | + $param = new Rest_Reflection_Parameter($params[$key], $type, $this->_paramDesc[$key]); | |
| 218 | + $param->setPosition($key); | |
| 219 | + $tmp[] = $param; | |
| 220 | + } | |
| 221 | + | |
| 222 | + $this->_prototypes[] = new Rest_Reflection_Prototype($return, $tmp); | |
| 223 | + } | |
| 224 | + } | |
| 225 | + | |
| 226 | + /** | |
| 227 | + * Use code reflection to create method signatures | |
| 228 | + * | |
| 229 | + * Determines the method help/description text from the function DocBlock | |
| 230 | + * comment. Determines method signatures using a combination of | |
| 231 | + * ReflectionFunction and parsing of DocBlock @param and @return values. | |
| 232 | + * | |
| 233 | + * @param ReflectionFunction $function | |
| 234 | + * @return array | |
| 235 | + */ | |
| 236 | + protected function _reflect() | |
| 237 | + { | |
| 238 | + $function = $this->_reflection; | |
| 239 | + $helpText = ''; | |
| 240 | + $signatures = array(); | |
| 241 | + $returnDesc = ''; | |
| 242 | + $paramCount = $function->getNumberOfParameters(); | |
| 243 | + $paramCountRequired = $function->getNumberOfRequiredParameters(); | |
| 244 | + $parameters = $function->getParameters(); | |
| 245 | + $docBlock = $function->getDocComment(); | |
| 246 | + | |
| 247 | + if (!empty($docBlock)) { | |
| 248 | + // Get help text | |
| 249 | + if (preg_match(':/\*\*\s*\r?\n\s*\*\s(.*?)\r?\n\s*\*(\s@|/):s', $docBlock, $matches)) | |
| 250 | + { | |
| 251 | + $helpText = $matches[1]; | |
| 252 | + $helpText = preg_replace('/(^\s*\*\s)/m', '', $helpText); | |
| 253 | + $helpText = preg_replace('/\r?\n\s*\*\s*(\r?\n)*/s', "\n", $helpText); | |
| 254 | + $helpText = trim($helpText); | |
| 255 | + } | |
| 256 | + | |
| 257 | + // Get return type(s) and description | |
| 258 | + $return = 'void'; | |
| 259 | + if (preg_match('/@return\s+(\S+)/', $docBlock, $matches)) { | |
| 260 | + $return = explode('|', $matches[1]); | |
| 261 | + if (preg_match('/@return\s+\S+\s+(.*?)(@|\*\/)/s', $docBlock, $matches)) | |
| 262 | + { | |
| 263 | + $value = $matches[1]; | |
| 264 | + $value = preg_replace('/\s?\*\s/m', '', $value); | |
| 265 | + $value = preg_replace('/\s{2,}/', ' ', $value); | |
| 266 | + $returnDesc = trim($value); | |
| 267 | + } | |
| 268 | + } | |
| 269 | + | |
| 270 | + // Get param types and description | |
| 271 | + if (preg_match_all('/@param\s+([^\s]+)/m', $docBlock, $matches)) { | |
| 272 | + $paramTypesTmp = $matches[1]; | |
| 273 | + if (preg_match_all('/@param\s+\S+\s+(\$^\S+)\s+(.*?)(@|\*\/)/s', $docBlock, $matches)) | |
| 274 | + { | |
| 275 | + $paramDesc = $matches[2]; | |
| 276 | + foreach ($paramDesc as $key => $value) { | |
| 277 | + $value = preg_replace('/\s?\*\s/m', '', $value); | |
| 278 | + $value = preg_replace('/\s{2,}/', ' ', $value); | |
| 279 | + $paramDesc[$key] = trim($value); | |
| 280 | + } | |
| 281 | + } | |
| 282 | + } | |
| 283 | + } else { | |
| 284 | + $helpText = $function->getName(); | |
| 285 | + $return = 'void'; | |
| 286 | + } | |
| 287 | + | |
| 288 | + // Set method description | |
| 289 | + $this->setDescription($helpText); | |
| 290 | + | |
| 291 | + // Get all param types as arrays | |
| 292 | + if (!isset($paramTypesTmp) && (0 < $paramCount)) { | |
| 293 | + $paramTypesTmp = array_fill(0, $paramCount, 'mixed'); | |
| 294 | + } elseif (!isset($paramTypesTmp)) { | |
| 295 | + $paramTypesTmp = array(); | |
| 296 | + } elseif (count($paramTypesTmp) < $paramCount) { | |
| 297 | + $start = $paramCount - count($paramTypesTmp); | |
| 298 | + for ($i = $start; $i < $paramCount; ++$i) { | |
| 299 | + $paramTypesTmp[$i] = 'mixed'; | |
| 300 | + } | |
| 301 | + } | |
| 302 | + | |
| 303 | + // Get all param descriptions as arrays | |
| 304 | + if (!isset($paramDesc) && (0 < $paramCount)) { | |
| 305 | + $paramDesc = array_fill(0, $paramCount, ''); | |
| 306 | + } elseif (!isset($paramDesc)) { | |
| 307 | + $paramDesc = array(); | |
| 308 | + } elseif (count($paramDesc) < $paramCount) { | |
| 309 | + $start = $paramCount - count($paramDesc); | |
| 310 | + for ($i = $start; $i < $paramCount; ++$i) { | |
| 311 | + $paramDesc[$i] = ''; | |
| 312 | + } | |
| 313 | + } | |
| 314 | + | |
| 315 | + if (count($paramTypesTmp) != $paramCount) { | |
| 316 | + require_once 'classes/rest/Exception.php'; | |
| 317 | + throw new Rest_Exception( | |
| 318 | + 'Variable number of arguments is not supported for services (except optional parameters). ' | |
| 319 | + . 'Number of function arguments must currespond to actual number of arguments described in a docblock.'); | |
| 320 | + } | |
| 321 | + | |
| 322 | + $paramTypes = array(); | |
| 323 | + foreach ($paramTypesTmp as $i => $param) { | |
| 324 | + $tmp = explode('|', $param); | |
| 325 | + if ($parameters[$i]->isOptional()) { | |
| 326 | + array_unshift($tmp, null); | |
| 327 | + } | |
| 328 | + $paramTypes[] = $tmp; | |
| 329 | + } | |
| 330 | + | |
| 331 | + $this->_buildSignatures($return, $returnDesc, $paramTypes, $paramDesc); | |
| 332 | + } | |
| 333 | + | |
| 334 | + | |
| 335 | + /** | |
| 336 | + * Proxy reflection calls | |
| 337 | + * | |
| 338 | + * @param string $method | |
| 339 | + * @param array $args | |
| 340 | + * @return mixed | |
| 341 | + */ | |
| 342 | + public function __call($method, $args) | |
| 343 | + { | |
| 344 | + if (method_exists($this->_reflection, $method)) { | |
| 345 | + return call_user_func_array(array($this->_reflection, $method), $args); | |
| 346 | + } | |
| 347 | + | |
| 348 | + require_once 'classes/rest/Exception.php'; | |
| 349 | + throw new Rest_Exception('Invalid reflection method ("' .$method. '")'); | |
| 350 | + } | |
| 351 | + | |
| 352 | + /** | |
| 353 | + * Retrieve configuration parameters | |
| 354 | + * | |
| 355 | + * Values are retrieved by key from {@link $_config}. Returns null if no | |
| 356 | + * value found. | |
| 357 | + * | |
| 358 | + * @param string $key | |
| 359 | + * @return mixed | |
| 360 | + */ | |
| 361 | + public function __get($key) | |
| 362 | + { | |
| 363 | + if (isset($this->_config[$key])) { | |
| 364 | + return $this->_config[$key]; | |
| 365 | + } | |
| 366 | + | |
| 367 | + return null; | |
| 368 | + } | |
| 369 | + | |
| 370 | + /** | |
| 371 | + * Set configuration parameters | |
| 372 | + * | |
| 373 | + * Values are stored by $key in {@link $_config}. | |
| 374 | + * | |
| 375 | + * @param string $key | |
| 376 | + * @param mixed $value | |
| 377 | + * @return void | |
| 378 | + */ | |
| 379 | + public function __set($key, $value) | |
| 380 | + { | |
| 381 | + $this->_config[$key] = $value; | |
| 382 | + } | |
| 383 | + | |
| 384 | + /** | |
| 385 | + * Set method's namespace | |
| 386 | + * | |
| 387 | + * @param string $namespace | |
| 388 | + * @return void | |
| 389 | + */ | |
| 390 | + public function setNamespace($namespace) | |
| 391 | + { | |
| 392 | + if (empty($namespace)) { | |
| 393 | + $this->_namespace = ''; | |
| 394 | + return; | |
| 395 | + } | |
| 396 | + | |
| 397 | + if (!is_string($namespace) || !preg_match('/[a-z0-9_\.]+/i', $namespace)) { | |
| 398 | + require_once 'classes/rest/Exception.php'; | |
| 399 | + throw new Rest_Exception('Invalid namespace'); | |
| 400 | + } | |
| 401 | + | |
| 402 | + $this->_namespace = $namespace; | |
| 403 | + } | |
| 404 | + | |
| 405 | + /** | |
| 406 | + * Return method's namespace | |
| 407 | + * | |
| 408 | + * @return string | |
| 409 | + */ | |
| 410 | + public function getNamespace() | |
| 411 | + { | |
| 412 | + return $this->_namespace; | |
| 413 | + } | |
| 414 | + | |
| 415 | + /** | |
| 416 | + * Set the description | |
| 417 | + * | |
| 418 | + * @param string $string | |
| 419 | + * @return void | |
| 420 | + */ | |
| 421 | + public function setDescription($string) | |
| 422 | + { | |
| 423 | + if (!is_string($string)) { | |
| 424 | + require_once 'classes/rest/Exception.php'; | |
| 425 | + throw new Rest_Exception('Invalid description'); | |
| 426 | + } | |
| 427 | + | |
| 428 | + $this->_description = $string; | |
| 429 | + } | |
| 430 | + | |
| 431 | + /** | |
| 432 | + * Retrieve the description | |
| 433 | + * | |
| 434 | + * @return void | |
| 435 | + */ | |
| 436 | + public function getDescription() | |
| 437 | + { | |
| 438 | + return $this->_description; | |
| 439 | + } | |
| 440 | + | |
| 441 | + /** | |
| 442 | + * Retrieve all prototypes as array of | |
| 443 | + * {@link Rest_Reflection_Prototype Rest_Reflection_Prototypes} | |
| 444 | + * | |
| 445 | + * @return array | |
| 446 | + */ | |
| 447 | + public function getPrototypes() | |
| 448 | + { | |
| 449 | + return $this->_prototypes; | |
| 450 | + } | |
| 451 | + | |
| 452 | + /** | |
| 453 | + * Retrieve additional invocation arguments | |
| 454 | + * | |
| 455 | + * @return array | |
| 456 | + */ | |
| 457 | + public function getInvokeArguments() | |
| 458 | + { | |
| 459 | + return $this->_argv; | |
| 460 | + } | |
| 461 | + | |
| 462 | + /** | |
| 463 | + * Wakeup from serialization | |
| 464 | + * | |
| 465 | + * Reflection needs explicit instantiation to work correctly. Re-instantiate | |
| 466 | + * reflection object on wakeup. | |
| 467 | + * | |
| 468 | + * @return void | |
| 469 | + */ | |
| 470 | + public function __wakeup() | |
| 471 | + { | |
| 472 | + if ($this->_reflection instanceof ReflectionMethod) { | |
| 473 | + $class = new ReflectionClass($this->_class); | |
| 474 | + $this->_reflection = new ReflectionMethod($class->newInstance(), $this->getName()); | |
| 475 | + } else { | |
| 476 | + $this->_reflection = new ReflectionFunction($this->getName()); | |
| 477 | + } | |
| 478 | + } | |
| 479 | +} | ... | ... |
webservice/classes/soap/IPPhpDoc.class.php
0 → 100755
| 1 | +<?PHP | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * The base phpdoc class searches for available classes | |
| 5 | + * | |
| 6 | + *@author KnowledgeTree Team | |
| 7 | + *@package Webservice | |
| 8 | + *@version Version 0.9 | |
| 9 | + */ | |
| 10 | +class IPPhpDoc{ | |
| 11 | + /** @var IPReflectionClass[] Array with available classes */ | |
| 12 | + public $classes = array(); | |
| 13 | + | |
| 14 | + /** @var IPReflectionClass The current class */ | |
| 15 | + public $class = ""; | |
| 16 | + | |
| 17 | + /** | |
| 18 | + * Constructor, initiates the getClasses() method | |
| 19 | + * | |
| 20 | + * @return void | |
| 21 | + */ | |
| 22 | + function __construct() { | |
| 23 | + $this->getClasses(); | |
| 24 | + } | |
| 25 | + | |
| 26 | + /** Sets the current class | |
| 27 | + * @param string The class name | |
| 28 | + * @return void | |
| 29 | + */ | |
| 30 | + public function setClass($class) { | |
| 31 | + $this->class = new IPReflectionClass($class); | |
| 32 | + } | |
| 33 | + /** | |
| 34 | + * Get all classes | |
| 35 | + * | |
| 36 | + * @return IPReflectionClass[] | |
| 37 | + */ | |
| 38 | + function getClasses() { | |
| 39 | + $ar = get_declared_classes(); | |
| 40 | + foreach($ar as $class){ | |
| 41 | + $c = new reflectionClass($class); | |
| 42 | + if($c->isUserDefined()){//add only when class is user-defined | |
| 43 | + $this->classes[$class] = new IPReflectionClass($class); | |
| 44 | + } | |
| 45 | + } | |
| 46 | + ksort($this->classes); | |
| 47 | + return $this->classes; | |
| 48 | + } | |
| 49 | + /** | |
| 50 | + * Generates the documentation page with all classes, methods etc. | |
| 51 | + * @TODO FIXME: use the new template class | |
| 52 | + * @param string Template file (optional) | |
| 53 | + * @return string | |
| 54 | + */ | |
| 55 | + public function getDocumentation($template="classes/soap/templates/docclass.xsl") { | |
| 56 | + if(!is_file($template)) | |
| 57 | + throw new WSException("Could not find the template file: '$template'"); | |
| 58 | + $xtpl = new IPXSLTemplate($template); | |
| 59 | + $documentation = Array(); | |
| 60 | + $documentation['menu'] = Array(); | |
| 61 | + //loop menu items | |
| 62 | + $documentation['menu'] = $this->getClasses(); | |
| 63 | + | |
| 64 | + if($this->class){ | |
| 65 | + if($this->class->isUserDefined()) { | |
| 66 | + $this->class->properties = $this->class->getProperties(false, false); | |
| 67 | + $this->class->methods = $this->class->getMethods(false, false); | |
| 68 | + foreach((array)$this->class->methods as $method) { | |
| 69 | + $method->params = $method->getParameters(); | |
| 70 | + } | |
| 71 | + } else { | |
| 72 | + $documentation['fault'] = "Native class"; | |
| 73 | + } | |
| 74 | + $documentation['class'] = $this->class; | |
| 75 | + } | |
| 76 | + echo $xtpl->execute($documentation); | |
| 77 | + } | |
| 78 | + | |
| 79 | + | |
| 80 | + /** | |
| 81 | + * | |
| 82 | + * @param $comment String The doccomment | |
| 83 | + * @param $annotationName String the annotation name | |
| 84 | + * @param $annotationClass String the annotation class | |
| 85 | + * @return void | |
| 86 | + */ | |
| 87 | + public static function getAnnotation($comment, $annotationName, $annotationClass = null){ | |
| 88 | + if(!$annotationClass){ | |
| 89 | + $annotationClass = $annotationName; | |
| 90 | + } | |
| 91 | + $start = 0; | |
| 92 | + if($start = stripos($comment, "@".$annotationName)){ | |
| 93 | + $obi = new $annotationClass(); | |
| 94 | + $start = strpos($comment, "(", $start); | |
| 95 | + $end = strpos($comment, ")", $start); | |
| 96 | + $propString = substr($comment, $start, ($end-$start) + 1); | |
| 97 | + $eval = "return Array$propString;"; | |
| 98 | + $arr = @eval($eval); | |
| 99 | + if($arr === false) throw new Exception("Error parsing annotation: $propString"); | |
| 100 | + | |
| 101 | + foreach ((Array)$arr as $name => $value){ | |
| 102 | + $obi->$name= $value; | |
| 103 | + } | |
| 104 | + return $obi; | |
| 105 | + } | |
| 106 | + throw new Exception("Cannot find annotation @$annotationName ($start, $end): {$this->comment} "); | |
| 107 | + } | |
| 108 | + | |
| 109 | +} | |
| 110 | +?> | |
| 0 | 111 | \ No newline at end of file | ... | ... |
webservice/classes/soap/IPReflectionClass.class.php
0 → 100755
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * An extended reflection/documentation class for classes | |
| 4 | + * | |
| 5 | + * This class extends the reflectionClass class by also parsing the | |
| 6 | + * comment for javadoc compatible @tags and by providing help | |
| 7 | + * functions to generate a WSDL file. THe class might also | |
| 8 | + * be used to generate a phpdoc on the fly | |
| 9 | + * | |
| 10 | + *@author KnowledgeTree Team | |
| 11 | + *@package Webservice | |
| 12 | + *@version Version 0.9 | |
| 13 | + *@extends reflectionClass | |
| 14 | + */ | |
| 15 | +class IPReflectionClass extends reflectionClass { | |
| 16 | + /** @var string class name */ | |
| 17 | + public $classname = null; | |
| 18 | + | |
| 19 | + /** @var string */ | |
| 20 | + public $fullDescription = ""; | |
| 21 | + | |
| 22 | + /** @var string */ | |
| 23 | + public $smallDescription = ""; | |
| 24 | + | |
| 25 | + /** @var IPReflectionMethod[] */ | |
| 26 | + public $methods = Array(); | |
| 27 | + | |
| 28 | + /** @var IPReflectionProperty[] */ | |
| 29 | + public $properties = Array(); | |
| 30 | + | |
| 31 | + /** @var string */ | |
| 32 | + public $extends; | |
| 33 | + | |
| 34 | + /** @var string */ | |
| 35 | + private $comment = null; | |
| 36 | + | |
| 37 | + | |
| 38 | + /** | |
| 39 | + * Constructor | |
| 40 | + * | |
| 41 | + * sets the class name and calls the constructor of the reflectionClass | |
| 42 | + * | |
| 43 | + * @param string The class name | |
| 44 | + * @return void | |
| 45 | + */ | |
| 46 | + public function __construct($classname){ | |
| 47 | + $this->classname = $classname; | |
| 48 | + parent::__construct($classname); | |
| 49 | + | |
| 50 | + $this->parseComment(); | |
| 51 | + } | |
| 52 | + | |
| 53 | + /** | |
| 54 | + *Provides all methods exposed by this class as an array | |
| 55 | + * | |
| 56 | + * @param boolean If the method should also return protected functions | |
| 57 | + * @param boolean If the method should also return private functions | |
| 58 | + * @return IPReflectionMethod[] | |
| 59 | + */ | |
| 60 | + public function getMethods($alsoProtected = true, $alsoPrivate = true){ | |
| 61 | + $ar = parent::getMethods(); | |
| 62 | + foreach($ar as $method){ | |
| 63 | + $m = new IPReflectionMethod($this->classname, $method->name); | |
| 64 | + if((!$m->isPrivate() || $alsoPrivate) && (!$m->isProtected() || $alsoProtected) && ($m->getDeclaringClass()->name == $this->classname)) | |
| 65 | + $this->methods[$method->name] = $m; | |
| 66 | + } | |
| 67 | + ksort($this->methods); | |
| 68 | + return $this->methods; | |
| 69 | + } | |
| 70 | + | |
| 71 | + /** | |
| 72 | + * Exposes an array with public properties of the class | |
| 73 | + * | |
| 74 | + * @param boolean If the method should also return protected properties | |
| 75 | + * @param boolean If the method should also return private properties | |
| 76 | + * @return IPReflectionProperty[] | |
| 77 | + */ | |
| 78 | + public function getProperties($alsoProtected=true,$alsoPrivate=true) { | |
| 79 | + $ar = parent::getProperties(); | |
| 80 | + $this->properties = Array(); | |
| 81 | + foreach($ar as $property){ | |
| 82 | + if((!$property->isPrivate() || $alsoPrivate) && (!$property->isProtected() || $alsoProtected)){ | |
| 83 | + try{ | |
| 84 | + $p = new IPReflectionProperty($this->classname, $property->getName()); | |
| 85 | + $this->properties[$property->name]=$p; | |
| 86 | + }catch(ReflectionException $exception){ | |
| 87 | + echo "Fault on property: ".$property->name."<br>\n"; | |
| 88 | + } | |
| 89 | + } | |
| 90 | + } | |
| 91 | + ksort($this->properties); | |
| 92 | + return $this->properties; | |
| 93 | + } | |
| 94 | + | |
| 95 | + /** | |
| 96 | + * Exposes annotations of the class | |
| 97 | + * @param $annotationName String the annotation name | |
| 98 | + * @param $annotationClass String the annotation class | |
| 99 | + * @return void | |
| 100 | + */ | |
| 101 | + public function getAnnotation($annotationName, $annotationClass = null){ | |
| 102 | + return IPPhpDoc::getAnnotation($this->comment, $annotationName, $annotationClass); | |
| 103 | + } | |
| 104 | + | |
| 105 | + /** | |
| 106 | + * Gets all the usefull information from the comments | |
| 107 | + * @return void | |
| 108 | + */ | |
| 109 | + private function parseComment() { | |
| 110 | + $this->comment = $this->getDocComment(); | |
| 111 | + new IPReflectionCommentParser($this->comment, $this); | |
| 112 | + } | |
| 113 | +} | |
| 114 | +?> | |
| 0 | 115 | \ No newline at end of file | ... | ... |
webservice/classes/soap/IPReflectionCommentParser.class.php
0 → 100755
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * Class for parsing the comment blocks for classes, functions | |
| 4 | + * methods and properties. | |
| 5 | + * | |
| 6 | + * The class parses the commentblock and extracts certain | |
| 7 | + * documentation tags and the (full/small) description | |
| 8 | + * | |
| 9 | + *@author KnowledgeTree Team | |
| 10 | + *@package Webservice | |
| 11 | + *@version Version 0.9 | |
| 12 | + */ | |
| 13 | + | |
| 14 | +class IPReflectionCommentParser{ | |
| 15 | + /** | |
| 16 | + * @var string Contains the full commen text | |
| 17 | + */ | |
| 18 | + public $comment; | |
| 19 | + | |
| 20 | + /** | |
| 21 | + * @var object refence to the IPReflection(Class|Method|Property) | |
| 22 | + */ | |
| 23 | + public $obj; | |
| 24 | + | |
| 25 | + /** @var boolean */ | |
| 26 | + public $smallDescriptionDone; | |
| 27 | + | |
| 28 | + /** @var boolean */ | |
| 29 | + public $fullDescriptionDone; | |
| 30 | + | |
| 31 | + /** | |
| 32 | + * Constructor, initiateds the parse function | |
| 33 | + * | |
| 34 | + * @param string Commentaar block | |
| 35 | + * @param string Defines if its the comment for a class, public of function | |
| 36 | + */ | |
| 37 | + function __construct($comment, $obj) { | |
| 38 | + $this->comment = $comment; | |
| 39 | + $this->obj = $obj; | |
| 40 | + $this->parse(); | |
| 41 | + } | |
| 42 | + /** | |
| 43 | + * parses the comment, line for line | |
| 44 | + * | |
| 45 | + * Will take the type of comment (class, property or function) as an | |
| 46 | + * argument and split it up in lines. | |
| 47 | + * @param string Defines if its the comment for a class, public of function | |
| 48 | + * @return void | |
| 49 | + */ | |
| 50 | + function parse() { | |
| 51 | + //reset object | |
| 52 | + $descriptionDone = false; | |
| 53 | + $this->fullDescriptionDone = false; | |
| 54 | + | |
| 55 | + //split lines | |
| 56 | + $lines = split("\n", $this->comment); | |
| 57 | + | |
| 58 | + //check lines for description or tags | |
| 59 | + foreach ($lines as $line) { | |
| 60 | + $pos = strpos($line,"* @"); | |
| 61 | + if (trim($line) == "/**" || trim($line) == "*/") { //skip the start and end line | |
| 62 | + }elseif (!($pos === false)) { //comment | |
| 63 | + $this->parseTagLine(substr($line,$pos+3)); | |
| 64 | + $descriptionDone=true; | |
| 65 | + }elseif(!$descriptionDone){ | |
| 66 | + $this->parseDescription($line); | |
| 67 | + } | |
| 68 | + } | |
| 69 | + //if full description is empty, put small description in full description | |
| 70 | + if (trim(str_replace(Array("\n","\r"), Array("", ""), $this->obj->fullDescription)) == "") | |
| 71 | + $this->obj->fullDescription = $this->obj->smallDescription; | |
| 72 | + } | |
| 73 | + | |
| 74 | + /** | |
| 75 | + * Parses the description to the small and full description properties | |
| 76 | + * | |
| 77 | + * @param string The description line | |
| 78 | + * @return void | |
| 79 | + */ | |
| 80 | + | |
| 81 | + function parseDescription($descriptionLine) { | |
| 82 | + if(strpos($descriptionLine,"*") <= 2) $descriptionLine = substr($descriptionLine, (strpos($descriptionLine,"*") + 1)); | |
| 83 | + | |
| 84 | + //geen lege comment regel indien al in grote omschrijving | |
| 85 | + if(trim(str_replace(Array("\n","\r"), Array("", ""), $descriptionLine)) == ""){ | |
| 86 | + if($this->obj->fullDescription == "") | |
| 87 | + $descriptionLine = ""; | |
| 88 | + $this->smallDescriptionDone = true; | |
| 89 | + } | |
| 90 | + | |
| 91 | + if(!$this->smallDescriptionDone)//add to small description | |
| 92 | + $this->obj->smallDescription.=$descriptionLine; | |
| 93 | + else{//add to full description | |
| 94 | + $this->obj->fullDescription.=$descriptionLine; | |
| 95 | + } | |
| 96 | + } | |
| 97 | + | |
| 98 | + /** | |
| 99 | + * Parses a tag line and extracts the tagname and values | |
| 100 | + * | |
| 101 | + * @param string The tagline | |
| 102 | + * @return void | |
| 103 | + */ | |
| 104 | + function parseTagLine($tagLine) { | |
| 105 | + $tagArr = explode(" ", $tagLine); | |
| 106 | + $tag = $tagArr[0]; | |
| 107 | + | |
| 108 | + switch(strtolower($tag)){ | |
| 109 | + case 'abstract': | |
| 110 | + $this->obj->abstract = true; break; | |
| 111 | + case 'access': | |
| 112 | + $this->obj->isPrivate = (strtolower(trim($tagArr[1]))=="private")?true:false; | |
| 113 | + break; | |
| 114 | + case 'author': | |
| 115 | + unset($tagArr[0]); | |
| 116 | + $this->obj->author = implode(" ",$tagArr); | |
| 117 | + break; | |
| 118 | + case 'copyright': | |
| 119 | + unset($tagArr[0]); | |
| 120 | + $this->obj->copyright = implode(" ",$tagArr); | |
| 121 | + break; | |
| 122 | + case 'deprecated': | |
| 123 | + case 'deprec': | |
| 124 | + $this->obj->deprecated = true; | |
| 125 | + break; | |
| 126 | + case 'extends': break; | |
| 127 | + case 'global': | |
| 128 | + $this->obj->globals[] = $tagArr[1]; | |
| 129 | + break; | |
| 130 | + case 'param': | |
| 131 | + $o = new stdClass(); | |
| 132 | + $o->type = trim($tagArr[1]); | |
| 133 | + $o->comment = implode(" ",$tagArr); | |
| 134 | + $this->obj->params[] = $o; | |
| 135 | + break; | |
| 136 | + case 'return': | |
| 137 | + $this->obj->return = trim($tagArr[1]); break; | |
| 138 | + case 'link':break; | |
| 139 | + case 'see':break; | |
| 140 | + case 'since': | |
| 141 | + $this->obj->since = trim($tagArr[1]); break; | |
| 142 | + case 'static': | |
| 143 | + $this->obj->static = true; break; | |
| 144 | + case 'throws': | |
| 145 | + unset($tagArr[0]); | |
| 146 | + $this->obj->throws = implode(" ",$tagArr); | |
| 147 | + break; | |
| 148 | + case 'todo': | |
| 149 | + unset($tagArr[0]); | |
| 150 | + $this->obj->todo[] = implode(" ",$tagArr); | |
| 151 | + break; | |
| 152 | + case 'var': | |
| 153 | + $this->obj->type = trim($tagArr[1]); | |
| 154 | + unset($tagArr[0],$tagArr[1]); | |
| 155 | + $comment=implode(" ",$tagArr); | |
| 156 | + //check if its an optional property | |
| 157 | + $this->obj->optional = strpos($comment,"[OPTIONAL]") !== FALSE; | |
| 158 | + $this->obj->autoincrement = strpos($comment,"[AUTOINCREMENT]") !== FALSE; | |
| 159 | + $this->obj->description = str_replace("[OPTIONAL]", "", $comment); | |
| 160 | + break; | |
| 161 | + case 'version': | |
| 162 | + $this->obj->version = $tagArr[1]; | |
| 163 | + break; | |
| 164 | + default: | |
| 165 | + //echo "\nno valid tag: '".strtolower($tag)."' at tagline: '$tagLine' <br>"; | |
| 166 | + //do nothing | |
| 167 | + } | |
| 168 | + } | |
| 169 | +} | |
| 170 | +?> | |
| 0 | 171 | \ No newline at end of file | ... | ... |
webservice/classes/soap/IPReflectionMethod.class.php
0 → 100755
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * An extended reflection/documentation class for class methods | |
| 4 | + * | |
| 5 | + * This class extends the reflectioMethod class by also parsing the | |
| 6 | + * comment for javadoc compatible @tags and by providing help | |
| 7 | + * functions to generate a WSDL file. The class might also | |
| 8 | + * be used to generate a phpdoc on the fly | |
| 9 | + * | |
| 10 | + *@author KnowledgeTree Team | |
| 11 | + *@package Webservice | |
| 12 | + *@version Version 0.9 | |
| 13 | + *@extends reflectionMethod | |
| 14 | + */ | |
| 15 | + | |
| 16 | +class IPReflectionMethod extends reflectionMethod{ | |
| 17 | + /** @var string class name */ | |
| 18 | + public $classname; | |
| 19 | + | |
| 20 | + /** @var string The return type for this method */ | |
| 21 | + public $return = ""; | |
| 22 | + | |
| 23 | + /** @var IPReflectionParameter[] Associative array with reflectionParameter objects */ | |
| 24 | + public $parameters = array(); | |
| 25 | + | |
| 26 | + /** @var string */ | |
| 27 | + public $fullDescription = ""; | |
| 28 | + | |
| 29 | + /** @var string */ | |
| 30 | + public $smallDescription = ""; | |
| 31 | + | |
| 32 | + /** @var string */ | |
| 33 | + public $throws=""; | |
| 34 | + | |
| 35 | + /** | |
| 36 | + * Constructor which calls the parent constructor and makes sure the comment | |
| 37 | + * of the method is parsed | |
| 38 | + * | |
| 39 | + * @param string The class name | |
| 40 | + * @param string The method name | |
| 41 | + */ | |
| 42 | + public function __construct($class,$method){ | |
| 43 | + $this->classname = $class; | |
| 44 | + parent::__construct($class,$method); | |
| 45 | + $this->parseComment(); | |
| 46 | + } | |
| 47 | + | |
| 48 | + /** | |
| 49 | + * Returns the full function name, including arguments | |
| 50 | + * @return string | |
| 51 | + */ | |
| 52 | + public function getFullName(){ | |
| 53 | + $args = $this->getParameters(); | |
| 54 | + $argstr = ""; | |
| 55 | + | |
| 56 | + foreach((array)$args as $arg){ | |
| 57 | + if($argstr!="")$argstr.=", "; | |
| 58 | + $argstr.= $arg->type ." $".$arg->name; | |
| 59 | + } | |
| 60 | + return $this->return." ".$this->name."(".$argstr.")"; | |
| 61 | + } | |
| 62 | + | |
| 63 | + /** | |
| 64 | + * Returns an array with parameter objects, containing type info etc. | |
| 65 | + * | |
| 66 | + * @return ReflectionParameter[] Associative array with parameter objects | |
| 67 | + */ | |
| 68 | + public function getParameters(){ | |
| 69 | + $this->parameters = Array(); | |
| 70 | + $ar = parent::getParameters(); | |
| 71 | + $i = 0; | |
| 72 | + | |
| 73 | + foreach((array)$ar as $parameter){ | |
| 74 | + $parameter->type = $this->params[$i++]->type; | |
| 75 | + $this->parameters[$parameter->name] = $parameter; | |
| 76 | + } | |
| 77 | + | |
| 78 | + return $this->parameters; | |
| 79 | + } | |
| 80 | + | |
| 81 | + /** | |
| 82 | + * | |
| 83 | + * @param $annotationName String the annotation name | |
| 84 | + * @param $annotationClass String the annotation class | |
| 85 | + * @return void | |
| 86 | + */ | |
| 87 | + public function getAnnotation($annotationName, $annotationClass = null){ | |
| 88 | + return IPPhpDoc::getAnnotation($this->comment, $annotationName, $annotationClass); | |
| 89 | + } | |
| 90 | + | |
| 91 | + /** | |
| 92 | + * Parses the comment and adds found properties to this class | |
| 93 | + * @return void | |
| 94 | + */ | |
| 95 | + private function parseComment(){ | |
| 96 | + $this->comment = $this->getDocComment(); | |
| 97 | + new IPReflectionCommentParser($this->comment, $this); | |
| 98 | + } | |
| 99 | +} | |
| 100 | +?> | |
| 0 | 101 | \ No newline at end of file | ... | ... |
webservice/classes/soap/IPReflectionProperty.class.php
0 → 100755
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * An extended reflection/documentation class for class properties | |
| 4 | + * | |
| 5 | + * This class extends the reflectionProperty class by also parsing the | |
| 6 | + * comment for javadoc compatible @tags and by providing help | |
| 7 | + * functions to generate a WSDL file. The class might also | |
| 8 | + * be used to generate a phpdoc on the fly | |
| 9 | + * | |
| 10 | + *@author KnowledgeTree Team | |
| 11 | + *@package Webservice | |
| 12 | + *@version Version 0.9 | |
| 13 | + *@extends reflectionProperty | |
| 14 | + */ | |
| 15 | +class IPReflectionProperty extends reflectionProperty { | |
| 16 | + /** @var string Classname to whom this property belongs */ | |
| 17 | + public $classname; | |
| 18 | + | |
| 19 | + /** @var string Type description of the property */ | |
| 20 | + public $type = ""; | |
| 21 | + | |
| 22 | + /** @var boolean Determens if the property is a private property */ | |
| 23 | + public $isPrivate = false; | |
| 24 | + | |
| 25 | + /** @var string */ | |
| 26 | + public $description; | |
| 27 | + | |
| 28 | + /** @var boolean */ | |
| 29 | + public $optional = false; | |
| 30 | + | |
| 31 | + /** @var boolean */ | |
| 32 | + public $autoincrement = false; | |
| 33 | + | |
| 34 | + /** @var string */ | |
| 35 | + public $fullDescription = ""; | |
| 36 | + | |
| 37 | + /** @var string */ | |
| 38 | + public $smallDescription = ""; | |
| 39 | + | |
| 40 | + /** @var string */ | |
| 41 | + public $name = null; | |
| 42 | + | |
| 43 | + /** @var string */ | |
| 44 | + private $comment = null; | |
| 45 | + | |
| 46 | + /** | |
| 47 | + * constructor. will initiate the commentParser | |
| 48 | + * | |
| 49 | + * @param string Class name | |
| 50 | + * @param string Property name | |
| 51 | + * @return void | |
| 52 | + */ | |
| 53 | + public function __construct($class, $property){ | |
| 54 | + $this->classname = $class; | |
| 55 | + parent::__construct($class, $property); | |
| 56 | + $this->parseComment(); | |
| 57 | + } | |
| 58 | + | |
| 59 | + /** | |
| 60 | + * | |
| 61 | + * @param $annotationName String the annotation name | |
| 62 | + * @param $annotationClass String the annotation class | |
| 63 | + * @return void | |
| 64 | + */ | |
| 65 | + public function getAnnotation($annotationName, $annotationClass = null){ | |
| 66 | + return IPPhpDoc::getAnnotation($this->comment, $annotationName, $annotationClass); | |
| 67 | + } | |
| 68 | + | |
| 69 | + private function parseComment(){ | |
| 70 | + // No getDocComment available for properties in php 5.0.3 :( | |
| 71 | + $this->comment = $this->getDocComment(); | |
| 72 | + new IPReflectionCommentParser($this->comment, $this); | |
| 73 | + } | |
| 74 | +} | |
| 75 | +?> | |
| 0 | 76 | \ No newline at end of file | ... | ... |
webservice/classes/soap/IPXMLSchema.class.php
0 → 100755
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * This class helps you creating a valid XMLSchema file | |
| 5 | + *@author KnowledgeTree Team | |
| 6 | + *@package Webservice | |
| 7 | + *@version Version 0.9 | |
| 8 | + */ | |
| 9 | +class IPXMLSchema { | |
| 10 | + /** @var domelement reference to the parent domelement */ | |
| 11 | + private $parentElement; | |
| 12 | + | |
| 13 | + /** @var domelement[] Array with references to all known types in this schema */ | |
| 14 | + private $types = Array(); | |
| 15 | + | |
| 16 | + /** @var boolean True=place array's inline */ | |
| 17 | + private $array_inline = false; | |
| 18 | + | |
| 19 | + public function __construct(domelement $parentElement){ | |
| 20 | + $this->parentElement = $parentElement; | |
| 21 | + } | |
| 22 | + | |
| 23 | + /** | |
| 24 | + * Ads a complexType tag with xmlschema content to the types tag | |
| 25 | + * @param string The variable type (Array or class name) | |
| 26 | + * @param string The variable name | |
| 27 | + * @param domNode Used when adding an inline complexType | |
| 28 | + * @return domNode The complexType node | |
| 29 | + */ | |
| 30 | + | |
| 31 | + public function addComplexType($type, $name = false, $parent = false) { | |
| 32 | + if(!$parent){//outline element | |
| 33 | + //check if the complexType doesn't already exists | |
| 34 | + if(isset($this->types[$name])) return $this->types[$name]; | |
| 35 | + | |
| 36 | + //create the complexType tag beneath the xsd:schema tag | |
| 37 | + $complexTypeTag=$this->addElement("xsd:complexType", $this->parentElement); | |
| 38 | + if($name){//might be an anonymous element | |
| 39 | + $complexTypeTag->setAttribute("name",$name); | |
| 40 | + $this->types[$name]=$complexTypeTag; | |
| 41 | + } | |
| 42 | + }else{//inline element | |
| 43 | + $complexTypeTag = $this->addElement("xsd:complexType", $parent); | |
| 44 | + } | |
| 45 | + | |
| 46 | + //check if its an array | |
| 47 | + if(strtolower(substr($type,0,6)) == 'array(' || substr($type,-2) == '[]'){ | |
| 48 | + $this->addArray($type,$complexTypeTag); | |
| 49 | + }else{//it should be an object | |
| 50 | + $tag=$this->addElement("xsd:all", $complexTypeTag); | |
| 51 | + //check if it has the name 'object()' (kind of a stdClass) | |
| 52 | + if(strtolower(substr($type,0,6)) == 'object'){//stdClass | |
| 53 | + $content = substr($type, 7, (strlen($type)-1)); | |
| 54 | + $properties = split(",", $content);//split the content into properties | |
| 55 | + foreach((array)$properties as $property){ | |
| 56 | + if($pos = strpos($property, "=>")){//array with keys (order is important, so use 'sequence' tag) | |
| 57 | + $keyType = substr($property,6,($pos-6)); | |
| 58 | + $valueType = substr($property,($pos+2), (strlen($property)-7)); | |
| 59 | + $el->$this->addTypeElement($valueType, $keyType, $tag); | |
| 60 | + }else{ | |
| 61 | + throw new WSDLException("Error creating WSDL: expected \"=>\". When using the object() as type, use it as object(paramname=>paramtype,paramname2=>paramtype2)"); | |
| 62 | + } | |
| 63 | + } | |
| 64 | + }else{ //should be a known class | |
| 65 | + | |
| 66 | + if(!class_exists($name)) throw new WSDLException("Error creating WSDL: no class found with the name '$name' / $type : $parent, so how should we know the structure for this datatype?"); | |
| 67 | + $v = new IPReflectionClass($name); | |
| 68 | + //TODO: check if the class extends another class? | |
| 69 | + $properties = $v->getProperties(false, false);//not protected and private properties | |
| 70 | + | |
| 71 | + foreach((array) $properties as $property){ | |
| 72 | + if(!$property->isPrivate){ | |
| 73 | + $el = $this->addTypeElement($property->type, $property->name, $tag, $property->optional); | |
| 74 | + } | |
| 75 | + } | |
| 76 | + } | |
| 77 | + } | |
| 78 | + return $complexTypeTag; | |
| 79 | + } | |
| 80 | + | |
| 81 | + /** | |
| 82 | + * Adds an element tag beneath the parent and takes care | |
| 83 | + * of the type (XMLSchema type or complexType) | |
| 84 | + * @param string The datatype | |
| 85 | + * @param string Name of the element | |
| 86 | + * @param domNode The parent domNode | |
| 87 | + * @param boolean If the property is optional | |
| 88 | + * @return domNode | |
| 89 | + */ | |
| 90 | + public function addTypeElement($type, $name, $parent, $optional = false) { | |
| 91 | + $el = $this->addElement("xsd:element", $parent); | |
| 92 | + $el->setAttribute("name", $name); | |
| 93 | + | |
| 94 | + if($optional){//if it's an optional property, set minOccur to 0 | |
| 95 | + $el->setAttribute("minOccurs", "0"); | |
| 96 | + $el->setAttribute("maxOccurs", "1"); | |
| 97 | + } | |
| 98 | + | |
| 99 | + //check if XML Schema datatype | |
| 100 | + if($t = $this->checkSchemaType(strtolower($type))) | |
| 101 | + $el->setAttribute("type", "xsd:".$t); | |
| 102 | + else{//no XML Schema datatype | |
| 103 | + //if valueType==Array, then create anonymouse inline complexType (within element tag without type attribute) | |
| 104 | + if(substr($type,-2) == '[]'){ | |
| 105 | + if($this->array_inline){ | |
| 106 | + $this->addComplexType($type, false, $el); | |
| 107 | + }else{ | |
| 108 | + $name = substr($type, 0, -2)."Array"; | |
| 109 | + $el->setAttribute("type", "tns:".$name); | |
| 110 | + $this->addComplexType($type, $name, false); | |
| 111 | + } | |
| 112 | + }else{//else, new complextype, outline (element with 'ref' attrib) | |
| 113 | + $el->setAttribute("type", "tns:".$type); | |
| 114 | + $this->addComplexType($type, $type); | |
| 115 | + } | |
| 116 | + } | |
| 117 | + return $el; | |
| 118 | + } | |
| 119 | + | |
| 120 | + /** | |
| 121 | + * Creates an xmlSchema element for the given array | |
| 122 | + */ | |
| 123 | + public function addArray($type, $parent) { | |
| 124 | + $cc = $this->addElement("xsd:complexContent", $parent); | |
| 125 | + $rs = $this->addElement("xsd:restriction", $cc); | |
| 126 | + $rs->setAttribute("base", "SOAP-ENC:Array"); | |
| 127 | + | |
| 128 | + $type = (substr($type,-2) == '[]') ? substr($type, 0, (strlen($type)-2)) : substr($type, 6, (strlen($type)-7)); | |
| 129 | + $el = $this->addElement("xsd:attribute", $rs); | |
| 130 | + $el->setAttribute("ref", "SOAP-ENC:arrayType"); | |
| 131 | + | |
| 132 | + //check if XML Schema datatype | |
| 133 | + if($t = $this->checkSchemaType(strtolower($type))) | |
| 134 | + $el->setAttribute("wsdl:arrayType", "xsd:".$t."[]"); | |
| 135 | + else{//no XML Schema datatype | |
| 136 | + //if valueType==Array, then create anonymouse inline complexType (within element tag without type attribute) | |
| 137 | + if(substr($type,-2) == '[]'){ | |
| 138 | + $this->addComplexType($type, false, $el); | |
| 139 | + }else{//else, new complextype, outline (element with 'ref' attrib) | |
| 140 | + $el->setAttribute("wsdl:arrayType", "tns:".$type."[]"); | |
| 141 | + $this->addComplexType($type, $type); | |
| 142 | + } | |
| 143 | + } | |
| 144 | + return $el; | |
| 145 | + } | |
| 146 | + | |
| 147 | + /** | |
| 148 | + * Checks if the given type is a valid XML Schema type or can be casted to a schema type | |
| 149 | + * @param string The datatype | |
| 150 | + * @return string | |
| 151 | + */ | |
| 152 | + public static function checkSchemaType($type) { | |
| 153 | + //XML Schema types | |
| 154 | + $types = Array("string" => "string", | |
| 155 | + "int" => "int", | |
| 156 | + "integer" => "int", | |
| 157 | + "boolean" => "boolean", | |
| 158 | + "float" => "float"); | |
| 159 | + if(isset($types[$type])) return $types[$type]; | |
| 160 | + else return false; | |
| 161 | + } | |
| 162 | + | |
| 163 | + /** | |
| 164 | + * Adds an child element to the parent | |
| 165 | + * @param string | |
| 166 | + * @param domNode | |
| 167 | + * @return domNode | |
| 168 | + */ | |
| 169 | + private function addElement($name, $parent = false, $ns = false) { | |
| 170 | + if($ns) | |
| 171 | + $el = $parent->ownerDocument->createElementNS($ns, $name); | |
| 172 | + else | |
| 173 | + $el = $parent->ownerDocument->createElement($name); | |
| 174 | + if($parent) | |
| 175 | + $parent->appendChild($el); | |
| 176 | + return $el; | |
| 177 | + } | |
| 178 | +} | |
| 179 | +?> | |
| 0 | 180 | \ No newline at end of file | ... | ... |
webservice/classes/soap/IPXSLTemplate.class.php
0 → 100755
| 1 | +<?php | |
| 2 | +class tagRegistration { | |
| 3 | + public $namespace; | |
| 4 | + public $tagName; | |
| 5 | + public $function; | |
| 6 | + public function __construct($namespace, $tagName, $function) { | |
| 7 | + $this->namespace = $namespace; | |
| 8 | + $this->tagName = $tagName; | |
| 9 | + $this->function = $function; | |
| 10 | + } | |
| 11 | + | |
| 12 | + public function process($node) { | |
| 13 | + $x = $node; | |
| 14 | + eval($this->function); | |
| 15 | + } | |
| 16 | +} | |
| 17 | + | |
| 18 | + | |
| 19 | +class IPXSLTemplate { | |
| 20 | + const NAMESPACE = "http://schema.knowledgetree.com/xmltemplate/"; | |
| 21 | + public $dom = null; | |
| 22 | + public $xsltproc = null; | |
| 23 | + public $customTags = Array(); | |
| 24 | + | |
| 25 | + public function __construct($file) { | |
| 26 | + $this->dom = new DOMDocument(); | |
| 27 | + $this->dom->load($file); | |
| 28 | + $this->xsltproc = new XSLTProcessor(); | |
| 29 | + $this->xsltproc->registerPHPFunctions(); | |
| 30 | + } | |
| 31 | + | |
| 32 | + public function execute($model) { | |
| 33 | + //process custom tags | |
| 34 | + foreach($this->customTags as $reg) { | |
| 35 | + $nodelist = $this->dom->getElementsByTagNameNS($reg->namespace, $reg->tagName); | |
| 36 | + for($i = $nodelist->length; $i > 0; $i--){ | |
| 37 | + $reg->process($nodelist->item($i-1)); | |
| 38 | + } | |
| 39 | + } | |
| 40 | + | |
| 41 | + $this->xsltproc->importStyleSheet($this->dom); | |
| 42 | + | |
| 43 | + $modelDom = new DomDocument(); | |
| 44 | + $modelDom->appendChild($modelDom->createElement("model")); //root node | |
| 45 | + IPXSLTemplate::makeXML($model, $modelDom->documentElement); | |
| 46 | + //echo $modelDom->saveXML(); | |
| 47 | + return $this->xsltproc->transformToXml($modelDom); | |
| 48 | + } | |
| 49 | + | |
| 50 | + /** Add a new custom tag registration */ | |
| 51 | + public function registerTag($namespace, $tagName, $function) { | |
| 52 | + $this->customTags[] = new tagRegistration($namespace, $tagName, $function); | |
| 53 | + } | |
| 54 | + | |
| 55 | + /** Makes a XML node from an object/ array / text */ | |
| 56 | + static function makeXML($model, $parent, $addToParent = false) { | |
| 57 | + if(is_array($model)){ | |
| 58 | + foreach($model as $name => $value){ | |
| 59 | + if(!is_numeric($name)) { | |
| 60 | + $node = $parent->ownerDocument->createElement($name); | |
| 61 | + $parent->appendChild($node); | |
| 62 | + IPXSLTemplate::makeXml($value, $node, true); | |
| 63 | + } else { | |
| 64 | + $node = $parent; | |
| 65 | + IPXSLTemplate::makeXml($value, $node); | |
| 66 | + } | |
| 67 | + } | |
| 68 | + } elseif (is_object($model)) { | |
| 69 | + if($addToParent) | |
| 70 | + $node = $parent; | |
| 71 | + else{ | |
| 72 | + $node = $parent->ownerDocument->createElement(get_class($model)); | |
| 73 | + $parent->appendChild($node); | |
| 74 | + } | |
| 75 | + foreach($model as $propertyName => $propertyValue){ | |
| 76 | + $property = $parent->ownerDocument->createElement($propertyName); | |
| 77 | + $node->appendChild($property); | |
| 78 | + IPXSLTemplate::makeXml($propertyValue, $property); | |
| 79 | + } | |
| 80 | + } else { | |
| 81 | + $parent->appendChild($parent->ownerDocument->createTextNode($model)); | |
| 82 | + } | |
| 83 | + } | |
| 84 | +} | |
| 85 | +?> | |
| 0 | 86 | \ No newline at end of file | ... | ... |
webservice/classes/soap/WSDLException.class.php
0 → 100755
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * Exception class which can be thrown by | |
| 4 | + * the WSDLStruct class. | |
| 5 | + * | |
| 6 | + *@author KnowledgeTree Team | |
| 7 | + *@package Webservice | |
| 8 | + *@version Version 0.9 | |
| 9 | + */ | |
| 10 | +class WSDLException extends Exception { | |
| 11 | + /** | |
| 12 | + * @param string The error message | |
| 13 | + * @return void | |
| 14 | + */ | |
| 15 | + function __construct($msg) { | |
| 16 | + $this->msg = $msg; | |
| 17 | + } | |
| 18 | + /** | |
| 19 | + * @return void | |
| 20 | + */ | |
| 21 | + function Display() { | |
| 22 | + print "Error creating WSDL document:".$this->msg; | |
| 23 | + //var_dump(debug_backtrace()); | |
| 24 | + } | |
| 25 | +} | |
| 26 | +?> | |
| 0 | 27 | \ No newline at end of file | ... | ... |
webservice/classes/soap/WSDLStruct.class.php
0 → 100755
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * Class that can generate a WSDL document from PHP code | |
| 4 | + * | |
| 5 | + * This class generates a WSDL document for the given | |
| 6 | + * methods when the the methods and parameters are documented | |
| 7 | + * enough. When there is not enough documentation available (ie | |
| 8 | + * unclear what the type of a variable or return type is) a | |
| 9 | + * WSDLException is thrown. | |
| 10 | + * | |
| 11 | + * | |
| 12 | + *@author KnowledgeTree Team | |
| 13 | + *@package Webservice | |
| 14 | + *@version Version 0.9 | |
| 15 | + */ | |
| 16 | +class WSDLStruct { | |
| 17 | + /** @var boolean */ | |
| 18 | + public $_debug = false; | |
| 19 | + | |
| 20 | + /** @var int binding type: SOAP_RPC | SOAP_DOCUMENT */ | |
| 21 | + public $binding_style; | |
| 22 | + | |
| 23 | + /** @var int use: SOAP_LITERAL | SOAP_ENCODED */ | |
| 24 | + public $use; | |
| 25 | + /************************** Private properties ***************************/ | |
| 26 | + | |
| 27 | + /** @var SOAPService[] */ | |
| 28 | + private $services = Array(); | |
| 29 | + | |
| 30 | + /** @var domElement[] */ | |
| 31 | + private $serviceTags = Array(); | |
| 32 | + | |
| 33 | + /** @var domElement[] */ | |
| 34 | + private $operationTags = Array(); | |
| 35 | + | |
| 36 | + /** @var domElement[] references to the portType tags. servicename as key */ | |
| 37 | + private $portTypeTags = Array(); | |
| 38 | + | |
| 39 | + /** @var domElement[] references to the binding tags. servicename as key */ | |
| 40 | + private $bindingTags = Array(); | |
| 41 | + | |
| 42 | + /** @var domElement[] references to the binding operation tags. servicename as first key, operationname as second */ | |
| 43 | + private $bindingOperationTags = Array(); | |
| 44 | + | |
| 45 | + /** @var domDocument */ | |
| 46 | + private $doc; | |
| 47 | + | |
| 48 | + /** @var domelement */ | |
| 49 | + private $definitions; | |
| 50 | + | |
| 51 | + /** @var domelement Refference tot the types tag*/ | |
| 52 | + private $typesTag; | |
| 53 | + | |
| 54 | + /** @var domelement Refference to the xsd:schema tag*/ | |
| 55 | + private $xsdSchema; | |
| 56 | + | |
| 57 | + /** @var IPXMLSchema */ | |
| 58 | + private $xmlSchema; | |
| 59 | + | |
| 60 | + //namespaces used | |
| 61 | + const NS_WSDL = "http://schemas.xmlsoap.org/wsdl/"; | |
| 62 | + const NS_SOAP = "http://schemas.xmlsoap.org/wsdl/soap/"; | |
| 63 | + const NS_ENC = "http://schemas.xmlsoap.org/soap/encoding/"; | |
| 64 | + const NS_XSD = "http://www.w3.org/2001/XMLSchema"; | |
| 65 | + | |
| 66 | + const CREATE_EMPTY_INPUTS = true; | |
| 67 | + | |
| 68 | + /* | |
| 69 | + * @param string Target namespace | |
| 70 | + * @param string URL for the webservice | |
| 71 | + * @return void | |
| 72 | + */ | |
| 73 | + public function __construct($tns, $url, $type = SOAP_RPC, $use = SOAP_ENCODED){ | |
| 74 | + if($type != SOAP_RPC && $type != SOAP_DOCUMENT) throw new Exception("Webservice type parameter should be either SOAP_RPC or SOAP_DOCUMENT"); | |
| 75 | + if($use != SOAP_ENCODED && $use != SOAP_LITERAL) throw new Exception("Webservice use parameter should be either SOAP_ENCODED or SOAP_LITERAL"); | |
| 76 | + | |
| 77 | + $this->use = $use; | |
| 78 | + $this->binding_style=$type; | |
| 79 | + $this->tns = $tns; | |
| 80 | + $this->url = $url; | |
| 81 | + $this->doc = new domDocument(); | |
| 82 | + $this->definitions = $this->addElement("wsdl:definitions",$this->doc); | |
| 83 | + | |
| 84 | + $this->typesTag = $this->addElement("wsdl:types", $this->definitions); | |
| 85 | + $this->xsdSchema = $this->addElement("xsd:schema", $this->typesTag); | |
| 86 | + $this->xsdSchema->setAttribute("targetNamespace", $this->tns); | |
| 87 | + $this->xmlSchema = new IPXMLSchema($this->xsdSchema); | |
| 88 | + | |
| 89 | + } | |
| 90 | + | |
| 91 | + /** | |
| 92 | + * Adds the class to the services for this WSDL | |
| 93 | + * | |
| 94 | + * @param IPReflectionClass The service | |
| 95 | + * @return void | |
| 96 | + */ | |
| 97 | + public function setService(IPReflectionClass $class){ | |
| 98 | + $this->services[$class->classname] = $class; | |
| 99 | + $this->services[$class->classname]->getMethods(false, false); | |
| 100 | + } | |
| 101 | + /** | |
| 102 | + * @return string The WSDL document for this structure | |
| 103 | + */ | |
| 104 | + public function generateDocument(){ | |
| 105 | + $this->addToDebug("Generating document"); | |
| 106 | + | |
| 107 | + //add all definitions | |
| 108 | + $definitions=$this->definitions; | |
| 109 | + $definitions->setAttribute("xmlns", self::NS_WSDL); | |
| 110 | + $definitions->setAttribute("xmlns:soap", self::NS_SOAP); | |
| 111 | + $definitions->setAttribute("xmlns:SOAP-ENC", self::NS_ENC); | |
| 112 | + $definitions->setAttribute("xmlns:wsdl", self::NS_WSDL); | |
| 113 | + $definitions->setAttribute("xmlns:xsd", self::NS_XSD); | |
| 114 | + $definitions->setAttribute("xmlns:tns", $this->tns); | |
| 115 | + $definitions->setAttribute("targetNamespace", $this->tns); | |
| 116 | + | |
| 117 | + //add all the services | |
| 118 | + foreach((array)$this->services as $serviceName => $service){ | |
| 119 | + //add the portType | |
| 120 | + $portType = $this->addPortType($serviceName); | |
| 121 | + | |
| 122 | + //add binding | |
| 123 | + $binding = $this->addBinding($serviceName); | |
| 124 | + | |
| 125 | + //loop the operations | |
| 126 | + foreach((array)$service->methods as $operation){ | |
| 127 | + $operationName = $operation->name; | |
| 128 | + $operationTag = $this->addOperation($operationName, $serviceName); | |
| 129 | + | |
| 130 | + //input | |
| 131 | + //only when to operation needs arguments | |
| 132 | + $parameters = $operation->getParameters(); | |
| 133 | + if(count($parameters)>0 || self::CREATE_EMPTY_INPUTS){ | |
| 134 | + $messageName = $operationName."Request"; | |
| 135 | + $input=$this->addElement("wsdl:input", $operationTag); | |
| 136 | + $input->setAttribute("message", "tns:".$messageName); | |
| 137 | + $para=Array(); | |
| 138 | + foreach((array)$parameters as $parameterName => $parameter){ | |
| 139 | + $para[$parameterName] = $parameter->type; | |
| 140 | + } | |
| 141 | + $this->addMessage($messageName, $para); | |
| 142 | + $this->addInput($this->bindingOperationTags[$serviceName][$operationName]); | |
| 143 | + } | |
| 144 | + | |
| 145 | + | |
| 146 | + //output | |
| 147 | + //only when the operation returns something | |
| 148 | + if(!$operation->return || trim($operation->return) == "") throw new WSDLException('No return type for '.$operationName); | |
| 149 | + if(strtolower(trim($operation->return))!='void'){ | |
| 150 | + $messageName = $operationName."Response"; | |
| 151 | + $output = $this->addElement("wsdl:output", $operationTag); | |
| 152 | + $output->setAttribute("message", "tns:".$messageName); | |
| 153 | + $this->addOutput($this->bindingOperationTags[$serviceName][$operationName]); | |
| 154 | + $this->addMessage($messageName,Array($operation->name."Return" => $operation->return)); | |
| 155 | + } | |
| 156 | + } | |
| 157 | + // SH. now add the portType and binding | |
| 158 | + $this->definitions->AppendChild($portType); | |
| 159 | + $this->definitions->AppendChild($binding); | |
| 160 | + | |
| 161 | + //add the service | |
| 162 | + $this->addService($serviceName); | |
| 163 | + | |
| 164 | + } | |
| 165 | + return $this->doc->saveXML(); | |
| 166 | + } | |
| 167 | + | |
| 168 | + /** | |
| 169 | + * Adds a new operation to the given service | |
| 170 | + * @param string operation name | |
| 171 | + * @param string service name | |
| 172 | + * @return domElement | |
| 173 | + */ | |
| 174 | + private function addOperation($operationName, $serviceName){ | |
| 175 | + $this->addToDebug("Adding Operation: '$operationName : $serviceName'"); | |
| 176 | + $operationTag = $this->addElement("wsdl:operation",$this->portTypeTags[$serviceName]); | |
| 177 | + $operationTag->setAttribute("name",$operationName); | |
| 178 | + | |
| 179 | + //create operation tag for binding | |
| 180 | + $bindingOperationTag = $this->addElement("wsdl:operation",$this->bindingTags[$serviceName]); | |
| 181 | + $bindingOperationTag->setAttribute("name",$operationName); | |
| 182 | + | |
| 183 | + //soap operation tag | |
| 184 | + $soapOperationTag = $this->addElement("soap:operation",$bindingOperationTag); | |
| 185 | + $soapOperationTag->setAttribute("soapAction",$this->url."&method=".$operationName); | |
| 186 | + $soapOperationTag->setAttribute("style",($this->binding_style == SOAP_RPC)? "rpc" : "document"); | |
| 187 | + | |
| 188 | + //save references | |
| 189 | + $this->operationTags[$serviceName][$operationName] = $operationTag; | |
| 190 | + $this->bindingOperationTags[$serviceName][$operationName] = $bindingOperationTag; | |
| 191 | + | |
| 192 | + //and return | |
| 193 | + return $operationTag; | |
| 194 | + } | |
| 195 | + | |
| 196 | + /** | |
| 197 | + * adds a new service tag to the WSDL file | |
| 198 | + * @param string the service name | |
| 199 | + * @return domElement | |
| 200 | + */ | |
| 201 | + private function addService($serviceName){ | |
| 202 | + $this->addToDebug("Adding service: '$serviceName'"); | |
| 203 | + //create service | |
| 204 | + $serviceTag=$this->addElement("wsdl:service",$this->definitions); | |
| 205 | + $serviceTag->setAttribute("name",$serviceName); | |
| 206 | + | |
| 207 | + //port tag | |
| 208 | + $portTag=$this->addElement("wsdl:port", $serviceTag); | |
| 209 | + $portTag->setAttribute("name", $serviceName."Port"); | |
| 210 | + $portTag->setAttribute("binding", "tns:".$serviceName."Binding"); | |
| 211 | + | |
| 212 | + //address tag | |
| 213 | + $addressTag = $this->addElement("soap:address", $portTag); | |
| 214 | + $addressTag->setAttribute("location", $this->url); | |
| 215 | + | |
| 216 | + //keep a reference | |
| 217 | + $this->serviceTags[$serviceName] = $serviceTag; | |
| 218 | + //and return | |
| 219 | + return $serviceTag; | |
| 220 | + } | |
| 221 | + | |
| 222 | + /** | |
| 223 | + * Adds a new portType to the WSDL structure | |
| 224 | + * @param string the service name for which we create a portType | |
| 225 | + * @return domElement | |
| 226 | + */ | |
| 227 | + private function addPortType($serviceName){ | |
| 228 | + $this->addToDebug("Adding portType: '$serviceName'"); | |
| 229 | + // SH don't add to main doc just yet | |
| 230 | + // $portTypeTag=$this->addElement("wsdl:portType", $this->definitions); | |
| 231 | + $portTypeTag = $this->addElement("wsdl:portType"); | |
| 232 | + $portTypeTag->setAttribute("name", $serviceName."PortType"); | |
| 233 | + | |
| 234 | + //keep a reference | |
| 235 | + $this->portTypeTags[$serviceName]=$portTypeTag; | |
| 236 | + //and return | |
| 237 | + return $portTypeTag; | |
| 238 | + } | |
| 239 | + | |
| 240 | + /** | |
| 241 | + * Adds a new binding to the WSDL structure | |
| 242 | + * @param string serviceName to bind | |
| 243 | + * @return domElement | |
| 244 | + */ | |
| 245 | + private function addBinding($serviceName){ | |
| 246 | + $this->addToDebug("Adding binding: '$serviceName'"); | |
| 247 | + // SH. don't add to main doc just yet | |
| 248 | + // $bindingTag=$this->addElement("binding"); | |
| 249 | + $bindingTag=$this->addElement("binding",$this->definitions); | |
| 250 | + $bindingTag->setAttribute("name", $serviceName."Binding"); | |
| 251 | + $bindingTag->setAttribute("type", "tns:".$serviceName."PortType"); | |
| 252 | + | |
| 253 | + //soap binding tag | |
| 254 | + $soapBindingTag = $this->addElement("soap:binding", $bindingTag); | |
| 255 | + $soapBindingTag->setAttribute("style", ($this->binding_style == SOAP_RPC)? "rpc" : "document"); | |
| 256 | + $soapBindingTag->setAttribute("transport", "http://schemas.xmlsoap.org/soap/http"); | |
| 257 | + | |
| 258 | + //keep a reference | |
| 259 | + $this->bindingTags[$serviceName] = $bindingTag; | |
| 260 | + //and return | |
| 261 | + return $bindingTag; | |
| 262 | + } | |
| 263 | + | |
| 264 | + /** | |
| 265 | + * Adds a message tag to the WSDL document | |
| 266 | + * @param string Message name | |
| 267 | + * @param Array[string=>string] Array with variables & types | |
| 268 | + */ | |
| 269 | + private function addMessage($name, $parts){ | |
| 270 | + $this->addToDebug("Adding message: '$name'"); | |
| 271 | + $msg = $this->addElement("message", $this->definitions); | |
| 272 | + $msg->setAttribute("name", $name); | |
| 273 | + foreach((array)$parts as $partName => $partType){ | |
| 274 | + $this->addToDebug("Adding Message part: '$partName => $partType'"); | |
| 275 | + $part=$this->addElement("part", $msg); | |
| 276 | + $part->setAttribute("name", $partName); | |
| 277 | + | |
| 278 | + //check if it is a valid XML Schema datatype | |
| 279 | + if($t = IPXMLSchema::checkSchemaType(strtolower($partType))) | |
| 280 | + $part->setAttribute("type", "xsd:".$t); | |
| 281 | + else{ | |
| 282 | + //If it is an array, change the type name | |
| 283 | + $partName = (substr($partType,-2) == "[]")?substr($partType,0,strpos($partType,"["))."Array":$partType; | |
| 284 | + | |
| 285 | + $part->setAttribute("type", "tns:".$partName); | |
| 286 | + $this->xmlSchema->addComplexType($partType, $partName); | |
| 287 | + } | |
| 288 | + } | |
| 289 | + } | |
| 290 | + | |
| 291 | + /** | |
| 292 | + * Adds an input element to the given parent (an operation tag) | |
| 293 | + * @param domNode The Parent domNode | |
| 294 | + * @param boolean Kind of tag. true=input tag, false=output tag | |
| 295 | + * @return domNode The input/output node | |
| 296 | + */ | |
| 297 | + private function addInput($parent, $input=true){ | |
| 298 | + $name = $input ? "wsdl:input" : "wsdl:output"; | |
| 299 | + $tag=$this->addElement($name, $parent); | |
| 300 | + $soapOperation=$this->addElement("soap:body", $tag); | |
| 301 | + $soapOperation->setAttribute("use", ($this->use == SOAP_ENCODED)? "encoded" : "literal"); | |
| 302 | + $soapOperation->setAttribute("namespace", $this->tns); | |
| 303 | + if($this->use == SOAP_ENCODED) | |
| 304 | + $soapOperation->setAttribute("encodingStyle", self::NS_ENC); | |
| 305 | + } | |
| 306 | + | |
| 307 | + /** | |
| 308 | + * Adds an output element to the given parent (an operation tag) | |
| 309 | + * @param domNode The Parent domNode | |
| 310 | + * @return domNode The output node | |
| 311 | + */ | |
| 312 | + private function addOutput($parent){ | |
| 313 | + return $this->addInput($parent,false); | |
| 314 | + } | |
| 315 | + | |
| 316 | + /************************* Supporting functions ****************************/ | |
| 317 | + | |
| 318 | + private function addToDebug($msg){ | |
| 319 | + if($this->_debug) echo '-'.$msg." <br>\n"; | |
| 320 | + } | |
| 321 | + | |
| 322 | + /** | |
| 323 | + * Adds an child element to the parent | |
| 324 | + * @param string The name element | |
| 325 | + * @param domNode | |
| 326 | + * @return domNode | |
| 327 | + */ | |
| 328 | + private function addElement($name, $parent=false, $ns=false){ | |
| 329 | + if($ns) | |
| 330 | + $el=$this->doc->createElementNS($ns,$name); | |
| 331 | + else | |
| 332 | + $el=$this->doc->createElement($name); | |
| 333 | + if($parent) | |
| 334 | + $parent->appendChild($el); | |
| 335 | + return $el; | |
| 336 | + } | |
| 337 | +} | |
| 338 | +?> | |
| 0 | 339 | \ No newline at end of file | ... | ... |
webservice/classes/soap/WSException.class.php
0 → 100755
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * Exception class which can be thrown by | |
| 4 | + * the WSHelper class. | |
| 5 | + *@author KnowledgeTree Team | |
| 6 | + *@package Webservice | |
| 7 | + *@version Version 0.9 | |
| 8 | + */ | |
| 9 | +class WSException extends Exception { | |
| 10 | + /** | |
| 11 | + * @param string The error message | |
| 12 | + * @return void | |
| 13 | + */ | |
| 14 | + public function __construct($msg) { | |
| 15 | + $this->msg = $msg; | |
| 16 | + } | |
| 17 | + /** | |
| 18 | + * @return void | |
| 19 | + */ | |
| 20 | + public function Display() { | |
| 21 | + echo $this->msg; | |
| 22 | + } | |
| 23 | +} | |
| 24 | +?> | |
| 0 | 25 | \ No newline at end of file | ... | ... |
webservice/classes/soap/WSHelper.class.php
0 → 100755
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * Class that generates a WSDL file and creates documentation | |
| 4 | + * for the webservices. | |
| 5 | + * | |
| 6 | + *@author KnowledgeTree Team | |
| 7 | + *@package Webservice | |
| 8 | + *@version Version 0.9 | |
| 9 | + */ | |
| 10 | +class WSHelper { | |
| 11 | + private $uri; | |
| 12 | + private $class = null; //IPReflectionClass object | |
| 13 | + private $name; //class name | |
| 14 | + private $persistence = SOAP_PERSISTENCE_SESSION; | |
| 15 | + private $wsdlfile; //wsdl file name | |
| 16 | + private $server; //soap server object | |
| 17 | + | |
| 18 | + public $actor; | |
| 19 | + public $structureMap = array(); | |
| 20 | + public $classNameArr = array(); | |
| 21 | + public $wsdlFolder; //WSDL cache folder | |
| 22 | + public $useWSDLCache = true; | |
| 23 | + | |
| 24 | + public $type = SOAP_RPC; | |
| 25 | + public $use = SOAP_LITERAL; | |
| 26 | + | |
| 27 | + /** | |
| 28 | + * Constructor | |
| 29 | + * @param string The Uri name | |
| 30 | + * @return void | |
| 31 | + */ | |
| 32 | + public function __construct($uri, $class=null){ | |
| 33 | + $this->uri = $uri; | |
| 34 | + $this->setWSDLCacheFolder($_SERVER['DOCUMENT_ROOT'].dirname($_SERVER['PHP_SELF'])."/wsdl/"); | |
| 35 | + if($class) $this->setClass($class); | |
| 36 | + } | |
| 37 | + | |
| 38 | + /** | |
| 39 | + * Adds the given class name to the list of classes | |
| 40 | + * to be included in the documentation/WSDL/Request handlers | |
| 41 | + * @param string | |
| 42 | + * @return void | |
| 43 | + */ | |
| 44 | + public function setClass($name){ | |
| 45 | + $this->name = $name; | |
| 46 | + $this->wsdlfile = $this->wsdlFolder.$this->name.".wsdl"; | |
| 47 | + } | |
| 48 | + | |
| 49 | + public function setWSDLCacheFolder($folder) { | |
| 50 | + $this->wsdlFolder = $folder; | |
| 51 | + //reset wsdlfile | |
| 52 | + $this->wsdlfile = $this->wsdlFolder.$this->name.".wsdl"; | |
| 53 | + } | |
| 54 | + /** | |
| 55 | + * Sets the persistence level for the soap class | |
| 56 | + */ | |
| 57 | + public function setPersistence($persistence) { | |
| 58 | + $this->persistence = $persistence; | |
| 59 | + } | |
| 60 | + | |
| 61 | + /** | |
| 62 | + * Handles everything. Makes sure the webservice is handled, | |
| 63 | + * documentations is generated, or the wsdl is generated, | |
| 64 | + * according to the page request | |
| 65 | + * @return void | |
| 66 | + */ | |
| 67 | + public function handle(){ | |
| 68 | + if(substr($_SERVER['QUERY_STRING'], -4) == 'wsdl'){ | |
| 69 | + $this->showWSDL(); | |
| 70 | + }elseif(isset($GLOBALS['HTTP_RAW_POST_DATA']) && strlen($GLOBALS['HTTP_RAW_POST_DATA'])>0){ | |
| 71 | + $this->handleRequest(); | |
| 72 | + }else{ | |
| 73 | + $this->createDocumentation(); | |
| 74 | + } | |
| 75 | + } | |
| 76 | + /** | |
| 77 | + * Checks if the current WSDL is up-to-date, regenerates if necessary and outputs the WSDL | |
| 78 | + * @return void | |
| 79 | + */ | |
| 80 | + public function showWSDL(){ | |
| 81 | + //check if it's a legal webservice class | |
| 82 | + if(!in_array($this->name, $this->classNameArr)) | |
| 83 | + throw new Exception("No valid webservice class."); | |
| 84 | + | |
| 85 | + //@TODO: nog een mooie oplossing voor het cachen zoeken | |
| 86 | + header("Content-type: text/xml"); | |
| 87 | + if($this->useWSDLCache && file_exists($this->wsdlfile)){ | |
| 88 | + readfile($this->wsdlfile); | |
| 89 | + }else{ | |
| 90 | + //make sure to refresh PHP WSDL cache system | |
| 91 | + ini_set("soap.wsdl_cache_enabled",0); | |
| 92 | + echo $this->createWSDL(); | |
| 93 | + } | |
| 94 | + } | |
| 95 | + | |
| 96 | + private function createWSDL(){ | |
| 97 | + $this->class = new IPReflectionClass($this->name); | |
| 98 | + $wsdl = new WSDLStruct($this->uri, "http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."?class=".$this->name, $this->type, $this->use); | |
| 99 | + $wsdl->setService($this->class); | |
| 100 | + | |
| 101 | + try { | |
| 102 | + $gendoc = $wsdl->generateDocument(); | |
| 103 | + } catch (WSDLException $exception) { | |
| 104 | + $exception->Display(); | |
| 105 | + exit(); | |
| 106 | + } | |
| 107 | + | |
| 108 | + $fh = fopen($this->wsdlfile, "w+"); | |
| 109 | + fwrite($fh, $gendoc); | |
| 110 | + fclose($fh); | |
| 111 | + | |
| 112 | + return $gendoc; | |
| 113 | + } | |
| 114 | + | |
| 115 | + /** | |
| 116 | + * Lets the native PHP5 soap implementation handle the request | |
| 117 | + * after registrating the class | |
| 118 | + * @return void | |
| 119 | + */ | |
| 120 | + private function handleRequest(){ | |
| 121 | + //check if it's a legal webservice class | |
| 122 | + if(!in_array($this->name, $this->classNameArr)) | |
| 123 | + throw new Exception("No valid webservice class."); | |
| 124 | + | |
| 125 | + //check cache | |
| 126 | + //if(!file_exists($this->wsdlfile)) | |
| 127 | + $this->createWSDL(); | |
| 128 | + | |
| 129 | + $options = Array('actor' => $this->actor, 'classmap' => $this->structureMap); | |
| 130 | + | |
| 131 | + header("Content-type: text/xml"); | |
| 132 | + $this->server = new SoapServer($this->wsdlfile, $options); | |
| 133 | + $this->server->setClass($this->name); | |
| 134 | + $this->server->setPersistence($this->persistence); | |
| 135 | + | |
| 136 | + use_soap_error_handler(true); | |
| 137 | + $this->server->handle(); | |
| 138 | + } | |
| 139 | + | |
| 140 | + /** | |
| 141 | + * @param string code | |
| 142 | + * @param string string | |
| 143 | + * @param string actor | |
| 144 | + * @param mixed details | |
| 145 | + * @param string name | |
| 146 | + * @return void | |
| 147 | + */ | |
| 148 | + public function fault($code, $string, $actor, $details, $name='') { | |
| 149 | + return $this->server->fault($code, $string, $actor, $details, $name); | |
| 150 | + } | |
| 151 | + | |
| 152 | + /** | |
| 153 | + * Generates the documentations for the webservice usage. | |
| 154 | + * @TODO: "int", "boolean", "double", "float", "string", "void" | |
| 155 | + * @param string Template filename | |
| 156 | + * @return void | |
| 157 | + */ | |
| 158 | + public function createDocumentation($template="classes/soap/templates/docclass.xsl") { | |
| 159 | + if(!is_file($template)) | |
| 160 | + throw new WSException("Could not find the template file: '$template'"); | |
| 161 | + $this->class = new IPReflectionClass($this->name); | |
| 162 | + $xtpl = new IPXSLTemplate($template); | |
| 163 | + $documentation = Array(); | |
| 164 | + $documentation['menu'] = Array(); | |
| 165 | + //loop menu items | |
| 166 | + sort($this->classNameArr); | |
| 167 | + foreach($this->classNameArr as $className) { | |
| 168 | + $documentation['menu'][] = new IPReflectionClass($className); | |
| 169 | + } | |
| 170 | + | |
| 171 | + if($this->class){ | |
| 172 | + $this->class->properties = $this->class->getProperties(false, false); | |
| 173 | + $this->class->methods = $this->class->getMethods(false, false); | |
| 174 | + foreach((array)$this->class->methods as $method) { | |
| 175 | + $method->params = $method->getParameters(); | |
| 176 | + } | |
| 177 | + | |
| 178 | + $documentation['class'] = $this->class; | |
| 179 | + } | |
| 180 | + echo $xtpl->execute($documentation); | |
| 181 | + } | |
| 182 | +} | |
| 183 | +?> | |
| 0 | 184 | \ No newline at end of file | ... | ... |
webservice/classes/soap/common.php
0 → 100755
| 1 | +<?php | |
| 2 | +/** | |
| 3 | +* Implements a cleaner wrapper for webservices API for KnowledgeTree. | |
| 4 | +* | |
| 5 | +* KnowledgeTree Community Edition | |
| 6 | +* Document Management Made Simple | |
| 7 | +* Copyright (C) 2008,2009 KnowledgeTree Inc. | |
| 8 | +* Portions copyright The Jam Warehouse Software (Pty) Limited | |
| 9 | +* | |
| 10 | +* This program is free software; you can redistribute it and/or modify it under | |
| 11 | +* the terms of the GNU General Public License version 3 as published by the | |
| 12 | +* Free Software Foundation. | |
| 13 | +* | |
| 14 | +* This program is distributed in the hope that it will be useful, but WITHOUT | |
| 15 | +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
| 16 | +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
| 17 | +* details. | |
| 18 | +* | |
| 19 | +* You should have received a copy of the GNU General Public License | |
| 20 | +* along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 21 | +* | |
| 22 | +* You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco, | |
| 23 | +* California 94120-7775, or email info@knowledgetree.com. | |
| 24 | +* | |
| 25 | +* The interactive user interfaces in modified source and object code versions | |
| 26 | +* of this program must display Appropriate Legal Notices, as required under | |
| 27 | +* Section 5 of the GNU General Public License version 3. | |
| 28 | +* | |
| 29 | +* In accordance with Section 7(b) of the GNU General Public License version 3, | |
| 30 | +* these Appropriate Legal Notices must retain the display of the "Powered by | |
| 31 | +* KnowledgeTree" logo and retain the original copyright notice. If the display of the | |
| 32 | +* logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices | |
| 33 | +* must display the words "Powered by KnowledgeTree" and retain the original | |
| 34 | +* copyright notice. | |
| 35 | +* | |
| 36 | +* @copyright 2008-2009, KnowledgeTree Inc. | |
| 37 | +* @license GNU General Public License version 3 | |
| 38 | +* @author KnowledgeTree Team | |
| 39 | +* @package Webservice | |
| 40 | +* @version Version 0.1 | |
| 41 | +*/ | |
| 42 | + | |
| 43 | + | |
| 44 | +error_reporting(E_ALL); | |
| 45 | +ob_start("ob_gzhandler"); | |
| 46 | + | |
| 47 | +require_once ("config.php"); | |
| 48 | + | |
| 49 | +if(!extension_loaded("soap")) | |
| 50 | + die("Soap extension not loaded!"); | |
| 51 | + | |
| 52 | +session_start(); | |
| 53 | + | |
| 54 | +/** autoload function for PHP5 | |
| 55 | +* Loads all the classes in the model | |
| 56 | +* | |
| 57 | +*/ | |
| 58 | +function __autoload($classname) { | |
| 59 | + try{ | |
| 60 | + if(file_exists("classes/soap/model/$classname.class.php")) | |
| 61 | + include("classes/soap/model/$classname.class.php"); | |
| 62 | + elseif(file_exists("classes/soap/$classname.class.php")) | |
| 63 | + include("classes/soap/$classname.class.php"); | |
| 64 | + elseif(file_exists("classes/soap/$classname.class.php")) | |
| 65 | + include("classes/soap/$classname.class.php"); | |
| 66 | + } catch (Exception $e) { | |
| 67 | + echo $e->getMessage(); | |
| 68 | + } | |
| 69 | + | |
| 70 | +} | |
| 71 | + | |
| 72 | +/** Write out debug file */ | |
| 73 | +function debug($txt,$file="debug.txt"){ | |
| 74 | + $fp = fopen($file, "a"); | |
| 75 | + fwrite($fp, str_replace("\n","\r\n","\r\n".$txt)); | |
| 76 | + fclose($fp); | |
| 77 | +} | |
| 78 | + | |
| 79 | +/** Write out object in the debug log */ | |
| 80 | +function debugObject($txt,$obj){ | |
| 81 | + ob_start(); | |
| 82 | + print_r($obj); | |
| 83 | + $data = ob_get_contents(); | |
| 84 | + ob_end_clean(); | |
| 85 | + debug($txt."\n".$data); | |
| 86 | +} | |
| 87 | +?> | ... | ... |
webservice/classes/soap/config.php
0 → 100755
| 1 | +<?php | |
| 2 | + | |
| 3 | +/* All the allowed webservice classes */ | |
| 4 | +$WSClasses = array( | |
| 5 | + "contactManager", | |
| 6 | + "RestService" | |
| 7 | + | |
| 8 | + | |
| 9 | +); | |
| 10 | + | |
| 11 | +/* The classmap associative array. When you want to allow objects as a parameter for | |
| 12 | + * your webservice method. ie. saveObject($object). By default $object will now be | |
| 13 | + * a stdClass, but when you add a classname defined in the type description in the @param | |
| 14 | + * documentation tag and add your class to the classmap below, the object will be of the | |
| 15 | + * given type. Requires PHP 5.0.3+ | |
| 16 | + */ | |
| 17 | +$WSStructures = array( | |
| 18 | + "contact" => "contact", | |
| 19 | + "address" => "address", | |
| 20 | + | |
| 21 | +); | |
| 22 | + | |
| 23 | +?> | |
| 0 | 24 | \ No newline at end of file | ... | ... |
webservice/classes/soap/model/RestService.class.php
0 → 100755
| 1 | +<?php | |
| 2 | +/** | |
| 3 | +* Implements a cleaner wrapper restservice and webservice API for KnowledgeTree. | |
| 4 | +* | |
| 5 | +* KnowledgeTree Community Edition | |
| 6 | +* Document Management Made Simple | |
| 7 | +* Copyright (C) 2008,2009 KnowledgeTree Inc. | |
| 8 | +* Portions copyright The Jam Warehouse Software (Pty) Limited | |
| 9 | +* | |
| 10 | +* This program is free software; you can redistribute it and/or modify it under | |
| 11 | +* the terms of the GNU General Public License version 3 as published by the | |
| 12 | +* Free Software Foundation. | |
| 13 | +* | |
| 14 | +* This program is distributed in the hope that it will be useful, but WITHOUT | |
| 15 | +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
| 16 | +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
| 17 | +* details. | |
| 18 | +* | |
| 19 | +* You should have received a copy of the GNU General Public License | |
| 20 | +* along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 21 | +* | |
| 22 | +* You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco, | |
| 23 | +* California 94120-7775, or email info@knowledgetree.com. | |
| 24 | +* | |
| 25 | +* The interactive user interfaces in modified source and object code versions | |
| 26 | +* of this program must display Appropriate Legal Notices, as required under | |
| 27 | +* Section 5 of the GNU General Public License version 3. | |
| 28 | +* | |
| 29 | +* In accordance with Section 7(b) of the GNU General Public License version 3, | |
| 30 | +* these Appropriate Legal Notices must retain the display of the "Powered by | |
| 31 | +* KnowledgeTree" logo and retain the original copyright notice. If the display of the | |
| 32 | +* logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices | |
| 33 | +* must display the words "Powered by KnowledgeTree" and retain the original | |
| 34 | +* copyright notice. | |
| 35 | +* | |
| 36 | +* @copyright 2008-2009, KnowledgeTree Inc. | |
| 37 | +* @license GNU General Public License version 3 | |
| 38 | +* @author KnowledgeTree Team | |
| 39 | +* @package Webservice | |
| 40 | +* @version Version 0.1 | |
| 41 | +*/ | |
| 42 | + | |
| 43 | + | |
| 44 | +/** | |
| 45 | + * Class Service - will act as a switch between | |
| 46 | + * SOAP requests and REST requests | |
| 47 | + *@author KnowledgeTree Team | |
| 48 | + *@package Webservice | |
| 49 | + *@version Version 0.9 | |
| 50 | + */ | |
| 51 | +class RestService | |
| 52 | +{ | |
| 53 | + /** | |
| 54 | + * Class construct | |
| 55 | + * | |
| 56 | + * @param object_type $object | |
| 57 | + * @return jason encoded string | |
| 58 | + */ | |
| 59 | + public function __construct($object) | |
| 60 | + { | |
| 61 | + try { | |
| 62 | + | |
| 63 | + $result = $this->runAsService($object); | |
| 64 | + echo jason_encode(array('status_code' => 0,'result' => $result)); | |
| 65 | + | |
| 66 | + } catch (Exception $e) { | |
| 67 | + echo json_encode(array('status_code' => 1,'result' => $e->getMessage())); | |
| 68 | + } | |
| 69 | + } | |
| 70 | + | |
| 71 | + /** | |
| 72 | + * Constructor for invoking a reflection object | |
| 73 | + * Initiates the object as a service | |
| 74 | + * @param class $object | |
| 75 | + * @access private | |
| 76 | + * @return class instance | |
| 77 | + */ | |
| 78 | + | |
| 79 | + private function runAsService($object) | |
| 80 | + { | |
| 81 | + | |
| 82 | + if (!isset($_GET['class'])) { | |
| 83 | + | |
| 84 | + throw new Exception('Method name not specified.'); | |
| 85 | + } | |
| 86 | + | |
| 87 | + $reflObject = new ReflectionObject($object); | |
| 88 | + | |
| 89 | + if (!$reflObject->hasMethod($_GET['class'])) { | |
| 90 | + | |
| 91 | + throw new Exception('There is no method with this name.'); | |
| 92 | + | |
| 93 | + } | |
| 94 | + | |
| 95 | + $reflMethod = $reflObject->getMethod($_GET['class']); | |
| 96 | + | |
| 97 | + if ( !$reflMethod->isPublic() || $reflMethod->isStatic() || $reflMethod->isInternal() ) { | |
| 98 | + | |
| 99 | + throw new Exception('Invalid method name specified.'); | |
| 100 | + | |
| 101 | + } | |
| 102 | + | |
| 103 | + $reflParameters = $reflMethod->getParameters(); | |
| 104 | + | |
| 105 | + $args = array(); | |
| 106 | + | |
| 107 | + | |
| 108 | + foreach ($reflParameters as $param) { | |
| 109 | + | |
| 110 | + $paramName = $param->getName(); | |
| 111 | + | |
| 112 | + if (!isset($_GET[$paramName])) { | |
| 113 | + | |
| 114 | + if ($param->isDefaultValueAvailable()) { | |
| 115 | + | |
| 116 | + $paramValue = $param->getDefaultValue(); | |
| 117 | + | |
| 118 | + } else { | |
| 119 | + | |
| 120 | + throw new Exception('Required parameter "'.$paramName.'" is not specified.'); | |
| 121 | + | |
| 122 | + } | |
| 123 | + | |
| 124 | + } else { | |
| 125 | + | |
| 126 | + $paramValue = $_GET[$paramName]; | |
| 127 | + | |
| 128 | + } | |
| 129 | + | |
| 130 | + | |
| 131 | + if ($param->getClass()) { | |
| 132 | + | |
| 133 | + throw new Exception('The method contains unsupported parameter type: class object.'); | |
| 134 | + | |
| 135 | + } | |
| 136 | + | |
| 137 | + | |
| 138 | + if ($param->isArray() && !is_array($paramValue)) { | |
| 139 | + | |
| 140 | + throw new Exception('Array expected for parameter "'.$paramName.'", but scalar found.'); | |
| 141 | + | |
| 142 | + } | |
| 143 | + | |
| 144 | + | |
| 145 | + $args[$param->getPosition()] = $paramValue; | |
| 146 | + | |
| 147 | + } | |
| 148 | + | |
| 149 | + return $reflMethod->invokeArgs($object, $args); | |
| 150 | + | |
| 151 | + } | |
| 152 | + | |
| 153 | +} | |
| 154 | + | |
| 155 | +?> | |
| 0 | 156 | \ No newline at end of file | ... | ... |
webservice/classes/soap/model/address.class.php
0 → 100755
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Stores an address | |
| 5 | + * | |
| 6 | + * An address consists of a street, number, zipcode and city. | |
| 7 | + * This class is for example purposes only, just to | |
| 8 | + * show how to create a webservice | |
| 9 | + * | |
| 10 | + */ | |
| 11 | +class address{ | |
| 12 | + /** @var string */ | |
| 13 | + public $street; | |
| 14 | + | |
| 15 | + /** @var string */ | |
| 16 | + public $nr; | |
| 17 | + | |
| 18 | + /** @var string */ | |
| 19 | + public $zipcode; | |
| 20 | + | |
| 21 | + /** @var string */ | |
| 22 | + public $city; | |
| 23 | +} | |
| 24 | +?> | |
| 0 | 25 | \ No newline at end of file | ... | ... |
webservice/classes/soap/model/contact.class.php
0 → 100755
| 1 | +<?php | |
| 2 | + | |
| 3 | + | |
| 4 | +/** | |
| 5 | + * The contact details for a person | |
| 6 | + * | |
| 7 | + * Stores the person's name, address and e-mail | |
| 8 | + * This class is for example purposes only, just to | |
| 9 | + * show how to create a webservice | |
| 10 | + * | |
| 11 | + */ | |
| 12 | +class contact{ | |
| 13 | + /** @var int */ | |
| 14 | + public $id; | |
| 15 | + | |
| 16 | + /** @var string */ | |
| 17 | + public $name; | |
| 18 | + | |
| 19 | + /** @var address */ | |
| 20 | + public $address; | |
| 21 | + | |
| 22 | + /** @var string */ | |
| 23 | + public $email; | |
| 24 | + | |
| 25 | + /** | |
| 26 | + * saves a contact | |
| 27 | + * | |
| 28 | + * @return void | |
| 29 | + */ | |
| 30 | + public function save() { | |
| 31 | + //save contact 2 db | |
| 32 | + } | |
| 33 | +} | |
| 34 | +?> | |
| 0 | 35 | \ No newline at end of file | ... | ... |
webservice/classes/soap/model/contactManager.class.php
0 → 100755
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Keeps track of the people in our contact list. | |
| 5 | + * | |
| 6 | + * Starts with a standard contact list and can add | |
| 7 | + * new people to our list or change existing contacts. | |
| 8 | + * This class is for example purposes only, just to | |
| 9 | + * show how to create a webservice | |
| 10 | + */ | |
| 11 | +class contactManager{ | |
| 12 | + | |
| 13 | + /** | |
| 14 | + * Gets the current contact list. | |
| 15 | + * @return contact[] | |
| 16 | + */ | |
| 17 | + public function getContacts() { | |
| 18 | + $contact = new contact(); | |
| 19 | + $contact->address = new Address(); | |
| 20 | + $contact->address->city ="sesamcity"; | |
| 21 | + $contact->address->street ="sesamstreet"; | |
| 22 | + $contact->email = "me@you.com"; | |
| 23 | + $contact->id = 1; | |
| 24 | + $contact->name ="me"; | |
| 25 | + | |
| 26 | + $ret[] = $contact; | |
| 27 | + return $ret; | |
| 28 | + } | |
| 29 | + | |
| 30 | + /** | |
| 31 | + * Gets the contact with the given id. | |
| 32 | + * @param int The id | |
| 33 | + * @return contact | |
| 34 | + */ | |
| 35 | + public function getContact($id) { | |
| 36 | + //get contact from db | |
| 37 | + //might wanna throw an exception when it does not exists | |
| 38 | + throw new Exception("Contact '$id' not found"); | |
| 39 | + } | |
| 40 | + /** | |
| 41 | + * Generates an new, empty contact template | |
| 42 | + * @return contact | |
| 43 | + */ | |
| 44 | + public function newContact() { | |
| 45 | + return new contact(); | |
| 46 | + } | |
| 47 | + | |
| 48 | + /** | |
| 49 | + * Saves a given contact | |
| 50 | + * @param contact | |
| 51 | + * @return void | |
| 52 | + */ | |
| 53 | + public function saveContact(contact $contact) { | |
| 54 | + $contact->save(); | |
| 55 | + } | |
| 56 | + | |
| 57 | +} | |
| 58 | +?> | |
| 0 | 59 | \ No newline at end of file | ... | ... |
webservice/classes/soap/templates/css/doc.css
0 → 100755
| 1 | +body { | |
| 2 | + margin:0; | |
| 3 | + padding:0; | |
| 4 | + text-align: center; | |
| 5 | + background: #ffffff url("../images/doc/back.gif") repeat-y center; | |
| 6 | +} | |
| 7 | +body, table, th, td, p, div { | |
| 8 | + font-family: Arial, Helvetica; | |
| 9 | + font-size: 12pt; | |
| 10 | + line-height:1.4; | |
| 11 | +} | |
| 12 | +#main { | |
| 13 | + margin-right: auto; | |
| 14 | + margin-left: auto; | |
| 15 | + text-align: left; | |
| 16 | + width: 980px; | |
| 17 | +} | |
| 18 | +#mainpadded { | |
| 19 | + padding: 0px 40px 80px 40px; | |
| 20 | +} | |
| 21 | +#mainheader { | |
| 22 | + background: #ffffff url("../images/doc/backtop.jpg") no-repeat; | |
| 23 | + height: 180px; | |
| 24 | +} | |
| 25 | +#mainheaderpadded { | |
| 26 | + padding: 130px 40px 0px 40px; | |
| 27 | + text-align: right; | |
| 28 | +} | |
| 29 | +td { | |
| 30 | + vertical-align: top; | |
| 31 | +} | |
| 32 | +td#menu { | |
| 33 | + width: 300px; | |
| 34 | +} | |
| 35 | +td#content { | |
| 36 | +} | |
| 37 | +div.method { | |
| 38 | + padding-left: 10px; | |
| 39 | + margin-bottom: 20px; | |
| 40 | + border-left: 2px solid #C0C0C0; | |
| 41 | +} | |
| 42 | +div.methodwarning { | |
| 43 | + padding-left: 10px; | |
| 44 | + margin-bottom: 20px; | |
| 45 | + border-left: 4px solid #FF0000; | |
| 46 | +} | |
| 47 | +div.property { | |
| 48 | + padding-left: 10px; | |
| 49 | + margin-bottom: 20px; | |
| 50 | + border-left: 2px solid #C0C0C0; | |
| 51 | +} | |
| 52 | +div.propertywarning { | |
| 53 | + padding-left: 10px; | |
| 54 | + margin-bottom: 20px; | |
| 55 | + border-left: 4px solid #FF0000; | |
| 56 | +} | |
| 57 | +div.warning { | |
| 58 | + font-weight: bold; | |
| 59 | + color: #FF0000; | |
| 60 | + float: left; | |
| 61 | +} | |
| 62 | +a { | |
| 63 | + color: #FFA619; | |
| 64 | + text-decoration: none; | |
| 65 | + font-weight: bold; | |
| 66 | +} | |
| 67 | +a:hover { | |
| 68 | + text-decoration: underline; | |
| 69 | +} | |
| 70 | +p { | |
| 71 | + margin-top: 5px; | |
| 72 | + margin-bottom: 10px; | |
| 73 | +} | |
| 74 | +h1 { | |
| 75 | + margin-top: 0px; | |
| 76 | + margin-bottom: 10px; | |
| 77 | + padding: 0px; | |
| 78 | + font-family: Verdana, Helvetica; | |
| 79 | + font-size: 20pt; | |
| 80 | + color: #000000; | |
| 81 | +} | |
| 82 | +h2 { | |
| 83 | + margin-top: 0px; | |
| 84 | + margin-bottom: 10px; | |
| 85 | + font-family: Verdana, Helvetica; | |
| 86 | + font-size: 16pt; | |
| 87 | + color: #000000; | |
| 88 | +} | |
| 0 | 89 | \ No newline at end of file | ... | ... |
webservice/classes/soap/templates/docclass.xsl
0 → 100755
| 1 | +<xsl:stylesheet | |
| 2 | + version="1.0" | |
| 3 | + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | |
| 4 | + xmlns:php="http://php.net/xsl" | |
| 5 | + xmlns:ipub="http://www.ipublisher.nl/4.0" | |
| 6 | + xmlns:exsl="http://exslt.org/common" | |
| 7 | + xmlns:str="http://exslt.org/strings" | |
| 8 | + xmlns:date="http://exslt.org/dates-and-times" | |
| 9 | + extension-element-prefixes="str exsl date" | |
| 10 | + > | |
| 11 | +<xsl:include href="str.replace.function.xsl"/> | |
| 12 | +<xsl:output method="html" encoding="utf-8" indent="yes" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" media-type="text/html"/> | |
| 13 | + | |
| 14 | +<xsl:template match="/model"> | |
| 15 | + <html> | |
| 16 | + <head> | |
| 17 | + <title>Webservices</title> | |
| 18 | + <link rel="stylesheet" href="classes/soap/templates/css/doc.css" type="text/css" ></link> | |
| 19 | + </head> | |
| 20 | + <body> | |
| 21 | + <div id="main"> | |
| 22 | + <div id="mainheader"> | |
| 23 | + <div id="mainheaderpadded"> | |
| 24 | + <xsl:if test="class != ''"> | |
| 25 | + <h1><xsl:value-of select="class/name" /> <a href="?class={class/name}&wsdl"> [WSDL]</a></h1> | |
| 26 | + </xsl:if> | |
| 27 | + </div> | |
| 28 | + </div> | |
| 29 | + <div id="mainpadded"> | |
| 30 | + <table cellpadding="0" cellspacing="0"> | |
| 31 | + <tr> | |
| 32 | + <td id="menu"> | |
| 33 | + <h2>Classes</h2> | |
| 34 | + <xsl:for-each select="/model/menu/*"> | |
| 35 | + <a href="?class={name}"><xsl:value-of select="name"/></a><br /> | |
| 36 | + </xsl:for-each> | |
| 37 | + </td> | |
| 38 | + <td id="content"> | |
| 39 | + <xsl:if test="fault != ''"> | |
| 40 | + <xsl:value-of select="fault" /> | |
| 41 | + </xsl:if> | |
| 42 | + <xsl:if test="class != '' and not(fault)"> | |
| 43 | + | |
| 44 | + <h2>Full description</h2> | |
| 45 | + <p><xsl:value-of select="class/fullDescription" /></p> | |
| 46 | + | |
| 47 | + <h2>Properties</h2> | |
| 48 | + <xsl:for-each select="class/properties/*"> | |
| 49 | + <a name="property_{name}"></a> | |
| 50 | + <div class="property{warning}"> | |
| 51 | + <b><xsl:value-of select="name" /></b><br /> | |
| 52 | + <xsl:choose> | |
| 53 | + <xsl:when test="type != ''"> | |
| 54 | + <xsl:choose> | |
| 55 | + <xsl:when test="contains('int,boolean,double,float,string,void', type)"> | |
| 56 | + <i>type <xsl:value-of select="type" /></i><br /> | |
| 57 | + </xsl:when> | |
| 58 | + <xsl:otherwise> | |
| 59 | + <i>type <a href="?class={str:replace(type,'[]','')}"><xsl:value-of select="type" /></a></i><br /> | |
| 60 | + </xsl:otherwise> | |
| 61 | + </xsl:choose> | |
| 62 | + </xsl:when> | |
| 63 | + <xsl:otherwise> | |
| 64 | + <div class='warning'><img src='classes/soap/templates/images/doc/warning.gif'/> missing type info</div><br /> | |
| 65 | + </xsl:otherwise> | |
| 66 | + </xsl:choose> | |
| 67 | + <xsl:value-of select="fullDescription" /> | |
| 68 | + </div> | |
| 69 | + </xsl:for-each> | |
| 70 | + | |
| 71 | + <h2>Methods</h2> | |
| 72 | + <xsl:for-each select="class/methods/*"> | |
| 73 | + <a name="method_{name}"></a> | |
| 74 | + <div class="method{warning}"> | |
| 75 | + <b><xsl:value-of select="name" /></b>( | |
| 76 | + <xsl:for-each select="params/*"> | |
| 77 | + <xsl:value-of select="name"/> | |
| 78 | + <xsl:if test="position() != last()">,</xsl:if> | |
| 79 | + </xsl:for-each> | |
| 80 | + ) | |
| 81 | + <br /> | |
| 82 | + <xsl:choose> | |
| 83 | + <xsl:when test="return != ''"> | |
| 84 | + <xsl:choose> | |
| 85 | + <xsl:when test="contains('int,boolean,double,float,string,void', return)"> | |
| 86 | + <i>returns <xsl:value-of select="return" /></i><br /> | |
| 87 | + </xsl:when> | |
| 88 | + <xsl:otherwise> | |
| 89 | + <i>returns <a href="?class={str:replace(return,'[]','')}"><xsl:value-of select="return" /></a></i><br /> | |
| 90 | + </xsl:otherwise> | |
| 91 | + </xsl:choose> | |
| 92 | + </xsl:when> | |
| 93 | + <xsl:otherwise> | |
| 94 | + <div class='warning'><img src='images/doc/warning.gif'/> missing return value</div><br /> | |
| 95 | + </xsl:otherwise> | |
| 96 | + </xsl:choose> | |
| 97 | + <xsl:choose> | |
| 98 | + <xsl:when test="throws != ''"> | |
| 99 | + <i>throws <xsl:value-of select="throws" /></i><br /> | |
| 100 | + </xsl:when> | |
| 101 | + </xsl:choose> | |
| 102 | + <xsl:value-of select="fullDescription" /><br /> | |
| 103 | + </div> | |
| 104 | + </xsl:for-each> | |
| 105 | + </xsl:if> | |
| 106 | + </td> | |
| 107 | + </tr> | |
| 108 | + </table> | |
| 109 | + | |
| 110 | + </div> | |
| 111 | + <div id="mainfooter"><img src="images/doc/backbottom.jpg" /></div> | |
| 112 | + </div> | |
| 113 | + </body> | |
| 114 | + </html> | |
| 115 | +</xsl:template> | |
| 116 | +</xsl:stylesheet> | |
| 0 | 117 | \ No newline at end of file | ... | ... |
webservice/classes/soap/templates/images/doc/back.gif
0 → 100755
7.78 KB
webservice/classes/soap/templates/images/doc/backbottom.jpg
0 → 100755
17.5 KB
webservice/classes/soap/templates/images/doc/backtop.jpg
0 → 100755
23.3 KB
webservice/classes/soap/templates/images/doc/warning.gif
0 → 100755
218 Bytes
webservice/classes/soap/templates/str.replace.function.xsl
0 → 100755
| 1 | +<?xml version="1.0"?> | |
| 2 | +<xsl:stylesheet version="1.0" | |
| 3 | + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | |
| 4 | + xmlns:str="http://exslt.org/strings" | |
| 5 | + xmlns:func="http://exslt.org/functions" | |
| 6 | + xmlns:exsl="http://exslt.org/common" | |
| 7 | + extension-element-prefixes="str exsl func"> | |
| 8 | + | |
| 9 | +<func:function name="str:replace"> | |
| 10 | + <xsl:param name="string" select="''" /> | |
| 11 | + <xsl:param name="search" select="/.." /> | |
| 12 | + <xsl:param name="replace" select="/.." /> | |
| 13 | + <xsl:choose> | |
| 14 | + <xsl:when test="not($string)"> | |
| 15 | + <func:result select="/.." /> | |
| 16 | + </xsl:when> | |
| 17 | + <xsl:when test="function-available('exsl:node-set')"> | |
| 18 | + <!-- this converts the search and replace arguments to node sets | |
| 19 | + if they are one of the other XPath types --> | |
| 20 | + <xsl:variable name="search-nodes-rtf"> | |
| 21 | + <xsl:copy-of select="$search" /> | |
| 22 | + </xsl:variable> | |
| 23 | + <xsl:variable name="replace-nodes-rtf"> | |
| 24 | + <xsl:copy-of select="$replace" /> | |
| 25 | + </xsl:variable> | |
| 26 | + <xsl:variable name="replacements-rtf"> | |
| 27 | + <xsl:for-each select="exsl:node-set($search-nodes-rtf)/node()"> | |
| 28 | + <xsl:variable name="pos" select="position()" /> | |
| 29 | + <replace search="{.}"> | |
| 30 | + <xsl:copy-of select="exsl:node-set($replace-nodes-rtf)/node()[$pos]" /> | |
| 31 | + </replace> | |
| 32 | + </xsl:for-each> | |
| 33 | + </xsl:variable> | |
| 34 | + <xsl:variable name="sorted-replacements-rtf"> | |
| 35 | + <xsl:for-each select="exsl:node-set($replacements-rtf)/replace"> | |
| 36 | + <xsl:sort select="string-length(@search)" data-type="number" order="descending" /> | |
| 37 | + <xsl:copy-of select="." /> | |
| 38 | + </xsl:for-each> | |
| 39 | + </xsl:variable> | |
| 40 | + <xsl:variable name="result"> | |
| 41 | + <xsl:choose> | |
| 42 | + <xsl:when test="not($search)"> | |
| 43 | + <xsl:value-of select="$string" /> | |
| 44 | + </xsl:when> | |
| 45 | + <xsl:otherwise> | |
| 46 | + <xsl:call-template name="str:_replace"> | |
| 47 | + <xsl:with-param name="string" select="$string" /> | |
| 48 | + <xsl:with-param name="replacements" select="exsl:node-set($sorted-replacements-rtf)/replace" /> | |
| 49 | + </xsl:call-template> | |
| 50 | + </xsl:otherwise> | |
| 51 | + </xsl:choose> | |
| 52 | + </xsl:variable> | |
| 53 | + <func:result select="exsl:node-set($result)/node()" /> | |
| 54 | + </xsl:when> | |
| 55 | + <xsl:otherwise> | |
| 56 | + <xsl:message terminate="yes"> | |
| 57 | + ERROR: function implementation of str:replace() relies on exsl:node-set(). | |
| 58 | + </xsl:message> | |
| 59 | + </xsl:otherwise> | |
| 60 | + </xsl:choose> | |
| 61 | +</func:function> | |
| 62 | + | |
| 63 | +<xsl:template name="str:_replace"> | |
| 64 | + <xsl:param name="string" select="''" /> | |
| 65 | + <xsl:param name="replacements" select="/.." /> | |
| 66 | + <xsl:choose> | |
| 67 | + <xsl:when test="not($string)" /> | |
| 68 | + <xsl:when test="not($replacements)"> | |
| 69 | + <xsl:value-of select="$string" /> | |
| 70 | + </xsl:when> | |
| 71 | + <xsl:otherwise> | |
| 72 | + <xsl:variable name="replacement" select="$replacements[1]" /> | |
| 73 | + <xsl:variable name="search" select="$replacement/@search" /> | |
| 74 | + <xsl:choose> | |
| 75 | + <xsl:when test="not(string($search))"> | |
| 76 | + <xsl:value-of select="substring($string, 1, 1)" /> | |
| 77 | + <xsl:copy-of select="$replacement/node()" /> | |
| 78 | + <xsl:call-template name="str:_replace"> | |
| 79 | + <xsl:with-param name="string" select="substring($string, 2)" /> | |
| 80 | + <xsl:with-param name="replacements" select="$replacements" /> | |
| 81 | + </xsl:call-template> | |
| 82 | + </xsl:when> | |
| 83 | + <xsl:when test="contains($string, $search)"> | |
| 84 | + <xsl:call-template name="str:_replace"> | |
| 85 | + <xsl:with-param name="string" select="substring-before($string, $search)" /> | |
| 86 | + <xsl:with-param name="replacements" select="$replacements[position() > 1]" /> | |
| 87 | + </xsl:call-template> | |
| 88 | + <xsl:copy-of select="$replacement/node()" /> | |
| 89 | + <xsl:call-template name="str:_replace"> | |
| 90 | + <xsl:with-param name="string" select="substring-after($string, $search)" /> | |
| 91 | + <xsl:with-param name="replacements" select="$replacements" /> | |
| 92 | + </xsl:call-template> | |
| 93 | + </xsl:when> | |
| 94 | + <xsl:otherwise> | |
| 95 | + <xsl:call-template name="str:_replace"> | |
| 96 | + <xsl:with-param name="string" select="$string" /> | |
| 97 | + <xsl:with-param name="replacements" select="$replacements[position() > 1]" /> | |
| 98 | + </xsl:call-template> | |
| 99 | + </xsl:otherwise> | |
| 100 | + </xsl:choose> | |
| 101 | + </xsl:otherwise> | |
| 102 | + </xsl:choose> | |
| 103 | +</xsl:template> | |
| 104 | + | |
| 105 | +</xsl:stylesheet> | |
| 0 | 106 | \ No newline at end of file | ... | ... |
webservice/documentation.php
0 → 100755
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | +* Generates documentation for WSDL generation for KnowledgeTree webservices. | |
| 5 | +* | |
| 6 | +* KnowledgeTree Community Edition | |
| 7 | +* Document Management Made Simple | |
| 8 | +* Copyright (C) 2008,2009 KnowledgeTree Inc. | |
| 9 | +* Portions copyright The Jam Warehouse Software (Pty) Limited | |
| 10 | +* | |
| 11 | +* This program is free software; you can redistribute it and/or modify it under | |
| 12 | +* the terms of the GNU General Public License version 3 as published by the | |
| 13 | +* Free Software Foundation. | |
| 14 | +* | |
| 15 | +* This program is distributed in the hope that it will be useful, but WITHOUT | |
| 16 | +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
| 17 | +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
| 18 | +* details. | |
| 19 | +* | |
| 20 | +* You should have received a copy of the GNU General Public License | |
| 21 | +* along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 22 | +* | |
| 23 | +* You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco, | |
| 24 | +* California 94120-7775, or email info@knowledgetree.com. | |
| 25 | +* | |
| 26 | +* The interactive user interfaces in modified source and object code versions | |
| 27 | +* of this program must display Appropriate Legal Notices, as required under | |
| 28 | +* Section 5 of the GNU General Public License version 3. | |
| 29 | +* | |
| 30 | +* In accordance with Section 7(b) of the GNU General Public License version 3, | |
| 31 | +* these Appropriate Legal Notices must retain the display of the "Powered by | |
| 32 | +* KnowledgeTree" logo and retain the original copyright notice. If the display of the | |
| 33 | +* logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices | |
| 34 | +* must display the words "Powered by KnowledgeTree" and retain the original | |
| 35 | +* copyright notice. | |
| 36 | +* | |
| 37 | +* @copyright 2008-2009, KnowledgeTree Inc. | |
| 38 | +* @license GNU General Public License version 3 | |
| 39 | +* @author KnowledgeTree Team | |
| 40 | +* @package Webservice | |
| 41 | +* @version Version 0.1 | |
| 42 | +*/ | |
| 43 | +//need to manually include for the function 'get_declared_classes()' | |
| 44 | +include_once("classes/soap/IPPhpDoc.class.php"); | |
| 45 | +include_once("classes/soap/IPReflectionClass.class.php"); | |
| 46 | +include_once("classes/soap/IPReflectionCommentParser.class.php"); | |
| 47 | +include_once("classes/soap/IPReflectionMethod.class.php"); | |
| 48 | +include_once("classes/soap/IPReflectionProperty.class.php"); | |
| 49 | +include_once("classes/soap/IPXMLSchema.class.php"); | |
| 50 | +include_once("classes/soap/WSDLStruct.class.php"); | |
| 51 | +include_once("classes/soap/WSHelper.class.php"); | |
| 52 | +include_once("classes/soap/IPXSLTemplate.class.php"); | |
| 53 | + | |
| 54 | +$phpdoc=new IPPhpdoc(); | |
| 55 | +if(isset($_GET['class'])) $phpdoc->setClass($_GET['class']); | |
| 56 | +echo $phpdoc->getDocumentation(); | |
| 57 | +?> | |
| 0 | 58 | \ No newline at end of file | ... | ... |
webservice/restservice.php
0 → 100755
| 1 | +<?php | |
| 2 | +/** | |
| 3 | +* Implements a cleaner wrapper restservice API for KnowledgeTree. | |
| 4 | +* | |
| 5 | +* KnowledgeTree Community Edition | |
| 6 | +* Document Management Made Simple | |
| 7 | +* Copyright (C) 2008,2009 KnowledgeTree Inc. | |
| 8 | +* Portions copyright The Jam Warehouse Software (Pty) Limited | |
| 9 | +* | |
| 10 | +* This program is free software; you can redistribute it and/or modify it under | |
| 11 | +* the terms of the GNU General Public License version 3 as published by the | |
| 12 | +* Free Software Foundation. | |
| 13 | +* | |
| 14 | +* This program is distributed in the hope that it will be useful, but WITHOUT | |
| 15 | +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
| 16 | +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
| 17 | +* details. | |
| 18 | +* | |
| 19 | +* You should have received a copy of the GNU General Public License | |
| 20 | +* along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 21 | +* | |
| 22 | +* You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco, | |
| 23 | +* California 94120-7775, or email info@knowledgetree.com. | |
| 24 | +* | |
| 25 | +* The interactive user interfaces in modified source and object code versions | |
| 26 | +* of this program must display Appropriate Legal Notices, as required under | |
| 27 | +* Section 5 of the GNU General Public License version 3. | |
| 28 | +* | |
| 29 | +* In accordance with Section 7(b) of the GNU General Public License version 3, | |
| 30 | +* these Appropriate Legal Notices must retain the display of the "Powered by | |
| 31 | +* KnowledgeTree" logo and retain the original copyright notice. If the display of the | |
| 32 | +* logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices | |
| 33 | +* must display the words "Powered by KnowledgeTree" and retain the original | |
| 34 | +* copyright notice. | |
| 35 | +* | |
| 36 | +* @copyright 2008-2009, KnowledgeTree Inc. | |
| 37 | +* @license GNU General Public License version 3 | |
| 38 | +* @author KnowledgeTree Team | |
| 39 | +* @package Webservice | |
| 40 | +* @version Version 0.1 | |
| 41 | +*/ | |
| 42 | + | |
| 43 | +ob_start("ob_gzhandler"); | |
| 44 | +session_start(); | |
| 45 | + | |
| 46 | +if(file_exists("classes/rest/Server.php")) | |
| 47 | + include("classes/rest/Server.php"); | |
| 48 | +if (file_exists("classes/rest/model/contactManager.class.php")) | |
| 49 | + include("classes/rest/model/contactManager.class.php"); | |
| 50 | +if (file_exists("classes/rest/model/RestService.class.php")) | |
| 51 | + include("classes/rest/model/RestService.class.php"); | |
| 52 | + | |
| 53 | + | |
| 54 | +try { | |
| 55 | + $server = new Rest_Server(); | |
| 56 | + | |
| 57 | + $server->setClass("contactManager"); | |
| 58 | + | |
| 59 | + //$server->addFunction('getContacts'); | |
| 60 | + | |
| 61 | + $server->handle(); | |
| 62 | + //var_dump($server); | |
| 63 | + | |
| 64 | + | |
| 65 | + }catch(Exception $e) { | |
| 66 | + //possible db transaction rollback | |
| 67 | + $server->fault("SERVER", $e->getMessage(),"", $e->__toString()); | |
| 68 | + } | |
| 69 | +exit; | |
| 70 | +?> | |
| 0 | 71 | \ No newline at end of file | ... | ... |
webservice/tests/RESTClient.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +require_once "HTTP/Request.php"; | |
| 4 | + | |
| 5 | +class RESTClient { | |
| 6 | + | |
| 7 | + private $root_url = ""; | |
| 8 | + private $curr_url = ""; | |
| 9 | + private $user_name = ""; | |
| 10 | + private $password = ""; | |
| 11 | + private $response = ""; | |
| 12 | + private $responseBody = ""; | |
| 13 | + private $req = null; | |
| 14 | + | |
| 15 | + public function __construct($root_url = "", $user_name = "", $password = "") { | |
| 16 | + $this->root_url = $this->curr_url = $root_url; | |
| 17 | + $this->user_name = $user_name; | |
| 18 | + $this->password = $password; | |
| 19 | + if ($root_url != "") { | |
| 20 | + $this->createRequest("GET"); | |
| 21 | + $this->sendRequest(); | |
| 22 | + } | |
| 23 | + return true; | |
| 24 | + } | |
| 25 | + | |
| 26 | + public function createRequest($url, $method, $arr = null) { | |
| 27 | + $this->curr_url = $url; | |
| 28 | + $this->req =& new HTTP_Request($url); | |
| 29 | + if ($this->user_name != "" && $this->password != "") { | |
| 30 | + $this->req->setBasicAuth($this->user_name, $this->password); | |
| 31 | + } | |
| 32 | + | |
| 33 | + switch($method) { | |
| 34 | + case "GET": | |
| 35 | + $this->req->setMethod(HTTP_REQUEST_METHOD_GET); | |
| 36 | + break; | |
| 37 | + case "POST": | |
| 38 | + $this->req->setMethod(HTTP_REQUEST_METHOD_POST); | |
| 39 | + $this->addPostData($arr); | |
| 40 | + break; | |
| 41 | + case "PUT": | |
| 42 | + $this->req->setMethod(HTTP_REQUEST_METHOD_PUT); | |
| 43 | + // to-do | |
| 44 | + break; | |
| 45 | + case "DELETE": | |
| 46 | + $this->req->setMethod(HTTP_REQUEST_METHOD_DELETE); | |
| 47 | + // to-do | |
| 48 | + break; | |
| 49 | + } | |
| 50 | + } | |
| 51 | + | |
| 52 | + private function addPostData($arr) { | |
| 53 | + if ($arr != null) { | |
| 54 | + foreach ($arr as $key => $value) { | |
| 55 | + $this->req->addPostData($key, $value); | |
| 56 | + } | |
| 57 | + } | |
| 58 | + } | |
| 59 | + | |
| 60 | + public function sendRequest() { | |
| 61 | + $this->response = $this->req->sendRequest(); | |
| 62 | + | |
| 63 | + if (PEAR::isError($this->response)) { | |
| 64 | + echo $this->response->getMessage(); | |
| 65 | + die(); | |
| 66 | + } else { | |
| 67 | + $this->responseBody = $this->req->getResponseBody(); | |
| 68 | + } | |
| 69 | + } | |
| 70 | + | |
| 71 | + public function getResponse() { | |
| 72 | + return $this->responseBody; | |
| 73 | + } | |
| 74 | + | |
| 75 | +} | |
| 76 | +?> | |
| 0 | 77 | \ No newline at end of file | ... | ... |
webservice/tests/Rest.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +include_once("RESTClient.php"); | |
| 4 | + | |
| 5 | +$rest = new RESTclient(); | |
| 6 | + | |
| 7 | +$inputs = array(); | |
| 8 | +$inputs["appid"] = "YahooDemo"; | |
| 9 | +$inputs["street"] = "701 First Street"; | |
| 10 | +$inputs["city"] = "Sunnyvale"; | |
| 11 | +$inputs["state"] = "CA"; | |
| 12 | + | |
| 13 | +$url = "http://www.knowledgetree.pr/webservice/service.php?class=RestService"; | |
| 14 | +$rest->createRequest("$url","GET",''); | |
| 15 | +$rest->sendRequest(); | |
| 16 | +$output = $rest->getResponse(); | |
| 17 | +echo $output; | |
| 18 | + | |
| 19 | +?> | |
| 0 | 20 | \ No newline at end of file | ... | ... |
webservice/tests/annotations.php
0 → 100755
| 1 | +<? | |
| 2 | +chdir(".."); | |
| 3 | +include "common.php"; | |
| 4 | + | |
| 5 | +class DefaultController { | |
| 6 | + const TYPE_PLAIN = 1; | |
| 7 | + const TYPE_HTML = 2; | |
| 8 | + public $type; | |
| 9 | + public $length; | |
| 10 | +} | |
| 11 | +/** | |
| 12 | + * @ann1('me'=>'you'); | |
| 13 | + */ | |
| 14 | +class something{ | |
| 15 | + /** | |
| 16 | + * @var string | |
| 17 | + * @Controller(type => DefaultController::TYPE_PLAIN, length => 100) | |
| 18 | + */ | |
| 19 | + public $propertyA; | |
| 20 | + | |
| 21 | + /** | |
| 22 | + * @var string | |
| 23 | + * @Controller(type => DefaultController::TYPE_HTML, length => 100) | |
| 24 | + */ | |
| 25 | + public function methodB () { | |
| 26 | + return "aap"; | |
| 27 | + } | |
| 28 | +} | |
| 29 | + | |
| 30 | +/* Annotation example */ | |
| 31 | +$rel = new IPReflectionClass("something"); | |
| 32 | +$properties = $rel->getProperties(); | |
| 33 | +$methods = $rel->getMethods(); | |
| 34 | + | |
| 35 | +var_dump($rel->getAnnotation("ann1", "stdClass")); | |
| 36 | + | |
| 37 | +$property = $properties["propertyA"]; | |
| 38 | +$ann = $property->getAnnotation("Controller", "DefaultController"); | |
| 39 | +var_dump($ann); | |
| 40 | + | |
| 41 | +$method = $methods["methodB"]; | |
| 42 | +$ann = $method->getAnnotation("Controller", "DefaultController"); | |
| 43 | +var_dump($ann); | |
| 44 | +?> | |
| 0 | 45 | \ No newline at end of file | ... | ... |
webservice/tests/webservice.php
0 → 100755
| 1 | +<?php | |
| 2 | +$wsdl = "http://".$_SERVER['HTTP_HOST']."/webservice/service.php?class=contactManager&wsdl"; | |
| 3 | +echo "<strong>WSDL file:</strong> ".$wsdl."<br>\n"; | |
| 4 | + | |
| 5 | +$options = Array('actor' =>'http://www.knowledgetree.pr', | |
| 6 | + 'trace' => true); | |
| 7 | +$client = new SoapClient($wsdl,$options); | |
| 8 | + | |
| 9 | +echo "<hr> <strong>Result from getContacts call:</strong><br>"; | |
| 10 | + | |
| 11 | +$res = $client->getContacts(); | |
| 12 | +print_r($res); | |
| 13 | +echo "<hr><strong>Raw Soap response:</strong><br>"; | |
| 14 | +echo htmlentities($client->__getLastResponse()); | |
| 15 | +echo "<hr><strong>SoapFault asking for an unknown contact:</strong><br>"; | |
| 16 | +$client->newContact(); | |
| 17 | +?> | |
| 0 | 18 | \ No newline at end of file | ... | ... |
webservice/webservice.php
0 → 100755
| 1 | +<?php | |
| 2 | +/** | |
| 3 | +* Invokes webservices API for KnowledgeTree. | |
| 4 | +* | |
| 5 | +* KnowledgeTree Community Edition | |
| 6 | +* Document Management Made Simple | |
| 7 | +* Copyright (C) 2008,2009 KnowledgeTree Inc. | |
| 8 | +* Portions copyright The Jam Warehouse Software (Pty) Limited | |
| 9 | +* | |
| 10 | +* This program is free software; you can redistribute it and/or modify it under | |
| 11 | +* the terms of the GNU General Public License version 3 as published by the | |
| 12 | +* Free Software Foundation. | |
| 13 | +* | |
| 14 | +* This program is distributed in the hope that it will be useful, but WITHOUT | |
| 15 | +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
| 16 | +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
| 17 | +* details. | |
| 18 | +* | |
| 19 | +* You should have received a copy of the GNU General Public License | |
| 20 | +* along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 21 | +* | |
| 22 | +* You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco, | |
| 23 | +* California 94120-7775, or email info@knowledgetree.com. | |
| 24 | +* | |
| 25 | +* The interactive user interfaces in modified source and object code versions | |
| 26 | +* of this program must display Appropriate Legal Notices, as required under | |
| 27 | +* Section 5 of the GNU General Public License version 3. | |
| 28 | +* | |
| 29 | +* In accordance with Section 7(b) of the GNU General Public License version 3, | |
| 30 | +* these Appropriate Legal Notices must retain the display of the "Powered by | |
| 31 | +* KnowledgeTree" logo and retain the original copyright notice. If the display of the | |
| 32 | +* logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices | |
| 33 | +* must display the words "Powered by KnowledgeTree" and retain the original | |
| 34 | +* copyright notice. | |
| 35 | +* | |
| 36 | +* @copyright 2008-2009, KnowledgeTree Inc. | |
| 37 | +* @license GNU General Public License version 3 | |
| 38 | +* @author KnowledgeTree Team | |
| 39 | +* @package Webservice | |
| 40 | +* @version Version 0.1 | |
| 41 | +*/ | |
| 42 | + | |
| 43 | +require_once "classes/soap/common.php"; | |
| 44 | + | |
| 45 | +if($_GET['class'] && (in_array($_GET['class'], $WSClasses) || in_array($_GET['class'], $WSStructures))) { | |
| 46 | + $WSHelper = new WSHelper("http://www.knowledgetree.com", $_GET['class']); | |
| 47 | + $WSHelper->actor = "http://www.knowledgetree.com"; | |
| 48 | + $WSHelper->use = SOAP_ENCODED; | |
| 49 | + $WSHelper->classNameArr = $WSClasses; | |
| 50 | + $WSHelper->structureMap = $WSStructures; | |
| 51 | + $WSHelper->setPersistence(SOAP_PERSISTENCE_REQUEST); | |
| 52 | + $WSHelper->setWSDLCacheFolder('wsdl/'); //trailing slash mandatory. Default is 'wsdl/' | |
| 53 | + | |
| 54 | + try { | |
| 55 | + | |
| 56 | + $WSHelper->handle(); | |
| 57 | + //possible db transaction commit | |
| 58 | + }catch(Exception $e) { | |
| 59 | + //possible db transaction rollback | |
| 60 | + $WSHelper->fault("SERVER", $e->getMessage(),"", $e->__toString()); | |
| 61 | + } | |
| 62 | +} else { | |
| 63 | + die("No valid class selected"); | |
| 64 | +} | |
| 65 | + | |
| 66 | +?> | |
| 0 | 67 | \ No newline at end of file | ... | ... |
webservice/wsdl/contactManager.wsdl
0 → 100644
| 1 | +<?xml version="1.0"?> | |
| 2 | +<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.knowledgetree.com" targetNamespace="http://www.knowledgetree.com"><wsdl:types><xsd:schema targetNamespace="http://www.knowledgetree.com"><xsd:complexType name="contact"><xsd:all><xsd:element name="address" type="tns:address"/><xsd:element name="email" type="xsd:string"/><xsd:element name="id" type="xsd:int"/><xsd:element name="name" type="xsd:string"/></xsd:all></xsd:complexType><xsd:complexType name="address"><xsd:all><xsd:element name="city" type="xsd:string"/><xsd:element name="nr" type="xsd:string"/><xsd:element name="street" type="xsd:string"/><xsd:element name="zipcode" type="xsd:string"/></xsd:all></xsd:complexType><xsd:complexType name="contactArray"><xsd:complexContent><xsd:restriction base="SOAP-ENC:Array"><xsd:attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="tns:contact[]"/></xsd:restriction></xsd:complexContent></xsd:complexType></xsd:schema></wsdl:types><message name="getContactRequest"><part name="id" type="xsd:int"/></message><message name="getContactResponse"><part name="getContactReturn" type="tns:contact"/></message><message name="getContactsRequest"/><message name="getContactsResponse"><part name="getContactsReturn" type="tns:contactArray"/></message><message name="newContactRequest"/><message name="newContactResponse"><part name="newContactReturn" type="tns:contact"/></message><message name="saveContactRequest"><part name="contact" type="tns:contact"/></message><wsdl:portType name="contactManagerPortType"><wsdl:operation name="getContact"><wsdl:input message="tns:getContactRequest"/><wsdl:output message="tns:getContactResponse"/></wsdl:operation><wsdl:operation name="getContacts"><wsdl:input message="tns:getContactsRequest"/><wsdl:output message="tns:getContactsResponse"/></wsdl:operation><wsdl:operation name="newContact"><wsdl:input message="tns:newContactRequest"/><wsdl:output message="tns:newContactResponse"/></wsdl:operation><wsdl:operation name="saveContact"><wsdl:input message="tns:saveContactRequest"/></wsdl:operation></wsdl:portType><binding name="contactManagerBinding" type="tns:contactManagerPortType"><soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/><wsdl:operation name="getContact"><soap:operation soapAction="http://www.knowledgetree.pr/webservice/webservice.php?class=contactManager&method=getContact" style="rpc"/><wsdl:input><soap:body use="encoded" namespace="http://www.knowledgetree.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></wsdl:input><wsdl:output><soap:body use="encoded" namespace="http://www.knowledgetree.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></wsdl:output></wsdl:operation><wsdl:operation name="getContacts"><soap:operation soapAction="http://www.knowledgetree.pr/webservice/webservice.php?class=contactManager&method=getContacts" style="rpc"/><wsdl:input><soap:body use="encoded" namespace="http://www.knowledgetree.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></wsdl:input><wsdl:output><soap:body use="encoded" namespace="http://www.knowledgetree.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></wsdl:output></wsdl:operation><wsdl:operation name="newContact"><soap:operation soapAction="http://www.knowledgetree.pr/webservice/webservice.php?class=contactManager&method=newContact" style="rpc"/><wsdl:input><soap:body use="encoded" namespace="http://www.knowledgetree.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></wsdl:input><wsdl:output><soap:body use="encoded" namespace="http://www.knowledgetree.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></wsdl:output></wsdl:operation><wsdl:operation name="saveContact"><soap:operation soapAction="http://www.knowledgetree.pr/webservice/webservice.php?class=contactManager&method=saveContact" style="rpc"/><wsdl:input><soap:body use="encoded" namespace="http://www.knowledgetree.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></wsdl:input></wsdl:operation></binding><wsdl:service name="contactManager"><wsdl:port name="contactManagerPort" binding="tns:contactManagerBinding"><soap:address location="http://www.knowledgetree.pr/webservice/webservice.php?class=contactManager"/></wsdl:port></wsdl:service></wsdl:definitions> | ... | ... |