1<?php 2 3namespace dokuwiki\Extension; 4 5use dokuwiki\Remote\Api; 6use ReflectionException; 7use ReflectionMethod; 8 9/** 10 * Remote Plugin prototype 11 * 12 * Add functionality to the remote API in a plugin 13 */ 14abstract class RemotePlugin extends Plugin 15{ 16 17 private $api; 18 19 /** 20 * Constructor 21 */ 22 public function __construct() 23 { 24 $this->api = new Api(); 25 } 26 27 /** 28 * Get all available methods with remote access. 29 * 30 * By default it exports all public methods of a remote plugin. Methods beginning 31 * with an underscore are skipped. 32 * 33 * @return array Information about all provided methods. {@see dokuwiki\Remote\RemoteAPI}. 34 * @throws ReflectionException 35 */ 36 public function _getMethods() 37 { 38 $result = array(); 39 40 $reflection = new \ReflectionClass($this); 41 foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { 42 // skip parent methods, only methods further down are exported 43 $declaredin = $method->getDeclaringClass()->name; 44 if ($declaredin == 'dokuwiki\Extension\Plugin' || $declaredin == 'dokuwiki\Extension\RemotePlugin') continue; 45 $method_name = $method->name; 46 if (substr($method_name, 0, 1) == '_') continue; 47 48 // strip asterisks 49 $doc = $method->getDocComment(); 50 $doc = preg_replace( 51 array('/^[ \t]*\/\*+[ \t]*/m', '/[ \t]*\*+[ \t]*/m', '/\*+\/\s*$/m', '/\s*\/\s*$/m'), 52 array('', '', '', ''), 53 $doc 54 ); 55 56 // prepare data 57 $data = array(); 58 $data['name'] = $method_name; 59 $data['public'] = 0; 60 $data['doc'] = $doc; 61 $data['args'] = array(); 62 63 // get parameter type from doc block type hint 64 foreach ($method->getParameters() as $parameter) { 65 $name = $parameter->name; 66 $type = 'string'; // we default to string 67 if (preg_match('/^@param[ \t]+([\w|\[\]]+)[ \t]\$' . $name . '/m', $doc, $m)) { 68 $type = $this->cleanTypeHint($m[1]); 69 } 70 $data['args'][] = $type; 71 } 72 73 // get return type from doc block type hint 74 if (preg_match('/^@return[ \t]+([\w|\[\]]+)/m', $doc, $m)) { 75 $data['return'] = $this->cleanTypeHint($m[1]); 76 } else { 77 $data['return'] = 'string'; 78 } 79 80 // add to result 81 $result[$method_name] = $data; 82 } 83 84 return $result; 85 } 86 87 /** 88 * Matches the given type hint against the valid options for the remote API 89 * 90 * @param string $hint 91 * @return string 92 */ 93 protected function cleanTypeHint($hint) 94 { 95 $types = explode('|', $hint); 96 foreach ($types as $t) { 97 if (substr($t, -2) == '[]') { 98 return 'array'; 99 } 100 if ($t == 'boolean') { 101 return 'bool'; 102 } 103 if (in_array($t, array('array', 'string', 'int', 'double', 'bool', 'null', 'date', 'file'))) { 104 return $t; 105 } 106 } 107 return 'string'; 108 } 109 110 /** 111 * @return Api 112 */ 113 protected function getApi() 114 { 115 return $this->api; 116 } 117 118} 119