<?php
/**
* @author Gaetano Giunta
- * @copyright (C) 2006-2020 G. Giunta
+ * @copyright (C) 2006-2021 G. Giunta
* @license code licensed under the BSD License: see file license.txt
*/
* @todo implement method wrapping with preservation of php objs in calls
* @todo when wrapping methods without obj rebuilding, use return_type = 'phpvals' (faster)
* @todo add support for 'epivals' mode
+ * @todo allow setting custom namespace for generated wrapping code
*/
class Wrapper
{
/// used to hold a reference to object instances whose methods get wrapped by wrapPhpFunction(), in 'create source' mode
public static $objHolder = array();
+ protected static $logger;
+
+ public function getLogger()
+ {
+ if (self::$logger === null) {
+ self::$logger = Logger::instance();
+ }
+ return self::$logger;
+ }
+
+ public static function setLogger($logger)
+ {
+ self::$logger = $logger;
+ }
+
/**
* Given a string defining a php type or phpxmlrpc type (loosely defined: strings
* accepted come from javadoc blocks), return corresponding phpxmlrpc type.
}
if (is_array($callable)) {
if (count($callable) < 2 || (!is_string($callable[0]) && !is_object($callable[0]))) {
- Logger::instance()->errorLog('XML-RPC: ' . __METHOD__ . ': syntax for function to be wrapped is wrong');
+ $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': syntax for function to be wrapped is wrong');
return false;
}
if (is_string($callable[0])) {
} else if ($callable instanceof \Closure) {
// we do not support creating code which wraps closures, as php does not allow to serialize them
if (!$buildIt) {
- Logger::instance()->errorLog('XML-RPC: ' . __METHOD__ . ': a closure can not be wrapped in generated source code');
+ $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': a closure can not be wrapped in generated source code');
return false;
}
}
if (!$exists) {
- Logger::instance()->errorLog('XML-RPC: ' . __METHOD__ . ': function to be wrapped is not defined: ' . $plainFuncName);
+ $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': function to be wrapped is not defined: ' . $plainFuncName);
return false;
}
if (is_array($callable)) {
$func = new \ReflectionMethod($callable[0], $callable[1]);
if ($func->isPrivate()) {
- Logger::instance()->errorLog('XML-RPC: ' . __METHOD__ . ': method to be wrapped is private: ' . $plainFuncName);
+ $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': method to be wrapped is private: ' . $plainFuncName);
return false;
}
if ($func->isProtected()) {
- Logger::instance()->errorLog('XML-RPC: ' . __METHOD__ . ': method to be wrapped is protected: ' . $plainFuncName);
+ $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': method to be wrapped is protected: ' . $plainFuncName);
return false;
}
if ($func->isConstructor()) {
- Logger::instance()->errorLog('XML-RPC: ' . __METHOD__ . ': method to be wrapped is the constructor: ' . $plainFuncName);
+ $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': method to be wrapped is the constructor: ' . $plainFuncName);
return false;
}
if ($func->isDestructor()) {
- Logger::instance()->errorLog('XML-RPC: ' . __METHOD__ . ': method to be wrapped is the destructor: ' . $plainFuncName);
+ $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': method to be wrapped is the destructor: ' . $plainFuncName);
return false;
}
if ($func->isAbstract()) {
- Logger::instance()->errorLog('XML-RPC: ' . __METHOD__ . ': method to be wrapped is abstract: ' . $plainFuncName);
+ $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': method to be wrapped is abstract: ' . $plainFuncName);
return false;
}
/// @todo add more checks for static vs. nonstatic?
if ($func->isInternal()) {
// Note: from PHP 5.1.0 onward, we will possibly be able to use invokeargs
// instead of getparameters to fully reflect internal php functions ?
- Logger::instance()->errorLog('XML-RPC: ' . __METHOD__ . ': function to be wrapped is internal: ' . $plainFuncName);
+ $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': function to be wrapped is internal: ' . $plainFuncName);
return false;
}
}
// since we are building source code for later use, if we are given an object instance,
- // we go out of our way and store a pointer to it in a static class var var...
+ // we go out of our way and store a pointer to it in a static class var...
if (is_array($callable) && is_object($callable[0])) {
self::$objHolder[$newFuncName] = $callable[0];
$innerCode .= "\$obj = PhpXmlRpc\\Wrapper::\$objHolder['$newFuncName'];\n";
* @param array $extraOptions see the docs for wrapPhpMethod for basic options, plus
* - string method_type 'static', 'nonstatic', 'all' and 'auto' (default); the latter will switch between static and non-static depending on whether $className is a class name or object instance
* - string method_filter a regexp used to filter methods to wrap based on their names
- * - string prefix used for the names of the xmlrpc methods created
- *
+ * - string prefix used for the names of the xmlrpc methods created.
+ * - string replace_class_name use to completely replace the class name with the prefix in the generated method names. e.g. instead of \Some\Namespace\Class.method use prefixmethod
* @return array|false false on failure
*/
public function wrapPhpClass($className, $extraOptions = array())
{
$methodFilter = isset($extraOptions['method_filter']) ? $extraOptions['method_filter'] : '';
$methodType = isset($extraOptions['method_type']) ? $extraOptions['method_type'] : 'auto';
- $prefix = isset($extraOptions['prefix']) ? $extraOptions['prefix'] : '';
$results = array();
$mList = get_class_methods($className);
(!$func->isStatic() && ($methodType == 'all' || $methodType == 'nonstatic' || ($methodType == 'auto' && is_object($className))))
) {
$methodWrap = $this->wrapPhpFunction(array($className, $mName), '', $extraOptions);
+
if ($methodWrap) {
- if (is_object($className)) {
- $realClassName = get_class($className);
- }else {
- $realClassName = $className;
- }
- $results[$prefix."$realClassName.$mName"] = $methodWrap;
+ $results[$this->generateMethodNameForClassMethod($className, $mName, $extraOptions)] = $methodWrap;
}
}
}
return $results;
}
+ /**
+ * @param string|object $className
+ * @param string $classMethod
+ * @param array $extraOptions
+ * @return string
+ */
+ protected function generateMethodNameForClassMethod($className, $classMethod, $extraOptions = array())
+ {
+ if (isset($extraOptions['replace_class_name']) && $extraOptions['replace_class_name']) {
+ return (isset($extraOptions['prefix']) ? $extraOptions['prefix'] : '') . $classMethod;
+ }
+
+ if (is_object($className)) {
+ $realClassName = get_class($className);
+ } else {
+ $realClassName = $className;
+ }
+ return (isset($extraOptions['prefix']) ? $extraOptions['prefix'] : '') . "$realClassName.$classMethod";
+ }
+
/**
* Given an xmlrpc client and a method name, register a php wrapper function
* that will call it and return results using native php types for both
return $results;
}
-
}
/**
$client->setDebug($debug);
$response = $client->send($req, $timeout, $protocol);
if ($response->faultCode()) {
- Logger::instance()->errorLog('XML-RPC: ' . __METHOD__ . ': could not retrieve method signature from remote server for method ' . $methodName);
+ $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': could not retrieve method signature from remote server for method ' . $methodName);
return false;
}
}
if (!is_array($mSig) || count($mSig) <= $sigNum) {
- Logger::instance()->errorLog('XML-RPC: ' . __METHOD__ . ': could not retrieve method signature nr.' . $sigNum . ' from remote server for method ' . $methodName);
+ $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': could not retrieve method signature nr.' . $sigNum . ' from remote server for method ' . $methodName);
return false;
}
$mDesc .= "* @param int \$debug when 1 (or 2) will enable debugging of the underlying {$prefix} call (defaults to 0)\n";
}
$plist = implode(', ', $plist);
- $mDesc .= '* @return ' . $this->xmlrpc2PhpType($mSig[0]) . " (or an {$namespace}Response obj instance if call fails)\n*/\n";
+ $mDesc .= '* @return {$namespace}Response|' . $this->xmlrpc2PhpType($mSig[0]) . " (an {$namespace}Response obj instance if call fails)\n*/\n";
$innerCode .= "\$res = \${$this_}client->send(\$req, $timeout, '$protocol');\n";
if ($decodeFault) {
$req = new $reqClass('system.listMethods');
$response = $client->send($req, $timeout, $protocol);
if ($response->faultCode()) {
- Logger::instance()->errorLog('XML-RPC: ' . __METHOD__ . ': could not retrieve method list from remote server');
+ $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': could not retrieve method list from remote server');
return false;
} else {
$mList = $decoder->decode($mList);
}
if (!is_array($mList) || !count($mList)) {
- Logger::instance()->errorLog('XML-RPC: ' . __METHOD__ . ': could not retrieve meaningful method list from remote server');
+ $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': could not retrieve meaningful method list from remote server');
return false;
} else {
}
$source .= $methodWrap['source'] . "\n";
} else {
- Logger::instance()->errorLog('XML-RPC: ' . __METHOD__ . ': will not create class method to wrap remote method ' . $mName);
+ $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': will not create class method to wrap remote method ' . $mName);
}
}
}
if ($allOK) {
return $xmlrpcClassName;
} else {
- Logger::instance()->errorLog('XML-RPC: ' . __METHOD__ . ': could not create class ' . $xmlrpcClassName . ' to wrap remote server ' . $client->server);
+ $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': could not create class ' . $xmlrpcClassName . ' to wrap remote server ' . $client->server);
return false;
}
} else {