Upgrade branch 3.0 of RESTLER (still 3.0.0 RC6)

This upgrade Swagger from 1.2 to 2.0
This commit is contained in:
Laurent Destailleur 2017-11-17 12:54:49 +01:00
parent a5a9b9b23f
commit f33b5067ad
53 changed files with 30276 additions and 2554 deletions

View File

@ -116,4 +116,15 @@ to get
if ($className == 'Luracast\Restler\string') return;
if ($className == 'Luracast\Restler\mixed') return;
...
Change also file Luracast/Restler/explorer/index.html
+With swagger 2:
* Add line into Util.php to complete function
public static function getShortName($className)
{
// @CHANGE LDR
if (! is_string($className)) return;
//var_dump($className);

View File

@ -307,10 +307,10 @@ class AutoLoader
*/
private function alias($className, $currentClass)
{
// @CHANGE LDR
// @CHANGE LDR
if ($className == 'Luracast\Restler\string') return;
if ($className == 'Luracast\Restler\mixed') return;
if ($className != $currentClass
&& false !== strpos($className, $currentClass))
if (!class_exists($currentClass, false)

View File

@ -505,7 +505,7 @@ class CommentParser
$data = explode('|', $data);
$r['type'] = count($data) == 1 ? $data[0] : $data;
}
if (isset($r['type']) && is_string($r['type']) && Text::endsWith($r['type'], '[]')) {
if (isset($r['type']) && Text::endsWith($r['type'], '[]')) {
$r[static::$embeddedDataName]['type'] = substr($r['type'], 0, -2);
$r['type'] = 'array';
}

View File

@ -13,7 +13,7 @@ namespace Luracast\Restler\Data;
* @link http://luracast.com/products/restler/
* @version 3.0.0rc6
*/
class Object
class Obj
{
/**
* @var bool|string|callable

View File

@ -454,7 +454,10 @@ class Validator implements iValidate
}
if (isset ($info->choice)) {
if (is_array($input)) {
if (!$info->required && empty($input)) {
//since its optional, and empty let it pass.
$input = null;
} elseif (is_array($input)) {
foreach ($input as $i) {
if (!in_array($i, $info->choice)) {
$error .= ". Expected one of (" . implode(',', $info->choice) . ").";
@ -468,6 +471,11 @@ class Validator implements iValidate
}
if (method_exists($class = get_called_class(), $info->type) && $info->type != 'validate') {
if(!$info->required && empty($input))
{
//optional parameter with a empty value assume null
return null;
}
try {
return call_user_func("$class::$info->type", $input, $info);
} catch (Invalid $e) {
@ -669,4 +677,4 @@ class Validator implements iValidate
throw $e;
}
}
}
}

View File

@ -44,7 +44,7 @@ class EventDispatcher
public function __call($eventName, $params)
{
if (0 === strpos($eventName, 'on')) {
if (!@is_array($this->listeners[$eventName]))
if (!isset($this->listeners[$eventName]) || !is_array($this->listeners[$eventName]))
$this->listeners[$eventName] = array();
$this->listeners[$eventName][] = $params[0];
}

View File

@ -16,7 +16,12 @@ use Luracast\Restler\Scope;
*/
class Explorer implements iProvideMultiVersionApi
{
const SWAGGER_VERSION = '1.2';
const SWAGGER = '2.0';
/**
* @var array http schemes supported. http or https or both http and https
*/
public static $schemes = array();
/**
* @var bool should protected resources be shown to unauthenticated users?
*/
@ -70,17 +75,17 @@ class Explorer implements iProvideMultiVersionApi
*/
public static $dataTypeAlias = array(
//'string' => 'string',
'int' => 'integer',
'number' => 'number',
'float' => array('number', 'float'),
'bool' => 'boolean',
'int' => 'integer',
'number' => 'number',
'float' => array('number', 'float'),
'bool' => 'boolean',
//'boolean' => 'boolean',
//'NULL' => 'null',
'array' => 'array',
'array' => 'array',
//'object' => 'object',
'stdClass' => 'object',
'mixed' => 'string',
'date' => array('string', 'date'),
'mixed' => 'string',
'date' => array('string', 'date'),
'datetime' => array('string', 'date-time'),
);
@ -89,9 +94,9 @@ class Explorer implements iProvideMultiVersionApi
* protected api
*/
public static $apiDescriptionSuffixSymbols = array(
0 => '&nbsp; <i class="fa fa-lg fa-unlock-alt"></i>', //public api
1 => '&nbsp; <i class="fa fa-lg fa-adjust"></i>', //hybrid api
2 => '&nbsp; <i class="fa fa-lg fa-lock"></i>', //protected api
0 => ' 🔓', //'&nbsp; <i class="fa fa-lg fa-unlock-alt"></i>', //public api
1 => ' ◑', //'&nbsp; <i class="fa fa-lg fa-adjust"></i>', //hybrid api
2 => ' 🔐', //'&nbsp; <i class="fa fa-lg fa-lock"></i>', //protected api
);
protected $models = array();
@ -100,27 +105,23 @@ class Explorer implements iProvideMultiVersionApi
*/
protected $_fullDataRequested = false;
protected $crud = array(
'POST' => 'create',
'GET' => 'retrieve',
'PUT' => 'update',
'POST' => 'create',
'GET' => 'retrieve',
'PUT' => 'update',
'DELETE' => 'delete',
'PATCH' => 'partial update'
'PATCH' => 'partial update'
);
protected static $prefixes = array(
'get' => 'retrieve',
'index' => 'list',
'post' => 'create',
'put' => 'update',
'patch' => 'modify',
'get' => 'retrieve',
'index' => 'list',
'post' => 'create',
'put' => 'update',
'patch' => 'modify',
'delete' => 'remove',
);
protected $_authenticated = false;
protected $cacheName = '';
public function __construct()
{
}
/**
* Serve static files for exploring
@ -131,7 +132,7 @@ class Explorer implements iProvideMultiVersionApi
*/
public function get()
{
if (func_num_args() > 1 && func_get_arg(0) == 'resources') {
if (func_num_args() > 1 && func_get_arg(0) == 'swagger') {
/**
* BUGFIX:
* If we use common resourcePath (e.g. $r->addAPIClass([api-class], 'api/shop')), than we must determine resource-ID of e.g. 'api/shop'!
@ -141,6 +142,7 @@ class Explorer implements iProvideMultiVersionApi
array_shift($arguments);
// create ID
$id = implode('/', $arguments);
return $this->getResources($id);
}
$filename = implode('/', func_get_args());
@ -161,125 +163,75 @@ class Explorer implements iProvideMultiVersionApi
) {
$filename .= '.js';
}
PassThrough::file(__DIR__ . '/explorer/' . (empty($filename) ? 'index.html' : $filename), false, 0); //60 * 60 * 24);
PassThrough::file(__DIR__ . '/explorer/' . (empty($filename) ? 'index.html' : $filename), false,
0); //60 * 60 * 24);
}
public function resources()
/**
* @return stdClass
*/
public function swagger()
{
$r = new stdClass();
$r->apiVersion = (string)$this->restler->getRequestedApiVersion();
$r->swaggerVersion = static::SWAGGER_VERSION;
$r->apis = $this->apis($r->apiVersion);
$r->authorizations = $this->authorizations();
$r->info = array_filter(get_class_vars(static::$infoClass));
return $r;
}
$version = (string)$this->restler->getRequestedApiVersion();
$r->swagger = static::SWAGGER;
public function getResources($id)
{
$r = new stdClass();
$r->apiVersion = (string)$this->restler->getRequestedApiVersion();
$r->swaggerVersion = static::SWAGGER_VERSION;
$r->basePath = $this->restler->getBaseUrl();
$r->resourcePath = "/$id";
$r->apis = $this->apis($r->apiVersion, $id);
$r->models = (object)$this->models;
$info = parse_url($this->restler->getBaseUrl());
$r->host = $info['host'];
if (isset($info['port'])) {
$r->host .= ':' . $info['port'];
}
$r->basePath = isset($info['path']) ? $info['path'] : '';
if (!empty(static::$schemes)) {
$r->schemes = static::$schemes;
}
$r->produces = $this->restler->getWritableMimeTypes();
$r->consumes = $this->restler->getReadableMimeTypes();
$r->authorizations = $this->authorizations();
$r->paths = $this->paths($version);
$r->definitions = (object)$this->models;
$r->securityDefinitions = $this->securityDefinitions();
$r->info = compact('version') + array_filter(get_class_vars(static::$infoClass));
return $r;
}
private function apis($version = 1, $resource = false)
private function paths($version = 1)
{
$map = Routes::findAll(static::$excludedPaths + array($this->base()), static::$excludedHttpMethods, $version);
$r = array();
$a = array();
$paths = array();
foreach ($map as $path => $data) {
$route = $data[0]['route'];
$access = $data[0]['access'];
if ($access && !Text::contains($path, '{')) {
$r[] = array(
'path' => empty($path) ? '/root' : "/$path",
//'description' => ''
//TODO: Util::nestedValue($route, 'metadata', 'classDescription') ? : ''
);
}
if (static::$hideProtected && !$access)
if (static::$hideProtected && !$access) {
continue;
$grouper = array();
}
foreach ($data as $item) {
$route = $item['route'];
$access = $item['access'];
if (static::$hideProtected && !$access)
if (static::$hideProtected && !$access) {
continue;
}
$url = $route['url'];
if (isset($grouper[$url])) {
$grouper[$url]['operations'][] = $this->operation($route);
} else {
$api = array(
'path' => "/$url",
'description' =>
Util::nestedValue($route, 'metadata', 'classDescription') ? : '',
'operations' => array($this->operation($route))
);
static::$groupOperations
? $grouper[$url] = $api
: $a[$path][] = $api;
}
$paths["/$url"][strtolower($route['httpMethod'])] = $this->operation($route);
}
if (!empty($grouper)) {
$a[$path] = array_values($grouper);
// sort REST-endpoints by path
foreach ($a as & $b) {
usort(
$b,
function ($x, $y) {
return $x['path'] > $y['path'];
}
);
}
} else {
$order = array(
'GET' => 1,
'POST' => 2,
'PUT' => 3,
'PATCH' => 4,
'DELETE' => 5
);
foreach ($a as & $b) {
usort(
$b,
function ($x, $y) use ($order) {
return
$x['operations'][0]->method ==
$y['operations'][0]->method
? $x['path'] > $y['path']
: $order[$x['operations'][0]->method] >
$order[$y['operations'][0]->method];
}
}
);
}
}
}
if (false !== $resource) {
if ($resource == 'root') $resource = '';
if (isset($a[$resource])) return $a[$resource];
}
return $r;
return $paths;
}
private function operation($route)
{
$r = new stdClass();
$r->method = $route['httpMethod'];
$r->nickname = $this->nickname($route);
$m = $route['metadata'];
$r->operationId = $this->operationId($route);
$base = strtok($route['url'], '/');
if (empty($base)) {
$base = 'root';
}
$r->tags = array($base);
$r->parameters = $this->parameters($route);
$m = $route['metadata'];
$r->summary = isset($m['description'])
? $m['description']
@ -287,13 +239,18 @@ class Explorer implements iProvideMultiVersionApi
$r->summary .= $route['accessLevel'] > 2
? static::$apiDescriptionSuffixSymbols[2]
: static::$apiDescriptionSuffixSymbols[$route['accessLevel']];
$r->notes = isset($m['longDescription'])
$r->description = isset($m['longDescription'])
? $m['longDescription']
: '';
$r->responseMessages = $this->responseMessages($route);
$r->responses = $this->responses($route);
//TODO: avoid hard coding. Properly detect security
if ($route['accessLevel']) {
$r->security = array(array('api_key' => array()));
}
/*
$this->setType(
$r,
new ValidationInfo(Util::nestedValue($m, 'return') ? : array())
new ValidationInfo(Util::nestedValue($m, 'return') ?: array())
);
if (is_null($r->type) || 'mixed' == $r->type) {
$r->type = 'array';
@ -302,7 +259,7 @@ class Explorer implements iProvideMultiVersionApi
} elseif (Text::contains($r->type, '|')) {
$r->type = 'array';
}
*/
//TODO: add $r->authorizations
//A list of authorizations required to execute this operation. While not mandatory, if used, it overrides
//the value given at the API Declaration's authorizations. In order to completely remove API Declaration's
@ -324,8 +281,9 @@ class Explorer implements iProvideMultiVersionApi
$info = new ValidationInfo($param);
$description = isset($param['description']) ? $param['description'] : '';
if ('body' == $info->from) {
if ($info->required)
if ($info->required) {
$required = true;
}
$param['description'] = $description;
$children[] = $param;
} else {
@ -341,31 +299,31 @@ class Explorer implements iProvideMultiVersionApi
if (empty($firstChild['children'])) {
$description = $firstChild['description'];
} else {
$description = '<section class="body-param">';
$description = ''; //'<section class="body-param">';
foreach ($firstChild['children'] as $child) {
$description .= isset($child['required']) && $child['required']
? '<strong>' . $child['name'] . '</strong> (required)<br/>'
: $child['name'] . '<br/>';
? '**' . $child['name'] . '** (required) '.PHP_EOL
: $child['name'] . ' '.PHP_EOL;
}
$description .= '</section>';
//$description .= '</section>';
}
$r[] = $this->parameter(new ValidationInfo($firstChild), $description);
} else {
$description = '<section class="body-param">';
$description = ''; //'<section class="body-param">';
foreach ($children as $child) {
$description .= isset($child['required']) && $child['required']
? '<strong>' . $child['name'] . '</strong> (required)<br/>'
: $child['name'] . '<br/>';
$description .= isset($child['required']) && $child['required']
? '**' . $child['name'] . '** (required) '.PHP_EOL
: $child['name'] . ' '.PHP_EOL;
}
$description .= '</section>';
//$description .= '</section>';
//lets group all body parameters under a generated model name
$name = $this->nameModel($route);
$name = $this->modelName($route);
$r[] = $this->parameter(
new ValidationInfo(array(
'name' => $name,
'type' => $name,
'from' => 'body',
'name' => $name,
'type' => $name,
'from' => 'body',
'required' => $required,
'children' => $children
)),
@ -373,196 +331,224 @@ class Explorer implements iProvideMultiVersionApi
);
}
}
return $r;
}
private function parameter(ValidationInfo $info, $description = '')
{
$p = new stdClass();
if(isset($info->rules['model'])){
$info->type = $info->rules['model'];
if (isset($info->rules['model'])) {
//$info->type = $info->rules['model'];
}
$p->name = $info->name;
$this->setType($p, $info);
if (empty($info->children) || $info->type != 'array') {
//primitives
if ($info->default)
if ($info->default) {
$p->defaultValue = $info->default;
if ($info->choice)
}
if ($info->choice) {
$p->enum = $info->choice;
if ($info->min)
}
if ($info->min) {
$p->minimum = $info->min;
if ($info->max)
}
if ($info->max) {
$p->maximum = $info->max;
}
//TODO: $p->items and $p->uniqueItems boolean
}
$p->description = $description;
$p->paramType = $info->from; //$info->from == 'body' ? 'form' : $info->from;
$p->in = $info->from; //$info->from == 'body' ? 'form' : $info->from;
$p->required = $info->required;
$p->allowMultiple = false;
//$p->allowMultiple = false;
if (isset($p->{'$ref'})) {
$p->schema = (object)array('$ref' => ($p->{'$ref'}));
unset($p->{'$ref'});
}
return $p;
}
private function responseMessages(array $route)
private function responses(array $route)
{
$r = array();
$code = '200';
$r = array(
$code => (object)array(
'description' => 'Success',
'schema' => new stdClass()
)
);
$return = Util::nestedValue($route, 'metadata', 'return');
if (!empty($return)) {
$this->setType($r[$code]->schema, new ValidationInfo($return));
}
if (is_array($throws = Util::nestedValue($route, 'metadata', 'throws'))) {
foreach ($throws as $message) {
$m = (object)$message;
//TODO: add $m->responseModel from composer class
$r[] = $m;
$r[$message['code']] = array('description' => $message['message']);
}
}
return $r;
}
private function model($type, array $children)
{
/**
* Bugfix:
* If we use namespaces, than the model will not be correct, if we use a short name for the type!
*
* Example (phpDoc/annotations in API-class, which uses custom domain-model with namespace):
* @param Car $car {@from body} {@type Aoe\RestServices\Domain\Model\Car}
* @return Car {@type Aoe\RestServices\Domain\Model\Car}
* Than, the model (in swagger-spec) must also be 'Aoe\RestServices\Domain\Model\Car' and not 'Car'
*
* When we use namespaces, than we must use the @type-annotation, otherwise the automatic reconstitution
* from request-data (e.g. when it is a POST-request) to custom domain-model-object will not work!
*
* Summary:
* - When we use no namespaces, than the type would not be changed, if we would call 'Util::getShortName'
* - When we use namespaces, than the model will not be correct, if we would call 'Util::getShortName'
* ...so this method-call is either needless or will create a bug/error
*/
//$type = Util::getShortName($type);
if (isset($this->models[$type]))
if (isset($this->models[$type])) {
return $this->models[$type];
}
$r = new stdClass();
$r->id = $type;
$r->description = "$type Model"; //TODO: enhance this on Router
$r->required = array();
$r->properties = array();
$required = array();
foreach ($children as $child) {
$info = new ValidationInfo($child);
$p = new stdClass();
$this->setType($p, $info);
$p->description = isset($child['description']) ? $child['description'] : '';
if ($info->default)
if ($info->default) {
$p->defaultValue = $info->default;
if ($info->choice)
}
if ($info->choice) {
$p->enum = $info->choice;
if ($info->min)
}
if ($info->min) {
$p->minimum = $info->min;
if ($info->max)
}
if ($info->max) {
$p->maximum = $info->max;
if ($info->required)
$r->required[] = $info->name;
}
if ($info->required) {
$required[] = $info->name;
}
$r->properties[$info->name] = $p;
}
if (!empty($required)) {
$r->required = $required;
}
//TODO: add $r->subTypes https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#527-model-object
//TODO: add $r->discriminator https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#527-model-object
$this->models[$type] = $r;
return $r;
}
private function setType(&$object, ValidationInfo $info)
{
//TODO: proper type management
$type = Util::getShortName($info->type);
if ($info->type == 'array') {
$object->type = 'array';
if ($info->children) {
$this->model($info->contentType, $info->children);
$contentType = Util::getShortName($info->contentType);
$model = $this->model($contentType, $info->children);
$object->items = (object)array(
'$ref' => $info->contentType
'$ref' => "#/definitions/$contentType"
);
} elseif ($info->contentType && $info->contentType == 'associative') {
unset($info->contentType);
$this->model($info->type = 'Object', array(
array(
'name' => 'property',
'type' => 'string',
'default' => '',
'required' => false,
'name' => 'property',
'type' => 'string',
'default' => '',
'required' => false,
'description' => ''
)
));
} elseif ($info->contentType && $info->contentType != 'indexed') {
$object->items = (object)array(
'type' => $info->contentType
);
if (is_string($info->contentType) && $t = Util::nestedValue(static::$dataTypeAlias,
strtolower($info->contentType))) {
if (is_array($t)) {
$object->items = (object)array(
'type' => $t[0],
'format' => $t[1],
);
} else {
$object->items = (object)array(
'type' => $t,
);
}
} else {
$contentType = Util::getShortName($info->contentType);
$object->items = (object)array(
'$ref' => "#/definitions/$contentType"
);
}
} else {
$object->items = (object)array(
'type' => 'string'
);
}
} elseif ($info->children) {
$this->model($info->type, $info->children);
$this->model($type, $info->children);
$object->{'$ref'} = "#/definitions/$type";
} elseif (is_string($info->type) && $t = Util::nestedValue(static::$dataTypeAlias, strtolower($info->type))) {
if (is_array($t)) {
list($info->type, $object->format) = $t;
$object->type = $t[0];
$object->format = $t[1];
} else {
$info->type = $t;
$object->type = $t;
}
} else {
$info->type = 'string';
$object->type = 'string';
}
$object->type = $info->type;
$has64bit = PHP_INT_MAX > 2147483647;
if ($object->type == 'integer') {
$object->format = $has64bit
? 'int64'
: 'int32';
} elseif ($object->type == 'number') {
$object->format = $has64bit
? 'double'
: 'float';
if (isset($object->type)) {
if ($object->type == 'integer') {
$object->format = $has64bit
? 'int64'
: 'int32';
} elseif ($object->type == 'number') {
$object->format = $has64bit
? 'double'
: 'float';
}
}
}
private function nickname(array $route)
private function operationId(array $route)
{
static $hash = array();
$id = $route['httpMethod'] . ' ' . $route['url'];
if (isset($hash[$id])) {
return $hash[$id];
}
$class = Util::getShortName($route['className']);
$method = $route['methodName'];
if (isset(static::$prefixes[$method])) {
$method = static::$prefixes[$method];
$method = static::$prefixes[$method] . $class;
} else {
$method = str_replace(
array_keys(static::$prefixes),
array_values(static::$prefixes),
$method
);
$method = lcfirst($class) . ucfirst($method);
}
while (isset($hash[$method]) && $route['url'] != $hash[$method]) {
//create another one
$method .= '_';
}
$hash[$method] = $route['url'];
$hash[$id] = $method;
return $method;
}
private function nameModel(array $route)
private function modelName(array $route)
{
static $hash = array();
$count = 1;
//$name = str_replace('/', '-', $route['url']) . 'Model';
$name = $route['className'] . 'Model';
while (isset($hash[$name . $count])) {
//create another one
$count++;
}
$name .= $count;
$hash[$name] = $route['url'];
return $name;
return $this->operationId($route) . 'Model';
}
private function authorizations()
private function securityDefinitions()
{
$r = new stdClass();
$r->apiKey = (object)array(
$r->api_key = (object)array(
'type' => 'apiKey',
'passAs' => 'query',
'keyname' => 'api_key',
'name' => 'api_key',
'in' => 'query',
);
return $r;
}

View File

@ -2,16 +2,22 @@
/**
* Class ExplorerInfo
* @package Luracast\Restler
*
* @package Luracast\Restler
*
* @version 3.0.0rc6
*/
class ExplorerInfo
{
public static $title = 'Restler API Explorer';
public static $description = 'Live API Documentation';
public static $termsOfServiceUrl = null;
public static $contact = 'arul@luracast.com';
public static $license = 'LGPL-2.1';
public static $licenseUrl = 'https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html';
public static $termsOfService = null;
public static $contact = array(
'name' => 'Restler Support',
'url' => 'luracast.com/products/restler',
'email' => 'arul@luracast.com',
);
public static $license = array(
'name' => 'LGPL-2.1',
'url' => 'https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html',
);
}

View File

@ -2,7 +2,7 @@
namespace Luracast\Restler\Format;
use Luracast\Restler\Data\Object;
use Luracast\Restler\Data\Obj;
use Luracast\Restler\RestException;
/**
@ -44,10 +44,10 @@ class CsvFormat extends Format implements iDecodeStream
*/
public function encode($data, $humanReadable = false)
{
$char = Object::$separatorChar;
Object::$separatorChar = false;
$data = Object::toArray($data);
Object::$separatorChar = $char;
$char = Obj::$separatorChar;
Obj::$separatorChar = false;
$data = Obj::toArray($data);
Obj::$separatorChar = $char;
if (is_array($data) && array_values($data) == $data) {
//if indexed array
$lines = array();
@ -109,10 +109,10 @@ class CsvFormat extends Format implements iDecodeStream
while (($row = static::getRow(array_shift($lines), $keys)) !== FALSE)
$decoded [] = $row;
$char = Object::$separatorChar;
Object::$separatorChar = false;
$decoded = Object::toArray($decoded);
Object::$separatorChar = $char;
$char = Obj::$separatorChar;
Obj::$separatorChar = false;
$decoded = Obj::toArray($decoded);
Obj::$separatorChar = $char;
return $decoded;
}
@ -172,10 +172,10 @@ class CsvFormat extends Format implements iDecodeStream
while (($row = static::getRow(stream_get_line($stream, 0, PHP_EOL), $keys)) !== FALSE)
$decoded [] = $row;
$char = Object::$separatorChar;
Object::$separatorChar = false;
$decoded = Object::toArray($decoded);
Object::$separatorChar = $char;
$char = Obj::$separatorChar;
Obj::$separatorChar = false;
$decoded = Obj::toArray($decoded);
Obj::$separatorChar = $char;
return $decoded;
}
}

View File

@ -11,7 +11,7 @@ use Illuminate\View\Engines\EngineResolver;
use Illuminate\View\Factory;
use Illuminate\View\FileViewFinder;
use Illuminate\View\View;
use Luracast\Restler\Data\Object;
use Luracast\Restler\Data\Obj;
use Luracast\Restler\Defaults;
use Luracast\Restler\RestException;
use Luracast\Restler\Restler;
@ -315,7 +315,7 @@ class HtmlFormat extends DependentFormat
$error = $success ? null : $exception->getMessage();
$data = array(
'response' => static::$convertResponseToArray
? Object::toArray($data)
? Obj::toArray($data)
: $data,
'stages' => $this->restler->getEvents(),
'success' => $success,

View File

@ -1,7 +1,7 @@
<?php
namespace Luracast\Restler\Format;
use Luracast\Restler\Data\Object;
use Luracast\Restler\Data\Obj;
use Luracast\Restler\RestException;
/**
@ -43,6 +43,13 @@ class JsonFormat extends Format
*/
public static $bigIntAsString = null;
/**
* @var boolean|null shim for json_decode JSON_NUMERIC_CHECK set it to
* null to
* use smart defaults
*/
public static $numbersAsNumbers = null;
const MIME = 'application/json';
const EXTENSION = 'json';
@ -80,13 +87,17 @@ class JsonFormat extends Format
$options |= JSON_UNESCAPED_UNICODE;
}
$result = json_encode(Object::toArray($data, true), $options);
if (self::$numbersAsNumbers) {
$options |= JSON_NUMERIC_CHECK;
}
$result = json_encode(Obj::toArray($data, true), $options);
$this->handleJsonError();
return $result;
}
$result = json_encode(Object::toArray($data, true));
$result = json_encode(Obj::toArray($data, true));
$this->handleJsonError();
if ($humanReadable) {
@ -116,6 +127,10 @@ class JsonFormat extends Format
public function decode($data)
{
if(empty($data)){
return null;
}
$options = 0;
if (self::$bigIntAsString) {
if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) // PHP >= 5.4
@ -142,7 +157,7 @@ class JsonFormat extends Format
throw new RestException(400, 'Error parsing JSON');
}
return Object::toArray($decoded);
return Obj::toArray($decoded);
}
/**
@ -259,4 +274,4 @@ class JsonFormat extends Format
throw new \RuntimeException('Error encoding/decoding JSON: '. $message);
}
}
}
}

View File

@ -1,7 +1,7 @@
<?php
namespace Luracast\Restler\Format;
use Luracast\Restler\Data\Object;
use Luracast\Restler\Data\Obj;
use CFPropertyList\CFTypeDetector;
use CFPropertyList\CFPropertyList;
@ -61,7 +61,7 @@ class PlistFormat extends DependentMultiFormat
$plist = new CFPropertyList ();
$td = new CFTypeDetector ();
$guessedStructure = $td->toCFType(
Object::toArray($data)
Obj::toArray($data)
);
$plist->add($guessedStructure);

View File

@ -25,7 +25,9 @@ class UploadFormat extends Format
2 => "The uploaded file exceeds the maximum allowed size",
3 => "The uploaded file was only partially uploaded",
4 => "No file was uploaded",
6 => "Missing a temporary folder"
6 => "Missing a temporary folder",
7 => "Failed to write file to disk",
8 => "A PHP extension stopped the file upload"
);
/**
* use it if you need to restrict uploads based on file type

View File

@ -1,7 +1,7 @@
<?php
namespace Luracast\Restler\Format;
use Luracast\Restler\Data\Object;
use Luracast\Restler\Data\Obj;
use Luracast\Restler\RestException;
use SimpleXMLElement;
use XMLWriter;
@ -89,7 +89,7 @@ class XmlFormat extends Format
public function encode($data, $humanReadable = false)
{
$data = Object::toArray($data);
$data = Obj::toArray($data);
$xml = new XMLWriter();
$xml->openMemory();
$xml->startDocument('1.0', $this->charset);

View File

@ -2,7 +2,7 @@
namespace Luracast\Restler\Format;
use Symfony\Component\Yaml\Yaml;
use Luracast\Restler\Data\Object;
use Luracast\Restler\Data\Obj;
/**
* YAML Format for Restler Framework
@ -26,7 +26,7 @@ class YamlFormat extends DependentFormat
public function encode($data, $humanReadable = false)
{
return @Yaml::dump(Object::toArray($data), $humanReadable ? 10 : 4);
return @Yaml::dump(Obj::toArray($data), $humanReadable ? 10 : 4);
}
public function decode($data)

View File

@ -34,7 +34,6 @@ class PassThrough
* @param bool $isPublic cache control, is it public or private
*
* @throws RestException
* @internal param string $pragma
*
*/
public static function file($filename, $forceDownload = false, $expires = 0, $isPublic = true)

View File

@ -538,7 +538,7 @@ class Restler extends EventDispatcher
if ($version && $version <= $this->apiVersion) {
$this->requestedApiVersion = $version;
$path = explode('/', $path, 2);
$path = $path[1];
$path = count($path) == 2 ? $path[1] : '';
}
} else {
$this->requestedApiVersion = $this->apiMinimumVersion;
@ -718,7 +718,8 @@ class Restler extends EventDispatcher
. $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']);
header('Access-Control-Allow-Origin: ' .
(Defaults::$accessControlAllowOrigin == '*' ? $_SERVER['HTTP_ORIGIN'] : Defaults::$accessControlAllowOrigin));
((Defaults::$accessControlAllowOrigin == '*' && isset($_SERVER['HTTP_ORIGIN']))
? $_SERVER['HTTP_ORIGIN'] : Defaults::$accessControlAllowOrigin));
header('Access-Control-Allow-Credentials: true');
exit(0);
@ -1195,7 +1196,7 @@ class Restler extends EventDispatcher
foreach ($this->errorClasses as $className) {
if (method_exists($className, $method)) {
$obj = Scope::get($className);
if ($obj->$method())
if ($obj->$method($exception))
$handled = true;
}
}
@ -1397,6 +1398,135 @@ class Restler extends EventDispatcher
$this->errorClasses[] = $className;
}
/**
* protected methods will need at least one authentication class to be set
* in order to allow that method to be executed. When multiple authentication
* classes are in use, this function provides better performance by setting
* all auth classes through a single function call.
*
* @param array $classNames array of associative arrays containing
* the authentication class name & optional
* url prefix for mapping.
*/
public function setAuthClasses(array $classNames)
{
$this->authClasses = array_merge($this->authClasses, array_values($classNames));
}
/**
* Add multiple api classes through this method.
*
* This method provides better performance when large number
* of API classes are in use as it processes them all at once,
* as opposed to hundreds (or more) addAPIClass calls.
*
*
* All the public methods that do not start with _ (underscore)
* will be will be exposed as the public api by default.
*
* All the protected methods that do not start with _ (underscore)
* will exposed as protected api which will require authentication
*
* @param array $map array of associative arrays containing
* the class name & optional url prefix
* for mapping.
*
* @return null
*
* @throws Exception when supplied with invalid class name
*/
public function mapAPIClasses(array $map)
{
try {
if ($this->productionMode && is_null($this->cached)) {
$routes = $this->cache->get('routes');
if (isset($routes) && is_array($routes)) {
$this->apiVersionMap = $routes['apiVersionMap'];
unset($routes['apiVersionMap']);
Routes::fromArray($routes);
$this->cached = true;
} else {
$this->cached = false;
}
}
$maxVersionMethod = '__getMaximumSupportedVersion';
if (!$this->productionMode || !$this->cached) {
foreach ($map as $className => $resourcePath) {
if (is_numeric($className)) {
$className = $resourcePath;
$resourcePath = null;
}
if (isset(Scope::$classAliases[$className])) {
$className = Scope::$classAliases[$className];
}
if (class_exists($className)) {
if (method_exists($className, $maxVersionMethod)) {
$max = $className::$maxVersionMethod();
for ($i = 1; $i <= $max; $i++) {
$this->apiVersionMap[$className][$i] = $className;
}
} else {
$this->apiVersionMap[$className][1] = $className;
}
}
//versioned api
if (false !== ($index = strrpos($className, '\\'))) {
$name = substr($className, 0, $index)
. '\\v{$version}' . substr($className, $index);
} else {
if (false !== ($index = strrpos($className, '_'))) {
$name = substr($className, 0, $index)
. '_v{$version}' . substr($className, $index);
} else {
$name = 'v{$version}\\' . $className;
}
}
for ($version = $this->apiMinimumVersion;
$version <= $this->apiVersion;
$version++) {
$versionedClassName = str_replace('{$version}', $version,
$name);
if (class_exists($versionedClassName)) {
Routes::addAPIClass($versionedClassName,
Util::getResourcePath(
$className,
$resourcePath
),
$version
);
if (method_exists($versionedClassName, $maxVersionMethod)) {
$max = $versionedClassName::$maxVersionMethod();
for ($i = $version; $i <= $max; $i++) {
$this->apiVersionMap[$className][$i] = $versionedClassName;
}
} else {
$this->apiVersionMap[$className][$version] = $versionedClassName;
}
} elseif (isset($this->apiVersionMap[$className][$version])) {
Routes::addAPIClass($this->apiVersionMap[$className][$version],
Util::getResourcePath(
$className,
$resourcePath
),
$version
);
}
}
}
}
} catch (Exception $e) {
$e = new Exception(
"mapAPIClasses failed. " . $e->getMessage(),
$e->getCode(),
$e
);
$this->setSupportedFormats('JsonFormat');
$this->message($e);
}
}
/**
* Associated array that maps formats to their respective format class name
*
@ -1484,6 +1614,19 @@ class Restler extends EventDispatcher
public function __destruct()
{
if ($this->productionMode && !$this->cached) {
if (empty($this->url) && empty($this->requestMethod)) {
// url and requestMethod is NOT set:
// This can only happen, when an exception was thrown outside of restler, so that the method Restler::handle was NOT called.
// In this case, the routes can now be corrupt/incomplete, because we don't know, if all API-classes could be registered
// before the exception was thrown. So, don't cache the routes, because the routes can now be corrupt/incomplete!
return;
}
if ($this->exception instanceof RestException && $this->exception->getStage() === 'setup') {
// An exception has occured during configuration of restler. Maybe we could not add all API-classes correctly!
// So, don't cache the routes, because the routes can now be corrupt/incomplete!
return;
}
$this->cache->set(
'routes',
Routes::toArray() +

View File

@ -293,8 +293,6 @@ class Routes
}
$url = empty($methodUrl) ? rtrim($resourcePath, '/')
: $resourcePath . $methodUrl;
$lastPathParam = array_keys($pathParams);
$lastPathParam = end($lastPathParam);
for ($position = 0; $position < count($params); $position++) {
$from = $metadata['param'][$position][$dataName]['from'];
if ($from == 'body' && ($httpMethod == 'GET' ||
@ -307,6 +305,7 @@ class Routes
if (empty($pathParams) || $allowAmbiguity) {
static::addPath($url, $call, $httpMethod, $version);
}
$lastPathParam = end($pathParams);
foreach ($pathParams as $position) {
if (!empty($url))
$url .= '/';

View File

@ -52,7 +52,7 @@ class Scope
'MemcacheCache' => 'Luracast\Restler\MemcacheCache',
//Utility classes
'Object' => 'Luracast\Restler\Data\Object',
'Obj' => 'Luracast\Restler\Data\Obj',
'Text' => 'Luracast\Restler\Data\Text',
'Arr' => 'Luracast\Restler\Data\Arr',
@ -194,6 +194,11 @@ class Scope
{
if (empty($className) || !is_string($className))
return false;
if (self::isPrimitiveDataType($className)) {
return false;
}
$divider = '\\';
$qualified = false;
if ($className{0} == $divider) {
@ -212,4 +217,14 @@ class Scope
}
return false;
}
/**
* @param string $stringName
* @return boolean
*/
private static function isPrimitiveDataType($stringName)
{
$primitiveDataTypes = array('Array', 'array', 'bool', 'boolean', 'float', 'int', 'integer', 'string');
return in_array($stringName, $primitiveDataTypes);
}
}

View File

@ -226,6 +226,10 @@ class Util
public static function getShortName($className)
{
// @CHANGE LDR
if (! is_string($className)) return '';
//var_dump($className);
$className = explode('\\', $className);
return end($className);
}

File diff suppressed because it is too large Load Diff

View File

@ -126,6 +126,7 @@
max-width: 960px;
margin-left: auto;
margin-right: auto;
/* JSONEditor specific styling */
}
.swagger-section .swagger-ui-wrap b,
.swagger-section .swagger-ui-wrap strong {
@ -274,6 +275,9 @@
font-weight: bold;
font-size: 25px;
}
.swagger-section .swagger-ui-wrap .footer {
margin-top: 20px;
}
.swagger-section .swagger-ui-wrap p.big,
.swagger-section .swagger-ui-wrap div.big p {
font-size: 1em;
@ -294,7 +298,13 @@
.swagger-section .swagger-ui-wrap .message-fail {
color: #cc0000;
}
.swagger-section .swagger-ui-wrap .info_contact {
.swagger-section .swagger-ui-wrap .info_url {
padding-bottom: 5px;
}
.swagger-section .swagger-ui-wrap .info_email {
padding-bottom: 5px;
}
.swagger-section .swagger-ui-wrap .info_name {
padding-bottom: 5px;
}
.swagger-section .swagger-ui-wrap .info_description {
@ -350,7 +360,7 @@
font-size: .85em;
line-height: 1.2em;
overflow: auto;
max-height: 200px;
max-height: 400px;
cursor: pointer;
}
.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav {
@ -391,6 +401,43 @@
font-weight: bold;
color: #000;
}
.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper {
border-spacing: 0;
position: absolute;
background-color: #ffffff;
border: 1px solid #bbbbbb;
display: none;
font-size: 11px;
max-width: 400px;
line-height: 30px;
color: black;
padding: 5px;
margin-left: 10px;
}
.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th {
text-align: center;
background-color: #eeeeee;
border: 1px solid #bbbbbb;
font-size: 11px;
color: #666666;
font-weight: bold;
padding: 5px;
line-height: 15px;
}
.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName {
font-weight: bold;
}
.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:first-child,
.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:last-child {
display: inline;
}
.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:not(:first-child):before {
display: block;
content: '';
}
.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown > p:only-child {
margin-right: -3px;
}
.swagger-section .swagger-ui-wrap .model-signature .propName {
font-weight: bold;
}
@ -412,6 +459,17 @@
.swagger-section .swagger-ui-wrap .required {
font-weight: bold;
}
.swagger-section .swagger-ui-wrap .editor_holder {
font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
font-size: 0.9em;
}
.swagger-section .swagger-ui-wrap .editor_holder label {
font-weight: normal!important;
/* JSONEditor uses bold by default for all labels, we revert that back to normal to not give the impression that by default fields are required */
}
.swagger-section .swagger-ui-wrap .editor_holder label.required {
font-weight: bold!important;
}
.swagger-section .swagger-ui-wrap input.parameter {
width: 300px;
border: 1px solid #aaa;
@ -761,6 +819,9 @@
outline: 2px solid black;
outline-color: #cc0000;
}
.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name='parameterContentType'] {
max-width: 300px;
}
.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre {
font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
padding: 10px;
@ -1034,6 +1095,9 @@
.swagger-section .swagger-ui-wrap form.form_box p strong {
color: black;
}
.swagger-section .swagger-ui-wrap .operation-status td.markdown > p:last-child {
padding-bottom: 0;
}
.swagger-section .title {
font-style: bold;
}
@ -1072,14 +1136,14 @@
font-size: 24px;
padding: 10px 0;
}
.swagger-section .api-popup-dialog p.error-msg {
.swagger-section .api-popup-dialog .error-msg {
padding-left: 5px;
padding-bottom: 5px;
}
.swagger-section .api-popup-dialog button.api-popup-authbtn {
.swagger-section .api-popup-dialog .api-popup-authbtn {
height: 30px;
}
.swagger-section .api-popup-dialog button.api-popup-cancel {
.swagger-section .api-popup-dialog .api-popup-cancel {
height: 30px;
}
.swagger-section .api-popup-scopes {
@ -1089,14 +1153,14 @@
padding: 5px 0;
line-height: 20px;
}
.swagger-section .api-popup-scopes .api-scope-desc {
padding-left: 20px;
font-style: italic;
}
.swagger-section .api-popup-scopes li input {
position: relative;
top: 2px;
}
.swagger-section .api-popup-scopes .api-scope-desc {
padding-left: 20px;
font-style: italic;
}
.swagger-section .api-popup-actions {
padding-top: 10px;
}
@ -1106,8 +1170,16 @@
.swagger-section .auth {
float: right;
}
.swagger-section #api_information_panel {
position: absolute;
.swagger-section .api-ic {
height: 18px;
vertical-align: middle;
display: inline-block;
background: url(../images/explorer_icons.png) no-repeat;
}
.swagger-section .api-ic .api_information_panel {
position: relative;
margin-top: 20px;
margin-left: -5px;
background: #FFF;
border: 1px solid #ccc;
border-radius: 5px;
@ -1118,34 +1190,32 @@
color: black;
padding: 5px;
}
.swagger-section #api_information_panel p .api-msg-enabled {
.swagger-section .api-ic .api_information_panel p .api-msg-enabled {
color: green;
}
.swagger-section #api_information_panel p .api-msg-disabled {
.swagger-section .api-ic .api_information_panel p .api-msg-disabled {
color: red;
}
.swagger-section .api-ic {
height: 18px;
vertical-align: middle;
display: inline-block;
background: url(../images/explorer_icons.png) no-repeat;
.swagger-section .api-ic:hover .api_information_panel {
position: absolute;
display: block;
}
.swagger-section .ic-info {
background-position: 0 0;
width: 18px;
margin-top: -7px;
margin-top: -6px;
margin-left: 4px;
}
.swagger-section .ic-warning {
background-position: -60px 0;
width: 18px;
margin-top: -7px;
margin-top: -6px;
margin-left: 4px;
}
.swagger-section .ic-error {
background-position: -30px 0;
width: 18px;
margin-top: -7px;
margin-top: -6px;
margin-left: 4px;
}
.swagger-section .ic-off {
@ -1161,42 +1231,39 @@
cursor: pointer;
}
.swagger-section #header {
background-color: #89bf04;
background-color: #646257;
padding: 14px;
}
.swagger-section #header a#logo {
font-size: 1.5em;
font-weight: bold;
text-decoration: none;
background: transparent url(../images/logo_small.png) no-repeat left center;
padding: 20px 0 20px 40px;
color: white;
.swagger-section #input_baseUrl {
width: 400px;
}
.swagger-section #header form#api_selector {
.swagger-section #api_selector {
display: block;
clear: none;
float: right;
}
.swagger-section #header form#api_selector .input {
.swagger-section #api_selector .input {
display: block;
clear: none;
float: left;
margin: 0 10px 0 0;
}
.swagger-section #header form#api_selector .input input#input_apiKey {
.swagger-section #api_selector input {
font-size: 0.9em;
padding: 3px;
margin: 0;
}
.swagger-section #input_apiKey {
width: 200px;
}
.swagger-section #header form#api_selector .input input#input_baseUrl {
width: 400px;
}
.swagger-section #header form#api_selector .input a#explore {
.swagger-section #explore {
display: block;
text-decoration: none;
font-weight: bold;
padding: 6px 8px;
font-size: 0.9em;
color: white;
background-color: #547f00;
background-color: #000000;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
-o-border-radius: 4px;
@ -1204,13 +1271,16 @@
-khtml-border-radius: 4px;
border-radius: 4px;
}
.swagger-section #header form#api_selector .input a#explore:hover {
background-color: #547f00;
.swagger-section #explore:hover {
background-color: #a41e22;
}
.swagger-section #header form#api_selector .input input {
font-size: 0.9em;
padding: 3px;
margin: 0;
.swagger-section #header #logo {
font-size: 1.5em;
font-weight: bold;
text-decoration: none;
background: transparent url(../images/logo_small.png) no-repeat left center;
padding: 20px 0 20px 40px;
color: white;
}
.swagger-section #content_message {
margin: 10px 15px;
@ -1222,3 +1292,13 @@
text-align: center;
padding-top: 10px;
}
.swagger-section .swagger-collapse:before {
content: "-";
}
.swagger-section .swagger-expand:before {
content: "+";
}
#input_baseUrl {
display: none;
}

View File

@ -0,0 +1,250 @@
.swagger-section #header a#logo {
font-size: 1.5em;
font-weight: bold;
text-decoration: none;
background: transparent url(../images/logo.png) no-repeat left center;
padding: 20px 0 20px 40px;
}
#text-head {
font-size: 80px;
font-family: 'Roboto', sans-serif;
color: #ffffff;
float: right;
margin-right: 20%;
}
.navbar-fixed-top .navbar-nav {
height: auto;
}
.navbar-fixed-top .navbar-brand {
height: auto;
}
.navbar-header {
height: auto;
}
.navbar-inverse {
background-color: #000;
border-color: #000;
}
#navbar-brand {
margin-left: 20%;
}
.navtext {
font-size: 10px;
}
.h1,
h1 {
font-size: 60px;
}
.navbar-default .navbar-header .navbar-brand {
color: #a2dfee;
}
/* tag titles */
.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a {
color: #393939;
font-family: 'Arvo', serif;
font-size: 1.5em;
}
.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover {
color: black;
}
.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 {
color: #525252;
padding-left: 0px;
display: block;
clear: none;
float: left;
font-family: 'Arvo', serif;
font-weight: bold;
}
.navbar-default .navbar-collapse,
.navbar-default .navbar-form {
border-color: #0A0A0A;
}
.container1 {
width: 1500px;
margin: auto;
margin-top: 0;
background-image: url('../images/shield.png');
background-repeat: no-repeat;
background-position: -40px -20px;
margin-bottom: 210px;
}
.container-inner {
width: 1200px;
margin: auto;
background-color: rgba(223, 227, 228, 0.75);
padding-bottom: 40px;
padding-top: 40px;
border-radius: 15px;
}
.header-content {
padding: 0;
width: 1000px;
}
.title1 {
font-size: 80px;
font-family: 'Vollkorn', serif;
color: #404040;
text-align: center;
padding-top: 40px;
padding-bottom: 100px;
}
#icon {
margin-top: -18px;
}
.subtext {
font-size: 25px;
font-style: italic;
color: #08b;
text-align: right;
padding-right: 250px;
}
.bg-primary {
background-color: #00468b;
}
.navbar-default .nav > li > a,
.navbar-default .nav > li > a:focus {
color: #08b;
}
.navbar-default .nav > li > a,
.navbar-default .nav > li > a:hover {
color: #08b;
}
.navbar-default .nav > li > a,
.navbar-default .nav > li > a:focus:hover {
color: #08b;
}
.text-faded {
font-size: 25px;
font-family: 'Vollkorn', serif;
}
.section-heading {
font-family: 'Vollkorn', serif;
font-size: 45px;
padding-bottom: 10px;
}
hr {
border-color: #00468b;
padding-bottom: 10px;
}
.description {
margin-top: 20px;
padding-bottom: 200px;
}
.description li {
font-family: 'Vollkorn', serif;
font-size: 25px;
color: #525252;
margin-left: 28%;
padding-top: 5px;
}
.gap {
margin-top: 200px;
}
.troubleshootingtext {
color: rgba(255, 255, 255, 0.7);
padding-left: 30%;
}
.troubleshootingtext li {
list-style-type: circle;
font-size: 25px;
padding-bottom: 5px;
}
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
}
.block.response_body.json:hover {
cursor: pointer;
}
.backdrop {
color: blue;
}
#myModal {
height: 100%;
}
.modal-backdrop {
bottom: 0;
position: fixed;
}
.curl {
padding: 10px;
font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
font-size: 0.9em;
max-height: 400px;
margin-top: 5px;
overflow-y: auto;
background-color: #fcf6db;
border: 1px solid #e5e0c6;
border-radius: 4px;
}
.curl_title {
font-size: 1.1em;
margin: 0;
padding: 15px 0 5px;
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
font-weight: 500;
line-height: 1.1;
}
.footer {
display: none;
}
.swagger-section .swagger-ui-wrap h2 {
padding: 0;
}
h2 {
margin: 0;
margin-bottom: 5px;
}
.markdown p {
font-size: 15px;
font-family: 'Arvo', serif;
}
.swagger-section .swagger-ui-wrap .code {
font-size: 15px;
font-family: 'Arvo', serif;
}
.swagger-section .swagger-ui-wrap b {
font-family: 'Arvo', serif;
}
#signin:hover {
cursor: pointer;
}
.dropdown-menu {
padding: 15px;
}
.navbar-right .dropdown-menu {
left: 0;
right: auto;
}
#signinbutton {
width: 100%;
height: 32px;
font-size: 13px;
font-weight: bold;
color: #08b;
}
.navbar-default .nav > li .details {
color: #000000;
text-transform: none;
font-size: 15px;
font-weight: normal;
font-family: 'Open Sans', sans-serif;
font-style: italic;
line-height: 20px;
top: -2px;
}
.navbar-default .nav > li .details:hover {
color: black;
}
#signout {
width: 100%;
height: 32px;
font-size: 13px;
font-weight: bold;
color: #08b;
}

View File

@ -0,0 +1,14 @@
/* Google Font's Droid Sans */
@font-face {
font-family: 'Droid Sans';
font-style: normal;
font-weight: 400;
src: local('Droid Sans'), local('DroidSans'), url('../fonts/DroidSans.ttf') format('truetype');
}
/* Google Font's Droid Sans Bold */
@font-face {
font-family: 'Droid Sans';
font-style: normal;
font-weight: 700;
src: local('Droid Sans Bold'), local('DroidSans-Bold'), url('../fonts/DroidSans-Bold.ttf') format('truetype');
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 770 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 980 B

View File

@ -1,85 +1,126 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Api Explorer</title>
<!-- @CHANGE LDR Remove external links <link href='//fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'/>-->
<link href='css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='css/reset.css' media='print' rel='stylesheet' type='text/css'/>
<link href='css/screen.css' media='print' rel='stylesheet' type='text/css'/>
<script type="text/javascript" src="lib/shred.bundle.js"></script>
<link href='css/print.css' media='print' rel='stylesheet' type='text/css'/>
<!-- @CHANGE LDR Remove external links <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet"> -->
<script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>
<script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
<script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
<script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
<script src='lib/handlebars-1.0.0.js' type='text/javascript'></script>
<script src='lib/handlebars-2.0.0.js' type='text/javascript'></script>
<script src='lib/underscore-min.js' type='text/javascript'></script>
<script src='lib/backbone-min.js' type='text/javascript'></script>
<script src='lib/swagger.js' type='text/javascript'></script>
<script src='swagger-ui.js' type='text/javascript'></script>
<script src='lib/highlight.7.3.pack.js' type='text/javascript'></script>
<!-- enabling this will enable oauth2 implicit scope support -->
<script src='lib/jsoneditor.min.js' type='text/javascript'></script>
<script src='lib/marked.js' type='text/javascript'></script>
<script src='lib/swagger-oauth.js' type='text/javascript'></script>
<!-- Some basic translations -->
<!-- <script src='lang/translator.js' type='text/javascript'></script> -->
<!-- <script src='lang/ru.js' type='text/javascript'></script> -->
<!-- <script src='lang/en.js' type='text/javascript'></script> -->
<script type="text/javascript">
$(function () {
window.swaggerUi = new SwaggerUi({
url: "resources.json",
validatorUrl: null,
dom_id: "swagger-ui-container",
supportedSubmitMethods: ['get', 'post', 'put', 'delete'],
onComplete: function(swaggerApi, swaggerUi){
log("Loaded API Explorer");
if(typeof initOAuth == "function") {
/*
initOAuth({
clientId: "your-client-id",
realm: "your-realms",
appName: "your-app-name"
});
*/
}
$('pre code').each(function(i, e) {
hljs.highlightBlock(e)
});
},
defaultModelRendering: 'model',
onFailure: function(data) {
log("Unable to Load API Explorer");
},
docExpansion: "none",
/*showRequestHeaders: true,
jsonEditor: true */
/*, sorter : "alpha"*/
});
$('#input_apiKey').change(function() {
var key = $('#input_apiKey')[0].value;
log("key: " + key);
if(key && key.trim() != "") {
/* @CHANGE LDR We set DOLAPIKEY into header */
log("added key " + key);
/* Disabled for security reason. We keep only param in header
window.authorizations.add("key", new ApiKeyAuthorization("DOLAPIKEY", key, "query"));
console.log("param api_key added with value "+key);
*/
window.authorizations.add("key2", new ApiKeyAuthorization("DOLAPIKEY", key, "header"));
console.log("header DOLAPIKEY added with value "+key);
var url = window.location.search.match(/url=([^&]+)/);
if (url && url.length > 1) {
url = decodeURIComponent(url[1]);
} else {
url = "swagger.json";
}
// Pre load translate...
if(window.SwaggerTranslator) {
window.SwaggerTranslator.translate();
}
window.swaggerUi = new SwaggerUi({
url: url,
dom_id: "swagger-ui-container",
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
onComplete: function(swaggerApi, swaggerUi){
if(typeof initOAuth == "function") {
initOAuth({
clientId: "your-client-id",
clientSecret: "your-client-secret-if-required",
realm: "your-realms",
appName: "your-app-name",
scopeSeparator: ",",
additionalQueryStringParams: {}
});
}
if(window.SwaggerTranslator) {
window.SwaggerTranslator.translate();
}
$('pre code').each(function(i, e) {
hljs.highlightBlock(e)
});
addApiKeyAuthorization();
},
onFailure: function(data) {
log("Unable to Load SwaggerUI");
},
docExpansion: "none",
jsonEditor: false,
apisSorter: "alpha",
defaultModelRendering: 'schema',
showRequestHeaders: false
});
function addApiKeyAuthorization(){
var key = encodeURIComponent($('#input_apiKey')[0].value);
if(key && key.trim() != "") {
/* @CHANGE LDR We set DOLAPIKEY into header */
/* log("added key " + key); */
log("added key");
/* Disabled for security reason. We keep only param in header
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "query");
window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth);
log("added key " + key);
*/
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("DOLAPIKEY", key, "header");
window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth);
/* log("header DOLAPIKEY added with value "+key); */
log("header DOLAPIKEY added");
}
}
$('#input_apiKey').change(addApiKeyAuthorization);
// if you have an apiKey you would like to pre-populate on the page for demonstration purposes...
/*
var apiKey = "myApiKeyXXXX123456789";
$('#input_apiKey').val(apiKey);
*/
window.swaggerUi.load();
function log() {
if ('console' in window) {
console.log.apply(console, arguments);
}
}
})
window.swaggerUi.load();
});
</script>
<style>
.info_title, .info_description, .info_contact, .info_license {
.info_title, .info_description, .info_contact, .info_name, .info_url, .info_email, .info_license {
display: none;
}
</style>
</style>
</head>
<body class="swagger-section">
@ -87,22 +128,14 @@
<div class="swagger-ui-wrap">
<a id="logo" href="#">API Explorer</a>
<form id='api_selector'>
<!-- @CHANGE LDR
<div class='input icon-btn'>
<img id="show-pet-store-icon" src="images/pet_store_api.png" title="Show Swagger Petstore Example Apis">
</div>
<div class='input icon-btn'>
<img id="show-wordnik-dev-icon" src="images/wordnik_api.png" title="Show Wordnik Developer Apis">
</div>
-->
<div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="hidden" value="resources.json"/></div>
<div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
<div class='input'><input placeholder="DOLAPIKEY" id="input_apiKey" name="apiKey" type="text"/></div>
<div class='input'><a id="explore" href="#">Explore</a></div>
<div class='input'><a id="explore" href="#" data-sw-translate>Explore</a></div>
</form>
</div>
</div>
<div id="message-bar" class="swagger-ui-wrap">&nbsp;</div>
<div id="message-bar" class="swagger-ui-wrap" data-sw-translate>&nbsp;</div>
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
</body>
</html>

View File

@ -0,0 +1,55 @@
'use strict';
/* jshint quotmark: double */
window.SwaggerTranslator.learn({
"Warning: Deprecated":"Warning: Deprecated",
"Implementation Notes":"Implementation Notes",
"Response Class":"Response Class",
"Status":"Status",
"Parameters":"Parameters",
"Parameter":"Parameter",
"Value":"Value",
"Description":"Description",
"Parameter Type":"Parameter Type",
"Data Type":"Data Type",
"Response Messages":"Response Messages",
"HTTP Status Code":"HTTP Status Code",
"Reason":"Reason",
"Response Model":"Response Model",
"Request URL":"Request URL",
"Response Body":"Response Body",
"Response Code":"Response Code",
"Response Headers":"Response Headers",
"Hide Response":"Hide Response",
"Headers":"Headers",
"Try it out!":"Try it out!",
"Show/Hide":"Show/Hide",
"List Operations":"List Operations",
"Expand Operations":"Expand Operations",
"Raw":"Raw",
"can't parse JSON. Raw result":"can't parse JSON. Raw result",
"Model Schema":"Model Schema",
"Model":"Model",
"Click to set as parameter value":"Click to set as parameter value",
"apply":"apply",
"Username":"Username",
"Password":"Password",
"Terms of service":"Terms of service",
"Created by":"Created by",
"See more at":"See more at",
"Contact the developer":"Contact the developer",
"api version":"api version",
"Response Content Type":"Response Content Type",
"Parameter content type:":"Parameter content type:",
"fetching resource":"fetching resource",
"fetching resource list":"fetching resource list",
"Explore":"Explore",
"Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis",
"Can't read from server. It may not have the appropriate access-control-origin settings.":"Can't read from server. It may not have the appropriate access-control-origin settings.",
"Please specify the protocol for":"Please specify the protocol for",
"Can't read swagger JSON from":"Can't read swagger JSON from",
"Finished Loading Resource Information. Rendering Swagger UI":"Finished Loading Resource Information. Rendering Swagger UI",
"Unable to read api":"Unable to read api",
"from path":"from path",
"server returned":"server returned"
});

View File

@ -0,0 +1,52 @@
'use strict';
/* jshint quotmark: double */
window.SwaggerTranslator.learn({
"Warning: Deprecated":"Advertencia: Obsoleto",
"Implementation Notes":"Notas de implementación",
"Response Class":"Clase de la Respuesta",
"Status":"Status",
"Parameters":"Parámetros",
"Parameter":"Parámetro",
"Value":"Valor",
"Description":"Descripción",
"Parameter Type":"Tipo del Parámetro",
"Data Type":"Tipo del Dato",
"Response Messages":"Mensajes de la Respuesta",
"HTTP Status Code":"Código de Status HTTP",
"Reason":"Razón",
"Response Model":"Modelo de la Respuesta",
"Request URL":"URL de la Solicitud",
"Response Body":"Cuerpo de la Respuesta",
"Response Code":"Código de la Respuesta",
"Response Headers":"Encabezados de la Respuesta",
"Hide Response":"Ocultar Respuesta",
"Try it out!":"Pruébalo!",
"Show/Hide":"Mostrar/Ocultar",
"List Operations":"Listar Operaciones",
"Expand Operations":"Expandir Operaciones",
"Raw":"Crudo",
"can't parse JSON. Raw result":"no puede parsear el JSON. Resultado crudo",
"Model Schema":"Esquema del Modelo",
"Model":"Modelo",
"apply":"aplicar",
"Username":"Nombre de usuario",
"Password":"Contraseña",
"Terms of service":"Términos de Servicio",
"Created by":"Creado por",
"See more at":"Ver más en",
"Contact the developer":"Contactar al desarrollador",
"api version":"versión de la api",
"Response Content Type":"Tipo de Contenido (Content Type) de la Respuesta",
"fetching resource":"buscando recurso",
"fetching resource list":"buscando lista del recurso",
"Explore":"Explorar",
"Show Swagger Petstore Example Apis":"Mostrar Api Ejemplo de Swagger Petstore",
"Can't read from server. It may not have the appropriate access-control-origin settings.":"No se puede leer del servidor. Tal vez no tiene la configuración de control de acceso de origen (access-control-origin) apropiado.",
"Please specify the protocol for":"Por favor, especificar el protocola para",
"Can't read swagger JSON from":"No se puede leer el JSON de swagger desde",
"Finished Loading Resource Information. Rendering Swagger UI":"Finalizada la carga del recurso de Información. Mostrando Swagger UI",
"Unable to read api":"No se puede leer la api",
"from path":"desde ruta",
"server returned":"el servidor retornó"
});

View File

@ -0,0 +1,53 @@
'use strict';
/* jshint quotmark: double */
window.SwaggerTranslator.learn({
"Warning: Deprecated":"Avertissement : Obsolète",
"Implementation Notes":"Notes d'implementation",
"Response Class":"Classe de la réponse",
"Status":"Statut",
"Parameters":"Paramètres",
"Parameter":"Paramètre",
"Value":"Valeur",
"Description":"Description",
"Parameter Type":"Type du paramètre",
"Data Type":"Type de données",
"Response Messages":"Messages de la réponse",
"HTTP Status Code":"Code de statut HTTP",
"Reason":"Raison",
"Response Model":"Modèle de réponse",
"Request URL":"URL appelée",
"Response Body":"Corps de la réponse",
"Response Code":"Code de la réponse",
"Response Headers":"En-têtes de la réponse",
"Hide Response":"Cacher la réponse",
"Headers":"En-têtes",
"Try it out!":"Testez !",
"Show/Hide":"Afficher/Masquer",
"List Operations":"Liste des opérations",
"Expand Operations":"Développer les opérations",
"Raw":"Brut",
"can't parse JSON. Raw result":"impossible de décoder le JSON. Résultat brut",
"Model Schema":"Définition du modèle",
"Model":"Modèle",
"apply":"appliquer",
"Username":"Nom d'utilisateur",
"Password":"Mot de passe",
"Terms of service":"Conditions de service",
"Created by":"Créé par",
"See more at":"Voir plus sur",
"Contact the developer":"Contacter le développeur",
"api version":"version de l'api",
"Response Content Type":"Content Type de la réponse",
"fetching resource":"récupération de la ressource",
"fetching resource list":"récupération de la liste de ressources",
"Explore":"Explorer",
"Show Swagger Petstore Example Apis":"Montrer les Apis de l'exemple Petstore de Swagger",
"Can't read from server. It may not have the appropriate access-control-origin settings.":"Impossible de lire à partir du serveur. Il se peut que les réglages access-control-origin ne soient pas appropriés.",
"Please specify the protocol for":"Veuillez spécifier un protocole pour",
"Can't read swagger JSON from":"Impossible de lire le JSON swagger à partir de",
"Finished Loading Resource Information. Rendering Swagger UI":"Chargement des informations terminé. Affichage de Swagger UI",
"Unable to read api":"Impossible de lire l'api",
"from path":"à partir du chemin",
"server returned":"réponse du serveur"
});

View File

@ -0,0 +1,52 @@
'use strict';
/* jshint quotmark: double */
window.SwaggerTranslator.learn({
"Warning: Deprecated":"Attenzione: Deprecato",
"Implementation Notes":"Note di implementazione",
"Response Class":"Classe della risposta",
"Status":"Stato",
"Parameters":"Parametri",
"Parameter":"Parametro",
"Value":"Valore",
"Description":"Descrizione",
"Parameter Type":"Tipo di parametro",
"Data Type":"Tipo di dato",
"Response Messages":"Messaggi della risposta",
"HTTP Status Code":"Codice stato HTTP",
"Reason":"Motivo",
"Response Model":"Modello di risposta",
"Request URL":"URL della richiesta",
"Response Body":"Corpo della risposta",
"Response Code":"Oggetto della risposta",
"Response Headers":"Intestazioni della risposta",
"Hide Response":"Nascondi risposta",
"Try it out!":"Provalo!",
"Show/Hide":"Mostra/Nascondi",
"List Operations":"Mostra operazioni",
"Expand Operations":"Espandi operazioni",
"Raw":"Grezzo (raw)",
"can't parse JSON. Raw result":"non è possibile parsare il JSON. Risultato grezzo (raw).",
"Model Schema":"Schema del modello",
"Model":"Modello",
"apply":"applica",
"Username":"Nome utente",
"Password":"Password",
"Terms of service":"Condizioni del servizio",
"Created by":"Creato da",
"See more at":"Informazioni aggiuntive:",
"Contact the developer":"Contatta lo sviluppatore",
"api version":"versione api",
"Response Content Type":"Tipo di contenuto (content type) della risposta",
"fetching resource":"recuperando la risorsa",
"fetching resource list":"recuperando lista risorse",
"Explore":"Esplora",
"Show Swagger Petstore Example Apis":"Mostra le api di esempio di Swagger Petstore",
"Can't read from server. It may not have the appropriate access-control-origin settings.":"Non è possibile leggere dal server. Potrebbe non avere le impostazioni di controllo accesso origine (access-control-origin) appropriate.",
"Please specify the protocol for":"Si prega di specificare il protocollo per",
"Can't read swagger JSON from":"Impossibile leggere JSON swagger da:",
"Finished Loading Resource Information. Rendering Swagger UI":"Lettura informazioni risorse termianta. Swagger UI viene mostrata",
"Unable to read api":"Impossibile leggere la api",
"from path":"da cartella",
"server returned":"il server ha restituito"
});

View File

@ -0,0 +1,53 @@
'use strict';
/* jshint quotmark: double */
window.SwaggerTranslator.learn({
"Warning: Deprecated":"警告: 廃止予定",
"Implementation Notes":"実装メモ",
"Response Class":"レスポンスクラス",
"Status":"ステータス",
"Parameters":"パラメータ群",
"Parameter":"パラメータ",
"Value":"値",
"Description":"説明",
"Parameter Type":"パラメータタイプ",
"Data Type":"データタイプ",
"Response Messages":"レスポンスメッセージ",
"HTTP Status Code":"HTTPステータスコード",
"Reason":"理由",
"Response Model":"レスポンスモデル",
"Request URL":"リクエストURL",
"Response Body":"レスポンスボディ",
"Response Code":"レスポンスコード",
"Response Headers":"レスポンスヘッダ",
"Hide Response":"レスポンスを隠す",
"Headers":"ヘッダ",
"Try it out!":"実際に実行!",
"Show/Hide":"表示/非表示",
"List Operations":"操作一覧",
"Expand Operations":"操作の展開",
"Raw":"Raw",
"can't parse JSON. Raw result":"JSONへ解釈できません. 未加工の結果",
"Model Schema":"モデルスキーマ",
"Model":"モデル",
"apply":"実行",
"Username":"ユーザ名",
"Password":"パスワード",
"Terms of service":"サービス利用規約",
"Created by":"Created by",
"See more at":"See more at",
"Contact the developer":"開発者に連絡",
"api version":"APIバージョン",
"Response Content Type":"レスポンス コンテンツタイプ",
"fetching resource":"リソースの取得",
"fetching resource list":"リソース一覧の取得",
"Explore":"Explore",
"Show Swagger Petstore Example Apis":"SwaggerペットストアAPIの表示",
"Can't read from server. It may not have the appropriate access-control-origin settings.":"サーバから読み込めません. 適切なaccess-control-origin設定を持っていない可能性があります.",
"Please specify the protocol for":"プロトコルを指定してください",
"Can't read swagger JSON from":"次からswagger JSONを読み込めません",
"Finished Loading Resource Information. Rendering Swagger UI":"リソース情報の読み込みが完了しました. Swagger UIを描画しています",
"Unable to read api":"APIを読み込めません",
"from path":"次のパスから",
"server returned":"サーバからの返答"
});

View File

@ -0,0 +1,53 @@
'use strict';
/* jshint quotmark: double */
window.SwaggerTranslator.learn({
"Warning: Deprecated":"Uwaga: Wycofane",
"Implementation Notes":"Uwagi Implementacji",
"Response Class":"Klasa Odpowiedzi",
"Status":"Status",
"Parameters":"Parametry",
"Parameter":"Parametr",
"Value":"Wartość",
"Description":"Opis",
"Parameter Type":"Typ Parametru",
"Data Type":"Typ Danych",
"Response Messages":"Wiadomości Odpowiedzi",
"HTTP Status Code":"Kod Statusu HTTP",
"Reason":"Przyczyna",
"Response Model":"Model Odpowiedzi",
"Request URL":"URL Wywołania",
"Response Body":"Treść Odpowiedzi",
"Response Code":"Kod Odpowiedzi",
"Response Headers":"Nagłówki Odpowiedzi",
"Hide Response":"Ukryj Odpowiedź",
"Headers":"Nagłówki",
"Try it out!":"Wypróbuj!",
"Show/Hide":"Pokaż/Ukryj",
"List Operations":"Lista Operacji",
"Expand Operations":"Rozwiń Operacje",
"Raw":"Nieprzetworzone",
"can't parse JSON. Raw result":"nie można przetworzyć pliku JSON. Nieprzetworzone dane",
"Model Schema":"Schemat Modelu",
"Model":"Model",
"apply":"użyj",
"Username":"Nazwa użytkownika",
"Password":"Hasło",
"Terms of service":"Warunki używania",
"Created by":"Utworzone przez",
"See more at":"Zobacz więcej na",
"Contact the developer":"Kontakt z deweloperem",
"api version":"wersja api",
"Response Content Type":"Typ Zasobu Odpowiedzi",
"fetching resource":"ładowanie zasobu",
"fetching resource list":"ładowanie listy zasobów",
"Explore":"Eksploruj",
"Show Swagger Petstore Example Apis":"Pokaż Przykładowe Api Swagger Petstore",
"Can't read from server. It may not have the appropriate access-control-origin settings.":"Brak połączenia z serwerem. Może on nie mieć odpowiednich ustawień access-control-origin.",
"Please specify the protocol for":"Proszę podać protokół dla",
"Can't read swagger JSON from":"Nie można odczytać swagger JSON z",
"Finished Loading Resource Information. Rendering Swagger UI":"Ukończono Ładowanie Informacji o Zasobie. Renderowanie Swagger UI",
"Unable to read api":"Nie można odczytać api",
"from path":"ze ścieżki",
"server returned":"serwer zwrócił"
});

View File

@ -0,0 +1,53 @@
'use strict';
/* jshint quotmark: double */
window.SwaggerTranslator.learn({
"Warning: Deprecated":"Aviso: Depreciado",
"Implementation Notes":"Notas de Implementação",
"Response Class":"Classe de resposta",
"Status":"Status",
"Parameters":"Parâmetros",
"Parameter":"Parâmetro",
"Value":"Valor",
"Description":"Descrição",
"Parameter Type":"Tipo de parâmetro",
"Data Type":"Tipo de dados",
"Response Messages":"Mensagens de resposta",
"HTTP Status Code":"Código de status HTTP",
"Reason":"Razão",
"Response Model":"Modelo resposta",
"Request URL":"URL requisição",
"Response Body":"Corpo da resposta",
"Response Code":"Código da resposta",
"Response Headers":"Cabeçalho da resposta",
"Headers":"Cabeçalhos",
"Hide Response":"Esconder resposta",
"Try it out!":"Tente agora!",
"Show/Hide":"Mostrar/Esconder",
"List Operations":"Listar operações",
"Expand Operations":"Expandir operações",
"Raw":"Cru",
"can't parse JSON. Raw result":"Falha ao analisar JSON. Resulto cru",
"Model Schema":"Modelo esquema",
"Model":"Modelo",
"apply":"Aplicar",
"Username":"Usuário",
"Password":"Senha",
"Terms of service":"Termos do serviço",
"Created by":"Criado por",
"See more at":"Veja mais em",
"Contact the developer":"Contate o desenvolvedor",
"api version":"Versão api",
"Response Content Type":"Tipo de conteúdo da resposta",
"fetching resource":"busca recurso",
"fetching resource list":"buscando lista de recursos",
"Explore":"Explorar",
"Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis",
"Can't read from server. It may not have the appropriate access-control-origin settings.":"Não é possível ler do servidor. Pode não ter as apropriadas configurações access-control-origin",
"Please specify the protocol for":"Por favor especifique o protocolo",
"Can't read swagger JSON from":"Não é possível ler o JSON Swagger de",
"Finished Loading Resource Information. Rendering Swagger UI":"Carregar informação de recurso finalizada. Renderizando Swagger UI",
"Unable to read api":"Não foi possível ler api",
"from path":"do caminho",
"server returned":"servidor retornou"
});

View File

@ -0,0 +1,55 @@
'use strict';
/* jshint quotmark: double */
window.SwaggerTranslator.learn({
"Warning: Deprecated":"Предупреждение: Устарело",
"Implementation Notes":"Заметки",
"Response Class":"Пример ответа",
"Status":"Статус",
"Parameters":"Параметры",
"Parameter":"Параметр",
"Value":"Значение",
"Description":"Описание",
"Parameter Type":"Тип параметра",
"Data Type":"Тип данных",
"HTTP Status Code":"HTTP код",
"Reason":"Причина",
"Response Model":"Структура ответа",
"Request URL":"URL запроса",
"Response Body":"Тело ответа",
"Response Code":"HTTP код ответа",
"Response Headers":"Заголовки ответа",
"Hide Response":"Спрятать ответ",
"Headers":"Заголовки",
"Response Messages":"Что может прийти в ответ",
"Try it out!":"Попробовать!",
"Show/Hide":"Показать/Скрыть",
"List Operations":"Операции кратко",
"Expand Operations":"Операции подробно",
"Raw":"В сыром виде",
"can't parse JSON. Raw result":"Не удается распарсить ответ:",
"Model Schema":"Структура",
"Model":"Описание",
"Click to set as parameter value":"Нажмите, чтобы испльзовать в качестве значения параметра",
"apply":"применить",
"Username":"Имя пользователя",
"Password":"Пароль",
"Terms of service":"Условия использования",
"Created by":"Разработано",
"See more at":"Еще тут",
"Contact the developer":"Связаться с разработчиком",
"api version":"Версия API",
"Response Content Type":"Content Type ответа",
"Parameter content type:":"Content Type параметра:",
"fetching resource":"Получение ресурса",
"fetching resource list":"Получение ресурсов",
"Explore":"Показать",
"Show Swagger Petstore Example Apis":"Показать примеры АПИ",
"Can't read from server. It may not have the appropriate access-control-origin settings.":"Не удается получить ответ от сервера. Возможно, проблема с настройками доступа",
"Please specify the protocol for":"Пожалуйста, укажите протокол для",
"Can't read swagger JSON from":"Не получается прочитать swagger json из",
"Finished Loading Resource Information. Rendering Swagger UI":"Загрузка информации о ресурсах завершена. Рендерим",
"Unable to read api":"Не удалось прочитать api",
"from path":"по адресу",
"server returned":"сервер сказал"
});

View File

@ -0,0 +1,53 @@
'use strict';
/* jshint quotmark: double */
window.SwaggerTranslator.learn({
"Warning: Deprecated":"Uyarı: Deprecated",
"Implementation Notes":"Gerçekleştirim Notları",
"Response Class":"Dönen Sınıf",
"Status":"Statü",
"Parameters":"Parametreler",
"Parameter":"Parametre",
"Value":"Değer",
"Description":"Açıklama",
"Parameter Type":"Parametre Tipi",
"Data Type":"Veri Tipi",
"Response Messages":"Dönüş Mesajı",
"HTTP Status Code":"HTTP Statü Kodu",
"Reason":"Gerekçe",
"Response Model":"Dönüş Modeli",
"Request URL":"İstek URL",
"Response Body":"Dönüş İçeriği",
"Response Code":"Dönüş Kodu",
"Response Headers":"Dönüş Üst Bilgileri",
"Hide Response":"Dönüşü Gizle",
"Headers":"Üst Bilgiler",
"Try it out!":"Dene!",
"Show/Hide":"Göster/Gizle",
"List Operations":"Operasyonları Listele",
"Expand Operations":"Operasyonları Aç",
"Raw":"Ham",
"can't parse JSON. Raw result":"JSON çözümlenemiyor. Ham sonuç",
"Model Schema":"Model Şema",
"Model":"Model",
"apply":"uygula",
"Username":"Kullanıcı Adı",
"Password":"Parola",
"Terms of service":"Servis şartları",
"Created by":"Oluşturan",
"See more at":"Daha fazlası için",
"Contact the developer":"Geliştirici ile İletişime Geçin",
"api version":"api versiyon",
"Response Content Type":"Dönüş İçerik Tipi",
"fetching resource":"kaynak getiriliyor",
"fetching resource list":"kaynak listesi getiriliyor",
"Explore":"Keşfet",
"Show Swagger Petstore Example Apis":"Swagger Petstore Örnek Api'yi Gör",
"Can't read from server. It may not have the appropriate access-control-origin settings.":"Sunucudan okuma yapılamıyor. Sunucu access-control-origin ayarlarınızı kontrol edin.",
"Please specify the protocol for":"Lütfen istenen adres için protokol belirtiniz",
"Can't read swagger JSON from":"Swagger JSON bu kaynaktan okunamıyor",
"Finished Loading Resource Information. Rendering Swagger UI":"Kaynak baglantısı tamamlandı. Swagger UI gösterime hazırlanıyor",
"Unable to read api":"api okunamadı",
"from path":"yoldan",
"server returned":"sunucuya dönüldü"
});

View File

@ -0,0 +1,39 @@
'use strict';
/**
* Translator for documentation pages.
*
* To enable translation you should include one of language-files in your index.html
* after <script src='lang/translator.js' type='text/javascript'></script>.
* For example - <script src='lang/ru.js' type='text/javascript'></script>
*
* If you wish to translate some new texsts you should do two things:
* 1. Add a new phrase pair ("New Phrase": "New Translation") into your language file (for example lang/ru.js). It will be great if you add it in other language files too.
* 2. Mark that text it templates this way <anyHtmlTag data-sw-translate>New Phrase</anyHtmlTag> or <anyHtmlTag data-sw-translate value='New Phrase'/>.
* The main thing here is attribute data-sw-translate. Only inner html, title-attribute and value-attribute are going to translate.
*
*/
window.SwaggerTranslator = {
_words:[],
translate: function(sel) {
var $this = this;
sel = sel || '[data-sw-translate]';
$(sel).each(function() {
$(this).html($this._tryTranslate($(this).html()));
$(this).val($this._tryTranslate($(this).val()));
$(this).attr('title', $this._tryTranslate($(this).attr('title')));
});
},
_tryTranslate: function(word) {
return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word;
},
learn: function(wordsMap) {
this._words = wordsMap;
}
};

View File

@ -0,0 +1,53 @@
'use strict';
/* jshint quotmark: double */
window.SwaggerTranslator.learn({
"Warning: Deprecated":"警告:已过时",
"Implementation Notes":"实现备注",
"Response Class":"响应类",
"Status":"状态",
"Parameters":"参数",
"Parameter":"参数",
"Value":"值",
"Description":"描述",
"Parameter Type":"参数类型",
"Data Type":"数据类型",
"Response Messages":"响应消息",
"HTTP Status Code":"HTTP状态码",
"Reason":"原因",
"Response Model":"响应模型",
"Request URL":"请求URL",
"Response Body":"响应体",
"Response Code":"响应码",
"Response Headers":"响应头",
"Hide Response":"隐藏响应",
"Headers":"头",
"Try it out!":"试一下!",
"Show/Hide":"显示/隐藏",
"List Operations":"显示操作",
"Expand Operations":"展开操作",
"Raw":"原始",
"can't parse JSON. Raw result":"无法解析JSON. 原始结果",
"Model Schema":"模型架构",
"Model":"模型",
"apply":"应用",
"Username":"用户名",
"Password":"密码",
"Terms of service":"服务条款",
"Created by":"创建者",
"See more at":"查看更多:",
"Contact the developer":"联系开发者",
"api version":"api版本",
"Response Content Type":"响应Content Type",
"fetching resource":"正在获取资源",
"fetching resource list":"正在获取资源列表",
"Explore":"浏览",
"Show Swagger Petstore Example Apis":"显示 Swagger Petstore 示例 Apis",
"Can't read from server. It may not have the appropriate access-control-origin settings.":"无法从服务器读取。可能没有正确设置access-control-origin。",
"Please specify the protocol for":"请指定协议:",
"Can't read swagger JSON from":"无法读取swagger JSON于",
"Finished Loading Resource Information. Rendering Swagger UI":"已加载资源信息。正在渲染Swagger UI",
"Unable to read api":"无法读取api",
"from path":"从路径",
"server returned":"服务器返回"
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -3,14 +3,37 @@ var popupMask;
var popupDialog;
var clientId;
var realm;
var redirect_uri;
var clientSecret;
var scopeSeparator;
var additionalQueryStringParams;
function handleLogin() {
var scopes = [];
if(window.swaggerUi.api.authSchemes
&& window.swaggerUi.api.authSchemes.oauth2
&& window.swaggerUi.api.authSchemes.oauth2.scopes) {
scopes = window.swaggerUi.api.authSchemes.oauth2.scopes;
var auths = window.swaggerUi.api.authSchemes || window.swaggerUi.api.securityDefinitions;
if(auths) {
var key;
var defs = auths;
for(key in defs) {
var auth = defs[key];
if(auth.type === 'oauth2' && auth.scopes) {
var scope;
if(Array.isArray(auth.scopes)) {
// 1.2 support
var i;
for(i = 0; i < auth.scopes.length; i++) {
scopes.push(auth.scopes[i]);
}
}
else {
// 2.0 support
for(scope in auth.scopes) {
scopes.push({scope: scope, description: auth.scopes[scope], OAuthSchemeKey: key});
}
}
}
}
}
if(window.swaggerUi.api
@ -18,36 +41,37 @@ function handleLogin() {
appName = window.swaggerUi.api.info.title;
}
if(popupDialog.length > 0)
popupDialog = popupDialog.last();
else {
popupDialog = $(
[
'<div class="api-popup-dialog">',
'<div class="api-popup-title">Select OAuth2.0 Scopes</div>',
'<div class="api-popup-content">',
'<p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.',
'<a href="#">Learn how to use</a>',
'</p>',
'<p><strong>' + appName + '</strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>',
'<ul class="api-popup-scopes">',
'</ul>',
'<p class="error-msg"></p>',
'<div class="api-popup-actions"><button class="api-popup-authbtn api-button green" type="button">Authorize</button><button class="api-popup-cancel api-button gray" type="button">Cancel</button></div>',
'</div>',
'</div>'].join(''));
$(document.body).append(popupDialog);
$('.api-popup-dialog').remove();
popupDialog = $(
[
'<div class="api-popup-dialog">',
'<div class="api-popup-title">Select OAuth2.0 Scopes</div>',
'<div class="api-popup-content">',
'<p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.',
'<a href="#">Learn how to use</a>',
'</p>',
'<p><strong>' + appName + '</strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>',
'<ul class="api-popup-scopes">',
'</ul>',
'<p class="error-msg"></p>',
'<div class="api-popup-actions"><button class="api-popup-authbtn api-button green" type="button">Authorize</button><button class="api-popup-cancel api-button gray" type="button">Cancel</button></div>',
'</div>',
'</div>'].join(''));
$(document.body).append(popupDialog);
popup = popupDialog.find('ul.api-popup-scopes').empty();
for (i = 0; i < scopes.length; i ++) {
scope = scopes[i];
str = '<li><input type="checkbox" id="scope_' + i + '" scope="' + scope.scope + '"/>' + '<label for="scope_' + i + '">' + scope.scope;
if (scope.description) {
str += '<br/><span class="api-scope-desc">' + scope.description + '</span>';
}
str += '</label></li>';
popup.append(str);
//TODO: only display applicable scopes (will need to pass them into handleLogin)
popup = popupDialog.find('ul.api-popup-scopes').empty();
for (i = 0; i < scopes.length; i ++) {
scope = scopes[i];
str = '<li><input type="checkbox" id="scope_' + i + '" scope="' + scope.scope + '"' +'" oauthtype="' + scope.OAuthSchemeKey +'"/>' + '<label for="scope_' + i + '">' + scope.scope ;
if (scope.description) {
if ($.map(auths, function(n, i) { return i; }).length > 1) //if we have more than one scheme, display schemes
str += '<br/><span class="api-scope-desc">' + scope.description + ' ('+ scope.OAuthSchemeKey+')' +'</span>';
else
str += '<br/><span class="api-scope-desc">' + scope.description + '</span>';
}
str += '</label></li>';
popup.append(str);
}
var $win = $(window),
@ -67,7 +91,11 @@ function handleLogin() {
popupDialog.find('button.api-popup-cancel').click(function() {
popupMask.hide();
popupDialog.hide();
popupDialog.empty();
popupDialog = [];
});
$('button.api-popup-authbtn').unbind();
popupDialog.find('button.api-popup-authbtn').click(function() {
popupMask.hide();
popupDialog.hide();
@ -75,34 +103,74 @@ function handleLogin() {
var authSchemes = window.swaggerUi.api.authSchemes;
var host = window.location;
var pathname = location.pathname.substring(0, location.pathname.lastIndexOf("/"));
var redirectUrl = host.protocol + '//' + host.host + pathname + "/o2c.html";
var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html';
var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl;
var url = null;
var scopes = []
var o = popup.find('input:checked');
var OAuthSchemeKeys = [];
var state;
for(k =0; k < o.length; k++) {
var scope = $(o[k]).attr('scope');
if (scopes.indexOf(scope) === -1)
scopes.push(scope);
var OAuthSchemeKey = $(o[k]).attr('oauthtype');
if (OAuthSchemeKeys.indexOf(OAuthSchemeKey) === -1)
OAuthSchemeKeys.push(OAuthSchemeKey);
}
//TODO: merge not replace if scheme is different from any existing
//(needs to be aware of schemes to do so correctly)
window.enabledScopes=scopes;
for (var key in authSchemes) {
if (authSchemes.hasOwnProperty(key) && OAuthSchemeKeys.indexOf(key) != -1) { //only look at keys that match this scope.
var flow = authSchemes[key].flow;
for (var key in authSchemes) {
if (authSchemes.hasOwnProperty(key)) {
var o = authSchemes[key].grantTypes;
for(var t in o) {
if(o.hasOwnProperty(t) && t === 'implicit') {
var dets = o[t];
url = dets.loginEndpoint.url + "?response_type=token";
window.swaggerUi.tokenName = dets.tokenName;
if(authSchemes[key].type === 'oauth2' && flow && (flow === 'implicit' || flow === 'accessCode')) {
var dets = authSchemes[key];
url = dets.authorizationUrl + '?response_type=' + (flow === 'implicit' ? 'token' : 'code');
window.swaggerUi.tokenName = dets.tokenName || 'access_token';
window.swaggerUi.tokenUrl = (flow === 'accessCode' ? dets.tokenUrl : null);
state = key;
}
else if(authSchemes[key].type === 'oauth2' && flow && (flow === 'application')) {
var dets = authSchemes[key];
window.swaggerUi.tokenName = dets.tokenName || 'access_token';
clientCredentialsFlow(scopes, dets.tokenUrl, key);
return;
}
else if(authSchemes[key].grantTypes) {
// 1.2 support
var o = authSchemes[key].grantTypes;
for(var t in o) {
if(o.hasOwnProperty(t) && t === 'implicit') {
var dets = o[t];
var ep = dets.loginEndpoint.url;
url = dets.loginEndpoint.url + '?response_type=token';
window.swaggerUi.tokenName = dets.tokenName;
}
else if (o.hasOwnProperty(t) && t === 'accessCode') {
var dets = o[t];
var ep = dets.tokenRequestEndpoint.url;
url = dets.tokenRequestEndpoint.url + '?response_type=code';
window.swaggerUi.tokenName = dets.tokenName;
}
}
}
}
}
var scopes = []
var o = $('.api-popup-scopes').find('input:checked');
for(k =0; k < o.length; k++) {
scopes.push($(o[k]).attr("scope"));
}
window.enabledScopes=scopes;
redirect_uri = redirectUrl;
url += '&redirect_uri=' + encodeURIComponent(redirectUrl);
url += '&realm=' + encodeURIComponent(realm);
url += '&client_id=' + encodeURIComponent(clientId);
url += '&scope=' + encodeURIComponent(scopes);
url += '&scope=' + encodeURIComponent(scopes.join(scopeSeparator));
url += '&state=' + encodeURIComponent(state);
for (var key in additionalQueryStringParams) {
url += '&' + key + '=' + encodeURIComponent(additionalQueryStringParams[key]);
}
window.open(url);
});
@ -114,8 +182,8 @@ function handleLogin() {
function handleLogout() {
for(key in window.authorizations.authz){
window.authorizations.remove(key)
for(key in window.swaggerUi.api.clientAuthorizations.authz){
window.swaggerUi.api.clientAuthorizations.remove(key)
}
window.enabledScopes = null;
$('.api-ic.ic-on').addClass('ic-off');
@ -130,18 +198,22 @@ function initOAuth(opts) {
var o = (opts||{});
var errors = [];
appName = (o.appName||errors.push("missing appName"));
appName = (o.appName||errors.push('missing appName'));
popupMask = (o.popupMask||$('#api-common-mask'));
popupDialog = (o.popupDialog||$('.api-popup-dialog'));
clientId = (o.clientId||errors.push("missing client id"));
realm = (o.realm||errors.push("missing realm"));
clientId = (o.clientId||errors.push('missing client id'));
clientSecret = (o.clientSecret||null);
realm = (o.realm||errors.push('missing realm'));
scopeSeparator = (o.scopeSeparator||' ');
additionalQueryStringParams = (o.additionalQueryStringParams||{});
if(errors.length > 0){
log("auth unable initialize oauth: " + errors);
log('auth unable initialize oauth: ' + errors);
return;
}
$('pre code').each(function(i, e) {hljs.highlightBlock(e)});
$('.api-ic').unbind();
$('.api-ic').click(function(s) {
if($(s.target).hasClass('ic-off'))
handleLogin();
@ -152,7 +224,60 @@ function initOAuth(opts) {
});
}
function onOAuthComplete(token) {
function clientCredentialsFlow(scopes, tokenUrl, OAuthSchemeKey) {
var params = {
'client_id': clientId,
'client_secret': clientSecret,
'scope': scopes.join(' '),
'grant_type': 'client_credentials'
}
$.ajax(
{
url : tokenUrl,
type: "POST",
data: params,
success:function(data, textStatus, jqXHR)
{
onOAuthComplete(data,OAuthSchemeKey);
},
error: function(jqXHR, textStatus, errorThrown)
{
onOAuthComplete("");
}
});
}
window.processOAuthCode = function processOAuthCode(data) {
var OAuthSchemeKey = data.state;
var params = {
'client_id': clientId,
'code': data.code,
'grant_type': 'authorization_code',
'redirect_uri': redirect_uri
};
if (clientSecret) {
params.client_secret = clientSecret;
}
$.ajax(
{
url : window.swaggerUi.tokenUrl,
type: "POST",
data: params,
success:function(data, textStatus, jqXHR)
{
onOAuthComplete(data, OAuthSchemeKey);
},
error: function(jqXHR, textStatus, errorThrown)
{
onOAuthComplete("");
}
});
};
window.onOAuthComplete = function onOAuthComplete(token,OAuthSchemeKey) {
if(token) {
if(token.error) {
var checkbox = $('input[type=checkbox],.secured')
@ -162,11 +287,14 @@ function onOAuthComplete(token) {
alert(token.error);
}
else {
var b = token[window.swaggerUi.tokenName];
var b = token[window.swaggerUi.tokenName];
if (!OAuthSchemeKey){
OAuthSchemeKey = token.state;
}
if(b){
// if all roles are satisfied
var o = null;
$.each($('.auth #api_information_panel'), function(k, v) {
$.each($('.auth .api-ic .api_information_panel'), function(k, v) {
var children = v;
if(children && children.childNodes) {
var requiredScopes = [];
@ -183,7 +311,7 @@ function onOAuthComplete(token) {
}
}
if(diff.length > 0){
o = v.parentNode;
o = v.parentNode.parentNode;
$(o.parentNode).find('.api-ic.ic-on').addClass('ic-off');
$(o.parentNode).find('.api-ic.ic-on').removeClass('ic-on');
@ -192,20 +320,19 @@ function onOAuthComplete(token) {
$(o).find('.api-ic').removeClass('ic-error');
}
else {
o = v.parentNode;
o = v.parentNode.parentNode;
$(o.parentNode).find('.api-ic.ic-off').addClass('ic-on');
$(o.parentNode).find('.api-ic.ic-off').removeClass('ic-off');
// all scopes are satisfied
$(o).find('.api-ic').addClass('ic-info');
$(o).find('.api-ic').removeClass('ic-warning');
$(o).find('.api-ic').removeClass('ic-error');
$(o).find('.api-ic').removeClass('ic-error');
}
}
});
window.authorizations.add("oauth2", new ApiKeyAuthorization("Authorization", "Bearer " + b, "header"));
window.swaggerUi.api.clientAuthorizations.add(OAuthSchemeKey, new SwaggerClient.ApiKeyAuthorization('Authorization', 'Bearer ' + b, 'header'));
}
}
}
}
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -10,6 +10,11 @@ qp = qp ? JSON.parse('{"' + qp.replace(/&/g, '","').replace(/=/g,'":"') + '"}',
function(key, value) {
return key===""?value:decodeURIComponent(value) }
):{}
window.opener.onOAuthComplete(qp);
if (window.opener.swaggerUi.tokenUrl)
window.opener.processOAuthCode(qp);
else
window.opener.onOAuthComplete(qp);
window.close();
</script>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long