* @copyright Ryan Uber * @link https://github.com/ryanuber/veneer * @license http://opensource.org/licenses/MIT * @package veneer * @category api * * MIT LICENSE * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ namespace veneer\endpoint\swagger; /** * An endpoint to massage typical veneer documentation data normally * exposed via the HTTP OPTIONS method into a format consumable by the * swagger specification. This allows you to expose interactive * documentation using swagger-ui, without writing any additional code * or even modifying any of your existing endpoints. Just drop this in * and point swagger-ui at it! */ class v1 extends \veneer\call { public $get = array( '/' => array( 'function' => 'swagger', 'output_handler' => 'json' ), '/fetch' => array( 'function' => 'fetch', 'output_handler' => 'json' ) ); public function swagger($args) { $apis = array(); foreach (\veneer\util::get_endpoints() as $version => $endpoints) { foreach ($endpoints as $endpoint) { $endpoint != 'swagger' && $apis[] = array( 'path' => "/v1/swagger/fetch?endpoint=/{$version}/{$endpoint}", 'description' => '' ); } } return $this->response->set(array( 'apiVersion' => '0.1', 'swaggerVersion' => '1.1', 'basePath' => 'http'.(array_key_exists('HTTPS', $_SERVER)?'s':'').'://'.$_SERVER['HTTP_HOST'], 'apis' => $apis ), 200); } public function fetch($args) { $docs = \veneer\util::get_documentation(); list($null, $version, $endpoint) = explode('/', $args['endpoint']); $out = $docs[$endpoint][$version]; $result = array( 'apiVersion' => 'v1', 'swaggerVersion' => '1.1', 'basePath' => 'http'.(array_key_exists('HTTPS', $_SERVER)?'s':'').'://'.$_SERVER['HTTP_HOST'], 'resourcePath' => $args['endpoint'], 'apis' => array(), 'models' => array() ); foreach ($out as $method => $apis) { foreach ($apis as $api => $data) { is_array($data) || $data = array(); array_key_exists('parameters', $data) || $data['parameters'] = array(); $current = array(); $params = array(); foreach (explode('/', $api) as $part) { if (preg_match('~^:([^/]+)$~', $part, $matches)) { $param = array( 'name' => $matches[1], 'paramType' => 'path', 'dataType' => 'string', 'required' => true ); if (array_key_exists($matches[1], $data['parameters'])) { $param = array_merge($param, $data['parameters'][$matches[1]]); } array_push($params, $param); } } $route = preg_replace('~/:([^/]+)~', '/{$1}', $args['endpoint'].$api); /** * veneer-swagger can't support route splats, because they do not describe * a concrete endpoint route. */ if (strpos($route, '*')) { continue; } if (is_array($data) && is_array($data['parameters'])) { foreach ($data['parameters'] as $param_name => $param_data) { $param = array(); $param['name'] = $param_name; $param['dataType'] = 'string'; $param['paramType'] = 'query'; $found = false; foreach ($params as $p) { if ($p['name'] == $param_name) { $found = true; } } if (!$found) { array_push($params, array_merge($param, $param_data)); } } } $current['path'] = $route; $current['description'] = ''; if (array_key_exists('description', $data)) { $current['description'] = str_replace( "\n", '
', $data['description'] ); } $current['operations'][] = array( 'httpMethod' => strtoupper($method), 'nickname' => uniqid(), 'notes' => $current['description'], 'summary' => (array_key_exists('summary', $data) ? $data['summary'] : ''), 'parameters' => $params, 'errorResponses' => array() ); array_push($result['apis'], $current); } } return $this->response->set($result, 200); } } ?>