add api docs via swagger and use jms serializer
This commit is contained in:
parent
14755d8343
commit
49538b037d
@ -7,10 +7,12 @@
|
|||||||
"ext-ctype": "*",
|
"ext-ctype": "*",
|
||||||
"ext-iconv": "*",
|
"ext-iconv": "*",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
|
"jms/serializer-bundle": "^3.5",
|
||||||
|
"nelmio/api-doc-bundle": "^3.5",
|
||||||
"nesbot/carbon": "^1.33",
|
"nesbot/carbon": "^1.33",
|
||||||
"ocramius/proxy-manager": "^2.0",
|
"ocramius/proxy-manager": "^2.0",
|
||||||
"sensio/framework-extra-bundle": "^5.2",
|
"sensio/framework-extra-bundle": "^5.2",
|
||||||
"symfony/asset": "*",
|
"symfony/asset": "4.1.*",
|
||||||
"symfony/console": "*",
|
"symfony/console": "*",
|
||||||
"symfony/flex": "^1.1",
|
"symfony/flex": "^1.1",
|
||||||
"symfony/framework-bundle": "*",
|
"symfony/framework-bundle": "*",
|
||||||
@ -33,7 +35,7 @@
|
|||||||
"sort-packages": true,
|
"sort-packages": true,
|
||||||
"secure-http": false,
|
"secure-http": false,
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": "7.1.12"
|
"php": "7.3.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
2499
composer.lock
generated
2499
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -9,4 +9,6 @@ return [
|
|||||||
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
|
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
|
||||||
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
|
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
|
||||||
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
|
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
|
||||||
|
Nelmio\ApiDocBundle\NelmioApiDocBundle::class => ['all' => true],
|
||||||
|
JMS\SerializerBundle\JMSSerializerBundle::class => ['all' => true],
|
||||||
];
|
];
|
||||||
|
7
config/packages/dev/jms_serializer.yaml
Normal file
7
config/packages/dev/jms_serializer.yaml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
jms_serializer:
|
||||||
|
visitors:
|
||||||
|
json_serialization:
|
||||||
|
options:
|
||||||
|
- JSON_PRETTY_PRINT
|
||||||
|
- JSON_UNESCAPED_SLASHES
|
||||||
|
- JSON_PRESERVE_ZERO_FRACTION
|
13
config/packages/jms_serializer.yaml
Normal file
13
config/packages/jms_serializer.yaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
jms_serializer:
|
||||||
|
visitors:
|
||||||
|
xml_serialization:
|
||||||
|
format_output: '%kernel.debug%'
|
||||||
|
# metadata:
|
||||||
|
# auto_detection: false
|
||||||
|
# directories:
|
||||||
|
# any-name:
|
||||||
|
# namespace_prefix: "My\\FooBundle"
|
||||||
|
# path: "@MyFooBundle/Resources/config/serializer"
|
||||||
|
# another-name:
|
||||||
|
# namespace_prefix: "My\\BarBundle"
|
||||||
|
# path: "@MyBarBundle/Resources/config/serializer"
|
19
config/packages/nelmio_api_doc.yaml
Normal file
19
config/packages/nelmio_api_doc.yaml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
nelmio_api_doc:
|
||||||
|
documentation:
|
||||||
|
info:
|
||||||
|
title: Czy Dojadę?
|
||||||
|
version: 0.1.0
|
||||||
|
parameters:
|
||||||
|
provider:
|
||||||
|
in: path
|
||||||
|
name: provider
|
||||||
|
type: string
|
||||||
|
description: Data provider identificator, e.g. trojmiasto for ZTM Gdańsk.
|
||||||
|
required: true
|
||||||
|
|
||||||
|
areas:
|
||||||
|
path_patterns:
|
||||||
|
- ^/[^\/]+/api(?!/doc$) # Accepts routes under /api except /api/doc
|
||||||
|
|
||||||
|
|
||||||
|
|
6
config/packages/prod/jms_serializer.yaml
Normal file
6
config/packages/prod/jms_serializer.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
jms_serializer:
|
||||||
|
visitors:
|
||||||
|
json_serialization:
|
||||||
|
options:
|
||||||
|
- JSON_UNESCAPED_SLASHES
|
||||||
|
- JSON_PRESERVE_ZERO_FRACTION
|
12
config/routes/nelmio_api_doc.yaml
Normal file
12
config/routes/nelmio_api_doc.yaml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Expose your documentation as JSON swagger compliant
|
||||||
|
app.swagger:
|
||||||
|
path: /api/doc.json
|
||||||
|
methods: GET
|
||||||
|
defaults: { _controller: nelmio_api_doc.controller.swagger }
|
||||||
|
|
||||||
|
## Requires the Asset component and the Twig bundle
|
||||||
|
## $ composer require twig asset
|
||||||
|
app.swagger_ui:
|
||||||
|
path: /api/doc
|
||||||
|
methods: GET
|
||||||
|
defaults: { _controller: nelmio_api_doc.controller.swagger_ui }
|
@ -42,6 +42,15 @@ services:
|
|||||||
assets.modified_time_version_strategy:
|
assets.modified_time_version_strategy:
|
||||||
class: App\Asset\ModifiedTimeVersionStrategy
|
class: App\Asset\ModifiedTimeVersionStrategy
|
||||||
|
|
||||||
|
#eerialziser
|
||||||
|
jms_serializer.serialized_name_annotation_strategy:
|
||||||
|
class: JMS\Serializer\Naming\SerializedNameAnnotationStrategy
|
||||||
|
arguments:
|
||||||
|
- '@jms_serializer.identical_property_naming_strategy'
|
||||||
|
|
||||||
|
App\Serialization\CarbonHandler:
|
||||||
|
arguments: ['@jms_serializer.datetime_handler']
|
||||||
|
|
||||||
#proxy configuration
|
#proxy configuration
|
||||||
proxy.locator:
|
proxy.locator:
|
||||||
class: 'ProxyManager\FileLocator\FileLocator'
|
class: 'ProxyManager\FileLocator\FileLocator'
|
||||||
|
@ -32,6 +32,7 @@ if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? false) {
|
|||||||
Request::setTrustedHosts(explode(',', $trustedHosts));
|
Request::setTrustedHosts(explode(',', $trustedHosts));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
\Doctrine\Common\Annotations\AnnotationReader::addGlobalIgnoredName('alias');
|
||||||
$kernel = new Kernel($env, $debug);
|
$kernel = new Kernel($env, $debug);
|
||||||
$request = Request::createFromGlobals();
|
$request = Request::createFromGlobals();
|
||||||
$response = $kernel->handle($request);
|
$response = $kernel->handle($request);
|
||||||
|
@ -35,10 +35,10 @@ export class FinderComponent extends Vue {
|
|||||||
|
|
||||||
this.state = 'fetching';
|
this.state = 'fetching';
|
||||||
|
|
||||||
const response = await fetch(urls.prepare(urls.stops.search, { name: this.filter }));
|
const response = await fetch(urls.prepare(urls.stops.grouped, { name: this.filter }));
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
this.found = await response.json();
|
this.found = (await response.json()).reduce((accumulator, { name, stops }) => Object.assign(accumulator, { [name]: stops }), {});
|
||||||
this.state = 'ready';
|
this.state = 'ready';
|
||||||
} else {
|
} else {
|
||||||
this.state = 'error';
|
this.state = 'error';
|
||||||
|
@ -51,10 +51,10 @@ export default {
|
|||||||
departures: `${base}/departures`,
|
departures: `${base}/departures`,
|
||||||
messages: `${base}/messages`,
|
messages: `${base}/messages`,
|
||||||
stops: {
|
stops: {
|
||||||
all: `${base}/stops`,
|
all: `${base}/stops`,
|
||||||
search: `${base}/stops/search`,
|
grouped: `${base}/stops/groups`,
|
||||||
get: `${base}/stops/{id}`,
|
get: `${base}/stops/{id}`,
|
||||||
tracks: `${base}/stops/{id}/tracks`
|
tracks: `${base}/stops/{id}/tracks`
|
||||||
},
|
},
|
||||||
prepare: (url: string, params: UrlParams = { }) => prepare(url, Object.assign({}, { provider: window['data'].provider }, params))
|
prepare: (url: string, params: UrlParams = { }) => prepare(url, Object.assign({}, { provider: window['data'].provider }, params))
|
||||||
}
|
}
|
106
ruleset.xml
Normal file
106
ruleset.xml
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<rulset name="Kadet.CzyDojade">
|
||||||
|
<description>Czy Dojadę ruleset</description>
|
||||||
|
|
||||||
|
<arg name="colors"/>
|
||||||
|
<arg name="parallel" value="75"/>
|
||||||
|
|
||||||
|
<rule ref="Internal.Tokenizer.Exception">
|
||||||
|
<type>error</type>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- PSR 2 -->
|
||||||
|
<rule ref="PSR2">
|
||||||
|
<exclude name="PSR2.Namespaces"/>
|
||||||
|
<exclude name="PSR2.Classes.PropertyDeclaration.Underscore"/>
|
||||||
|
<exclude name="PSR2.Classes.MethodDeclaration.Underscore"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- No More Than 2 lines -->
|
||||||
|
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace">
|
||||||
|
<properties>
|
||||||
|
<property name="ignoreBlankLines" value="false"/>
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.StartFile">
|
||||||
|
<severity>10</severity>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EndFile">
|
||||||
|
<severity>10</severity>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EmptyLines">
|
||||||
|
<severity>5</severity>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule ref="Squiz.WhiteSpace.OperatorSpacing">
|
||||||
|
<properties>
|
||||||
|
<property name="ignoreNewlines" value="true"/>
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- Make this sniff more sensitive to commented out code blocks. -->
|
||||||
|
<rule ref="Squiz.PHP.CommentedOutCode">
|
||||||
|
<properties>
|
||||||
|
<property name="maxPercentage" value="60"/>
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- Line length -->
|
||||||
|
<rule ref="Generic.Files.LineLength">
|
||||||
|
<properties>
|
||||||
|
<property name="lineLimit" value="120"/>
|
||||||
|
<property name="absoluteLineLimit" value="180"/>
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- Linus rule -->
|
||||||
|
<rule ref="Generic.Metrics.NestingLevel">
|
||||||
|
<properties>
|
||||||
|
<property name="nestingLevel" value="3"/>
|
||||||
|
<property name="absoluteNestingLevel" value="6"/>
|
||||||
|
</properties>
|
||||||
|
<severity>50</severity>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule ref="Generic.Strings.UnnecessaryStringConcat">
|
||||||
|
<properties>
|
||||||
|
<property name="allowMultiline" value="true"/>
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule ref="Squiz.Arrays.ArrayDeclaration">
|
||||||
|
<exclude name="Squiz.Arrays.ArrayDeclaration.KeyNotAligned"/>
|
||||||
|
<exclude name="Squiz.Arrays.ArrayDeclaration.ValueNotAligned"/>
|
||||||
|
<exclude name="Squiz.Arrays.ArrayDeclaration.CloseBraceNotAligned"/>
|
||||||
|
<exclude name="Squiz.Arrays.ArrayDeclaration.SingleLineNotAllowed"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule ref="Generic.Arrays.ArrayIndent"/>
|
||||||
|
|
||||||
|
<rule ref="Squiz.Arrays.ArrayDeclaration.SingleLineNotAllowed">
|
||||||
|
<severity>0</severity>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule ref="Squiz.Arrays.ArrayDeclaration.MultiLineNotAllowed">
|
||||||
|
<severity>1</severity>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- Ban some functions -->
|
||||||
|
<rule ref="Generic.PHP.ForbiddenFunctions">
|
||||||
|
<properties>
|
||||||
|
<property name="forbiddenFunctions" type="array">
|
||||||
|
<element key="sizeof" value="count"/>
|
||||||
|
<element key="delete" value="unset"/>
|
||||||
|
<element key="print" value="echo"/>
|
||||||
|
<element key="is_null" value="null"/>
|
||||||
|
<element key="create_function" value="null"/>
|
||||||
|
</property>
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- a feee -->
|
||||||
|
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
|
||||||
|
</rulset>
|
@ -7,6 +7,8 @@ use App\Controller\Controller;
|
|||||||
use App\Model\Departure;
|
use App\Model\Departure;
|
||||||
use App\Provider\DepartureRepository;
|
use App\Provider\DepartureRepository;
|
||||||
use App\Provider\StopRepository;
|
use App\Provider\StopRepository;
|
||||||
|
use Nelmio\ApiDocBundle\Annotation\Model;
|
||||||
|
use Swagger\Annotations as SWG;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
|
||||||
@ -18,17 +20,22 @@ use Symfony\Component\Routing\Annotation\Route;
|
|||||||
class DeparturesController extends Controller
|
class DeparturesController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @Route("/{id}")
|
* @Route("/{stop}", methods={"GET"})
|
||||||
|
* @SWG\Response(
|
||||||
|
* description="Gets departures from particular stop.",
|
||||||
|
* response=200,
|
||||||
|
* @SWG\Schema(type="array", @SWG\Items(ref=@Model(type=Departure::class)))
|
||||||
|
* )
|
||||||
*/
|
*/
|
||||||
public function stop(DepartureRepository $departures, StopRepository $stops, $id)
|
public function stop(DepartureRepository $departures, StopRepository $stops, $stop)
|
||||||
{
|
{
|
||||||
$stop = $stops->getById($id);
|
$stop = $stops->getById($stop);
|
||||||
|
|
||||||
return $this->json($departures->getForStop($stop));
|
return $this->json($departures->getForStop($stop));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/")
|
* @Route("/", methods={"GET"})
|
||||||
*/
|
*/
|
||||||
public function stops(DepartureRepository $departures, StopRepository $stops, Request $request)
|
public function stops(DepartureRepository $departures, StopRepository $stops, Request $request)
|
||||||
{
|
{
|
||||||
|
@ -5,14 +5,20 @@ namespace App\Controller\Api\v1;
|
|||||||
|
|
||||||
use App\Controller\Controller;
|
use App\Controller\Controller;
|
||||||
use App\Provider\MessageRepository;
|
use App\Provider\MessageRepository;
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
use Nelmio\ApiDocBundle\Annotation\Model;
|
||||||
|
use Swagger\Annotations as SWG;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use App\Model\Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/messages")
|
* @Route("/messages")
|
||||||
|
* @SWG\Tag(name="Messages")
|
||||||
|
* @SWG\Parameter(ref="#/parameters/provider")
|
||||||
*/
|
*/
|
||||||
class MessagesController extends Controller
|
class MessagesController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
* @SWG\Response(response=200, description="Returns all messages from carrier at given moment.", @SWG\Schema(type="array", @SWG\Items(ref=@Model(type=Message::class))))
|
||||||
* @Route("/", methods={"GET"})
|
* @Route("/", methods={"GET"})
|
||||||
*/
|
*/
|
||||||
public function all(MessageRepository $messages)
|
public function all(MessageRepository $messages)
|
||||||
|
@ -5,9 +5,12 @@ namespace App\Controller\Api\v1;
|
|||||||
|
|
||||||
use App\Controller\Controller;
|
use App\Controller\Controller;
|
||||||
use App\Model\Stop;
|
use App\Model\Stop;
|
||||||
|
use App\Model\StopGroup;
|
||||||
use App\Provider\StopRepository;
|
use App\Provider\StopRepository;
|
||||||
use App\Provider\TrackRepository;
|
use App\Provider\TrackRepository;
|
||||||
use App\Service\Proxy\ReferenceFactory;
|
use App\Service\Proxy\ReferenceFactory;
|
||||||
|
use Nelmio\ApiDocBundle\Annotation\Model;
|
||||||
|
use Swagger\Annotations as SWG;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
|
||||||
@ -16,34 +19,95 @@ use Symfony\Component\Routing\Annotation\Route;
|
|||||||
*
|
*
|
||||||
* @package App\Controller
|
* @package App\Controller
|
||||||
* @Route("/stops")
|
* @Route("/stops")
|
||||||
|
*
|
||||||
|
* @SWG\Tag(name="stops")
|
||||||
|
* @SWG\Parameter(ref="#/parameters/provider")
|
||||||
*/
|
*/
|
||||||
class StopsController extends Controller
|
class StopsController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
* @SWG\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns all stops for specific provider, e.g. ZTM Gdańsk.",
|
||||||
|
* @SWG\Schema(type="array", @SWG\Items(ref=@Model(type=Stop::class)))
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @SWG\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="query",
|
||||||
|
* type="array",
|
||||||
|
* description="Stop identificators to retrieve at once. Can be used to bulk load data. If not specified will return all data.",
|
||||||
|
* @SWG\Items(type="string")
|
||||||
|
* )
|
||||||
|
*
|
||||||
* @Route("/", methods={"GET"})
|
* @Route("/", methods={"GET"})
|
||||||
*/
|
*/
|
||||||
public function index(Request $request, StopRepository $stops)
|
public function index(Request $request, StopRepository $stops)
|
||||||
{
|
{
|
||||||
$result = $request->query->has('id')
|
switch (true) {
|
||||||
? $stops->getManyById($request->query->get('id'))
|
case $request->query->has('id'):
|
||||||
: $stops->getAllGroups();
|
$result = $stops->getManyById($request->query->get('id'));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case $request->query->has('name'):
|
||||||
|
$result = $stops->findGroupsByName($request->query->get('name'));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$result = $stops->getAllGroups();
|
||||||
|
}
|
||||||
|
|
||||||
return $this->json($result->all());
|
return $this->json($result->all());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/search", methods={"GET"})
|
* @SWG\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns grouped stops for specific provider, e.g. ZTM Gdańsk.",
|
||||||
|
* @SWG\Schema(type="array", @SWG\Items(ref=@Model(type=StopGroup::class)))
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @SWG\Parameter(
|
||||||
|
* name="name",
|
||||||
|
* in="query",
|
||||||
|
* type="string",
|
||||||
|
* description="Part of the stop name to search for.",
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @Route("/groups", methods={"GET"})
|
||||||
*/
|
*/
|
||||||
public function find(Request $request, StopRepository $stops)
|
public function groups(Request $request, StopRepository $stops)
|
||||||
{
|
{
|
||||||
$result = $request->query->has('name')
|
switch (true) {
|
||||||
? $stops->findGroupsByName($request->query->get('name'))
|
case $request->query->has('id'):
|
||||||
: $stops->getAllGroups();
|
$result = $stops->getManyById($request->query->get('id'));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case $request->query->has('name'):
|
||||||
|
$result = $stops->findGroupsByName($request->query->get('name'));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$result = $stops->getAllGroups();
|
||||||
|
}
|
||||||
|
|
||||||
return $this->json($result->all());
|
return $this->json($result->all());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @SWG\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns specific stop referenced via identificator.",
|
||||||
|
* @SWG\Schema(ref=@Model(type=Stop::class))
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @SWG\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* type="string",
|
||||||
|
* description="Stop identificator as provided by data provider."
|
||||||
|
* )
|
||||||
|
*
|
||||||
* @Route("/{id}", methods={"GET"})
|
* @Route("/{id}", methods={"GET"})
|
||||||
*/
|
*/
|
||||||
public function one(Request $request, StopRepository $stops, $id)
|
public function one(Request $request, StopRepository $stops, $id)
|
||||||
|
@ -4,10 +4,13 @@ namespace App\Controller\Api\v1;
|
|||||||
|
|
||||||
use App\Controller\Controller;
|
use App\Controller\Controller;
|
||||||
use App\Model\Stop;
|
use App\Model\Stop;
|
||||||
|
use App\Model\Track;
|
||||||
use App\Provider\TrackRepository;
|
use App\Provider\TrackRepository;
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
use Nelmio\ApiDocBundle\Annotation\Model;
|
||||||
|
use Swagger\Annotations as SWG;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
use function App\Functions\encapsulate;
|
use function App\Functions\encapsulate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,7 +19,12 @@ use function App\Functions\encapsulate;
|
|||||||
class TracksController extends Controller
|
class TracksController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @Route("/")
|
* @SWG\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns all tracks for specific provider, e.g. ZTM Gdańsk.",
|
||||||
|
* )
|
||||||
|
* @SWG\Tag(name="tracks")
|
||||||
|
* @Route("/", methods={"GET"})
|
||||||
*/
|
*/
|
||||||
public function index(Request $request, TrackRepository $repository)
|
public function index(Request $request, TrackRepository $repository)
|
||||||
{
|
{
|
||||||
@ -28,7 +36,12 @@ class TracksController extends Controller
|
|||||||
case $request->query->has('id'):
|
case $request->query->has('id'):
|
||||||
return $this->byId($request, $repository);
|
return $this->byId($request, $repository);
|
||||||
default:
|
default:
|
||||||
throw new BadRequestHttpException(sprintf('At least one parameter of %s must be set.', implode(', ', ['stop', 'line', 'id'])));
|
throw new BadRequestHttpException(
|
||||||
|
sprintf(
|
||||||
|
'At least one parameter of %s must be set.',
|
||||||
|
implode(', ', ['stop', 'line', 'id'])
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,8 +4,21 @@
|
|||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
|
|
||||||
|
use JMS\Serializer\SerializerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller as SymfonyController;
|
use Symfony\Bundle\FrameworkBundle\Controller\Controller as SymfonyController;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
|
|
||||||
abstract class Controller extends SymfonyController
|
abstract class Controller extends SymfonyController
|
||||||
{
|
{
|
||||||
|
private $serializer;
|
||||||
|
|
||||||
|
public function __construct(SerializerInterface $serializer)
|
||||||
|
{
|
||||||
|
$this->serializer = $serializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function json($data, int $status = 200, array $headers = [], array $context = []): JsonResponse
|
||||||
|
{
|
||||||
|
return new JsonResponse($this->serializer->serialize($data, "json"), $status, $headers, true);
|
||||||
|
}
|
||||||
}
|
}
|
@ -26,7 +26,7 @@ class MainController extends Controller
|
|||||||
$state = json_decode($request->query->get('state', '{}'), true) ?: [];
|
$state = json_decode($request->query->get('state', '{}'), true) ?: [];
|
||||||
$state = array_merge([
|
$state = array_merge([
|
||||||
'version' => 1,
|
'version' => 1,
|
||||||
'stops' => []
|
'stops' => [],
|
||||||
], $state);
|
], $state);
|
||||||
|
|
||||||
return $this->render('app.html.twig', compact('state', 'provider'));
|
return $this->render('app.html.twig', compact('state', 'provider'));
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App;
|
namespace App;
|
||||||
|
|
||||||
|
use Doctrine\Common\Annotations\AnnotationReader;
|
||||||
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
||||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||||
use Symfony\Component\Config\Resource\FileResource;
|
use Symfony\Component\Config\Resource\FileResource;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Model;
|
namespace App\Model;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use JMS\Serializer\Annotation as Serializer;
|
||||||
|
|
||||||
class Departure implements Fillable
|
class Departure implements Fillable
|
||||||
{
|
{
|
||||||
@ -104,6 +105,7 @@ class Departure implements Fillable
|
|||||||
$this->stop = $stop;
|
$this->stop = $stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @Serializer\VirtualProperty() */
|
||||||
public function getDelay(): ?int
|
public function getDelay(): ?int
|
||||||
{
|
{
|
||||||
return $this->getEstimated()
|
return $this->getEstimated()
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
namespace App\Model;
|
namespace App\Model;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use JMS\Serializer\Annotation as Serializer;
|
||||||
|
use Swagger\Annotations as SWG;
|
||||||
|
|
||||||
class Message implements Fillable
|
class Message implements Fillable
|
||||||
{
|
{
|
||||||
@ -14,18 +16,23 @@ class Message implements Fillable
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Message content.
|
* Message content.
|
||||||
|
* @Serializer\Type("string")
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $message;
|
private $message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Message type, see TYPE_* constants
|
* Message type, see TYPE_* constants
|
||||||
|
* @Serializer\Type("string")
|
||||||
|
* @SWG\Property(type="string", enum={ Message::TYPE_INFO, Message::TYPE_BREAKDOWN, Message::TYPE_UNKNOWN })
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $type = self::TYPE_UNKNOWN;
|
private $type = self::TYPE_UNKNOWN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Message validity time span start
|
* Message validity time span start
|
||||||
|
* @Serializer\Type("Carbon")
|
||||||
|
* @SWG\Property(type="string")
|
||||||
* @var Carbon|null
|
* @var Carbon|null
|
||||||
*/
|
*/
|
||||||
private $validFrom;
|
private $validFrom;
|
||||||
@ -33,6 +40,8 @@ class Message implements Fillable
|
|||||||
/**
|
/**
|
||||||
* Message validity time span end
|
* Message validity time span end
|
||||||
* @var Carbon|null
|
* @var Carbon|null
|
||||||
|
* @Serializer\Type("Carbon")
|
||||||
|
* @SWG\Property(type="string")
|
||||||
*/
|
*/
|
||||||
private $validTo;
|
private $validTo;
|
||||||
|
|
||||||
|
@ -2,11 +2,15 @@
|
|||||||
|
|
||||||
namespace App\Model;
|
namespace App\Model;
|
||||||
|
|
||||||
|
use Swagger\Annotations as SWG;
|
||||||
|
|
||||||
trait ReferableTrait
|
trait ReferableTrait
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Identifier coming from provider service
|
* Identifier coming from provider service
|
||||||
* @var string
|
* @var string
|
||||||
|
*
|
||||||
|
* @SWG\Property(example="1045")
|
||||||
*/
|
*/
|
||||||
private $id;
|
private $id;
|
||||||
|
|
||||||
|
@ -2,11 +2,18 @@
|
|||||||
|
|
||||||
namespace App\Model;
|
namespace App\Model;
|
||||||
|
|
||||||
|
use JMS\Serializer\Annotation as Serializer;
|
||||||
|
use Swagger\Annotations as SWG;
|
||||||
use Symfony\Component\Serializer\Annotation\Groups;
|
use Symfony\Component\Serializer\Annotation\Groups;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizableInterface;
|
use Symfony\Component\Serializer\Normalizer\NormalizableInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||||
use Tightenco\Collect\Support\Arr;
|
use Tightenco\Collect\Support\Arr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Stop
|
||||||
|
*
|
||||||
|
* @package App\Model
|
||||||
|
*/
|
||||||
class Stop implements Referable, Fillable, NormalizableInterface
|
class Stop implements Referable, Fillable, NormalizableInterface
|
||||||
{
|
{
|
||||||
use FillTrait, ReferableTrait;
|
use FillTrait, ReferableTrait;
|
||||||
@ -14,36 +21,45 @@ class Stop implements Referable, Fillable, NormalizableInterface
|
|||||||
/**
|
/**
|
||||||
* Stop name
|
* Stop name
|
||||||
* @var string
|
* @var string
|
||||||
|
* @SWG\Property(example="Jasień PKM")
|
||||||
|
* @Serializer\Type("string")
|
||||||
*/
|
*/
|
||||||
private $name;
|
private $name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional stop description, should not be longer than 255 chars
|
* Optional stop description, should not be longer than 255 chars.
|
||||||
* @var string|null
|
* @var string|null
|
||||||
|
* @Serializer\Type("string")
|
||||||
*/
|
*/
|
||||||
private $description;
|
private $description;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional stop variant - for example number of shed
|
* Optional stop variant - for example number of shed.
|
||||||
* @var string|null
|
* @var string|null
|
||||||
|
* @SWG\Property(example="01")
|
||||||
|
* @Serializer\Type("string")
|
||||||
*/
|
*/
|
||||||
private $variant;
|
private $variant;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Latitude of stop
|
* Latitude of stop
|
||||||
* @var float|null
|
* @var float|null
|
||||||
|
* @Serializer\Exclude()
|
||||||
*/
|
*/
|
||||||
private $latitude;
|
private $latitude;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Longitude of stop
|
* Longitude of stop
|
||||||
* @var float|null
|
* @var float|null
|
||||||
|
* @Serializer\Exclude()
|
||||||
*/
|
*/
|
||||||
private $longitude;
|
private $longitude;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if stop is available only on demand
|
* True if stop is available only on demand
|
||||||
* @var bool
|
* @var bool
|
||||||
|
* @Serializer\Type("bool")
|
||||||
|
* @SWG\Property(example=false)
|
||||||
*/
|
*/
|
||||||
private $onDemand = false;
|
private $onDemand = false;
|
||||||
|
|
||||||
@ -77,7 +93,6 @@ class Stop implements Referable, Fillable, NormalizableInterface
|
|||||||
$this->variant = $variant;
|
$this->variant = $variant;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @Groups({"hidden"}) */
|
|
||||||
public function getLatitude(): ?float
|
public function getLatitude(): ?float
|
||||||
{
|
{
|
||||||
return $this->latitude;
|
return $this->latitude;
|
||||||
@ -88,7 +103,6 @@ class Stop implements Referable, Fillable, NormalizableInterface
|
|||||||
$this->latitude = $latitude;
|
$this->latitude = $latitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @Groups({"hidden"}) */
|
|
||||||
public function getLongitude(): ?float
|
public function getLongitude(): ?float
|
||||||
{
|
{
|
||||||
return $this->longitude;
|
return $this->longitude;
|
||||||
@ -99,6 +113,12 @@ class Stop implements Referable, Fillable, NormalizableInterface
|
|||||||
$this->longitude = $longitude;
|
$this->longitude = $longitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
* @Serializer\VirtualProperty()
|
||||||
|
* @Serializer\Type("array<string>")
|
||||||
|
* @SWG\Property(type="array", @SWG\Items(type="string", example="1"))
|
||||||
|
*/
|
||||||
public function getLocation(): array
|
public function getLocation(): array
|
||||||
{
|
{
|
||||||
return [ $this->latitude, $this->longitude ];
|
return [ $this->latitude, $this->longitude ];
|
||||||
@ -106,7 +126,7 @@ class Stop implements Referable, Fillable, NormalizableInterface
|
|||||||
|
|
||||||
public function setLocation(array $location)
|
public function setLocation(array $location)
|
||||||
{
|
{
|
||||||
list($this->latitude, $this->longitude) = $location;
|
[$this->latitude, $this->longitude] = $location;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isOnDemand(): bool
|
public function isOnDemand(): bool
|
||||||
|
@ -2,16 +2,42 @@
|
|||||||
|
|
||||||
namespace App\Model;
|
namespace App\Model;
|
||||||
|
|
||||||
|
use JMS\Serializer\Annotation as Serializer;
|
||||||
|
use Nelmio\ApiDocBundle\Annotation\Model;
|
||||||
|
use Swagger\Annotations as SWG;
|
||||||
use Tightenco\Collect\Support\Collection;
|
use Tightenco\Collect\Support\Collection;
|
||||||
|
use App\Model\Stop;
|
||||||
|
|
||||||
class StopGroup extends Collection
|
/**
|
||||||
|
* Class StopGroup
|
||||||
|
*
|
||||||
|
* @package App\Model
|
||||||
|
*/
|
||||||
|
class StopGroup
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Name of stop group
|
* Name of stop group.
|
||||||
|
* @SWG\Property(example="Jasień PKM")
|
||||||
|
* @Serializer\Type("string")
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private $name;
|
private $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All stops in group.
|
||||||
|
* @var Collection|Stop[]
|
||||||
|
* @SWG\Property(
|
||||||
|
* type="array",
|
||||||
|
* @SWG\Items(ref=@Model(type=Stop::class))
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
private $stops;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->stops = new Collection();
|
||||||
|
}
|
||||||
|
|
||||||
public function getName(): string
|
public function getName(): string
|
||||||
{
|
{
|
||||||
return $this->name;
|
return $this->name;
|
||||||
@ -21,4 +47,14 @@ class StopGroup extends Collection
|
|||||||
{
|
{
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setStops($stops)
|
||||||
|
{
|
||||||
|
$this->stops = new Collection($stops);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getStops()
|
||||||
|
{
|
||||||
|
return $this->stops;
|
||||||
|
}
|
||||||
}
|
}
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Model;
|
namespace App\Model;
|
||||||
|
|
||||||
|
use Swagger\Annotations as SWG;
|
||||||
use Tightenco\Collect\Support\Collection;
|
use Tightenco\Collect\Support\Collection;
|
||||||
|
|
||||||
class Track implements Referable, Fillable
|
class Track implements Referable, Fillable
|
||||||
@ -29,11 +30,11 @@ class Track implements Referable, Fillable
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops in track
|
* Stops in track
|
||||||
* @var Collection
|
* @var Stop[]|Collection
|
||||||
|
* @SWG\Property(type="Stop")
|
||||||
*/
|
*/
|
||||||
private $stops;
|
private $stops;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Track constructor.
|
* Track constructor.
|
||||||
*/
|
*/
|
||||||
|
@ -56,11 +56,13 @@ class GenericStopRepository extends DatabaseRepository implements StopRepository
|
|||||||
{
|
{
|
||||||
return $stops->groupBy(function (Stop $stop) {
|
return $stops->groupBy(function (Stop $stop) {
|
||||||
return $stop->getName();
|
return $stop->getName();
|
||||||
})->map(function ($group, $key) {
|
})->map(function ($stops, $key) {
|
||||||
$group = new StopGroup($group);
|
$group = new StopGroup();
|
||||||
|
|
||||||
$group->setName($key);
|
$group->setName($key);
|
||||||
|
$group->setStops($stops);
|
||||||
|
|
||||||
return $group;
|
return $group;
|
||||||
});
|
})->values();
|
||||||
}
|
}
|
||||||
}
|
}
|
90
src/Serialization/CarbonHandler.php
Normal file
90
src/Serialization/CarbonHandler.php
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Serialization;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use JMS\Serializer\DeserializationContext;
|
||||||
|
use JMS\Serializer\GraphNavigatorInterface;
|
||||||
|
use JMS\Serializer\Handler\DateHandler;
|
||||||
|
use JMS\Serializer\Handler\SubscribingHandlerInterface;
|
||||||
|
use JMS\Serializer\SerializationContext;
|
||||||
|
use JMS\Serializer\Visitor\DeserializationVisitorInterface;
|
||||||
|
use JMS\Serializer\Visitor\SerializationVisitorInterface;
|
||||||
|
use Tightenco\Collect\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class LaravelCollectionHandler
|
||||||
|
*
|
||||||
|
* Shamelessly copied from https://github.com/schmittjoh/serializer/blob/master/src/Handler/ArrayCollectionHandler.php
|
||||||
|
*
|
||||||
|
* @package App\Serialization
|
||||||
|
*/
|
||||||
|
final class CarbonHandler implements SubscribingHandlerInterface
|
||||||
|
{
|
||||||
|
private $dateTimeHandler;
|
||||||
|
|
||||||
|
public function __construct(DateHandler $dateHandler)
|
||||||
|
{
|
||||||
|
$this->dateTimeHandler = $dateHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public static function getSubscribingMethods()
|
||||||
|
{
|
||||||
|
$methods = [];
|
||||||
|
$formats = ['json', 'xml', 'yml'];
|
||||||
|
|
||||||
|
$collectionTypes = [
|
||||||
|
'Carbon',
|
||||||
|
Carbon::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($collectionTypes as $type) {
|
||||||
|
foreach ($formats as $format) {
|
||||||
|
$methods[] = [
|
||||||
|
'direction' => GraphNavigatorInterface::DIRECTION_SERIALIZATION,
|
||||||
|
'type' => $type,
|
||||||
|
'format' => $format,
|
||||||
|
'method' => 'serialize',
|
||||||
|
];
|
||||||
|
|
||||||
|
$methods[] = [
|
||||||
|
'direction' => GraphNavigatorInterface::DIRECTION_DESERIALIZATION,
|
||||||
|
'type' => $type,
|
||||||
|
'format' => $format,
|
||||||
|
'method' => 'deserialize',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|\ArrayObject
|
||||||
|
*/
|
||||||
|
public function serialize(
|
||||||
|
SerializationVisitorInterface $visitor,
|
||||||
|
Carbon $date,
|
||||||
|
array $type,
|
||||||
|
SerializationContext $context
|
||||||
|
) {
|
||||||
|
return $this->dateTimeHandler->serializeDateTime($visitor, $date, $type, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $data
|
||||||
|
*/
|
||||||
|
public function deserialize(
|
||||||
|
DeserializationVisitorInterface $visitor,
|
||||||
|
$data,
|
||||||
|
array $type,
|
||||||
|
DeserializationContext $context
|
||||||
|
): Collection {
|
||||||
|
return new Collection($visitor->visitArray($data, $type));
|
||||||
|
}
|
||||||
|
}
|
87
src/Serialization/LaravelCollectionHandler.php
Normal file
87
src/Serialization/LaravelCollectionHandler.php
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Serialization;
|
||||||
|
|
||||||
|
use JMS\Serializer\DeserializationContext;
|
||||||
|
use JMS\Serializer\GraphNavigatorInterface;
|
||||||
|
use JMS\Serializer\Handler\SubscribingHandlerInterface;
|
||||||
|
use JMS\Serializer\SerializationContext;
|
||||||
|
use JMS\Serializer\Visitor\DeserializationVisitorInterface;
|
||||||
|
use JMS\Serializer\Visitor\SerializationVisitorInterface;
|
||||||
|
use Tightenco\Collect\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class LaravelCollectionHandler
|
||||||
|
*
|
||||||
|
* Shamelessly copied from https://github.com/schmittjoh/serializer/blob/master/src/Handler/ArrayCollectionHandler.php
|
||||||
|
*
|
||||||
|
* @package App\Serialization
|
||||||
|
*/
|
||||||
|
final class LaravelCollectionHandler implements SubscribingHandlerInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public static function getSubscribingMethods()
|
||||||
|
{
|
||||||
|
$methods = [];
|
||||||
|
$formats = ['json', 'xml', 'yml'];
|
||||||
|
$collectionTypes = [
|
||||||
|
'Collection',
|
||||||
|
Collection::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($collectionTypes as $type) {
|
||||||
|
foreach ($formats as $format) {
|
||||||
|
$methods[] = [
|
||||||
|
'direction' => GraphNavigatorInterface::DIRECTION_SERIALIZATION,
|
||||||
|
'type' => $type,
|
||||||
|
'format' => $format,
|
||||||
|
'method' => 'serializeCollection',
|
||||||
|
];
|
||||||
|
|
||||||
|
$methods[] = [
|
||||||
|
'direction' => GraphNavigatorInterface::DIRECTION_DESERIALIZATION,
|
||||||
|
'type' => $type,
|
||||||
|
'format' => $format,
|
||||||
|
'method' => 'deserializeCollection',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|\ArrayObject
|
||||||
|
*/
|
||||||
|
public function serializeCollection(
|
||||||
|
SerializationVisitorInterface $visitor,
|
||||||
|
Collection $collection,
|
||||||
|
array $type,
|
||||||
|
SerializationContext $context
|
||||||
|
) {
|
||||||
|
// We change the base type, and pass through possible parameters.
|
||||||
|
$type['name'] = 'array';
|
||||||
|
$result = $visitor->visitArray($collection->all(), $type);
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $data
|
||||||
|
*/
|
||||||
|
public function deserializeCollection(
|
||||||
|
DeserializationVisitorInterface $visitor,
|
||||||
|
$data,
|
||||||
|
array $type,
|
||||||
|
DeserializationContext $context
|
||||||
|
): Collection {
|
||||||
|
// See above.
|
||||||
|
$type['name'] = 'array';
|
||||||
|
|
||||||
|
return new Collection($visitor->visitArray($data, $type));
|
||||||
|
}
|
||||||
|
}
|
86
symfony.lock
86
symfony.lock
@ -65,15 +65,89 @@
|
|||||||
"doctrine/reflection": {
|
"doctrine/reflection": {
|
||||||
"version": "v1.0.0"
|
"version": "v1.0.0"
|
||||||
},
|
},
|
||||||
|
"exsyst/swagger": {
|
||||||
|
"version": "v0.4.1"
|
||||||
|
},
|
||||||
|
"hoa/compiler": {
|
||||||
|
"version": "3.17.08.08"
|
||||||
|
},
|
||||||
|
"hoa/consistency": {
|
||||||
|
"version": "1.17.05.02"
|
||||||
|
},
|
||||||
|
"hoa/event": {
|
||||||
|
"version": "1.17.01.13"
|
||||||
|
},
|
||||||
|
"hoa/exception": {
|
||||||
|
"version": "1.17.01.16"
|
||||||
|
},
|
||||||
|
"hoa/file": {
|
||||||
|
"version": "1.17.07.11"
|
||||||
|
},
|
||||||
|
"hoa/iterator": {
|
||||||
|
"version": "2.17.01.10"
|
||||||
|
},
|
||||||
|
"hoa/math": {
|
||||||
|
"version": "1.17.05.16"
|
||||||
|
},
|
||||||
|
"hoa/protocol": {
|
||||||
|
"version": "1.17.01.14"
|
||||||
|
},
|
||||||
|
"hoa/regex": {
|
||||||
|
"version": "1.17.01.13"
|
||||||
|
},
|
||||||
|
"hoa/stream": {
|
||||||
|
"version": "1.17.02.21"
|
||||||
|
},
|
||||||
|
"hoa/ustring": {
|
||||||
|
"version": "4.17.01.16"
|
||||||
|
},
|
||||||
|
"hoa/visitor": {
|
||||||
|
"version": "2.17.01.16"
|
||||||
|
},
|
||||||
|
"hoa/zformat": {
|
||||||
|
"version": "1.17.01.10"
|
||||||
|
},
|
||||||
"jdorn/sql-formatter": {
|
"jdorn/sql-formatter": {
|
||||||
"version": "v1.2.17"
|
"version": "v1.2.17"
|
||||||
},
|
},
|
||||||
|
"jms/metadata": {
|
||||||
|
"version": "1.7.0"
|
||||||
|
},
|
||||||
|
"jms/serializer": {
|
||||||
|
"version": "1.14.0"
|
||||||
|
},
|
||||||
|
"jms/serializer-bundle": {
|
||||||
|
"version": "3.0",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes-contrib",
|
||||||
|
"branch": "master",
|
||||||
|
"version": "3.0",
|
||||||
|
"ref": "384cec52df45f3bfd46a09930d6960a58872b268"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"config/packages/dev/jms_serializer.yaml",
|
||||||
|
"config/packages/jms_serializer.yaml",
|
||||||
|
"config/packages/prod/jms_serializer.yaml"
|
||||||
|
]
|
||||||
|
},
|
||||||
"kadet/functional": {
|
"kadet/functional": {
|
||||||
"version": "dev-master"
|
"version": "dev-master"
|
||||||
},
|
},
|
||||||
|
"kylekatarnls/update-helper": {
|
||||||
|
"version": "1.2.0"
|
||||||
|
},
|
||||||
"monolog/monolog": {
|
"monolog/monolog": {
|
||||||
"version": "1.23.0"
|
"version": "1.23.0"
|
||||||
},
|
},
|
||||||
|
"nelmio/api-doc-bundle": {
|
||||||
|
"version": "3.0",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes-contrib",
|
||||||
|
"branch": "master",
|
||||||
|
"version": "3.0",
|
||||||
|
"ref": "c8e0c38e1a280ab9e37587a8fa32b251d5bc1c94"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nesbot/carbon": {
|
"nesbot/carbon": {
|
||||||
"version": "1.33.0"
|
"version": "1.33.0"
|
||||||
},
|
},
|
||||||
@ -83,6 +157,9 @@
|
|||||||
"ocramius/proxy-manager": {
|
"ocramius/proxy-manager": {
|
||||||
"version": "2.2.1"
|
"version": "2.2.1"
|
||||||
},
|
},
|
||||||
|
"php": {
|
||||||
|
"version": "7.3.12"
|
||||||
|
},
|
||||||
"phpdocumentor/reflection-common": {
|
"phpdocumentor/reflection-common": {
|
||||||
"version": "1.0.1"
|
"version": "1.0.1"
|
||||||
},
|
},
|
||||||
@ -191,6 +268,9 @@
|
|||||||
"ref": "18ebf5a940573a20de06f9c4060101eeb438cf3d"
|
"ref": "18ebf5a940573a20de06f9c4060101eeb438cf3d"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"symfony/options-resolver": {
|
||||||
|
"version": "v4.1.12"
|
||||||
|
},
|
||||||
"symfony/orm-pack": {
|
"symfony/orm-pack": {
|
||||||
"version": "v1.0.5"
|
"version": "v1.0.5"
|
||||||
},
|
},
|
||||||
@ -224,6 +304,9 @@
|
|||||||
"symfony/serializer-pack": {
|
"symfony/serializer-pack": {
|
||||||
"version": "v1.0.1"
|
"version": "v1.0.1"
|
||||||
},
|
},
|
||||||
|
"symfony/stopwatch": {
|
||||||
|
"version": "v4.1.12"
|
||||||
|
},
|
||||||
"symfony/translation": {
|
"symfony/translation": {
|
||||||
"version": "3.3",
|
"version": "3.3",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
@ -274,5 +357,8 @@
|
|||||||
},
|
},
|
||||||
"zendframework/zend-eventmanager": {
|
"zendframework/zend-eventmanager": {
|
||||||
"version": "3.2.1"
|
"version": "3.2.1"
|
||||||
|
},
|
||||||
|
"zircote/swagger-php": {
|
||||||
|
"version": "2.0.14"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
{% extends '@!NelmioApiDoc/SwaggerUi/index.html.twig' %}
|
||||||
|
|
||||||
|
{% block stylesheets %}
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700">
|
||||||
|
{{ parent() }}
|
||||||
|
<style type="text/css" rel="stylesheet">
|
||||||
|
#formats {
|
||||||
|
font-family: Open Sans,sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.swagger-ui .opblock-tag,
|
||||||
|
.swagger-ui .opblock .opblock-section-header label,
|
||||||
|
.swagger-ui .opblock .opblock-section-header h4,
|
||||||
|
.swagger-ui .opblock .opblock-summary-method,
|
||||||
|
.swagger-ui .tab li,
|
||||||
|
.swagger-ui .scheme-container .schemes>label,
|
||||||
|
.swagger-ui .loading-container .loading:after,
|
||||||
|
.swagger-ui .btn,
|
||||||
|
.swagger-ui .btn.cancel,
|
||||||
|
.swagger-ui select,
|
||||||
|
.swagger-ui label,
|
||||||
|
.swagger-ui .dialog-ux .modal-ux-content h4,
|
||||||
|
.swagger-ui .dialog-ux .modal-ux-header h3,
|
||||||
|
.swagger-ui section.models h4,
|
||||||
|
.swagger-ui section.models h5,
|
||||||
|
.swagger-ui .model-title,
|
||||||
|
.swagger-ui .parameter__name,
|
||||||
|
.swagger-ui .topbar a,
|
||||||
|
.swagger-ui .topbar .download-url-wrapper .download-url-button,
|
||||||
|
.swagger-ui .info .title small pre,
|
||||||
|
.swagger-ui .scopes h2,
|
||||||
|
.swagger-ui .errors-wrapper hgroup h4 {
|
||||||
|
font-family: Open Sans,sans-serif!important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock stylesheets %}
|
Loading…
Reference in New Issue
Block a user