├── .env.dist
├── .gitignore
├── .php-version
├── .php_cs.cache
├── README.md
├── bin
└── console
├── composer.json
├── composer.lock
├── config
├── bootstrap.php
├── bundles.php
├── jwt
│ ├── private.pem
│ └── public.pem
├── packages
│ ├── cache.yaml
│ ├── dev
│ │ ├── routing.yaml
│ │ └── web_profiler.yaml
│ ├── doctrine.yaml
│ ├── doctrine_migrations.yaml
│ ├── fos_rest.yaml
│ ├── framework.yaml
│ ├── lexik_jwt_authentication.yaml
│ ├── nelmio_api_doc.yaml
│ ├── prod
│ │ ├── doctrine.yaml
│ │ └── routing.yaml
│ ├── routing.yaml
│ ├── security.yaml
│ ├── test
│ │ ├── framework.yaml
│ │ ├── routing.yaml
│ │ ├── twig.yaml
│ │ ├── validator.yaml
│ │ └── web_profiler.yaml
│ ├── twig.yaml
│ └── validator.yaml
├── preload.php
├── routes.yaml
├── routes
│ ├── annotations.yaml
│ ├── dev
│ │ ├── framework.yaml
│ │ └── web_profiler.yaml
│ └── nelmio_api_doc.yaml
├── services.yaml
└── services_test.yaml
├── depfile.yml
├── migrations
└── .gitignore
├── psalm.xml
├── public
└── index.php
├── sample.png
├── src
├── Command
│ └── MeetingCommand.php
├── Controller
│ ├── .gitignore
│ ├── MeetingController.php
│ ├── MeetingRegistrationController.php
│ ├── MeetingTagController.php
│ ├── UserController.php
│ └── UserDeviceController.php
├── DataFixtures
│ ├── .gitignore
│ └── UserFixtures.php
├── Doctrine
│ └── RefreshTokenManager.php
├── Entity
│ ├── .UserDevice.php.swp
│ ├── .gitignore
│ ├── Meeting.php
│ ├── Tag.php
│ ├── User.php
│ └── UserDevice.php
├── Event
│ ├── MeetingModifiedEvent.php
│ ├── MeetingRegisteredEvent.php
│ ├── MeetingUnRegisteredEvent.php
│ ├── MeetingUserRegisteredEvent.php
│ ├── MeetingUserUnRegisteredEvent.php
│ ├── UserDeviceRegisteredEvent.php
│ └── UserDeviceRemovedEvent.php
├── EventListener
│ └── MeetingRegisteredListener.php
├── EventSubscriber
│ └── MeetingRegisteredSubscriber.php
├── Exception
│ └── MyException.php
├── Form
│ ├── MeetingType.php
│ └── UserType.php
├── Kernel.php
├── MeetingEvents.php
├── Message
│ └── MeetingMessage.php
├── MessageHandler
│ └── MeetingMessageHandler.php
├── Migrations
│ ├── Version20200125074328.php
│ ├── Version20201222071711.php
│ └── Version20201222132851.php
├── Repository
│ ├── .gitignore
│ ├── MeetingRepository.php
│ ├── TagRepository.php
│ ├── UserDeviceRepository.php
│ └── UserRepository.php
└── Security
│ └── Voter
│ └── MeetingVoter.php
├── symfony.lock
├── templates
├── base.html.twig
├── default
│ └── index.html.twig
├── emails
│ └── registration.html.twig
├── meeting_registration
│ └── index.html.twig
└── user
│ └── index.html.twig
├── tests
└── Util
│ └── CalculatorTest.php
└── ts
└── index.php
/.env.dist:
--------------------------------------------------------------------------------
1 |
2 | # This file is a "template" of which env vars needs to be defined in your configuration or in an .env file
3 | # Set variables here that may be different on each deployment target of the app, e.g. development, staging, production.
4 | # https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration
5 |
6 | ###> symfony/framework-bundle ###
7 | APP_ENV=dev
8 | APP_DEBUG=1
9 | APP_SECRET=67d829bf61dc5f87a73fd814e2c9f629
10 | ###< symfony/framework-bundle ###
11 |
12 | ###> doctrine/doctrine-bundle ###
13 | # Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
14 | # For a sqlite database, use: "sqlite:///%kernel.project_dir%/var/data.db"
15 | # Set "serverVersion" to your server version to avoid edge-case exceptions and extra database calls
16 | DATABASE_URL=mysql://root:root@127.0.0.1:3306/api?charset=utf8mb4&serverVersion=mariadb-10.2.14
17 | ###< doctrine/doctrine-bundle ###
18 |
19 | ###> nelmio/cors-bundle ###
20 | CORS_ALLOW_ORIGIN=^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$
21 | ###< nelmio/cors-bundle ###
22 |
23 | ###> symfony/messenger ###
24 | # Choose one of the transports below
25 | # MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
26 | # MESSENGER_TRANSPORT_DSN=doctrine://default
27 | # MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
28 | ###< symfony/messenger ###
29 |
30 | ###> lexik/jwt-authentication-bundle ###
31 | JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem
32 | JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
33 | JWT_PASSPHRASE=1714faf6bd29f8bd1a02d69a0d136984
34 | ###< lexik/jwt-authentication-bundle ###
35 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ###> symfony/framework-bundle ###
2 | /.env
3 | /public/bundles/
4 | /var/
5 | /vendor/
6 | ###< symfony/framework-bundle ###
7 | tags
8 | .ctags
9 |
10 | ###> lexik/jwt-authentication-bundle ###
11 | /config/jwt/*.pem
12 | ###< lexik/jwt-authentication-bundle ###
13 |
14 |
--------------------------------------------------------------------------------
/.php-version:
--------------------------------------------------------------------------------
1 | 7.4
2 |
--------------------------------------------------------------------------------
/.php_cs.cache:
--------------------------------------------------------------------------------
1 | {"php":"7.2.5-1+ubuntu16.04.1+deb.sury.org+1","version":"2.12.2","rules":{"blank_line_after_namespace":true,"braces":true,"class_definition":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_constants":true,"lowercase_keywords":true,"method_argument_space":{"on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_spaces_after_function_name":true,"no_spaces_inside_parenthesis":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_import_per_statement":true,"single_line_after_imports":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"visibility_required":true,"encoding":true,"full_opening_tag":true},"hashes":{"src\/Event\/MeetingModifiedEvent.php":3291987488,"src\/Event\/UserDeviceRegisteredEvent.php":599758648,"src\/Event\/MeetingRegisteredEvent.php":2196285934,"src\/Event\/MeetingUserRegisteredEvent.php":1234027932,"src\/Event\/MeetingUserUnRegisteredEvent.php":2033796812,"src\/Event\/MeetingUnRegisteredEvent.php":3236709851,"src\/Event\/UserDeviceRemovedEvent.php":3668399556,"src\/MeetingEvents.php":3394194698,"src\/Services\/Interfaces\/MeetingInterface.php":4170378143,"src\/Services\/MeetingService.php":3942900065,"src\/Serializer\/Normalizer\/ExceptionHandler.php":1271418393,"src\/Serializer\/Normalizer\/UserNormalizer.php":2417151589,"src\/EventSubscriber\/MeetingRegisteredSubscriber.php":16862354,"src\/Exception\/MyException.php":2670735671,"src\/Util\/Calculator.php":51273867,"src\/DependencyInjection\/RuleManagerCompilerPass.php":2661132051,"src\/DataFixtures\/UserFixtures.php":486183908,"src\/DataFixtures\/MeetingFixtures.php":1106745876,"src\/Kernel.php":1569315419,"src\/EventListener\/MeetingRegisteredListener.php":1965350084,"src\/Controller\/MeetingTagController.php":2690697174,"src\/Controller\/DefaultController.php":3224857040,"src\/Controller\/UserDeviceController.php":1827808311,"src\/Controller\/MeetingRegistrationController.php":2573131551,"src\/Controller\/MeetingController.php":207569449,"src\/Controller\/MeetingUserController.php":1563735223,"src\/Normalizer\/ExceptionNormalizer.php":2670216402,"src\/Repository\/UserRepository.php":2371032551,"src\/Repository\/TagRepository.php":3447230577,"src\/Repository\/UserDeviceRepository.php":3343829094,"src\/Repository\/MeetingRepository.php":2476684908,"src\/Service\/RuleManager.php":3268426555,"src\/Service\/RuleInterface.php":1620116641,"src\/Service\/IsNumericRule.php":877526536,"src\/Service\/GreaterThanRule.php":561809094,"src\/Entity\/Meeting.php":3051859627,"src\/Entity\/User.php":565099987,"src\/Entity\/Tag.php":1521624089,"src\/Entity\/UserDevice.php":2294109357}}
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Symfony 5 Rest API Using FOSBundle 3 with JWT
2 | ===========================================
3 |
4 | Rest API for Meetings
5 |
6 | $ cp .env.dist .env
7 |
8 | $ composer install
9 |
10 | $ php -S localhost:9100 -t public
11 |
12 |
13 | 
14 |
15 | # RabbitMQ Installation
16 | https://www.linuxhelp.com/how-to-install-rabbitmq-on-linuxmint-18-3/
17 |
--------------------------------------------------------------------------------
/bin/console:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | load(__DIR__.'/../.env');
23 | }
24 |
25 | $input = new ArgvInput();
26 | $env = $input->getParameterOption(['--env', '-e'], $_SERVER['APP_ENV'] ?? 'dev', true);
27 | $debug = (bool) ($_SERVER['APP_DEBUG'] ?? ('prod' !== $env)) && !$input->hasParameterOption('--no-debug', true);
28 |
29 | if ($debug) {
30 | umask(0000);
31 |
32 | if (class_exists(Debug::class)) {
33 | Debug::enable();
34 | }
35 | }
36 |
37 | $kernel = new Kernel($env, $debug);
38 | $application = new Application($kernel);
39 | $application->run($input);
40 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "project",
3 | "license": "proprietary",
4 | "require": {
5 | "php": "^7.2.5",
6 | "ext-ctype": "*",
7 | "ext-iconv": "*",
8 | "doctrine/doctrine-migrations-bundle": "^2.1",
9 | "friendsofsymfony/rest-bundle": "^3.0",
10 | "gesdinet/jwt-refresh-token-bundle": "^0.9.1",
11 | "lexik/jwt-authentication-bundle": "^2.10",
12 | "nelmio/api-doc-bundle": "^4.0",
13 | "predis/predis": "^1.1",
14 | "symfony/asset": "5.2.*",
15 | "symfony/console": "5.2.*",
16 | "symfony/dotenv": "5.2.*",
17 | "symfony/flex": "^1.3.1",
18 | "symfony/framework-bundle": "5.2.*",
19 | "symfony/security-bundle": "5.2.*",
20 | "symfony/serializer-pack": "^1.0",
21 | "symfony/validator": "5.2.*",
22 | "symfony/yaml": "5.2.*"
23 | },
24 | "require-dev": {
25 | "doctrine/doctrine-fixtures-bundle": "^3.4",
26 | "symfony/maker-bundle": "^1.14",
27 | "symfony/profiler-pack": "^1.0"
28 | },
29 | "config": {
30 | "preferred-install": {
31 | "*": "dist"
32 | },
33 | "sort-packages": true
34 | },
35 | "autoload": {
36 | "psr-4": {
37 | "App\\": "src/"
38 | }
39 | },
40 | "autoload-dev": {
41 | "psr-4": {
42 | "App\\Tests\\": "tests/"
43 | }
44 | },
45 | "replace": {
46 | "paragonie/random_compat": "2.*",
47 | "symfony/polyfill-ctype": "*",
48 | "symfony/polyfill-iconv": "*",
49 | "symfony/polyfill-php72": "*",
50 | "symfony/polyfill-php71": "*",
51 | "symfony/polyfill-php70": "*",
52 | "symfony/polyfill-php56": "*"
53 | },
54 | "scripts": {
55 | "auto-scripts": {
56 | "cache:clear": "symfony-cmd",
57 | "assets:install %PUBLIC_DIR%": "symfony-cmd"
58 | },
59 | "post-install-cmd": [
60 | "@auto-scripts"
61 | ],
62 | "post-update-cmd": [
63 | "@auto-scripts"
64 | ]
65 | },
66 | "conflict": {
67 | "symfony/symfony": "*"
68 | },
69 | "extra": {
70 | "symfony": {
71 | "allow-contrib": false,
72 | "require": "5.2.*"
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/config/bootstrap.php:
--------------------------------------------------------------------------------
1 | =1.2)
9 | if (is_array($env = @include dirname(__DIR__).'/.env.local.php')) {
10 | $_ENV += $env;
11 | } elseif (!class_exists(Dotenv::class)) {
12 | throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.');
13 | } else {
14 | $path = dirname(__DIR__).'/.env';
15 | $dotenv = new Dotenv(false);
16 |
17 | // load all the .env files
18 | if (method_exists($dotenv, 'loadEnv')) {
19 | $dotenv->loadEnv($path);
20 | } else {
21 | // fallback code in case your Dotenv component is not 4.2 or higher (when loadEnv() was added)
22 |
23 | if (file_exists($path) || !file_exists($p = "$path.dist")) {
24 | $dotenv->load($path);
25 | } else {
26 | $dotenv->load($p);
27 | }
28 |
29 | if (null === $env = $_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) {
30 | $dotenv->populate(array('APP_ENV' => $env = 'dev'));
31 | }
32 |
33 | if ('test' !== $env && file_exists($p = "$path.local")) {
34 | $dotenv->load($p);
35 | $env = $_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? $env;
36 | }
37 |
38 | if (file_exists($p = "$path.$env")) {
39 | $dotenv->load($p);
40 | }
41 |
42 | if (file_exists($p = "$path.$env.local")) {
43 | $dotenv->load($p);
44 | }
45 | }
46 | }
47 |
48 | $_SERVER += $_ENV;
49 | $_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev';
50 | $_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV'];
51 | $_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0';
52 |
--------------------------------------------------------------------------------
/config/bundles.php:
--------------------------------------------------------------------------------
1 | ['all' => true],
5 | Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
6 | Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
7 | Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
8 | Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
9 | Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
10 | Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
11 | Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
12 | Nelmio\ApiDocBundle\NelmioApiDocBundle::class => ['all' => true],
13 | FOS\RestBundle\FOSRestBundle::class => ['all' => true],
14 | Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true],
15 | Gesdinet\JWTRefreshTokenBundle\GesdinetJWTRefreshTokenBundle::class => ['all' => true],
16 | ];
17 |
--------------------------------------------------------------------------------
/config/jwt/private.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN ENCRYPTED PRIVATE KEY-----
2 | MIIJnzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQISrxe8Wcc7A4CAggA
3 | MB0GCWCGSAFlAwQBKgQQXVjsXKp92jfhA24bWc10bASCCVCQY7jTq2GojScQKeUr
4 | FiiwrlLdPKiGKetLoCmLiID2FkMX05AyyIrTP1qt/z6G7m0lB4wPs0yvAGQgScDb
5 | l/gfjT6ZLiOuEDH59mEoBSnISWZYhSelwqWplP5cHdAhv6+UcweVYK3pPhwvYgch
6 | oI+ER8OK2KGcK6fBFJMetSFEctcpngiZm89y7eCqc/JRENLv4ebH9TnHef1Y9nR9
7 | bHLphNw5FMZ3NfpMws2M47uM0W7Vm9k8FHwDTyzzQ+6zBJ5fh+oGL0A4p0tpbCFQ
8 | Xb+GasVCvtqs1sNasi1rOj4b/gGIN1DhgrbUI32GBgqd/qJYuQEukIX1A09jetLI
9 | S9BAXEupOfGytUdZffhb7kENOvYzb+SyplR7uALxzFHGJU45DjjQDvhTxKPz7f91
10 | /j50FrX1EOhhVhvmZ8VRgs1WkDeohDfykY7ncbHjPfX0UdeYbfrwXg+6o809I56U
11 | Rwf7HehSm41Gtx3D+ne48oXhNFCDgaqAKwK1oEiWdVXg/v/wUUteup+AB8dxD7Hy
12 | W3OuQTThWg2wr5gClvwdWsJ4aQMLTLKe4JbDxovRXG2Za1D1X52Mwl289I+9cFjt
13 | 21mMRWVrLrLvDu2gXcqHphSUATDwdQCQCqjTcoWtNn5V1x3aFX4i90FKqnoS0dYu
14 | E9VQCyn2YqqOuoIemj+6GGo8/vOrELZQ/7g3Qqsd7IwXViVrqHHMupwGkhBjhV2b
15 | sLwOnFtc3hcpBE2qVprgoOFhNaaVSlzlFBcEQoB0Je6Bfdsg9PZ3ri5iiBha4Bok
16 | wedPEEVL9MFdLZOFTqwAL9FKwnmjlp+8pYTnngmm5u+0Cm4dIKVrr2e30NMpqFeH
17 | AVb5ljKPzlGHOv85oqWDx+K/MA34GCSxke5lyUip4+djS03Sq/oVYICMDogQ8Ieo
18 | YDlvsTTCERXOzr6mrKOK63iAlSRL59cKcqBhrXcgy4Ksi9c08Q3rI1NxXGps8g30
19 | qSRCAr2mrqnU8QAWftLfhH9SOJi+A3nxg+RUgSUKgGX/QnJD8CfDpZ9wLOhHGWZq
20 | 3yYcnE89cJpol/RHmt2NAW3hm9E3iSJJakN09hsCublX2qmF33IAz2TzqB0gXWTq
21 | W43QZxLpAzC9wuvw2HWqliQf+N/uQi0yrm+aKcSXxHBf4RSiaKiS1retI/R3bnsk
22 | 2HX9o1bD0tH9+oB+459JwoDPP8wlLLkl89gldfUWYyAdduMxLvrTcd6ny5EvQYu+
23 | 7Qnx5W7Yh7d6D2knC6hShNkqSQHEiM0haIkGkXLrjULZTPUtxLE+jFqIRi8DddNB
24 | qlfDriCP01OKwFKTnXKI5TN1WzG8j0UxtkkZeDDXrPNg7+KAMHUPp7lH8a04RsJ3
25 | xoGExMa4fM6aDU0Nz0Q6lEKpiMCrHS3y6pEwDWQhYktTyVB2t4eS/v9YpSvyi4Kn
26 | CSJwTvn1oMo8ZHsd+S96xGsRk1VOC/OBnlFSdC72d19r4g5qVT9Ack3dOcLI/HUB
27 | ED6Av8f5Vq4PBmDJrr54WQz3PdkM+9niOerzb9Xy+8hNFE9OXV7oYfnGb3hwmKxc
28 | /QBg63tEir7KQqZax+W8VV8b69a0R/u5EvXFDsUApMyG608/8awmYFlxa5JNmoLc
29 | 6rrv2FpS8zsXOQCcHyx8NhK2GVuxNW+UZlFATWEes11GSY20w4H6qK0SCu4PbLvx
30 | i/M3am9WfKfyaK0iInCbFsoywxwnUeNqYrqK8Im9DqbH5nrLrswwUuL8WHNwBETy
31 | 4vfM5h0+DL+5EXiSKcgaeVLlg6h01rxGT+3dDDX0d3cx8IpHvzWyihSocW0+UOQx
32 | lCpFAz5m0npbvcf9SOhnDD0Y8fe/UHDoNHR0uLPou2EJsZeJjPZPgSAdAXTU3iT+
33 | ggfN1R5CG0HsPFveWwnNurYgdgGUFw51IQ2BWx6khKLANCN0VrYyElmKbP3Y85Vn
34 | ALV4g2x6KqYDUChzy9hdPxpks4v9KWdXFEJS2aJC58L68Nwt7GXbVxzYNH/HWkDK
35 | f8+MyQiZz/i/VquzBJzG5E1ZyecyLsmBdGpsYaGhH1ewEIvrOelvTgRsLra/1GF5
36 | nIMoTrejQPt0uVKAL+KGSuTQr1L3Gu/pf1mZx88EzNwzJbZygkb7PHVgpSPsessQ
37 | vjQmVuyzq84/mJ3rreLrrSiT6xf9rFWPVyexNKHLDK1hFUwKGy8dXH9/zZ2HYU4q
38 | Cn8T7UqvWNpCfS4jpjg+4NVxVUKJ5o3qSpENm4JCk2qhRToN/s3e0u6LO7MkO5K2
39 | MR7XOlBCNI3LSq47aFphr9gB8CCIY3n1v1esK5KNptTYyVw7JEdnXsUbn9mvZ+A9
40 | JLG1F9yCnrYcRUbjbTvT3v5lsGkf0GyQH6UOY/EzV+6+4k27e9pIng55U7xDBUWF
41 | 7gSarFhy6l86vp4SowYQy5tH9q1NaUZf0K3qr88xM1XDi7EToxDbL+6gS4sc8fr3
42 | EXEkH/4CzFRDXcmBiwWRq4myhKtDLgmonsDWovB4oVY2XqNPneONE7UobblT0Woi
43 | pZ5D1MThE0OQeFwV4CCcIxViJuEEutBR7khzBlTxLbPTgeLCSJ1xrSHBzvh66mmj
44 | qBBmc9VW36lRKeM+u6JXTvgIC312GwIts1ZtGE3na5FJr0Gufq9TovmEp8lrfIDi
45 | ZM4p8r6qiuVU7MpQjuL+430CIhvEay3dbNstz6BzUOiE+cR5cru/wnkydFVErPz/
46 | qLDwaaczn38w36+YxbMKpNkEML0mOSOsL8UHrgUwdUO5sglhvLoXonWuqrWMZgG4
47 | ilgtdeOWkUDCDYJ/SMDUWnSKaduZKtF9+REwFkNeTqUb+zxwQxPoqGB8GeqyfQ/9
48 | xZfvkFPujHQWaWa99qv87dxIXIb9V+J4nB/iiz9H3FVJfQLgoaI0VNgZVBHh74+b
49 | Ab/Vfj6cwlXnq0U80qdtUhsuHQ/1z6z0bgHq3P+Wesi+kTiAmcDPqqGFDlRgy2kd
50 | 3f4cjrptn5qiOsyypq/AWtBJ/spENED46XvnKL6vprOanbuZ2ZZJmO8T99Yw9yhz
51 | sLz+3D0DPoEXlRzWxokteaxCrDo8Zi7OYOZEYtmmiEbsfwoaN2yt+EqDBlMDHOgX
52 | iuKK4nteirmxWpuX7nBoWRDUlEf30sdVvAVTyFhK4WSZxjxCKLra5EF1Xshd/psO
53 | vIfGzjPHkCPpMYuWBRBOOpoAPA==
54 | -----END ENCRYPTED PRIVATE KEY-----
55 |
--------------------------------------------------------------------------------
/config/jwt/public.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxMO73KjldnfgHSHcyyr7
3 | ikgUkAML30nTuPiZB4zoCd9BorkK3t9JEh61HYpHHC9CpqMjjr3uwnWKeCl9bCmU
4 | 3biYkxoqwZh+MXQpmcQ2hJEa1bWlxmDcLQUvk7SPEs6hxbyG2aiLbLcOm9D5LwSm
5 | bIo5jRrdxBPBazt3rPJJTSBn4MqKnLhoMgvGYTqOfL3QN/3e5vDZN1qLEYO2hpRW
6 | 3vdCXEJxU8UxihftEcd0nyOHGxlKftKdFrrZSGEqYwBaEdvoMKDIX5TdtydGRHhH
7 | 26EJ3HvuF2jClmUGkaHQhrQ93qzBQ+RZzjsTXs+UYB1c77IdB2uRkIrNxxpwMHhh
8 | dIZFS1Ah+dLYI8PCmZHhYYYf7feiszWP06Qzx44ElMbCe/MTzbksSPWqljWXldSb
9 | QpuGOFCRv9SJvfVFKqRqR5MWdWrqcrfpIVsPtjp1Ln+U8d5HAexX84yD5P2XEnDa
10 | C/iA0/JHEyTFRZoJYx9LIOXHtWwSvXi2LUXvzUyUV5MRdaXxgMeqgnfJHzuzDTRg
11 | YtkQwK46Ku/vBtxG5raOPJZpmzU0yhxFSRgQCC3cb8ddWNuIQSURz7IR5at6WBLW
12 | 4EIRXlzyDKWl27l/rteRpnkQoNXpnW+i/zHf4DO5EtY6CxNDH+qLfjKe/Kz0nEFP
13 | pj3MxctGbWUxGVRMUTUTeDMCAwEAAQ==
14 | -----END PUBLIC KEY-----
15 |
--------------------------------------------------------------------------------
/config/packages/cache.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | cache:
3 | # Put the unique name of your app here: the prefix seed
4 | # is used to compute stable namespaces for cache keys.
5 | #prefix_seed: your_vendor_name/app_name
6 |
7 | # The app cache caches to the filesystem by default.
8 | # Other options include:
9 |
10 | # Redis
11 | #app: cache.adapter.redis
12 | #default_redis_provider: redis://localhost
13 |
14 | # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
15 | #app: cache.adapter.apcu
16 |
17 | # Namespaced pools use the above "app" backend by default
18 | pools:
19 |
20 | redis.cache:
21 | adapter: cache.adapter.redis
22 | provider: app.my_custom_redis_provider
23 |
--------------------------------------------------------------------------------
/config/packages/dev/routing.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | router:
3 | strict_requirements: true
4 |
--------------------------------------------------------------------------------
/config/packages/dev/web_profiler.yaml:
--------------------------------------------------------------------------------
1 | web_profiler:
2 | toolbar: true
3 | intercept_redirects: false
4 |
5 | framework:
6 | profiler: { only_exceptions: false }
7 |
--------------------------------------------------------------------------------
/config/packages/doctrine.yaml:
--------------------------------------------------------------------------------
1 | doctrine:
2 | dbal:
3 | url: '%env(resolve:DATABASE_URL)%'
4 |
5 | # IMPORTANT: You MUST configure your server version,
6 | # either here or in the DATABASE_URL env var (see .env file)
7 | #server_version: '5.7'
8 | orm:
9 | auto_generate_proxy_classes: true
10 | naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
11 | auto_mapping: true
12 | mappings:
13 | App:
14 | is_bundle: false
15 | type: annotation
16 | dir: '%kernel.project_dir%/src/Entity'
17 | prefix: 'App\Entity'
18 | alias: App
19 |
--------------------------------------------------------------------------------
/config/packages/doctrine_migrations.yaml:
--------------------------------------------------------------------------------
1 | doctrine_migrations:
2 | dir_name: '%kernel.project_dir%/src/Migrations'
3 | # namespace is arbitrary but should be different from App\Migrations
4 | # as migrations classes should NOT be autoloaded
5 | namespace: DoctrineMigrations
6 |
--------------------------------------------------------------------------------
/config/packages/fos_rest.yaml:
--------------------------------------------------------------------------------
1 | # Read the documentation: https://symfony.com/doc/master/bundles/FOSRestBundle/index.html
2 | fos_rest:
3 | param_fetcher_listener: true
4 | allowed_methods_listener: true
5 | view:
6 | view_response_listener: true
7 | format_listener:
8 | rules:
9 | - { path: ^/api, prefer_extension: true, fallback_format: json, priorities: [ json] }
10 |
11 | service:
12 | serializer: fos_rest.serializer.symfony
13 |
--------------------------------------------------------------------------------
/config/packages/framework.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | secret: '%env(APP_SECRET)%'
3 | #default_locale: en
4 | #http_method_override: true
5 |
6 | # Enables session support. Note that the session will ONLY be started if you read or write from it.
7 | # Remove or comment this section to explicitly disable session support.
8 | session:
9 | handler_id: ~
10 |
11 | #esi: true
12 | #fragments: true
13 | php_errors:
14 | log: true
15 |
--------------------------------------------------------------------------------
/config/packages/lexik_jwt_authentication.yaml:
--------------------------------------------------------------------------------
1 | lexik_jwt_authentication:
2 | secret_key: '%env(resolve:JWT_SECRET_KEY)%'
3 | public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
4 | pass_phrase: '%env(JWT_PASSPHRASE)%'
5 | user_identity_field: email
6 |
--------------------------------------------------------------------------------
/config/packages/nelmio_api_doc.yaml:
--------------------------------------------------------------------------------
1 | nelmio_api_doc:
2 | models: { use_jms: false }
3 |
4 | media_types:
5 | # Default:
6 | - json
7 | - xml
8 | documentation:
9 | info:
10 | title: Meetings API
11 | description: A RestAPI for Manage Meetings
12 | version: 1.0.0
13 |
14 | components:
15 | securitySchemes:
16 | Bearer:
17 | type: http
18 | scheme: bearer
19 | bearerFormat: JWT
20 |
21 | security:
22 | - Bearer: []
23 | paths:
24 | /api/login_check:
25 | post:
26 | tags:
27 | - Authentication
28 | summary: Login into the api.
29 | requestBody:
30 | content:
31 | application/json:
32 | schema:
33 | properties:
34 | username:
35 | type: string
36 | password:
37 | type: string
38 | type: object
39 | responses:
40 | '200':
41 | description: OK
42 | content:
43 | application/json:
44 | schema:
45 | type: object
46 | properties:
47 | token:
48 | type: string
49 | refresh_token:
50 | type: string
51 | '401':
52 | description: Invalid credentials
53 | '400':
54 | description: Invalid JSON.
55 | security: []
56 | /api/token/refresh:
57 | post:
58 | tags:
59 | - Authentication
60 | summary: Login into the api by refresh token.
61 | requestBody:
62 | content:
63 | application/json:
64 | schema:
65 | properties:
66 | refresh_token:
67 | type: string
68 | type: object
69 | responses:
70 | '200':
71 | description: OK
72 | content:
73 | application/json:
74 | schema:
75 | type: object
76 | properties:
77 | token:
78 | type: string
79 | refresh_token:
80 | type: string
81 | '401':
82 | description: An authentication exception occurred.
83 | security: []
84 |
85 | areas: # to filter documented areas
86 | path_patterns:
87 | - ^/api(?!(/doc|/doc.json|/token/refresh)$)
88 |
89 |
90 |
--------------------------------------------------------------------------------
/config/packages/prod/doctrine.yaml:
--------------------------------------------------------------------------------
1 | doctrine:
2 | orm:
3 | auto_generate_proxy_classes: false
4 | metadata_cache_driver:
5 | type: pool
6 | pool: doctrine.system_cache_pool
7 | query_cache_driver:
8 | type: pool
9 | pool: doctrine.system_cache_pool
10 | result_cache_driver:
11 | type: pool
12 | pool: doctrine.result_cache_pool
13 |
14 | framework:
15 | cache:
16 | pools:
17 | doctrine.result_cache_pool:
18 | adapter: cache.app
19 | doctrine.system_cache_pool:
20 | adapter: cache.system
21 |
--------------------------------------------------------------------------------
/config/packages/prod/routing.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | router:
3 | strict_requirements: null
4 |
--------------------------------------------------------------------------------
/config/packages/routing.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | router:
3 | strict_requirements: ~
4 |
--------------------------------------------------------------------------------
/config/packages/security.yaml:
--------------------------------------------------------------------------------
1 | security:
2 | encoders:
3 | App\Entity\User:
4 | algorithm: auto
5 |
6 | # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
7 | providers:
8 | # used to reload user from session & other features (e.g. switch_user)
9 | app_user_provider:
10 | entity:
11 | class: App\Entity\User
12 | property: email
13 |
14 | firewalls:
15 |
16 | apidoc:
17 | pattern: ^/api/doc
18 | anonymous: true
19 |
20 |
21 | login:
22 | pattern: ^/api/login
23 | stateless: true
24 | anonymous: true
25 | json_login:
26 | check_path: /api/login_check
27 | success_handler: lexik_jwt_authentication.handler.authentication_success
28 | failure_handler: lexik_jwt_authentication.handler.authentication_failure
29 | refresh:
30 | pattern: ^/api/token/refresh
31 | stateless: true
32 | anonymous: true
33 |
34 | api:
35 | pattern: ^/api
36 | stateless: true
37 | guard:
38 | authenticators:
39 | - lexik_jwt_authentication.jwt_token_authenticator
40 |
41 | access_control:
42 | - { path: ^/api/doc, roles: IS_AUTHENTICATED_ANONYMOUSLY }
43 | - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
44 | - { path: ^/api/token/refresh, roles: IS_AUTHENTICATED_ANONYMOUSLY }
45 | - { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
46 |
--------------------------------------------------------------------------------
/config/packages/test/framework.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | test: true
3 | session:
4 | storage_id: session.storage.mock_file
5 |
--------------------------------------------------------------------------------
/config/packages/test/routing.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | router:
3 | strict_requirements: true
4 |
--------------------------------------------------------------------------------
/config/packages/test/twig.yaml:
--------------------------------------------------------------------------------
1 | twig:
2 | strict_variables: true
3 |
--------------------------------------------------------------------------------
/config/packages/test/validator.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | validation:
3 | not_compromised_password: false
4 |
--------------------------------------------------------------------------------
/config/packages/test/web_profiler.yaml:
--------------------------------------------------------------------------------
1 | web_profiler:
2 | toolbar: false
3 | intercept_redirects: false
4 |
5 | framework:
6 | profiler: { collect: false }
7 |
--------------------------------------------------------------------------------
/config/packages/twig.yaml:
--------------------------------------------------------------------------------
1 | twig:
2 | default_path: '%kernel.project_dir%/templates'
3 |
--------------------------------------------------------------------------------
/config/packages/validator.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | validation:
3 | email_validation_mode: html5
4 |
5 | # Enables validator auto-mapping support.
6 | # For instance, basic validation constraints will be inferred from Doctrine's metadata.
7 | #auto_mapping:
8 | # App\Entity\: []
9 |
--------------------------------------------------------------------------------
/config/preload.php:
--------------------------------------------------------------------------------
1 | get() won't work.
13 | # The best practice is to be explicit about your dependencies anyway.
14 |
15 | # makes classes in src/ available to be used as services
16 | # this creates a service per class whose id is the fully-qualified class name
17 | App\:
18 | resource: '../src/*'
19 | exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'
20 |
21 | # controllers are imported separately to make sure services can be injected
22 | # as action arguments even if you don't extend any base controller class
23 | App\Controller\:
24 | resource: '../src/Controller'
25 | tags: ['controller.service_arguments']
26 |
27 | # add more service definitions when explicit configuration is needed
28 | # please note that last definitions always *replace* previous ones
29 | sensio_framework_extra.view.listener:
30 | alias: Sensio\Bundle\FrameworkExtraBundle\EventListener\TemplateListener
31 |
32 |
33 | App\MessageHandler\:
34 | resource: '../src/MessageHandler'
35 | tags: ['messenger.message_handler']
36 |
37 | app.my_custom_redis_provider:
38 | class: \Redis
39 | factory: ['Symfony\Component\Cache\Adapter\RedisAdapter', 'createConnection']
40 | arguments:
41 | - 'redis://localhost'
42 | - { retry_interval: 2, timeout: 10 }
43 |
44 | gesdinet.jwtrefreshtoken.refresh_token_manager:
45 | class: App\Doctrine\RefreshTokenManager
46 | public: true
47 | arguments: [ '@doctrine.orm.default_entity_manager', 'Gesdinet\JWTRefreshTokenBundle\Entity\RefreshToken']
48 |
49 |
--------------------------------------------------------------------------------
/config/services_test.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | _defaults:
3 | public: true
4 |
5 | # If you need to access services in a test, create an alias
6 | # and then fetch that alias from the container. As a convention,
7 | # aliases are prefixed with test. For example:
8 | #
9 | # test.App\Service\MyService: '@App\Service\MyService'
10 |
--------------------------------------------------------------------------------
/depfile.yml:
--------------------------------------------------------------------------------
1 | # depfile.yml
2 | paths:
3 | - ./src
4 | exclude_files:
5 | - .*test.*
6 | layers:
7 | - name: Controller
8 | collectors:
9 | - type: className
10 | regex: .*Controller.*
11 | - name: Repository
12 | collectors:
13 | - type: className
14 | regex: .*Repository.*
15 | - name: Service
16 | collectors:
17 | - type: className
18 | regex: .*Service.*
19 | ruleset:
20 | Controller:
21 | - Service
22 | Service:
23 | - Repository
24 | Repository: ~
--------------------------------------------------------------------------------
/migrations/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shambhu384/symfony5-jwt-restapi/0264a7be4cad4516d89235a6b3ad692e1e6bdf79/migrations/.gitignore
--------------------------------------------------------------------------------
/psalm.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 | load(__DIR__.'/../.env');
16 | }
17 |
18 | $env = $_SERVER['APP_ENV'] ?? 'dev';
19 | $debug = (bool) ($_SERVER['APP_DEBUG'] ?? ('prod' !== $env));
20 |
21 | if ($debug) {
22 | umask(0000);
23 |
24 | Debug::enable();
25 | }
26 |
27 | if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? false) {
28 | Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
29 | }
30 |
31 | if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? false) {
32 | Request::setTrustedHosts(explode(',', $trustedHosts));
33 | }
34 |
35 | $kernel = new Kernel($env, $debug);
36 | $request = Request::createFromGlobals();
37 | $response = $kernel->handle($request);
38 | $response->send();
39 | $kernel->terminate($request, $response);
40 |
--------------------------------------------------------------------------------
/sample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shambhu384/symfony5-jwt-restapi/0264a7be4cad4516d89235a6b3ad692e1e6bdf79/sample.png
--------------------------------------------------------------------------------
/src/Command/MeetingCommand.php:
--------------------------------------------------------------------------------
1 | setDescription('Add a short description for your command')
20 | ->addArgument('arg1', InputArgument::OPTIONAL, 'Argument description')
21 | ->addOption('option1', null, InputOption::VALUE_NONE, 'Option description')
22 | ;
23 | }
24 |
25 | protected function execute(InputInterface $input, OutputInterface $output)
26 | {
27 | $io = new SymfonyStyle($input, $output);
28 | $arg1 = $input->getArgument('arg1');
29 |
30 | if ($arg1) {
31 | $io->note(sprintf('You passed an argument: %s', $arg1));
32 | }
33 |
34 | if ($input->getOption('option1')) {
35 | // ...
36 | }
37 |
38 | $io->success('You have a new command! Now make it your own! Pass --help to see your options.');
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Controller/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shambhu384/symfony5-jwt-restapi/0264a7be4cad4516d89235a6b3ad692e1e6bdf79/src/Controller/.gitignore
--------------------------------------------------------------------------------
/src/Controller/MeetingController.php:
--------------------------------------------------------------------------------
1 | deserialize($request->getContent(), Meeting::class, 'json');
79 | } catch (NotEncodableValueException $exception) {
80 | throw new HttpException(Response::HTTP_BAD_REQUEST, 'Invalid Json');
81 | }
82 |
83 | $errors = $validator->validate($meeting);
84 |
85 | if (count($errors) > 0) {
86 | /*
87 | * Uses a __toString method on the $errors variable which is a
88 | * ConstraintViolationList object. This gives us a nice string
89 | * for debugging.
90 | */
91 | $json = $serializer->serialize($errors, 'json', array_merge([
92 | 'json_encode_options' => JsonResponse::DEFAULT_ENCODING_OPTIONS,
93 | ], []));
94 |
95 | return new JsonResponse($json, Response::HTTP_BAD_REQUEST, [], true);
96 | }
97 |
98 | $meeting->setOrganiser($this->getUser()->getId());
99 |
100 | $em->persist($meeting);
101 | $em->flush();
102 |
103 | $dispatcher->dispatch(new MeetingRegisteredEvent($meeting));
104 | return new Response(null, Response::HTTP_CREATED);
105 | }
106 |
107 | /**
108 | * Lists all Meetings.
109 | * @Route("/meetings", name="get_all", methods={"GET"})
110 | *
111 | * @OA\Response(
112 | * response=200,
113 | * description="Returns the meetings of an user",
114 | * @OA\JsonContent(
115 | * type="array",
116 | * @OA\Items(ref=@Model(type=Meeting::class, groups={"full"}))
117 | * )
118 | * )
119 | * @OA\Parameter(
120 | * name="order",
121 | * in="query",
122 | * description="The field used to order meetings",
123 | * @OA\Schema(type="string")
124 | * )
125 | * @OA\Tag(name="Meetings")
126 | * @Security(name="Bearer")
127 |
128 | */
129 | public function getMeetings(CacheInterface $redisCache, MeetingRepository $meetingRepository, SerializerInterface $serializer) {
130 | // add pagination on data using ParamFetcherInterface
131 |
132 | $meetings = $redisCache->get('meetings', function (ItemInterface $item) use ($meetingRepository) {
133 | return $meetingRepository->findAll();
134 | });
135 |
136 | $context = new Context();
137 | $context->setVersion('1.0');
138 | $context->addGroup('user');
139 |
140 | $view = $this->view($meetings, 200);
141 | $view->setContext($context);
142 |
143 |
144 | return $this->handleView($view);
145 | }
146 |
147 | /**
148 | * Get Meeting.
149 | *
150 | * @OA\Response(
151 | * response=200,
152 | * description="Returns the meetings of an user",
153 | * @OA\JsonContent(
154 | * type="array",
155 | * @OA\Items(ref=@Model(type=Meeting::class, groups={"full"}))
156 | * )
157 | * )
158 | * @OA\Parameter(
159 | * name="order",
160 | * in="query",
161 | * description="The field used to order meetings",
162 | * @OA\Schema(type="string")
163 | * )
164 | * @OA\Tag(name="Meetings")
165 | * @Security(name="Bearer")
166 | * @Route("/meetings/{id<\d+>?1}", name="meeting_index", methods={"GET"})
167 | */
168 | public function getMeeting($id, MeetingRepository $meetingRepository): Response
169 | {
170 | // query for a single Product by its primary key (usually "id")
171 | $meeting = $meetingRepository->find($id);
172 | if (!$meeting) {
173 | throw new HttpException(404, 'Meeting not found');
174 | }
175 |
176 | $context = new Context();
177 | $context->setVersion('1.0');
178 | $context->addGroup('user');
179 |
180 | $view = $this->view($meeting, 200);
181 | $view->setContext($context);
182 |
183 | // Move this in Meeting normalizer
184 | return $this->handleView($view);
185 | }
186 |
187 | /**
188 | * Update an Meeting.
189 | *
190 | * @OA\Response(
191 | * response=200,
192 | * description="Returns the meetings of an user",
193 | * @OA\JsonContent(
194 | * type="array",
195 | * @OA\Items(ref=@Model(type=Meeting::class, groups={"full"}))
196 | * )
197 | * )
198 | * @OA\Parameter(
199 | * name="order",
200 | * in="query",
201 | * description="The field used to order meetings",
202 | * @OA\Schema(type="string")
203 | * )
204 | * @OA\Tag(name="Meetings")
205 | * @Security(name="Bearer")
206 | *
207 | * @Route("/meetings/{id<\d+>?1}", name="meeting_put", methods={"PUT"})
208 | * @return View
209 | */
210 | public function putMeeting($id, Request $request, MeetingRepository $meetingRepository, EntityManagerInterface $em): View
211 | {
212 | $meeting = $meetingRepository->find($id);
213 | if (!$meeting) {
214 | throw new HttpException(404, 'Meeting not found');
215 | }
216 | $postdata = json_decode($request->getContent());
217 | $meeting->setDescription($postdata->description);
218 | $meeting->setDateTime(new \DateTime($postdata->datetime));
219 | $em->persist($meeting);
220 | $em->flush();
221 | return View::create($meeting, Response::HTTP_OK, []);
222 | }
223 |
224 | /**
225 | * Delete an Meeting.
226 | *
227 | * @OA\Parameter(
228 | * name="order",
229 | * in="query",
230 | * description="The field used to order meetings",
231 | * @OA\Schema(type="string")
232 | * )
233 | * @OA\Tag(name="Meetings")
234 | * @Security(name="Bearer")
235 | *
236 | * @Route("/meetings/{id<\d+>?1}", name="meeting_delete", methods={"DELETE"})
237 | * @return View
238 | */
239 | public function deleteMeeting($id, Request $request, MeetingRepository $meetingRepository, EntityManagerInterface $em): View
240 | {
241 | $meeting = $meetingRepository->find($id);
242 | if (!$meeting) {
243 | throw new HttpException(404, 'Meeting not found');
244 | }
245 | $em->remove($meeting);
246 | $em->flush();
247 | return View::create(null, Response::HTTP_NO_CONTENT);
248 | }
249 | }
250 |
--------------------------------------------------------------------------------
/src/Controller/MeetingRegistrationController.php:
--------------------------------------------------------------------------------
1 | findBy(array('id' => $request->get('user_id')));
38 | if (!$user) {
39 | throw new HttpException(400, 'Userid invalid.');
40 | }
41 |
42 | $meeting = $meetingRepository->find(array('id' => $request->get('meeting_id')));
43 | if (!$meeting) {
44 | throw new HttpException(400, 'Meetingid invalid.');
45 | }
46 |
47 | $user->setMeeting($meeting);
48 | $meeting->setUser($user);
49 |
50 | $em->persist($user);
51 | $em->persist($meeting);
52 | $em->flush();
53 | return new Response('', Response::HTTP_NO_CONTENT, []);
54 | }
55 |
56 | /**
57 | * Unregister
58 | *
59 | * @Route("/meetings/{id}/unregister/{user}", name="meeting_user_unregister", methods={"POST"})
60 | * @OA\Tag(name="Meetings")
61 | */
62 | public function unregisterUserMeeting(
63 | EntityManagerInterface $em,
64 | MeetingRepository $meetingRepository,
65 | Request $request,
66 | UserRepository $userRepository
67 | ): Response
68 | {
69 | // Check user already exists
70 | $user = $userRepository->findBy(array('id' => $request->get('user_id')));
71 | if (!$user) {
72 | throw new HttpException(400, 'Userid invalid.');
73 | }
74 |
75 | $meeting = $meetingRepository->find(array('id' => $request->get('meeting_id')));
76 | if (!$meeting) {
77 | throw new HttpException(400, 'Meetingid invalid.');
78 | }
79 |
80 | $user->removeMeeting($meeting);
81 | //$meeting->removeUser($user);
82 | $em->remove($meeting);
83 | //$em->remove($user);
84 | $em->flush();
85 | return new Response('', Response::HTTP_NO_CONTENT, []);
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/Controller/MeetingTagController.php:
--------------------------------------------------------------------------------
1 | 1], Response::HTTP_CREATED, []);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Controller/UserController.php:
--------------------------------------------------------------------------------
1 | deserialize($request->getContent(), User::class, 'json');
65 | } catch (NotEncodableValueException $exception) {
66 | throw new HttpException(Response::HTTP_BAD_REQUEST, 'Invalid Json');
67 | }
68 |
69 | $errors = $validator->validate($user);
70 |
71 | if (count($errors) > 0) {
72 | /*
73 | * Uses a __toString method on the $errors variable which is a
74 | * ConstraintViolationList object. This gives us a nice string
75 | * for debugging.
76 | */
77 | $json = $serializer->serialize($errors, 'json', array_merge([
78 | 'json_encode_options' => JsonResponse::DEFAULT_ENCODING_OPTIONS,
79 | ], []));
80 |
81 | return new JsonResponse($json, Response::HTTP_BAD_REQUEST, [], true);
82 | }
83 |
84 | $em->persist($user);
85 | $em->flush();
86 |
87 | return new Response(null, Response::HTTP_CREATED);
88 | }
89 |
90 | /**
91 | */
92 | public function getUsers(AdapterInterface $cache, EntityManagerInterface $em, UserRepository $userRepository): Response
93 | {
94 | // add pagination on data using ParamFetcherInterface
95 | $limit = $paramFetcher->get('limit');
96 | $page = $limit * ($paramFetcher->get('page') - 1);
97 | $users = $userRepository->findAll(array(), array('id' => $paramFetcher->get('sort')), $limit, $page);
98 | // Move this in User normalizer
99 | $response = array();
100 | if (count($users) > 0) {
101 | foreach ($users as $user) {
102 | // find users
103 | $response[] = array(
104 | 'id' => $user->getId(),
105 | 'name' => $user->getFullName(),
106 | 'email' => $user->getEmail()
107 | );
108 | }
109 | }
110 |
111 | return new Response(array(
112 | "metadata" => array("limit" => (int)$limit, "start"=> $page),
113 | 'collections' => $response
114 | ), Response::HTTP_OK, []);
115 | }
116 |
117 | /**
118 | * Get User
119 | *
120 | * @Route("/users/{id}", name="users_get", methods={"GET"})
121 | * @OA\Tag(name="Users")
122 | * @return Response
123 | */
124 | public function getApiUser($id, UserRepository $userRepository): View
125 | {
126 | // query for a single Product by its primary key (usually "id")
127 | $user = $userRepository->find($id);
128 | if (!$user) {
129 | throw new HttpException(404, 'User not found');
130 | }
131 |
132 | $context = new Context();
133 | $context->setVersion('1.0');
134 | $context->addGroup('user');
135 |
136 | $view = $this->view($user, 200);
137 | $view->setContext($context);
138 |
139 | return $this->handleView($view);
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/src/Controller/UserDeviceController.php:
--------------------------------------------------------------------------------
1 | 1], Response::HTTP_CREATED, []);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/DataFixtures/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shambhu384/symfony5-jwt-restapi/0264a7be4cad4516d89235a6b3ad692e1e6bdf79/src/DataFixtures/.gitignore
--------------------------------------------------------------------------------
/src/DataFixtures/UserFixtures.php:
--------------------------------------------------------------------------------
1 | encoder = $encoder;
18 | }
19 |
20 | // ...
21 | public function load(ObjectManager $manager)
22 | {
23 | $user = new User();
24 | $user->setEmail('admin@lp.com');
25 |
26 | $password = $this->encoder->encodePassword($user, 'pass_1234');
27 | $user->setPassword($password);
28 |
29 | $manager->persist($user);
30 | $manager->flush();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Doctrine/RefreshTokenManager.php:
--------------------------------------------------------------------------------
1 | objectManager = $om;
12 | $this->repository = $om->getRepository($class);
13 | $metadata = $om->getClassMetadata($class);
14 | $this->class = $metadata->getName();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Entity/.UserDevice.php.swp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shambhu384/symfony5-jwt-restapi/0264a7be4cad4516d89235a6b3ad692e1e6bdf79/src/Entity/.UserDevice.php.swp
--------------------------------------------------------------------------------
/src/Entity/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shambhu384/symfony5-jwt-restapi/0264a7be4cad4516d89235a6b3ad692e1e6bdf79/src/Entity/.gitignore
--------------------------------------------------------------------------------
/src/Entity/Meeting.php:
--------------------------------------------------------------------------------
1 | users = new ArrayCollection();
98 | $this->tags = new ArrayCollection();
99 | }
100 |
101 |
102 | /**
103 | * Get id.
104 | *
105 | * @return int
106 | */
107 | public function getId(): int
108 | {
109 | return $this->id;
110 | }
111 |
112 | /**
113 | * Set id.
114 | *
115 | * @param int $id
116 | *
117 | * @return self
118 | */
119 | public function setId(int $id)
120 | {
121 | $this->id = $id;
122 |
123 | }
124 |
125 | /**
126 | * Get name.
127 | *
128 | * @return string
129 | */
130 | public function getName(): ?string
131 | {
132 | return $this->name;
133 | }
134 |
135 | /**
136 | * Set name.
137 | *
138 | * @param string $name
139 | */
140 | public function setName($name)
141 | {
142 | $this->name = $name;
143 | }
144 |
145 | /**
146 | * Get description.
147 | *
148 | * @return string
149 | */
150 | public function getDescription(): ?string
151 | {
152 | return $this->description;
153 | }
154 |
155 | /**
156 | * Set description.
157 | *
158 | * @param string $description
159 | */
160 | public function setDescription($description)
161 | {
162 | $this->description = $description;
163 | }
164 |
165 | /**
166 | * @param User $user
167 | */
168 | public function setUser(User $user)
169 | {
170 | if ($this->users->contains($user)) {
171 | return;
172 | }
173 | $this->users->add($user);
174 | $user->setMeeting($this);
175 | }
176 |
177 | /**
178 | * @param User $user
179 | */
180 | public function removeUser(User $user)
181 | {
182 | if (!$this->users->contains($user)) {
183 | return;
184 | }
185 | $this->users->removeElement($user);
186 | $user->removeMeeting($this);
187 | }
188 |
189 | /**
190 | * @param Tag $tag
191 | */
192 | public function setTag(Tag $tag)
193 | {
194 | if ($this->tags->contains($tag)) {
195 | return;
196 | }
197 | $this->tags->add($tag);
198 | }
199 |
200 | /**
201 | * @param Tag $tag
202 | */
203 | public function removeTag(Tag $tag)
204 | {
205 | if (!$this->tags->contains($tag)) {
206 | return;
207 | }
208 | $this->tags->removeElement($tag);
209 | $tag->removeMeeting($this);
210 | }
211 |
212 | /**
213 | * Get users.
214 | *
215 | * @return Collection
216 | */
217 | public function getUsers(): Collection
218 | {
219 | return $this->users;
220 | }
221 |
222 | /**
223 | * @return Collection
224 | */
225 | public function getTags(): Collection
226 | {
227 | return $this->tags;
228 | }
229 |
230 | public function addTag(Tag $tag): self
231 | {
232 | if (!$this->tags->contains($tag)) {
233 | $this->tags[] = $tag;
234 | $tag->addMeeting($this);
235 | }
236 |
237 | return $this;
238 | }
239 |
240 | public function getOrganiser(): ?int
241 | {
242 | return $this->organiser;
243 | }
244 |
245 | public function setOrganiser(int $organiser): self
246 | {
247 | $this->organiser = $organiser;
248 |
249 | return $this;
250 | }
251 |
252 | /**
253 | * Pre persist event listener
254 | *
255 | * @ORM\PrePersist
256 | *
257 | * @return void
258 | */
259 | public function beforeSave()
260 | {
261 | $this->createdAt = new DateTime('now', new \DateTimeZone('UTC'));
262 | $this->updatedAt = new DateTime('now', new \DateTimeZone('UTC'));
263 | }
264 |
265 | /**
266 | * Pre update event handler
267 | *
268 | * @ORM\PreUpdate
269 | *
270 | * @return void
271 | */
272 | public function doPreUpdate()
273 | {
274 | $this->updatedAt = new DateTime('now', new \DateTimeZone('UTC'));
275 | }
276 |
277 | /**
278 | * Get created date/time
279 | *
280 | * @return \DateTime
281 | */
282 | public function getCreatedAt()
283 | {
284 | return $this->createdAt;
285 | }
286 | /**
287 | * Set created at
288 | *
289 | * @param DateTime $created timestamp
290 | *
291 | * @return self
292 | */
293 | public function setCreatedAt($created)
294 | {
295 | $this->createdAt = $created;
296 | return $this;
297 | }
298 | /**
299 | * Get last update date/time
300 | *
301 | * @return \DateTime
302 | */
303 | public function getUpdatedAt()
304 | {
305 | return $this->updatedAt;
306 | }
307 |
308 | /**
309 | * Set updated at
310 | *
311 | * @param DateTime $updated timestamp
312 | *
313 | * @return self
314 | */
315 | public function setUpdatedAt($updated)
316 | {
317 | $this->updatedAt = $updated;
318 | return $this;
319 | }
320 |
321 | /**
322 | * {@inherit}
323 | *
324 | * @return string
325 | */
326 | public function __toString(): string
327 | {
328 | return (string) $this->getName();
329 | }
330 |
331 | public function getMeetingAt(): ?\DateTimeInterface
332 | {
333 | return $this->meetingAt;
334 | }
335 |
336 | public function setMeetingAt(\DateTimeInterface $meetingAt): self
337 | {
338 | $this->meetingAt = $meetingAt;
339 |
340 | return $this;
341 | }
342 | }
343 |
--------------------------------------------------------------------------------
/src/Entity/Tag.php:
--------------------------------------------------------------------------------
1 | meetings = new ArrayCollection();
50 | }
51 |
52 | public function getId()
53 | {
54 | return $this->id;
55 | }
56 |
57 | public function getName(): ?string
58 | {
59 | return $this->name;
60 | }
61 |
62 | public function setName(string $name): self
63 | {
64 | $this->name = $name;
65 |
66 | return $this;
67 | }
68 |
69 | /**
70 | * @return Collection|Meeting[]
71 | */
72 | public function getMeetings(): Collection
73 | {
74 | return $this->meetings;
75 | }
76 |
77 | public function addMeeting(Meeting $meeting): self
78 | {
79 | if (!$this->meetings->contains($meeting)) {
80 | $this->meetings[] = $meeting;
81 | }
82 |
83 | return $this;
84 | }
85 |
86 | public function removeMeeting(Meeting $meeting): self
87 | {
88 | if ($this->meetings->contains($meeting)) {
89 | $this->meetings->removeElement($meeting);
90 | }
91 |
92 | return $this;
93 | }
94 |
95 | /**
96 | * Pre persist event listener
97 | *
98 | * @ORM\PrePersist
99 | */
100 | public function beforeSave()
101 | {
102 | $this->createdAt = new \DateTime('now', new \DateTimeZone('UTC'));
103 | $this->updatedAt = new \DateTime('now', new \DateTimeZone('UTC'));
104 | }
105 | /**
106 | * Pre update event handler
107 | *
108 | * @ORM\PreUpdate
109 | */
110 | public function doPreUpdate()
111 | {
112 | $this->updatedAt = new \DateTime('now', new \DateTimeZone('UTC'));
113 | }
114 |
115 | /**
116 | * Get created date/time
117 | *
118 | * @return \DateTime
119 | */
120 | public function getCreatedAt()
121 | {
122 | return $this->createdAt;
123 | }
124 | /**
125 | * @param \DateTime
126 | *
127 | * @return Account
128 | */
129 | public function setCreatedAt($created)
130 | {
131 | $this->createdAt = $created;
132 | return $this;
133 | }
134 | /**
135 | * Get last update date/time
136 | *
137 | * @return \DateTime
138 | */
139 | public function getUpdatedAt()
140 | {
141 | return $this->updatedAt;
142 | }
143 | /**
144 | * @param \DateTime
145 | *
146 | * @return Account
147 | */
148 | public function setUpdatedAt($updated)
149 | {
150 | $this->updatedAt = $updated;
151 | return $this;
152 | }
153 |
154 | public function __toString()
155 | {
156 | return (string) $this->getName();
157 | }
158 |
159 | }
160 |
--------------------------------------------------------------------------------
/src/Entity/User.php:
--------------------------------------------------------------------------------
1 | id;
43 | }
44 |
45 | public function getEmail(): ?string
46 | {
47 | return $this->email;
48 | }
49 |
50 | public function setEmail(string $email): self
51 | {
52 | $this->email = $email;
53 |
54 | return $this;
55 | }
56 |
57 | /**
58 | * A visual identifier that represents this user.
59 | *
60 | * @see UserInterface
61 | */
62 | public function getUsername(): string
63 | {
64 | return (string) $this->email;
65 | }
66 |
67 | /**
68 | * @see UserInterface
69 | */
70 | public function getRoles(): array
71 | {
72 | $roles = $this->roles;
73 | // guarantee every user at least has ROLE_USER
74 | $roles[] = 'ROLE_USER';
75 |
76 | return array_unique($roles);
77 | }
78 |
79 | public function setRoles(array $roles): self
80 | {
81 | $this->roles = $roles;
82 |
83 | return $this;
84 | }
85 |
86 | /**
87 | * @see UserInterface
88 | */
89 | public function getPassword(): string
90 | {
91 | return (string) $this->password;
92 | }
93 |
94 | public function setPassword(string $password): self
95 | {
96 | $this->password = $password;
97 |
98 | return $this;
99 | }
100 |
101 | /**
102 | * @see UserInterface
103 | */
104 | public function getSalt()
105 | {
106 | // not needed when using the "bcrypt" algorithm in security.yaml
107 | }
108 |
109 | /**
110 | * @see UserInterface
111 | */
112 | public function eraseCredentials()
113 | {
114 | // If you store any temporary, sensitive data on the user, clear it here
115 | // $this->plainPassword = null;
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/Entity/UserDevice.php:
--------------------------------------------------------------------------------
1 | id;
76 | }
77 |
78 | public function getAppid(): ?string
79 | {
80 | return $this->appid;
81 | }
82 |
83 | public function setAppid(string $appid): self
84 | {
85 | $this->appid = $appid;
86 |
87 | return $this;
88 | }
89 |
90 | public function getName(): ?string
91 | {
92 | return $this->name;
93 | }
94 |
95 | public function setName(string $name): self
96 | {
97 | $this->name = $name;
98 |
99 | return $this;
100 | }
101 |
102 | public function getModel(): ?string
103 | {
104 | return $this->model;
105 | }
106 |
107 | public function setModel(?string $model): self
108 | {
109 | $this->model = $model;
110 |
111 | return $this;
112 | }
113 |
114 | public function getPlatform(): ?string
115 | {
116 | return $this->platform;
117 | }
118 |
119 | public function setPlatform(?string $platform): self
120 | {
121 | $this->platform = $platform;
122 |
123 | return $this;
124 | }
125 |
126 | public function getVersion(): ?string
127 | {
128 | return $this->version;
129 | }
130 |
131 | public function setVersion(?string $version): self
132 | {
133 | $this->version = $version;
134 |
135 | return $this;
136 | }
137 |
138 | public function getPushid(): ?string
139 | {
140 | return $this->pushid;
141 | }
142 |
143 | public function setPushid(?string $pushid): self
144 | {
145 | $this->pushid = $pushid;
146 |
147 | return $this;
148 | }
149 |
150 | public function getUuid(): ?string
151 | {
152 | return $this->uuid;
153 | }
154 |
155 | public function setUuid(?string $uuid): self
156 | {
157 | $this->uuid = $uuid;
158 |
159 | return $this;
160 | }
161 |
162 | public function getUserid(): ?User
163 | {
164 | return $this->userid;
165 | }
166 |
167 | public function setUserid(?User $userid): self
168 | {
169 | $this->userid = $userid;
170 |
171 | return $this;
172 | }
173 |
174 | /**
175 | * Pre persist event listener
176 | *
177 | * @ORM\PrePersist
178 | */
179 | public function beforeSave()
180 | {
181 | $this->createdAt = new \DateTime('now', new \DateTimeZone('UTC'));
182 | $this->updatedAt = new \DateTime('now', new \DateTimeZone('UTC'));
183 | }
184 | /**
185 | * Pre update event handler
186 | *
187 | * @ORM\PreUpdate
188 | */
189 | public function doPreUpdate()
190 | {
191 | $this->updatedAt = new \DateTime('now', new \DateTimeZone('UTC'));
192 | }
193 |
194 | /**
195 | * Get created date/time
196 | *
197 | * @return \DateTime
198 | */
199 | public function getCreatedAt()
200 | {
201 | return $this->createdAt;
202 | }
203 | /**
204 | * @param \DateTime
205 | *
206 | * @return Account
207 | */
208 | public function setCreatedAt($created)
209 | {
210 | $this->createdAt = $created;
211 | return $this;
212 | }
213 | /**
214 | * Get last update date/time
215 | *
216 | * @return \DateTime
217 | */
218 | public function getUpdatedAt()
219 | {
220 | return $this->updatedAt;
221 | }
222 | /**
223 | * @param \DateTime
224 | *
225 | * @return Account
226 | */
227 | public function setUpdatedAt($updated)
228 | {
229 | $this->updatedAt = $updated;
230 | return $this;
231 | }
232 |
233 | public function __toString()
234 | {
235 | return (string) $this->getName();
236 | }
237 |
238 | }
239 |
--------------------------------------------------------------------------------
/src/Event/MeetingModifiedEvent.php:
--------------------------------------------------------------------------------
1 | meeting = $meeting;
18 | }
19 |
20 | /**
21 | * Get meeting.
22 | *
23 | * @return Meeting
24 | */
25 | public function getMeeting(): Meeting
26 | {
27 | return $this->meeting;
28 | }
29 |
30 | /**
31 | * Set meeting.
32 | *
33 | * @param Meeting $meeting
34 | */
35 | public function setMeeting(Meeting $meeting)
36 | {
37 | $this->meeting = $meeting;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Event/MeetingRegisteredEvent.php:
--------------------------------------------------------------------------------
1 | meeting = $meeting;
18 | }
19 |
20 | /**
21 | * Get meeting.
22 | *
23 | * @return Meeting
24 | */
25 | public function getMeeting(): Meeting
26 | {
27 | return $this->meeting;
28 | }
29 |
30 | /**
31 | * Set meeting.
32 | *
33 | * @param Meeting $meeting
34 | */
35 | public function setMeeting(Meeting $meeting)
36 | {
37 | $this->meeting = $meeting;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Event/MeetingUnRegisteredEvent.php:
--------------------------------------------------------------------------------
1 | meeting = $meeting;
17 | }
18 |
19 | /**
20 | * Get meeting.
21 | *
22 | * @return Meeting
23 | */
24 | public function getMeeting(): Meeting
25 | {
26 | return $this->meeting;
27 | }
28 |
29 | /**
30 | * Set meeting.
31 | *
32 | * @param Meeting $meeting
33 | */
34 | public function setMeeting(Meeting $meeting)
35 | {
36 | $this->meeting = $meeting;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Event/MeetingUserRegisteredEvent.php:
--------------------------------------------------------------------------------
1 | meeting = $meeting;
18 | }
19 |
20 | /**
21 | * Get meeting.
22 | *
23 | * @return Meeting
24 | */
25 | public function getMeeting(): Meeting
26 | {
27 | return $this->meeting;
28 | }
29 |
30 | /**
31 | * Set meeting.
32 | *
33 | * @param Meeting $meeting
34 | */
35 | public function setMeeting(Meeting $meeting)
36 | {
37 | $this->meeting = $meeting;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Event/MeetingUserUnRegisteredEvent.php:
--------------------------------------------------------------------------------
1 | meeting = $meeting;
17 | }
18 |
19 | /**
20 | * Get meeting.
21 | *
22 | * @return Meeting
23 | */
24 | public function getMeeting(): Meeting
25 | {
26 | return $this->meeting;
27 | }
28 |
29 | /**
30 | * Set meeting.
31 | *
32 | * @param Meeting $meeting
33 | */
34 | public function setMeeting(Meeting $meeting)
35 | {
36 | $this->meeting = $meeting;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Event/UserDeviceRegisteredEvent.php:
--------------------------------------------------------------------------------
1 | meeting = $meeting;
18 | }
19 |
20 | /**
21 | * Get meeting.
22 | *
23 | * @return Meeting
24 | */
25 | public function getMeeting()
26 | {
27 | return $this->meeting;
28 | }
29 |
30 | /**
31 | * Set meeting.
32 | *
33 | * @param Meeting $meeting
34 | */
35 | public function setMeeting(Meeting $meeting)
36 | {
37 | $this->meeting = $meeting;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Event/UserDeviceRemovedEvent.php:
--------------------------------------------------------------------------------
1 | meeting = $meeting;
18 | }
19 |
20 | /**
21 | * Get meeting.
22 | *
23 | * @return meeting.
24 | */
25 | public function getMeeting()
26 | {
27 | return $this->meeting;
28 | }
29 |
30 | /**
31 | * Set meeting.
32 | *
33 | * @param Meeting $meeting
34 | */
35 | public function setMeeting(Meeting $meeting)
36 | {
37 | $this->meeting = $meeting;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/EventListener/MeetingRegisteredListener.php:
--------------------------------------------------------------------------------
1 | setLogger($logger);
20 | }
21 |
22 | public static function getSubscribedEvents()
23 | {
24 | // return the subscribed events, their methods and priorities
25 | return array(
26 | 'meeting.registered' => array(
27 | array('processMeeting', 10),
28 | array('logMeeting', 0),
29 | array('notifyMeeting', -10),
30 | )
31 | );
32 | }
33 |
34 | public function processMeeting(MeetingRegisteredEvent $event)
35 | {
36 | $this->logger->info(sprintf('Metting initilise : %s', $event->getMeeting()->getName()));
37 | }
38 |
39 | public function logMeeting(MeetingRegisteredEvent $event)
40 | {
41 | $this->logger->info(sprintf('Meeting created: %s', $event->getMeeting()->getName()));
42 | }
43 |
44 | public function notifyMeeting(MeetingRegisteredEvent $event)
45 | {
46 | $this->logger->info(sprintf('Notify users about new : %s', $event->getMeeting()->getName()));
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Exception/MyException.php:
--------------------------------------------------------------------------------
1 | add('name')
18 | ->add('description')
19 | ->add('datetime')
20 | ->add('organiser', UserType::class)
21 | ->add('tags');
22 | }
23 |
24 | public function configureOptions(OptionsResolver $resolver)
25 | {
26 | $resolver->setDefaults([
27 | 'data_class' => Meeting::class,
28 | 'csrf_protection' => false,
29 | ]);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Form/UserType.php:
--------------------------------------------------------------------------------
1 | add('username')
16 | ->add('email')
17 | ;
18 | }
19 |
20 | public function configureOptions(OptionsResolver $resolver)
21 | {
22 | $resolver->setDefaults([
23 | 'data_class' => User::class,
24 | ]);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Kernel.php:
--------------------------------------------------------------------------------
1 | getProjectDir().'/var/cache/'.$this->environment;
22 | }
23 |
24 | public function getLogDir()
25 | {
26 | return $this->getProjectDir().'/var/log';
27 | }
28 |
29 | public function registerBundles()
30 | {
31 | $contents = require $this->getProjectDir().'/config/bundles.php';
32 | foreach ($contents as $class => $envs) {
33 | if (isset($envs['all']) || isset($envs[$this->environment])) {
34 | yield new $class();
35 | }
36 | }
37 | }
38 |
39 | protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
40 | {
41 | $container->addResource(new FileResource($this->getProjectDir().'/config/bundles.php'));
42 | // Feel free to remove the "container.autowiring.strict_mode" parameter
43 | // if you are using symfony/dependency-injection 4.0+ as it's the default behavior
44 | $container->setParameter('container.autowiring.strict_mode', true);
45 | $container->setParameter('container.dumper.inline_class_loader', true);
46 | $confDir = $this->getProjectDir().'/config';
47 |
48 | $loader->load($confDir.'/{packages}/*'.self::CONFIG_EXTS, 'glob');
49 | $loader->load($confDir.'/{packages}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob');
50 | $loader->load($confDir.'/{services}'.self::CONFIG_EXTS, 'glob');
51 | $loader->load($confDir.'/{services}_'.$this->environment.self::CONFIG_EXTS, 'glob');
52 | }
53 |
54 | protected function configureRoutes(RouteCollectionBuilder $routes)
55 | {
56 | $confDir = $this->getProjectDir().'/config';
57 |
58 | $routes->import($confDir.'/{routes}/*'.self::CONFIG_EXTS, '/', 'glob');
59 | $routes->import($confDir.'/{routes}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, '/', 'glob');
60 | $routes->import($confDir.'/{routes}'.self::CONFIG_EXTS, '/', 'glob');
61 | }
62 |
63 | protected function build(ContainerBuilder $container): void
64 | {
65 | parent::build($container);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/MeetingEvents.php:
--------------------------------------------------------------------------------
1 | abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
24 |
25 | $this->addSql('CREATE TABLE user (id INT AUTO_INCREMENT NOT NULL, fullname VARCHAR(100) NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, email VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL, username VARCHAR(255) NOT NULL, roles LONGTEXT NOT NULL COMMENT \'(DC2Type:array)\', PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
26 | $this->addSql('CREATE TABLE user_meeting (user_id INT NOT NULL, meeting_id INT NOT NULL, INDEX IDX_AD18FF33A76ED395 (user_id), INDEX IDX_AD18FF3367433D9C (meeting_id), PRIMARY KEY(user_id, meeting_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
27 | $this->addSql('CREATE TABLE user_device (id INT AUTO_INCREMENT NOT NULL, userid_id INT NOT NULL, appid VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, model VARCHAR(255) DEFAULT NULL, platform VARCHAR(255) DEFAULT NULL, version VARCHAR(255) DEFAULT NULL, pushid VARCHAR(255) DEFAULT NULL, uuid VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, INDEX IDX_6C7DADB358E0A285 (userid_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
28 | $this->addSql('CREATE TABLE tag (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
29 | $this->addSql('CREATE TABLE tag_meeting (tag_id INT NOT NULL, meeting_id INT NOT NULL, INDEX IDX_C724CC93BAD26311 (tag_id), INDEX IDX_C724CC9367433D9C (meeting_id), PRIMARY KEY(tag_id, meeting_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
30 | $this->addSql('CREATE TABLE meeting (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(100) NOT NULL, description LONGTEXT NOT NULL, datetime DATETIME NOT NULL, organiser INT NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
31 | $this->addSql('ALTER TABLE user_meeting ADD CONSTRAINT FK_AD18FF33A76ED395 FOREIGN KEY (user_id) REFERENCES user (id)');
32 | $this->addSql('ALTER TABLE user_meeting ADD CONSTRAINT FK_AD18FF3367433D9C FOREIGN KEY (meeting_id) REFERENCES meeting (id)');
33 | $this->addSql('ALTER TABLE user_device ADD CONSTRAINT FK_6C7DADB358E0A285 FOREIGN KEY (userid_id) REFERENCES user (id)');
34 | $this->addSql('ALTER TABLE tag_meeting ADD CONSTRAINT FK_C724CC93BAD26311 FOREIGN KEY (tag_id) REFERENCES tag (id) ON DELETE CASCADE');
35 | $this->addSql('ALTER TABLE tag_meeting ADD CONSTRAINT FK_C724CC9367433D9C FOREIGN KEY (meeting_id) REFERENCES meeting (id) ON DELETE CASCADE');
36 | }
37 |
38 | public function down(Schema $schema) : void
39 | {
40 | // this down() migration is auto-generated, please modify it to your needs
41 | $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
42 |
43 | $this->addSql('ALTER TABLE user_meeting DROP FOREIGN KEY FK_AD18FF33A76ED395');
44 | $this->addSql('ALTER TABLE user_device DROP FOREIGN KEY FK_6C7DADB358E0A285');
45 | $this->addSql('ALTER TABLE tag_meeting DROP FOREIGN KEY FK_C724CC93BAD26311');
46 | $this->addSql('ALTER TABLE user_meeting DROP FOREIGN KEY FK_AD18FF3367433D9C');
47 | $this->addSql('ALTER TABLE tag_meeting DROP FOREIGN KEY FK_C724CC9367433D9C');
48 | $this->addSql('DROP TABLE user');
49 | $this->addSql('DROP TABLE user_meeting');
50 | $this->addSql('DROP TABLE user_device');
51 | $this->addSql('DROP TABLE tag');
52 | $this->addSql('DROP TABLE tag_meeting');
53 | $this->addSql('DROP TABLE meeting');
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/Migrations/Version20201222071711.php:
--------------------------------------------------------------------------------
1 | abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
24 |
25 | $this->addSql('DROP TABLE user_meeting');
26 | $this->addSql('ALTER TABLE user DROP fullname, DROP created_at, DROP updated_at, DROP username, CHANGE email email VARCHAR(180) NOT NULL, CHANGE roles roles LONGTEXT NOT NULL COMMENT \'(DC2Type:json)\'');
27 | $this->addSql('CREATE UNIQUE INDEX UNIQ_8D93D649E7927C74 ON user (email)');
28 | }
29 |
30 | public function down(Schema $schema) : void
31 | {
32 | // this down() migration is auto-generated, please modify it to your needs
33 | $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
34 |
35 | $this->addSql('CREATE TABLE user_meeting (user_id INT NOT NULL, meeting_id INT NOT NULL, INDEX IDX_AD18FF33A76ED395 (user_id), INDEX IDX_AD18FF3367433D9C (meeting_id), PRIMARY KEY(user_id, meeting_id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB COMMENT = \'\' ');
36 | $this->addSql('ALTER TABLE user_meeting ADD CONSTRAINT FK_AD18FF3367433D9C FOREIGN KEY (meeting_id) REFERENCES meeting (id)');
37 | $this->addSql('ALTER TABLE user_meeting ADD CONSTRAINT FK_AD18FF33A76ED395 FOREIGN KEY (user_id) REFERENCES user (id)');
38 | $this->addSql('DROP INDEX UNIQ_8D93D649E7927C74 ON user');
39 | $this->addSql('ALTER TABLE user ADD fullname VARCHAR(100) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`, ADD created_at DATETIME NOT NULL, ADD updated_at DATETIME NOT NULL, ADD username VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`, CHANGE email email VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`, CHANGE roles roles LONGTEXT CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci` COMMENT \'(DC2Type:array)\'');
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Migrations/Version20201222132851.php:
--------------------------------------------------------------------------------
1 | abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
24 |
25 | $this->addSql('ALTER TABLE meeting CHANGE datetime meeting_at DATETIME NOT NULL');
26 | }
27 |
28 | public function down(Schema $schema) : void
29 | {
30 | // this down() migration is auto-generated, please modify it to your needs
31 | $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
32 |
33 | $this->addSql('ALTER TABLE meeting CHANGE meeting_at datetime DATETIME NOT NULL');
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Repository/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shambhu384/symfony5-jwt-restapi/0264a7be4cad4516d89235a6b3ad692e1e6bdf79/src/Repository/.gitignore
--------------------------------------------------------------------------------
/src/Repository/MeetingRepository.php:
--------------------------------------------------------------------------------
1 | createQueryBuilder('u')
31 | ->andWhere('u.exampleField = :val')
32 | ->setParameter('val', $value)
33 | ->orderBy('u.id', 'ASC')
34 | ->setMaxResults(10)
35 | ->getQuery()
36 | ->getResult()
37 | ;
38 | }
39 | */
40 |
41 | /*
42 | public function findOneBySomeField($value): ?Meeting
43 | {
44 | return $this->createQueryBuilder('u')
45 | ->andWhere('u.exampleField = :val')
46 | ->setParameter('val', $value)
47 | ->getQuery()
48 | ->getOneOrNullResult()
49 | ;
50 | }
51 | */
52 | }
53 |
--------------------------------------------------------------------------------
/src/Repository/TagRepository.php:
--------------------------------------------------------------------------------
1 | createQueryBuilder('t')
33 | ->andWhere('t.exampleField = :val')
34 | ->setParameter('val', $value)
35 | ->orderBy('t.id', 'ASC')
36 | ->setMaxResults(10)
37 | ->getQuery()
38 | ->getResult()
39 | ;
40 | }
41 | */
42 |
43 | /*
44 | public function findOneBySomeField($value): ?Tag
45 | {
46 | return $this->createQueryBuilder('t')
47 | ->andWhere('t.exampleField = :val')
48 | ->setParameter('val', $value)
49 | ->getQuery()
50 | ->getOneOrNullResult()
51 | ;
52 | }
53 | */
54 | }
55 |
--------------------------------------------------------------------------------
/src/Repository/UserDeviceRepository.php:
--------------------------------------------------------------------------------
1 | createQueryBuilder('u')
34 | ->andWhere('u.exampleField = :val')
35 | ->setParameter('val', $value)
36 | ->orderBy('u.id', 'ASC')
37 | ->setMaxResults(10)
38 | ->getQuery()
39 | ->getResult()
40 | ;
41 | }
42 | */
43 |
44 | /*
45 | public function findOneBySomeField($value): ?UserDevice
46 | {
47 | return $this->createQueryBuilder('u')
48 | ->andWhere('u.exampleField = :val')
49 | ->setParameter('val', $value)
50 | ->getQuery()
51 | ->getOneOrNullResult()
52 | ;
53 | }
54 | */
55 | }
56 |
--------------------------------------------------------------------------------
/src/Repository/UserRepository.php:
--------------------------------------------------------------------------------
1 | setPassword($newEncodedPassword);
35 | $this->_em->persist($user);
36 | $this->_em->flush();
37 | }
38 |
39 | // /**
40 | // * @return User[] Returns an array of User objects
41 | // */
42 | /*
43 | public function findByExampleField($value)
44 | {
45 | return $this->createQueryBuilder('u')
46 | ->andWhere('u.exampleField = :val')
47 | ->setParameter('val', $value)
48 | ->orderBy('u.id', 'ASC')
49 | ->setMaxResults(10)
50 | ->getQuery()
51 | ->getResult()
52 | ;
53 | }
54 | */
55 |
56 | /*
57 | public function findOneBySomeField($value): ?User
58 | {
59 | return $this->createQueryBuilder('u')
60 | ->andWhere('u.exampleField = :val')
61 | ->setParameter('val', $value)
62 | ->getQuery()
63 | ->getOneOrNullResult()
64 | ;
65 | }
66 | */
67 | }
68 |
--------------------------------------------------------------------------------
/src/Security/Voter/MeetingVoter.php:
--------------------------------------------------------------------------------
1 | getUser();
31 | // if the user is anonymous, do not grant access
32 | if (!$user instanceof UserInterface) {
33 | return false;
34 | }
35 |
36 | // ... (check conditions and return true to grant permission) ...
37 | switch ($attribute) {
38 | case self::EDIT:
39 | // logic to determine if the user can EDIT
40 | // return true or false
41 | break;
42 | }
43 |
44 | return false;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/symfony.lock:
--------------------------------------------------------------------------------
1 | {
2 | "doctrine/annotations": {
3 | "version": "1.0",
4 | "recipe": {
5 | "repo": "github.com/symfony/recipes",
6 | "branch": "master",
7 | "version": "1.0",
8 | "ref": "a2759dd6123694c8d901d0ec80006e044c2e6457"
9 | },
10 | "files": [
11 | "config/routes/annotations.yaml"
12 | ]
13 | },
14 | "doctrine/cache": {
15 | "version": "1.10.2"
16 | },
17 | "doctrine/collections": {
18 | "version": "1.6.7"
19 | },
20 | "doctrine/common": {
21 | "version": "3.1.0"
22 | },
23 | "doctrine/data-fixtures": {
24 | "version": "1.4.4"
25 | },
26 | "doctrine/dbal": {
27 | "version": "2.12.1"
28 | },
29 | "doctrine/doctrine-bundle": {
30 | "version": "2.0",
31 | "recipe": {
32 | "repo": "github.com/symfony/recipes",
33 | "branch": "master",
34 | "version": "2.0",
35 | "ref": "368794356c1fb634e58b38ad2addb36933f2e73e"
36 | },
37 | "files": [
38 | "config/packages/doctrine.yaml",
39 | "config/packages/prod/doctrine.yaml",
40 | "src/Entity/.gitignore",
41 | "src/Repository/.gitignore"
42 | ]
43 | },
44 | "doctrine/doctrine-fixtures-bundle": {
45 | "version": "3.0",
46 | "recipe": {
47 | "repo": "github.com/symfony/recipes",
48 | "branch": "master",
49 | "version": "3.0",
50 | "ref": "e5b542d4ef47d8a003c91beb35650c76907f7e53"
51 | },
52 | "files": [
53 | "src/DataFixtures/AppFixtures.php"
54 | ]
55 | },
56 | "doctrine/doctrine-migrations-bundle": {
57 | "version": "2.2",
58 | "recipe": {
59 | "repo": "github.com/symfony/recipes",
60 | "branch": "master",
61 | "version": "2.2",
62 | "ref": "baaa439e3e3179e69e3da84b671f0a3e4a2f56ad"
63 | },
64 | "files": [
65 | "config/packages/doctrine_migrations.yaml",
66 | "migrations/.gitignore"
67 | ]
68 | },
69 | "doctrine/event-manager": {
70 | "version": "1.1.1"
71 | },
72 | "doctrine/inflector": {
73 | "version": "2.0.3"
74 | },
75 | "doctrine/instantiator": {
76 | "version": "1.4.0"
77 | },
78 | "doctrine/lexer": {
79 | "version": "1.2.1"
80 | },
81 | "doctrine/migrations": {
82 | "version": "2.3.1"
83 | },
84 | "doctrine/orm": {
85 | "version": "2.8.1"
86 | },
87 | "doctrine/persistence": {
88 | "version": "2.1.0"
89 | },
90 | "doctrine/sql-formatter": {
91 | "version": "1.1.1"
92 | },
93 | "friendsofsymfony/rest-bundle": {
94 | "version": "2.2",
95 | "recipe": {
96 | "repo": "github.com/symfony/recipes-contrib",
97 | "branch": "master",
98 | "version": "2.2",
99 | "ref": "cad41ef93d6150067ae2bb3c7fd729492dff6f0a"
100 | },
101 | "files": [
102 | "config/packages/fos_rest.yaml"
103 | ]
104 | },
105 | "gesdinet/jwt-refresh-token-bundle": {
106 | "version": "v0.9.1"
107 | },
108 | "laminas/laminas-code": {
109 | "version": "3.5.1"
110 | },
111 | "laminas/laminas-eventmanager": {
112 | "version": "3.3.0"
113 | },
114 | "laminas/laminas-zendframework-bridge": {
115 | "version": "1.1.1"
116 | },
117 | "lcobucci/clock": {
118 | "version": "2.0.0"
119 | },
120 | "lcobucci/jwt": {
121 | "version": "4.0.0"
122 | },
123 | "lexik/jwt-authentication-bundle": {
124 | "version": "2.5",
125 | "recipe": {
126 | "repo": "github.com/symfony/recipes",
127 | "branch": "master",
128 | "version": "2.5",
129 | "ref": "5b2157bcd5778166a5696e42f552ad36529a07a6"
130 | },
131 | "files": [
132 | "config/packages/lexik_jwt_authentication.yaml"
133 | ]
134 | },
135 | "namshi/jose": {
136 | "version": "7.2.3"
137 | },
138 | "nelmio/api-doc-bundle": {
139 | "version": "3.0",
140 | "recipe": {
141 | "repo": "github.com/symfony/recipes-contrib",
142 | "branch": "master",
143 | "version": "3.0",
144 | "ref": "c8e0c38e1a280ab9e37587a8fa32b251d5bc1c94"
145 | },
146 | "files": [
147 | "config/packages/nelmio_api_doc.yaml",
148 | "config/routes/nelmio_api_doc.yaml"
149 | ]
150 | },
151 | "nikic/php-parser": {
152 | "version": "v4.10.4"
153 | },
154 | "ocramius/proxy-manager": {
155 | "version": "2.10.0"
156 | },
157 | "phpdocumentor/reflection-common": {
158 | "version": "2.2.0"
159 | },
160 | "phpdocumentor/reflection-docblock": {
161 | "version": "5.2.2"
162 | },
163 | "phpdocumentor/type-resolver": {
164 | "version": "1.4.0"
165 | },
166 | "predis/predis": {
167 | "version": "v1.1.6"
168 | },
169 | "psr/cache": {
170 | "version": "1.0.1"
171 | },
172 | "psr/container": {
173 | "version": "1.0.0"
174 | },
175 | "psr/event-dispatcher": {
176 | "version": "1.0.0"
177 | },
178 | "psr/log": {
179 | "version": "1.1.3"
180 | },
181 | "symfony/asset": {
182 | "version": "v5.2.1"
183 | },
184 | "symfony/cache": {
185 | "version": "v5.0.11"
186 | },
187 | "symfony/cache-contracts": {
188 | "version": "v2.2.0"
189 | },
190 | "symfony/config": {
191 | "version": "v5.0.11"
192 | },
193 | "symfony/console": {
194 | "version": "4.4",
195 | "recipe": {
196 | "repo": "github.com/symfony/recipes",
197 | "branch": "master",
198 | "version": "4.4",
199 | "ref": "ea8c0eda34fda57e7d5cd8cbd889e2a387e3472c"
200 | },
201 | "files": [
202 | "bin/console",
203 | "config/bootstrap.php"
204 | ]
205 | },
206 | "symfony/dependency-injection": {
207 | "version": "v5.0.11"
208 | },
209 | "symfony/deprecation-contracts": {
210 | "version": "v2.2.0"
211 | },
212 | "symfony/doctrine-bridge": {
213 | "version": "v5.0.11"
214 | },
215 | "symfony/dotenv": {
216 | "version": "v5.0.11"
217 | },
218 | "symfony/error-handler": {
219 | "version": "v5.0.11"
220 | },
221 | "symfony/event-dispatcher": {
222 | "version": "v5.0.11"
223 | },
224 | "symfony/event-dispatcher-contracts": {
225 | "version": "v2.2.0"
226 | },
227 | "symfony/filesystem": {
228 | "version": "v5.0.11"
229 | },
230 | "symfony/finder": {
231 | "version": "v5.0.11"
232 | },
233 | "symfony/flex": {
234 | "version": "1.0",
235 | "recipe": {
236 | "repo": "github.com/symfony/recipes",
237 | "branch": "master",
238 | "version": "1.0",
239 | "ref": "c0eeb50665f0f77226616b6038a9b06c03752d8e"
240 | },
241 | "files": [
242 | ".env"
243 | ]
244 | },
245 | "symfony/framework-bundle": {
246 | "version": "4.4",
247 | "recipe": {
248 | "repo": "github.com/symfony/recipes",
249 | "branch": "master",
250 | "version": "4.4",
251 | "ref": "df1f2fe60b8fbb5cf7e26a7af19445c128a13b90"
252 | },
253 | "files": [
254 | "config/bootstrap.php",
255 | "config/packages/cache.yaml",
256 | "config/packages/framework.yaml",
257 | "config/packages/test/framework.yaml",
258 | "config/preload.php",
259 | "config/routes/dev/framework.yaml",
260 | "config/services.yaml",
261 | "public/index.php",
262 | "src/Controller/.gitignore",
263 | "src/Kernel.php"
264 | ]
265 | },
266 | "symfony/http-client-contracts": {
267 | "version": "v2.3.1"
268 | },
269 | "symfony/http-foundation": {
270 | "version": "v5.0.11"
271 | },
272 | "symfony/http-kernel": {
273 | "version": "v5.0.11"
274 | },
275 | "symfony/maker-bundle": {
276 | "version": "1.0",
277 | "recipe": {
278 | "repo": "github.com/symfony/recipes",
279 | "branch": "master",
280 | "version": "1.0",
281 | "ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f"
282 | }
283 | },
284 | "symfony/options-resolver": {
285 | "version": "v5.2.1"
286 | },
287 | "symfony/polyfill-intl-grapheme": {
288 | "version": "v1.20.0"
289 | },
290 | "symfony/polyfill-intl-normalizer": {
291 | "version": "v1.20.0"
292 | },
293 | "symfony/polyfill-mbstring": {
294 | "version": "v1.20.0"
295 | },
296 | "symfony/polyfill-php73": {
297 | "version": "v1.20.0"
298 | },
299 | "symfony/polyfill-php80": {
300 | "version": "v1.20.0"
301 | },
302 | "symfony/profiler-pack": {
303 | "version": "v1.0.5"
304 | },
305 | "symfony/property-access": {
306 | "version": "v5.0.11"
307 | },
308 | "symfony/property-info": {
309 | "version": "v5.0.11"
310 | },
311 | "symfony/routing": {
312 | "version": "4.2",
313 | "recipe": {
314 | "repo": "github.com/symfony/recipes",
315 | "branch": "master",
316 | "version": "4.2",
317 | "ref": "683dcb08707ba8d41b7e34adb0344bfd68d248a7"
318 | },
319 | "files": [
320 | "config/packages/prod/routing.yaml",
321 | "config/packages/routing.yaml",
322 | "config/routes.yaml"
323 | ]
324 | },
325 | "symfony/security-bundle": {
326 | "version": "4.4",
327 | "recipe": {
328 | "repo": "github.com/symfony/recipes",
329 | "branch": "master",
330 | "version": "4.4",
331 | "ref": "7b4408dc203049666fe23fabed23cbadc6d8440f"
332 | },
333 | "files": [
334 | "config/packages/security.yaml"
335 | ]
336 | },
337 | "symfony/security-core": {
338 | "version": "v5.0.11"
339 | },
340 | "symfony/security-csrf": {
341 | "version": "v5.0.11"
342 | },
343 | "symfony/security-guard": {
344 | "version": "v5.0.11"
345 | },
346 | "symfony/security-http": {
347 | "version": "v5.0.11"
348 | },
349 | "symfony/serializer": {
350 | "version": "v5.0.11"
351 | },
352 | "symfony/serializer-pack": {
353 | "version": "v1.0.4"
354 | },
355 | "symfony/service-contracts": {
356 | "version": "v2.2.0"
357 | },
358 | "symfony/stopwatch": {
359 | "version": "v5.0.11"
360 | },
361 | "symfony/string": {
362 | "version": "v5.2.1"
363 | },
364 | "symfony/translation-contracts": {
365 | "version": "v2.3.0"
366 | },
367 | "symfony/twig-bridge": {
368 | "version": "v5.0.11"
369 | },
370 | "symfony/twig-bundle": {
371 | "version": "5.0",
372 | "recipe": {
373 | "repo": "github.com/symfony/recipes",
374 | "branch": "master",
375 | "version": "5.0",
376 | "ref": "fab9149bbaa4d5eca054ed93f9e1b66cc500895d"
377 | },
378 | "files": [
379 | "config/packages/test/twig.yaml",
380 | "config/packages/twig.yaml",
381 | "templates/base.html.twig"
382 | ]
383 | },
384 | "symfony/validator": {
385 | "version": "4.3",
386 | "recipe": {
387 | "repo": "github.com/symfony/recipes",
388 | "branch": "master",
389 | "version": "4.3",
390 | "ref": "d902da3e4952f18d3bf05aab29512eb61cabd869"
391 | },
392 | "files": [
393 | "config/packages/test/validator.yaml",
394 | "config/packages/validator.yaml"
395 | ]
396 | },
397 | "symfony/var-dumper": {
398 | "version": "v5.0.11"
399 | },
400 | "symfony/var-exporter": {
401 | "version": "v5.0.11"
402 | },
403 | "symfony/web-profiler-bundle": {
404 | "version": "3.3",
405 | "recipe": {
406 | "repo": "github.com/symfony/recipes",
407 | "branch": "master",
408 | "version": "3.3",
409 | "ref": "6bdfa1a95f6b2e677ab985cd1af2eae35d62e0f6"
410 | },
411 | "files": [
412 | "config/packages/dev/web_profiler.yaml",
413 | "config/packages/test/web_profiler.yaml",
414 | "config/routes/dev/web_profiler.yaml"
415 | ]
416 | },
417 | "symfony/yaml": {
418 | "version": "v5.0.11"
419 | },
420 | "twig/twig": {
421 | "version": "v3.1.1"
422 | },
423 | "webimpress/safe-writer": {
424 | "version": "2.1.0"
425 | },
426 | "webmozart/assert": {
427 | "version": "1.9.1"
428 | },
429 | "willdurand/jsonp-callback-validator": {
430 | "version": "v1.1.0"
431 | },
432 | "willdurand/negotiation": {
433 | "version": "3.0.0"
434 | },
435 | "zircote/swagger-php": {
436 | "version": "2.1.0"
437 | }
438 | }
439 |
--------------------------------------------------------------------------------
/templates/base.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {% block title %}Welcome!{% endblock %}
6 | {% block stylesheets %}{% endblock %}
7 |
8 |
9 | {% block body %}{% endblock %}
10 | {% block javascripts %}{% endblock %}
11 |
12 |
13 |
--------------------------------------------------------------------------------
/templates/default/index.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'base.html.twig' %}
2 |
3 | {% block title %} Meeting api For App Development {% endblock %}
4 |
5 | {% block body %}
6 |
10 |
11 |
Free Meeting RestAPI for Mobile app developement
12 |
13 |
Api features
14 |
15 | - JWT Authentication
16 | - Manage Meetings
17 | - Registration/Unregistration for Meeting
18 |
19 |
See Meetings
20 |
21 |
22 |
23 | 
24 | Download postman file
25 |
26 |
27 |
Source code explore
28 |
29 |
30 |
33 | {% endblock %}
34 |
35 |
--------------------------------------------------------------------------------
/templates/emails/registration.html.twig:
--------------------------------------------------------------------------------
1 | {# templates/emails/registration.html.twig #}
2 | You did it! You registered!
3 |
4 | Hi {{ name }}! You're successfully registered.
5 |
6 | {# example, assuming you have a route named "login" #}
7 | To login, go to: ....
8 |
9 | Thanks!
10 |
11 | {# Makes an absolute URL to the /images/logo.png file #}
12 |
13 |
--------------------------------------------------------------------------------
/templates/meeting_registration/index.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'base.html.twig' %}
2 |
3 | {% block title %}Hello {{ controller_name }}!{% endblock %}
4 |
5 | {% block body %}
6 |
10 |
11 |
12 |
Hello {{ controller_name }}! ✅
13 |
14 | This friendly message is coming from:
15 |
16 | - Your controller at
src/Controller/MeetingRegistrationController.php
17 | - Your template at
templates/meeting_registration/index.html.twig
18 |
19 |
20 | {% endblock %}
21 |
--------------------------------------------------------------------------------
/templates/user/index.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'base.html.twig' %}
2 |
3 | {% block title %}Hello {{ controller_name }}!{% endblock %}
4 |
5 | {% block body %}
6 |
10 |
11 |
12 |
Hello {{ controller_name }}! ✅
13 |
14 | This friendly message is coming from:
15 |
16 | - Your controller at
src/Controller/UserController.php
17 | - Your template at
templates/user/index.html.twig
18 |
19 |
20 | {% endblock %}
21 |
--------------------------------------------------------------------------------
/tests/Util/CalculatorTest.php:
--------------------------------------------------------------------------------
1 | add(30, 12);
13 |
14 | // assert that your calculator added the numbers correctly!
15 | $this->assertEquals(42, $result);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ts/index.php:
--------------------------------------------------------------------------------
1 |