ILIAS  Release_4_2_x_branch Revision 61807
 All Data Structures Namespaces Files Functions Variables Groups Pages
Method.php
Go to the documentation of this file.
1 <?php
2 
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
4 
5 // LICENSE AGREEMENT. If folded, press za here to unfold and read license {{{
6 
40 // }}}
41 
42 // dependencies {{{
43 require_once 'XML/RPC2/Exception.php';
44 // }}}
45 
60 {
61  // {{{ properties
62 
68  private $_parameters;
69 
75  private $_returns ;
76 
82  private $_help;
83 
90 
96  private $_hidden;
97 
103  private $_name;
104 
111 
112  // }}}
113  // {{{ getInternalMethod()
114 
120  public function getInternalMethod()
121  {
122  return $this->_internalMethod;
123  }
124 
125  // }}}
126  // {{{ isHidden()
127 
133  public function isHidden()
134  {
135  return $this->_hidden;
136  }
137 
138  // }}}
139  // {{{ getName()
140 
146  public function getName()
147  {
148  return $this->_name;
149  }
150 
151  // }}}
152  // {{{ constructor
153 
160  public function __construct(ReflectionMethod $method, $defaultPrefix)
161  {
162  $hidden = false;
163  $docs = $method->getDocComment();
164  if (!$docs) {
165  $hidden = true;
166  }
167  $docs = explode("\n", $docs);
168 
169  $parameters = array();
170  $methodname = null;
171  $returns = 'mixed';
172  $shortdesc = '';
173  $paramcount = -1;
174  $prefix = $defaultPrefix;
175 
176  // Extract info from Docblock
177  $paramDocs = array();
178  foreach ($docs as $i => $doc) {
179  $doc = trim($doc, " \r\t/*");
180  if (strlen($doc) && strpos($doc, '@') !== 0) {
181  if ($shortdesc) {
182  $shortdesc .= "\n";
183  }
184  $shortdesc .= $doc;
185  continue;
186  }
187  if (strpos($doc, '@xmlrpc.hidden') === 0) {
188  $hidden = true;
189  }
190  if ((strpos($doc, '@xmlrpc.prefix') === 0) && preg_match('/@xmlrpc.prefix( )*(.*)/', $doc, $matches)) {
191  $prefix = $matches[2];
192  }
193  if ((strpos($doc, '@xmlrpc.methodname') === 0) && preg_match('/@xmlrpc.methodname( )*(.*)/', $doc, $matches)) {
194  $methodname = $matches[2];
195  }
196  if (strpos($doc, '@param') === 0) { // Save doctag for usage later when filling parameters
197  $paramDocs[] = $doc;
198  }
199 
200  if (strpos($doc, '@return') === 0) {
201  $param = preg_split("/\s+/", $doc);
202  if (isset($param[1])) {
203  $param = $param[1];
204  $returns = $param;
205  }
206  }
207  }
208  $this->_numberOfRequiredParameters = $method->getNumberOfRequiredParameters(); // we don't use isOptional() because of bugs in the reflection API
209  // Fill in info for each method parameter
210  foreach ($method->getParameters() as $parameterIndex => $parameter) {
211  // Parameter defaults
212  $newParameter = array('type' => 'mixed');
213 
214  // Attempt to extract type and doc from docblock
215  if (array_key_exists($parameterIndex, $paramDocs) &&
216  preg_match('/@param\s+(\S+)(\s+(.+))/', $paramDocs[$parameterIndex], $matches)) {
217  if (strpos($matches[1], '|')) {
218  $newParameter['type'] = XML_RPC2_Server_Method::_limitPHPType(explode('|', $matches[1]));
219  } else {
220  $newParameter['type'] = XML_RPC2_Server_Method::_limitPHPType($matches[1]);
221  }
222  $tmp = '$' . $parameter->getName() . ' ';
223  if (strpos($matches[2], '$' . $tmp) === 0) {
224  $newParameter['doc'] = $matches[2];
225  } else {
226  // The phpdoc comment is something like "@param string $param description of param"
227  // Let's keep only "description of param" as documentation (remove $param)
228  $newParameter['doc'] = substr($matches[2], strlen($tmp));
229  }
230  }
231 
232  $parameters[$parameter->getName()] = $newParameter;
233  }
234 
235  if (is_null($methodname)) {
236  $methodname = $prefix . $method->getName();
237  }
238 
239  $this->_internalMethod = $method->getName();
240  $this->_parameters = $parameters;
241  $this->_returns = $returns;
242  $this->_help = $shortdesc;
243  $this->_name = $methodname;
244  $this->_hidden = $hidden;
245  }
246 
247  // }}}
248  // {{{ matchesSignature()
249 
260  public function matchesSignature($methodName, $callParams)
261  {
262  if ($methodName != $this->_name) return false;
263  if (count($callParams) < $this->_numberOfRequiredParameters) return false;
264  if (count($callParams) > $this->_parameters) return false;
265  $paramIndex = 0;
266  foreach($this->_parameters as $param) {
267  $paramIndex++;
268  if ($paramIndex <= $this->_numberOfRequiredParameters) {
269  // the parameter is not optional
270  $callParamType = XML_RPC2_Server_Method::_limitPHPType(gettype($callParams[$paramIndex-1]));
271  if ((!($param['type'] == 'mixed')) and ($param['type'] != $callParamType)) {
272  return false;
273  }
274  }
275  }
276  return true;
277  }
278 
279  // }}}
280  // {{{ getHTMLSignature()
281 
287  public function getHTMLSignature()
288  {
289  $name = $this->_name;
290  $returnType = $this->_returns;
291  $result = "<span class=\"type\">($returnType)</span> ";
292  $result .= "<span class=\"name\">$name</span>";
293  $result .= "<span class=\"other\">(</span>";
294  $first = true;
295  $nbr = 0;
296  while (list($name, $parameter) = each($this->_parameters)) {
297  $nbr++;
298  if ($nbr == $this->_numberOfRequiredParameters + 1) {
299  $result .= "<span class=\"other\"> [ </span>";
300  }
301  if ($first) {
302  $first = false;
303  } else {
304  $result .= ', ';
305  }
306  $type = $parameter['type'];
307  $result .= "<span class=\"paratype\">($type) </span>";
308  $result .= "<span class=\"paraname\">$name</span>";
309  }
310  reset($this->_parameters);
311  if ($nbr > $this->_numberOfRequiredParameters) {
312  $result .= "<span class=\"other\"> ] </span>";
313  }
314  $result .= "<span class=\"other\">)</span>";
315  return $result;
316  }
317 
318  // }}}
319  // {{{ autoDocument()
323  public function autoDocument()
324  {
325  $name = $this->getName();
326  $signature = $this->getHTMLSignature();
327  $id = md5($name);
328  $help = nl2br(htmlentities($this->_help));
329  print " <h3><a name=\"$id\">$signature</a></h3>\n";
330  print " <p><b>Description :</b></p>\n";
331  print " <div class=\"description\">\n";
332  print " $help\n";
333  print " </div>\n";
334  if (count($this->_parameters)>0) {
335  print " <p><b>Parameters : </b></p>\n";
336  if (count($this->_parameters)>0) {
337  print " <table>\n";
338  print " <tr><td><b>Type</b></td><td><b>Name</b></td><td><b>Documentation</b></td></tr>\n";
339  while (list($name, $parameter) = each($this->_parameters)) {
340  $type = $parameter['type'];
341  $doc = htmlentities($parameter['doc']);
342  print " <tr><td>$type</td><td>$name</td><td>$doc</td></tr>\n";
343  }
344  reset($this->_parameters);
345  print " </table>\n";
346  }
347  }
348  }
349 
350  // }}}
351  // {{{ _limitPHPType()
358  private static function _limitPHPType($type)
359  {
360  $tmp = strtolower($type);
361  $convertArray = array(
362  'int' => 'integer',
363  'i4' => 'integer',
364  'integer' => 'integer',
365  'string' => 'string',
366  'str' => 'string',
367  'char' => 'string',
368  'bool' => 'boolean',
369  'boolean' => 'boolean',
370  'array' => 'array',
371  'float' => 'double',
372  'double' => 'double',
373  'array' => 'array',
374  'struct' => 'array',
375  'assoc' => 'array',
376  'structure' => 'array',
377  'datetime' => 'mixed',
378  'datetime.iso8601' => 'mixed',
379  'iso8601' => 'mixed',
380  'base64' => 'string'
381  );
382  if (isset($convertArray[$tmp])) {
383  return $convertArray[$tmp];
384  }
385  return 'mixed';
386  }
387 
388 }
389 
390 ?>