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