/** * Attach a function or callback to the server * * @param string|array $function Valid PHP callback * @param string $namespace Ignored * @return Zend_Json_Server */ public function addFunction($function, $namespace = '') { if (!is_string($function) && (!is_array($function) || 2 > count($function))) { require_once 'Zend/Json/Server/Exception.php'; throw new Zend_Json_Server_Exception('Unable to attach function; invalid'); } if (!is_callable($function)) { require_once 'Zend/Json/Server/Exception.php'; throw new Zend_Json_Server_Exception('Unable to attach function; does not exist'); } require_once 'Zend/Server/Reflection.php'; if (is_string($function)) { $method = Zend_Server_Reflection::reflectFunction($function); } else { $class = array_shift($function); $action = array_shift($function); $reflection = Zend_Server_Reflection::reflectClass($class); $methods = $reflection->getMethods(); $found = false; foreach ($methods as $method) { if ($action == $method->getName()) { $found = true; break; } } if (!$found) { $this->fault('Method not found', -32601); return $this; } } $this->_methods[$method->getName()] = $method; $this->_addMethodServiceMap($method); return $this; }
/** * Add a Single or Multiple Functions to the WSDL * * @param string $function Function Name * @param string $namespace Function namespace - Not Used * @return Zend_Soap_AutoDiscover */ public function addFunction($function, $namespace = '') { static $port; static $operation; static $binding; if (!is_array($function)) { $function = (array) $function; } $uri = $this->getUri(); if (!$this->_wsdl instanceof Zend_Soap_Wsdl) { $parts = explode('.', basename($_SERVER['SCRIPT_NAME'])); $name = $parts[0]; $wsdl = new Zend_Soap_Wsdl($name, $uri, $this->_strategy); // The wsdl:types element must precede all other elements (WS-I Basic Profile 1.1 R2023) $wsdl->addSchemaTypeSection(); $port = $wsdl->addPortType($name . 'Port'); $binding = $wsdl->addBinding($name . 'Binding', 'tns:' . $name . 'Port'); $wsdl->addSoapBinding($binding, $this->_bindingStyle['style'], $this->_bindingStyle['transport']); $wsdl->addService($name . 'Service', $name . 'Port', 'tns:' . $name . 'Binding', $uri); } else { $wsdl = $this->_wsdl; } foreach ($function as $func) { $method = $this->_reflection->reflectFunction($func); $this->_addFunctionToWsdl($method, $wsdl, $port, $binding); } $this->_wsdl = $wsdl; return $this; }
/** * Add a Single or Multiple Functions to the WSDL * * @param string $function Function Name * @param string $namespace Function namespace - Not Used */ public function addFunction($function, $namespace = '') { static $port; static $operation; static $binding; if (!is_array($function)) { $function = (array) $function; } $uri = $this->getUri(); if (!$this->_wsdl instanceof Zend_Soap_Wsdl) { $parts = explode('.', basename($_SERVER['SCRIPT_NAME'])); $name = $parts[0]; $wsdl = new Zend_Soap_Wsdl($name, $uri, $this->_strategy); $port = $wsdl->addPortType($name . 'Port'); $binding = $wsdl->addBinding($name . 'Binding', 'tns:' . $name . 'Port'); $wsdl->addSoapBinding($binding, $this->_bindingStyle['style'], $this->_bindingStyle['transport']); $wsdl->addService($name . 'Service', $name . 'Port', 'tns:' . $name . 'Binding', $uri); } else { $wsdl = $this->_wsdl; } foreach ($function as $func) { $method = $this->_reflection->reflectFunction($func); foreach ($method->getPrototypes() as $prototype) { $args = array(); foreach ($prototype->getParameters() as $param) { $args[$param->getName()] = $wsdl->getType($param->getType()); } $message = $wsdl->addMessage($method->getName() . 'Request', $args); $desc = $method->getDescription(); if (strlen($desc) > 0) { //$wsdl->addDocumentation($message, $desc); } if ($prototype->getReturnType() != "void") { if ($this->_responseMessageReturnNameCompability === true) { $returnName = "return"; } else { $returnName = $method->getName() . 'Return'; } $message = $wsdl->addMessage($method->getName() . 'Response', array($returnName => $wsdl->getType($prototype->getReturnType()))); } /* <wsdl:portType>'s */ $portOperation = $wsdl->addPortOperation($port, $method->getName(), 'tns:' . $method->getName() . 'Request', 'tns:' . $method->getName() . 'Response'); if (strlen($desc) > 0) { //$wsdl->addDocumentation($portOperation, $desc); } /* </wsdl:portType>'s */ /* <wsdl:binding>'s */ $operation = $wsdl->addBindingOperation($binding, $method->getName(), $this->_operationBodyStyle, $this->_operationBodyStyle); $wsdl->addSoapOperation($operation, $uri->getUri() . '#' . $method->getName()); /* </wsdl:binding>'s */ $this->_functions[] = $method->getName(); // We will only add one prototype break; } } $this->_wsdl = $wsdl; }
/** * Add a Single or Multiple Functions to the WSDL * * @param string $function Function Name * @param string $namespace Function namespace - Not Used */ public function addFunction($function, $namespace = '') { static $port; static $operation; static $binding; if (!is_array($function)) { $function = (array) $function; } $uri = Zend_Uri::factory('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME']); if (!$this->_wsdl instanceof Zend_Soap_Wsdl) { $parts = explode('.', basename($_SERVER['SCRIPT_NAME'])); $name = $parts[0]; $wsdl = new Zend_Soap_Wsdl($name, $uri, $this->_extractComplexTypes); $port = $wsdl->addPortType($name . 'Port'); $binding = $wsdl->addBinding($name . 'Binding', 'tns:' . $name . 'Port'); $wsdl->addSoapBinding($binding, 'rpc'); $wsdl->addService($name . 'Service', $name . 'Port', 'tns:' . $name . 'Binding', $uri); } else { $wsdl = $this->_wsdl; } foreach ($function as $func) { $method = $this->_reflection->reflectFunction($func); foreach ($method->getPrototypes() as $prototype) { $args = array(); foreach ($prototype->getParameters() as $param) { $args[$param->getName()] = $wsdl->getType($param->getType()); } $message = $wsdl->addMessage($method->getName() . 'Request', $args); $desc = $method->getDescription(); if (strlen($desc) > 0) { //$wsdl->addDocumentation($message, $desc); } if ($prototype->getReturnType() != "void") { $message = $wsdl->addMessage($method->getName() . 'Response', array($method->getName() . 'Return' => $wsdl->getType($prototype->getReturnType()))); } /* <wsdl:portType>'s */ $portOperation = $wsdl->addPortOperation($port, $method->getName(), 'tns:' . $method->getName() . 'Request', 'tns:' . $method->getName() . 'Response'); if (strlen($desc) > 0) { //$wsdl->addDocumentation($portOperation, $desc); } /* </wsdl:portType>'s */ /* <wsdl:binding>'s */ $operation = $wsdl->addBindingOperation($binding, $method->getName(), array('use' => 'encoded', 'encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/"), array('use' => 'encoded', 'encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/")); $wsdl->addSoapOperation($binding, $uri->getUri() . '#' . $method->getName()); /* </wsdl:binding>'s */ $this->_functions[] = $method->getName(); // We will only add one prototype break; } } $this->_wsdl = $wsdl; }
/** * Implement Zend_Server_Interface::addFunction() * * @param string $function Function Name * @param string $namespace Function namespace (unused) */ public function addFunction($function, $namespace = '') { if (!is_array($function)) { $function = (array) $function; } foreach ($function as $func) { if (is_callable($func) && !in_array($func, self::$magic_methods)) { $this->_functions[$func] = $this->_reflection->reflectFunction($func); } else { throw new Zend_Rest_Server_Exception("Invalid Method Added to Service."); } } }
/** * Implement Zend_Server_Interface::addFunction() * * @param string $function Function Name * @param string $namespace Function namespace (unused) */ public function addFunction($function, $namespace = '') { if (!is_array($function)) { $function = (array) $function; } foreach ($function as $func) { if (is_callable($func) && !in_array($func, self::$magicMethods)) { $this->_functions[$func] = $this->_reflection->reflectFunction($func); } else { require_once PHP_LIBRARY_PATH . 'Zend/Rest/Server/Exception.php'; throw new Zend_Rest_Server_Exception("Invalid Method Added to Service."); } } }
/** * Attach a callback as an XMLRPC method * * Attaches a callback as an XMLRPC method, prefixing the XMLRPC method name * with $namespace, if provided. Reflection is done on the callback's * docblock to create the methodHelp for the XMLRPC method. * * Additional arguments to pass to the function at dispatch may be passed; * any arguments following the namespace will be aggregated and passed at * dispatch time. * * @param string|array $function Valid callback * @param string $namespace Optional namespace prefix * @return void * @throws Zend_XmlRpc_Server_Exception */ public function addFunction($function, $namespace = '') { if (!is_string($function) && !is_array($function)) { require_once 'Zend/XmlRpc/Server/Exception.php'; throw new Zend_XmlRpc_Server_Exception('Unable to attach function; invalid', 611); } $argv = null; if (2 < func_num_args()) { $argv = func_get_args(); $argv = array_slice($argv, 2); } $function = (array) $function; foreach ($function as $func) { if (!is_string($func) || !function_exists($func)) { require_once 'Zend/XmlRpc/Server/Exception.php'; throw new Zend_XmlRpc_Server_Exception('Unable to attach function; invalid', 611); } $reflection = Zend_Server_Reflection::reflectFunction($func, $argv, $namespace); $this->_buildSignature($reflection); } }
/** * Attach a function to the server * * Additional arguments to pass to the function at dispatch may be passed; * any arguments following the namespace will be aggregated and passed at * dispatch time. * * @param string|array $function Valid callback * @param string $namespace Optional namespace prefix * @return Zend_Amf_Server * @throws Zend_Amf_Server_Exception */ public function addFunction($function, $namespace = '') { if (!is_string($function) && !is_array($function)) { require_once 'Zend/Amf/Server/Exception.php'; throw new Zend_Amf_Server_Exception('Unable to attach function'); } $argv = null; if (2 < func_num_args()) { $argv = array_slice(func_get_args(), 2); } $function = (array) $function; foreach ($function as $func) { if (!is_string($func) || !function_exists($func)) { require_once 'Zend/Amf/Server/Exception.php'; throw new Zend_Amf_Server_Exception('Unable to attach function'); } $this->_methods[] = Zend_Server_Reflection::reflectFunction($func, $argv, $namespace); } $this->_buildDispatchTable(); return $this; }
/** * reflectFunction() test; test namespaces */ public function testReflectFunction2() { $reflection = Zend_Server_Reflection::reflectFunction('Zend_Server_Reflection_testFunction', false, 'zsr'); $this->assertEquals('zsr', $reflection->getNamespace()); }
/** * upgrades the mnet rpc definitions for the given component. * this method doesn't return status, an exception will be thrown in the case of an error * * @param string $component the plugin to upgrade, eg auth_mnet */ function upgrade_plugin_mnet_functions($component) { global $DB, $CFG; list($type, $plugin) = core_component::normalize_component($component); $path = core_component::get_plugin_directory($type, $plugin); $publishes = array(); $subscribes = array(); if (file_exists($path . '/db/mnet.php')) { require_once($path . '/db/mnet.php'); // $publishes comes from this file } if (empty($publishes)) { $publishes = array(); // still need this to be able to disable stuff later } if (empty($subscribes)) { $subscribes = array(); // still need this to be able to disable stuff later } static $servicecache = array(); // rekey an array based on the rpc method for easy lookups later $publishmethodservices = array(); $subscribemethodservices = array(); foreach($publishes as $servicename => $service) { if (is_array($service['methods'])) { foreach($service['methods'] as $methodname) { $service['servicename'] = $servicename; $publishmethodservices[$methodname][] = $service; } } } // Disable functions that don't exist (any more) in the source // Should these be deleted? What about their permissions records? foreach ($DB->get_records('mnet_rpc', array('pluginname'=>$plugin, 'plugintype'=>$type), 'functionname ASC ') as $rpc) { if (!array_key_exists($rpc->functionname, $publishmethodservices) && $rpc->enabled) { $DB->set_field('mnet_rpc', 'enabled', 0, array('id' => $rpc->id)); } else if (array_key_exists($rpc->functionname, $publishmethodservices) && !$rpc->enabled) { $DB->set_field('mnet_rpc', 'enabled', 1, array('id' => $rpc->id)); } } // reflect all the services we're publishing and save them require_once($CFG->dirroot . '/lib/zend/Zend/Server/Reflection.php'); static $cachedclasses = array(); // to store reflection information in foreach ($publishes as $service => $data) { $f = $data['filename']; $c = $data['classname']; foreach ($data['methods'] as $method) { $dataobject = new stdClass(); $dataobject->plugintype = $type; $dataobject->pluginname = $plugin; $dataobject->enabled = 1; $dataobject->classname = $c; $dataobject->filename = $f; if (is_string($method)) { $dataobject->functionname = $method; } else if (is_array($method)) { // wants to override file or class $dataobject->functionname = $method['method']; $dataobject->classname = $method['classname']; $dataobject->filename = $method['filename']; } $dataobject->xmlrpcpath = $type.'/'.$plugin.'/'.$dataobject->filename.'/'.$method; $dataobject->static = false; require_once($path . '/' . $dataobject->filename); $functionreflect = null; // slightly different ways to get this depending on whether it's a class method or a function if (!empty($dataobject->classname)) { if (!class_exists($dataobject->classname)) { throw new moodle_exception('installnosuchmethod', 'mnet', '', (object)array('method' => $dataobject->functionname, 'class' => $dataobject->classname)); } $key = $dataobject->filename . '|' . $dataobject->classname; if (!array_key_exists($key, $cachedclasses)) { // look to see if we've already got a reflection object try { $cachedclasses[$key] = Zend_Server_Reflection::reflectClass($dataobject->classname); } catch (Zend_Server_Reflection_Exception $e) { // catch these and rethrow them to something more helpful throw new moodle_exception('installreflectionclasserror', 'mnet', '', (object)array('method' => $dataobject->functionname, 'class' => $dataobject->classname, 'error' => $e->getMessage())); } } $r =& $cachedclasses[$key]; if (!$r->hasMethod($dataobject->functionname)) { throw new moodle_exception('installnosuchmethod', 'mnet', '', (object)array('method' => $dataobject->functionname, 'class' => $dataobject->classname)); } // stupid workaround for zend not having a getMethod($name) function $ms = $r->getMethods(); foreach ($ms as $m) { if ($m->getName() == $dataobject->functionname) { $functionreflect = $m; break; } } $dataobject->static = (int)$functionreflect->isStatic(); } else { if (!function_exists($dataobject->functionname)) { throw new moodle_exception('installnosuchfunction', 'mnet', '', (object)array('method' => $dataobject->functionname, 'file' => $dataobject->filename)); } try { $functionreflect = Zend_Server_Reflection::reflectFunction($dataobject->functionname); } catch (Zend_Server_Reflection_Exception $e) { // catch these and rethrow them to something more helpful throw new moodle_exception('installreflectionfunctionerror', 'mnet', '', (object)array('method' => $dataobject->functionname, '' => $dataobject->filename, 'error' => $e->getMessage())); } } $dataobject->profile = serialize(admin_mnet_method_profile($functionreflect)); $dataobject->help = $functionreflect->getDescription(); if ($record_exists = $DB->get_record('mnet_rpc', array('xmlrpcpath'=>$dataobject->xmlrpcpath))) { $dataobject->id = $record_exists->id; $dataobject->enabled = $record_exists->enabled; $DB->update_record('mnet_rpc', $dataobject); } else { $dataobject->id = $DB->insert_record('mnet_rpc', $dataobject, true); } // TODO this API versioning must be reworked, here the recently processed method // sets the service API which may not be correct foreach ($publishmethodservices[$dataobject->functionname] as $service) { if ($serviceobj = $DB->get_record('mnet_service', array('name'=>$service['servicename']))) { $serviceobj->apiversion = $service['apiversion']; $DB->update_record('mnet_service', $serviceobj); } else { $serviceobj = new stdClass(); $serviceobj->name = $service['servicename']; $serviceobj->description = empty($service['description']) ? '' : $service['description']; $serviceobj->apiversion = $service['apiversion']; $serviceobj->offer = 1; $serviceobj->id = $DB->insert_record('mnet_service', $serviceobj); } $servicecache[$service['servicename']] = $serviceobj; if (!$DB->record_exists('mnet_service2rpc', array('rpcid'=>$dataobject->id, 'serviceid'=>$serviceobj->id))) { $obj = new stdClass(); $obj->rpcid = $dataobject->id; $obj->serviceid = $serviceobj->id; $DB->insert_record('mnet_service2rpc', $obj, true); } } } } // finished with methods we publish, now do subscribable methods foreach($subscribes as $service => $methods) { if (!array_key_exists($service, $servicecache)) { if (!$serviceobj = $DB->get_record('mnet_service', array('name' => $service))) { debugging("TODO: skipping unknown service $service - somebody needs to fix MDL-21993"); continue; } $servicecache[$service] = $serviceobj; } else { $serviceobj = $servicecache[$service]; } foreach ($methods as $method => $xmlrpcpath) { if (!$rpcid = $DB->get_field('mnet_remote_rpc', 'id', array('xmlrpcpath'=>$xmlrpcpath))) { $remoterpc = (object)array( 'functionname' => $method, 'xmlrpcpath' => $xmlrpcpath, 'plugintype' => $type, 'pluginname' => $plugin, 'enabled' => 1, ); $rpcid = $remoterpc->id = $DB->insert_record('mnet_remote_rpc', $remoterpc, true); } if (!$DB->record_exists('mnet_remote_service2rpc', array('rpcid'=>$rpcid, 'serviceid'=>$serviceobj->id))) { $obj = new stdClass(); $obj->rpcid = $rpcid; $obj->serviceid = $serviceobj->id; $DB->insert_record('mnet_remote_service2rpc', $obj, true); } $subscribemethodservices[$method][] = $service; } } foreach ($DB->get_records('mnet_remote_rpc', array('pluginname'=>$plugin, 'plugintype'=>$type), 'functionname ASC ') as $rpc) { if (!array_key_exists($rpc->functionname, $subscribemethodservices) && $rpc->enabled) { $DB->set_field('mnet_remote_rpc', 'enabled', 0, array('id' => $rpc->id)); } else if (array_key_exists($rpc->functionname, $subscribemethodservices) && !$rpc->enabled) { $DB->set_field('mnet_remote_rpc', 'enabled', 1, array('id' => $rpc->id)); } } return true; }
/** * Attach a callback as an XMLRPC method * * Attaches a callback as an XMLRPC method, prefixing the XMLRPC method name * with $namespace, if provided. Reflection is done on the callback's * docblock to create the methodHelp for the XMLRPC method. * * Additional arguments to pass to the function at dispatch may be passed; * any arguments following the namespace will be aggregated and passed at * dispatch time. * * @param string|array $function Valid callback * @param string $namespace Optional namespace prefix * @return void * @throws Zend_XmlRpc_Server_Exception */ public function addFunction($function, $namespace = '') { if (!is_string($function) && !is_array($function)) { throw new Zend_XmlRpc_Server_Exception('Unable to attach function; invalid', 611); } $argv = null; if (2 < func_num_args()) { $argv = func_get_args(); $argv = array_slice($argv, 2); } $function = (array) $function; foreach ($function as $func) { if (!is_string($func) || !function_exists($func)) { throw new Zend_XmlRpc_Server_Exception('Unable to attach function; invalid', 611); } $this->_methods[] = Zend_Server_Reflection::reflectFunction($func, $argv, $namespace); } $this->_buildDispatchTable(); }
/** * Attach a function or callback to the server * * @param string|array $function Valid PHP callback * @param string $namespace Ignored * @return Zend_Json_Server */ public function addFunction($function, $namespace = '') { if (!is_string($function) && (!is_array($function) || 2 > count($function))) { //$1 'Zend/Json/Server/Exception.php'; throw new Zend_Json_Server_Exception('Unable to attach function; invalid'); } if (!is_callable($function)) { //$1 'Zend/Json/Server/Exception.php'; throw new Zend_Json_Server_Exception('Unable to attach function; does not exist'); } $argv = null; if (2 < func_num_args()) { $argv = func_get_args(); $argv = array_slice($argv, 2); } //$1 'Zend/Server/Reflection.php'; if (is_string($function)) { $method = Zend_Server_Reflection::reflectFunction($function, $argv, $namespace); } else { $class = array_shift($function); $action = array_shift($function); $reflection = Zend_Server_Reflection::reflectClass($class, $argv, $namespace); $methods = $reflection->getMethods(); $found = false; foreach ($methods as $method) { if ($action == $method->getName()) { $found = true; break; } } if (!$found) { $this->fault('Method not found', -32601); return $this; } } $definition = $this->_buildSignature($method); $this->_addMethodServiceMap($definition); return $this; }