Skip to content

Commit

Permalink
Upgrade to Symfony 5.4
Browse files Browse the repository at this point in the history
  • Loading branch information
vtsykun committed Dec 29, 2022
1 parent 3f6afbd commit 40176fd
Show file tree
Hide file tree
Showing 34 changed files with 390 additions and 278 deletions.
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ MAILER_DSN=null://null
REDIS_URL=redis://localhost
###< snc/redis-bundle ###

APP_COMPOSER_HOME="%kernel.project_dir%/var/.composer"

###> nelmio/cors-bundle ###
CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
###< nelmio/cors-bundle ###
8 changes: 8 additions & 0 deletions config/packages/packeton.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
packeton:
github_no_api: true
rss_max_items: 30
archive: true
archive_options:
format: zip
basedir: '%kernel.project_dir%/var/zipball'
endpoint: dist_host
8 changes: 4 additions & 4 deletions config/packages/security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,19 @@ security:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/login/, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/reset-password, role: IS_AUTHENTICATED_ANONYMOUSLY }

# Packagist
- { path: (^(/change-password|/profile/?|/search|/logout|/packages/|/versions/))+, role: ROLE_USER }
- { path: (^(/change-password|/profile|/search|/logout|/packages/|/versions/))+, role: ROLE_USER }
- { path: (^(/packages.json$|/p/|/p2/|/zipball/|/downloads/))+, role: ROLE_USER }
- { path: (^(/api/webhook-invoke/))+, role: ROLE_USER }
- { path: (^(/api/(create-package|update-package|github|bitbucket)))$, role: ROLE_MAINTAINER }
- { path: ^/$, role: ROLE_USER }

# Maintainers
- { path: (^(/users/(.+)/packages))+, role: ROLE_MAINTAINER }
- { path: (^(/users/(.+)/favorites))+, role: ROLE_MAINTAINER }
- { path: (^(/explore|/jobs/))+, role: ROLE_MAINTAINER }

# Secured part of the site
# This config requires being logged for the whole site and having the admin role for the admin part.
# Change these rules to adapt them to your needs
Expand Down
19 changes: 17 additions & 2 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
parameters:
packagist_web.archive: []
env(APP_COMPOSER_HOME): null

services:
# default configuration for services in *this* file
Expand Down Expand Up @@ -47,9 +47,24 @@ services:

Packeton\Service\DistConfig:
arguments:
$config: '%packagist_web.archive%'
$config: '%packeton_archive_opts%'

Packeton\Security\Api\ApiTokenAuthenticator:
abstract: true
arguments:
$userProvider: '@Packeton\Security\Provider\UserProvider'

Packeton\Composer\PackagistFactory:
arguments:
$composerHome: '%env(resolve:APP_COMPOSER_HOME)%'
$githubNoApi: '%packeton_github_no_api%'

Packeton\Service\UpdaterWorker:
tags:
- { name: queue_worker, topic: package:updates }

Packeton\Cron\CronWorker:
arguments:
- '@okvpn_cron.runner_default'
tags:
- { name: queue_worker, topic: cron:execute }
7 changes: 7 additions & 0 deletions config/validator/validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Packeton\Entity\Package:
constraints:
- Packeton\Validator\Constraint\PackageUnique: { groups: [Create] }
- Packeton\Validator\Constraint\PackageRepository: { groups: [Update, Create] }
properties:
repository:
- NotBlank: ~
2 changes: 1 addition & 1 deletion src/Controller/ApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ protected function findPackagesByUrl($url, $urlRegex)
/**
* {@inheritDoc}
*/
public static function getSubscribedServices()
public static function getSubscribedServices(): array
{
return array_merge(
parent::getSubscribedServices(),
Expand Down
102 changes: 44 additions & 58 deletions src/Controller/ExploreController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

namespace Packeton\Controller;

use Doctrine\DBAL\ConnectionException;
use Doctrine\Persistence\ManagerRegistry;
use Packeton\Entity\Package;
use Packeton\Entity\Version;
Expand Down Expand Up @@ -42,7 +41,7 @@ public function __construct(
) {}

/**
* @Route("/", name="browse")
* @Route("", name="browse")
*/
public function exploreAction(\Redis $redis)
{
Expand All @@ -61,20 +60,16 @@ public function exploreAction(\Redis $redis)
->setMaxResults(10)
->getQuery()->getResult();

try {
$popular = [];
$popularIds = $redis->zrevrange('downloads:trending', 0, 9);
if ($popularIds) {
$popular = $pkgRepo->createQueryBuilder('p')
->where('p.id IN (:ids)')
->setParameter('ids', $popularIds)
->getQuery()->getResult();
usort($popular, function ($a, $b) use ($popularIds) {
return array_search($a->getId(), $popularIds) > array_search($b->getId(), $popularIds) ? 1 : -1;
});
}
} catch (ConnectionException $e) {
$popular = [];
$popular = [];
$popularIds = $redis->zrevrange('downloads:trending', 0, 9);
if ($popularIds) {
$popular = $pkgRepo->createQueryBuilder('p')
->where('p.id IN (:ids)')
->setParameter('ids', $popularIds)
->getQuery()->getResult();
usort($popular, function ($a, $b) use ($popularIds) {
return array_search($a->getId(), $popularIds) > array_search($b->getId(), $popularIds) ? 1 : -1;
});
}

return $this->render('explore/explore.html.twig', [
Expand All @@ -86,73 +81,64 @@ public function exploreAction(\Redis $redis)
}

/**
* todo Template()
* @Route("/popular.{_format}", name="browse_popular", defaults={"_format"="html"})
*/
public function popularAction(Request $req)
public function popularAction(Request $req, \Redis $redis)
{
try {
$redis = $this->get('snc_redis.default');
$perPage = $req->query->getInt('per_page', 15);
if ($perPage <= 0 || $perPage > 100) {
if ($req->getRequestFormat() === 'json') {
return new JsonResponse(array(
'status' => 'error',
'message' => 'The optional packages per_page parameter must be an integer between 1 and 100 (default: 15)',
), 400);
}

$perPage = max(0, min(100, $perPage));
$perPage = $req->query->getInt('per_page', 15);
if ($perPage <= 0 || $perPage > 100) {
if ($req->getRequestFormat() === 'json') {
return new JsonResponse([
'status' => 'error',
'message' => 'The optional packages per_page parameter must be an integer between 1 and 100 (default: 15)',
], 400);
}

$popularIds = $redis->zrevrange(
'downloads:trending',
($req->get('page', 1) - 1) * $perPage,
$req->get('page', 1) * $perPage - 1
);
$popular = $this->registry->getRepository(Package::class)
->createQueryBuilder('p')->where('p.id IN (:ids)')->setParameter('ids', $popularIds)
->getQuery()->getResult();
usort($popular, function ($a, $b) use ($popularIds) {
return array_search($a->getId(), $popularIds) > array_search($b->getId(), $popularIds) ? 1 : -1;
});

$packages = new Pagerfanta(new FixedAdapter($redis->zcard('downloads:trending'), $popular));
$packages->setMaxPerPage($perPage);
$packages->setCurrentPage($req->get('page', 1), false, true);
} catch (ConnectionException $e) {
$packages = new Pagerfanta(new FixedAdapter(0, []));
$perPage = max(0, min(100, $perPage));
}

$data = array(
'packages' => $packages,
$popularIds = $redis->zrevrange(
'downloads:trending',
($req->get('page', 1) - 1) * $perPage,
$req->get('page', 1) * $perPage - 1
);
$popular = $this->registry->getRepository(Package::class)
->createQueryBuilder('p')->where('p.id IN (:ids)')->setParameter('ids', $popularIds)
->getQuery()->getResult();
usort($popular, function ($a, $b) use ($popularIds) {
return array_search($a->getId(), $popularIds) > array_search($b->getId(), $popularIds) ? 1 : -1;
});

$packages = new Pagerfanta(new FixedAdapter($redis->zcard('downloads:trending'), $popular));
$packages->setMaxPerPage($perPage);
$packages->setCurrentPage($req->get('page', 1));

$data = ['packages' => $packages];
$data['meta'] = $this->getPackagesMetadata($data['packages']);

if ($req->getRequestFormat() === 'json') {
$result = array(
$result = [
'packages' => [],
'total' => $packages->getNbResults(),
);
];

/** @var Package $package */
foreach ($packages as $package) {
$url = $this->generateUrl('view_package', array('name' => $package->getName()), UrlGeneratorInterface::ABSOLUTE_URL);

$result['packages'][] = array(
$url = $this->generateUrl('view_package', ['name' => $package->getName()], UrlGeneratorInterface::ABSOLUTE_URL);
$result['packages'][] = [
'name' => $package->getName(),
'description' => $package->getDescription() ?: '',
'url' => $url,
'downloads' => $data['meta']['downloads'][$package->getId()],
'favers' => $data['meta']['favers'][$package->getId()],
);
];
}

if ($packages->hasNextPage()) {
$params = array(
$params = [
'_format' => 'json',
'page' => $packages->getNextPage(),
);
];
if ($perPage !== 15) {
$params['per_page'] = $perPage;
}
Expand All @@ -162,6 +148,6 @@ public function popularAction(Request $req)
return new JsonResponse($result);
}

return $data;
return $this->render('explore/popular.html.twig', $data);
}
}
2 changes: 1 addition & 1 deletion src/Controller/FeedController.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function __construct(
*/
public function feedsAction()
{
return [];
return $this->render('feed/feeds.html.twig');
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Controller/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ protected function getUserPackages($req, $user)
/**
* {@inheritDoc}
*/
public static function getSubscribedServices()
public static function getSubscribedServices(): array
{
return array_merge(
parent::getSubscribedServices(),
Expand Down
2 changes: 1 addition & 1 deletion src/Cron/CronWorker.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function __construct(ScheduleRunnerInterface $scheduleRunner)
* @param Job $job
* @return array
*/
public function process(Job $job): array
public function __invoke(Job $job): array
{
$payload = $job->getPayload();
$envelope = unserialize($payload['envelope']);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Packeton\DependencyInjection\CompilerPass;

use Packeton\Security\Api\ApiContextListener;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
Expand Down Expand Up @@ -71,7 +72,7 @@ private function configureStatelessFirewallWithContext(
$listeners = $contextDef->getArgument(0);
$contextListeners = array_merge([new Reference($listenerId)], $listeners->getValues());

$contextDef->replaceArgument(0, $contextListeners);
$contextDef->replaceArgument(0, new IteratorArgument($contextListeners));
}

/**
Expand All @@ -86,9 +87,10 @@ private function createContextListener(ContainerBuilder $container, $contextKey)
return $this->contextListeners[$contextKey];
}

$listenerId = 'packagist.context_listener.' . $contextKey;
$listenerId = 'packeton.context_listener.' . $contextKey;
$container
->setDefinition($listenerId, new ChildDefinition('security.context_listener'))
->setClass(ApiContextListener::class)
->replaceArgument(2, $contextKey)
->replaceArgument(4, null); // Remove event dispatcher to prevent save session for stateless api.

Expand Down
13 changes: 12 additions & 1 deletion src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ class Configuration implements ConfigurationInterface
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder('packagist_web');
$treeBuilder = new TreeBuilder('packeton');
$rootNode = $treeBuilder->getRootNode();

$rootNode
->children()
->booleanNode('github_no_api')->end()
->scalarNode('rss_max_items')->defaultValue(40)->end()
->booleanNode('archive')
->defaultFalse()
Expand All @@ -36,6 +37,16 @@ public function getConfigTreeBuilder()
->end()
->end();

$rootNode
->validate()
->always(function ($values) {
if (($values['archive'] ?? false) && !isset($values['archive_options'])) {
throw new \InvalidArgumentException('archive_options is required if archive: true');
}

return $values;
})->end();

return $treeBuilder;
}
}
35 changes: 35 additions & 0 deletions src/DependencyInjection/PacketonExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace Packeton\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;

class PacketonExtension extends Extension
{
/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);

$container->setParameter('packagist_web.rss_max_items', $config['rss_max_items']);
if (true === $config['archive']) {
$container->setParameter('packeton_archive_opts', $config['archive_options'] ?? []);
}

$container->setParameter('packeton_github_no_api', $config['github_no_api'] ?? false);
}

/**
* @return string
*/
public function getAlias(): string
{
return 'packeton';
}
}
2 changes: 1 addition & 1 deletion src/DependencyInjection/Security/ApiHttpBasicFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function addConfiguration(NodeDefinition $builder)
/**
* {@inheritdoc}
*/
public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId)
public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId): string|array
{
$authenticatorId = 'packeton.security.authentication.' . $firewallName;

Expand Down
Loading

0 comments on commit 40176fd

Please sign in to comment.