docs: add inline documentation where missing
This commit is contained in:
@@ -4,6 +4,13 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace App\BusProNet\DataProcessor;
|
namespace App\BusProNet\DataProcessor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms raw pickup planning data into structured travel-indexed pickup information.
|
||||||
|
*
|
||||||
|
* Processes JSON payload from the CMS pickup planning endpoint, filtering for outbound
|
||||||
|
* trips (HIN direction) and grouping pickups by travel code. Each pickup includes city,
|
||||||
|
* location, and datetime, sorted chronologically per travel code.
|
||||||
|
*/
|
||||||
class PickupPlanningTransformer
|
class PickupPlanningTransformer
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\EventListener;
|
namespace App\EventListener;
|
||||||
|
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
@@ -9,6 +11,14 @@ use Symfony\Component\HttpKernel\Event\ExceptionEvent;
|
|||||||
use Symfony\Component\HttpKernel\KernelEvents;
|
use Symfony\Component\HttpKernel\KernelEvents;
|
||||||
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts AccessDeniedException to user-friendly flash messages.
|
||||||
|
*
|
||||||
|
* Logs access denials and adds appropriate flash messages: "Please log in" for
|
||||||
|
* anonymous users, or "Access denied" for authenticated users. Clears target
|
||||||
|
* path for authenticated denials to prevent redirect loops. OAuth2 routes are
|
||||||
|
* logged but allowed to pass through without modification.
|
||||||
|
*/
|
||||||
class AccessDeniedListener implements EventSubscriberInterface
|
class AccessDeniedListener implements EventSubscriberInterface
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\EventListener;
|
namespace App\EventListener;
|
||||||
|
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
@@ -13,6 +15,14 @@ use Symfony\Component\HttpFoundation\RequestStack;
|
|||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles OAuth2 authorization code grant flow.
|
||||||
|
*
|
||||||
|
* Automatically approves authorization requests for authenticated users without
|
||||||
|
* consent prompts. Redirects anonymous users to login. For external OAuth2
|
||||||
|
* requests (flagged via session), logs out the user after authorization to
|
||||||
|
* prevent session hijacking.
|
||||||
|
*/
|
||||||
#[AsEventListener(event: OAuth2Events::AUTHORIZATION_REQUEST_RESOLVE, method: 'onAuthorizationRequestResolve')]
|
#[AsEventListener(event: OAuth2Events::AUTHORIZATION_REQUEST_RESOLVE, method: 'onAuthorizationRequestResolve')]
|
||||||
class AuthorizationCodeListener
|
class AuthorizationCodeListener
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,6 +10,18 @@ use App\Form\Model\BookingDto;
|
|||||||
use App\Form\Service\Abstract\AbstractParticipantFieldHandler;
|
use App\Form\Service\Abstract\AbstractParticipantFieldHandler;
|
||||||
use App\Service\ServiceAvailabilityCalculator;
|
use App\Service\ServiceAvailabilityCalculator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles automatic replacement of discounted transportation based on booking rules.
|
||||||
|
*
|
||||||
|
* This virtual field handler enforces the business rule that discounted self-organized
|
||||||
|
* transportation (PKW with negative price) is only available when both outbound AND
|
||||||
|
* inbound travel use PKW. When inbound changes to BUS, the outbound PKW is automatically
|
||||||
|
* replaced with the regular (non-discounted) PKW variant.
|
||||||
|
*
|
||||||
|
* Conversely, when inbound changes back to PKW, this handler restores the discounted
|
||||||
|
* variant if availability permits. Baby participants (age <= 2) are excluded from
|
||||||
|
* discounted transportation restoration.
|
||||||
|
*/
|
||||||
class ParticipantTransportationDiscountReplacementFieldHandler extends AbstractParticipantFieldHandler
|
class ParticipantTransportationDiscountReplacementFieldHandler extends AbstractParticipantFieldHandler
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Logger;
|
namespace App\Logger;
|
||||||
|
|
||||||
use App\Entity\LogEntry;
|
use App\Entity\LogEntry;
|
||||||
@@ -7,6 +9,12 @@ use Doctrine\ORM\EntityManagerInterface;
|
|||||||
use Monolog\Handler\AbstractProcessingHandler;
|
use Monolog\Handler\AbstractProcessingHandler;
|
||||||
use Monolog\LogRecord;
|
use Monolog\LogRecord;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monolog handler that persists log entries to the database.
|
||||||
|
*
|
||||||
|
* Writes log records to the LogEntry entity, replacing message placeholders
|
||||||
|
* with context values. Includes channel, context, and extra data for auditing.
|
||||||
|
*/
|
||||||
class DatabaseHandler extends AbstractProcessingHandler
|
class DatabaseHandler extends AbstractProcessingHandler
|
||||||
{
|
{
|
||||||
public function __construct(private readonly EntityManagerInterface $entityManager)
|
public function __construct(private readonly EntityManagerInterface $entityManager)
|
||||||
|
|||||||
@@ -1,11 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Logger;
|
namespace App\Logger;
|
||||||
|
|
||||||
use Monolog\Attribute\AsMonologProcessor;
|
use Monolog\Attribute\AsMonologProcessor;
|
||||||
use Monolog\LogRecord;
|
use Monolog\LogRecord;
|
||||||
use Symfony\Component\HttpFoundation\RequestStack;
|
use Symfony\Component\HttpFoundation\RequestStack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enriches log records with HTTP request context.
|
||||||
|
*
|
||||||
|
* Adds the current request URI and method to the log record's extra data,
|
||||||
|
* enabling correlation of log entries with specific HTTP requests.
|
||||||
|
*/
|
||||||
#[AsMonologProcessor]
|
#[AsMonologProcessor]
|
||||||
class RequestInfoProcessor
|
class RequestInfoProcessor
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Logger;
|
namespace App\Logger;
|
||||||
|
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
@@ -8,6 +10,12 @@ use Monolog\LogRecord;
|
|||||||
use Symfony\Bundle\SecurityBundle\Security;
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
|
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enriches log records with current user information.
|
||||||
|
*
|
||||||
|
* Adds username and roles to log entries for audit trails. Handles CLI context
|
||||||
|
* (system user), anonymous requests, and user impersonation via SwitchUserToken.
|
||||||
|
*/
|
||||||
#[AsMonologProcessor]
|
#[AsMonologProcessor]
|
||||||
class UserDataProcessor
|
class UserDataProcessor
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Security;
|
namespace App\Security;
|
||||||
|
|
||||||
use App\BusProNet\ApiClient;
|
use App\BusProNet\ApiClient;
|
||||||
@@ -22,6 +24,13 @@ use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPasspor
|
|||||||
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
|
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
|
||||||
use Symfony\Component\Security\Http\Util\TargetPathTrait;
|
use Symfony\Component\Security\Http\Util\TargetPathTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticates users against the BPN API.
|
||||||
|
*
|
||||||
|
* Validates credentials via BPN's getPersonalData endpoint, creates or updates
|
||||||
|
* local User entities, and retrieves CRM attributes (roles, hotel codes) for
|
||||||
|
* authorization. Passwords are stored encrypted with RSA for subsequent API calls.
|
||||||
|
*/
|
||||||
class BpnAuthenticator extends AbstractLoginFormAuthenticator implements AuthenticationEntryPointInterface
|
class BpnAuthenticator extends AbstractLoginFormAuthenticator implements AuthenticationEntryPointInterface
|
||||||
{
|
{
|
||||||
use TargetPathTrait;
|
use TargetPathTrait;
|
||||||
|
|||||||
@@ -1,10 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Security;
|
namespace App\Security;
|
||||||
|
|
||||||
use Spatie\Crypto\Rsa\PrivateKey;
|
use Spatie\Crypto\Rsa\PrivateKey;
|
||||||
use Spatie\Crypto\Rsa\PublicKey;
|
use Spatie\Crypto\Rsa\PublicKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RSA encryption/decryption utilities for secure credential storage.
|
||||||
|
*
|
||||||
|
* Uses asymmetric encryption to store BPN API passwords securely. Private key
|
||||||
|
* encrypts data for storage, public key decrypts for API calls. Also provides
|
||||||
|
* signing/verification for message integrity.
|
||||||
|
*/
|
||||||
class Crypt
|
class Crypt
|
||||||
{
|
{
|
||||||
public function __construct(private readonly string $path)
|
public function __construct(private readonly string $path)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Security\Voter;
|
namespace App\Security\Voter;
|
||||||
|
|
||||||
use App\BusProNet\Model\Booking;
|
use App\BusProNet\Model\Booking;
|
||||||
@@ -7,6 +9,13 @@ use App\Entity\User;
|
|||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines access permissions for booking operations.
|
||||||
|
*
|
||||||
|
* Enforces ownership check via personId matching. VIEW access requires ownership,
|
||||||
|
* EDIT access additionally requires the booking to be in an editable state
|
||||||
|
* (determined by booking.isEditable()).
|
||||||
|
*/
|
||||||
class BookingVoter extends Voter
|
class BookingVoter extends Voter
|
||||||
{
|
{
|
||||||
public const VIEW = 'VIEW';
|
public const VIEW = 'VIEW';
|
||||||
|
|||||||
@@ -1,11 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Twig;
|
namespace App\Twig;
|
||||||
|
|
||||||
use Twig\Extension\AbstractExtension;
|
use Twig\Extension\AbstractExtension;
|
||||||
use Twig\TwigFilter;
|
use Twig\TwigFilter;
|
||||||
use Twig\TwigFunction;
|
use Twig\TwigFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Twig extension registering booking-related filters and functions.
|
||||||
|
*
|
||||||
|
* Provides filters for formatting (file_size, format_money, format_service_price)
|
||||||
|
* and mapping (map_gender, map_status, map_country, map_nationality), plus
|
||||||
|
* functions for field state checking and participant eligibility.
|
||||||
|
*/
|
||||||
class AppExtension extends AbstractExtension
|
class AppExtension extends AbstractExtension
|
||||||
{
|
{
|
||||||
public function getFilters(): array
|
public function getFilters(): array
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Twig;
|
namespace App\Twig;
|
||||||
|
|
||||||
use App\BusProNet\DataProvider\CountryDataProvider;
|
use App\BusProNet\DataProvider\CountryDataProvider;
|
||||||
@@ -14,6 +16,13 @@ use Twig\Environment;
|
|||||||
use Twig\Extension\RuntimeExtensionInterface;
|
use Twig\Extension\RuntimeExtensionInterface;
|
||||||
use Twig\Extra\Intl\IntlExtension;
|
use Twig\Extra\Intl\IntlExtension;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runtime implementation for AppExtension's filters and functions.
|
||||||
|
*
|
||||||
|
* Provides formatting utilities (money, file size, service prices), code-to-label
|
||||||
|
* mapping for display (gender, status, country), and field state introspection
|
||||||
|
* for conditional rendering in templates.
|
||||||
|
*/
|
||||||
class AppRuntime implements RuntimeExtensionInterface
|
class AppRuntime implements RuntimeExtensionInterface
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Validator\Constraints;
|
namespace App\Validator\Constraints;
|
||||||
|
|
||||||
use Symfony\Component\Validator\Constraint;
|
use Symfony\Component\Validator\Constraint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates participant data for cross-field consistency.
|
||||||
|
*
|
||||||
|
* Applied as a class-level constraint on ParticipantDto to enforce business rules
|
||||||
|
* that depend on multiple fields (e.g., requiring pickup when bus transport is selected).
|
||||||
|
*/
|
||||||
#[\Attribute]
|
#[\Attribute]
|
||||||
class Participant extends Constraint
|
class Participant extends Constraint
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,11 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Validator\Constraints;
|
namespace App\Validator\Constraints;
|
||||||
|
|
||||||
use App\Form\Model\ParticipantDto;
|
use App\Form\Model\ParticipantDto;
|
||||||
use Symfony\Component\Validator\Constraint;
|
use Symfony\Component\Validator\Constraint;
|
||||||
use Symfony\Component\Validator\ConstraintValidator;
|
use Symfony\Component\Validator\ConstraintValidator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates cross-field constraints on participant data.
|
||||||
|
*
|
||||||
|
* Enforces business rules that require examining multiple fields together,
|
||||||
|
* such as requiring a pickup location when bus transportation is selected.
|
||||||
|
*/
|
||||||
class ParticipantValidator extends ConstraintValidator
|
class ParticipantValidator extends ConstraintValidator
|
||||||
{
|
{
|
||||||
public function validate(mixed $value, Constraint $constraint): void
|
public function validate(mixed $value, Constraint $constraint): void
|
||||||
|
|||||||
@@ -11,6 +11,13 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
use Symfony\Component\Validator\ConstraintValidator;
|
use Symfony\Component\Validator\ConstraintValidator;
|
||||||
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates promotional voucher codes against the BPN API.
|
||||||
|
*
|
||||||
|
* Verifies that promo codes are valid for the current travel, checks minimum price
|
||||||
|
* thresholds, and validates code availability. Uses the participant's calculated
|
||||||
|
* total price (including room and all selected services) for threshold comparison.
|
||||||
|
*/
|
||||||
class PromoVoucherValidator extends ConstraintValidator
|
class PromoVoucherValidator extends ConstraintValidator
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
|||||||
@@ -10,6 +10,12 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
use Symfony\Component\Validator\ConstraintValidator;
|
use Symfony\Component\Validator\ConstraintValidator;
|
||||||
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates purchase voucher codes against the BPN API.
|
||||||
|
*
|
||||||
|
* Verifies that voucher codes exist and have remaining balance. Unlike promo
|
||||||
|
* vouchers, purchase vouchers do not require travel or price context validation.
|
||||||
|
*/
|
||||||
class PurchaseVoucherValidator extends ConstraintValidator
|
class PurchaseVoucherValidator extends ConstraintValidator
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
|||||||
@@ -6,6 +6,13 @@ namespace App\Validator\Constraints;
|
|||||||
|
|
||||||
use Symfony\Component\Validator\Constraint;
|
use Symfony\Component\Validator\Constraint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates room selection requirements for bookings.
|
||||||
|
*
|
||||||
|
* Applied as a class-level constraint on BookingDto to ensure valid room
|
||||||
|
* configurations: at least one room must be selected, and baby rooms
|
||||||
|
* cannot be booked without accompanying regular rooms.
|
||||||
|
*/
|
||||||
#[\Attribute]
|
#[\Attribute]
|
||||||
class RoomSelection extends Constraint
|
class RoomSelection extends Constraint
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,6 +10,12 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
use Symfony\Component\Validator\ConstraintValidator;
|
use Symfony\Component\Validator\ConstraintValidator;
|
||||||
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates room selection business rules for bookings.
|
||||||
|
*
|
||||||
|
* Enforces that at least one room is selected and that baby rooms (BABY code)
|
||||||
|
* are only booked in combination with regular rooms, not standalone.
|
||||||
|
*/
|
||||||
class RoomSelectionValidator extends ConstraintValidator
|
class RoomSelectionValidator extends ConstraintValidator
|
||||||
{
|
{
|
||||||
public function validate(mixed $value, Constraint $constraint): void
|
public function validate(mixed $value, Constraint $constraint): void
|
||||||
|
|||||||
Reference in New Issue
Block a user