From 57245211d894fcf68c54d12b087a0a66b2f1b4dd Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Sun, 8 Nov 2015 22:34:26 +0200 Subject: [PATCH] Added Swagger --- LICENSE | 2 +- app/Http/Controllers/AccountApiController.php | 1 + app/Http/Controllers/BaseAPIController.php | 30 +++++ app/Http/Controllers/InvoiceApiController.php | 15 +++ app/Http/Middleware/ApiCheck.php | 6 +- app/Ninja/Transformers/InvoiceTransformer.php | 17 ++- composer.json | 3 +- composer.lock | 110 +++++++++++++++- config/app.php | 2 +- config/swaggervel.php | 97 ++++++++++++++ resources/views/invoices/edit.blade.php | 2 +- resources/views/vendor/swaggervel/.gitkeep | 0 .../views/vendor/swaggervel/index.blade.php | 121 ++++++++++++++++++ 13 files changed, 395 insertions(+), 11 deletions(-) create mode 100644 config/swaggervel.php create mode 100644 resources/views/vendor/swaggervel/.gitkeep create mode 100644 resources/views/vendor/swaggervel/index.blade.php diff --git a/LICENSE b/LICENSE index eaa9f1e367..83e6795919 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ Attribution Assurance License -Copyright (c) 2014 by Hillel Coren +Copyright (c) 2015 by Hillel Coren http://www.hillelcoren.com All Rights Reserved diff --git a/app/Http/Controllers/AccountApiController.php b/app/Http/Controllers/AccountApiController.php index abe3a7c377..b085874bbf 100644 --- a/app/Http/Controllers/AccountApiController.php +++ b/app/Http/Controllers/AccountApiController.php @@ -15,6 +15,7 @@ use App\Ninja\Serializers\ArraySerializer; use App\Ninja\Transformers\AccountTransformer; use App\Ninja\Transformers\UserAccountTransformer; use App\Http\Controllers\BaseAPIController; +use Swagger\Annotations as SWG; class AccountApiController extends BaseAPIController { diff --git a/app/Http/Controllers/BaseAPIController.php b/app/Http/Controllers/BaseAPIController.php index 4873933899..ac10d66786 100644 --- a/app/Http/Controllers/BaseAPIController.php +++ b/app/Http/Controllers/BaseAPIController.php @@ -8,6 +8,36 @@ use League\Fractal\Resource\Item; use League\Fractal\Resource\Collection; use App\Ninja\Serializers\ArraySerializer; +/** + * @SWG\Swagger( + * schemes={"http","https"}, + * host="ninja.dev", + * basePath="/api/v1", + * @SWG\Info( + * version="1.0.0", + * title="Invoice Ninja API", + * description="An open-source invoicing and time-tracking app built with Laravel", + * termsOfService="", + * @SWG\Contact( + * email="contact@invoiceninja.com" + * ), + * @SWG\License( + * name="Attribution Assurance License", + * url="https://raw.githubusercontent.com/invoiceninja/invoiceninja/master/LICENSE" + * ) + * ), + * @SWG\ExternalDocumentation( + * description="Find out more about Invoice Ninja", + * url="https://www.invoiceninja.com" + * ), + * @SWG\SecurityScheme( + * securityDefinition="api_key", + * type="apiKey", + * in="header", + * name="TOKEN" + * ) + * ) + */ class BaseAPIController extends Controller { protected $manager; diff --git a/app/Http/Controllers/InvoiceApiController.php b/app/Http/Controllers/InvoiceApiController.php index b0d7aede07..26b28fae0b 100644 --- a/app/Http/Controllers/InvoiceApiController.php +++ b/app/Http/Controllers/InvoiceApiController.php @@ -24,6 +24,21 @@ class InvoiceApiController extends Controller $this->mailer = $mailer; } + /** + * @SWG\Get( + * path="/invoices", + * summary="List of invoices", + * @SWG\Response( + * response=200, + * description="A list with invoices", + * @SWG\Schema(type="array", @SWG\Items(ref="#/definitions/Invoice")) + * ), + * @SWG\Response( + * response="default", + * description="an ""unexpected"" error" + * ) + * ) + */ public function index($clientPublicId = false) { $invoices = Invoice::scope() diff --git a/app/Http/Middleware/ApiCheck.php b/app/Http/Middleware/ApiCheck.php index 9323b46056..5632e7de4e 100644 --- a/app/Http/Middleware/ApiCheck.php +++ b/app/Http/Middleware/ApiCheck.php @@ -35,7 +35,7 @@ class ApiCheck { Session::set('token_id', $token->id); } else { sleep(3); - return Response::make('Invalid token', 403, $headers); + return Response::json('Invalid token', 403, $headers); } } @@ -44,7 +44,7 @@ class ApiCheck { } if (!Utils::isPro() && !$loggingIn) { - return Response::make('API requires pro plan', 403, $headers); + return Response::json('API requires pro plan', 403, $headers); } else { $key = Auth::check() ? Auth::user()->account->id : $request->getClientIp(); @@ -68,7 +68,7 @@ class ApiCheck { if ($new_hour_throttle > $hour) { $wait = ceil($new_hour_throttle - $hour); sleep(1); - return Response::make("Please wait {$wait} second(s)", 403, $headers); + return Response::json("Please wait {$wait} second(s)", 403, $headers); } Cache::put("hour_throttle:{$key}", $new_hour_throttle, 10); diff --git a/app/Ninja/Transformers/InvoiceTransformer.php b/app/Ninja/Transformers/InvoiceTransformer.php index 0246ca4190..1395ddef30 100644 --- a/app/Ninja/Transformers/InvoiceTransformer.php +++ b/app/Ninja/Transformers/InvoiceTransformer.php @@ -4,8 +4,21 @@ use App\Models\Invoice; use League\Fractal; use League\Fractal\TransformerAbstract; +/** + * @SWG\Definition(definition="Invoice",required={"invoice_number"}, @SWG\Xml(name="Invoice")) + */ + class InvoiceTransformer extends TransformerAbstract { + /** + * @SWG\Property(property="id", type="integer", example=1) + * @SWG\Property(property="invoice_number", type="string", example="0001") + * @SWG\Property(property="amount", type="float", example=10) + * @SWG\Property(property="balance", type="float", example=10) + * @SWG\Property(property="client_id", type="integer", example=1) + * @SWG\Property(property="invoice_status_id", type="integer", example=1) + */ + protected $defaultIncludes = [ 'invoice_items', ]; @@ -18,11 +31,11 @@ class InvoiceTransformer extends TransformerAbstract public function transform(Invoice $invoice) { return [ - 'public_id' => (int) $invoice->public_id, + 'id' => (int) $invoice->public_id, 'invoice_number' => $invoice->invoice_number, 'amount' => (float) $invoice->amount, 'balance' => (float) $invoice->balance, - 'client_id' => (int) $invoice->client_id, + 'client_id' => (int) $invoice->client->public_id, 'invoice_status_id' => (int) $invoice->invoice_status_id, 'updated_at' => $invoice->updated_at, 'deleted_at' => $invoice->deleted_at, diff --git a/composer.json b/composer.json index 20c80fd000..85a1095557 100644 --- a/composer.json +++ b/composer.json @@ -66,7 +66,8 @@ "phpspec/phpspec": "~2.1", "codeception/codeception": "~2.0", "codeception/c3": "~2.0", - "fzaninotto/faker": "^1.5" + "fzaninotto/faker": "^1.5", + "jlapp/swaggervel": "master-dev" }, "autoload": { "classmap": [ diff --git a/composer.lock b/composer.lock index a2cbca370b..5280b5bfb5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "4c2d5d48a648e380f3acf2943b91e6bc", + "hash": "fb15622e77287d516219e55ebb01ea3e", "packages": [ { "name": "agmscode/omnipay-agms", @@ -2464,6 +2464,51 @@ ], "time": "2015-03-11 20:06:43" }, + { + "name": "jlapp/swaggervel", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/slampenny/Swaggervel.git", + "reference": "ea47fafde4984278e27a8044a1b1b0bcfd79130c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/slampenny/Swaggervel/zipball/ea47fafde4984278e27a8044a1b1b0bcfd79130c", + "reference": "ea47fafde4984278e27a8044a1b1b0bcfd79130c", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "zircote/swagger-php": "*" + }, + "type": "library", + "autoload": { + "psr-0": { + "Jlapp\\Swaggervel": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "jlapp", + "email": "jordan@jordanlapp.com" + } + ], + "description": "A great way to integrate Swagger into Laravel", + "keywords": [ + "L4", + "api", + "documentation", + "l5", + "laravel", + "swagger" + ], + "time": "2015-08-18 15:33:39" + }, { "name": "jsanc623/phpbenchtime", "version": "2.1.0", @@ -6968,6 +7013,66 @@ ], "description": "A Swiftmailer Transport for Postmark.", "time": "2015-03-19 13:06:11" + }, + { + "name": "zircote/swagger-php", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/zircote/swagger-php.git", + "reference": "f6624cc067d7894ec32943f5b94cf282c683f7c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zircote/swagger-php/zipball/f6624cc067d7894ec32943f5b94cf282c683f7c7", + "reference": "f6624cc067d7894ec32943f5b94cf282c683f7c7", + "shasum": "" + }, + "require": { + "doctrine/annotations": "*", + "php": ">=5.4.0", + "symfony/finder": "*" + }, + "require-dev": { + "zendframework/zend-form": "*" + }, + "bin": [ + "bin/swagger" + ], + "type": "library", + "autoload": { + "psr-4": { + "Swagger\\": "src" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache2" + ], + "authors": [ + { + "name": "Robert Allen", + "email": "zircote@gmail.com", + "homepage": "http://www.zircote.com" + }, + { + "name": "Bob Fanger", + "email": "bfanger@gmail.com", + "homepage": "http://bfanger.nl" + } + ], + "description": "Swagger-PHP - Generate interactive documentation for your RESTful API using phpdoc annotations", + "homepage": "https://github.com/zircote/swagger-php/", + "keywords": [ + "api", + "json", + "rest", + "service discovery" + ], + "time": "2015-10-18 13:05:54" } ], "packages-dev": [ @@ -8377,7 +8482,8 @@ "dercoder/omnipay-paysafecard": 20, "meebio/omnipay-secure-trading": 20, "labs7in0/omnipay-wechat": 20, - "laracasts/presenter": 20 + "laracasts/presenter": 20, + "jlapp/swaggervel": 20 }, "prefer-stable": false, "prefer-lowest": false, diff --git a/config/app.php b/config/app.php index e5fcf2eebc..4aa26f9194 100644 --- a/config/app.php +++ b/config/app.php @@ -150,7 +150,7 @@ return [ 'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider', 'Illuminate\Html\HtmlServiceProvider', 'Laravel\Socialite\SocialiteServiceProvider', - + 'Jlapp\Swaggervel\SwaggervelServiceProvider', /* * Application Service Providers... diff --git a/config/swaggervel.php b/config/swaggervel.php new file mode 100644 index 0000000000..341b47ed83 --- /dev/null +++ b/config/swaggervel.php @@ -0,0 +1,97 @@ + storage_path() . '/docs', + + /* + |-------------------------------------------------------------------------- + | Relative path to access parsed swagger annotations. + |-------------------------------------------------------------------------- + */ + 'doc-route' => 'docs', + + /* + |-------------------------------------------------------------------------- + | Absolute path to directory containing the swagger annotations are stored. + |-------------------------------------------------------------------------- + */ + "app-dir" => "app", + + /* + |-------------------------------------------------------------------------- + | Absolute path to directories that you would like to exclude from swagger generation + |-------------------------------------------------------------------------- + */ + "excludes" => array( + storage_path(), + base_path()."/tests", + base_path()."/resources/views", + base_path()."/config", + base_path()."/vendor" + ), + + /* + |-------------------------------------------------------------------------- + | Turn this off to remove swagger generation on production + |-------------------------------------------------------------------------- + */ + "generateAlways" => env('APP_DEBUG'), + + "api-key" => "auth_token", + + /* + |-------------------------------------------------------------------------- + | Edit to set the api's version number + |-------------------------------------------------------------------------- + */ + "default-api-version" => "v1", + + /* + |-------------------------------------------------------------------------- + | Edit to set the swagger version number + |-------------------------------------------------------------------------- + */ + "default-swagger-version" => "2.0", + + /* + |-------------------------------------------------------------------------- + | Edit to set the api's base path + |-------------------------------------------------------------------------- + */ + "default-base-path" => "", + + /* + |-------------------------------------------------------------------------- + | Edit to trust the proxy's ip address - needed for AWS Load Balancer + |-------------------------------------------------------------------------- + */ + "behind-reverse-proxy" => false, + /* + |-------------------------------------------------------------------------- + | Uncomment to add response headers when swagger is generated + |-------------------------------------------------------------------------- + */ + /*"viewHeaders" => array( + 'Content-Type' => 'text/plain' + ),*/ + + /* + |-------------------------------------------------------------------------- + | Uncomment to add request headers when swagger performs requests + |-------------------------------------------------------------------------- + */ + /*"requestHeaders" => array( + 'TestMe' => 'testValue' + ),*/ +); diff --git a/resources/views/invoices/edit.blade.php b/resources/views/invoices/edit.blade.php index a2c90a1d9d..366523bd7e 100644 --- a/resources/views/invoices/edit.blade.php +++ b/resources/views/invoices/edit.blade.php @@ -838,7 +838,7 @@ function createInvoiceModel() { var invoice = ko.toJS(window.model).invoice; invoice.is_pro = {{ Auth::user()->isPro() ? 'true' : 'false' }}; - //invoice.is_quote = {{ $entityType == ENTITY_QUOTE ? 'true' : 'false' }}; + invoice.is_quote = {{ $entityType == ENTITY_QUOTE ? 'true' : 'false' }}; invoice.contact = _.findWhere(invoice.client.contacts, {send_invoice: true}); if (invoice.is_recurring) { diff --git a/resources/views/vendor/swaggervel/.gitkeep b/resources/views/vendor/swaggervel/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/resources/views/vendor/swaggervel/index.blade.php b/resources/views/vendor/swaggervel/index.blade.php new file mode 100644 index 0000000000..09d91916a8 --- /dev/null +++ b/resources/views/vendor/swaggervel/index.blade.php @@ -0,0 +1,121 @@ + + + + + + Swagger UI + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+
+ +