Opened 15 years ago
Closed 15 years ago
#14933 closed defect (bug) (fixed)
IXR_Server->call() fails when calling method that uses __call()
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 3.1 | Priority: | normal |
| Severity: | normal | Version: | 3.0.1 |
| Component: | XML-RPC | Keywords: | has-patch |
| Focuses: | Cc: |
Description
I have a class in a plugin that uses PHP's magic method __call() to add some XMl-RPC callback methods, but IXR_Server->call() throws an IXR_Error as it uses method_exists() instead of is_callable().
method_exists() returns true only if a method is specifically defined (and is visible). is_callable() should be identical to method_exists(), except also return true on any classes with a visible __call() method.
Attachments (2)
Change History (15)
#1
@
15 years ago
- Component changed from General to XML-RPC
- Keywords has-patch added
- Resolution set to fixed
- Status changed from new to closed
#4
@
15 years ago
Any reason you aren't using the xmlrpc_methods filter to add new XML-RPC methods? I wrote a simple example on how to do this http://josephscott.org/archives/2008/11/adding-xml-rpc-methods-to-wordpress/
#6
@
15 years ago
I am using the xml_rpc filter (inside a class):
// lots of code snipped
class MyXmlRpc {
public function __construct() {
add_filter( 'xmlrpc_methods', array($this, 'add_new_xmlrpc_methods') );
}
public function add_new_xmlrpc_methods($methods) {
foreach ($this->methods as $method) {
$methods[$this->PREFIX . $method] = array($this, $method);
}
return $methods;
}
public function __call($method, $args) {
// ... does lots of things with $method and $args here
return call_user_func_array(array($this, $method), $args);
}
}
I think I even used your how to :-)
#7
@
15 years ago
Patch does not apply clean against trunk.
call() will only be called if a certain function does not exists by name. So I don't understand your code example, because if so, your call() implementation will fail by call_user_func_array() as $method on $this does not exists and that's why call() will be invoked.
Or do I see something wrong here?
#9
@
15 years ago
Thanks for the patch against trunk. I'm still learning SVN.
__call() is called when a method of that name is not visible. I.e. if you have private / protected methods with the same name. This means certain non-public methods can be run, but they are filtered through __call(). In my code I'm also modifying $method in some cases.
Some random examples of what is possible using __call() in this situation:
if (strpos($method, 'secure', 0) !== false) {
$this->authenticate();
}
if ($args[0] == 7 || date('D') == 'Mon') {
$method .= '_awesome';
$args[1]++;
}
I guess I could work around it by sending all XML-RPC requests to 1 method and adding an extra arg, but that's a bit messy.
#10
@
15 years ago
I had missed the protected / private members, my fault. is_callable() looks valid to me. +1.
Didn't mean to close, sorry