From 470a8575c0ea954d64c0b20cbce375b32306e374 Mon Sep 17 00:00:00 2001 From: Casper Meijn Date: Sun, 6 Nov 2022 13:00:41 +0100 Subject: [PATCH] Update to nelmio/api-doc 3.0 Convert ApiDoc to Swagger --- app/config/config.yml | 21 +- app/config/routing.yml | 2 +- composer.json | 2 +- composer.lock | 473 +++++++++--- .../Controller/AnnotationRestController.php | 106 ++- .../Controller/ConfigRestController.php | 12 +- .../Controller/EntryRestController.php | 708 +++++++++++++++--- .../Controller/SearchRestController.php | 43 +- .../Controller/TagRestController.php | 71 +- .../Controller/TaggingRuleRestController.php | 12 +- .../Controller/UserRestController.php | 54 +- .../Controller/WallabagRestController.php | 21 +- .../common/Developer/howto_app.html.twig | 2 +- .../themes/common/Developer/index.html.twig | 2 +- 14 files changed, 1264 insertions(+), 265 deletions(-) diff --git a/app/config/config.yml b/app/config/config.yml index cced41f53..7dc3698e2 100644 --- a/app/config/config.yml +++ b/app/config/config.yml @@ -131,11 +131,22 @@ fos_rest: - { path: '^/', priorities: ['text/html', '*/*'], fallback_format: html, prefer_extension: false } nelmio_api_doc: - sandbox: - enabled: false - cache: - enabled: true - name: wallabag API documentation + areas: + default: + disable_default_routes: true + documentation: + info: + title: wallabag API documentation + description: This is the API documentation of wallabag + version: 2.x + securityDefinitions: + Bearer: + type: apiKey + description: 'Value: Bearer {jwt}' + name: Authorization + in: header + security: + - Bearer: [] nelmio_cors: defaults: diff --git a/app/config/routing.yml b/app/config/routing.yml index 86c6602e6..fdf6a0d30 100644 --- a/app/config/routing.yml +++ b/app/config/routing.yml @@ -22,7 +22,7 @@ app: type: annotation doc-api: - resource: "@NelmioApiDocBundle/Resources/config/routing.yml" + resource: "@NelmioApiDocBundle/Resources/config/routing/swaggerui.xml" prefix: /api/doc rest : diff --git a/composer.json b/composer.json index b728923a4..d3c8ee077 100644 --- a/composer.json +++ b/composer.json @@ -86,7 +86,7 @@ "liip/theme-bundle": "^1.4.6", "mgargano/simplehtmldom": "~1.5", "mnapoli/piwik-twig-extension": "^3.0", - "nelmio/api-doc-bundle": "^2.13.2", + "nelmio/api-doc-bundle": "^3.0", "nelmio/cors-bundle": "~1.5", "ocramius/proxy-manager": "^2.1.1", "pagerfanta/pagerfanta": "^2.4", diff --git a/composer.lock b/composer.lock index 8afe59f54..56e4d176d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e5c2882514fa196e705c3adfc178e1e5", + "content-hash": "25b03b05eeff545aa68314784c949834", "packages": [ { "name": "babdev/pagerfanta-bundle", @@ -2104,6 +2104,49 @@ }, "time": "2022-02-21T09:13:59+00:00" }, + { + "name": "exsyst/swagger", + "version": "v0.4.2", + "source": { + "type": "git", + "url": "https://github.com/GuilhemN/swagger.git", + "reference": "5d4ad40fe816b7783adc090b64fba6c392be64bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GuilhemN/swagger/zipball/5d4ad40fe816b7783adc090b64fba6c392be64bc", + "reference": "5d4ad40fe816b7783adc090b64fba6c392be64bc", + "shasum": "" + }, + "require": { + "php": "^7.0|^8.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.1.8|^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "EXSyst\\Component\\Swagger\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilhem Niot", + "email": "guilhem@gniot.fr" + } + ], + "description": "A php library to manipulate Swagger specifications", + "support": { + "issues": "https://github.com/GuilhemN/swagger/issues", + "source": "https://github.com/GuilhemN/swagger/tree/v0.4.2" + }, + "time": "2020-11-19T17:14:18+00:00" + }, { "name": "fig/link-util", "version": "1.1.2", @@ -5923,59 +5966,6 @@ }, "time": "2014-01-05T18:17:34+00:00" }, - { - "name": "michelf/php-markdown", - "version": "1.9.1", - "source": { - "type": "git", - "url": "https://github.com/michelf/php-markdown.git", - "reference": "5024d623c1a057dcd2d076d25b7d270a1d0d55f3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/michelf/php-markdown/zipball/5024d623c1a057dcd2d076d25b7d270a1d0d55f3", - "reference": "5024d623c1a057dcd2d076d25b7d270a1d0d55f3", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": ">=4.3 <5.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "Michelf\\": "Michelf/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Michel Fortin", - "email": "michel.fortin@michelf.ca", - "homepage": "https://michelf.ca/", - "role": "Developer" - }, - { - "name": "John Gruber", - "homepage": "https://daringfireball.net/" - } - ], - "description": "PHP Markdown", - "homepage": "https://michelf.ca/projects/php-markdown/", - "keywords": [ - "markdown" - ], - "support": { - "issues": "https://github.com/michelf/php-markdown/issues", - "source": "https://github.com/michelf/php-markdown/tree/1.9.1" - }, - "time": "2021-11-24T02:52:38+00:00" - }, { "name": "mnapoli/piwik-twig-extension", "version": "3.0.0", @@ -6104,65 +6094,72 @@ }, { "name": "nelmio/api-doc-bundle", - "version": "2.13.5", - "target-dir": "Nelmio/ApiDocBundle", + "version": "v3.10.1", "source": { "type": "git", "url": "https://github.com/nelmio/NelmioApiDocBundle.git", - "reference": "158149568863c688abfa3df94037257bbed628ed" + "reference": "f5fb7a408824d44d36453f6edff20f9fa05296a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/158149568863c688abfa3df94037257bbed628ed", - "reference": "158149568863c688abfa3df94037257bbed628ed", + "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/f5fb7a408824d44d36453f6edff20f9fa05296a1", + "reference": "f5fb7a408824d44d36453f6edff20f9fa05296a1", "shasum": "" }, "require": { - "michelf/php-markdown": "~1.4", - "php": ">=5.4", - "symfony/console": "~2.3|~3.0|~4.0", - "symfony/framework-bundle": "~2.3|~3.0|~4.0", - "symfony/twig-bundle": "~2.3|~3.0|~4.0" + "exsyst/swagger": "^0.4.1", + "php": ">=7.1.3", + "phpdocumentor/reflection-docblock": "^3.1|^4.0|^5.0", + "symfony/framework-bundle": "^3.4|^4.0|^5.0", + "symfony/options-resolver": "^3.4.4|^4.0|^5.0", + "symfony/property-info": "^3.4|^4.0|^5.0", + "zircote/swagger-php": "^2.0.9" }, "conflict": { - "jms/serializer": "<0.12", - "jms/serializer-bundle": "<0.11", - "symfony/symfony": "~2.7.8", - "twig/twig": "<1.12" + "symfony/framework-bundle": "4.2.7" }, "require-dev": { - "doctrine/doctrine-bundle": "~1.5", - "doctrine/orm": "~2.3", - "dunglas/api-bundle": "~1.0", - "friendsofsymfony/rest-bundle": "~1.0|~2.0", - "jms/serializer-bundle": ">=0.11", - "sensio/framework-extra-bundle": "~3.0", - "symfony/browser-kit": "~2.3|~3.0|~4.0", - "symfony/css-selector": "~2.3|~3.0|~4.0", - "symfony/finder": "~2.3|~3.0|~4.0", - "symfony/form": "~2.3|~3.0|~4.0", - "symfony/phpunit-bridge": "~2.7|~3.0|~4.0", - "symfony/serializer": "~2.7|~3.0|~4.0", - "symfony/validator": "~2.3|~3.0|~4.0", - "symfony/yaml": "~2.3|~3.0|~4.0" + "api-platform/core": "^2.1.2", + "doctrine/annotations": "^1.2", + "doctrine/common": "^2.4", + "friendsofsymfony/rest-bundle": "^2.0|^3.0", + "jms/serializer": "^1.14|^3.0", + "jms/serializer-bundle": "^2.3|^3.0", + "sensio/framework-extra-bundle": "^3.0.13|^4.0|^5.0", + "symfony/asset": "^3.4|^4.0|^5.0", + "symfony/browser-kit": "^3.4|^4.0|^5.0", + "symfony/cache": "^3.4|^4.0|^5.0", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/console": "^3.4|^4.0|^5.0", + "symfony/dom-crawler": "^3.4|^4.0|^5.0", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/form": "^3.4|^4.0|^5.0", + "symfony/phpunit-bridge": "^3.4.24|^4.0|^5.0", + "symfony/property-access": "^3.4|^4.0|^5.0", + "symfony/routing": "^3.4.42|^4.0|^5.0", + "symfony/stopwatch": "^3.4|^4.0|^5.0", + "symfony/templating": "^3.4|^4.0|^5.0", + "symfony/twig-bundle": "^3.4|^4.0|^5.0", + "symfony/validator": "^3.4|^4.0|^5.0", + "willdurand/hateoas-bundle": "^1.0|^2.0" }, "suggest": { - "dunglas/api-bundle": "For making use of resources definitions of DunglasApiBundle.", - "friendsofsymfony/rest-bundle": "For making use of REST information in the doc.", - "jms/serializer": "For making use of serializer information in the doc.", - "symfony/form": "For using form definitions as input.", - "symfony/validator": "For making use of validator information in the doc." + "api-platform/core": "For using an API oriented framework.", + "friendsofsymfony/rest-bundle": "For using the parameters annotations." }, "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-2.x": "2.13-dev" + "dev-3.x": "3.7.x-dev" } }, "autoload": { - "psr-0": { - "Nelmio\\ApiDocBundle": "" - } + "psr-4": { + "Nelmio\\ApiDocBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6187,9 +6184,9 @@ ], "support": { "issues": "https://github.com/nelmio/NelmioApiDocBundle/issues", - "source": "https://github.com/nelmio/NelmioApiDocBundle/tree/2.13.5" + "source": "https://github.com/nelmio/NelmioApiDocBundle/tree/v3.10.1" }, - "time": "2021-03-23T07:09:33+00:00" + "time": "2021-12-11T13:22:14+00:00" }, { "name": "nelmio/cors-bundle", @@ -7395,6 +7392,171 @@ }, "time": "2022-01-14T16:27:10+00:00" }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.6.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2" + }, + "time": "2022-10-14T12:47:21+00:00" + }, { "name": "phpseclib/phpseclib", "version": "3.0.17", @@ -11358,6 +11520,64 @@ ], "time": "2021-04-19T16:34:45+00:00" }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + }, { "name": "willdurand/hateoas", "version": "3.8.0", @@ -11590,6 +11810,71 @@ "source": "https://github.com/willdurand/Negotiation/tree/3.1.0" }, "time": "2022-01-30T20:08:53+00:00" + }, + { + "name": "zircote/swagger-php", + "version": "2.1.2", + "source": { + "type": "git", + "url": "https://github.com/zircote/swagger-php.git", + "reference": "f144351118e6bcc04a275f490d7e359a3dd62586" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zircote/swagger-php/zipball/f144351118e6bcc04a275f490d7e359a3dd62586", + "reference": "f144351118e6bcc04a275f490d7e359a3dd62586", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.7", + "php": ">=7.2", + "symfony/finder": ">=3.4" + }, + "require-dev": { + "phpunit/phpunit": "^8 || ^9", + "squizlabs/php_codesniffer": ">=2.7" + }, + "bin": [ + "bin/swagger" + ], + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Swagger\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "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" + ], + "support": { + "issues": "https://github.com/zircote/swagger-php/issues", + "source": "https://github.com/zircote/swagger-php/tree/2.1.2" + }, + "time": "2022-06-18T00:00:23+00:00" } ], "packages-dev": [ @@ -12923,5 +13208,5 @@ "platform-overrides": { "php": "7.4.29" }, - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.2.0" } diff --git a/src/Wallabag/ApiBundle/Controller/AnnotationRestController.php b/src/Wallabag/ApiBundle/Controller/AnnotationRestController.php index 58c942d40..61604e7ef 100644 --- a/src/Wallabag/ApiBundle/Controller/AnnotationRestController.php +++ b/src/Wallabag/ApiBundle/Controller/AnnotationRestController.php @@ -2,8 +2,9 @@ namespace Wallabag\ApiBundle\Controller; -use Nelmio\ApiDocBundle\Annotation\ApiDoc; +use Nelmio\ApiDocBundle\Annotation\Operation; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; +use Swagger\Annotations as SWG; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Wallabag\AnnotationBundle\Entity\Annotation; @@ -14,10 +15,21 @@ class AnnotationRestController extends WallabagRestController /** * Retrieve annotations for an entry. * - * @ApiDoc( - * requirements={ - * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} - * } + * @Operation( + * tags={"Annotations"}, + * summary="Retrieve annotations for an entry.", + * @SWG\Parameter( + * name="entry", + * in="path", + * description="The entry ID", + * required=true, + * pattern="\w+", + * type="integer" + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse @@ -34,12 +46,46 @@ class AnnotationRestController extends WallabagRestController /** * Creates a new annotation. * - * @ApiDoc( - * requirements={ - * {"name"="ranges", "dataType"="array", "requirement"="\w+", "description"="The range array for the annotation"}, - * {"name"="quote", "dataType"="string", "description"="The annotated text"}, - * {"name"="text", "dataType"="string", "required"=true, "description"="Content of annotation"}, - * } + * @Operation( + * tags={"Annotations"}, + * summary="Creates a new annotation.", + * @SWG\Parameter( + * name="entry", + * in="path", + * description="The entry ID", + * required=true, + * pattern="\w+", + * type="integer" + * ), + * @SWG\Parameter( + * name="ranges", + * in="body", + * description="The range array for the annotation", + * required=false, + * pattern="\w+", + * @SWG\Schema( + * type="array", + * @SWG\Items(type="string") + * ) + * ), + * @SWG\Parameter( + * name="quote", + * in="body", + * description="The annotated text", + * required=false, + * @SWG\Schema(type="string") + * ), + * @SWG\Parameter( + * name="text", + * in="body", + * description="Content of annotation", + * required=true, + * @SWG\Schema(type="string") + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse @@ -57,10 +103,21 @@ class AnnotationRestController extends WallabagRestController /** * Updates an annotation. * - * @ApiDoc( - * requirements={ - * {"name"="annotation", "dataType"="string", "requirement"="\w+", "description"="The annotation ID"} - * } + * @Operation( + * tags={"Annotations"}, + * summary="Updates an annotation.", + * @SWG\Parameter( + * name="annotation", + * in="path", + * description="The annotation ID", + * required=true, + * pattern="\w+", + * type="string" + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @ParamConverter("annotation", class="Wallabag\AnnotationBundle\Entity\Annotation") @@ -80,10 +137,21 @@ class AnnotationRestController extends WallabagRestController /** * Removes an annotation. * - * @ApiDoc( - * requirements={ - * {"name"="annotation", "dataType"="string", "requirement"="\w+", "description"="The annotation ID"} - * } + * @Operation( + * tags={"Annotations"}, + * summary="Removes an annotation.", + * @SWG\Parameter( + * name="annotation", + * in="path", + * description="The annotation ID", + * required=true, + * pattern="\w+", + * type="string" + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @ParamConverter("annotation", class="Wallabag\AnnotationBundle\Entity\Annotation") diff --git a/src/Wallabag/ApiBundle/Controller/ConfigRestController.php b/src/Wallabag/ApiBundle/Controller/ConfigRestController.php index 24c26103e..ac694e48e 100644 --- a/src/Wallabag/ApiBundle/Controller/ConfigRestController.php +++ b/src/Wallabag/ApiBundle/Controller/ConfigRestController.php @@ -4,7 +4,8 @@ namespace Wallabag\ApiBundle\Controller; use JMS\Serializer\SerializationContext; use JMS\Serializer\SerializerInterface; -use Nelmio\ApiDocBundle\Annotation\ApiDoc; +use Nelmio\ApiDocBundle\Annotation\Operation; +use Swagger\Annotations as SWG; use Symfony\Component\HttpFoundation\JsonResponse; class ConfigRestController extends WallabagRestController @@ -12,7 +13,14 @@ class ConfigRestController extends WallabagRestController /** * Retrieve configuration for current user. * - * @ApiDoc() + * @Operation( + * tags={"Config"}, + * summary="Retrieve configuration for current user.", + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) + * ) * * @return JsonResponse */ diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php index 3b898368c..47353b301 100644 --- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php +++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php @@ -4,8 +4,9 @@ namespace Wallabag\ApiBundle\Controller; use Hateoas\Configuration\Route; use Hateoas\Representation\Factory\PagerfantaFactory; -use Nelmio\ApiDocBundle\Annotation\ApiDoc; +use Nelmio\ApiDocBundle\Annotation\Operation; use Pagerfanta\Pagerfanta; +use Swagger\Annotations as SWG; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -31,14 +32,52 @@ class EntryRestController extends WallabagRestController * * @todo Remove that `return_id` in the next major release * - * @ApiDoc( - * parameters={ - * {"name"="return_id", "dataType"="string", "required"=false, "format"="1 or 0", "description"="Set 1 if you want to retrieve ID in case entry(ies) exists, 0 by default"}, - * {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="DEPRECATED, use hashed_url instead"}, - * {"name"="urls", "dataType"="string", "required"=false, "format"="An array of urls (?urls[]=http...&urls[]=http...)", "description"="DEPRECATED, use hashed_urls instead"}, - * {"name"="hashed_url", "dataType"="string", "required"=false, "format"="A hashed url", "description"="Hashed url using SHA1 to check if it exists"}, - * {"name"="hashed_urls", "dataType"="string", "required"=false, "format"="An array of hashed urls (?hashed_urls[]=xxx...&hashed_urls[]=xxx...)", "description"="An array of hashed urls using SHA1 to check if they exist"} - * } + * @Operation( + * tags={"Entries"}, + * summary="Check if an entry exist by url.", + * @SWG\Parameter( + * name="return_id", + * in="body", + * description="Set 1 if you want to retrieve ID in case entry(ies) exists, 0 by default", + * required=false, + * @SWG\Schema( + * type="string", + * enum={"1", "0"}, + * default="0" + * ) + * ), + * @SWG\Parameter( + * name="url", + * in="body", + * description="DEPRECATED, use hashed_url instead. An url", + * required=true, + * @SWG\Schema(type="string") + * ), + * @SWG\Parameter( + * name="urls", + * in="body", + * description="DEPRECATED, use hashed_urls instead. An array of urls (?urls[]=http...&urls[]=http...)", + * required=false, + * @SWG\Schema(type="string") + * ), + * @SWG\Parameter( + * name="hashed_url", + * in="body", + * description="Hashed url using SHA1 to check if it exists. A hashed url", + * required=false, + * @SWG\Schema(type="string") + * ), + * @SWG\Parameter( + * name="hashed_urls", + * in="body", + * description="An array of hashed urls using SHA1 to check if they exist. An array of hashed urls (?hashed_urls[]=xxx...&hashed_urls[]=xxx...)", + * required=false, + * @SWG\Schema(type="string") + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse @@ -107,20 +146,130 @@ class EntryRestController extends WallabagRestController /** * Retrieve all entries. It could be filtered by many options. * - * @ApiDoc( - * parameters={ - * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by archived status."}, - * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by starred status."}, - * {"name"="sort", "dataType"="string", "required"=false, "format"="'created' or 'updated' or 'archived', default 'created'", "description"="sort entries by date."}, - * {"name"="order", "dataType"="string", "required"=false, "format"="'asc' or 'desc', default 'desc'", "description"="order of sort."}, - * {"name"="page", "dataType"="integer", "required"=false, "format"="default '1'", "description"="what page you want."}, - * {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."}, - * {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."}, - * {"name"="since", "dataType"="integer", "required"=false, "format"="default '0'", "description"="The timestamp since when you want entries updated."}, - * {"name"="public", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by entries with a public link"}, - * {"name"="detail", "dataType"="string", "required"=false, "format"="metadata or full, metadata by default", "description"="include content field if 'full'. 'full' by default for backward compatibility."}, - * {"name"="domain_name", "dataType"="string", "required"=false, "format"="example.com", "description"="filter entries with the given domain name"}, - * } + * @Operation( + * tags={"Entries"}, + * summary="Retrieve all entries. It could be filtered by many options.", + * @SWG\Parameter( + * name="archive", + * in="body", + * description="filter by archived status. all entries by default.", + * required=false, + * @SWG\Schema( + * type="integer", + * enum={"1", "0"}, + * default="0" + * ) + * ), + * @SWG\Parameter( + * name="starred", + * in="body", + * description="filter by starred status. all entries by default", + * required=false, + * @SWG\Schema( + * type="integer", + * enum={"1", "0"}, + * default="0" + * ) + * ), + * @SWG\Parameter( + * name="sort", + * in="body", + * description="sort entries by date.", + * required=false, + * @SWG\Schema( + * type="string", + * enum={"created", "updated", "archived"}, + * default="created" + * ) + * ), + * @SWG\Parameter( + * name="order", + * in="body", + * description="order of sort.", + * required=false, + * @SWG\Schema( + * type="string", + * enum={"asc", "desc"}, + * default="desc" + * ) + * ), + * @SWG\Parameter( + * name="page", + * in="body", + * description="what page you want.", + * required=false, + * @SWG\Schema( + * type="integer", + * default=1 + * ) + * ), + * @SWG\Parameter( + * name="perPage", + * in="body", + * description="results per page.", + * required=false, + * @SWG\Schema( + * type="integer", + * default=30 + * ) + * ), + * @SWG\Parameter( + * name="tags", + * in="body", + * description="a list of tags url encoded. Will returns entries that matches ALL tags.", + * required=false, + * format="comma-seperated", + * @SWG\Schema( + * type="string", + * example="api,rest" + * ) + * ), + * @SWG\Parameter( + * name="since", + * in="body", + * description="The timestamp since when you want entries updated.", + * required=false, + * @SWG\Schema( + * type="integer", + * default=0 + * ) + * ), + * @SWG\Parameter( + * name="public", + * in="body", + * description="filter by entries with a public link. all entries by default", + * required=false, + * @SWG\Schema( + * type="integer", + * enum={"1", "0"}, + * default="0" + * ) + * ), + * @SWG\Parameter( + * name="detail", + * in="body", + * description="include content field if 'full'. 'full' by default for backward compatibility.", + * required=false, + * @SWG\Schema( + * type="string", + * enum={"metadata", "full"}, + * default="full" + * ) + * ), + * @SWG\Parameter( + * name="domain_name", + * in="body", + * description="filter entries with the given domain name", + * required=false, + * @SWG\Schema( + * type="string", + * example="example.com", + * ) + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse @@ -189,10 +338,21 @@ class EntryRestController extends WallabagRestController /** * Retrieve a single entry. * - * @ApiDoc( - * requirements={ - * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} - * } + * @Operation( + * tags={"Entries"}, + * summary="Retrieve a single entry.", + * @SWG\Parameter( + * name="entry", + * in="path", + * description="The entry ID", + * required=true, + * pattern="\w+", + * type="integer" + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse @@ -208,10 +368,29 @@ class EntryRestController extends WallabagRestController /** * Retrieve a single entry as a predefined format. * - * @ApiDoc( - * requirements={ - * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} - * } + * @Operation( + * tags={"Entries"}, + * summary="Retrieve a single entry as a predefined format.", + * @SWG\Parameter( + * name="entry", + * in="path", + * description="The entry ID", + * required=true, + * pattern="\w+", + * type="integer" + * ), + * @SWG\Parameter( + * name="_format", + * in="path", + * description="", + * required=true, + * type="string", + * enum={"xml", "json", "txt", "csv", "pdf", "epub", "mobi"}, + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return Response @@ -231,10 +410,20 @@ class EntryRestController extends WallabagRestController /** * Handles an entries list and delete URL. * - * @ApiDoc( - * parameters={ - * {"name"="urls", "dataType"="string", "required"=true, "format"="A JSON array of urls [{'url': 'http://...'}, {'url': 'http://...'}]", "description"="Urls (as an array) to delete."} - * } + * @Operation( + * tags={"Entries"}, + * summary="Handles an entries list and delete URL.", + * @SWG\Parameter( + * name="urls", + * in="body", + * description="Urls (as an array) to delete. A JSON array of urls [{'url': 'http://...'}, {'url': 'http://...'}]", + * required=true, + * @SWG\Schema(type="string") + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse @@ -278,10 +467,20 @@ class EntryRestController extends WallabagRestController /** * Handles an entries list and create URL. * - * @ApiDoc( - * parameters={ - * {"name"="urls", "dataType"="string", "required"=true, "format"="A JSON array of urls [{'url': 'http://...'}, {'url': 'http://...'}]", "description"="Urls (as an array) to create."} - * } + * @Operation( + * tags={"Entries"}, + * summary="Handles an entries list and create URL.", + * @SWG\Parameter( + * name="urls", + * in="formData", + * description="Urls (as an array) to create. A JSON array of urls [{'url': 'http://...'}, {'url': 'http://...'}]", + * required=true, + * type="string" + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @throws HttpException When limit is reached @@ -339,21 +538,132 @@ class EntryRestController extends WallabagRestController * If you want to provide the HTML content (which means wallabag won't fetch it from the url), you must provide `content`, `title` & `url` fields **non-empty**. * Otherwise, content will be fetched as normal from the url and values will be overwritten. * - * @ApiDoc( - * parameters={ - * {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."}, - * {"name"="title", "dataType"="string", "required"=false, "description"="Optional, we'll get the title from the page."}, - * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."}, - * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already archived"}, - * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already starred"}, - * {"name"="content", "dataType"="string", "required"=false, "description"="Content of the entry"}, - * {"name"="language", "dataType"="string", "required"=false, "description"="Language of the entry"}, - * {"name"="preview_picture", "dataType"="string", "required"=false, "description"="Preview picture of the entry"}, - * {"name"="published_at", "dataType"="datetime|integer", "format"="YYYY-MM-DDTHH:II:SS+TZ or a timestamp", "required"=false, "description"="Published date of the entry"}, - * {"name"="authors", "dataType"="string", "format"="Name Firstname,author2,author3", "required"=false, "description"="Authors of the entry"}, - * {"name"="public", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="will generate a public link for the entry"}, - * {"name"="origin_url", "dataType"="string", "required"=false, "format"="http://www.test.com/article.html", "description"="Origin url for the entry (from where you found it)."}, - * } + * @Operation( + * tags={"Entries"}, + * summary="Create an entry.", + * @SWG\Parameter( + * name="url", + * in="body", + * description="Url for the entry.", + * required=true, + * @SWG\Schema( + * type="string", + * example="http://www.test.com/article.html" + * ) + * ), + * @SWG\Parameter( + * name="title", + * in="body", + * description="Optional, we'll get the title from the page.", + * required=false, + * @SWG\Schema( + * type="string", + * ) + * ), + * @SWG\Parameter( + * name="tags", + * in="body", + * description="a comma-separated list of tags.", + * required=false, + * @SWG\Schema( + * type="string", + * example="tag1,tag2,tag3" + * ) + * ), + * @SWG\Parameter( + * name="archive", + * in="body", + * description="entry already archived", + * required=false, + * @SWG\Schema( + * type="integer", + * enum={"1", "0"}, + * default="0" + * ) + * ), + * @SWG\Parameter( + * name="starred", + * in="body", + * description="entry already starred", + * required=false, + * @SWG\Schema( + * type="integer", + * enum={"1", "0"}, + * default="0" + * ) + * ), + * @SWG\Parameter( + * name="content", + * in="body", + * description="Content of the entry", + * required=false, + * @SWG\Schema( + * type="string" + * ) + * ), + * @SWG\Parameter( + * name="language", + * in="body", + * description="Language of the entry", + * required=false, + * @SWG\Schema( + * type="string" + * ) + * ), + * @SWG\Parameter( + * name="preview_picture", + * in="body", + * description="Preview picture of the entry", + * required=false, + * @SWG\Schema( + * type="string" + * ) + * ), + * @SWG\Parameter( + * name="published_at", + * in="body", + * description="Published date of the entry", + * required=false, + * format="YYYY-MM-DDTHH:II:SS+TZ or a timestamp (integer)", + * @SWG\Schema( + * type="string", + * ) + * ), + * @SWG\Parameter( + * name="authors", + * in="body", + * description="Authors of the entry", + * required=false, + * @SWG\Schema( + * type="string", + * example="Name Firstname,author2,author3" + * ) + * ), + * @SWG\Parameter( + * name="public", + * in="body", + * description="will generate a public link for the entry", + * required=false, + * @SWG\Schema( + * type="integer", + * enum={"1", "0"}, + * default="0" + * ) + * ), + * @SWG\Parameter( + * name="origin_url", + * in="body", + * description="Origin url for the entry (from where you found it).", + * required=false, + * @SWG\Schema( + * type="string", + * example="http://www.test.com/article.html" + * ) + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse @@ -443,23 +753,120 @@ class EntryRestController extends WallabagRestController /** * Change several properties of an entry. * - * @ApiDoc( - * requirements={ - * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} - * }, - * parameters={ - * {"name"="title", "dataType"="string", "required"=false}, - * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."}, - * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="archived the entry."}, - * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="starred the entry."}, - * {"name"="content", "dataType"="string", "required"=false, "description"="Content of the entry"}, - * {"name"="language", "dataType"="string", "required"=false, "description"="Language of the entry"}, - * {"name"="preview_picture", "dataType"="string", "required"=false, "description"="Preview picture of the entry"}, - * {"name"="published_at", "dataType"="datetime|integer", "format"="YYYY-MM-DDTHH:II:SS+TZ or a timestamp", "required"=false, "description"="Published date of the entry"}, - * {"name"="authors", "dataType"="string", "format"="Name Firstname,author2,author3", "required"=false, "description"="Authors of the entry"}, - * {"name"="public", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="will generate a public link for the entry"}, - * {"name"="origin_url", "dataType"="string", "required"=false, "format"="http://www.test.com/article.html", "description"="Origin url for the entry (from where you found it)."}, - * } + * @Operation( + * tags={"Entries"}, + * summary="Change several properties of an entry.", + * @SWG\Parameter( + * name="entry", + * in="path", + * description="The entry ID", + * required=true, + * pattern="\w+", + * type="integer" + * ), + * @SWG\Parameter( + * name="title", + * in="body", + * description="", + * required=false, + * @SWG\Schema(type="string") + * ), + * @SWG\Parameter( + * name="tags", + * in="body", + * description="a comma-separated list of tags.", + * required=false, + * @SWG\Schema( + * type="string", + * example="tag1,tag2,tag3", + * ) + * ), + * @SWG\Parameter( + * name="archive", + * in="body", + * description="archived the entry.", + * required=false, + * @SWG\Schema( + * type="integer", + * enum={"1", "0"}, + * default="0" + * ) + * ), + * @SWG\Parameter( + * name="starred", + * in="body", + * description="starred the entry.", + * required=false, + * @SWG\Schema( + * type="integer", + * enum={"1", "0"}, + * default="0" + * ) + * ), + * @SWG\Parameter( + * name="content", + * in="body", + * description="Content of the entry", + * required=false, + * @SWG\Schema(type="string") + * ), + * @SWG\Parameter( + * name="language", + * in="body", + * description="Language of the entry", + * required=false, + * @SWG\Schema(type="string") + * ), + * @SWG\Parameter( + * name="preview_picture", + * in="body", + * description="Preview picture of the entry", + * required=false, + * @SWG\Schema(type="string") + * ), + * @SWG\Parameter( + * name="published_at", + * in="body", + * description="Published date of the entry", + * required=false, + * format="YYYY-MM-DDTHH:II:SS+TZ or a timestamp", + * @SWG\Schema(type="datetime|integer") + * ), + * @SWG\Parameter( + * name="authors", + * in="body", + * description="Authors of the entry", + * required=false, + * @SWG\Schema( + * type="string", + * example="Name Firstname,author2,author3", + * ) + * ), + * @SWG\Parameter( + * name="public", + * in="body", + * description="will generate a public link for the entry", + * required=false, + * @SWG\Schema( + * type="integer", + * enum={"1", "0"}, + * default="0" + * ) + * ), + * @SWG\Parameter( + * name="origin_url", + * in="body", + * description="Origin url for the entry (from where you found it).", + * required=false, + * @SWG\Schema( + * type="string", + * example="http://www.test.com/article.html", + * ) + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse @@ -561,10 +968,21 @@ class EntryRestController extends WallabagRestController * Reload an entry. * An empty response with HTTP Status 304 will be send if we weren't able to update the content (because it hasn't changed or we got an error). * - * @ApiDoc( - * requirements={ - * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} - * } + * @Operation( + * tags={"Entries"}, + * summary="Reload an entry.", + * @SWG\Parameter( + * name="entry", + * in="path", + * description="The entry ID", + * required=true, + * pattern="\w+", + * type="integer" + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse @@ -603,13 +1021,24 @@ class EntryRestController extends WallabagRestController /** * Delete **permanently** an entry. * - * @ApiDoc( - * requirements={ - * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} - * }, - * parameters={ - * {"name"="expect", "dataType"="string", "required"=false, "format"="id or entry", "description"="Only returns the id instead of the deleted entry's full entity if 'id' is specified. Default to entry"}, - * } + * @Operation( + * tags={"Entries"}, + * summary="Delete permanently an entry.", + * @SWG\Parameter( + * name="expect", + * in="body", + * description="Only returns the id instead of the deleted entry's full entity if 'id' is specified.", + * required=false, + * @SWG\Schema( + * type="string", + * enum={"id", "entry"}, + * default="entry" + * ) + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse @@ -645,10 +1074,21 @@ class EntryRestController extends WallabagRestController /** * Retrieve all tags for an entry. * - * @ApiDoc( - * requirements={ - * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} - * } + * @Operation( + * tags={"Entries"}, + * summary="Retrieve all tags for an entry.", + * @SWG\Parameter( + * name="entry", + * in="path", + * description="The entry ID", + * required=true, + * pattern="\w+", + * type="integer" + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse @@ -664,13 +1104,31 @@ class EntryRestController extends WallabagRestController /** * Add one or more tags to an entry. * - * @ApiDoc( - * requirements={ - * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} - * }, - * parameters={ - * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."}, - * } + * @Operation( + * tags={"Entries"}, + * summary="Add one or more tags to an entry.", + * @SWG\Parameter( + * name="entry", + * in="path", + * description="The entry ID", + * required=true, + * pattern="\w+", + * type="integer" + * ), + * @SWG\Parameter( + * name="tags", + * in="body", + * description="a comma-separated list of tags.", + * required=false, + * @SWG\Schema( + * type="string", + * example="tag1,tag2,tag3", + * ) + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse @@ -695,11 +1153,29 @@ class EntryRestController extends WallabagRestController /** * Permanently remove one tag for an entry. * - * @ApiDoc( - * requirements={ - * {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag ID"}, - * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} - * } + * @Operation( + * tags={"Entries"}, + * summary="Permanently remove one tag for an entry.", + * @SWG\Parameter( + * name="entry", + * in="path", + * description="The entry ID", + * required=true, + * pattern="\w+", + * type="integer" + * ), + * @SWG\Parameter( + * name="tag", + * in="path", + * description="The tag ID", + * required=true, + * pattern="\w+", + * type="integer" + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse @@ -720,10 +1196,20 @@ class EntryRestController extends WallabagRestController /** * Handles an entries list delete tags from them. * - * @ApiDoc( - * parameters={ - * {"name"="list", "dataType"="string", "required"=true, "format"="A JSON array of urls [{'url': 'http://...','tags': 'tag1, tag2'}, {'url': 'http://...','tags': 'tag1, tag2'}]", "description"="Urls (as an array) to handle."} - * } + * @Operation( + * tags={"Entries"}, + * summary="Handles an entries list delete tags from them.", + * @SWG\Parameter( + * name="list", + * in="body", + * description="Urls (as an array) to handle. A JSON array of urls [{'url': 'http://...','tags': 'tag1, tag2'}, {'url': 'http://...','tags': 'tag1, tag2'}]", + * required=true, + * @SWG\Schema(type="string") + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse @@ -778,10 +1264,20 @@ class EntryRestController extends WallabagRestController /** * Handles an entries list and add tags to them. * - * @ApiDoc( - * parameters={ - * {"name"="list", "dataType"="string", "required"=true, "format"="A JSON array of urls [{'url': 'http://...','tags': 'tag1, tag2'}, {'url': 'http://...','tags': 'tag1, tag2'}]", "description"="Urls (as an array) to handle."} - * } + * @Operation( + * tags={"Entries"}, + * summary="Handles an entries list and add tags to them.", + * @SWG\Parameter( + * name="list", + * in="formData", + * description="Urls (as an array) to handle. A JSON array of urls [{'url': 'http://...','tags': 'tag1, tag2'}, {'url': 'http://...','tags': 'tag1, tag2'}]", + * required=true, + * type="string" + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse diff --git a/src/Wallabag/ApiBundle/Controller/SearchRestController.php b/src/Wallabag/ApiBundle/Controller/SearchRestController.php index 54709f317..277896ccf 100644 --- a/src/Wallabag/ApiBundle/Controller/SearchRestController.php +++ b/src/Wallabag/ApiBundle/Controller/SearchRestController.php @@ -4,9 +4,10 @@ namespace Wallabag\ApiBundle\Controller; use Hateoas\Configuration\Route; use Hateoas\Representation\Factory\PagerfantaFactory; -use Nelmio\ApiDocBundle\Annotation\ApiDoc; +use Nelmio\ApiDocBundle\Annotation\Operation; use Pagerfanta\Doctrine\ORM\QueryAdapter as DoctrineORMAdapter; use Pagerfanta\Pagerfanta; +use Swagger\Annotations as SWG; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Wallabag\CoreBundle\Repository\EntryRepository; @@ -16,12 +17,40 @@ class SearchRestController extends WallabagRestController /** * Search all entries by term. * - * @ApiDoc( - * parameters={ - * {"name"="term", "dataType"="string", "required"=false, "format"="any", "description"="Any query term"}, - * {"name"="page", "dataType"="integer", "required"=false, "format"="default '1'", "description"="what page you want."}, - * {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."} - * } + * @Operation( + * tags={"Search"}, + * summary="Search all entries by term.", + * @SWG\Parameter( + * name="term", + * in="body", + * description="Any query term", + * required=false, + * @SWG\Schema(type="string") + * ), + * @SWG\Parameter( + * name="page", + * in="body", + * description="what page you want.", + * required=false, + * @SWG\Schema( + * type="integer", + * default=1 + * ) + * ), + * @SWG\Parameter( + * name="perPage", + * in="body", + * description="results per page.", + * required=false, + * @SWG\Schema( + * type="integer", + * default=30 + * ) + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse diff --git a/src/Wallabag/ApiBundle/Controller/TagRestController.php b/src/Wallabag/ApiBundle/Controller/TagRestController.php index 7e14e8d1c..f51557567 100644 --- a/src/Wallabag/ApiBundle/Controller/TagRestController.php +++ b/src/Wallabag/ApiBundle/Controller/TagRestController.php @@ -3,7 +3,8 @@ namespace Wallabag\ApiBundle\Controller; use JMS\Serializer\SerializerInterface; -use Nelmio\ApiDocBundle\Annotation\ApiDoc; +use Nelmio\ApiDocBundle\Annotation\Operation; +use Swagger\Annotations as SWG; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Wallabag\CoreBundle\Entity\Entry; @@ -14,7 +15,14 @@ class TagRestController extends WallabagRestController /** * Retrieve all tags. * - * @ApiDoc() + * @Operation( + * tags={"Tags"}, + * summary="Retrieve all tags.", + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) + * ) * * @return JsonResponse */ @@ -34,10 +42,21 @@ class TagRestController extends WallabagRestController /** * Permanently remove one tag from **every** entry by passing the Tag label. * - * @ApiDoc( - * requirements={ - * {"name"="tag", "dataType"="string", "required"=true, "requirement"="\w+", "description"="Tag as a string"} - * } + * @Operation( + * tags={"Tags"}, + * summary="Permanently remove one tag from every entry by passing the Tag label.", + * @SWG\Parameter( + * name="tag", + * in="body", + * description="Tag as a string", + * required=true, + * pattern="\w+", + * @SWG\Schema(type="string") + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse @@ -69,10 +88,23 @@ class TagRestController extends WallabagRestController /** * Permanently remove some tags from **every** entry. * - * @ApiDoc( - * requirements={ - * {"name"="tags", "dataType"="string", "required"=true, "format"="tag1,tag2", "description"="Tags as strings (comma splitted)"} - * } + * @Operation( + * tags={"Tags"}, + * summary="Permanently remove some tags from every entry.", + * @SWG\Parameter( + * name="tags", + * in="body", + * description="Tags as strings (comma splitted)", + * required=true, + * @SWG\Schema( + * type="string", + * example="tag1,tag2", + * ) + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse @@ -103,10 +135,21 @@ class TagRestController extends WallabagRestController /** * Permanently remove one tag from **every** entry by passing the Tag ID. * - * @ApiDoc( - * requirements={ - * {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag"} - * } + * @Operation( + * tags={"Tags"}, + * summary="Permanently remove one tag from every entry by passing the Tag ID.", + * @SWG\Parameter( + * name="tag", + * in="body", + * description="The tag", + * required=true, + * pattern="\w+", + * @SWG\Schema(type="integer") + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @return JsonResponse diff --git a/src/Wallabag/ApiBundle/Controller/TaggingRuleRestController.php b/src/Wallabag/ApiBundle/Controller/TaggingRuleRestController.php index 2496298aa..e6c3e5544 100644 --- a/src/Wallabag/ApiBundle/Controller/TaggingRuleRestController.php +++ b/src/Wallabag/ApiBundle/Controller/TaggingRuleRestController.php @@ -4,7 +4,8 @@ namespace Wallabag\ApiBundle\Controller; use JMS\Serializer\SerializationContext; use JMS\Serializer\SerializerBuilder; -use Nelmio\ApiDocBundle\Annotation\ApiDoc; +use Nelmio\ApiDocBundle\Annotation\Operation; +use Swagger\Annotations as SWG; use Symfony\Component\HttpFoundation\Response; class TaggingRuleRestController extends WallabagRestController @@ -12,7 +13,14 @@ class TaggingRuleRestController extends WallabagRestController /** * Export all tagging rules as a json file. * - * @ApiDoc() + * @Operation( + * tags={"TaggingRule"}, + * summary="Export all tagging rules as a json file.", + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) + * ) * * @return Response */ diff --git a/src/Wallabag/ApiBundle/Controller/UserRestController.php b/src/Wallabag/ApiBundle/Controller/UserRestController.php index 5d91cd582..9988f2890 100644 --- a/src/Wallabag/ApiBundle/Controller/UserRestController.php +++ b/src/Wallabag/ApiBundle/Controller/UserRestController.php @@ -8,7 +8,8 @@ use FOS\UserBundle\FOSUserEvents; use FOS\UserBundle\Model\UserManagerInterface; use JMS\Serializer\SerializationContext; use JMS\Serializer\SerializerInterface; -use Nelmio\ApiDocBundle\Annotation\ApiDoc; +use Nelmio\ApiDocBundle\Annotation\Operation; +use Swagger\Annotations as SWG; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -22,7 +23,14 @@ class UserRestController extends WallabagRestController /** * Retrieve current logged in user informations. * - * @ApiDoc() + * @Operation( + * tags={"User"}, + * summary="Retrieve current logged in user informations.", + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) + * ) * * @return JsonResponse */ @@ -36,13 +44,41 @@ class UserRestController extends WallabagRestController /** * Register an user and create a client. * - * @ApiDoc( - * requirements={ - * {"name"="username", "dataType"="string", "required"=true, "description"="The user's username"}, - * {"name"="password", "dataType"="string", "required"=true, "description"="The user's password"}, - * {"name"="email", "dataType"="string", "required"=true, "description"="The user's email"}, - * {"name"="client_name", "dataType"="string", "required"=true, "description"="The client name (to be used by your app)"} - * } + * @Operation( + * tags={"User"}, + * summary="Register an user and create a client.", + * @SWG\Parameter( + * name="username", + * in="body", + * description="The user's username", + * required=true, + * @SWG\Schema(type="string") + * ), + * @SWG\Parameter( + * name="password", + * in="body", + * description="The user's password", + * required=true, + * @SWG\Schema(type="string") + * ), + * @SWG\Parameter( + * name="email", + * in="body", + * description="The user's email", + * required=true, + * @SWG\Schema(type="string") + * ), + * @SWG\Parameter( + * name="client_name", + * in="body", + * description="The client name (to be used by your app)", + * required=true, + * @SWG\Schema(type="string") + * ), + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) * ) * * @todo Make this method (or the whole API) accessible only through https diff --git a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php index 5ac85d39a..b2349d38d 100644 --- a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php +++ b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php @@ -5,7 +5,8 @@ namespace Wallabag\ApiBundle\Controller; use FOS\RestBundle\Controller\AbstractFOSRestController; use JMS\Serializer\SerializationContext; use JMS\Serializer\SerializerInterface; -use Nelmio\ApiDocBundle\Annotation\ApiDoc; +use Nelmio\ApiDocBundle\Annotation\Operation; +use Swagger\Annotations as SWG; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; @@ -16,7 +17,14 @@ class WallabagRestController extends AbstractFOSRestController /** * Retrieve version number. * - * @ApiDoc() + * @Operation( + * tags={"Informations"}, + * summary="Retrieve version number.", + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) + * ) * * @deprecated Should use info endpoint instead * @@ -33,7 +41,14 @@ class WallabagRestController extends AbstractFOSRestController /** * Retrieve information about the wallabag instance. * - * @ApiDoc() + * @Operation( + * tags={"Informations"}, + * summary="Retrieve information about the wallabag instance.", + * @SWG\Response( + * response="200", + * description="Returned when successful" + * ) + * ) * * @return JsonResponse */ diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/howto_app.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/howto_app.html.twig index 0f40b7914..5027de938 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/howto_app.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/howto_app.html.twig @@ -51,7 +51,7 @@ X-Powered-By: PHP/5.5.9-1ubuntu4.13 "Authorization:Bearer ZWFjNjA3ZWMwYWVmYzRkYTBlMmQ3NTllYmVhOGJiZDE0ZTg1NjE4MjczOTVlNzM0ZTRlMWQ0MmRlMmYwNTk5Mw"

{{ 'developer.howto.description.paragraph_7'|trans }}

-

{{ 'developer.howto.description.paragraph_8'|trans({'%link%': path('nelmio_api_doc_index')})|raw }}

+

{{ 'developer.howto.description.paragraph_8'|trans({'%link%': path('nelmio_api_doc.swagger_ui')})|raw }}

{{ 'developer.howto.back'|trans }}

diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/index.html.twig index 1dac14653..2093227d0 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/index.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/index.html.twig @@ -15,7 +15,7 @@

{{ 'developer.clients.title'|trans }}