Compare commits

..

5 commits

22 changed files with 1497 additions and 1397 deletions

2
.env
View file

@ -5,8 +5,6 @@
###> symfony/framework-bundle ### ###> symfony/framework-bundle ###
APP_ENV=dev APP_ENV=dev
APP_SECRET=xxx APP_SECRET=xxx
#TRUSTED_PROXIES=127.0.0.1,127.0.0.2
#TRUSTED_HOSTS=localhost,example.com
###< symfony/framework-bundle ### ###< symfony/framework-bundle ###
###> doctrine/doctrine-bundle ### ###> doctrine/doctrine-bundle ###

1
.gitignore vendored
View file

@ -4,6 +4,7 @@
/.env.local /.env.local
/.env.local.php /.env.local.php
/.env.*.local /.env.*.local
/config/secrets/prod/prod.decrypt.private.php
/public/bundles/ /public/bundles/
/var/ /var/
/vendor/ /vendor/

View file

@ -12,45 +12,47 @@
], ],
"type": "project", "type": "project",
"require": { "require": {
"php": ">=8.0.0", "php": ">=8.1.0",
"ext-ctype": "*", "ext-ctype": "*",
"ext-hash": "*", "ext-hash": "*",
"ext-iconv": "*", "ext-iconv": "*",
"ext-json": "*", "ext-json": "*",
"babdev/pagerfanta-bundle": "^2.4", "babdev/pagerfanta-bundle": "^3.0",
"composer/package-versions-deprecated": "1.11.99.5", "composer/package-versions-deprecated": "1.11.99.5",
"doctrine/annotations": "^1.0", "doctrine/annotations": "^1.0",
"doctrine/doctrine-bundle": "^2", "doctrine/doctrine-bundle": "^2",
"doctrine/doctrine-migrations-bundle": "^2", "doctrine/doctrine-migrations-bundle": "^2",
"doctrine/orm": "^2", "doctrine/orm": "^2",
"excelwebzone/recaptcha-bundle": "^1.5", "excelwebzone/recaptcha-bundle": "^1.5",
"pagerfanta/doctrine-orm-adapter": "^3.6",
"pagerfanta/twig": "^3.6",
"phpdocumentor/reflection-docblock": "^5.3", "phpdocumentor/reflection-docblock": "^5.3",
"phpstan/phpdoc-parser": "^1.6", "phpstan/phpdoc-parser": "^1.6",
"pugx/sentry-sdk": "^2.0", "sensio/framework-extra-bundle": "^6.0",
"sensio/framework-extra-bundle": "^5.1",
"sentry/sentry-symfony": "^4", "sentry/sentry-symfony": "^4",
"suin/php-rss-writer": "^1.6", "suin/php-rss-writer": "^1.6",
"symfony/asset": "^4.1", "symfony/asset": "^5.4",
"symfony/console": "^4.1", "symfony/console": "^5.4",
"symfony/dotenv": "^4.1", "symfony/dotenv": "^5.4",
"symfony/expression-language": "^4.1", "symfony/expression-language": "^5.4",
"symfony/flex": "^1.0", "symfony/flex": "^1.0",
"symfony/form": "^4.1", "symfony/form": "^5.4",
"symfony/framework-bundle": "^4.1", "symfony/framework-bundle": "^5.4",
"symfony/http-client": "^4.1", "symfony/http-client": "^5.4",
"symfony/mailer": "^4.1", "symfony/mailer": "^5.4",
"symfony/monolog-bundle": "^3.3", "symfony/monolog-bundle": "^3.3",
"symfony/property-access": "^4.1", "symfony/property-access": "^5.4",
"symfony/property-info": "^4.1", "symfony/property-info": "^5.4",
"symfony/security-bundle": "^4.1", "symfony/runtime": "^5.4",
"symfony/serializer": "^4.1", "symfony/security-bundle": "^5.4",
"symfony/translation": "^4.1", "symfony/serializer": "^5.4",
"symfony/twig-bundle": "^4.1", "symfony/translation": "^5.4",
"symfony/validator": "^4.1", "symfony/twig-bundle": "^5.4",
"symfony/yaml": "^4.1" "symfony/validator": "^5.4",
"symfony/yaml": "^5.4"
}, },
"require-dev": { "require-dev": {
"symfony/web-profiler-bundle": "^4.1", "symfony/web-profiler-bundle": "^5.4",
"symfony/web-server-bundle": "^4.1" "symfony/web-server-bundle": "^4.1"
}, },
"config": { "config": {
@ -59,7 +61,8 @@
}, },
"sort-packages": true, "sort-packages": true,
"allow-plugins": { "allow-plugins": {
"symfony/flex": true "symfony/flex": true,
"symfony/runtime": true
} }
}, },
"autoload": { "autoload": {

2568
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,25 @@
framework:
cache:
# Unique name of your app: used to compute stable namespaces for cache keys.
#prefix_seed: your_vendor_name/app_name
# The "app" cache stores to the filesystem by default.
# The data in this cache should persist between deploys.
# Other options include:
# Redis
#app: cache.adapter.redis
#default_redis_provider: redis://localhost
# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
#app: cache.adapter.apcu
# Namespaced pools use the above "app" backend by default
#pools:
#my.dedicated.cache: null
prefix_seed: magnetico-web
pools:
magneticod.cache:
adapter: cache.adapter.redis
provider: '%env(REDIS_DSN)%'
default_lifetime: 600

View file

@ -1,36 +1,24 @@
# see https://symfony.com/doc/current/reference/configuration/framework.html
framework: framework:
secret: '%env(APP_SECRET)%' secret: '%env(APP_SECRET)%'
#default_locale: en
#csrf_protection: true #csrf_protection: true
#http_method_override: true http_method_override: false
# Enables session support. Note that the session will ONLY be started if you read or write from it. # Enables session support. Note that the session will ONLY be started if you read or write from it.
# Remove or comment this section to explicitly disable session support. # Remove or comment this section to explicitly disable session support.
session: session:
handler_id: ~ handler_id: null
cookie_secure: auto
cookie_samesite: lax
storage_factory_id: session.storage.factory.native
#esi: true #esi: true
#fragments: true #fragments: true
php_errors: php_errors:
log: true log: true
cache: when@test:
# Put the unique name of your app here: the prefix seed framework:
# is used to compute stable namespaces for cache keys. test: true
#prefix_seed: your_vendor_name/app_name session:
storage_factory_id: session.storage.factory.mock_file
# The app cache caches to the filesystem by default.
# Other options include:
# Redis
#app: cache.adapter.redis
#default_redis_provider: redis://localhost
# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
#app: cache.adapter.apcu
prefix_seed: magnetico-web
pools:
magneticod.cache:
adapter: cache.adapter.redis
provider: '%env(REDIS_DSN)%'
default_lifetime: 600

View file

@ -1,21 +0,0 @@
services:
# Register nyholm/psr7 services for autowiring with PSR-17 (HTTP factories)
Psr\Http\Message\RequestFactoryInterface: '@nyholm.psr7.psr17_factory'
Psr\Http\Message\ResponseFactoryInterface: '@nyholm.psr7.psr17_factory'
Psr\Http\Message\ServerRequestFactoryInterface: '@nyholm.psr7.psr17_factory'
Psr\Http\Message\StreamFactoryInterface: '@nyholm.psr7.psr17_factory'
Psr\Http\Message\UploadedFileFactoryInterface: '@nyholm.psr7.psr17_factory'
Psr\Http\Message\UriFactoryInterface: '@nyholm.psr7.psr17_factory'
# Register nyholm/psr7 services for autowiring with HTTPlug factories
Http\Message\MessageFactory: '@nyholm.psr7.httplug_factory'
Http\Message\RequestFactory: '@nyholm.psr7.httplug_factory'
Http\Message\ResponseFactory: '@nyholm.psr7.httplug_factory'
Http\Message\StreamFactory: '@nyholm.psr7.httplug_factory'
Http\Message\UriFactory: '@nyholm.psr7.httplug_factory'
nyholm.psr7.psr17_factory:
class: Nyholm\Psr7\Factory\Psr17Factory
nyholm.psr7.httplug_factory:
class: Nyholm\Psr7\Factory\HttplugFactory

View file

@ -1,21 +0,0 @@
services:
_defaults:
autowire: true
autoconfigure: true
Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface:
'@Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory'
Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface:
'@Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory'
Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory: null
Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory: null
# Uncomment the following line to allow controllers to receive a
# PSR-7 server request object instead of an HttpFoundation request
#Symfony\Bridge\PsrHttpMessage\ArgumentValueResolver\PsrServerRequestResolver: null
# Uncomment the following line to allow controllers to return a
# PSR-7 response object instead of an HttpFoundation response
#Symfony\Bridge\PsrHttpMessage\EventListener\PsrResponseListener: null

5
config/preload.php Normal file
View file

@ -0,0 +1,5 @@
<?php
if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) {
require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php';
}

View file

@ -1,3 +0,0 @@
_errors:
resource: '@TwigBundle/Resources/config/routing/errors.xml'
prefix: /_error

View file

@ -0,0 +1,4 @@
when@dev:
_errors:
resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
prefix: /_error

View file

@ -1,3 +1,6 @@
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
# Put parameters here that don't need to change on each machine where the app is deployed # Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters: parameters:
@ -18,8 +21,10 @@ services:
$newUserInvites: '%env(NEW_USER_INVITES)%' $newUserInvites: '%env(NEW_USER_INVITES)%'
$fromAddress: '%env(MAILER_FROM)%' $fromAddress: '%env(MAILER_FROM)%'
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\: App\:
resource: '../src/*' resource: '../src/'
exclude: '../src/{Api/V1/{DTO},Magnetico/{Entity,Migrations},Entity,FormRequest,Migrations,Tests,View,Kernel.php}' exclude: '../src/{Api/V1/{DTO},Magnetico/{Entity,Migrations},Entity,FormRequest,Migrations,Tests,View,Kernel.php}'
# Use array in exclude config from Symfony 4.2 # Use array in exclude config from Symfony 4.2
#- '../src/Api/V1/{DTO}' #- '../src/Api/V1/{DTO}'

View file

@ -1,27 +1,10 @@
<?php <?php
declare(strict_types=1);
use App\Kernel; use App\Kernel;
use Symfony\Component\Debug\Debug;
use Symfony\Component\HttpFoundation\Request;
require dirname(__DIR__).'/config/bootstrap.php'; require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
if ($_SERVER['APP_DEBUG']) { return function (array $context) {
umask(0000); return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
};
Debug::enable();
}
if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? $_ENV['TRUSTED_PROXIES'] ?? false) {
Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
}
if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? $_ENV['TRUSTED_HOSTS'] ?? false) {
Request::setTrustedHosts([$trustedHosts]);
}
$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

View file

@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
namespace App\Feed; namespace App\Feed;

View file

@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
namespace App\Helper; namespace App\Helper;

View file

@ -3,59 +3,9 @@
namespace App; namespace App;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel as BaseKernel; use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Component\Routing\RouteCollectionBuilder;
class Kernel extends BaseKernel class Kernel extends BaseKernel
{ {
use MicroKernelTrait; use MicroKernelTrait;
const CONFIG_EXTS = '.{php,xml,yaml,yml}';
public function getCacheDir()
{
return $this->getProjectDir().'/var/cache/'.$this->environment;
}
public function getLogDir()
{
return $this->getProjectDir().'/var/log';
}
public function registerBundles()
{
$contents = require $this->getProjectDir().'/config/bundles.php';
foreach ($contents as $class => $envs) {
if (isset($envs['all']) || isset($envs[$this->environment])) {
yield new $class();
}
}
}
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
{
$container->addResource(new FileResource($this->getProjectDir().'/config/bundles.php'));
// Feel free to remove the "container.autowiring.strict_mode" parameter
// if you are using symfony/dependency-injection 4.0+ as it's the default behavior
$container->setParameter('container.autowiring.strict_mode', true);
$container->setParameter('container.dumper.inline_class_loader', true);
$confDir = $this->getProjectDir().'/config';
$loader->load($confDir.'/{packages}/*'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/{packages}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/{services}'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/{services}_'.$this->environment.self::CONFIG_EXTS, 'glob');
}
protected function configureRoutes(RouteCollectionBuilder $routes)
{
$confDir = $this->getProjectDir().'/config';
$routes->import($confDir.'/{routes}/*'.self::CONFIG_EXTS, '/', 'glob');
$routes->import($confDir.'/{routes}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, '/', 'glob');
$routes->import($confDir.'/{routes}'.self::CONFIG_EXTS, '/', 'glob');
}
} }

View file

@ -1,15 +1,16 @@
<?php <?php
declare(strict_types=1);
namespace App\Pager; namespace App\Pager;
use Pagerfanta\Adapter\DoctrineORMAdapter; use Pagerfanta\Doctrine\ORM\QueryAdapter;
/** /**
* This adapter don't make COUNT() queries. * This adapter don't make COUNT() queries.
*/ */
class PagelessDoctrineORMAdapter extends DoctrineORMAdapter class PagelessDoctrineORMAdapter extends QueryAdapter
{ {
public function getNbResults() public function getNbResults(): int
{ {
return 1; return 1;
} }

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace App\Pager\View; namespace App\Pager\View;
use Pagerfanta\Pagerfanta; use Pagerfanta\Pagerfanta;
@ -27,7 +29,7 @@ class TwitterBootstrap4PagelessView implements ViewInterface
$this->template = $template ?: $this->createDefaultTemplate(); $this->template = $template ?: $this->createDefaultTemplate();
} }
public function render(PagerfantaInterface $pagerfanta, $routeGenerator, array $options = array()) public function render(PagerfantaInterface $pagerfanta, callable $routeGenerator, array $options = []): string
{ {
$this->initializePagerfanta($pagerfanta); $this->initializePagerfanta($pagerfanta);
@ -36,7 +38,7 @@ class TwitterBootstrap4PagelessView implements ViewInterface
return $this->generate(); return $this->generate();
} }
public function getName() public function getName(): string
{ {
return 'twitter_bootstrap4_pageless'; return 'twitter_bootstrap4_pageless';
} }

View file

@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
namespace App\Search; namespace App\Search;

View file

@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
namespace App\Security; namespace App\Security;
@ -13,6 +14,9 @@ use Symfony\Component\Security\Core\User\{UserInterface, UserProviderInterface};
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator; use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\Serializer\SerializerInterface;
/**
* @deprecated Refactor to new Authenticators system @see https://gitlab.com/skobkin/magnetico-web/-/issues/26
*/
class ApiTokenAuthenticator extends AbstractGuardAuthenticator class ApiTokenAuthenticator extends AbstractGuardAuthenticator
{ {
public const TOKEN_HEADER = 'api-token'; public const TOKEN_HEADER = 'api-token';
@ -104,13 +108,14 @@ class ApiTokenAuthenticator extends AbstractGuardAuthenticator
return new JsonResponse($json, JsonResponse::HTTP_UNAUTHORIZED,[], true); return new JsonResponse($json, JsonResponse::HTTP_UNAUTHORIZED,[], true);
} }
/** @deprecated use AuthenticatorInterface::createToken() instead */
public function createAuthenticatedToken(UserInterface $user, $providerKey) public function createAuthenticatedToken(UserInterface $user, $providerKey)
{ {
$request = $this->requestStack->getCurrentRequest(); $request = $this->requestStack->getCurrentRequest();
$tokenKey = $request->headers->get(self::TOKEN_HEADER) ?: $tokenKey = $request?->headers?->get(self::TOKEN_HEADER) ?:
$request->cookies->get(self::TOKEN_HEADER) ?: $request?->cookies?->get(self::TOKEN_HEADER) ?:
$request->query->get(self::TOKEN_HEADER) $request?->query?->get(self::TOKEN_HEADER)
; ;
return new AuthenticatedApiToken( return new AuthenticatedApiToken(

View file

@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
namespace App\Security\Token; namespace App\Security\Token;
@ -6,7 +7,11 @@ use App\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken; use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
use Symfony\Component\Security\Guard\Token\GuardTokenInterface; use Symfony\Component\Security\Guard\Token\GuardTokenInterface;
/** This token stores ApiToken key even after eraseCredentials() called */ /**
* This token stores ApiToken key even after eraseCredentials() called
*
* @deprecated Refactor to new Authenticators system @see https://gitlab.com/skobkin/magnetico-web/-/issues/26
*/
class AuthenticatedApiToken extends PreAuthenticatedToken implements GuardTokenInterface class AuthenticatedApiToken extends PreAuthenticatedToken implements GuardTokenInterface
{ {
/** @var string|null This token is stored only for this request and will not be erased by eraseCredentials() or serialized */ /** @var string|null This token is stored only for this request and will not be erased by eraseCredentials() or serialized */

View file

@ -120,27 +120,12 @@
"monolog/monolog": { "monolog/monolog": {
"version": "1.23.0" "version": "1.23.0"
}, },
"nyholm/psr7": {
"version": "1.0",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "master",
"version": "1.0",
"ref": "7c0a9352a57376f04f5444e74565102c3a23d0c7"
},
"files": [
"config/packages/nyholm_psr7.yaml"
]
},
"ocramius/package-versions": { "ocramius/package-versions": {
"version": "1.3.0" "version": "1.3.0"
}, },
"ocramius/proxy-manager": { "ocramius/proxy-manager": {
"version": "2.2.0" "version": "2.2.0"
}, },
"pagerfanta/pagerfanta": {
"version": "v2.3.0"
},
"php": { "php": {
"version": "8.0" "version": "8.0"
}, },
@ -243,9 +228,6 @@
"ref": "e3868d2f4a5104f19f844fe551099a00c6562527" "ref": "e3868d2f4a5104f19f844fe551099a00c6562527"
} }
}, },
"symfony/debug": {
"version": "v4.1.0"
},
"symfony/dependency-injection": { "symfony/dependency-injection": {
"version": "v4.1.0" "version": "v4.1.0"
}, },
@ -289,13 +271,23 @@
"version": "v4.1.0" "version": "v4.1.0"
}, },
"symfony/framework-bundle": { "symfony/framework-bundle": {
"version": "3.3", "version": "5.4",
"recipe": { "recipe": {
"repo": "github.com/symfony/recipes", "repo": "github.com/symfony/recipes",
"branch": "master", "branch": "main",
"version": "3.3", "version": "5.4",
"ref": "1279df12895f20d8076324036431833181eb6645" "ref": "3cd216a4d007b78d8554d44a5b1c0a446dab24fb"
} },
"files": [
"config/packages/cache.yaml",
"config/packages/framework.yaml",
"config/preload.php",
"config/routes/framework.yaml",
"config/services.yaml",
"public/index.php",
"src/Controller/.gitignore",
"src/Kernel.php"
]
}, },
"symfony/http-client": { "symfony/http-client": {
"version": "v4.4.2" "version": "v4.4.2"
@ -309,9 +301,6 @@
"symfony/http-kernel": { "symfony/http-kernel": {
"version": "v4.1.0" "version": "v4.1.0"
}, },
"symfony/intl": {
"version": "v4.1.0"
},
"symfony/mailer": { "symfony/mailer": {
"version": "4.3", "version": "4.3",
"recipe": { "recipe": {