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