Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • dbp/relay/dbp-relay-base-course-bundle
1 result
Show changes
Commits on Source (2)
Showing
with 131 additions and 413 deletions
......@@ -6,7 +6,6 @@
"php": ">=7.3",
"ext-json": "*",
"api-platform/core": "^2.6",
"dbp/relay-base-person-bundle": "dev-main",
"dbp/relay-core-bundle": "^0.1.11",
"symfony/framework-bundle": "^5.4"
},
......
......@@ -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": "c6de62624b6c871ceea7cd39f50c97b9",
"content-hash": "f5c22688f47ec610c9b3ebcd5797cb1b",
"packages": [
{
"name": "api-platform/core",
......@@ -167,56 +167,6 @@
],
"time": "2022-01-11T10:29:54+00:00"
},
{
"name": "dbp/relay-base-person-bundle",
"version": "dev-main",
"source": {
"type": "git",
"url": "https://gitlab.tugraz.at/dbp/relay/dbp-relay-base-person-bundle",
"reference": "a7e3c201348fe70841d7e7c031e7a5ca8a007a54"
},
"require": {
"api-platform/core": "^2.6.3",
"dbp/relay-core-bundle": "^0.1.25",
"ext-json": "*",
"guzzlehttp/guzzle": "^7.0",
"nelmio/cors-bundle": "^2.1.0",
"php": ">=7.3",
"phpdocumentor/reflection-docblock": "^3.0 || ^4.0 || ^5.0",
"symfony/config": "^5.2",
"symfony/expression-language": "^5.2",
"symfony/framework-bundle": "^5.2",
"symfony/security-bundle": "^5.2",
"symfony/security-core": "^5.2",
"symfony/security-guard": "^5.2",
"symfony/twig-bundle": "^5.2",
"symfony/validator": "^5.2",
"symfony/yaml": "^5.2"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.0",
"phpstan/phpstan": "^1.0.0",
"phpstan/phpstan-phpunit": "^1.0.0",
"phpunit/phpunit": "^9",
"symfony/browser-kit": "^5.2",
"symfony/http-client": "^5.2",
"symfony/monolog-bundle": "^3.7",
"symfony/phpunit-bridge": "^5.2",
"vimeo/psalm": "^4.4"
},
"default-branch": true,
"type": "symfony-bundle",
"autoload": {
"psr-4": {
"Dbp\\Relay\\BasePersonBundle\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"AGPL-3.0-or-later"
],
"time": "2022-01-31T11:47:53+00:00"
},
{
"name": "dbp/relay-core-bundle",
"version": "v0.1.30",
......@@ -9967,9 +9917,7 @@
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
"dbp/relay-base-person-bundle": 20
},
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
......
......@@ -4,9 +4,7 @@ declare(strict_types=1);
namespace Dbp\Relay\CourseBundle\API;
use Dbp\Relay\BasePersonBundle\Entity\Person;
use Dbp\Relay\CourseBundle\Entity\Course;
use Dbp\Relay\CourseBundle\Entity\Exam;
interface CourseProviderInterface
{
......@@ -21,19 +19,4 @@ interface CourseProviderInterface
* @return Course[]
*/
public function getCoursesByOrganization(string $orgUnitId, array $options = []): array;
/**
* @return Course[]
*/
public function getCoursesByPerson(string $personId, array $options = []): array;
/**
* @return Person[]
*/
public function getStudentsByCourse(string $courseId, array $options = []): array;
/**
* @return Exam[]
*/
public function getExamsByCourse(string $courseId, array $options = []): array;
}
......@@ -27,11 +27,7 @@ class GetCoursesByOrganization extends AbstractController
$page = (int) $request->query->get('page', 1);
$perPage = (int) $request->query->get('perPage', self::ITEMS_PER_PAGE);
$options = [];
if ($request->query->has('lang')) {
$options['lang'] = (string) $request->query->get('lang');
}
$options = ['lang' => $request->query->get('lang', 'de')];
$courses = $this->coursesProvider->getCoursesByOrganization($id, $options);
......
<?php
declare(strict_types=1);
namespace Dbp\Relay\CourseBundle\Controller;
use ApiPlatform\Core\DataProvider\PaginatorInterface;
use Dbp\Relay\CoreBundle\Helpers\ArrayFullPaginator;
use Dbp\Relay\CourseBundle\API\CourseProviderInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
class GetCoursesByPerson extends AbstractController
{
public const ITEMS_PER_PAGE = 250;
protected $coursesProvider;
public function __construct(CourseProviderInterface $coursesProvider)
{
$this->coursesProvider = $coursesProvider;
}
public function __invoke(string $id, Request $request): PaginatorInterface
{
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
$page = (int) $request->query->get('page', 1);
$perPage = (int) $request->query->get('perPage', self::ITEMS_PER_PAGE);
$options = [];
if ($request->query->has('lang')) {
$options['lang'] = (string) $request->query->get('lang');
}
$courses = $this->coursesProvider->getCoursesByPerson($id, $options);
return new ArrayFullPaginator($courses, $page, $perPage);
}
}
<?php
declare(strict_types=1);
namespace Dbp\Relay\CourseBundle\Controller;
use ApiPlatform\Core\DataProvider\PaginatorInterface;
use Dbp\Relay\CoreBundle\Helpers\ArrayFullPaginator;
use Dbp\Relay\CourseBundle\API\CourseProviderInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
class GetExamsByCourse extends AbstractController
{
public const ITEMS_PER_PAGE = 250;
protected $coursesProvider;
public function __construct(CourseProviderInterface $coursesProvider)
{
$this->coursesProvider = $coursesProvider;
}
public function __invoke(string $id, Request $request): PaginatorInterface
{
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
$page = (int) $request->query->get('page', 1);
$perPage = (int) $request->query->get('perPage', self::ITEMS_PER_PAGE);
$options = [];
if ($request->query->has('lang')) {
$options['lang'] = (string) $request->query->get('lang');
}
$courses = $this->coursesProvider->getExamsByCourse($id, $options);
return new ArrayFullPaginator($courses, $page, $perPage);
}
}
<?php
declare(strict_types=1);
namespace Dbp\Relay\CourseBundle\Controller;
use ApiPlatform\Core\DataProvider\PaginatorInterface;
use Dbp\Relay\CoreBundle\Helpers\ArrayFullPaginator;
use Dbp\Relay\CourseBundle\API\CourseProviderInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
class GetStudentsByCourse extends AbstractController
{
public const ITEMS_PER_PAGE = 250;
protected $coursesProvider;
public function __construct(CourseProviderInterface $coursesProvider)
{
$this->coursesProvider = $coursesProvider;
}
public function __invoke(string $id, Request $request): PaginatorInterface
{
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
$page = (int) $request->query->get('page', 1);
$perPage = (int) $request->query->get('perPage', self::ITEMS_PER_PAGE);
$options = [];
if ($request->query->has('lang')) {
$options['lang'] = (string) $request->query->get('lang');
}
$courses = $this->coursesProvider->getStudentsByCourse($id, $options);
return new ArrayFullPaginator($courses, $page, $perPage);
}
}
......@@ -27,17 +27,21 @@ final class CourseCollectionDataProvider extends AbstractController implements C
public function getCollection(string $resourceClass, string $operationName = null, array $context = []): ArrayFullPaginator
{
$perPage = 30;
$page = 1;
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
$filters = $context['filters'] ?? [];
$options = ['lang' => $filters['lang'] ?? 'de'];
$page = 1;
if (isset($filters['page'])) {
$page = (int) $filters['page'];
}
$perPage = 30;
if (isset($filters['perPage'])) {
$perPage = (int) $filters['perPage'];
}
return new ArrayFullPaginator($this->api->getCourses(), $page, $perPage);
return new ArrayFullPaginator($this->api->getCourses($options), $page, $perPage);
}
}
......@@ -26,6 +26,11 @@ final class CourseItemDataProvider extends AbstractController implements ItemDat
public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): ?Course
{
return $this->api->getCourseById($id);
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
$filters = $context['filters'] ?? [];
$options = ['lang' => $filters['lang'] ?? 'de'];
return $this->api->getCourseById($id, $options);
}
}
......@@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Dbp\Relay\CourseBundle\Entity;
use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;
use Dbp\Relay\CourseBundle\Controller\GetCoursesByOrganization;
use Symfony\Component\Serializer\Annotation\Groups;
/**
......@@ -33,20 +33,6 @@ use Symfony\Component\Serializer\Annotation\Groups;
* }
* },
* },
* "get_byperson" = {
* "method" = "GET",
* "path" = "/base/people/{id}/courses",
* "controller" = GetCoursesByPerson::class,
* "read" = false,
* "openapi_context" = {
* "tags" = {"Courses"},
* "summary" = "Get the Courses related to a person.",
* "parameters" = {
* {"name" = "lang", "in" = "query", "description" = "Language of result", "type" = "string", "enum" = {"de", "en"}, "example" = "de"},
* {"name" = "id", "in" = "path", "description" = "Id of Organization", "required" = true, "type" = "string", "example" = "123456"}
* }
* },
* },
* },
* itemOperations={
* "get" = {
......@@ -60,77 +46,9 @@ use Symfony\Component\Serializer\Annotation\Groups;
* },
* iri="https://schema.org/Course",
* normalizationContext={"groups" = {"Course:output"}, "jsonld_embed_context" = true},
* denormalizationContext={"groups" = {"Course:input"}, "jsonld_embed_context" = true}
* )
*/
class Course
class Course implements CourseInterface
{
/**
* @ApiProperty(identifier=true)
*/
private $identifier;
/**
* @ApiProperty(iri="https://schema.org/name")
* @Groups({"Course:output"})
*
* @var string
*/
private $name;
/**
* @ApiProperty
* @Groups({"Course:output"})
*
* @var string
*/
private $type;
/**
* @ApiProperty(iri="https://schema.org/description")
* @Groups({"Course:output"})
*
* @var string
*/
private $description;
public function getIdentifier(): string
{
return $this->identifier;
}
public function setIdentifier(string $identifier): void
{
$this->identifier = $identifier;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): void
{
$this->name = $name;
}
public function getType(): string
{
return $this->type;
}
public function setType(string $type): void
{
$this->type = $type;
}
public function getDescription(): string
{
return $this->description;
}
public function setDescription(string $description): void
{
$this->description = $description;
}
use CourseTrait;
}
<?php
declare(strict_types=1);
namespace Dbp\Relay\CourseBundle\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Dbp\Relay\BasePersonBundle\Entity\PersonTrait;
/**
* @ApiResource(
* collectionOperations={
* "get_bycourse" = {
* "method" = "GET",
* "path" = "/courses/{id}/attendees",
* "controller" = GetStudentsByCourse::class,
* "read" = false,
* "openapi_context" = {
* "tags" = {"Courses"},
* "summary" = "Get the attendees attending to a course.",
* "parameters" = {
* {"name" = "lang", "in" = "query", "description" = "Language of result", "type" = "string", "enum" = {"de", "en"}, "example" = "de"},
* {"name" = "id", "in" = "path", "description" = "Id of Organization", "required" = true, "type" = "string", "example" = "123456"}
* }
* },
* }
* },
* itemOperations={},
* iri="https://schema.org/EducationEvent",
* normalizationContext={"groups" = {"BasePerson:output"}, "jsonld_embed_context" = true},
* denormalizationContext={"groups" = {"BasePerson:input"}, "jsonld_embed_context" = true}
* )
*/
class CourseAttendee
{
use PersonTrait;
}
<?php
declare(strict_types=1);
namespace Dbp\Relay\CourseBundle\Entity;
interface CourseInterface
{
public function getIdentifier(): string;
public function setIdentifier(string $identifier): void;
public function getName(): string;
public function setName(string $name): void;
public function getType(): string;
public function setType(string $type): void;
public function getDescription(): string;
public function setDescription(string $description): void;
}
......@@ -5,75 +5,38 @@ declare(strict_types=1);
namespace Dbp\Relay\CourseBundle\Entity;
use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;
use DateTime;
use DBP\API\CourseBundle\Controller\GetExamsByCourse;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ApiResource(
* collectionOperations={
* "get_bycourse" = {
* "method" = "GET",
* "path" = "/courses/{id}/exams",
* "controller" = GetExamsByCourse::class,
* "read" = false,
* "openapi_context" = {
* "tags" = {"Courses"},
* "summary" = "Get the Exams for a course.",
* "parameters" = {
* {"name" = "lang", "in" = "query", "description" = "Language of result", "type" = "string", "enum" = {"de", "en"}, "example" = "de"},
* {"name" = "id", "in" = "path", "description" = "Id of Organization", "required" = true, "type" = "string", "example" = "123456"}
* }
* },
* }
* },
* itemOperations={},
* iri="https://schema.org/EducationEvent",
* normalizationContext={"groups" = {"Exam:output"}, "jsonld_embed_context" = true},
* denormalizationContext={"groups" = {"Exam:input"}, "jsonld_embed_context" = true}
* )
*/
class Exam
trait CourseTrait
{
/**
* @ApiProperty(identifier=true)
*
* @var string
*/
private $identifier;
/**
* @ApiProperty(iri="https://schema.org/description")
* @Groups({"Exam:output"})
* @ApiProperty(iri="https://schema.org/name")
* @Groups({"Course:output"})
*
* @var string
*/
private $description;
private $name;
/**
* @ApiProperty(iri="https://schema.org/startDate")
* @Groups({"Exam:output"})
* @ApiProperty
* @Groups({"Course:output"})
*
* @var DateTime
*/
private $startDate;
/**
* @ApiProperty(iri="https://schema.org/endDate")
* @Groups({"Exam:output"})
*
* @var DateTime
* @var string
*/
private $endDate;
private $type;
/**
* @ApiProperty(iri="https://schema.org/location")
* @Groups({"Exam:output"})
* @ApiProperty(iri="https://schema.org/description")
* @Groups({"Course:output"})
*
* @var string
*/
private $location;
private $description;
public function getIdentifier(): string
{
......@@ -85,43 +48,33 @@ class Exam
$this->identifier = $identifier;
}
public function getDescription(): string
public function getName(): string
{
return $this->description;
return $this->name;
}
public function setDescription(string $description): void
{
$this->description = $description;
}
public function getStartDate(): DateTime
{
return $this->startDate;
}
public function setStartDate(DateTime $startDate): void
public function setName(string $name): void
{
$this->startDate = $startDate;
$this->name = $name;
}
public function getEndDate(): DateTime
public function getType(): string
{
return $this->endDate;
return $this->type;
}
public function setEndDate(DateTime $endDate): void
public function setType(string $type): void
{
$this->endDate = $endDate;
$this->type = $type;
}
public function getLocation(): string
public function getDescription(): string
{
return $this->location;
return $this->description;
}
public function setLocation(string $location): void
public function setDescription(string $description): void
{
$this->location = $location;
$this->description = $description;
}
}
services:
Dbp\Relay\CourseBundle\Command\TestCommand:
autowire: true
autoconfigure: true
Dbp\Relay\CourseBundle\Controller\:
resource: '../../Controller'
autoconfigure: true
autowire: true
Dbp\Relay\CourseBundle\DataPersister\:
resource: '../../DataPersister'
autowire: true
autoconfigure: true
Dbp\Relay\CourseBundle\DataProvider\:
resource: '../../DataProvider'
autowire: true
autoconfigure: true
Dbp\Relay\CourseBundle\Service\ExternalApi:
autowire: true
autoconfigure: true
Dbp\Relay\CourseBundle\Service\MyCustomService:
Dbp\Relay\CourseBundle\Service\DummyCourseProvider:
autowire: true
autoconfigure: true
Dbp\Relay\CourseBundle\Service\CourseProviderInterface:
'@Dbp\Relay\CourseBundle\Service\ExternalApi'
Dbp\Relay\CourseBundle\API\CourseProviderInterface:
'@Dbp\Relay\CourseBundle\Service\DummyCourseProvider'
......@@ -4,11 +4,8 @@ declare(strict_types=1);
namespace Dbp\Relay\CourseBundle\Service;
use DateTime;
use Dbp\Relay\BasePersonBundle\Entity\Person;
use Dbp\Relay\CourseBundle\API\CourseProviderInterface;
use Dbp\Relay\CourseBundle\Entity\Course;
use Dbp\Relay\CourseBundle\Entity\Exam;
class DummyCourseProvider implements CourseProviderInterface
{
......@@ -34,33 +31,4 @@ class DummyCourseProvider implements CourseProviderInterface
{
return $this->getCourses($options);
}
public function getCoursesByPerson(string $personId, array $options = []): array
{
return $this->getCourses($options);
}
public function getStudentsByCourse(string $courseId, array $options = []): array
{
$person = new Person();
$person->setIdentifier('123');
$person->setFamilyName('Spencer');
$person->setGivenName('Bud');
$person->setEmail('bud@spencer.net');
$person->setBirthDate('1.1.1950');
return [$person];
}
public function getExamsByCourse(string $courseId, array $options = []): array
{
$exam = new Exam();
$exam->setIdentifier('123');
$exam->setDescription('Oral exam');
$exam->setStartDate(new DateTime('25.08.2021 8:00AM'));
$exam->setEndDate(new DateTime('25.08.2021 10:00AM'));
$exam->setLocation('In a room');
return [$exam];
}
}
......@@ -9,32 +9,17 @@ use Symfony\Component\HttpFoundation\Response;
class ApiTest extends ApiTestCase
{
public function testBasics()
public function testCoursesNoAuth()
{
$client = self::createClient();
$response = $client->request('GET', '/course/courses');
$this->assertSame(Response::HTTP_OK, $response->getStatusCode());
$response = $client->request('GET', '/course/courses/graz');
$this->assertSame(Response::HTTP_OK, $response->getStatusCode());
$response = $client->request('DELETE', '/course/courses/graz');
$this->assertSame(Response::HTTP_NO_CONTENT, $response->getStatusCode());
$response = $client->request('PUT', '/course/courses/graz', [
'headers' => [
'Content-Type' => 'application/json',
],
'body' => json_encode(['name' => 'foo']),
]);
$this->assertSame(Response::HTTP_OK, $response->getStatusCode());
$this->assertSame('foo', json_decode($response->getContent(), true)['name']);
$response = $client->request('GET', '/courses');
$this->assertSame(Response::HTTP_UNAUTHORIZED, $response->getStatusCode());
}
public function testNoAuth()
public function testCourseNoAuth()
{
$client = self::createClient();
$response = $client->request('GET', '/course/courses/graz/loggedin-only');
$response = $client->request('GET', '/courses/123');
$this->assertSame(Response::HTTP_UNAUTHORIZED, $response->getStatusCode());
}
}
......@@ -46,9 +46,5 @@ class Kernel extends BaseKernel
'test' => true,
'secret' => '',
]);
$container->extension('dbp_relay_course', [
'example_config' => 'test-42',
]);
}
}
<?php
declare(strict_types=1);
namespace Dbp\Relay\CourseBundle\Tests\Service;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class ExternalApiTest extends WebTestCase
{
protected function setUp(): void
{
}
public function test()
{
}
}