Opened 14 years ago
Closed 14 years ago
#14933 closed defect (bug) (fixed)
IXR_Server->call() fails when calling method that uses __call()
Reported by: | dave1010 | Owned by: | westi |
---|---|---|---|
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
@
14 years ago
- Component changed from General to XML-RPC
- Keywords has-patch added
- Resolution set to fixed
- Status changed from new to closed
#4
@
14 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
@
14 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
@
14 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
@
14 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
@
14 years ago
I had missed the protected / private members, my fault. is_callable()
looks valid to me. +1.
Didn't mean to close, sorry