Simple API V1 implemented using Symfony Serializer.
This commit is contained in:
parent
d1eefb3d12
commit
027476c553
|
@ -21,6 +21,7 @@
|
||||||
"symfony/framework-bundle": "^4.1",
|
"symfony/framework-bundle": "^4.1",
|
||||||
"symfony/lts": "^4@dev",
|
"symfony/lts": "^4@dev",
|
||||||
"symfony/orm-pack": "^1.0",
|
"symfony/orm-pack": "^1.0",
|
||||||
|
"symfony/serializer-pack": "^1.0",
|
||||||
"symfony/translation": "^4.1",
|
"symfony/translation": "^4.1",
|
||||||
"symfony/twig-bundle": "^4.1",
|
"symfony/twig-bundle": "^4.1",
|
||||||
"symfony/web-server-bundle": "^4.1",
|
"symfony/web-server-bundle": "^4.1",
|
||||||
|
|
391
composer.lock
generated
391
composer.lock
generated
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "6451fb298116549e08f8a9860dc00786",
|
"content-hash": "fcc11531a19d6444ffb2125e69ff29bd",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "doctrine/annotations",
|
"name": "doctrine/annotations",
|
||||||
|
@ -1166,6 +1166,158 @@
|
||||||
],
|
],
|
||||||
"time": "2018-05-17T09:23:52+00:00"
|
"time": "2018-05-17T09:23:52+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "phpdocumentor/reflection-common",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
|
||||||
|
"reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
|
||||||
|
"reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.5"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4.6"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.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"
|
||||||
|
],
|
||||||
|
"time": "2017-09-11T18:02:19+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpdocumentor/reflection-docblock",
|
||||||
|
"version": "4.3.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
|
||||||
|
"reference": "94fd0001232e47129dd3504189fa1c7225010d08"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08",
|
||||||
|
"reference": "94fd0001232e47129dd3504189fa1c7225010d08",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.0",
|
||||||
|
"phpdocumentor/reflection-common": "^1.0.0",
|
||||||
|
"phpdocumentor/type-resolver": "^0.4.0",
|
||||||
|
"webmozart/assert": "^1.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"doctrine/instantiator": "~1.0.5",
|
||||||
|
"mockery/mockery": "^1.0",
|
||||||
|
"phpunit/phpunit": "^6.4"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "4.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": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
|
||||||
|
"time": "2017-11-30T07:14:17+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpdocumentor/type-resolver",
|
||||||
|
"version": "0.4.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/phpDocumentor/TypeResolver.git",
|
||||||
|
"reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
|
||||||
|
"reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^5.5 || ^7.0",
|
||||||
|
"phpdocumentor/reflection-common": "^1.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"mockery/mockery": "^0.9.4",
|
||||||
|
"phpunit/phpunit": "^5.2||^4.8.24"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.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"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2017-07-14T14:27:02+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/cache",
|
"name": "psr/cache",
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
|
@ -2650,6 +2802,82 @@
|
||||||
],
|
],
|
||||||
"time": "2018-05-30T07:26:09+00:00"
|
"time": "2018-05-30T07:26:09+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/property-info",
|
||||||
|
"version": "v4.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/property-info.git",
|
||||||
|
"reference": "724cca5ae45760156029f14d2e293a281fab89e0"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/property-info/zipball/724cca5ae45760156029f14d2e293a281fab89e0",
|
||||||
|
"reference": "724cca5ae45760156029f14d2e293a281fab89e0",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.1.3",
|
||||||
|
"symfony/inflector": "~3.4|~4.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.2",
|
||||||
|
"phpdocumentor/type-resolver": "<0.2.1",
|
||||||
|
"symfony/dependency-injection": "<3.4"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"doctrine/annotations": "~1.0",
|
||||||
|
"phpdocumentor/reflection-docblock": "^3.0|^4.0",
|
||||||
|
"symfony/cache": "~3.4|~4.0",
|
||||||
|
"symfony/dependency-injection": "~3.4|~4.0",
|
||||||
|
"symfony/serializer": "~3.4|~4.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"phpdocumentor/reflection-docblock": "To use the PHPDoc",
|
||||||
|
"psr/cache-implementation": "To cache results",
|
||||||
|
"symfony/doctrine-bridge": "To use Doctrine metadata",
|
||||||
|
"symfony/serializer": "To use Serializer metadata"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "4.1-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\PropertyInfo\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Kévin Dunglas",
|
||||||
|
"email": "dunglas@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony Property Info Component",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"doctrine",
|
||||||
|
"phpdoc",
|
||||||
|
"property",
|
||||||
|
"symfony",
|
||||||
|
"type",
|
||||||
|
"validator"
|
||||||
|
],
|
||||||
|
"time": "2018-05-16T14:33:22+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/routing",
|
"name": "symfony/routing",
|
||||||
"version": "v4.1.0",
|
"version": "v4.1.0",
|
||||||
|
@ -2728,6 +2956,117 @@
|
||||||
],
|
],
|
||||||
"time": "2018-05-30T07:26:09+00:00"
|
"time": "2018-05-30T07:26:09+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/serializer",
|
||||||
|
"version": "v4.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/serializer.git",
|
||||||
|
"reference": "db427d70438645789ffce6048d61b3992118a33a"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/serializer/zipball/db427d70438645789ffce6048d61b3992118a33a",
|
||||||
|
"reference": "db427d70438645789ffce6048d61b3992118a33a",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.1.3",
|
||||||
|
"symfony/polyfill-ctype": "~1.8"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"phpdocumentor/type-resolver": "<0.2.1",
|
||||||
|
"symfony/dependency-injection": "<3.4",
|
||||||
|
"symfony/property-access": "<3.4",
|
||||||
|
"symfony/property-info": "<3.4",
|
||||||
|
"symfony/yaml": "<3.4"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"doctrine/annotations": "~1.0",
|
||||||
|
"doctrine/cache": "~1.0",
|
||||||
|
"phpdocumentor/reflection-docblock": "^3.0|^4.0",
|
||||||
|
"symfony/cache": "~3.4|~4.0",
|
||||||
|
"symfony/config": "~3.4|~4.0",
|
||||||
|
"symfony/dependency-injection": "~3.4|~4.0",
|
||||||
|
"symfony/http-foundation": "~3.4|~4.0",
|
||||||
|
"symfony/property-access": "~3.4|~4.0",
|
||||||
|
"symfony/property-info": "~3.4|~4.0",
|
||||||
|
"symfony/validator": "~3.4|~4.0",
|
||||||
|
"symfony/yaml": "~3.4|~4.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.",
|
||||||
|
"doctrine/cache": "For using the default cached annotation reader and metadata cache.",
|
||||||
|
"psr/cache-implementation": "For using the metadata cache.",
|
||||||
|
"symfony/config": "For using the XML mapping loader.",
|
||||||
|
"symfony/http-foundation": "To use the DataUriNormalizer.",
|
||||||
|
"symfony/property-access": "For using the ObjectNormalizer.",
|
||||||
|
"symfony/property-info": "To deserialize relations.",
|
||||||
|
"symfony/yaml": "For using the default YAML mapping loader."
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "4.1-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\Serializer\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony Serializer Component",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"time": "2018-05-30T07:26:09+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/serializer-pack",
|
||||||
|
"version": "v1.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/serializer-pack.git",
|
||||||
|
"reference": "35cea385ea44d1f40ec12571996bf768fbe409de"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/serializer-pack/zipball/35cea385ea44d1f40ec12571996bf768fbe409de",
|
||||||
|
"reference": "35cea385ea44d1f40ec12571996bf768fbe409de",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/annotations": "^1.0",
|
||||||
|
"php": "^7.0",
|
||||||
|
"phpdocumentor/reflection-docblock": "^3.0|^4.0",
|
||||||
|
"symfony/cache": "^3.3|^4.0",
|
||||||
|
"symfony/property-access": "^3.3|^4.0",
|
||||||
|
"symfony/property-info": "^3.3|^4.0",
|
||||||
|
"symfony/serializer": "^3.3|^4.0"
|
||||||
|
},
|
||||||
|
"type": "symfony-pack",
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"description": "A pack for the Symfony serializer",
|
||||||
|
"time": "2017-12-12T01:48:53+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/translation",
|
"name": "symfony/translation",
|
||||||
"version": "v4.1.0",
|
"version": "v4.1.0",
|
||||||
|
@ -3145,6 +3484,56 @@
|
||||||
],
|
],
|
||||||
"time": "2018-04-02T09:24:19+00:00"
|
"time": "2018-04-02T09:24:19+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "webmozart/assert",
|
||||||
|
"version": "1.3.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/webmozart/assert.git",
|
||||||
|
"reference": "0df1908962e7a3071564e857d86874dad1ef204a"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a",
|
||||||
|
"reference": "0df1908962e7a3071564e857d86874dad1ef204a",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^5.3.3 || ^7.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4.6",
|
||||||
|
"sebastian/version": "^1.0.1"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.3-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"
|
||||||
|
],
|
||||||
|
"time": "2018-01-29T19:49:41+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "white-october/pagerfanta-bundle",
|
"name": "white-october/pagerfanta-bundle",
|
||||||
"version": "v1.2.1",
|
"version": "v1.2.1",
|
||||||
|
|
|
@ -1,16 +1,37 @@
|
||||||
|
# Basic Front-End
|
||||||
index:
|
index:
|
||||||
path: /
|
path: /
|
||||||
controller: App\Controller\MainController::index
|
controller: App\Controller\MainController::index
|
||||||
|
|
||||||
torrent_show:
|
torrents_search:
|
||||||
|
path: /torrents/search
|
||||||
|
controller: App\Controller\TorrentController::searchTorrent
|
||||||
|
requirements:
|
||||||
|
method: GET
|
||||||
|
|
||||||
|
torrents_show:
|
||||||
path: /torrents/{id}
|
path: /torrents/{id}
|
||||||
controller: App\Controller\TorrentController::showTorrent
|
controller: App\Controller\TorrentController::showTorrent
|
||||||
requirements:
|
requirements:
|
||||||
method: GET
|
method: GET
|
||||||
id: '\d+'
|
id: '\d+'
|
||||||
|
|
||||||
torrent_search:
|
# API
|
||||||
path: /torrents/search
|
api_v1_torrents_search:
|
||||||
controller: App\Controller\TorrentController::searchTorrent
|
path: /api/v1/torrents/search
|
||||||
|
controller: App\Api\V1\Controller\TorrentController::search
|
||||||
|
defaults:
|
||||||
|
_format: json
|
||||||
requirements:
|
requirements:
|
||||||
method: GET
|
method: GET
|
||||||
|
_format: json
|
||||||
|
|
||||||
|
api_v1_torrents_show:
|
||||||
|
path: /api/v1/torrents/{id}
|
||||||
|
controller: App\Api\V1\Controller\TorrentController::show
|
||||||
|
defaults:
|
||||||
|
_format: json
|
||||||
|
requirements:
|
||||||
|
method: GET
|
||||||
|
_format: json
|
||||||
|
id: '\d+'
|
|
@ -22,3 +22,10 @@ services:
|
||||||
App\Controller\:
|
App\Controller\:
|
||||||
resource: '../src/Controller'
|
resource: '../src/Controller'
|
||||||
tags: ['controller.service_arguments']
|
tags: ['controller.service_arguments']
|
||||||
|
|
||||||
|
# Fast normalizer for Symfony Serializer
|
||||||
|
get_set_method_normalizer:
|
||||||
|
class: Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer
|
||||||
|
public: false
|
||||||
|
tags:
|
||||||
|
- { name: serializer.normalizer, priority: 1 }
|
46
src/Api/V1/Controller/TorrentController.php
Normal file
46
src/Api/V1/Controller/TorrentController.php
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Api\V1\Controller;
|
||||||
|
|
||||||
|
use App\Api\V1\DTO\ApiResponse;
|
||||||
|
use App\Entity\Torrent;
|
||||||
|
use App\Repository\TorrentRepository;
|
||||||
|
use Pagerfanta\Adapter\DoctrineORMAdapter;
|
||||||
|
use Pagerfanta\Pagerfanta;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||||
|
use Symfony\Component\HttpFoundation\{Request, Response};
|
||||||
|
|
||||||
|
class TorrentController extends Controller
|
||||||
|
{
|
||||||
|
private const DEFAULT_SERIALIZER_GROUPS = ['api_v1'];
|
||||||
|
|
||||||
|
private const PER_PAGE = 20;
|
||||||
|
|
||||||
|
public function search(Request $request, TorrentRepository $repo): Response
|
||||||
|
{
|
||||||
|
$query = $request->query->get('query', '');
|
||||||
|
$page = (int) $request->query->get('page', '1');
|
||||||
|
|
||||||
|
$pagerAdapter = new DoctrineORMAdapter($repo->createFindLikeQueryBuilder($query));
|
||||||
|
$pager = new Pagerfanta($pagerAdapter);
|
||||||
|
$pager
|
||||||
|
->setCurrentPage($page)
|
||||||
|
->setMaxPerPage(self::PER_PAGE)
|
||||||
|
;
|
||||||
|
|
||||||
|
return $this->json(new ApiResponse($pager->getCurrentPageResults()),Response::HTTP_OK, [], [
|
||||||
|
'groups' => array_merge(self::DEFAULT_SERIALIZER_GROUPS,['api_v1_search']),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show(Torrent $torrent): Response
|
||||||
|
{
|
||||||
|
return $this->json(new ApiResponse($torrent), Response::HTTP_OK, [], [
|
||||||
|
'groups' => array_merge(self::DEFAULT_SERIALIZER_GROUPS,['api_v1_show']),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
88
src/Api/V1/DTO/ApiResponse.php
Normal file
88
src/Api/V1/DTO/ApiResponse.php
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Api\V1\DTO;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Serializer\Annotation\{Groups, MaxDepth};
|
||||||
|
|
||||||
|
class ApiResponse
|
||||||
|
{
|
||||||
|
public const STATUS_SUCCESS = 'success';
|
||||||
|
public const STATUS_ERROR = 'error';
|
||||||
|
public const STATUS_FAIL = 'fail';
|
||||||
|
public const STATUS_UNKNOWN = 'unknown';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int HTTP response status code
|
||||||
|
*
|
||||||
|
* @Groups({"api_v1"})
|
||||||
|
*/
|
||||||
|
private $code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Status text: 'success' (1xx-3xx), 'error' (4xx), 'fail' (5xx) or 'unknown'
|
||||||
|
*
|
||||||
|
* @Groups({"api_v1"})
|
||||||
|
*/
|
||||||
|
private $status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string|null Used for 'fail' and 'error'
|
||||||
|
*
|
||||||
|
* @Groups({"api_v1"})
|
||||||
|
*/
|
||||||
|
private $message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string|\object|array|null Response body. In case of 'error' or 'fail' contains cause or exception name.
|
||||||
|
*
|
||||||
|
* @Groups({"api_v1"})
|
||||||
|
*/
|
||||||
|
private $data;
|
||||||
|
|
||||||
|
public function __construct($data = null, int $code = Response::HTTP_OK, string $message = null, string $status = '')
|
||||||
|
{
|
||||||
|
$this->data = $data;
|
||||||
|
$this->code = $code;
|
||||||
|
$this->message = $message;
|
||||||
|
|
||||||
|
if ('' === $status) {
|
||||||
|
switch ($code) {
|
||||||
|
case ($code >= 100 && $code < 300):
|
||||||
|
$this->status = self::STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
case ($code >= 400 && $code < 500):
|
||||||
|
$this->status = self::STATUS_ERROR;
|
||||||
|
break;
|
||||||
|
case ($code >= 500 && $code < 600):
|
||||||
|
$this->status = self::STATUS_FAIL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->status = self::STATUS_UNKNOWN;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->status = $status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCode(): int
|
||||||
|
{
|
||||||
|
return $this->code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getStatus(): string
|
||||||
|
{
|
||||||
|
return $this->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMessage(): ?string
|
||||||
|
{
|
||||||
|
return $this->message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return array|\object|string|null */
|
||||||
|
public function getData()
|
||||||
|
{
|
||||||
|
return $this->data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,10 +4,11 @@ namespace App\Controller;
|
||||||
|
|
||||||
use App\Repository\TorrentRepository;
|
use App\Repository\TorrentRepository;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
class MainController extends Controller
|
class MainController extends Controller
|
||||||
{
|
{
|
||||||
public function index(TorrentRepository $repo)
|
public function index(TorrentRepository $repo): Response
|
||||||
{
|
{
|
||||||
return $this->render('index.html.twig', [
|
return $this->render('index.html.twig', [
|
||||||
'torrentsCount' => $repo->getTorrentsTotalCount(),
|
'torrentsCount' => $repo->getTorrentsTotalCount(),
|
||||||
|
|
|
@ -8,19 +8,13 @@ use Pagerfanta\Adapter\DoctrineORMAdapter;
|
||||||
use Pagerfanta\Pagerfanta;
|
use Pagerfanta\Pagerfanta;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
class TorrentController extends Controller
|
class TorrentController extends Controller
|
||||||
{
|
{
|
||||||
private const PER_PAGE = 20;
|
private const PER_PAGE = 20;
|
||||||
|
|
||||||
public function showTorrent(Torrent $torrent)
|
public function searchTorrent(Request $request, TorrentRepository $repo): Response
|
||||||
{
|
|
||||||
return $this->render('torrent_show.html.twig', [
|
|
||||||
'torrent' => $torrent,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function searchTorrent(Request $request, TorrentRepository $repo)
|
|
||||||
{
|
{
|
||||||
$query = $request->query->get('query', '');
|
$query = $request->query->get('query', '');
|
||||||
$page = (int) $request->query->get('page', '1');
|
$page = (int) $request->query->get('page', '1');
|
||||||
|
@ -37,4 +31,11 @@ class TorrentController extends Controller
|
||||||
'searchQuery' => $query,
|
'searchQuery' => $query,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function showTorrent(Torrent $torrent): Response
|
||||||
|
{
|
||||||
|
return $this->render('torrent_show.html.twig', [
|
||||||
|
'torrent' => $torrent,
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
namespace App\Entity;
|
namespace App\Entity;
|
||||||
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Table(name="files", indexes={
|
* @ORM\Table(name="files", indexes={
|
||||||
|
@ -31,6 +32,8 @@ class File
|
||||||
/**
|
/**
|
||||||
* @var int File size in bytes
|
* @var int File size in bytes
|
||||||
*
|
*
|
||||||
|
* @Serializer\Groups({"api_v1_show"})
|
||||||
|
*
|
||||||
* @ORM\Column(name="size", type="integer", nullable=false)
|
* @ORM\Column(name="size", type="integer", nullable=false)
|
||||||
*/
|
*/
|
||||||
private $size;
|
private $size;
|
||||||
|
@ -38,6 +41,8 @@ class File
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*
|
*
|
||||||
|
* @Serializer\Groups({"api_v1_show"})
|
||||||
|
*
|
||||||
* @ORM\Column(name="path", type="text", nullable=false)
|
* @ORM\Column(name="path", type="text", nullable=false)
|
||||||
*/
|
*/
|
||||||
private $path;
|
private $path;
|
||||||
|
|
|
@ -4,6 +4,7 @@ namespace App\Entity;
|
||||||
|
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Table(name="torrents", indexes={
|
* @ORM\Table(name="torrents", indexes={
|
||||||
|
@ -17,6 +18,8 @@ class Torrent
|
||||||
/**
|
/**
|
||||||
* @var int
|
* @var int
|
||||||
*
|
*
|
||||||
|
* @Serializer\Groups({"api_v1_search", "api_v1_show"})
|
||||||
|
*
|
||||||
* @ORM\Column(name="id", type="integer")
|
* @ORM\Column(name="id", type="integer")
|
||||||
* @ORM\Id
|
* @ORM\Id
|
||||||
*/
|
*/
|
||||||
|
@ -25,6 +28,8 @@ class Torrent
|
||||||
/**
|
/**
|
||||||
* @var resource Resource pointing to info-hash BLOB
|
* @var resource Resource pointing to info-hash BLOB
|
||||||
*
|
*
|
||||||
|
* @Serializer\Groups({"api_v1_search", "api_v1_show"})
|
||||||
|
*
|
||||||
* @ORM\Column(name="info_hash", type="blob", nullable=false)
|
* @ORM\Column(name="info_hash", type="blob", nullable=false)
|
||||||
*/
|
*/
|
||||||
private $infoHash;
|
private $infoHash;
|
||||||
|
@ -37,6 +42,8 @@ class Torrent
|
||||||
/**
|
/**
|
||||||
* @var string Torrent name
|
* @var string Torrent name
|
||||||
*
|
*
|
||||||
|
* @Serializer\Groups({"api_v1_search", "api_v1_show"})
|
||||||
|
*
|
||||||
* @ORM\Column(name="name", type="text", nullable=false)
|
* @ORM\Column(name="name", type="text", nullable=false)
|
||||||
*/
|
*/
|
||||||
private $name;
|
private $name;
|
||||||
|
@ -44,6 +51,8 @@ class Torrent
|
||||||
/**
|
/**
|
||||||
* @var int Torrent files total size in bytes
|
* @var int Torrent files total size in bytes
|
||||||
*
|
*
|
||||||
|
* @Serializer\Groups({"api_v1_search", "api_v1_show"})
|
||||||
|
*
|
||||||
* @ORM\Column(name="total_size", type="integer", nullable=false)
|
* @ORM\Column(name="total_size", type="integer", nullable=false)
|
||||||
*/
|
*/
|
||||||
private $totalSize;
|
private $totalSize;
|
||||||
|
@ -51,6 +60,8 @@ class Torrent
|
||||||
/**
|
/**
|
||||||
* @var int Torrent discovery timestamp
|
* @var int Torrent discovery timestamp
|
||||||
*
|
*
|
||||||
|
* @Serializer\Groups({"api_v1_search", "api_v1_show"})
|
||||||
|
*
|
||||||
* @ORM\Column(name="discovered_on", type="integer", nullable=false)
|
* @ORM\Column(name="discovered_on", type="integer", nullable=false)
|
||||||
*/
|
*/
|
||||||
private $discoveredOn;
|
private $discoveredOn;
|
||||||
|
@ -58,6 +69,8 @@ class Torrent
|
||||||
/**
|
/**
|
||||||
* @var File[]|ArrayCollection
|
* @var File[]|ArrayCollection
|
||||||
*
|
*
|
||||||
|
* @Serializer\Groups({"api_v1_show"})
|
||||||
|
*
|
||||||
* @ORM\OneToMany(targetEntity="App\Entity\File", fetch="EXTRA_LAZY", mappedBy="torrent")
|
* @ORM\OneToMany(targetEntity="App\Entity\File", fetch="EXTRA_LAZY", mappedBy="torrent")
|
||||||
*/
|
*/
|
||||||
private $files;
|
private $files;
|
||||||
|
@ -68,16 +81,18 @@ class Torrent
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns torrent info hash BLOB resource
|
* Returns torrent info hash as HEX string
|
||||||
*
|
|
||||||
* @return resource
|
|
||||||
*/
|
*/
|
||||||
public function getInfoHash()
|
public function getInfoHash(): string
|
||||||
{
|
{
|
||||||
return $this->infoHash;
|
return $this->getInfoHashAsHex();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns torrent info hash as HEX string */
|
/**
|
||||||
|
* @deprecated Use getInfoHash() instead
|
||||||
|
*
|
||||||
|
* Returns torrent info hash as HEX string
|
||||||
|
*/
|
||||||
public function getInfoHashAsHex(): string
|
public function getInfoHashAsHex(): string
|
||||||
{
|
{
|
||||||
if (null === $this->infoHashHexCache) {
|
if (null === $this->infoHashHexCache) {
|
||||||
|
|
21
symfony.lock
21
symfony.lock
|
@ -68,6 +68,15 @@
|
||||||
"pagerfanta/pagerfanta": {
|
"pagerfanta/pagerfanta": {
|
||||||
"version": "v2.0.1"
|
"version": "v2.0.1"
|
||||||
},
|
},
|
||||||
|
"phpdocumentor/reflection-common": {
|
||||||
|
"version": "1.0.1"
|
||||||
|
},
|
||||||
|
"phpdocumentor/reflection-docblock": {
|
||||||
|
"version": "4.3.0"
|
||||||
|
},
|
||||||
|
"phpdocumentor/type-resolver": {
|
||||||
|
"version": "0.4.0"
|
||||||
|
},
|
||||||
"psr/cache": {
|
"psr/cache": {
|
||||||
"version": "1.0.1"
|
"version": "1.0.1"
|
||||||
},
|
},
|
||||||
|
@ -170,6 +179,9 @@
|
||||||
"symfony/property-access": {
|
"symfony/property-access": {
|
||||||
"version": "v4.1.0"
|
"version": "v4.1.0"
|
||||||
},
|
},
|
||||||
|
"symfony/property-info": {
|
||||||
|
"version": "v4.1.0"
|
||||||
|
},
|
||||||
"symfony/routing": {
|
"symfony/routing": {
|
||||||
"version": "4.0",
|
"version": "4.0",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
|
@ -179,6 +191,12 @@
|
||||||
"ref": "cda8b550123383d25827705d05a42acf6819fe4e"
|
"ref": "cda8b550123383d25827705d05a42acf6819fe4e"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"symfony/serializer": {
|
||||||
|
"version": "v4.1.0"
|
||||||
|
},
|
||||||
|
"symfony/serializer-pack": {
|
||||||
|
"version": "v1.0.1"
|
||||||
|
},
|
||||||
"symfony/translation": {
|
"symfony/translation": {
|
||||||
"version": "3.3",
|
"version": "3.3",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
|
@ -227,6 +245,9 @@
|
||||||
"twig/twig": {
|
"twig/twig": {
|
||||||
"version": "v2.4.8"
|
"version": "v2.4.8"
|
||||||
},
|
},
|
||||||
|
"webmozart/assert": {
|
||||||
|
"version": "1.3.0"
|
||||||
|
},
|
||||||
"white-october/pagerfanta-bundle": {
|
"white-october/pagerfanta-bundle": {
|
||||||
"version": "v1.2.1"
|
"version": "v1.2.1"
|
||||||
},
|
},
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
<a class="nav-link" href="#">Item</a>
|
<a class="nav-link" href="#">Item</a>
|
||||||
</li>-->
|
</li>-->
|
||||||
</ul>
|
</ul>
|
||||||
<form class="form-inline my-2 my-lg-0" action="{{ path('torrent_search') }}" method="get">
|
<form class="form-inline my-2 my-lg-0" action="{{ path('torrents_search') }}" method="get">
|
||||||
<input name="query" class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search"
|
<input name="query" class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search"
|
||||||
value="{% if searchQuery is defined %}{{ searchQuery }}{% endif %}">
|
value="{% if searchQuery is defined %}{{ searchQuery }}{% endif %}">
|
||||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
|
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
{% for torrent in torrents %}
|
{% for torrent in torrents %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{{ magnet(torrent.name, torrent.infoHashAsHex) }}">🔗</a></td>
|
<td><a href="{{ magnet(torrent.name, torrent.infoHashAsHex) }}">🔗</a></td>
|
||||||
<td><a href="{{ path('torrent_show', {'id': torrent.id}) }}">{{ torrent.name }}</a></td>
|
<td><a href="{{ path('torrents_show', {'id': torrent.id}) }}">{{ torrent.name }}</a></td>
|
||||||
<td>{{ torrent.totalSize | readable_size }}</td>
|
<td>{{ torrent.totalSize | readable_size }}</td>
|
||||||
<td>{{ torrent.discoveredOn | date('Y-m-d H:i:s')}}</td>
|
<td>{{ torrent.discoveredOn | date('Y-m-d H:i:s')}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
Loading…
Reference in a new issue