diff --git a/app/V1Module/security/ACLModuleBuilder.php b/app/V1Module/security/ACLModuleBuilder.php index 2a5b4d42e..cbe943a69 100644 --- a/app/V1Module/security/ACLModuleBuilder.php +++ b/app/V1Module/security/ACLModuleBuilder.php @@ -3,7 +3,7 @@ namespace App\Security; use Nette\PhpGenerator\ClassType; -use Nette\PhpGenerator\PhpLiteral; +use Nette\PhpGenerator\Literal; use Nette\Utils\Strings; use ReflectionClass; use ReflectionMethod; @@ -72,7 +72,7 @@ public function build($interfaceName, $name, $uniqueId): ClassType 'return $this->check(?, ?);', [ $action, - new PhpLiteral("[" . implode(", ", $contextStrings) . "]") + new Literal("[" . implode(", ", $contextStrings) . "]") ] ); } diff --git a/app/V1Module/security/AuthorizatorBuilder.php b/app/V1Module/security/AuthorizatorBuilder.php index 690c65d64..f180291db 100644 --- a/app/V1Module/security/AuthorizatorBuilder.php +++ b/app/V1Module/security/AuthorizatorBuilder.php @@ -5,9 +5,7 @@ use LogicException; use Nette\PhpGenerator\ClassType; use Nette\PhpGenerator\Dumper; -use Nette\PhpGenerator\PhpLiteral; -use Nette\PhpGenerator\Helpers; -use Nette\Security\Permission; +use Nette\PhpGenerator\Literal; use Nette\Utils\Arrays; use ReflectionClass; use ReflectionException; @@ -48,7 +46,7 @@ public function build($aclInterfaces, array $permissions, $uniqueId): ClassType $allow = Arrays::get($rule, "allow", true); $role = Arrays::get($rule, "role", null); $resource = Arrays::get($rule, "resource", null); - $interface = $resource !== null ? new ReflectionClass(Arrays::get($aclInterfaces, $resource)) : null; + $interface = $resource !== null ? new ReflectionClass(Arrays::get($aclInterfaces, $resource) ?? '') : null; $actions = (array)Arrays::get($rule, "actions", []); $assertion = null; @@ -61,10 +59,10 @@ public function build($aclInterfaces, array $permissions, $uniqueId): ClassType $condition = $this->loadConditionClauses($conditions, $interface, $actions, $checkVariables); foreach ($checkVariables as $variableName => $variableValue) { - $assertion->addBody("? = ?;", [new PhpLiteral($variableName), new PhpLiteral($variableValue)]); + $assertion->addBody("? = ?;", [new Literal($variableName), new Literal($variableValue)]); } - $assertion->addBody("return ?;", [new PhpLiteral($condition)]); + $assertion->addBody("return ?;", [new Literal($condition)]); } $actionsString = '"' . implode('", "', $actions) . '"'; @@ -72,10 +70,10 @@ public function build($aclInterfaces, array $permissions, $uniqueId): ClassType $check->addBody( 'if (? && ? && ? && ?) {', [ - $role !== null ? new PhpLiteral(sprintf('$this->isInRole($role, "%s")', $role)) : true, - $resource !== null ? new PhpLiteral(sprintf('$resource === "%s"', $resource)) : true, - count($actions) > 0 ? new PhpLiteral(sprintf('in_array($privilege, [%s])', $actionsString)) : true, - $assertion !== null ? new PhpLiteral(sprintf('$this->%s()', $assertion->getName())) : true + $role !== null ? new Literal(sprintf('$this->isInRole($role, "%s")', $role)) : true, + $resource !== null ? new Literal(sprintf('$resource === "%s"', $resource)) : true, + count($actions) > 0 ? new Literal(sprintf('in_array($privilege, [%s])', $actionsString)) : true, + $assertion !== null ? new Literal(sprintf('$this->%s()', $assertion->getName())) : true ] ); $check->addBody('return ?;', [$allow]); @@ -108,7 +106,7 @@ private function loadConditionClauses($conditions, $interface, &$actions, array $checkVariable = "\$check_" . $this->checkCounter++; $checkValues[$checkVariable] = $this->dumper->format( '$this->policy->check(?, ?, $this->queriedIdentity)', - $conditionTarget ? new PhpLiteral(sprintf('$this->queriedContext["%s"]', $conditionTarget)) : null, + $conditionTarget ? new Literal(sprintf('$this->queriedContext["%s"]', $conditionTarget)) : null, $condition ); @@ -136,11 +134,11 @@ private function loadConditionClauses($conditions, $interface, &$actions, array } if ($type === "and") { - return $this->dumper->format("(?)", new PhpLiteral(join(" && ", $children))); - } elseif ($type === "or") { - return $this->dumper->format("(?)", new PhpLiteral(join(" || ", $children))); + return $this->dumper->format("(?)", new Literal(join(" && ", $children))); + } /* @phpstan-ignore identical.alwaysTrue */ elseif ($type === "or") { + return $this->dumper->format("(?)", new Literal(join(" || ", $children))); } else { - return new PhpLiteral("true"); + return new Literal("true"); } } diff --git a/app/V1Module/security/UserStorage.php b/app/V1Module/security/UserStorage.php index 6e546068c..89040ddc9 100644 --- a/app/V1Module/security/UserStorage.php +++ b/app/V1Module/security/UserStorage.php @@ -42,7 +42,7 @@ public function setExpiration(?string $expire, bool $clearIdentity): void /** * @inheritDoc */ - public function saveAuthentication(IIdentity $identity): void + public function saveAuthentication(?IIdentity $identity): void { if ($identity !== null && !($identity instanceof Identity)) { throw new InvalidArgumentException("Wrong identity class"); diff --git a/app/async/Notify.php b/app/async/Notify.php index 79a65c5f6..2d76135b4 100644 --- a/app/async/Notify.php +++ b/app/async/Notify.php @@ -21,6 +21,7 @@ public static function isAvailable(): bool { $requirements = ['inotify_init', 'inotify_add_watch', 'inotify_read', 'inotify_queue_len', 'stream_select']; foreach ($requirements as $reqFnc) { + // @phpstan-ignore-next-line if (!function_exists($reqFnc)) { return false; } @@ -31,6 +32,7 @@ public static function isAvailable(): bool /** * @var string|null path to the inotify file used to wake up the worker (null = no inotify) */ + // @phpstan-ignore property.unusedType private $inotifyFile = null; /** diff --git a/app/commands/AsyncJobsUpkeep.php b/app/commands/AsyncJobsUpkeep.php index 948840c69..da3119e6f 100644 --- a/app/commands/AsyncJobsUpkeep.php +++ b/app/commands/AsyncJobsUpkeep.php @@ -3,6 +3,7 @@ namespace App\Console; use App\Helpers\Notifications\AsyncJobsStuckEmailsSender; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -10,10 +11,12 @@ use Nette\Utils\Arrays; use DateTime; +#[AsCommand( + name: 'asyncJobs:upkeep', + description: 'Performs periodic upkeep for async jobs (cleanup, send warning emails)' +)] class AsyncJobsUpkeep extends Command { - protected static $defaultName = 'asyncJobs:upkeep'; - /** @var AsyncJobsStuckEmailsSender */ private $sender; @@ -46,13 +49,6 @@ public function __construct( $this->entityManager = $entityManager; } - protected function configure() - { - $this->setName(self::$defaultName)->setDescription( - 'Performs periodic upkeep for async jobs (cleanup, send warning emails)' - ); - } - /** * Delete all async jobs that match given clause and are passed given threshold. * @param string $additionalErrorClause raw SQL WHERE clause fragment @@ -110,7 +106,7 @@ protected function sendStuckNotifications() } } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $this->cleanupOldCompleted(); $this->sendStuckNotifications(); diff --git a/app/commands/DoctrineFixtures.php b/app/commands/DoctrineFixtures.php index 886d8bc0d..c5c994bd2 100644 --- a/app/commands/DoctrineFixtures.php +++ b/app/commands/DoctrineFixtures.php @@ -7,7 +7,9 @@ use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Id\AssignedGenerator; use Nette\Utils\Finder; +use Nette\Utils\FileInfo; use SplFileInfo; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -20,6 +22,7 @@ * in add/fixtures directory. Also, 'db:fill' command is registered to provide * convenient usage of this function. */ +#[AsCommand(name: 'db:fill', description: 'Clear the database and fill it with initial data.')] class DoctrineFixtures extends Command { protected static $defaultName = 'db:fill'; @@ -64,7 +67,6 @@ public function __construct( */ protected function configure() { - $this->setName('db:fill')->setDescription('Clear the database and fill it with initial data.'); $this->addOption( 'test', 't', @@ -81,7 +83,7 @@ protected function configure() * @param OutputInterface $output Console output for logging * @return int 0 on success, 1 on error */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $this->clearDatabase(); @@ -97,7 +99,7 @@ protected function execute(InputInterface $input, OutputInterface $output) foreach ($input->getArgument("groups") as $group) { $groupFiles = []; - /** @var SplFileInfo $file */ + /** @var FileInfo $file */ foreach ( Finder::findFiles("*.neon", "*.yml", "*.yaml", "*.json") ->in($fixtureDir . "/" . $group) as $file diff --git a/app/commands/ExportDatabase.php b/app/commands/ExportDatabase.php index 197e6e9d2..c22347f26 100644 --- a/app/commands/ExportDatabase.php +++ b/app/commands/ExportDatabase.php @@ -11,6 +11,7 @@ use App\Model\Repository\RuntimeEnvironments; use Nette\Neon\Neon; use Nette\Utils\FileSystem; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -20,10 +21,9 @@ * YAML file in fixtures/generated directory. Also, 'db:export' command is * registered to provide convenient usage of this function. */ +#[AsCommand(name: 'db:export', description: 'Export some of the data from database.')] class ExportDatabase extends Command { - protected static $defaultName = 'db:export'; - private const EXTENSION = ".neon"; private const PARAMETERS_KEY = "parameters"; @@ -59,21 +59,13 @@ public function __construct( $this->hardwareGroups = $hardwareGroups; } - /** - * Register the 'db:export' command in the framework - */ - protected function configure() - { - $this->setName('db:export')->setDescription('Export some of the data from database.'); - } - /** * Execute the database exporting. * @param InputInterface $input Console input, not used * @param OutputInterface $output Console output for logging * @return int 0 on success, 1 on error */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $fixtureDir = __DIR__ . '/../../fixtures/generated/'; FileSystem::createDir($fixtureDir); diff --git a/app/commands/GeneralStatsNotification.php b/app/commands/GeneralStatsNotification.php index 2088614c2..e6cef6d15 100644 --- a/app/commands/GeneralStatsNotification.php +++ b/app/commands/GeneralStatsNotification.php @@ -4,14 +4,17 @@ use App\Helpers\Notifications\GeneralStatsEmailsSender; use App\Helpers\GeneralStatsHelper; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +#[AsCommand( + name: 'notifications:general-stats', + description: 'Send notifications with general statistics overview for the administrator.' +)] class GeneralStatsNotification extends Command { - protected static $defaultName = 'notifications:general-stats'; - /** @var GeneralStatsEmailsSender */ private $emailSender; @@ -25,14 +28,7 @@ public function __construct(GeneralStatsEmailsSender $emailSender, GeneralStatsH $this->generalStats = $generalStats; } - protected function configure() - { - $this->setName('notifications:general-stats')->setDescription( - 'Send notifications with general statistics overview for the administrator.' - ); - } - - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $this->emailSender->send($this->generalStats); return 0; diff --git a/app/commands/GenerateSwagger.php b/app/commands/GenerateSwagger.php index 348d3f82e..257134e41 100644 --- a/app/commands/GenerateSwagger.php +++ b/app/commands/GenerateSwagger.php @@ -2,6 +2,7 @@ namespace App\Console; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -10,19 +11,14 @@ /** * Command that consumes a temporary file containing endpoint annotations and generates a swagger documentation. */ +#[AsCommand( + name: 'swagger:generate', + description: 'Generate an OpenAPI documentation from the temporary file created by the swagger:annotate command. ' + . 'The temporary file is deleted afterwards.' +)] class GenerateSwagger extends Command { - protected static $defaultName = 'swagger:generate'; - - protected function configure() - { - $this->setName(self::$defaultName)->setDescription( - 'Generate an OpenAPI documentation from the temporary file created by the swagger:annotate command.' - . ' The temporary file is deleted afterwards.' - ); - } - - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $path = __DIR__ . '/../V1Module/presenters/_autogenerated_annotations_temp.php'; diff --git a/app/commands/MetaConverter.php b/app/commands/MetaConverter.php index 3f16326cc..cad0685a1 100644 --- a/app/commands/MetaConverter.php +++ b/app/commands/MetaConverter.php @@ -3,6 +3,7 @@ namespace App\Console; use App\Helpers\MetaFormats\AnnotationConversion\AnnotationToAttributeConverter; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -12,18 +13,10 @@ * parameter annotations are converted into attributes. * The new folder is named 'presenters2'. */ +#[AsCommand(name: 'meta:convert', description: 'Convert endpoint parameter annotations to attributes.')] class MetaConverter extends Command { - protected static $defaultName = 'meta:convert'; - - protected function configure() - { - $this->setName(self::$defaultName)->setDescription( - 'Convert endpoint parameter annotations to attributes..' - ); - } - - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $this->generatePresenters(); return Command::SUCCESS; diff --git a/app/commands/PlagiarismDetectionAccessToken.php b/app/commands/PlagiarismDetectionAccessToken.php index 2522ecc5a..f16a64a88 100644 --- a/app/commands/PlagiarismDetectionAccessToken.php +++ b/app/commands/PlagiarismDetectionAccessToken.php @@ -6,6 +6,7 @@ use App\Security\AccessManager; use App\Security\TokenScope; use App\Security\Roles; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -18,10 +19,12 @@ * A console command that generates token restricted for plagiarism detection tools. * This token can be used to create plagiarism detection batches and upload their data regarding detected similarities. */ +#[AsCommand( + name: 'plagiarism:create-access-token', + description: 'Generate token restricted for plagiarism scope (for 3rd party tools).' +)] class PlagiarismDetectionAccessToken extends Command { - protected static $defaultName = 'plagiarism:create-access-token'; - /** @var AccessManager */ public $accessManager; @@ -37,8 +40,6 @@ public function __construct(AccessManager $accessManager, Users $users) protected function configure() { - $this->setName(self::$defaultName) - ->setDescription('Generate token restricted for plagiarism scope (for 3rd party tools).'); $this->addArgument('userId', InputArgument::REQUIRED, 'ID of the admin owning the token.'); $this->addOption( 'expiration', @@ -49,7 +50,7 @@ protected function configure() ); } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { // get user by given ID $userId = $input->getArgument('userId'); diff --git a/app/commands/RemoveInactiveUsers.php b/app/commands/RemoveInactiveUsers.php index 8935fe7a2..d6f4517e5 100644 --- a/app/commands/RemoveInactiveUsers.php +++ b/app/commands/RemoveInactiveUsers.php @@ -6,6 +6,7 @@ use App\Helpers\AnonymizationHelper; use DateTime; use DateInterval; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -17,10 +18,9 @@ * A console command that removes inactive users. * A user is inactive if no authentication (nor token renewal) is recorded for given period of time. */ +#[AsCommand(name: 'users:remove-inactive', description: 'Remove inactive users from the database.')] class RemoveInactiveUsers extends Command { - protected static $defaultName = 'users:remove-inactive'; - /** @var DateTime|null */ private $disableThreshold = null; @@ -66,7 +66,6 @@ public function __construct(array $config, Users $users, AnonymizationHelper $an protected function configure() { - $this->setName('users:remove-inactive')->setDescription('Remove users who has not been active for some time.'); $this->addOption( 'report', null, @@ -82,7 +81,7 @@ protected function configure() ); } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $report = $input->getOption('report'); $silent = !$report && $input->getOption('silent'); diff --git a/app/commands/SendAssignmentDeadlineNotification.php b/app/commands/SendAssignmentDeadlineNotification.php index c98e70356..e05864cce 100644 --- a/app/commands/SendAssignmentDeadlineNotification.php +++ b/app/commands/SendAssignmentDeadlineNotification.php @@ -5,16 +5,18 @@ use App\Helpers\Notifications\AssignmentEmailsSender; use App\Model\Repository\Assignments; use App\Model\Repository\ShadowAssignments; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use DateTime; +#[AsCommand( + name: 'notifications:assignment-deadlines', + description: 'Send notifications for assignments with imminent deadlines.' +)] class SendAssignmentDeadlineNotification extends Command { - protected static $defaultName = 'notifications:assignment-deadlines'; - /** @var AssignmentEmailsSender */ private $sender; @@ -45,14 +47,7 @@ public function __construct( $this->thresholdTo = $thresholdTo; } - protected function configure() - { - $this->setName(self::$defaultName)->setDescription( - 'Send notifications for assignments with imminent deadlines.' - ); - } - - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $from = new DateTime(); if ($this->thresholdFrom) { diff --git a/app/commands/SendPendingReviewsNotification.php b/app/commands/SendPendingReviewsNotification.php index 7e612f9a6..1cfbbccb9 100644 --- a/app/commands/SendPendingReviewsNotification.php +++ b/app/commands/SendPendingReviewsNotification.php @@ -5,15 +5,18 @@ use App\Helpers\Notifications\ReviewsEmailsSender; use App\Model\Repository\AssignmentSolutions; use App\Model\Entity\Group; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use DateTime; +#[AsCommand( + name: 'notifications:pending-reviews', + description: 'Send notifications for pending (not closed) code reviews to group admins.' +)] class SendPendingReviewsNotification extends Command { - protected static $defaultName = 'notifications:pending-reviews'; - /** @var ReviewsEmailsSender */ private $sender; @@ -34,13 +37,6 @@ public function __construct( $this->assignmentSolutions = $assignmentSolutions; } - protected function configure() - { - $this->setName(self::$defaultName)->setDescription( - 'Send notifications for pending (not closed) code reviews to group admins.' - ); - } - private $groupAdminsCache = []; private function getGroupAdmins(Group $group): array @@ -55,7 +51,7 @@ private function getGroupAdmins(Group $group): array return $this->groupAdminsCache[$group->getId()]; } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $threshold = new DateTime(); if ($this->threshold) { diff --git a/app/commands/SwaggerAnnotator.php b/app/commands/SwaggerAnnotator.php index ce6cd2d17..45e551f3f 100644 --- a/app/commands/SwaggerAnnotator.php +++ b/app/commands/SwaggerAnnotator.php @@ -4,6 +4,7 @@ use App\Helpers\Swagger\TempAnnotationFileBuilder; use App\Helpers\Swagger\AnnotationHelper; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -14,20 +15,15 @@ * The command uses the RouterFactory to find all endpoints. * The temporary file is consumed by the swagger:generate command. */ +#[AsCommand( + name: 'swagger:annotate', + description: 'Extracts endpoint method annotations and puts them into a temporary file' + . ' that can be used to generate an OpenAPI documentation.' +)] class SwaggerAnnotator extends Command { - protected static $defaultName = 'swagger:annotate'; private static $autogeneratedAnnotationFilePath = 'app/V1Module/presenters/_autogenerated_annotations_temp.php'; - protected function configure(): void - { - $filePath = self::$autogeneratedAnnotationFilePath; - $this->setName(self::$defaultName)->setDescription( - "Extracts endpoint method annotations and puts them into a temporary file that can be used to generate" - . " an OpenAPI documentation. The file is located at {$filePath}" - ); - } - protected function execute(InputInterface $input, OutputInterface $output): int { try { diff --git a/app/commands/cleanup/CleanupExerciseConfigs.php b/app/commands/cleanup/CleanupExerciseConfigs.php index 0131e8efb..438837903 100644 --- a/app/commands/cleanup/CleanupExerciseConfigs.php +++ b/app/commands/cleanup/CleanupExerciseConfigs.php @@ -7,6 +7,7 @@ use Exception; use Doctrine\DBAL\ArrayParameterType; use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -15,10 +16,12 @@ * A console command that removes exercise configs (all of them including limits) that are not associated with any * exercise or assignment and were created before more than a given amount of days */ +#[AsCommand( + name: 'db:cleanup:exercise-configs', + description: 'Remove unused exercise configs (all of them including limits) that are older than 14 days.' +)] class CleanupExerciseConfigs extends Command { - protected static $defaultName = 'db:cleanup:exercise-configs'; - /** @var Exercises */ private $exercises; @@ -32,13 +35,6 @@ public function __construct(Exercises $exercises, EntityManagerInterface $entity $this->entityManager = $entityManager; } - protected function configure() - { - $this->setName('db:cleanup:exercise-configs')->setDescription( - 'Remove unused exercise configs (all of them including limits) that are older than 14 days.' - ); - } - /** * Delete environment configs and return number of deleted entities. * @param DateTime $limit @@ -159,7 +155,7 @@ protected function executeUnsafe(DateTime $limit, OutputInterface $output) $output->writeln(join(' ', $report)); } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $limit = new DateTime(); $limit->modify("-14 days"); diff --git a/app/commands/cleanup/CleanupExerciseFiles.php b/app/commands/cleanup/CleanupExerciseFiles.php index 513fd365e..d4db32a3a 100644 --- a/app/commands/cleanup/CleanupExerciseFiles.php +++ b/app/commands/cleanup/CleanupExerciseFiles.php @@ -6,15 +6,19 @@ use App\Helpers\FileStorage\FileStorageException; use App\Model\Repository\SupplementaryExerciseFiles; use App\Model\Repository\AttachmentFiles; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Tracy\ILogger; +#[AsCommand( + name: 'db:cleanup:exercise-files', + description: 'Remove unused supplementary and attachment files ' + . '(only DB records are removed in case of supplementary files).' +)] class CleanupExercisesFiles extends Command { - protected static $defaultName = 'db:cleanup:exercise-files'; - /** * @var SupplementaryExerciseFiles */ @@ -49,13 +53,6 @@ public function __construct( $this->fileStorage = $fileStorage; } - protected function configure() - { - $this->setName('db:cleanup:exercise-files') - ->setDescription('Remove unused supplementary and attachment files " - . "(only DB records are removed in case of supplementary files).'); - } - private function removeUnusedSupplementaryFiles(OutputInterface $output) { $unused = $this->supplementaryFiles->findUnused(); diff --git a/app/commands/cleanup/CleanupLocalizedTexts.php b/app/commands/cleanup/CleanupLocalizedTexts.php index b6e65dfa8..ae3a10e7e 100644 --- a/app/commands/cleanup/CleanupLocalizedTexts.php +++ b/app/commands/cleanup/CleanupLocalizedTexts.php @@ -9,6 +9,7 @@ use DateTime; use Doctrine\DBAL\ArrayParameterType; use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -17,10 +18,12 @@ * A console command that removes localized texts that are not associated with any entity and were created before more * than a given amount of days */ +#[AsCommand( + name: 'db:cleanup:localized-texts', + description: 'Remove unused localized texts that are older than 14 days.' +)] class CleanupLocalizedTexts extends Command { - protected static $defaultName = 'db:cleanup:localized-texts'; - /** @var Exercises */ private $exercises; @@ -38,14 +41,7 @@ public function __construct(Exercises $exercises, Assignments $assignments, Enti $this->entityManager = $entityManager; } - protected function configure() - { - $this->setName('db:cleanup:localized-texts')->setDescription( - 'Remove unused localized texts that are older than 14 days.' - ); - } - - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $now = new DateTime(); $deleted = 0; diff --git a/app/commands/cleanup/CleanupPipelineConfigs.php b/app/commands/cleanup/CleanupPipelineConfigs.php index 4fd133077..d1946efed 100644 --- a/app/commands/cleanup/CleanupPipelineConfigs.php +++ b/app/commands/cleanup/CleanupPipelineConfigs.php @@ -7,6 +7,7 @@ use DateTime; use Doctrine\DBAL\ArrayParameterType; use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -15,10 +16,12 @@ * A console command that removes pipeline configurations that are not associated with any pipeline and were created * before more than a given amount of days */ +#[AsCommand( + name: 'db:cleanup:pipeline-configs', + description: 'Remove unused pipeline configs that are older than 14 days.' +)] class CleanupPipelineConfigs extends Command { - protected static $defaultName = 'db:cleanup:pipeline-configs'; - /** @var Pipelines */ private $pipelines; @@ -32,14 +35,7 @@ public function __construct(Pipelines $pipelines, EntityManagerInterface $entity $this->entityManager = $entityManager; } - protected function configure() - { - $this->setName('db:cleanup:pipeline-configs')->setDescription( - 'Remove unused pipeline configs that are older than 14 days.' - ); - } - - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $now = new DateTime(); $deleted = 0; diff --git a/app/commands/cleanup/CleanupUploads.php b/app/commands/cleanup/CleanupUploads.php index 7a75705cb..c6ff86731 100644 --- a/app/commands/cleanup/CleanupUploads.php +++ b/app/commands/cleanup/CleanupUploads.php @@ -8,16 +8,16 @@ use App\Model\Repository\BaseRepository; use App\Model\Repository\UploadedFiles; use App\Model\Repository\UploadedPartialFiles; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Tracy\ILogger; use DateTime; +#[AsCommand(name: 'db:cleanup:uploads', description: 'Remove unused uploaded files and corresponding DB records.')] class CleanupUploads extends Command { - protected static $defaultName = 'db:cleanup:uploads'; - /** * @var UploadsConfig */ @@ -59,12 +59,6 @@ public function __construct( $this->fileStorage = $fileStorage; } - protected function configure() - { - $this->setName('db:cleanup:uploads') - ->setDescription('Remove unused uploaded files and corresponding DB records.'); - } - /** * Wrapper function for deleting a list of files, computing basic stats, and printing out job results. * @param array $files list of files to be deleted @@ -110,7 +104,7 @@ protected function removeOldFiles( } } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $now = new DateTime(); $threshold = $this->uploadsConfig->getRemovalThreshold(); diff --git a/app/commands/cleanup/CleanupWorkerTmpFiles.php b/app/commands/cleanup/CleanupWorkerTmpFiles.php index 775031079..4d6d60b5e 100644 --- a/app/commands/cleanup/CleanupWorkerTmpFiles.php +++ b/app/commands/cleanup/CleanupWorkerTmpFiles.php @@ -5,14 +5,17 @@ use App\Helpers\WorkerFilesConfig; use App\Helpers\FileStorageManager; use DateTime; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +#[AsCommand( + name: 'db:cleanup:worker', + description: 'Remove old worker files (tmp solution archives and lingering results archives).' +)] class CleanupWorkerTmpFiles extends Command { - protected static $defaultName = 'fs:cleanup:worker'; - /** * @var FileStorageManager */ @@ -30,13 +33,7 @@ public function __construct(FileStorageManager $fileStorage, WorkerFilesConfig $ $this->workerFilesConfig = $config; } - protected function configure() - { - $this->setName('fs:cleanup:worker') - ->setDescription('Remove old worker files (tmp solution archives and lingering results archives).'); - } - - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $thresholdDate = new DateTime(); $thresholdDate->modify("-" . $this->workerFilesConfig->getRemovalThreshold()); diff --git a/app/commands/runtimes/FixConfigVariables.php b/app/commands/runtimes/FixConfigVariables.php index b7ebf1550..a7a0266aa 100644 --- a/app/commands/runtimes/FixConfigVariables.php +++ b/app/commands/runtimes/FixConfigVariables.php @@ -5,13 +5,12 @@ use App\Model\Repository\RuntimeEnvironments; use App\Model\Repository\Pipelines; use App\Model\Repository\ExerciseConfigs; -use App\Model\Entity\Pipeline; use App\Model\Entity\RuntimeEnvironment; use App\Helpers\ExerciseConfig\Helper; use App\Helpers\ExerciseConfig\Loader; -use App\Helpers\ExerciseConfig\Variable; use App\Helpers\ExerciseConfig\VariablesTable; use Exception; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; @@ -19,10 +18,14 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\ConsoleOutputInterface; +#[AsCommand( + name: 'runtimes:fix-config-variables', + description: 'Scan exercise configs of given runtime environment and attempt to fix the variables. ' . + 'The variables lists are extracted from pipelines, new variables are added (with defaults), ' . + 'unidentified variables are removed.' +)] class FixConfigVariables extends BaseCommand { - protected static $defaultName = 'runtimes:fixConfigVariables'; - /** @var bool */ private $silent = false; @@ -66,28 +69,21 @@ public function __construct( protected function configure() { - $this->setName(self::$defaultName)->setDescription( - 'Scan exercise configs of given runtime environment and attempt to fix the variables. ' . - 'The variables lists are extracted from pipelines, new variables are added (with defaults), ' . - 'unidentified variables are removed.' - ) - ->addArgument( - 'runtime', - InputArgument::REQUIRED, - 'Identifier of the runtime environment of which the exercises will be updated.' - ) - ->addOption( - 'yes', - 'y', - InputOption::VALUE_NONE, - "Assume 'yes' to all inquiries (run in non-interactive mode)" - ) - ->addOption( - 'silent', - 's', - InputOption::VALUE_NONE, - "Silent mode (no outputs except for errors)" - ); + $this->addArgument( + 'runtime', + InputArgument::REQUIRED, + 'Identifier of the runtime environment of which the exercises will be updated.' + )->addOption( + 'yes', + 'y', + InputOption::VALUE_NONE, + "Assume 'yes' to all inquiries (run in non-interactive mode)" + )->addOption( + 'silent', + 's', + InputOption::VALUE_NONE, + "Silent mode (no outputs except for errors)" + ); } private function writeln(...$lines): void @@ -300,7 +296,7 @@ private function fixTestsPipelines(array &$tests, string $runtimeId, array $expe * Finally, the main function of command! */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { // just to save time (we do not have to pass this down to every other method invoked) $this->input = $input; diff --git a/app/commands/runtimes/FixExerciseConfigs.php b/app/commands/runtimes/FixExerciseConfigs.php index 192adb00c..4ec18fa61 100644 --- a/app/commands/runtimes/FixExerciseConfigs.php +++ b/app/commands/runtimes/FixExerciseConfigs.php @@ -7,6 +7,7 @@ use App\Model\Repository\ExerciseConfigs; use App\Model\Entity\Pipeline; use Exception; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; @@ -14,10 +15,13 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\ConsoleOutputInterface; +#[AsCommand( + name: 'runtimes:fix-exercise-configs', + description: 'Scan exercise configs of given runtime environment and attempts to fix them. ' . + 'This feature may be used when runtime was updated and some of its pipelines replaced.' +)] class FixExerciseConfigs extends BaseCommand { - protected static $defaultName = 'runtimes:fixExerciseConfigs'; - /** @var bool */ private $silent = false; @@ -51,27 +55,21 @@ public function __construct( protected function configure() { - $this->setName(self::$defaultName)->setDescription( - 'Scan exercise configs of given runtime environment and attempts to fix them. ' . - 'This feature may be used when runtime was updated and some of its pipelines replaced.' - ) - ->addArgument( - 'runtime', - InputArgument::REQUIRED, - 'Identifier of the runtime environment of which the exercises will be updated.' - ) - ->addOption( - 'yes', - 'y', - InputOption::VALUE_NONE, - "Assume 'yes' to all inquiries (run in non-interactive mode)" - ) - ->addOption( - 'silent', - 's', - InputOption::VALUE_NONE, - "Silent mode (no outputs except for errors)" - ); + $this->addArgument( + 'runtime', + InputArgument::REQUIRED, + 'Identifier of the runtime environment of which the exercises will be updated.' + )->addOption( + 'yes', + 'y', + InputOption::VALUE_NONE, + "Assume 'yes' to all inquiries (run in non-interactive mode)" + )->addOption( + 'silent', + 's', + InputOption::VALUE_NONE, + "Silent mode (no outputs except for errors)" + ); } private function writeln(...$lines): void @@ -201,7 +199,7 @@ private function fixTestsPipelines(array &$tests, string $runtimeId) * Finally, the main function of command! */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { // just to save time (we do not have to pass this down to every other method invoked) $this->input = $input; diff --git a/app/commands/runtimes/RuntimeExport.php b/app/commands/runtimes/RuntimeExport.php index 5b6fc4768..00f29b119 100644 --- a/app/commands/runtimes/RuntimeExport.php +++ b/app/commands/runtimes/RuntimeExport.php @@ -9,16 +9,16 @@ use ZipArchive; use Exception; use RuntimeException; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\ConsoleOutputInterface; +#[AsCommand(name: 'runtimes:export', description: 'Export runtime environment and its pipelines into a ZIP package.')] class RuntimeExport extends Command { - protected static $defaultName = 'runtimes:export'; - /** @var RuntimeEnvironments */ private $runtimeEnvironments; @@ -42,9 +42,7 @@ public function __construct( protected function configure() { - $this->setName(self::$defaultName)->setDescription( - 'Export runtime environment and its pipelines into a ZIP package.' - )->addArgument('runtime', InputArgument::REQUIRED, 'ID of the runtime environment to be exported.') + $this->addArgument('runtime', InputArgument::REQUIRED, 'ID of the runtime environment to be exported.') ->addArgument('saveAs', InputArgument::REQUIRED, 'Path to the output ZIP archive.'); } @@ -82,7 +80,7 @@ protected static function addJsonFile(ZipArchive $zip, string $entry, $json) } } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $stderr = $output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output; diff --git a/app/commands/runtimes/RuntimeImport.php b/app/commands/runtimes/RuntimeImport.php index b6495ef30..cafbee1cd 100644 --- a/app/commands/runtimes/RuntimeImport.php +++ b/app/commands/runtimes/RuntimeImport.php @@ -17,6 +17,7 @@ use DateTime; use Exception; use RuntimeException; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; @@ -24,10 +25,9 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\ConsoleOutputInterface; +#[AsCommand(name: 'runtimes:import', description: 'Import runtime environment and its pipelines from a ZIP package.')] class RuntimeImport extends BaseCommand { - protected static $defaultName = 'runtimes:import'; - /** @var bool */ private $silent = false; @@ -75,26 +75,21 @@ public function __construct( protected function configure() { - $this->setName(self::$defaultName)->setDescription( - 'Import runtime environment and its pipelines from a ZIP package.' - ) - ->addArgument( - 'zipFile', - InputArgument::REQUIRED, - 'Path to the ZIP package from which the data will be loaded.' - ) - ->addOption( - 'yes', - 'y', - InputOption::VALUE_NONE, - "Assume 'yes' to all inquiries (run in non-interactive mode)" - ) - ->addOption( - 'silent', - 's', - InputOption::VALUE_NONE, - "Silent mode (no outputs except for errors)" - ); + $this->addArgument( + 'zipFile', + InputArgument::REQUIRED, + 'Path to the ZIP package from which the data will be loaded.' + )->addOption( + 'yes', + 'y', + InputOption::VALUE_NONE, + "Assume 'yes' to all inquiries (run in non-interactive mode)" + )->addOption( + 'silent', + 's', + InputOption::VALUE_NONE, + "Silent mode (no outputs except for errors)" + ); } /* @@ -477,7 +472,7 @@ protected function updatePipelineSupplementaryFiles(ZipArchive $zip, array $data * Finally, the main function of command! */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { // just to save time (we do not have to pass this down to every other method invoked) $this->input = $input; diff --git a/app/commands/security/ListExamEvents.php b/app/commands/security/ListExamEvents.php index 8e5f0943e..8cd7ad98d 100644 --- a/app/commands/security/ListExamEvents.php +++ b/app/commands/security/ListExamEvents.php @@ -5,6 +5,7 @@ use App\Model\Entity\GroupExamLock; use App\Model\Repository\GroupExamLocks; use Exception; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -14,10 +15,9 @@ * Lists all group exam lock records that occurred in given time interval. * Locks are listed with related data in CSV format on the stdout. */ +#[AsCommand(name: 'sec:exam-events', description: 'List all exam events in given date/time interval in CSV format.')] class ListExamEvents extends BaseCommand { - protected static $defaultName = 'sec:examEvents'; - protected static $csvDelimiter = ','; protected static $csvColumns = [ 'id', @@ -47,8 +47,6 @@ public function __construct(GroupExamLocks $examLocks) protected function configure() { - $this->setName(self::$defaultName) - ->setDescription('List all exam events in given date/time interval in CSV format.'); $this->addOption( 'from', null, @@ -107,7 +105,7 @@ protected function printCsvLine(array $data) fputcsv($fp, $line, self::$csvDelimiter); } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { // just to save time (we do not have to pass this down to every other method invoked) $this->input = $input; diff --git a/app/commands/security/ListSecurityEvents.php b/app/commands/security/ListSecurityEvents.php index 07e2a8c4d..c98738b93 100644 --- a/app/commands/security/ListSecurityEvents.php +++ b/app/commands/security/ListSecurityEvents.php @@ -5,6 +5,7 @@ use App\Model\Entity\SecurityEvent; use App\Model\Repository\SecurityEvents; use Exception; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -14,10 +15,12 @@ * List security events (login, token refresh, ...) from given time interval. * Events are printed to stdout in CSV format. */ +#[AsCommand( + name: 'sec:security-events', + description: 'List all security events in given date/time interval in CSV format.' +)] class ListSecurityEvents extends BaseCommand { - protected static $defaultName = 'sec:securityEvents'; - protected static $csvDelimiter = ','; protected static $csvColumns = [ 'id', @@ -43,8 +46,6 @@ public function __construct(SecurityEvents $events) protected function configure() { - $this->setName(self::$defaultName) - ->setDescription('List all security events in given date/time interval in CSV format.'); $this->addOption( 'from', null, @@ -99,7 +100,7 @@ protected function printCsvLine(array $data) fputcsv($fp, $line, self::$csvDelimiter); } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { // just to save time (we do not have to pass this down to every other method invoked) $this->input = $input; diff --git a/app/config/config.neon b/app/config/config.neon index 571fd0706..95f141d1e 100644 --- a/app/config/config.neon +++ b/app/config/config.neon @@ -526,8 +526,8 @@ nettrine.extensions.atlantic18: nettrine.migrations: table: doctrine_migrations # database table for applied migrations column: version # database column for applied migrations - directory: %appDir%/../migrations # directory, where all migrations are stored - namespace: Migrations # namespace of migration classes + directories: + Migrations: %appDir%/../migrations # directory, where all migrations are stored fixtures: locale: "en_US" diff --git a/app/helpers/ExerciseConfig/Compilation/VariablesResolver.php b/app/helpers/ExerciseConfig/Compilation/VariablesResolver.php index 232cbe70e..5e6fd7e4d 100644 --- a/app/helpers/ExerciseConfig/Compilation/VariablesResolver.php +++ b/app/helpers/ExerciseConfig/Compilation/VariablesResolver.php @@ -21,7 +21,6 @@ */ class VariablesResolver { - /** * Variables defined in exercise config or environment config can contain * references, these references are resolved against user submitted variable @@ -310,13 +309,11 @@ private function resolveForVariable( // check if the ports was processed and processed correctly if ($inPort->getVariableValue() !== null) { return; // this port was already processed - } else { - if ($inPort->getVariableValue() === null && $outPort && $outPort->getVariableValue() !== null) { - // only input value is assigned... this means it was process before with - // some other child, so just assign value and return - $inPort->setVariableValue($outPort->getVariableValue()); - return; - } + } elseif ($outPort && $outPort->getVariableValue() !== null) { + // only input value is assigned... this means it was process before with + // some other child, so just assign value and return + $inPort->setVariableValue($outPort->getVariableValue()); + return; } $variableName = $inPort->getVariable(); diff --git a/app/helpers/ExerciseConfig/ExerciseConfigChecker.php b/app/helpers/ExerciseConfig/ExerciseConfigChecker.php index 3ea3fa146..4de058027 100644 --- a/app/helpers/ExerciseConfig/ExerciseConfigChecker.php +++ b/app/helpers/ExerciseConfig/ExerciseConfigChecker.php @@ -165,7 +165,7 @@ private function validateLimits(Exercise $exercise): bool */ private function validateEnvironmentConfigurations(Exercise $exercise): bool { - /** @var RuntimeEnvironment $environment */ + /** @var RuntimeEnvironment|null $environment */ $environment = null; try { foreach ($exercise->getRuntimeEnvironments() as $environment) { @@ -243,7 +243,7 @@ public function check(Exercise $exercise) ) { $errors[] = "@score The score configuration is invalid"; } - + if ($errors) { $exercise->setBroken(implode("\n", $errors)); return; diff --git a/app/helpers/Swagger/AnnotationHelper.php b/app/helpers/Swagger/AnnotationHelper.php index 7f9d6cc46..f3c8066b7 100644 --- a/app/helpers/Swagger/AnnotationHelper.php +++ b/app/helpers/Swagger/AnnotationHelper.php @@ -109,7 +109,7 @@ private static function getSwaggerType(string $annotationType): string // if the type is not specified, default to a string $type = 'string'; $typename = $annotationType; - if ($typename !== null) { + if ($typename) { if (self::isDatatypeNullable($annotationType)) { $typename = substr($typename, 0, -strlen(self::$nullableSuffix)); } diff --git a/app/helpers/Wildcards.php b/app/helpers/Wildcards.php index 0eb8bd8b3..bf34f3516 100644 --- a/app/helpers/Wildcards.php +++ b/app/helpers/Wildcards.php @@ -44,6 +44,7 @@ public static function expandPattern($pattern) $start = strpos($pattern, "{", $offset); if ($start === false) { + // @phpstan-ignore identical.alwaysTrue if ($offset === 0) { yield $pattern; } @@ -59,7 +60,8 @@ public static function expandPattern($pattern) $counter -= 1; if ($counter === 0) { - $end = $offset = $i; + $end = $i; + $offset = $i; $head = substr($pattern, 0, $start); $tail = substr($pattern, $end + 1); $subPatterns = static::splitPattern(substr($pattern, $start + 1, $end - $start - 1)); diff --git a/app/helpers/ZenifyFixtures/Alice/AliceLoader.php b/app/helpers/ZenifyFixtures/Alice/AliceLoader.php index d00daf838..b21f4c87c 100644 --- a/app/helpers/ZenifyFixtures/Alice/AliceLoader.php +++ b/app/helpers/ZenifyFixtures/Alice/AliceLoader.php @@ -12,7 +12,7 @@ use App\Helpers\ZenifyFixtures\Alice\CustomNativeLoader; use Doctrine\ORM\EntityManagerInterface; use Nette\Utils\Finder; -use SplFileInfo; +use Nette\Utils\FileInfo; use Zenify\DoctrineFixtures\Contract\Alice\AliceLoaderInterface; use Zenify\DoctrineFixtures\Exception\MissingSourceException; @@ -79,7 +79,7 @@ private function getFilesFromDirectory(string $path): array { $files = []; foreach (Finder::find('*.neon', '*.yaml', '*.yml')->from($path) as $file) { - /** @var SplFileInfo $file */ + /** @var FileInfo $file */ $files[] = $file->getPathname(); } return $files; diff --git a/build-adminer b/build-adminer new file mode 100755 index 000000000..426f36664 --- /dev/null +++ b/build-adminer @@ -0,0 +1,14 @@ +#!/bin/bash + +if [ ! -d vendor/vrana/adminer ]; then + echo "Please run 'composer install' first." + exit 1 +fi + +cd www/adminer || exit 1 +php ../../vendor/vrana/adminer/compile.php || exit 2 +git add adminer-*.php + +echo "There are following adminer version built:" +ls -1 adminer-*.php +echo "Consider removing old versions and do not forget to commit the changes." diff --git a/composer.json b/composer.json index a326aed96..07d10e98a 100644 --- a/composer.json +++ b/composer.json @@ -27,50 +27,50 @@ }, "require": { "php": ">=8.2", + "bjeavons/zxcvbn-php": "^1.4", + "contributte/console": "^0.10.0", + "firebase/php-jwt": "^6.11", + "forxer/gravatar": "^5.0", + "guzzlehttp/guzzle": "^7.10", + "eluceo/ical": "^2.7", "ext-yaml": ">=2.0", "ext-json": ">=1.7", "ext-zip": ">=1.15", - "nette/application": "^3.1", - "nette/bootstrap": "^3.1", - "nette/caching": "^3.1", - "nette/database": "^3.1", - "nette/di": "^3.0", + "latte/latte": "^3.0", + "league/commonmark": "^2.7", + "limenet/git-version": "v0.1.6", + "nelmio/alice": "^3.14", + "nette/application": "^3.2", + "nette/bootstrap": "^3.2", + "nette/caching": "^3.4", + "nette/database": "^3.2", + "nette/di": "^3.2", "nette/finder": "^3.0", - "nette/forms": "^3.1", - "nette/http": "^3.1", + "nette/forms": "^3.2", + "nette/http": "^3.3", "nette/mail": "^4.0", - "nette/robot-loader": "^4.0", + "nette/neon": "^3.4", + "nette/robot-loader": "^4.1", "nette/safe-stream": "^3.0", - "nette/security": "^3.1", + "nette/security": "^3.2", "nette/utils": "^4.0", - "nette/neon": "^3.2", - "latte/latte": "^3.0", - "tracy/tracy": "^2.8", - "dg/adminer-custom": "^2.0", - "contributte/console": "^0.10.0", - "nettrine/orm": "^0.8.3", - "nettrine/dbal": "^0.8.0", - "nettrine/migrations": "^0.9.0", + "nettrine/dbal": "^0.9", "nettrine/extensions-atlantic18": "^0.6.0", - "guzzlehttp/guzzle": "~7.4", - "symfony/process": "^7.1", - "firebase/php-jwt": "^6.3", - "forxer/gravatar": "^5.0", + "nettrine/migrations": "^0.10", + "nettrine/orm": "^0.9", "mrdm-nl/ldap": "^1.1", - "bjeavons/zxcvbn-php": "^1.2", - "limenet/git-version": "v0.1.6", - "nelmio/alice": "^3.8", "ramsey/uuid-doctrine": "^2.0", - "eluceo/ical": "^2.7", - "league/commonmark": "^2.3", - "zircote/swagger-php": "^4.10" + "symfony/process": "^7.3", + "tracy/tracy": "^2.11", + "zircote/swagger-php": "^5.5" }, "require-dev": { "mockery/mockery": "@stable", "mikey179/vfsstream": "@stable", "nette/tester": "^2.4", - "phpstan/phpstan": "^1.11", - "phpstan/phpstan-nette": "^1.3" + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-nette": "^2.0", + "vrana/adminer": "^5.4" }, "minimum-stability": "dev", "prefer-stable": true diff --git a/composer.lock b/composer.lock index b690c125d..da28cd525 100644 --- a/composer.lock +++ b/composer.lock @@ -4,69 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "cf7677a8572cdc148b2617c231b9228f", + "content-hash": "2d0456d40067884acbf20b7c367a11b1", "packages": [ - { - "name": "behat/transliterator", - "version": "v1.5.0", - "source": { - "type": "git", - "url": "https://github.com/Behat/Transliterator.git", - "reference": "baac5873bac3749887d28ab68e2f74db3a4408af" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Behat/Transliterator/zipball/baac5873bac3749887d28ab68e2f74db3a4408af", - "reference": "baac5873bac3749887d28ab68e2f74db3a4408af", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "require-dev": { - "chuyskywalker/rolling-curl": "^3.1", - "php-yaoi/php-yaoi": "^1.0", - "phpunit/phpunit": "^8.5.25 || ^9.5.19" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Behat\\Transliterator\\": "src/Behat/Transliterator" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Artistic-1.0" - ], - "description": "String transliterator", - "keywords": [ - "i18n", - "slug", - "transliterator" - ], - "support": { - "issues": "https://github.com/Behat/Transliterator/issues", - "source": "https://github.com/Behat/Transliterator/tree/v1.5.0" - }, - "time": "2022-03-30T09:27:43+00:00" - }, { "name": "bjeavons/zxcvbn-php", - "version": "1.3.1", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/bjeavons/zxcvbn-php.git", - "reference": "994928ae5b17ecff8baa2406832d37bdf01116c0" + "reference": "426f664501a0747beb8f3ee17ac30c7dd6327ffa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bjeavons/zxcvbn-php/zipball/994928ae5b17ecff8baa2406832d37bdf01116c0", - "reference": "994928ae5b17ecff8baa2406832d37bdf01116c0", + "url": "https://api.github.com/repos/bjeavons/zxcvbn-php/zipball/426f664501a0747beb8f3ee17ac30c7dd6327ffa", + "reference": "426f664501a0747beb8f3ee17ac30c7dd6327ffa", "shasum": "" }, "require": { @@ -76,6 +27,7 @@ }, "require-dev": { "php-coveralls/php-coveralls": "*", + "phpstan/phpstan": "^2.0", "phpunit/phpunit": "^8.5", "squizlabs/php_codesniffer": "3.*" }, @@ -106,31 +58,31 @@ ], "support": { "issues": "https://github.com/bjeavons/zxcvbn-php/issues", - "source": "https://github.com/bjeavons/zxcvbn-php/tree/1.3.1" + "source": "https://github.com/bjeavons/zxcvbn-php/tree/1.4.2" }, - "time": "2021-12-21T18:37:02+00:00" + "time": "2025-02-24T16:47:20+00:00" }, { "name": "brick/math", - "version": "0.12.1", + "version": "0.14.0", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "f510c0a40911935b77b86859eb5223d58d660df1" + "reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/f510c0a40911935b77b86859eb5223d58d660df1", - "reference": "f510c0a40911935b77b86859eb5223d58d660df1", + "url": "https://api.github.com/repos/brick/math/zipball/113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2", + "reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^8.2" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^10.1", - "vimeo/psalm": "5.16.0" + "phpstan/phpstan": "2.1.22", + "phpunit/phpunit": "^11.5" }, "type": "library", "autoload": { @@ -160,7 +112,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.12.1" + "source": "https://github.com/brick/math/tree/0.14.0" }, "funding": [ { @@ -168,7 +120,7 @@ "type": "github" } ], - "time": "2023-11-29T23:19:16+00:00" + "time": "2025-08-29T12:40:03+00:00" }, { "name": "contributte/console", @@ -241,82 +193,6 @@ ], "time": "2024-01-04T20:10:58+00:00" }, - { - "name": "contributte/di", - "version": "v0.5.6", - "source": { - "type": "git", - "url": "https://github.com/contributte/di.git", - "reference": "49d6b93d46f57be319b1e811cd983bfed0c90979" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/contributte/di/zipball/49d6b93d46f57be319b1e811cd983bfed0c90979", - "reference": "49d6b93d46f57be319b1e811cd983bfed0c90979", - "shasum": "" - }, - "require": { - "nette/di": "^3.1.0", - "nette/utils": "^3.2.8 || ^4.0", - "php": ">=7.2" - }, - "conflict": { - "nette/schema": "<1.1.0" - }, - "require-dev": { - "nette/bootstrap": "^3.1.4", - "nette/robot-loader": "^3.4.2 || ^4.0", - "ninjify/nunjuck": "^0.4", - "ninjify/qa": "^0.13", - "phpstan/phpstan": "^1.9.11", - "phpstan/phpstan-deprecation-rules": "^1.1.1", - "phpstan/phpstan-nette": "^1.2.0", - "phpstan/phpstan-strict-rules": "^1.4.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.6.x-dev" - } - }, - "autoload": { - "psr-4": { - "Contributte\\DI\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Milan Felix Šulc", - "homepage": "https://f3l1x.io" - } - ], - "description": "Extra contrib to nette/di", - "homepage": "https://github.com/contributte/di", - "keywords": [ - "dependency", - "inject", - "nette" - ], - "support": { - "issues": "https://github.com/contributte/di/issues", - "source": "https://github.com/contributte/di/tree/v0.5.6" - }, - "funding": [ - { - "url": "https://contributte.org/partners.html", - "type": "custom" - }, - { - "url": "https://github.com/f3l1x", - "type": "github" - } - ], - "time": "2023-09-05T08:23:55+00:00" - }, { "name": "dflydev/dot-access-data", "version": "v3.0.3", @@ -392,38 +268,6 @@ }, "time": "2024-07-08T12:26:09+00:00" }, - { - "name": "dg/adminer-custom", - "version": "v2.0.0", - "source": { - "type": "git", - "url": "https://github.com/dg/adminer.git", - "reference": "95a992cd99f9425b5d810923bc84371b06779dfb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dg/adminer/zipball/95a992cd99f9425b5d810923bc84371b06779dfb", - "reference": "95a992cd99f9425b5d810923bc84371b06779dfb", - "shasum": "" - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "description": "Customization for Adminer, the best database management tool written in PHP.", - "keywords": [ - "database", - "elasticsearch", - "mongodb", - "mssql", - "mysql", - "oracle", - "postgresql", - "sqlite" - ], - "support": { - "source": "https://github.com/dg/adminer/tree/v2.0.0" - }, - "time": "2024-06-04T14:12:15+00:00" - }, { "name": "doctrine/annotations", "version": "1.14.4", @@ -498,20 +342,21 @@ "issues": "https://github.com/doctrine/annotations/issues", "source": "https://github.com/doctrine/annotations/tree/1.14.4" }, + "abandoned": true, "time": "2024-09-05T10:15:52+00:00" }, { "name": "doctrine/cache", - "version": "1.13.0", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "56cd022adb5514472cb144c087393c1821911d09" + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/56cd022adb5514472cb144c087393c1821911d09", - "reference": "56cd022adb5514472cb144c087393c1821911d09", + "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", "shasum": "" }, "require": { @@ -521,19 +366,13 @@ "doctrine/common": ">2.2,<2.4" }, "require-dev": { - "alcaeus/mongo-php-adapter": "^1.1", "cache/integration-tests": "dev-master", "doctrine/coding-standard": "^9", - "mongodb/mongodb": "^1.1", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "predis/predis": "~1.0", "psr/cache": "^1.0 || ^2.0 || ^3.0", "symfony/cache": "^4.4 || ^5.4 || ^6", "symfony/var-exporter": "^4.4 || ^5.4 || ^6" }, - "suggest": { - "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" - }, "type": "library", "autoload": { "psr-4": { @@ -581,7 +420,7 @@ ], "support": { "issues": "https://github.com/doctrine/cache/issues", - "source": "https://github.com/doctrine/cache/tree/1.13.0" + "source": "https://github.com/doctrine/cache/tree/2.2.0" }, "funding": [ { @@ -597,33 +436,34 @@ "type": "tidelift" } ], - "time": "2022-05-20T20:06:54+00:00" + "abandoned": true, + "time": "2022-05-20T20:07:39+00:00" }, { "name": "doctrine/collections", - "version": "2.2.2", + "version": "2.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "d8af7f248c74f195f7347424600fd9e17b57af59" + "reference": "9acfeea2e8666536edff3d77c531261c63680160" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/d8af7f248c74f195f7347424600fd9e17b57af59", - "reference": "d8af7f248c74f195f7347424600fd9e17b57af59", + "url": "https://api.github.com/repos/doctrine/collections/zipball/9acfeea2e8666536edff3d77c531261c63680160", + "reference": "9acfeea2e8666536edff3d77c531261c63680160", "shasum": "" }, "require": { "doctrine/deprecations": "^1", - "php": "^8.1" + "php": "^8.1", + "symfony/polyfill-php84": "^1.30" }, "require-dev": { - "doctrine/coding-standard": "^12", + "doctrine/coding-standard": "^14", "ext-json": "*", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^10.5", - "vimeo/psalm": "^5.11" + "phpstan/phpstan": "^2.1.30", + "phpstan/phpstan-phpunit": "^2.0.7", + "phpunit/phpunit": "^10.5.58 || ^11.5.42 || ^12.4" }, "type": "library", "autoload": { @@ -667,7 +507,7 @@ ], "support": { "issues": "https://github.com/doctrine/collections/issues", - "source": "https://github.com/doctrine/collections/tree/2.2.2" + "source": "https://github.com/doctrine/collections/tree/2.4.0" }, "funding": [ { @@ -683,24 +523,24 @@ "type": "tidelift" } ], - "time": "2024-04-18T06:56:21+00:00" + "time": "2025-10-25T09:18:13+00:00" }, { "name": "doctrine/common", - "version": "3.4.4", + "version": "3.5.0", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a" + "reference": "d9ea4a54ca2586db781f0265d36bea731ac66ec5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a", - "reference": "0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a", + "url": "https://api.github.com/repos/doctrine/common/zipball/d9ea4a54ca2586db781f0265d36bea731ac66ec5", + "reference": "d9ea4a54ca2586db781f0265d36bea731ac66ec5", "shasum": "" }, "require": { - "doctrine/persistence": "^2.0 || ^3.0", + "doctrine/persistence": "^2.0 || ^3.0 || ^4.0", "php": "^7.1 || ^8.0" }, "require-dev": { @@ -758,7 +598,7 @@ ], "support": { "issues": "https://github.com/doctrine/common/issues", - "source": "https://github.com/doctrine/common/tree/3.4.4" + "source": "https://github.com/doctrine/common/tree/3.5.0" }, "funding": [ { @@ -774,44 +614,45 @@ "type": "tidelift" } ], - "time": "2024-04-16T13:35:33+00:00" + "time": "2025-01-01T22:12:03+00:00" }, { "name": "doctrine/dbal", - "version": "3.9.1", + "version": "3.10.3", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "d7dc08f98cba352b2bab5d32c5e58f7e745c11a7" + "reference": "65edaca19a752730f290ec2fb89d593cb40afb43" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/d7dc08f98cba352b2bab5d32c5e58f7e745c11a7", - "reference": "d7dc08f98cba352b2bab5d32c5e58f7e745c11a7", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/65edaca19a752730f290ec2fb89d593cb40afb43", + "reference": "65edaca19a752730f290ec2fb89d593cb40afb43", "shasum": "" }, "require": { "composer-runtime-api": "^2", - "doctrine/cache": "^1.11|^2.0", "doctrine/deprecations": "^0.5.3|^1", "doctrine/event-manager": "^1|^2", "php": "^7.4 || ^8.0", "psr/cache": "^1|^2|^3", "psr/log": "^1|^2|^3" }, + "conflict": { + "doctrine/cache": "< 1.11" + }, "require-dev": { - "doctrine/coding-standard": "12.0.0", + "doctrine/cache": "^1.11|^2.0", + "doctrine/coding-standard": "14.0.0", "fig/log-test": "^1", "jetbrains/phpstorm-stubs": "2023.1", - "phpstan/phpstan": "1.12.0", - "phpstan/phpstan-strict-rules": "^1.6", - "phpunit/phpunit": "9.6.20", - "psalm/plugin-phpunit": "0.18.4", - "slevomat/coding-standard": "8.13.1", - "squizlabs/php_codesniffer": "3.10.2", + "phpstan/phpstan": "2.1.30", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "9.6.29", + "slevomat/coding-standard": "8.24.0", + "squizlabs/php_codesniffer": "4.0.0", "symfony/cache": "^5.4|^6.0|^7.0", - "symfony/console": "^4.4|^5.4|^6.0|^7.0", - "vimeo/psalm": "4.30.0" + "symfony/console": "^4.4|^5.4|^6.0|^7.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -871,7 +712,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.9.1" + "source": "https://github.com/doctrine/dbal/tree/3.10.3" }, "funding": [ { @@ -887,33 +728,34 @@ "type": "tidelift" } ], - "time": "2024-09-01T13:49:23+00:00" + "time": "2025-10-09T09:05:12+00:00" }, { "name": "doctrine/deprecations", - "version": "1.1.3", + "version": "1.1.5", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", + "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, + "conflict": { + "phpunit/phpunit": "<=7.5 || >=13" + }, "require-dev": { - "doctrine/coding-standard": "^9", - "phpstan/phpstan": "1.4.10 || 1.10.15", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psalm/plugin-phpunit": "0.18.4", - "psr/log": "^1 || ^2 || ^3", - "vimeo/psalm": "4.30.0 || 5.12.0" + "doctrine/coding-standard": "^9 || ^12 || ^13", + "phpstan/phpstan": "1.4.10 || 2.1.11", + "phpstan/phpstan-phpunit": "^1.0 || ^2", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12", + "psr/log": "^1 || ^2 || ^3" }, "suggest": { "psr/log": "Allows logging deprecations via PSR-3 logger implementation" @@ -921,7 +763,7 @@ "type": "library", "autoload": { "psr-4": { - "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + "Doctrine\\Deprecations\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -932,9 +774,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.3" + "source": "https://github.com/doctrine/deprecations/tree/1.1.5" }, - "time": "2024-01-30T19:34:25+00:00" + "time": "2025-04-07T20:06:18+00:00" }, { "name": "doctrine/event-manager", @@ -1029,33 +871,32 @@ }, { "name": "doctrine/inflector", - "version": "2.0.10", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc" + "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/5817d0659c5b50c9b950feb9af7b9668e2c436bc", - "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/6d6c96277ea252fc1304627204c3d5e6e15faa3b", + "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^11.0", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.3", - "phpunit/phpunit": "^8.5 || ^9.5", - "vimeo/psalm": "^4.25 || ^5.4" + "doctrine/coding-standard": "^12.0 || ^13.0", + "phpstan/phpstan": "^1.12 || ^2.0", + "phpstan/phpstan-phpunit": "^1.4 || ^2.0", + "phpstan/phpstan-strict-rules": "^1.6 || ^2.0", + "phpunit/phpunit": "^8.5 || ^12.2" }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + "Doctrine\\Inflector\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1100,7 +941,7 @@ ], "support": { "issues": "https://github.com/doctrine/inflector/issues", - "source": "https://github.com/doctrine/inflector/tree/2.0.10" + "source": "https://github.com/doctrine/inflector/tree/2.1.0" }, "funding": [ { @@ -1116,7 +957,7 @@ "type": "tidelift" } ], - "time": "2024-02-18T20:23:39+00:00" + "time": "2025-08-10T19:31:58+00:00" }, { "name": "doctrine/instantiator", @@ -1268,16 +1109,16 @@ }, { "name": "doctrine/migrations", - "version": "3.8.1", + "version": "3.9.4", "source": { "type": "git", "url": "https://github.com/doctrine/migrations.git", - "reference": "7760fbd0b7cb58bfb50415505a7bab821adf0877" + "reference": "1b88fcb812f2cd6e77c83d16db60e3cf1e35c66c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/migrations/zipball/7760fbd0b7cb58bfb50415505a7bab821adf0877", - "reference": "7760fbd0b7cb58bfb50415505a7bab821adf0877", + "url": "https://api.github.com/repos/doctrine/migrations/zipball/1b88fcb812f2cd6e77c83d16db60e3cf1e35c66c", + "reference": "1b88fcb812f2cd6e77c83d16db60e3cf1e35c66c", "shasum": "" }, "require": { @@ -1295,18 +1136,18 @@ "doctrine/orm": "<2.12 || >=4" }, "require-dev": { - "doctrine/coding-standard": "^12", + "doctrine/coding-standard": "^13", "doctrine/orm": "^2.13 || ^3", - "doctrine/persistence": "^2 || ^3", + "doctrine/persistence": "^2 || ^3 || ^4", "doctrine/sql-formatter": "^1.0", "ext-pdo_sqlite": "*", "fig/log-test": "^1", - "phpstan/phpstan": "^1.10", - "phpstan/phpstan-deprecation-rules": "^1.1", - "phpstan/phpstan-phpunit": "^1.3", - "phpstan/phpstan-strict-rules": "^1.4", - "phpstan/phpstan-symfony": "^1.3", - "phpunit/phpunit": "^10.3", + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-phpunit": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpstan/phpstan-symfony": "^2", + "phpunit/phpunit": "^10.3 || ^11.0 || ^12.0", "symfony/cache": "^5.4 || ^6.0 || ^7.0", "symfony/process": "^5.4 || ^6.0 || ^7.0", "symfony/yaml": "^5.4 || ^6.0 || ^7.0" @@ -1351,7 +1192,7 @@ ], "support": { "issues": "https://github.com/doctrine/migrations/issues", - "source": "https://github.com/doctrine/migrations/tree/3.8.1" + "source": "https://github.com/doctrine/migrations/tree/3.9.4" }, "funding": [ { @@ -1367,20 +1208,20 @@ "type": "tidelift" } ], - "time": "2024-08-28T13:17:28+00:00" + "time": "2025-08-19T06:41:07+00:00" }, { "name": "doctrine/orm", - "version": "2.19.7", + "version": "2.20.7", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "168ac31084226f94d42e7461a40ff5607a56bd35" + "reference": "59938cae57c88b386cb79c81685426c83d27a120" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/168ac31084226f94d42e7461a40ff5607a56bd35", - "reference": "168ac31084226f94d42e7461a40ff5607a56bd35", + "url": "https://api.github.com/repos/doctrine/orm/zipball/59938cae57c88b386cb79c81685426c83d27a120", + "reference": "59938cae57c88b386cb79c81685426c83d27a120", "shasum": "" }, "require": { @@ -1407,16 +1248,16 @@ }, "require-dev": { "doctrine/annotations": "^1.13 || ^2", - "doctrine/coding-standard": "^9.0.2 || ^12.0", + "doctrine/coding-standard": "^9.0.2 || ^14.0", "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "~1.4.10 || 1.11.1", + "phpstan/extension-installer": "~1.1.0 || ^1.4", + "phpstan/phpstan": "~1.4.10 || 2.1.22", + "phpstan/phpstan-deprecation-rules": "^1 || ^2", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", "psr/log": "^1 || ^2 || ^3", - "squizlabs/php_codesniffer": "3.7.2", "symfony/cache": "^4.4 || ^5.4 || ^6.4 || ^7.0", "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2 || ^7.0", - "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "vimeo/psalm": "4.30.0 || 5.24.0" + "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0 || ^7.0" }, "suggest": { "ext-dom": "Provides support for XSD validation for XML mapping files", @@ -1466,22 +1307,22 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.19.7" + "source": "https://github.com/doctrine/orm/tree/2.20.7" }, - "time": "2024-08-23T06:54:57+00:00" + "time": "2025-10-27T21:19:59+00:00" }, { "name": "doctrine/persistence", - "version": "3.3.3", + "version": "3.4.3", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "b337726451f5d530df338fc7f68dee8781b49779" + "reference": "d59e6ef7caffe6a30f4b6f9e9079a75f52c64ae0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/b337726451f5d530df338fc7f68dee8781b49779", - "reference": "b337726451f5d530df338fc7f68dee8781b49779", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/d59e6ef7caffe6a30f4b6f9e9079a75f52c64ae0", + "reference": "d59e6ef7caffe6a30f4b6f9e9079a75f52c64ae0", "shasum": "" }, "require": { @@ -1493,14 +1334,13 @@ "doctrine/common": "<2.10" }, "require-dev": { - "doctrine/coding-standard": "^12", + "doctrine/coding-standard": "^12 || ^14", "doctrine/common": "^3.0", - "phpstan/phpstan": "1.11.1", - "phpstan/phpstan-phpunit": "^1", - "phpstan/phpstan-strict-rules": "^1.1", - "phpunit/phpunit": "^8.5 || ^9.5", - "symfony/cache": "^4.4 || ^5.4 || ^6.0", - "vimeo/psalm": "4.30.0 || 5.24.0" + "phpstan/phpstan": "^1 || 2.1.30", + "phpstan/phpstan-phpunit": "^1 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8.5.38 || ^9.5", + "symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0" }, "type": "library", "autoload": { @@ -1549,7 +1389,7 @@ ], "support": { "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/3.3.3" + "source": "https://github.com/doctrine/persistence/tree/3.4.3" }, "funding": [ { @@ -1565,7 +1405,7 @@ "type": "tidelift" } ], - "time": "2024-06-20T10:14:30+00:00" + "time": "2025-10-21T15:21:39+00:00" }, { "name": "eluceo/ical", @@ -1633,16 +1473,16 @@ }, { "name": "fakerphp/faker", - "version": "v1.23.1", + "version": "v1.24.1", "source": { "type": "git", "url": "https://github.com/FakerPHP/Faker.git", - "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b" + "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/bfb4fe148adbf78eff521199619b93a52ae3554b", - "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", + "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", "shasum": "" }, "require": { @@ -1690,22 +1530,22 @@ ], "support": { "issues": "https://github.com/FakerPHP/Faker/issues", - "source": "https://github.com/FakerPHP/Faker/tree/v1.23.1" + "source": "https://github.com/FakerPHP/Faker/tree/v1.24.1" }, - "time": "2024-01-02T13:46:09+00:00" + "time": "2024-11-21T13:46:39+00:00" }, { "name": "firebase/php-jwt", - "version": "v6.10.1", + "version": "v6.11.1", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "500501c2ce893c824c801da135d02661199f60c5" + "reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/500501c2ce893c824c801da135d02661199f60c5", - "reference": "500501c2ce893c824c801da135d02661199f60c5", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/d1e91ecf8c598d073d0995afa8cd5c75c6e19e66", + "reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66", "shasum": "" }, "require": { @@ -1753,30 +1593,30 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v6.10.1" + "source": "https://github.com/firebase/php-jwt/tree/v6.11.1" }, - "time": "2024-05-18T18:05:11+00:00" + "time": "2025-04-09T20:32:01+00:00" }, { "name": "forxer/gravatar", - "version": "5.0.0", + "version": "5.0.2", "source": { "type": "git", "url": "https://github.com/forxer/gravatar.git", - "reference": "0fbc0993b83be7edd5b85daafb4f3b7ee299e0c6" + "reference": "1b08442e8de2188a0a31dbf7c99cd6f5e0eab70c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/forxer/gravatar/zipball/0fbc0993b83be7edd5b85daafb4f3b7ee299e0c6", - "reference": "0fbc0993b83be7edd5b85daafb4f3b7ee299e0c6", + "url": "https://api.github.com/repos/forxer/gravatar/zipball/1b08442e8de2188a0a31dbf7c99cd6f5e0eab70c", + "reference": "1b08442e8de2188a0a31dbf7c99cd6f5e0eab70c", "shasum": "" }, "require": { "php": "^8.2" }, "require-dev": { - "laravel/pint": "^1.16.0", - "rector/rector": "^1.1.0" + "laravel/pint": "^1.22.1", + "rector/rector": "^2.0.16" }, "type": "library", "autoload": { @@ -1803,59 +1643,62 @@ "support": { "email": "forxer@gmail.com", "issues": "https://github.com/forxer/gravatar/issues", - "source": "https://github.com/forxer/gravatar/tree/5.0.0" + "source": "https://github.com/forxer/gravatar/tree/5.0.2" }, - "time": "2024-05-26T21:45:17+00:00" + "time": "2025-05-28T08:53:04+00:00" }, { "name": "gedmo/doctrine-extensions", - "version": "v3.16.1", + "version": "v3.21.0", "source": { "type": "git", "url": "https://github.com/doctrine-extensions/DoctrineExtensions.git", - "reference": "e85560ed96f977b8c29428a99222cb2ef2f0e80d" + "reference": "eb53dfcb2b592327b76ac5226fbb003d32aea37e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine-extensions/DoctrineExtensions/zipball/e85560ed96f977b8c29428a99222cb2ef2f0e80d", - "reference": "e85560ed96f977b8c29428a99222cb2ef2f0e80d", + "url": "https://api.github.com/repos/doctrine-extensions/DoctrineExtensions/zipball/eb53dfcb2b592327b76ac5226fbb003d32aea37e", + "reference": "eb53dfcb2b592327b76ac5226fbb003d32aea37e", "shasum": "" }, "require": { - "behat/transliterator": "^1.2", "doctrine/collections": "^1.2 || ^2.0", - "doctrine/common": "^2.13 || ^3.0", "doctrine/deprecations": "^1.0", "doctrine/event-manager": "^1.2 || ^2.0", - "doctrine/persistence": "^2.2 || ^3.0", + "doctrine/persistence": "^2.2 || ^3.0 || ^4.0", "php": "^7.4 || ^8.0", "psr/cache": "^1 || ^2 || ^3", "psr/clock": "^1", - "symfony/cache": "^5.4 || ^6.0 || ^7.0" + "symfony/cache": "^5.4 || ^6.0 || ^7.0", + "symfony/string": "^5.4 || ^6.0 || ^7.0" }, "conflict": { + "behat/transliterator": "<1.2 || >=2.0", "doctrine/annotations": "<1.13 || >=3.0", - "doctrine/dbal": "<3.2 || >=4.0", + "doctrine/common": "<2.13 || >=4.0", + "doctrine/dbal": "<3.7 || >=5.0", "doctrine/mongodb-odm": "<2.3 || >=3.0", - "doctrine/orm": "<2.14.0 || 2.16.0 || 2.16.1 || >=4.0" + "doctrine/orm": "<2.20 || >=3.0 <3.3 || >=4.0" }, "require-dev": { + "behat/transliterator": "^1.2", "doctrine/annotations": "^1.13 || ^2.0", "doctrine/cache": "^1.11 || ^2.0", - "doctrine/dbal": "^3.2", + "doctrine/common": "^2.13 || ^3.0", + "doctrine/dbal": "^3.7 || ^4.0", "doctrine/doctrine-bundle": "^2.3", "doctrine/mongodb-odm": "^2.3", - "doctrine/orm": "^2.14.0 || ^3.0", - "friendsofphp/php-cs-fixer": "^3.14.0", + "doctrine/orm": "^2.20 || ^3.3", + "friendsofphp/php-cs-fixer": "^3.70", "nesbot/carbon": "^2.71 || ^3.0", - "phpstan/phpstan": "^1.11", - "phpstan/phpstan-doctrine": "^1.4", - "phpstan/phpstan-phpunit": "^1.4", + "phpstan/phpstan": "^2.1.1", + "phpstan/phpstan-doctrine": "^2.0.1", + "phpstan/phpstan-phpunit": "^2.0.3", "phpunit/phpunit": "^9.6", - "rector/rector": "^1.1", + "rector/rector": "^2.0.6", "symfony/console": "^5.4 || ^6.0 || ^7.0", "symfony/doctrine-bridge": "^5.4 || ^6.0 || ^7.0", - "symfony/phpunit-bridge": "^6.0 || ^7.0", + "symfony/phpunit-bridge": "^6.4 || ^7.0", "symfony/uid": "^5.4 || ^6.0 || ^7.0", "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, @@ -1912,10 +1755,9 @@ "uploadable" ], "support": { - "email": "gediminas.morkevicius@gmail.com", + "docs": "https://github.com/doctrine-extensions/DoctrineExtensions/tree/main/doc", "issues": "https://github.com/doctrine-extensions/DoctrineExtensions/issues", - "source": "https://github.com/doctrine-extensions/DoctrineExtensions/tree/v3.16.1", - "wiki": "https://github.com/Atlantic18/DoctrineExtensions/tree/main/doc" + "source": "https://github.com/doctrine-extensions/DoctrineExtensions/tree/v3.21.0" }, "funding": [ { @@ -1935,26 +1777,26 @@ "type": "github" } ], - "time": "2024-06-25T16:22:14+00:00" + "time": "2025-09-22T17:04:34+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "7.9.2", + "version": "7.10.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "d281ed313b989f213357e3be1a179f02196ac99b" + "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b", - "reference": "d281ed313b989f213357e3be1a179f02196ac99b", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", + "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5.3 || ^2.0.3", - "guzzlehttp/psr7": "^2.7.0", + "guzzlehttp/promises": "^2.3", + "guzzlehttp/psr7": "^2.8", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -2045,7 +1887,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.9.2" + "source": "https://github.com/guzzle/guzzle/tree/7.10.0" }, "funding": [ { @@ -2061,20 +1903,20 @@ "type": "tidelift" } ], - "time": "2024-07-24T11:22:20+00:00" + "time": "2025-08-23T22:36:01+00:00" }, { "name": "guzzlehttp/promises", - "version": "2.0.3", + "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8" + "reference": "481557b130ef3790cf82b713667b43030dc9c957" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8", - "reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8", + "url": "https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957", + "reference": "481557b130ef3790cf82b713667b43030dc9c957", "shasum": "" }, "require": { @@ -2082,7 +1924,7 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.39 || ^9.6.20" + "phpunit/phpunit": "^8.5.44 || ^9.6.25" }, "type": "library", "extra": { @@ -2128,7 +1970,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.0.3" + "source": "https://github.com/guzzle/promises/tree/2.3.0" }, "funding": [ { @@ -2144,20 +1986,20 @@ "type": "tidelift" } ], - "time": "2024-07-18T10:29:17+00:00" + "time": "2025-08-22T14:34:08+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.7.0", + "version": "2.8.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201" + "reference": "21dc724a0583619cd1652f673303492272778051" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/a70f5c95fb43bc83f07c9c948baa0dc1829bf201", - "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051", + "reference": "21dc724a0583619cd1652f673303492272778051", "shasum": "" }, "require": { @@ -2173,7 +2015,7 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "http-interop/http-factory-tests": "0.9.0", - "phpunit/phpunit": "^8.5.39 || ^9.6.20" + "phpunit/phpunit": "^8.5.44 || ^9.6.25" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" @@ -2244,7 +2086,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.7.0" + "source": "https://github.com/guzzle/psr7/tree/2.8.0" }, "funding": [ { @@ -2260,26 +2102,26 @@ "type": "tidelift" } ], - "time": "2024-07-18T11:15:46+00:00" + "time": "2025-08-23T21:21:41+00:00" }, { "name": "latte/latte", - "version": "v3.0.18", + "version": "v3.0.24", "source": { "type": "git", "url": "https://github.com/nette/latte.git", - "reference": "fca0a3eddd70213201b3b3abec0cb8dde7bbc259" + "reference": "2ec95b542197d82a4837ba5949bd823d0ca7d170" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/latte/zipball/fca0a3eddd70213201b3b3abec0cb8dde7bbc259", - "reference": "fca0a3eddd70213201b3b3abec0cb8dde7bbc259", + "url": "https://api.github.com/repos/nette/latte/zipball/2ec95b542197d82a4837ba5949bd823d0ca7d170", + "reference": "2ec95b542197d82a4837ba5949bd823d0ca7d170", "shasum": "" }, "require": { "ext-json": "*", "ext-tokenizer": "*", - "php": "8.0 - 8.4" + "php": "8.0 - 8.5" }, "conflict": { "nette/application": "<3.1.7", @@ -2289,7 +2131,7 @@ "nette/php-generator": "^4.0", "nette/tester": "^2.5", "nette/utils": "^4.0", - "phpstan/phpstan": "^1", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.10" }, "suggest": { @@ -2310,6 +2152,9 @@ } }, "autoload": { + "psr-4": { + "Latte\\": "src/Latte" + }, "classmap": [ "src/" ] @@ -2344,22 +2189,22 @@ ], "support": { "issues": "https://github.com/nette/latte/issues", - "source": "https://github.com/nette/latte/tree/v3.0.18" + "source": "https://github.com/nette/latte/tree/v3.0.24" }, - "time": "2024-08-06T07:58:55+00:00" + "time": "2025-10-31T00:53:04+00:00" }, { "name": "league/commonmark", - "version": "2.7.0", + "version": "2.7.1", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "6fbb36d44824ed4091adbcf4c7d4a3923cdb3405" + "reference": "10732241927d3971d28e7ea7b5712721fa2296ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/6fbb36d44824ed4091adbcf4c7d4a3923cdb3405", - "reference": "6fbb36d44824ed4091adbcf4c7d4a3923cdb3405", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/10732241927d3971d28e7ea7b5712721fa2296ca", + "reference": "10732241927d3971d28e7ea7b5712721fa2296ca", "shasum": "" }, "require": { @@ -2388,7 +2233,7 @@ "symfony/process": "^5.4 | ^6.0 | ^7.0", "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0", "unleashedtech/php-coding-standard": "^3.1.1", - "vimeo/psalm": "^4.24.0 || ^5.0.0" + "vimeo/psalm": "^4.24.0 || ^5.0.0 || ^6.0.0" }, "suggest": { "symfony/yaml": "v2.3+ required if using the Front Matter extension" @@ -2453,7 +2298,7 @@ "type": "tidelift" } ], - "time": "2025-05-05T12:20:28+00:00" + "time": "2025-07-20T12:47:49+00:00" }, { "name": "league/config", @@ -3077,12 +2922,12 @@ "type": "library", "extra": { "laravel": { - "providers": [ - "limenet\\GitVersion\\Laravel\\ServiceProvider" - ], "aliases": { "GitVersion": "limenet\\GitVersion\\Laravel\\Facade" - } + }, + "providers": [ + "limenet\\GitVersion\\Laravel\\ServiceProvider" + ] } }, "autoload": { @@ -3105,6 +2950,7 @@ "issues": "https://github.com/limenet/git-version/issues", "source": "https://github.com/limenet/git-version/tree/master" }, + "abandoned": true, "time": "2018-11-01T09:47:34+00:00" }, { @@ -3157,16 +3003,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.12.0", + "version": "1.13.4", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", "shasum": "" }, "require": { @@ -3205,7 +3051,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" }, "funding": [ { @@ -3213,27 +3059,28 @@ "type": "tidelift" } ], - "time": "2024-06-12T14:39:25+00:00" + "time": "2025-08-01T08:46:24+00:00" }, { "name": "nelmio/alice", - "version": "3.13.6", + "version": "3.14.2", "source": { "type": "git", "url": "https://github.com/nelmio/alice.git", - "reference": "76caab8675c68956d56a2dd03f66384251e0aa7c" + "reference": "f353866956ac4760514e24e8d51902d261d50489" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nelmio/alice/zipball/76caab8675c68956d56a2dd03f66384251e0aa7c", - "reference": "76caab8675c68956d56a2dd03f66384251e0aa7c", + "url": "https://api.github.com/repos/nelmio/alice/zipball/f353866956ac4760514e24e8d51902d261d50489", + "reference": "f353866956ac4760514e24e8d51902d261d50489", "shasum": "" }, "require": { "fakerphp/faker": "^1.10", "myclabs/deep-copy": "^1.10", "php": "^8.1", - "sebastian/comparator": "^3.0 || ^4.0 || ^5.0 || ^6.0", + "sebastian/comparator": "^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0", + "symfony/polyfill-php84": "^1.31", "symfony/property-access": "^6.4 || ^7.0", "symfony/yaml": "^6.0 || ^7.0" }, @@ -3300,7 +3147,7 @@ ], "support": { "issues": "https://github.com/nelmio/alice/issues", - "source": "https://github.com/nelmio/alice/tree/3.13.6" + "source": "https://github.com/nelmio/alice/tree/3.14.2" }, "funding": [ { @@ -3308,31 +3155,31 @@ "type": "github" } ], - "time": "2024-07-03T17:54:12+00:00" + "time": "2025-02-26T09:01:07+00:00" }, { "name": "nette/application", - "version": "v3.2.6", + "version": "v3.2.7", "source": { "type": "git", "url": "https://github.com/nette/application.git", - "reference": "9c288cc45df467dc012504f4ad64791279720af8" + "reference": "262f16bc2adab6f489a715efd854f1e2c909c702" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/application/zipball/9c288cc45df467dc012504f4ad64791279720af8", - "reference": "9c288cc45df467dc012504f4ad64791279720af8", + "url": "https://api.github.com/repos/nette/application/zipball/262f16bc2adab6f489a715efd854f1e2c909c702", + "reference": "262f16bc2adab6f489a715efd854f1e2c909c702", "shasum": "" }, "require": { "nette/component-model": "^3.1", - "nette/http": "^3.3", + "nette/http": "^3.3.2", "nette/routing": "^3.1", "nette/utils": "^4.0", "php": "8.1 - 8.4" }, "conflict": { - "latte/latte": "<2.7.1 || >=3.0.0 <3.0.18 || >=3.1", + "latte/latte": "<2.7.1 || >=3.0.0 <3.0.18 || >=3.2", "nette/caching": "<3.2", "nette/di": "<3.2", "nette/forms": "<3.2", @@ -3340,15 +3187,15 @@ "tracy/tracy": "<2.9" }, "require-dev": { - "jetbrains/phpstorm-attributes": "dev-master", + "jetbrains/phpstorm-attributes": "^1.2", "latte/latte": "^2.10.2 || ^3.0.18", - "mockery/mockery": "^2.0", + "mockery/mockery": "^1.6@stable", "nette/di": "^3.2", "nette/forms": "^3.2", "nette/robot-loader": "^4.0", "nette/security": "^3.2", - "nette/tester": "^2.5", - "phpstan/phpstan-nette": "^1.0", + "nette/tester": "^2.5.2", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.9" }, "suggest": { @@ -3362,6 +3209,9 @@ } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -3398,28 +3248,28 @@ ], "support": { "issues": "https://github.com/nette/application/issues", - "source": "https://github.com/nette/application/tree/v3.2.6" + "source": "https://github.com/nette/application/tree/v3.2.7" }, - "time": "2024-09-10T10:08:04+00:00" + "time": "2025-07-17T22:41:57+00:00" }, { "name": "nette/bootstrap", - "version": "v3.2.4", + "version": "v3.2.7", "source": { "type": "git", "url": "https://github.com/nette/bootstrap.git", - "reference": "4876d25955b4164d714bc17c265f664f6594685b" + "reference": "10fdb1cb05497da39396f2ce1785cea67c8aa439" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/bootstrap/zipball/4876d25955b4164d714bc17c265f664f6594685b", - "reference": "4876d25955b4164d714bc17c265f664f6594685b", + "url": "https://api.github.com/repos/nette/bootstrap/zipball/10fdb1cb05497da39396f2ce1785cea67c8aa439", + "reference": "10fdb1cb05497da39396f2ce1785cea67c8aa439", "shasum": "" }, "require": { "nette/di": "^3.1", "nette/utils": "^3.2.1 || ^4.0", - "php": "8.0 - 8.4" + "php": "8.0 - 8.5" }, "conflict": { "tracy/tracy": "<2.6" @@ -3436,7 +3286,7 @@ "nette/safe-stream": "^2.2", "nette/security": "^3.0", "nette/tester": "^2.4", - "phpstan/phpstan-nette": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.9" }, "suggest": { @@ -3450,6 +3300,9 @@ } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -3479,36 +3332,36 @@ ], "support": { "issues": "https://github.com/nette/bootstrap/issues", - "source": "https://github.com/nette/bootstrap/tree/v3.2.4" + "source": "https://github.com/nette/bootstrap/tree/v3.2.7" }, - "time": "2024-06-18T22:13:57+00:00" + "time": "2025-08-01T02:02:03+00:00" }, { "name": "nette/caching", - "version": "v3.3.1", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/nette/caching.git", - "reference": "b37d2c9647b41a9d04f099f10300dc5496c4eb77" + "reference": "a1c13221b350d0db0a2bd4a77c1e7b65e0aa065d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/caching/zipball/b37d2c9647b41a9d04f099f10300dc5496c4eb77", - "reference": "b37d2c9647b41a9d04f099f10300dc5496c4eb77", + "url": "https://api.github.com/repos/nette/caching/zipball/a1c13221b350d0db0a2bd4a77c1e7b65e0aa065d", + "reference": "a1c13221b350d0db0a2bd4a77c1e7b65e0aa065d", "shasum": "" }, "require": { "nette/utils": "^4.0", - "php": "8.0 - 8.4" + "php": "8.1 - 8.5" }, "conflict": { - "latte/latte": ">=3.0.0 <3.0.12" + "latte/latte": "<3.0.12" }, "require-dev": { - "latte/latte": "^2.11 || ^3.0.12", + "latte/latte": "^3.0.12", "nette/di": "^3.1 || ^4.0", "nette/tester": "^2.4", - "phpstan/phpstan": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "psr/simple-cache": "^2.0 || ^3.0", "tracy/tracy": "^2.9" }, @@ -3518,10 +3371,13 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.3-dev" + "dev-master": "3.4-dev" } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -3553,31 +3409,31 @@ ], "support": { "issues": "https://github.com/nette/caching/issues", - "source": "https://github.com/nette/caching/tree/v3.3.1" + "source": "https://github.com/nette/caching/tree/v3.4.0" }, - "time": "2024-08-07T00:01:58+00:00" + "time": "2025-08-06T23:05:08+00:00" }, { "name": "nette/component-model", - "version": "v3.1.0", + "version": "v3.1.2", "source": { "type": "git", "url": "https://github.com/nette/component-model.git", - "reference": "4e0946a788b4ac42ea903b761c693ec7dd083a69" + "reference": "f8debd4867117e969478a7142047c7c3c389d085" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/component-model/zipball/4e0946a788b4ac42ea903b761c693ec7dd083a69", - "reference": "4e0946a788b4ac42ea903b761c693ec7dd083a69", + "url": "https://api.github.com/repos/nette/component-model/zipball/f8debd4867117e969478a7142047c7c3c389d085", + "reference": "f8debd4867117e969478a7142047c7c3c389d085", "shasum": "" }, "require": { "nette/utils": "^4.0", - "php": "8.1 - 8.3" + "php": "8.1 - 8.5" }, "require-dev": { "nette/tester": "^2.5", - "phpstan/phpstan": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.9" }, "type": "library", @@ -3587,6 +3443,9 @@ } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -3615,36 +3474,36 @@ ], "support": { "issues": "https://github.com/nette/component-model/issues", - "source": "https://github.com/nette/component-model/tree/v3.1.0" + "source": "https://github.com/nette/component-model/tree/v3.1.2" }, - "time": "2024-02-08T20:25:40+00:00" + "time": "2025-08-06T22:45:03+00:00" }, { "name": "nette/database", - "version": "v3.2.4", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/nette/database.git", - "reference": "8e9a427d98ec0929102ee037016bb47eb7e8b75c" + "reference": "1a84d3e61aa33461a3d6415235b25a7cd8b3f442" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/database/zipball/8e9a427d98ec0929102ee037016bb47eb7e8b75c", - "reference": "8e9a427d98ec0929102ee037016bb47eb7e8b75c", + "url": "https://api.github.com/repos/nette/database/zipball/1a84d3e61aa33461a3d6415235b25a7cd8b3f442", + "reference": "1a84d3e61aa33461a3d6415235b25a7cd8b3f442", "shasum": "" }, "require": { "ext-pdo": "*", "nette/caching": "^3.2", "nette/utils": "^4.0", - "php": "8.1 - 8.4" + "php": "8.1 - 8.5" }, "require-dev": { - "jetbrains/phpstorm-attributes": "^1.0", - "mockery/mockery": "^1.6", + "jetbrains/phpstorm-attributes": "^1.2", + "mockery/mockery": "^1.6@stable", "nette/di": "^3.1", "nette/tester": "^2.5", - "phpstan/phpstan-nette": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.9" }, "type": "library", @@ -3654,6 +3513,9 @@ } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -3690,37 +3552,37 @@ ], "support": { "issues": "https://github.com/nette/database/issues", - "source": "https://github.com/nette/database/tree/v3.2.4" + "source": "https://github.com/nette/database/tree/v3.2.8" }, - "time": "2024-08-28T01:03:21+00:00" + "time": "2025-10-30T22:06:23+00:00" }, { "name": "nette/di", - "version": "v3.2.2", + "version": "v3.2.5", "source": { "type": "git", "url": "https://github.com/nette/di.git", - "reference": "50beb3271322a7c9a7b9f76d991476c9ae5c82d6" + "reference": "5708c328ce7658a73c96b14dd6da7b8b27bf220f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/di/zipball/50beb3271322a7c9a7b9f76d991476c9ae5c82d6", - "reference": "50beb3271322a7c9a7b9f76d991476c9ae5c82d6", + "url": "https://api.github.com/repos/nette/di/zipball/5708c328ce7658a73c96b14dd6da7b8b27bf220f", + "reference": "5708c328ce7658a73c96b14dd6da7b8b27bf220f", "shasum": "" }, "require": { "ext-ctype": "*", "ext-tokenizer": "*", - "nette/neon": "^3.3 || ^4.0", - "nette/php-generator": "^4.1.3", + "nette/neon": "^3.3", + "nette/php-generator": "^4.1.6", "nette/robot-loader": "^4.0", "nette/schema": "^1.2.5", "nette/utils": "^4.0", - "php": "8.1 - 8.3" + "php": "8.1 - 8.5" }, "require-dev": { "nette/tester": "^2.5.2", - "phpstan/phpstan": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.9" }, "type": "library", @@ -3730,6 +3592,9 @@ } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -3763,9 +3628,9 @@ ], "support": { "issues": "https://github.com/nette/di/issues", - "source": "https://github.com/nette/di/tree/v3.2.2" + "source": "https://github.com/nette/di/tree/v3.2.5" }, - "time": "2024-05-16T13:30:24+00:00" + "time": "2025-08-14T22:59:46+00:00" }, { "name": "nette/finder", @@ -3822,16 +3687,16 @@ }, { "name": "nette/forms", - "version": "v3.2.4", + "version": "v3.2.7", "source": { "type": "git", "url": "https://github.com/nette/forms.git", - "reference": "e61535036669a78bcafb061dcfa46da827fcf377" + "reference": "cedc41fe0eff7568f8875d6e4347e95bc4f0cf7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/forms/zipball/e61535036669a78bcafb061dcfa46da827fcf377", - "reference": "e61535036669a78bcafb061dcfa46da827fcf377", + "url": "https://api.github.com/repos/nette/forms/zipball/cedc41fe0eff7568f8875d6e4347e95bc4f0cf7a", + "reference": "cedc41fe0eff7568f8875d6e4347e95bc4f0cf7a", "shasum": "" }, "require": { @@ -3841,14 +3706,14 @@ "php": "8.1 - 8.4" }, "conflict": { - "latte/latte": ">=3.0.0 <3.0.12 || >=3.1" + "latte/latte": ">=3.0.0 <3.0.12 || >=3.2" }, "require-dev": { "latte/latte": "^2.10.2 || ^3.0.12", "nette/application": "^3.0", "nette/di": "^3.0", "nette/tester": "^2.5.2", - "phpstan/phpstan-nette": "^1", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.9" }, "suggest": { @@ -3861,6 +3726,9 @@ } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -3893,27 +3761,27 @@ ], "support": { "issues": "https://github.com/nette/forms/issues", - "source": "https://github.com/nette/forms/tree/v3.2.4" + "source": "https://github.com/nette/forms/tree/v3.2.7" }, - "time": "2024-08-05T23:11:27+00:00" + "time": "2025-07-17T22:54:05+00:00" }, { "name": "nette/http", - "version": "v3.3.0", + "version": "v3.3.3", "source": { "type": "git", "url": "https://github.com/nette/http.git", - "reference": "c779293fb79e6d2a16d474cd19dce866615f3b9c" + "reference": "c557f21c8cedd621dbfd7990752b1d55ef353f1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/http/zipball/c779293fb79e6d2a16d474cd19dce866615f3b9c", - "reference": "c779293fb79e6d2a16d474cd19dce866615f3b9c", + "url": "https://api.github.com/repos/nette/http/zipball/c557f21c8cedd621dbfd7990752b1d55ef353f1d", + "reference": "c557f21c8cedd621dbfd7990752b1d55ef353f1d", "shasum": "" }, "require": { "nette/utils": "^4.0.4", - "php": "8.1 - 8.3" + "php": "8.1 - 8.5" }, "conflict": { "nette/di": "<3.0.3", @@ -3923,7 +3791,7 @@ "nette/di": "^3.0", "nette/security": "^3.0", "nette/tester": "^2.4", - "phpstan/phpstan": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.8" }, "suggest": { @@ -3939,6 +3807,9 @@ } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -3974,33 +3845,33 @@ ], "support": { "issues": "https://github.com/nette/http/issues", - "source": "https://github.com/nette/http/tree/v3.3.0" + "source": "https://github.com/nette/http/tree/v3.3.3" }, - "time": "2024-01-30T18:16:20+00:00" + "time": "2025-10-30T22:32:24+00:00" }, { "name": "nette/mail", - "version": "v4.0.2", + "version": "v4.0.4", "source": { "type": "git", "url": "https://github.com/nette/mail.git", - "reference": "c0b81124284bee573ee968de98fe3dcf2c2a9b5e" + "reference": "5f16f76ed14a32f34580811d1a07ac357352bbc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/mail/zipball/c0b81124284bee573ee968de98fe3dcf2c2a9b5e", - "reference": "c0b81124284bee573ee968de98fe3dcf2c2a9b5e", + "url": "https://api.github.com/repos/nette/mail/zipball/5f16f76ed14a32f34580811d1a07ac357352bbc4", + "reference": "5f16f76ed14a32f34580811d1a07ac357352bbc4", "shasum": "" }, "require": { "ext-iconv": "*", "nette/utils": "^4.0", - "php": "8.0 - 8.3" + "php": "8.0 - 8.5" }, "require-dev": { "nette/di": "^3.1 || ^4.0", "nette/tester": "^2.4", - "phpstan/phpstan-nette": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.8" }, "suggest": { @@ -4014,6 +3885,9 @@ } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -4034,7 +3908,7 @@ "homepage": "https://nette.org/contributors" } ], - "description": "📧 Nette Mail: handy email creation and transfer library for PHP with both text and MIME-compliant support.", + "description": "📧 Nette Mail: A handy library for creating and sending emails in PHP.", "homepage": "https://nette.org", "keywords": [ "mail", @@ -4045,31 +3919,31 @@ ], "support": { "issues": "https://github.com/nette/mail/issues", - "source": "https://github.com/nette/mail/tree/v4.0.2" + "source": "https://github.com/nette/mail/tree/v4.0.4" }, - "time": "2023-10-02T20:59:33+00:00" + "time": "2025-08-01T02:09:42+00:00" }, { "name": "nette/neon", - "version": "v3.4.3", + "version": "v3.4.5", "source": { "type": "git", "url": "https://github.com/nette/neon.git", - "reference": "c8481c104431c8d94cc88424a1e21f47f8c93280" + "reference": "0b14d95a19c4ca0666339170d3a7fcf83a32fd6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/neon/zipball/c8481c104431c8d94cc88424a1e21f47f8c93280", - "reference": "c8481c104431c8d94cc88424a1e21f47f8c93280", + "url": "https://api.github.com/repos/nette/neon/zipball/0b14d95a19c4ca0666339170d3a7fcf83a32fd6b", + "reference": "0b14d95a19c4ca0666339170d3a7fcf83a32fd6b", "shasum": "" }, "require": { "ext-json": "*", - "php": "8.0 - 8.3" + "php": "8.0 - 8.5" }, "require-dev": { "nette/tester": "^2.4", - "phpstan/phpstan": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.7" }, "bin": [ @@ -4082,6 +3956,9 @@ } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -4103,7 +3980,7 @@ } ], "description": "🍸 Nette NEON: encodes and decodes NEON file format.", - "homepage": "https://ne-on.org", + "homepage": "https://neon.nette.org", "keywords": [ "export", "import", @@ -4113,33 +3990,33 @@ ], "support": { "issues": "https://github.com/nette/neon/issues", - "source": "https://github.com/nette/neon/tree/v3.4.3" + "source": "https://github.com/nette/neon/tree/v3.4.5" }, - "time": "2024-06-26T14:53:59+00:00" + "time": "2025-10-30T22:42:06+00:00" }, { "name": "nette/php-generator", - "version": "v4.1.6", + "version": "v4.2.0", "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", - "reference": "c90961e782ae86e517fe5ed732eb2b512945565b" + "reference": "4707546a1f11badd72f5d82af4f8a6bc64bd56ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/c90961e782ae86e517fe5ed732eb2b512945565b", - "reference": "c90961e782ae86e517fe5ed732eb2b512945565b", + "url": "https://api.github.com/repos/nette/php-generator/zipball/4707546a1f11badd72f5d82af4f8a6bc64bd56ac", + "reference": "4707546a1f11badd72f5d82af4f8a6bc64bd56ac", "shasum": "" }, "require": { - "nette/utils": "^3.2.9 || ^4.0", - "php": "8.0 - 8.4" + "nette/utils": "^4.0.6", + "php": "8.1 - 8.5" }, "require-dev": { - "jetbrains/phpstorm-attributes": "dev-master", + "jetbrains/phpstorm-attributes": "^1.2", "nette/tester": "^2.4", - "nikic/php-parser": "^4.18 || ^5.0", - "phpstan/phpstan": "^1.0", + "nikic/php-parser": "^5.0", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.8" }, "suggest": { @@ -4148,10 +4025,13 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -4172,7 +4052,7 @@ "homepage": "https://nette.org/contributors" } ], - "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.3 features.", + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.5 features.", "homepage": "https://nette.org", "keywords": [ "code", @@ -4182,41 +4062,44 @@ ], "support": { "issues": "https://github.com/nette/php-generator/issues", - "source": "https://github.com/nette/php-generator/tree/v4.1.6" + "source": "https://github.com/nette/php-generator/tree/v4.2.0" }, - "time": "2024-09-10T09:31:55+00:00" + "time": "2025-08-06T18:24:31+00:00" }, { "name": "nette/robot-loader", - "version": "v4.0.2", + "version": "v4.1.0", "source": { "type": "git", "url": "https://github.com/nette/robot-loader.git", - "reference": "6a921e88345fc7263b89ed878c927efc7c5e6092" + "reference": "805fb81376c24755d50bdb8bc69ca4db3def71d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/robot-loader/zipball/6a921e88345fc7263b89ed878c927efc7c5e6092", - "reference": "6a921e88345fc7263b89ed878c927efc7c5e6092", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/805fb81376c24755d50bdb8bc69ca4db3def71d1", + "reference": "805fb81376c24755d50bdb8bc69ca4db3def71d1", "shasum": "" }, "require": { "ext-tokenizer": "*", "nette/utils": "^4.0", - "php": "8.0 - 8.3" + "php": "8.1 - 8.5" }, "require-dev": { "nette/tester": "^2.4", - "phpstan/phpstan": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "4.1-dev" } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -4248,32 +4131,32 @@ ], "support": { "issues": "https://github.com/nette/robot-loader/issues", - "source": "https://github.com/nette/robot-loader/tree/v4.0.2" + "source": "https://github.com/nette/robot-loader/tree/v4.1.0" }, - "time": "2024-06-18T20:19:22+00:00" + "time": "2025-08-06T18:34:21+00:00" }, { "name": "nette/routing", - "version": "v3.1.0", + "version": "v3.1.2", "source": { "type": "git", "url": "https://github.com/nette/routing.git", - "reference": "f7419bc147164106cb03b3d331c85aff6cb81fc3" + "reference": "14c466f3383add0d4f78a82074d3c9841f8edf47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/routing/zipball/f7419bc147164106cb03b3d331c85aff6cb81fc3", - "reference": "f7419bc147164106cb03b3d331c85aff6cb81fc3", + "url": "https://api.github.com/repos/nette/routing/zipball/14c466f3383add0d4f78a82074d3c9841f8edf47", + "reference": "14c466f3383add0d4f78a82074d3c9841f8edf47", "shasum": "" }, "require": { "nette/http": "^3.2 || ~4.0.0", "nette/utils": "^4.0", - "php": "8.1 - 8.3" + "php": "8.1 - 8.5" }, "require-dev": { "nette/tester": "^2.5", - "phpstan/phpstan": "^1", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.9" }, "type": "library", @@ -4283,6 +4166,9 @@ } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -4310,30 +4196,30 @@ ], "support": { "issues": "https://github.com/nette/routing/issues", - "source": "https://github.com/nette/routing/tree/v3.1.0" + "source": "https://github.com/nette/routing/tree/v3.1.2" }, - "time": "2024-01-21T21:13:45+00:00" + "time": "2025-10-31T00:55:27+00:00" }, { "name": "nette/safe-stream", - "version": "v3.0.1", + "version": "v3.0.3", "source": { "type": "git", "url": "https://github.com/nette/safe-stream.git", - "reference": "b9a275f7f2517cacac6ab4360a73722340478bce" + "reference": "1c26efc4f09117d4ac6b8e56c97c8b61d1f5427a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/safe-stream/zipball/b9a275f7f2517cacac6ab4360a73722340478bce", - "reference": "b9a275f7f2517cacac6ab4360a73722340478bce", + "url": "https://api.github.com/repos/nette/safe-stream/zipball/1c26efc4f09117d4ac6b8e56c97c8b61d1f5427a", + "reference": "1c26efc4f09117d4ac6b8e56c97c8b61d1f5427a", "shasum": "" }, "require": { - "php": "8.0 - 8.3" + "php": "8.0 - 8.5" }, "require-dev": { "nette/tester": "^2.4", - "phpstan/phpstan": "^0.12", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.8" }, "type": "library", @@ -4378,31 +4264,31 @@ ], "support": { "issues": "https://github.com/nette/safe-stream/issues", - "source": "https://github.com/nette/safe-stream/tree/v3.0.1" + "source": "https://github.com/nette/safe-stream/tree/v3.0.3" }, - "time": "2023-08-05T18:54:54+00:00" + "time": "2025-08-01T02:24:13+00:00" }, { "name": "nette/schema", - "version": "v1.3.2", + "version": "v1.3.3", "source": { "type": "git", "url": "https://github.com/nette/schema.git", - "reference": "da801d52f0354f70a638673c4a0f04e16529431d" + "reference": "2befc2f42d7c715fd9d95efc31b1081e5d765004" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/schema/zipball/da801d52f0354f70a638673c4a0f04e16529431d", - "reference": "da801d52f0354f70a638673c4a0f04e16529431d", + "url": "https://api.github.com/repos/nette/schema/zipball/2befc2f42d7c715fd9d95efc31b1081e5d765004", + "reference": "2befc2f42d7c715fd9d95efc31b1081e5d765004", "shasum": "" }, "require": { "nette/utils": "^4.0", - "php": "8.1 - 8.4" + "php": "8.1 - 8.5" }, "require-dev": { "nette/tester": "^2.5.2", - "phpstan/phpstan-nette": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.8" }, "type": "library", @@ -4412,6 +4298,9 @@ } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -4440,38 +4329,38 @@ ], "support": { "issues": "https://github.com/nette/schema/issues", - "source": "https://github.com/nette/schema/tree/v1.3.2" + "source": "https://github.com/nette/schema/tree/v1.3.3" }, - "time": "2024-10-06T23:10:23+00:00" + "time": "2025-10-30T22:57:59+00:00" }, { "name": "nette/security", - "version": "v3.2.0", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/nette/security.git", - "reference": "fe89d52697036fb2e14835dfb46b696d28a9ebf6" + "reference": "beca6757457281ebc9428743bec7960809f40d49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/security/zipball/fe89d52697036fb2e14835dfb46b696d28a9ebf6", - "reference": "fe89d52697036fb2e14835dfb46b696d28a9ebf6", + "url": "https://api.github.com/repos/nette/security/zipball/beca6757457281ebc9428743bec7960809f40d49", + "reference": "beca6757457281ebc9428743bec7960809f40d49", "shasum": "" }, "require": { "nette/utils": "^4.0", - "php": "8.1 - 8.3" + "php": "8.1 - 8.5" }, "conflict": { "nette/di": "<3.0-stable", "nette/http": "<3.1.3" }, "require-dev": { - "mockery/mockery": "^1.5", + "mockery/mockery": "^1.6@stable", "nette/di": "^3.1", "nette/http": "^3.2", "nette/tester": "^2.5", - "phpstan/phpstan-nette": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.9" }, "type": "library", @@ -4481,6 +4370,9 @@ } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -4511,35 +4403,35 @@ ], "support": { "issues": "https://github.com/nette/security/issues", - "source": "https://github.com/nette/security/tree/v3.2.0" + "source": "https://github.com/nette/security/tree/v3.2.2" }, - "time": "2024-01-21T21:33:53+00:00" + "time": "2025-08-01T02:15:08+00:00" }, { "name": "nette/utils", - "version": "v4.0.6", + "version": "v4.0.8", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "ce708655043c7050eb050df361c5e313cf708309" + "reference": "c930ca4e3cf4f17dcfb03037703679d2396d2ede" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/ce708655043c7050eb050df361c5e313cf708309", - "reference": "ce708655043c7050eb050df361c5e313cf708309", + "url": "https://api.github.com/repos/nette/utils/zipball/c930ca4e3cf4f17dcfb03037703679d2396d2ede", + "reference": "c930ca4e3cf4f17dcfb03037703679d2396d2ede", "shasum": "" }, "require": { - "php": "8.0 - 8.4" + "php": "8.0 - 8.5" }, "conflict": { "nette/finder": "<3", "nette/schema": "<1.2.2" }, "require-dev": { - "jetbrains/phpstorm-attributes": "dev-master", + "jetbrains/phpstorm-attributes": "^1.2", "nette/tester": "^2.5", - "phpstan/phpstan": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "tracy/tracy": "^2.9" }, "suggest": { @@ -4557,6 +4449,9 @@ } }, "autoload": { + "psr-4": { + "Nette\\": "src" + }, "classmap": [ "src/" ] @@ -4597,43 +4492,39 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.0.6" + "source": "https://github.com/nette/utils/tree/v4.0.8" }, - "time": "2025-03-30T21:06:30+00:00" + "time": "2025-08-06T21:43:34+00:00" }, { "name": "nettrine/annotations", - "version": "v0.7.0", + "version": "v0.8.1", "source": { "type": "git", "url": "https://github.com/contributte/doctrine-annotations.git", - "reference": "fbb06d156a4edcbf37e4154e5b4ede079136388b" + "reference": "d284d9108f335ca2c9a9ee2ec16bebfbaabf0b35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/contributte/doctrine-annotations/zipball/fbb06d156a4edcbf37e4154e5b4ede079136388b", - "reference": "fbb06d156a4edcbf37e4154e5b4ede079136388b", + "url": "https://api.github.com/repos/contributte/doctrine-annotations/zipball/d284d9108f335ca2c9a9ee2ec16bebfbaabf0b35", + "reference": "d284d9108f335ca2c9a9ee2ec16bebfbaabf0b35", "shasum": "" }, "require": { - "contributte/di": "^0.5.0", "doctrine/annotations": "^1.6.1", - "nettrine/cache": "^0.3.0", - "php": ">=7.2" + "nette/di": "^3.1.2", + "nettrine/cache": "^0.4.0 || ^0.5.0", + "php": ">=8.1" }, "require-dev": { - "ninjify/qa": "^0.10.0", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan-deprecation-rules": "^0.11.0", - "phpstan/phpstan-nette": "^0.11.0", - "phpstan/phpstan-shim": "^0.11.5", - "phpstan/phpstan-strict-rules": "^0.11.0", - "phpunit/phpunit": "^8.1.0" + "contributte/phpstan": "^0.1", + "contributte/qa": "^0.4", + "contributte/tester": "^0.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "0.8.x-dev" + "dev-master": "0.9.x-dev" } }, "autoload": { @@ -4649,14 +4540,10 @@ { "name": "Milan Felix Šulc", "homepage": "https://f3l1x.io" - }, - { - "name": "Marek Bartoš", - "homepage": "https://github.com/mabar" } ], "description": "Doctrine Annotations for Nette Framework", - "homepage": "https://github.com/nettrine/annotations", + "homepage": "https://github.com/contributte/doctrine-annotations", "keywords": [ "annotations", "doctrine", @@ -4665,7 +4552,7 @@ ], "support": { "issues": "https://github.com/contributte/doctrine-annotations/issues", - "source": "https://github.com/contributte/doctrine-annotations/tree/v0.7.0" + "source": "https://github.com/contributte/doctrine-annotations/tree/v0.8.1" }, "funding": [ { @@ -4677,40 +4564,38 @@ "type": "github" } ], - "time": "2020-12-10T18:01:50+00:00" + "time": "2023-07-03T16:12:16+00:00" }, { "name": "nettrine/cache", - "version": "v0.3.0", + "version": "v0.5.0", "source": { "type": "git", "url": "https://github.com/contributte/doctrine-cache.git", - "reference": "8a58596de24cdd61e45866ef8f35788675f6d2bc" + "reference": "85223ef25e1dd4e35471405aed254e9da983e4a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/contributte/doctrine-cache/zipball/8a58596de24cdd61e45866ef8f35788675f6d2bc", - "reference": "8a58596de24cdd61e45866ef8f35788675f6d2bc", + "url": "https://api.github.com/repos/contributte/doctrine-cache/zipball/85223ef25e1dd4e35471405aed254e9da983e4a3", + "reference": "85223ef25e1dd4e35471405aed254e9da983e4a3", "shasum": "" }, "require": { - "contributte/di": "^0.5.0", - "doctrine/cache": "^1.8.0", - "php": ">=7.2" + "doctrine/cache": "^2.2.0", + "nette/di": "^3.2.4", + "php": ">=8.2", + "symfony/cache": "^7.2.1" }, "require-dev": { - "ninjify/qa": "^0.9.0", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan-deprecation-rules": "^0.11.0", - "phpstan/phpstan-nette": "^0.11.0", - "phpstan/phpstan-shim": "^0.11.5", - "phpstan/phpstan-strict-rules": "^0.11.0", - "phpunit/phpunit": "^8.1.0" + "contributte/phpstan": "^0.2", + "contributte/qa": "^0.4", + "contributte/tester": "^0.3", + "tracy/tracy": "^2.10.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "0.3.x-dev" + "dev-master": "0.6.x-dev" } }, "autoload": { @@ -4720,16 +4605,16 @@ }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MPL-2.0" + "MIT" ], "authors": [ { - "name": "Marek Bartoš", - "homepage": "https://github.com/mabar" + "name": "Milan Felix Šulc", + "homepage": "https://f3l1x.io" } ], "description": "Doctrine Cache for Nette Framework", - "homepage": "https://github.com/nettrine/cache", + "homepage": "https://github.com/contributte/doctrine-cache", "keywords": [ "cache", "doctrine", @@ -4738,7 +4623,7 @@ ], "support": { "issues": "https://github.com/contributte/doctrine-cache/issues", - "source": "https://github.com/contributte/doctrine-cache/tree/v0.3.0" + "source": "https://github.com/contributte/doctrine-cache/tree/v0.5.0" }, "funding": [ { @@ -4750,43 +4635,43 @@ "type": "github" } ], - "time": "2020-12-10T17:56:32+00:00" + "time": "2025-01-10T17:33:34+00:00" }, { "name": "nettrine/dbal", - "version": "v0.8.2", + "version": "v0.9.0", "source": { "type": "git", "url": "https://github.com/contributte/doctrine-dbal.git", - "reference": "e5d38af256c05617c1387ecba8f04ec58c32447a" + "reference": "15bd7770b098edb6c47909990506bdd7f6449d49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/contributte/doctrine-dbal/zipball/e5d38af256c05617c1387ecba8f04ec58c32447a", - "reference": "e5d38af256c05617c1387ecba8f04ec58c32447a", + "url": "https://api.github.com/repos/contributte/doctrine-dbal/zipball/15bd7770b098edb6c47909990506bdd7f6449d49", + "reference": "15bd7770b098edb6c47909990506bdd7f6449d49", "shasum": "" }, "require": { - "contributte/di": "^0.5.0", - "doctrine/dbal": "^3.5.3", - "nettrine/cache": "^0.3.0", - "php": ">=7.4" + "doctrine/dbal": "^3.6.7", + "nette/di": "^3.2.2", + "nettrine/cache": "^0.4.0 || ^0.5.0", + "php": ">=8.1" }, "conflict": { + "doctrine/event-manager": "<2.0.0", "nette/di": "<3.0.6", "nette/schema": "<1.1.0" }, "require-dev": { - "contributte/console": "^0.9.1", + "contributte/console": "^0.10.1", + "contributte/phpstan": "^0.1", + "contributte/qa": "^0.4", + "contributte/tester": "^0.3", + "ext-pdo": "*", "mockery/mockery": "^1.3.5", - "ninjify/nunjuck": "^0.4", - "ninjify/qa": "^0.13", - "phpstan/phpstan": "^1.2.0", - "phpstan/phpstan-deprecation-rules": "^1.0.0", - "phpstan/phpstan-nette": "^1.0.0", - "phpstan/phpstan-strict-rules": "^1.1.0", - "psr/log": "^1.1 || ^2.0 || ^3.0", - "tracy/tracy": "^2.6.2" + "nettrine/orm": "^0.9.0", + "psr/log": "^3.0", + "tracy/tracy": "^2.10.3" }, "type": "library", "extra": { @@ -4822,7 +4707,7 @@ ], "support": { "issues": "https://github.com/contributte/doctrine-dbal/issues", - "source": "https://github.com/contributte/doctrine-dbal/tree/v0.8.2" + "source": "https://github.com/contributte/doctrine-dbal/tree/v0.9.0" }, "funding": [ { @@ -4834,7 +4719,7 @@ "type": "github" } ], - "time": "2023-01-13T16:26:05+00:00" + "time": "2024-07-22T07:03:27+00:00" }, { "name": "nettrine/extensions-atlantic18", @@ -4913,35 +4798,35 @@ }, { "name": "nettrine/migrations", - "version": "v0.9.1", + "version": "v0.10.0", "source": { "type": "git", "url": "https://github.com/contributte/doctrine-migrations.git", - "reference": "a201572c58184e912b96e7fa96d656e6bd1bd09f" + "reference": "e553bc0439f9359bea05a715f1239b972fcff5f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/contributte/doctrine-migrations/zipball/a201572c58184e912b96e7fa96d656e6bd1bd09f", - "reference": "a201572c58184e912b96e7fa96d656e6bd1bd09f", + "url": "https://api.github.com/repos/contributte/doctrine-migrations/zipball/e553bc0439f9359bea05a715f1239b972fcff5f1", + "reference": "e553bc0439f9359bea05a715f1239b972fcff5f1", "shasum": "" }, "require": { - "doctrine/migrations": "^3.6.0", - "nette/di": "^3.1.2", - "php": ">=8.1", - "symfony/console": "^6.2.0" + "doctrine/migrations": "^3.8.2", + "nette/di": "^3.2.3", + "php": ">=8.2" }, "require-dev": { - "contributte/phpstan": "^0.1", - "contributte/qa": "^0.4", - "contributte/tester": "^0.3", - "doctrine/orm": "^2.6", - "mockery/mockery": "^1.3.0" + "contributte/phpstan": "^0.2.0", + "contributte/qa": "^0.4.0", + "contributte/tester": "^0.4.0", + "doctrine/orm": "^3.3.0", + "mockery/mockery": "^1.6.12", + "symfony/console": "^7.2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "0.10.x-dev" + "dev-master": "0.11.x-dev" } }, "autoload": { @@ -4972,7 +4857,7 @@ ], "support": { "issues": "https://github.com/contributte/doctrine-migrations/issues", - "source": "https://github.com/contributte/doctrine-migrations/tree/v0.9.1" + "source": "https://github.com/contributte/doctrine-migrations/tree/v0.10.0" }, "funding": [ { @@ -4984,49 +4869,48 @@ "type": "github" } ], - "time": "2023-07-03T16:24:04+00:00" + "time": "2025-01-10T15:55:13+00:00" }, { "name": "nettrine/orm", - "version": "v0.8.4", + "version": "v0.9.0", "source": { "type": "git", "url": "https://github.com/contributte/doctrine-orm.git", - "reference": "d253e200217293ede49a4c4ca76c6e0d43b57242" + "reference": "f3afa2cf045259e1f4c996a693643510656ff95c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/contributte/doctrine-orm/zipball/d253e200217293ede49a4c4ca76c6e0d43b57242", - "reference": "d253e200217293ede49a4c4ca76c6e0d43b57242", + "url": "https://api.github.com/repos/contributte/doctrine-orm/zipball/f3afa2cf045259e1f4c996a693643510656ff95c", + "reference": "f3afa2cf045259e1f4c996a693643510656ff95c", "shasum": "" }, "require": { - "contributte/di": "^0.5.0", - "doctrine/common": "^2.13.1 || ^3.0.0", - "doctrine/orm": "^2.6.3", - "nettrine/annotations": "^0.7.0 || ^0.8.0", - "nettrine/cache": "^0.3.0 || ^0.4.0", - "nettrine/dbal": "^0.7.0 || ^0.8.0", - "php": ">=7.2", - "symfony/console": "^4.2.5|^5.0.0|^6.0.0" + "doctrine/common": "^3.4.3", + "doctrine/orm": "^2.14.0", + "nette/di": "^3.1.2", + "nettrine/annotations": "^0.8.0 || ^0.9.0", + "nettrine/cache": "^0.4.0 || ^0.5.0", + "nettrine/dbal": "^0.8.0 || ^0.9.0", + "php": ">=8.1", + "symfony/console": "^5.3.0 || ^6.2.0 || ^7.0.0 " }, "conflict": { + "doctrine/persistence": "<3.0.0", "nette/di": "<3.0.6", "nette/schema": "<1.1.0" }, "require-dev": { + "contributte/phpstan": "^0.1", + "contributte/qa": "^0.4", + "contributte/tester": "^0.3", "mockery/mockery": "^1.3.1", - "ninjify/nunjuck": "^0.4", - "ninjify/qa": "^0.12", - "phpstan/phpstan": "^1.4.0", - "phpstan/phpstan-deprecation-rules": "^1.0.0", - "phpstan/phpstan-nette": "^1.0.0", - "phpstan/phpstan-strict-rules": "^1.0.0" + "tracy/tracy": "^2.10.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "0.8.x-dev" + "dev-master": "0.9.x-dev" } }, "autoload": { @@ -5054,7 +4938,7 @@ ], "support": { "issues": "https://github.com/contributte/doctrine-orm/issues", - "source": "https://github.com/contributte/doctrine-orm/tree/v0.8.4" + "source": "https://github.com/contributte/doctrine-orm/tree/v0.9.0" }, "funding": [ { @@ -5066,50 +4950,155 @@ "type": "github" } ], - "time": "2022-12-27T18:27:01+00:00" + "time": "2024-08-20T09:11:52+00:00" }, { - "name": "psr/cache", - "version": "3.0.0", + "name": "nikic/php-parser", + "version": "v5.6.2", "source": { "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "3a454ca033b9e06b63282ce19562e892747449bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", - "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3a454ca033b9e06b63282ce19562e892747449bb", + "reference": "3a454ca033b9e06b63282ce19562e892747449bb", "shasum": "" }, "require": { - "php": ">=8.0.0" + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" }, + "bin": [ + "bin/php-parse" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "5.x-dev" } }, "autoload": { "psr-4": { - "Psr\\Cache\\": "src/" + "PhpParser\\": "lib/PhpParser" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Nikita Popov" } ], - "description": "Common interface for caching libraries", + "description": "A PHP parser written in PHP", "keywords": [ - "cache", - "psr", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.2" + }, + "time": "2025-10-21T19:32:17+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495", + "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^5.3.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0" + }, + "time": "2025-08-30T15:50:23+00:00" + }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", "psr-6" ], "support": { @@ -5575,16 +5564,16 @@ }, { "name": "ramsey/collection", - "version": "2.0.0", + "version": "2.1.1", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", - "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "url": "https://api.github.com/repos/ramsey/collection/zipball/344572933ad0181accbf4ba763e85a0306a8c5e2", + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2", "shasum": "" }, "require": { @@ -5592,25 +5581,22 @@ }, "require-dev": { "captainhook/plugin-composer": "^5.3", - "ergebnis/composer-normalize": "^2.28.3", - "fakerphp/faker": "^1.21", + "ergebnis/composer-normalize": "^2.45", + "fakerphp/faker": "^1.24", "hamcrest/hamcrest-php": "^2.0", - "jangregor/phpstan-prophecy": "^1.0", - "mockery/mockery": "^1.5", + "jangregor/phpstan-prophecy": "^2.1", + "mockery/mockery": "^1.6", "php-parallel-lint/php-console-highlighter": "^1.0", - "php-parallel-lint/php-parallel-lint": "^1.3", - "phpcsstandards/phpcsutils": "^1.0.0-rc1", - "phpspec/prophecy-phpunit": "^2.0", - "phpstan/extension-installer": "^1.2", - "phpstan/phpstan": "^1.9", - "phpstan/phpstan-mockery": "^1.1", - "phpstan/phpstan-phpunit": "^1.3", - "phpunit/phpunit": "^9.5", - "psalm/plugin-mockery": "^1.1", - "psalm/plugin-phpunit": "^0.18.4", - "ramsey/coding-standard": "^2.0.3", - "ramsey/conventional-commits": "^1.3", - "vimeo/psalm": "^5.4" + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpspec/prophecy-phpunit": "^2.3", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5", + "ramsey/coding-standard": "^2.3", + "ramsey/conventional-commits": "^1.6", + "roave/security-advisories": "dev-latest" }, "type": "library", "extra": { @@ -5648,37 +5634,26 @@ ], "support": { "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/2.0.0" + "source": "https://github.com/ramsey/collection/tree/2.1.1" }, - "funding": [ - { - "url": "https://github.com/ramsey", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", - "type": "tidelift" - } - ], - "time": "2022-12-31T21:50:55+00:00" + "time": "2025-03-22T05:38:12+00:00" }, { "name": "ramsey/uuid", - "version": "4.7.6", + "version": "4.9.1", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "91039bc1faa45ba123c4328958e620d382ec7088" + "reference": "81f941f6f729b1e3ceea61d9d014f8b6c6800440" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088", - "reference": "91039bc1faa45ba123c4328958e620d382ec7088", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/81f941f6f729b1e3ceea61d9d014f8b6c6800440", + "reference": "81f941f6f729b1e3ceea61d9d014f8b6c6800440", "shasum": "" }, "require": { - "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12", - "ext-json": "*", + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14", "php": "^8.0", "ramsey/collection": "^1.2 || ^2.0" }, @@ -5686,26 +5661,23 @@ "rhumsaa/uuid": "self.version" }, "require-dev": { - "captainhook/captainhook": "^5.10", + "captainhook/captainhook": "^5.25", "captainhook/plugin-composer": "^5.3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "doctrine/annotations": "^1.8", - "ergebnis/composer-normalize": "^2.15", - "mockery/mockery": "^1.3", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "ergebnis/composer-normalize": "^2.47", + "mockery/mockery": "^1.6", "paragonie/random-lib": "^2", - "php-mock/php-mock": "^2.2", - "php-mock/php-mock-mockery": "^1.3", - "php-parallel-lint/php-parallel-lint": "^1.1", - "phpbench/phpbench": "^1.0", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-mockery": "^1.1", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^8.5 || ^9", - "ramsey/composer-repl": "^1.4", - "slevomat/coding-standard": "^8.4", - "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^4.9" + "php-mock/php-mock": "^2.6", + "php-mock/php-mock-mockery": "^1.5", + "php-parallel-lint/php-parallel-lint": "^1.4.0", + "phpbench/phpbench": "^1.2.14", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6", + "slevomat/coding-standard": "^8.18", + "squizlabs/php_codesniffer": "^3.13" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", @@ -5740,19 +5712,9 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.7.6" + "source": "https://github.com/ramsey/uuid/tree/4.9.1" }, - "funding": [ - { - "url": "https://github.com/ramsey", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", - "type": "tidelift" - } - ], - "time": "2024-04-27T21:32:50+00:00" + "time": "2025-09-04T20:59:21+00:00" }, { "name": "ramsey/uuid-doctrine", @@ -5840,16 +5802,16 @@ }, { "name": "sebastian/comparator", - "version": "6.1.0", + "version": "6.3.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa37b9e2ca618cb051d71b60120952ee8ca8b03d" + "reference": "85c77556683e6eee4323e4c5468641ca0237e2e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa37b9e2ca618cb051d71b60120952ee8ca8b03d", - "reference": "fa37b9e2ca618cb051d71b60120952ee8ca8b03d", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/85c77556683e6eee4323e4c5468641ca0237e2e8", + "reference": "85c77556683e6eee4323e4c5468641ca0237e2e8", "shasum": "" }, "require": { @@ -5860,12 +5822,15 @@ "sebastian/exporter": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^11.3" + "phpunit/phpunit": "^11.4" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.1-dev" + "dev-main": "6.3-dev" } }, "autoload": { @@ -5905,15 +5870,27 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/6.1.0" + "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.2" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" } ], - "time": "2024-09-11T15:42:56+00:00" + "time": "2025-08-10T08:07:46+00:00" }, { "name": "sebastian/diff", @@ -5984,16 +5961,16 @@ }, { "name": "sebastian/exporter", - "version": "6.1.3", + "version": "6.3.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e" + "reference": "70a298763b40b213ec087c51c739efcaa90bcd74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", - "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/70a298763b40b213ec087c51c739efcaa90bcd74", + "reference": "70a298763b40b213ec087c51c739efcaa90bcd74", "shasum": "" }, "require": { @@ -6002,12 +5979,12 @@ "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^11.2" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.1-dev" + "dev-main": "6.3-dev" } }, "autoload": { @@ -6050,35 +6027,47 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/6.1.3" + "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.2" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" } ], - "time": "2024-07-03T04:56:19+00:00" + "time": "2025-09-24T06:12:51+00:00" }, { "name": "sebastian/recursion-context", - "version": "6.0.2", + "version": "6.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" + "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", - "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/f6458abbf32a6c8174f8f26261475dc133b3d9dc", + "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { @@ -6114,15 +6103,27 @@ "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" } ], - "time": "2024-07-03T05:10:34+00:00" + "time": "2025-08-13T04:42:22+00:00" }, { "name": "spatie/regex", @@ -6189,23 +6190,23 @@ }, { "name": "symfony/cache", - "version": "v7.1.5", + "version": "v7.3.5", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "86e5296b10e4dec8c8441056ca606aedb8a3be0a" + "reference": "4a55feb59664f49042a0824c0f955e2f4c1412ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/86e5296b10e4dec8c8441056ca606aedb8a3be0a", - "reference": "86e5296b10e4dec8c8441056ca606aedb8a3be0a", + "url": "https://api.github.com/repos/symfony/cache/zipball/4a55feb59664f49042a0824c0f955e2f4c1412ad", + "reference": "4a55feb59664f49042a0824c0f955e2f4c1412ad", "shasum": "" }, "require": { "php": ">=8.2", "psr/cache": "^2.0|^3.0", "psr/log": "^1.1|^2|^3", - "symfony/cache-contracts": "^2.5|^3", + "symfony/cache-contracts": "^3.6", "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/service-contracts": "^2.5|^3", "symfony/var-exporter": "^6.4|^7.0" @@ -6226,6 +6227,7 @@ "doctrine/dbal": "^3.6|^4", "predis/predis": "^1.1|^2.0", "psr/simple-cache": "^1.0|^2.0|^3.0", + "symfony/clock": "^6.4|^7.0", "symfony/config": "^6.4|^7.0", "symfony/dependency-injection": "^6.4|^7.0", "symfony/filesystem": "^6.4|^7.0", @@ -6266,7 +6268,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v7.1.5" + "source": "https://github.com/symfony/cache/tree/v7.3.5" }, "funding": [ { @@ -6277,25 +6279,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-17T09:16:35+00:00" + "time": "2025-10-16T13:55:38+00:00" }, { "name": "symfony/cache-contracts", - "version": "v3.5.0", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/cache-contracts.git", - "reference": "df6a1a44c890faded49a5fca33c2d5c5fd3c2197" + "reference": "5d68a57d66910405e5c0b63d6f0af941e66fc868" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/df6a1a44c890faded49a5fca33c2d5c5fd3c2197", - "reference": "df6a1a44c890faded49a5fca33c2d5c5fd3c2197", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/5d68a57d66910405e5c0b63d6f0af941e66fc868", + "reference": "5d68a57d66910405e5c0b63d6f0af941e66fc868", "shasum": "" }, "require": { @@ -6304,12 +6310,12 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" } }, "autoload": { @@ -6342,7 +6348,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/cache-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/cache-contracts/tree/v3.6.0" }, "funding": [ { @@ -6358,51 +6364,51 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2025-03-13T15:25:07+00:00" }, { "name": "symfony/console", - "version": "v6.4.12", + "version": "v7.3.5", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "72d080eb9edf80e36c19be61f72c98ed8273b765" + "reference": "cdb80fa5869653c83cfe1a9084a673b6daf57ea7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/72d080eb9edf80e36c19be61f72c98ed8273b765", - "reference": "72d080eb9edf80e36c19be61f72c98ed8273b765", + "url": "https://api.github.com/repos/symfony/console/zipball/cdb80fa5869653c83cfe1a9084a673b6daf57ea7", + "reference": "cdb80fa5869653c83cfe1a9084a673b6daf57ea7", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^5.4|^6.0|^7.0" + "symfony/string": "^7.2" }, "conflict": { - "symfony/dependency-injection": "<5.4", - "symfony/dotenv": "<5.4", - "symfony/event-dispatcher": "<5.4", - "symfony/lock": "<5.4", - "symfony/process": "<5.4" + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", "symfony/http-foundation": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^5.4|^6.0|^7.0", - "symfony/messenger": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/stopwatch": "^5.4|^6.0|^7.0", - "symfony/var-dumper": "^5.4|^6.0|^7.0" + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6436,7 +6442,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.12" + "source": "https://github.com/symfony/console/tree/v7.3.5" }, "funding": [ { @@ -6447,25 +6453,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-20T08:15:52+00:00" + "time": "2025-10-14T15:46:26+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.5.1", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", "shasum": "" }, "require": { @@ -6478,7 +6488,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.5-dev" + "dev-main": "3.6-dev" } }, "autoload": { @@ -6503,7 +6513,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" }, "funding": [ { @@ -6519,20 +6529,20 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/finder", - "version": "v7.1.4", + "version": "v7.3.5", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "d95bbf319f7d052082fb7af147e0f835a695e823" + "reference": "9f696d2f1e340484b4683f7853b273abff94421f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823", - "reference": "d95bbf319f7d052082fb7af147e0f835a695e823", + "url": "https://api.github.com/repos/symfony/finder/zipball/9f696d2f1e340484b4683f7853b273abff94421f", + "reference": "9f696d2f1e340484b4683f7853b273abff94421f", "shasum": "" }, "require": { @@ -6567,7 +6577,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.1.4" + "source": "https://github.com/symfony/finder/tree/v7.3.5" }, "funding": [ { @@ -6578,16 +6588,20 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-08-13T14:28:19+00:00" + "time": "2025-10-15T18:45:57+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.31.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -6611,8 +6625,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -6646,7 +6660,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" }, "funding": [ { @@ -6657,6 +6671,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -6666,16 +6684,16 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.31.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", - "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", "shasum": "" }, "require": { @@ -6687,8 +6705,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -6724,7 +6742,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" }, "funding": [ { @@ -6735,16 +6753,20 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2025-06-27T09:58:17+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.31.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", @@ -6765,8 +6787,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -6805,7 +6827,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" }, "funding": [ { @@ -6816,6 +6838,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -6825,19 +6851,20 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.31.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", "shasum": "" }, "require": { + "ext-iconv": "*", "php": ">=7.2" }, "provide": { @@ -6849,8 +6876,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -6885,7 +6912,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" }, "funding": [ { @@ -6896,12 +6923,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2024-12-23T08:48:59+00:00" }, { "name": "symfony/polyfill-php72", @@ -6923,8 +6954,8 @@ "type": "metapackage", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "notification-url": "https://packagist.org/downloads/", @@ -6970,7 +7001,7 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.32.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", @@ -7030,7 +7061,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.32.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" }, "funding": [ { @@ -7041,6 +7072,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -7048,18 +7083,98 @@ ], "time": "2025-01-02T08:10:11+00:00" }, + { + "name": "symfony/polyfill-php84", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php84.git", + "reference": "d8ced4d875142b6a7426000426b8abc631d6b191" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191", + "reference": "d8ced4d875142b6a7426000426b8abc631d6b191", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php84\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-24T13:30:11+00:00" + }, { "name": "symfony/process", - "version": "v7.1.7", + "version": "v7.3.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "9b8a40b7289767aa7117e957573c2a535efe6585" + "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/9b8a40b7289767aa7117e957573c2a535efe6585", - "reference": "9b8a40b7289767aa7117e957573c2a535efe6585", + "url": "https://api.github.com/repos/symfony/process/zipball/f24f8f316367b30810810d4eb30c543d7003ff3b", + "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b", "shasum": "" }, "require": { @@ -7091,7 +7206,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.1.7" + "source": "https://github.com/symfony/process/tree/v7.3.4" }, "funding": [ { @@ -7102,25 +7217,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-11-06T09:25:12+00:00" + "time": "2025-09-11T10:12:26+00:00" }, { "name": "symfony/property-access", - "version": "v7.1.4", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "6c709f97103355016e5782d0622437ae381012ad" + "reference": "4a4389e5c8bd1d0320d80a23caa6a1ac71cb81a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/6c709f97103355016e5782d0622437ae381012ad", - "reference": "6c709f97103355016e5782d0622437ae381012ad", + "url": "https://api.github.com/repos/symfony/property-access/zipball/4a4389e5c8bd1d0320d80a23caa6a1ac71cb81a7", + "reference": "4a4389e5c8bd1d0320d80a23caa6a1ac71cb81a7", "shasum": "" }, "require": { @@ -7167,7 +7286,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v7.1.4" + "source": "https://github.com/symfony/property-access/tree/v7.3.3" }, "funding": [ { @@ -7178,41 +7297,47 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-08-30T16:12:47+00:00" + "time": "2025-08-04T15:15:28+00:00" }, { "name": "symfony/property-info", - "version": "v7.1.3", + "version": "v7.3.5", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "88a279df2db5b7919cac6f35d6a5d1d7147e6a9b" + "reference": "0b346ed259dc5da43535caf243005fe7d4b0f051" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/88a279df2db5b7919cac6f35d6a5d1d7147e6a9b", - "reference": "88a279df2db5b7919cac6f35d6a5d1d7147e6a9b", + "url": "https://api.github.com/repos/symfony/property-info/zipball/0b346ed259dc5da43535caf243005fe7d4b0f051", + "reference": "0b346ed259dc5da43535caf243005fe7d4b0f051", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/string": "^6.4|^7.0", - "symfony/type-info": "^7.1" + "symfony/type-info": "^7.3.5" }, "conflict": { "phpdocumentor/reflection-docblock": "<5.2", "phpdocumentor/type-resolver": "<1.5.1", + "symfony/cache": "<6.4", "symfony/dependency-injection": "<6.4", "symfony/serializer": "<6.4" }, "require-dev": { "phpdocumentor/reflection-docblock": "^5.2", - "phpstan/phpdoc-parser": "^1.0", + "phpstan/phpdoc-parser": "^1.0|^2.0", "symfony/cache": "^6.4|^7.0", "symfony/dependency-injection": "^6.4|^7.0", "symfony/serializer": "^6.4|^7.0" @@ -7251,7 +7376,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v7.1.3" + "source": "https://github.com/symfony/property-info/tree/v7.3.5" }, "funding": [ { @@ -7262,25 +7387,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-07-26T07:36:36+00:00" + "time": "2025-10-05T22:12:41+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.5.0", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", "shasum": "" }, "require": { @@ -7293,12 +7422,12 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" } }, "autoload": { @@ -7334,7 +7463,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.6.0" }, "funding": [ { @@ -7350,20 +7479,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2025-04-25T09:37:31+00:00" }, { "name": "symfony/stopwatch", - "version": "v7.1.1", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d" + "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d", - "reference": "5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", + "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", "shasum": "" }, "require": { @@ -7396,7 +7525,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v7.1.1" + "source": "https://github.com/symfony/stopwatch/tree/v7.3.0" }, "funding": [ { @@ -7412,20 +7541,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2025-02-24T10:49:57+00:00" }, { "name": "symfony/string", - "version": "v7.1.5", + "version": "v7.3.4", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306" + "reference": "f96476035142921000338bad71e5247fbc138872" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/d66f9c343fa894ec2037cc928381df90a7ad4306", - "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306", + "url": "https://api.github.com/repos/symfony/string/zipball/f96476035142921000338bad71e5247fbc138872", + "reference": "f96476035142921000338bad71e5247fbc138872", "shasum": "" }, "require": { @@ -7440,7 +7569,6 @@ }, "require-dev": { "symfony/emoji": "^7.1", - "symfony/error-handler": "^6.4|^7.0", "symfony/http-client": "^6.4|^7.0", "symfony/intl": "^6.4|^7.0", "symfony/translation-contracts": "^2.5|^3.0", @@ -7483,7 +7611,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.5" + "source": "https://github.com/symfony/string/tree/v7.3.4" }, "funding": [ { @@ -7494,40 +7622,41 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-20T08:28:38+00:00" + "time": "2025-09-11T14:36:48+00:00" }, { "name": "symfony/type-info", - "version": "v7.1.5", + "version": "v7.3.5", "source": { "type": "git", "url": "https://github.com/symfony/type-info.git", - "reference": "9f6094aa900d2c06bd61576a6f279d4ac441515f" + "reference": "8b36f41421160db56914f897b57eaa6a830758b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/type-info/zipball/9f6094aa900d2c06bd61576a6f279d4ac441515f", - "reference": "9f6094aa900d2c06bd61576a6f279d4ac441515f", + "url": "https://api.github.com/repos/symfony/type-info/zipball/8b36f41421160db56914f897b57eaa6a830758b3", + "reference": "8b36f41421160db56914f897b57eaa6a830758b3", "shasum": "" }, "require": { "php": ">=8.2", - "psr/container": "^1.1|^2.0" + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { - "phpstan/phpdoc-parser": "<1.0", - "symfony/dependency-injection": "<6.4", - "symfony/property-info": "<6.4" + "phpstan/phpdoc-parser": "<1.30" }, "require-dev": { - "phpstan/phpdoc-parser": "^1.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/property-info": "^6.4|^7.0" + "phpstan/phpdoc-parser": "^1.30|^2.0" }, "type": "library", "autoload": { @@ -7565,7 +7694,7 @@ "type" ], "support": { - "source": "https://github.com/symfony/type-info/tree/v7.1.5" + "source": "https://github.com/symfony/type-info/tree/v7.3.5" }, "funding": [ { @@ -7576,29 +7705,34 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-19T21:48:23+00:00" + "time": "2025-10-16T12:30:12+00:00" }, { "name": "symfony/var-exporter", - "version": "v7.1.2", + "version": "v7.3.4", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "b80a669a2264609f07f1667f891dbfca25eba44c" + "reference": "0f020b544a30a7fe8ba972e53ee48a74c0bc87f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/b80a669a2264609f07f1667f891dbfca25eba44c", - "reference": "b80a669a2264609f07f1667f891dbfca25eba44c", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/0f020b544a30a7fe8ba972e53ee48a74c0bc87f4", + "reference": "0f020b544a30a7fe8ba972e53ee48a74c0bc87f4", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" }, "require-dev": { "symfony/property-access": "^6.4|^7.0", @@ -7641,7 +7775,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v7.1.2" + "source": "https://github.com/symfony/var-exporter/tree/v7.3.4" }, "funding": [ { @@ -7652,29 +7786,34 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-06-28T08:00:31+00:00" + "time": "2025-09-11T10:12:26+00:00" }, { "name": "symfony/yaml", - "version": "v7.1.5", + "version": "v7.3.5", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "4e561c316e135e053bd758bf3b3eb291d9919de4" + "reference": "90208e2fc6f68f613eae7ca25a2458a931b1bacc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/4e561c316e135e053bd758bf3b3eb291d9919de4", - "reference": "4e561c316e135e053bd758bf3b3eb291d9919de4", + "url": "https://api.github.com/repos/symfony/yaml/zipball/90208e2fc6f68f613eae7ca25a2458a931b1bacc", + "reference": "90208e2fc6f68f613eae7ca25a2458a931b1bacc", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { @@ -7712,7 +7851,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.1.5" + "source": "https://github.com/symfony/yaml/tree/v7.3.5" }, "funding": [ { @@ -7723,31 +7862,35 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-17T12:49:58+00:00" + "time": "2025-09-27T09:00:46+00:00" }, { "name": "tracy/tracy", - "version": "v2.10.8", + "version": "v2.11.0", "source": { "type": "git", "url": "https://github.com/nette/tracy.git", - "reference": "0e0f3312708fb9c179a92072ebacc24aeee7e2e8" + "reference": "eec57bcf2ff11d79f519a19da9d7ae1e2c63c42e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/tracy/zipball/0e0f3312708fb9c179a92072ebacc24aeee7e2e8", - "reference": "0e0f3312708fb9c179a92072ebacc24aeee7e2e8", + "url": "https://api.github.com/repos/nette/tracy/zipball/eec57bcf2ff11d79f519a19da9d7ae1e2c63c42e", + "reference": "eec57bcf2ff11d79f519a19da9d7ae1e2c63c42e", "shasum": "" }, "require": { "ext-json": "*", "ext-session": "*", - "php": "8.0 - 8.4" + "php": "8.2 - 8.5" }, "conflict": { "nette/di": "<3.0" @@ -7759,19 +7902,22 @@ "nette/mail": "^3.0 || ^4.0", "nette/tester": "^2.2", "nette/utils": "^3.0 || ^4.0", - "phpstan/phpstan": "^1.0", + "phpstan/phpstan-nette": "^2.0@stable", "psr/log": "^1.0 || ^2.0 || ^3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.10-dev" + "dev-master": "2.11-dev" } }, "autoload": { "files": [ "src/Tracy/functions.php" ], + "psr-4": { + "Tracy\\": "src" + }, "classmap": [ "src" ] @@ -7801,42 +7947,49 @@ ], "support": { "issues": "https://github.com/nette/tracy/issues", - "source": "https://github.com/nette/tracy/tree/v2.10.8" + "source": "https://github.com/nette/tracy/tree/v2.11.0" }, - "time": "2024-08-07T02:04:53+00:00" + "time": "2025-10-31T00:12:50+00:00" }, { "name": "zircote/swagger-php", - "version": "4.10.6", + "version": "5.5.2", "source": { "type": "git", "url": "https://github.com/zircote/swagger-php.git", - "reference": "e462ff5269ea0ec91070edd5d51dc7215bdea3b6" + "reference": "0ca908380414596f5ed3a7ad33a04abb4cffe613" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zircote/swagger-php/zipball/e462ff5269ea0ec91070edd5d51dc7215bdea3b6", - "reference": "e462ff5269ea0ec91070edd5d51dc7215bdea3b6", + "url": "https://api.github.com/repos/zircote/swagger-php/zipball/0ca908380414596f5ed3a7ad33a04abb4cffe613", + "reference": "0ca908380414596f5ed3a7ad33a04abb4cffe613", "shasum": "" }, "require": { "ext-json": "*", - "php": ">=7.2", + "nikic/php-parser": "^4.19 || ^5.0", + "php": ">=7.4", + "phpstan/phpdoc-parser": "^2.0", "psr/log": "^1.1 || ^2.0 || ^3.0", "symfony/deprecation-contracts": "^2 || ^3", - "symfony/finder": ">=2.2", - "symfony/yaml": ">=3.3" + "symfony/finder": "^5.0 || ^6.0 || ^7.0", + "symfony/yaml": "^5.0 || ^6.0 || ^7.0" + }, + "conflict": { + "symfony/process": ">=6, <6.4.14" }, "require-dev": { "composer/package-versions-deprecated": "^1.11", - "doctrine/annotations": "^1.7 || ^2.0", - "friendsofphp/php-cs-fixer": "^2.17 || ^3.47.1", - "phpstan/phpstan": "^1.6", - "phpunit/phpunit": ">=8", - "vimeo/psalm": "^4.23" + "doctrine/annotations": "^2.0", + "friendsofphp/php-cs-fixer": "^3.62.0", + "phpstan/phpstan": "^1.6 || ^2.0", + "phpunit/phpunit": "^9.0", + "rector/rector": "^1.0 || ^2.0", + "vimeo/psalm": "^4.30 || ^5.0" }, "suggest": { - "doctrine/annotations": "^1.7 || ^2.0" + "doctrine/annotations": "^2.0", + "radebatz/type-info-extras": "^1.0.2" }, "bin": [ "bin/openapi" @@ -7844,7 +7997,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev" + "dev-master": "5.x-dev" } }, "autoload": { @@ -7872,8 +8025,8 @@ "homepage": "https://radebatz.net" } ], - "description": "swagger-php - Generate interactive documentation for your RESTful API using phpdoc annotations", - "homepage": "https://github.com/zircote/swagger-php/", + "description": "Generate interactive documentation for your RESTful API using PHP attributes (preferred) or PHPDoc annotations", + "homepage": "https://github.com/zircote/swagger-php", "keywords": [ "api", "json", @@ -7882,28 +8035,28 @@ ], "support": { "issues": "https://github.com/zircote/swagger-php/issues", - "source": "https://github.com/zircote/swagger-php/tree/4.10.6" + "source": "https://github.com/zircote/swagger-php/tree/5.5.2" }, - "time": "2024-07-26T03:04:43+00:00" + "time": "2025-10-27T04:40:08+00:00" } ], "packages-dev": [ { "name": "hamcrest/hamcrest-php", - "version": "v2.0.1", + "version": "v2.1.1", "source": { "type": "git", "url": "https://github.com/hamcrest/hamcrest-php.git", - "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" + "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", - "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487", + "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487", "shasum": "" }, "require": { - "php": "^5.3|^7.0|^8.0" + "php": "^7.4|^8.0" }, "replace": { "cordoval/hamcrest-php": "*", @@ -7911,8 +8064,8 @@ "kodova/hamcrest-php": "*" }, "require-dev": { - "phpunit/php-file-iterator": "^1.4 || ^2.0", - "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" + "phpunit/php-file-iterator": "^1.4 || ^2.0 || ^3.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0 || ^8.0 || ^9.0" }, "type": "library", "extra": { @@ -7935,9 +8088,9 @@ ], "support": { "issues": "https://github.com/hamcrest/hamcrest-php/issues", - "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.1.1" }, - "time": "2020-07-09T08:09:16+00:00" + "time": "2025-04-30T06:54:44+00:00" }, { "name": "mikey179/vfsstream", @@ -8076,24 +8229,24 @@ }, { "name": "nette/tester", - "version": "v2.5.3", + "version": "v2.5.6", "source": { "type": "git", "url": "https://github.com/nette/tester.git", - "reference": "ee0a4b8402a8c1831db547ec0a56d18196906b51" + "reference": "f7328f743d06df233bbc9b68da9f4941f73ad661" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/tester/zipball/ee0a4b8402a8c1831db547ec0a56d18196906b51", - "reference": "ee0a4b8402a8c1831db547ec0a56d18196906b51", + "url": "https://api.github.com/repos/nette/tester/zipball/f7328f743d06df233bbc9b68da9f4941f73ad661", + "reference": "f7328f743d06df233bbc9b68da9f4941f73ad661", "shasum": "" }, "require": { - "php": "8.0 - 8.3" + "php": "8.0 - 8.5" }, "require-dev": { "ext-simplexml": "*", - "phpstan/phpstan": "^1.0" + "phpstan/phpstan-nette": "^2.0@stable" }, "bin": [ "src/tester" @@ -8105,6 +8258,9 @@ } }, "autoload": { + "psr-4": { + "Tester\\": "src" + }, "classmap": [ "src/" ] @@ -8145,26 +8301,21 @@ ], "support": { "issues": "https://github.com/nette/tester/issues", - "source": "https://github.com/nette/tester/tree/v2.5.3" + "source": "https://github.com/nette/tester/tree/v2.5.6" }, - "time": "2024-06-18T18:44:12+00:00" + "time": "2025-08-07T00:28:58+00:00" }, { "name": "phpstan/phpstan", - "version": "1.12.5", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "7e6c6cb7cecb0a6254009a1a8a7d54ec99812b17" - }, + "version": "2.1.31", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/7e6c6cb7cecb0a6254009a1a8a7d54ec99812b17", - "reference": "7e6c6cb7cecb0a6254009a1a8a7d54ec99812b17", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ead89849d879fe203ce9292c6ef5e7e76f867b96", + "reference": "ead89849d879fe203ce9292c6ef5e7e76f867b96", "shasum": "" }, "require": { - "php": "^7.2|^8.0" + "php": "^7.4|^8.0" }, "conflict": { "phpstan/phpstan-shim": "*" @@ -8205,25 +8356,25 @@ "type": "github" } ], - "time": "2024-09-26T12:45:22+00:00" + "time": "2025-10-10T14:14:11+00:00" }, { "name": "phpstan/phpstan-nette", - "version": "1.3.8", + "version": "2.0.6", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-nette.git", - "reference": "bc74b8b208b47f163fe55708fcf1a0333247fa79" + "reference": "aa6c413df9587c355a744c3a84ecf9736987b607" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-nette/zipball/bc74b8b208b47f163fe55708fcf1a0333247fa79", - "reference": "bc74b8b208b47f163fe55708fcf1a0333247fa79", + "url": "https://api.github.com/repos/phpstan/phpstan-nette/zipball/aa6c413df9587c355a744c3a84ecf9736987b607", + "reference": "aa6c413df9587c355a744c3a84ecf9736987b607", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.11.11" + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.1.12" }, "conflict": { "nette/application": "<2.3.0", @@ -8235,13 +8386,14 @@ }, "require-dev": { "nette/application": "^3.0", + "nette/di": "^3.1.10", "nette/forms": "^3.0", "nette/utils": "^2.3.0 || ^3.0.0", - "nikic/php-parser": "^4.13.2", "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-phpunit": "^1.0", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "~9.5.28" + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6" }, "type": "phpstan-extension", "extra": { @@ -8264,9 +8416,73 @@ "description": "Nette Framework class reflection extension for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-nette/issues", - "source": "https://github.com/phpstan/phpstan-nette/tree/1.3.8" + "source": "https://github.com/phpstan/phpstan-nette/tree/2.0.6" + }, + "time": "2025-09-19T19:54:10+00:00" + }, + { + "name": "vrana/adminer", + "version": "v5.4.1", + "source": { + "type": "git", + "url": "https://github.com/vrana/adminer.git", + "reference": "eaad45a781a3e0d9fa04e3431c1826e81c061699" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vrana/adminer/zipball/eaad45a781a3e0d9fa04e3431c1826e81c061699", + "reference": "eaad45a781a3e0d9fa04e3431c1826e81c061699", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "type": "library", + "autoload": { + "classmap": [ + "plugins/" + ], + "exclude-from-classmap": [ + "adminer/drivers/", + "plugins/drivers/" + ] }, - "time": "2024-08-25T12:11:12+00:00" + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0", + "GPL-2.0-only" + ], + "authors": [ + { + "name": "Jakub Vrána", + "homepage": "https://www.vrana.cz/" + } + ], + "description": "Database management in a single PHP file.", + "homepage": "https://www.adminer.org/", + "keywords": [ + "database" + ], + "support": { + "forum": "https://github.com/vrana/adminer/discussions", + "issues": "https://github.com/vrana/adminer/issues", + "source": "https://github.com/vrana/adminer/" + }, + "funding": [ + { + "url": "https://www.paypal.com/donate/?hosted_button_id=6PK5VNUCFT3FG", + "type": "custom" + }, + { + "url": "https://github.com/vrana", + "type": "github" + }, + { + "url": "https://www.patreon.com/jakubvrana", + "type": "patreon" + } + ], + "time": "2025-09-26T15:38:02+00:00" } ], "aliases": [], @@ -8287,5 +8503,5 @@ "platform-overrides": { "php": "8.2.0" }, - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 7318a38b6..a9e852a15 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1,10 +1,12 @@ openapi: 3.0.0 info: title: 'ReCodEx API' + description: '* @OA\Info(version="1.0", title="ReCodEx API")' version: '1.0' paths: /v1/security/check: post: + summary: '* @OA\Post(path="/v1/security/check", operationId="securityPresenterActionCheck", @OA\RequestBody(@OA\MediaType(mediaType="application/json",@OA\Schema(@OA\Property(property="url", type="string", nullable=true, description="URL of the resource that we are checking"), @OA\Property(property="method", type="string", nullable=true, description="The HTTP method"), required={"url","method"}))), @OA\Response(response="200",description="Placeholder response"))' operationId: securityPresenterActionCheck requestBody: content: @@ -3065,6 +3067,7 @@ paths: '200': description: 'Placeholder response' delete: + summary: '* @OA\Delete(path="/v1/group-invitations/{id}", operationId="groupInvitationsPresenterActionRemove", @OA\Parameter(name="id", in="path", required=true, description="Identifier of the group invitation", @OA\Schema(type="string", nullable=false, pattern="^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$")), @OA\Response(response="200",description="Placeholder response"))' operationId: groupInvitationsPresenterActionRemove parameters: - @@ -3133,6 +3136,23 @@ paths: '200': description: 'Placeholder response' '/v1/group-attributes/{groupId}': + get: + summary: 'Get all external attributes for a group. This endpoint is meant to be used by webapp to display the attributes.' + description: 'Get all external attributes for a group. This endpoint is meant to be used by webapp to display the attributes.' + operationId: groupExternalAttributesPresenterActionGet + parameters: + - + name: groupId + in: path + description: '' + required: true + schema: + type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' + nullable: false + responses: + '200': + description: 'Placeholder response' post: summary: 'Create an external attribute for given group.' description: 'Create an external attribute for given group.' @@ -4035,6 +4055,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4051,6 +4072,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4068,6 +4090,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4085,6 +4108,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -5883,6 +5907,7 @@ paths: description: 'Placeholder response' /v1/extensions/sis/status/: get: + summary: '* @OA\Get(path="/v1/extensions/sis/status/", operationId="sisPresenterActionStatus", @OA\Response(response="200",description="Placeholder response"))' operationId: sisPresenterActionStatus responses: '200': diff --git a/tests/AccessToken/AccessManager.phpt b/tests/AccessToken/AccessManager.phpt index be6ecdec5..0b85fb737 100644 --- a/tests/AccessToken/AccessManager.phpt +++ b/tests/AccessToken/AccessManager.phpt @@ -7,7 +7,6 @@ use App\Security\AccessManager; use Tester\Assert; use App\Exceptions\InvalidAccessTokenException; use App\Exceptions\ForbiddenRequestException; -use App\Model\Repository\Users; use Firebase\JWT\JWT; use Firebase\JWT\Key; @@ -19,7 +18,7 @@ use Nette\Http\Request; */ class TestAccessManager extends Tester\TestCase { - use MockeryTrait; + use \MockeryTrait; /* * Token decoding diff --git a/tests/Authorizator/AuthorizatorBasic.phpt b/tests/Authorizator/AuthorizatorBasic.phpt index 532ec735e..8388f1be3 100644 --- a/tests/Authorizator/AuthorizatorBasic.phpt +++ b/tests/Authorizator/AuthorizatorBasic.phpt @@ -10,13 +10,9 @@ use App\Security\Roles; use Tester\Assert; use Mockery\Mock; -class Resource1 -{ -} +class Resource1 {} -class Resource2 -{ -} +class Resource2 {} interface ITestResource1Permissions { @@ -33,7 +29,7 @@ interface ITestResource2Permissions */ class TestAuthorizatorBasic extends Tester\TestCase { - use MockeryTrait; + use \MockeryTrait; /** @var PolicyRegistry */ private $policies; @@ -56,10 +52,13 @@ class TestAuthorizatorBasic extends Tester\TestCase public function __construct() { $this->loader = new Loader( - TEMP_DIR . '/security', __DIR__ . '/config/basic.neon', [ - 'resource1' => ITestResource1Permissions::class, - 'resource2' => ITestResource2Permissions::class - ], Mockery::mock(\App\Security\UserStorage::class) + TEMP_DIR . '/security', + __DIR__ . '/config/basic.neon', + [ + 'resource1' => ITestResource1Permissions::class, + 'resource2' => ITestResource2Permissions::class + ], + Mockery::mock(\App\Security\UserStorage::class) ); } diff --git a/tests/Authorizator/AuthorizatorWithEffectiveRole.phpt b/tests/Authorizator/AuthorizatorWithEffectiveRole.phpt index 1a7065860..5912a3da9 100644 --- a/tests/Authorizator/AuthorizatorWithEffectiveRole.phpt +++ b/tests/Authorizator/AuthorizatorWithEffectiveRole.phpt @@ -9,9 +9,7 @@ use App\Security\Roles; use App\Security\UserStorage; use Tester\Assert; -class Resource1 -{ -} +class Resource1 {} interface ITestResource1Permissions { @@ -25,7 +23,7 @@ interface ITestResource1Permissions */ class TestAuthorizatorWithEffectiveRole extends Tester\TestCase { - use MockeryTrait; + use \MockeryTrait; /** @var PolicyRegistry */ private $policies; @@ -42,9 +40,12 @@ class TestAuthorizatorWithEffectiveRole extends Tester\TestCase public function __construct() { $this->loader = new Loader( - TEMP_DIR . '/security', __DIR__ . '/config/with_effective_role.neon', [ - 'resource1' => ITestResource1Permissions::class - ], Mockery::mock(UserStorage::class) + TEMP_DIR . '/security', + __DIR__ . '/config/with_effective_role.neon', + [ + 'resource1' => ITestResource1Permissions::class + ], + Mockery::mock(UserStorage::class) ); } diff --git a/tests/Authorizator/AuthorizatorWithOr.phpt b/tests/Authorizator/AuthorizatorWithOr.phpt index fbf74f286..d6bf42f9c 100644 --- a/tests/Authorizator/AuthorizatorWithOr.phpt +++ b/tests/Authorizator/AuthorizatorWithOr.phpt @@ -10,13 +10,9 @@ use App\Security\Roles; use Tester\Assert; use Mockery\Mock; -class Resource1 -{ -} +class Resource1 {} -class Resource2 -{ -} +class Resource2 {} interface ITestResource1Permissions { @@ -33,7 +29,7 @@ interface ITestResource2Permissions */ class TestAuthorizatorWithOr extends Tester\TestCase { - use MockeryTrait; + use \MockeryTrait; /** @var PolicyRegistry */ private $policies; @@ -56,10 +52,13 @@ class TestAuthorizatorWithOr extends Tester\TestCase public function __construct() { $this->loader = new Loader( - TEMP_DIR . '/security', __DIR__ . '/config/with_or.neon', [ - 'resource1' => ITestResource1Permissions::class, - 'resource2' => ITestResource2Permissions::class - ], Mockery::mock(\App\Security\UserStorage::class) + TEMP_DIR . '/security', + __DIR__ . '/config/with_or.neon', + [ + 'resource1' => ITestResource1Permissions::class, + 'resource2' => ITestResource2Permissions::class + ], + Mockery::mock(\App\Security\UserStorage::class) ); } diff --git a/tests/Authorizator/AuthorizatorWithScopeRoles.phpt b/tests/Authorizator/AuthorizatorWithScopeRoles.phpt index 62930904e..6b1735675 100644 --- a/tests/Authorizator/AuthorizatorWithScopeRoles.phpt +++ b/tests/Authorizator/AuthorizatorWithScopeRoles.phpt @@ -8,9 +8,7 @@ use App\Security\PolicyRegistry; use App\Security\Roles; use Tester\Assert; -class Resource1 -{ -} +class Resource1 {} interface ITestResource1Permissions { @@ -24,7 +22,7 @@ interface ITestResource1Permissions */ class TestAuthorizatorWithScopeRoles extends Tester\TestCase { - use MockeryTrait; + use \MockeryTrait; /** @var PolicyRegistry */ private $policies; @@ -41,9 +39,12 @@ class TestAuthorizatorWithScopeRoles extends Tester\TestCase public function __construct() { $this->loader = new Loader( - TEMP_DIR . '/security', __DIR__ . '/config/with_scope_roles.neon', [ - 'resource1' => ITestResource1Permissions::class - ], Mockery::mock(\App\Security\UserStorage::class) + TEMP_DIR . '/security', + __DIR__ . '/config/with_scope_roles.neon', + [ + 'resource1' => ITestResource1Permissions::class + ], + Mockery::mock(\App\Security\UserStorage::class) ); } diff --git a/tests/Security/UserStorage.phpt b/tests/Security/UserStorage.phpt index eefbd2f99..0815d2296 100644 --- a/tests/Security/UserStorage.phpt +++ b/tests/Security/UserStorage.phpt @@ -19,7 +19,7 @@ use Tester\Assert; */ class TestUserStorage extends Tester\TestCase { - use MockeryTrait; + use \MockeryTrait; /** @var Container */ private $container; diff --git a/tests/base/MockeryTrait.php b/tests/base/MockeryTrait.php index 0011745d6..01ca72145 100644 --- a/tests/base/MockeryTrait.php +++ b/tests/base/MockeryTrait.php @@ -1,5 +1,6 @@ "pdo_sqlite", "path" => $dbPath], $configuration, $eventManager @@ -98,7 +98,7 @@ public static function fillDatabase(Container $container, string $group = "demo" $originalEm->getConfiguration(), $originalEm->getEventManager() ); - static::replaceService($container, $schemaEm, EntityManagerDecorator::class); + static::replaceService($container, $schemaEm, SimpleEntityManagerDecorator::class); $schemaTool = new Doctrine\ORM\Tools\SchemaTool($schemaEm); $schemaTool->dropSchema($schemaEm->getMetadataFactory()->getAllMetadata()); @@ -126,7 +126,7 @@ public static function fillDatabase(Container $container, string $group = "demo" file_put_contents($dumpPath, $sqliteProcess->getOutput()); // Replace the temporary entity manager with the original one - static::replaceService($container, $originalEm, EntityManagerDecorator::class); + static::replaceService($container, $originalEm, SimpleEntityManagerDecorator::class); } flock($lockHandle, LOCK_UN); diff --git a/www/adminer/adminer-5.4.1.php b/www/adminer/adminer-5.4.1.php new file mode 100644 index 000000000..947033fca --- /dev/null +++ b/www/adminer/adminer-5.4.1.php @@ -0,0 +1,12249 @@ + + + + +credentials(); + $return = Driver::connect($credentials[0], $credentials[1], $credentials[2]); + return (is_object($return) ? $return : null); +} + +/** Unescape database identifier +* @param string $idf text inside `` +*/ +function idf_unescape(string $idf): string { + if (!preg_match('~^[`\'"[]~', $idf)) { + return $idf; + } + $last = substr($idf, -1); + return str_replace($last . $last, $last, substr($idf, 1, -1)); +} + +/** Shortcut for connection()->quote($string) */ +function q(string $string): string { + return connection()->quote($string); +} + +/** Escape string to use inside '' */ +function escape_string(string $val): string { + return substr(q($val), 1, -1); +} + +/** Get a possibly missing item from a possibly missing array +* idx($row, $key) is better than $row[$key] ?? null because PHP will report error for undefined $row +* @param ?mixed[] $array +* @param array-key $key +* @param mixed $default +* @return mixed +*/ +function idx(?array $array, $key, $default = null) { + return ($array && array_key_exists($key, $array) ? $array[$key] : $default); +} + +/** Remove non-digits from a string; used instead of intval() to not corrupt big numbers +* @return numeric-string +*/ +function number(string $val): string { + return preg_replace('~[^0-9]+~', '', $val); +} + +/** Get regular expression to match numeric types */ +function number_type(): string { + return '((? $process e.g. [&$_GET, &$_POST, &$_COOKIE] +* @param bool $filter whether to leave values as is +* @return void modified in place +*/ +function remove_slashes(array $process, bool $filter = false): void { + if (function_exists("get_magic_quotes_gpc") && get_magic_quotes_gpc()) { + while (list($key, $val) = each($process)) { + foreach ($val as $k => $v) { + unset($process[$key][$k]); + if (is_array($v)) { + $process[$key][stripslashes($k)] = $v; + $process[] = &$process[$key][stripslashes($k)]; + } else { + $process[$key][stripslashes($k)] = ($filter ? $v : stripslashes($v)); + } + } + } + } +} + +/** Escape or unescape string to use inside form [] */ +function bracket_escape(string $idf, bool $back = false): string { + // escape brackets inside name="x[]" + static $trans = array(':' => ':1', ']' => ':2', '[' => ':3', '"' => ':4'); + return strtr($idf, ($back ? array_flip($trans) : $trans)); +} + +/** Check if connection has at least the given version +* @param string|float $version required version +* @param string|float $maria_db required MariaDB version +*/ +function min_version($version, $maria_db = "", ?Db $connection2 = null): bool { + $connection2 = connection($connection2); + $server_info = $connection2->server_info; + if ($maria_db && preg_match('~([\d.]+)-MariaDB~', $server_info, $match)) { + $server_info = $match[1]; + $version = $maria_db; + } + return $version && version_compare($server_info, $version) >= 0; +} + +/** Get connection charset */ +function charset(Db $connection): string { + return (min_version("5.5.3", 0, $connection) ? "utf8mb4" : "utf8"); // SHOW CHARSET would require an extra query +} + +/** Get INI boolean value */ +function ini_bool(string $ini): bool { + $val = ini_get($ini); + return (preg_match('~^(on|true|yes)$~i', $val) || (int) $val); // boolean values set by php_value are strings +} + +/** Get INI bytes value */ +function ini_bytes(string $ini): int { + $val = ini_get($ini); + switch (strtolower(substr($val, -1))) { + case 'g': + $val = (int) $val * 1024; // no break + case 'm': + $val = (int) $val * 1024; // no break + case 'k': + $val = (int) $val * 1024; + } + return $val; +} + +/** Check if SID is necessary */ +function sid(): bool { + static $return; + if ($return === null) { // restart_session() defines SID + $return = (SID && !($_COOKIE && ini_bool("session.use_cookies"))); // $_COOKIE - don't pass SID with permanent login + } + return $return; +} + +/** Set password to session */ +function set_password(string $vendor, ?string $server, string $username, ?string $password): void { + $_SESSION["pwds"][$vendor][$server][$username] = ($_COOKIE["adminer_key"] && is_string($password) + ? array(encrypt_string($password, $_COOKIE["adminer_key"])) + : $password + ); +} + +/** Get password from session +* @return string|false|null null for missing password, false for expired password +*/ +function get_password() { + $return = get_session("pwds"); + if (is_array($return)) { + $return = ($_COOKIE["adminer_key"] + ? decrypt_string($return[0], $_COOKIE["adminer_key"]) + : false + ); + } + return $return; +} + +/** Get single value from database +* @return string|false false if error +*/ +function get_val(string $query, int $field = 0, ?Db $conn = null) { + $conn = connection($conn); + $result = $conn->query($query); + if (!is_object($result)) { + return false; + } + $row = $result->fetch_row(); + return ($row ? $row[$field] : false); +} + +/** Get list of values from database +* @param array-key $column +* @return list +*/ +function get_vals(string $query, $column = 0): array { + $return = array(); + $result = connection()->query($query); + if (is_object($result)) { + while ($row = $result->fetch_row()) { + $return[] = $row[$column]; + } + } + return $return; +} + +/** Get keys from first column and values from second +* @return string[] +*/ +function get_key_vals(string $query, ?Db $connection2 = null, bool $set_keys = true): array { + $connection2 = connection($connection2); + $return = array(); + $result = $connection2->query($query); + if (is_object($result)) { + while ($row = $result->fetch_row()) { + if ($set_keys) { + $return[$row[0]] = $row[1]; + } else { + $return[] = $row[0]; + } + } + } + return $return; +} + +/** Get all rows of result +* @return list of associative arrays +*/ +function get_rows(string $query, ?Db $connection2 = null, string $error = "

"): array { + $conn = connection($connection2); + $return = array(); + $result = $conn->query($query); + if (is_object($result)) { // can return true + while ($row = $result->fetch_assoc()) { + $return[] = $row; + } + } elseif (!$result && !$connection2 && $error && (defined('Adminer\PAGE_HEADER') || $error == "-- ")) { + echo $error . error() . "\n"; + } + return $return; +} + +/** Find unique identifier of a row +* @param string[] $row +* @param Index[] $indexes +* @return string[]|void null if there is no unique identifier +*/ +function unique_array(?array $row, array $indexes) { + foreach ($indexes as $index) { + if (preg_match("~PRIMARY|UNIQUE~", $index["type"])) { + $return = array(); + foreach ($index["columns"] as $key) { + if (!isset($row[$key])) { // NULL is ambiguous + continue 2; + } + $return[$key] = $row[$key]; + } + return $return; + } + } +} + +/** Escape column key used in where() */ +function escape_key(string $key): string { + if (preg_match('(^([\w(]+)(' . str_replace("_", ".*", preg_quote(idf_escape("_"))) . ')([ \w)]+)$)', $key, $match)) { //! columns looking like functions + return $match[1] . idf_escape(idf_unescape($match[2])) . $match[3]; //! SQL injection + } + return idf_escape($key); +} + +/** Create SQL condition from parsed query string +* @param array{where:string[], null:list} $where parsed query string +* @param Field[] $fields +*/ +function where(array $where, array $fields = array()): string { + $return = array(); + foreach ((array) $where["where"] as $key => $val) { + $key = bracket_escape($key, true); // true - back + $column = escape_key($key); + $field = idx($fields, $key, array()); + $field_type = $field["type"]; + $return[] = $column + . (JUSH == "sql" && $field_type == "json" ? " = CAST(" . q($val) . " AS JSON)" + : (JUSH == "pgsql" && preg_match('~^json~', $field_type) ? "::jsonb = " . q($val) . "::jsonb" + : (JUSH == "sql" && is_numeric($val) && preg_match('~\.~', $val) ? " LIKE " . q($val) // LIKE because of floats but slow with ints + : (JUSH == "mssql" && strpos($field_type, "datetime") === false ? " LIKE " . q(preg_replace('~[_%[]~', '[\0]', $val)) // LIKE because of text but it does not work with datetime + : " = " . unconvert_field($field, q($val)))))) + ; //! enum and set + if (JUSH == "sql" && preg_match('~char|text~', $field_type) && preg_match("~[^ -@]~", $val)) { // not just [a-z] to catch non-ASCII characters + $return[] = "$column = " . q($val) . " COLLATE " . charset(connection()) . "_bin"; + } + } + foreach ((array) $where["null"] as $key) { + $return[] = escape_key($key) . " IS NULL"; + } + return implode(" AND ", $return); +} + +/** Create SQL condition from query string +* @param Field[] $fields +*/ +function where_check(string $val, array $fields = array()): string { + parse_str($val, $check); + remove_slashes(array(&$check)); + return where($check, $fields); +} + +/** Create query string where condition from value +* @param int $i condition order +* @param string $column column identifier +*/ +function where_link(int $i, string $column, ?string $value, string $operator = "="): string { + return "&where%5B$i%5D%5Bcol%5D=" . urlencode($column) . "&where%5B$i%5D%5Bop%5D=" . urlencode(($value !== null ? $operator : "IS NULL")) . "&where%5B$i%5D%5Bval%5D=" . urlencode($value); +} + +/** Get select clause for convertible fields +* @param mixed[] $columns only keys are used +* @param Field[] $fields +* @param list $select +*/ +function convert_fields(array $columns, array $fields, array $select = array()): string { + $return = ""; + foreach ($columns as $key => $val) { + if ($select && !in_array(idf_escape($key), $select)) { + continue; + } + $as = convert_field($fields[$key]); + if ($as) { + $return .= ", $as AS " . idf_escape($key); + } + } + return $return; +} + +/** Set cookie valid on current path +* @param int $lifetime number of seconds, 0 for session cookie, 2592000 - 30 days +*/ +function cookie(string $name, ?string $value, int $lifetime = 2592000): void { + header( + "Set-Cookie: $name=" . urlencode($value) + . ($lifetime ? "; expires=" . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT" : "") + . "; path=" . preg_replace('~\?.*~', '', $_SERVER["REQUEST_URI"]) + . (HTTPS ? "; secure" : "") + . "; HttpOnly; SameSite=lax", + false + ); +} + +/** Get settings stored in a cookie +* @return mixed[] +*/ +function get_settings(string $cookie): array { + parse_str($_COOKIE[$cookie], $settings); + return $settings; +} + +/** Get setting stored in a cookie +* @param mixed $default +* @return mixed +*/ +function get_setting(string $key, string $cookie = "adminer_settings", $default = null) { + return idx(get_settings($cookie), $key, $default); +} + +/** Store settings to a cookie +* @param mixed[] $settings +*/ +function save_settings(array $settings, string $cookie = "adminer_settings"): void { + $value = http_build_query($settings + get_settings($cookie)); + cookie($cookie, $value); + $_COOKIE[$cookie] = $value; +} + +/** Restart stopped session */ +function restart_session(): void { + if (!ini_bool("session.use_cookies") && (!function_exists('session_status') || session_status() == 1)) { // 1 - PHP_SESSION_NONE, session_status() available since PHP 5.4 + session_start(); + } +} + +/** Stop session if possible */ +function stop_session(bool $force = false): void { + $use_cookies = ini_bool("session.use_cookies"); + if (!$use_cookies || $force) { + session_write_close(); // improves concurrency if a user opens several pages at once, may be restarted later + if ($use_cookies && @ini_set("session.use_cookies", '0') === false) { // @ - may be disabled + session_start(); + } + } +} + +/** Get session variable for current server +* @return mixed +*/ +function &get_session(string $key) { + return $_SESSION[$key][DRIVER][SERVER][$_GET["username"]]; +} + +/** Set session variable for current server +* @param mixed $val +* @return mixed +*/ +function set_session(string $key, $val) { + $_SESSION[$key][DRIVER][SERVER][$_GET["username"]] = $val; // used also in auth.inc.php +} + +/** Get authenticated URL */ +function auth_url(string $vendor, ?string $server, string $username, ?string $db = null): string { + $uri = remove_from_uri(implode("|", array_keys(SqlDriver::$drivers)) + . "|username|ext|" + . ($db !== null ? "db|" : "") + . ($vendor == 'mssql' || $vendor == 'pgsql' ? "" : "ns|") // we don't have access to support() here + . session_name()) + ; + preg_match('~([^?]*)\??(.*)~', $uri, $match); + return "$match[1]?" + . (sid() ? SID . "&" : "") + . ($vendor != "server" || $server != "" ? urlencode($vendor) . "=" . urlencode($server) . "&" : "") + . ($_GET["ext"] ? "ext=" . urlencode($_GET["ext"]) . "&" : "") + . "username=" . urlencode($username) + . ($db != "" ? "&db=" . urlencode($db) : "") + . ($match[2] ? "&$match[2]" : "") + ; +} + +/** Find whether it is an AJAX request */ +function is_ajax(): bool { + return ($_SERVER["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest"); +} + +/** Send Location header and exit +* @param ?string $location null to only set a message +*/ +function redirect(?string $location, ?string $message = null): void { + if ($message !== null) { + restart_session(); + $_SESSION["messages"][preg_replace('~^[^?]*~', '', ($location !== null ? $location : $_SERVER["REQUEST_URI"]))][] = $message; + } + if ($location !== null) { + if ($location == "") { + $location = "."; + } + header("Location: $location"); + exit; + } +} + +/** Execute query and redirect if successful +* @param bool $redirect +*/ +function query_redirect(string $query, ?string $location, string $message, $redirect = true, bool $execute = true, bool $failed = false, string $time = ""): bool { + if ($execute) { + $start = microtime(true); + $failed = !connection()->query($query); + $time = format_time($start); + } + $sql = ($query ? adminer()->messageQuery($query, $time, $failed) : ""); + if ($failed) { + adminer()->error .= error() . $sql . script("messagesPrint();") . "
"; + return false; + } + if ($redirect) { + redirect($location, $message . $sql); + } + return true; +} + +class Queries { + /** @var string[] */ static array $queries = array(); + static float $start = 0; +} + +/** Execute and remember query +* @param string $query end with ';' to use DELIMITER +* @return Result|bool +*/ +function queries(string $query) { + if (!Queries::$start) { + Queries::$start = microtime(true); + } + Queries::$queries[] = (preg_match('~;$~', $query) ? "DELIMITER ;;\n$query;\nDELIMITER " : $query) . ";"; + return connection()->query($query); +} + +/** Apply command to all array items +* @param list $tables +* @param callable(string):string $escape +*/ +function apply_queries(string $query, array $tables, $escape = 'Adminer\table'): bool { + foreach ($tables as $table) { + if (!queries("$query " . $escape($table))) { + return false; + } + } + return true; +} + +/** Redirect by remembered queries +* @param bool $redirect +*/ +function queries_redirect(?string $location, string $message, $redirect): bool { + $queries = implode("\n", Queries::$queries); + $time = format_time(Queries::$start); + return query_redirect($queries, $location, $message, $redirect, false, !$redirect, $time); +} + +/** Format elapsed time +* @param float $start output of microtime(true) +* @return string HTML code +*/ +function format_time(float $start): string { + return lang(0, max(0, microtime(true) - $start)); +} + +/** Get relative REQUEST_URI */ +function relative_uri(): string { + return str_replace(":", "%3a", preg_replace('~^[^?]*/([^?]*)~', '\1', $_SERVER["REQUEST_URI"])); +} + +/** Remove parameter from query string */ +function remove_from_uri(string $param = ""): string { + return substr(preg_replace("~(?<=[?&])($param" . (SID ? "" : "|" . session_name()) . ")=[^&]*&~", '', relative_uri() . "&"), 0, -1); +} + +/** Get file contents from $_FILES +* @return mixed int for error, string otherwise +*/ +function get_file(string $key, bool $decompress = false, string $delimiter = "") { + $file = $_FILES[$key]; + if (!$file) { + return null; + } + foreach ($file as $key => $val) { + $file[$key] = (array) $val; + } + $return = ''; + foreach ($file["error"] as $key => $error) { + if ($error) { + return $error; + } + $name = $file["name"][$key]; + $tmp_name = $file["tmp_name"][$key]; + $content = file_get_contents( + $decompress && preg_match('~\.gz$~', $name) + ? "compress.zlib://$tmp_name" + : $tmp_name + ); //! may not be reachable because of open_basedir + if ($decompress) { + $start = substr($content, 0, 3); + if (function_exists("iconv") && preg_match("~^\xFE\xFF|^\xFF\xFE~", $start)) { // not ternary operator to save memory + $content = iconv("utf-16", "utf-8", $content); + } elseif ($start == "\xEF\xBB\xBF") { // UTF-8 BOM + $content = substr($content, 3); + } + } + $return .= $content; + if ($delimiter) { + $return .= (preg_match("($delimiter\\s*\$)", $content) ? "" : $delimiter) . "\n\n"; + } + } + return $return; +} + +/** Determine upload error */ +function upload_error(int $error): string { + $max_size = ($error == UPLOAD_ERR_INI_SIZE ? ini_get("upload_max_filesize") : 0); // post_max_size is checked in index.php + return ($error ? lang(1) . ($max_size ? " " . lang(2, $max_size) : "") : lang(3)); +} + +/** Create repeat pattern for preg */ +function repeat_pattern(string $pattern, int $length): string { + // fix for Compilation failed: number too big in {} quantifier + return str_repeat("$pattern{0,65535}", $length / 65535) . "$pattern{0," . ($length % 65535) . "}"; // can create {0,0} which is OK +} + +/** Check whether the string is in UTF-8 */ +function is_utf8(?string $val): bool { + // don't print control chars except \t\r\n + return (preg_match('~~u', $val) && !preg_match('~[\0-\x8\xB\xC\xE-\x1F]~', $val)); +} + +/** Format decimal number +* @param float|numeric-string $val +*/ +function format_number($val): string { + return strtr(number_format($val, 0, ".", lang(4)), preg_split('~~u', lang(5), -1, PREG_SPLIT_NO_EMPTY)); +} + +/** Generate friendly URL */ +function friendly_url(string $val): string { + // used for blobs and export + return preg_replace('~\W~i', '-', $val); +} + +/** Get status of a single table and fall back to name on error +* @return TableStatus one element from table_status() +*/ +function table_status1(string $table, bool $fast = false): array { + $return = table_status($table, $fast); + return ($return ? reset($return) : array("Name" => $table)); +} + +/** Find out foreign keys for each column +* @return list[] [$col => []] +*/ +function column_foreign_keys(string $table): array { + $return = array(); + foreach (adminer()->foreignKeys($table) as $foreign_key) { + foreach ($foreign_key["source"] as $val) { + $return[$val][] = $foreign_key; + } + } + return $return; +} + +/** Compute fields() from $_POST edit data; used by Mongo and SimpleDB +* @return Field[] same as fields() +*/ +function fields_from_edit(): array { + $return = array(); + foreach ((array) $_POST["field_keys"] as $key => $val) { + if ($val != "") { + $val = bracket_escape($val); + $_POST["function"][$val] = $_POST["field_funs"][$key]; + $_POST["fields"][$val] = $_POST["field_vals"][$key]; + } + } + foreach ((array) $_POST["fields"] as $key => $val) { + $name = bracket_escape($key, true); // true - back + $return[$name] = array( + "field" => $name, + "privileges" => array("insert" => 1, "update" => 1, "where" => 1, "order" => 1), + "null" => 1, + "auto_increment" => ($key == driver()->primary), + ); + } + return $return; +} + +/** Send headers for export +* @return string extension +*/ +function dump_headers(string $identifier, bool $multi_table = false): string { + $return = adminer()->dumpHeaders($identifier, $multi_table); + $output = $_POST["output"]; + if ($output != "text") { + header("Content-Disposition: attachment; filename=" . adminer()->dumpFilename($identifier) . ".$return" . ($output != "file" && preg_match('~^[0-9a-z]+$~', $output) ? ".$output" : "")); + } + session_write_close(); + if (!ob_get_level()) { + ob_start(null, 4096); + } + ob_flush(); + flush(); + return $return; +} + +/** Print CSV row +* @param string[] $row +*/ +function dump_csv(array $row): void { + foreach ($row as $key => $val) { + if (preg_match('~["\n,;\t]|^0.|\.\d*0$~', $val) || $val === "") { + $row[$key] = '"' . str_replace('"', '""', $val) . '"'; + } + } + echo implode(($_POST["format"] == "csv" ? "," : ($_POST["format"] == "tsv" ? "\t" : ";")), $row) . "\r\n"; +} + +/** Apply SQL function +* @param string $column escaped column identifier +*/ +function apply_sql_function(?string $function, string $column): string { + return ($function ? ($function == "unixepoch" ? "DATETIME($column, '$function')" : ($function == "count distinct" ? "COUNT(DISTINCT " : strtoupper("$function(")) . "$column)") : $column); +} + +/** Get path of the temporary directory */ +function get_temp_dir(): string { + $return = ini_get("upload_tmp_dir"); // session_save_path() may contain other storage path + if (!$return) { + if (function_exists('sys_get_temp_dir')) { + $return = sys_get_temp_dir(); + } else { + $filename = @tempnam("", ""); // @ - temp directory can be disabled by open_basedir + if (!$filename) { + return ''; + } + $return = dirname($filename); + unlink($filename); + } + } + return $return; +} + +/** Open and exclusively lock a file +* @return resource|void null for error +*/ +function file_open_lock(string $filename) { + if (is_link($filename)) { + return; // https://cwe.mitre.org/data/definitions/61.html + } + $fp = @fopen($filename, "c+"); // @ - may not be writable + if (!$fp) { + return; + } + @chmod($filename, 0660); // @ - may not be permitted + if (!flock($fp, LOCK_EX)) { + fclose($fp); + return; + } + return $fp; +} + +/** Write and unlock a file +* @param resource $fp +*/ +function file_write_unlock($fp, string $data): void { + rewind($fp); + fwrite($fp, $data); + ftruncate($fp, strlen($data)); + file_unlock($fp); +} + +/** Unlock and close a file +* @param resource $fp +*/ +function file_unlock($fp): void { + flock($fp, LOCK_UN); + fclose($fp); +} + +/** Get first element of an array +* @param mixed[] $array +* @return mixed if not found +*/ +function first(array $array) { + // reset(f()) triggers a notice + return reset($array); +} + +/** Read password from file adminer.key in temporary directory or create one +* @return string '' if the file can not be created +*/ +function password_file(bool $create): string { + $filename = get_temp_dir() . "/adminer.key"; + if (!$create && !file_exists($filename)) { + return ''; + } + $fp = file_open_lock($filename); + if (!$fp) { + return ''; + } + $return = stream_get_contents($fp); + if (!$return) { + $return = rand_string(); + file_write_unlock($fp, $return); + } else { + file_unlock($fp); + } + return $return; +} + +/** Get a random string +* @return string 32 hexadecimal characters +*/ +function rand_string(): string { + return md5(uniqid(strval(mt_rand()), true)); +} + +/** Format value to use in select +* @param string|string[] $val +* @param Field $field +* @param ?numeric-string $text_length +* @return string HTML +*/ +function select_value($val, string $link, array $field, ?string $text_length): string { + if (is_array($val)) { + $return = ""; + foreach ($val as $k => $v) { + $return .= "" + . ($val != array_values($val) ? "" . h($k) : "") + . "" . select_value($v, $link, $field, $text_length) + ; + } + return "$return
"; + } + if (!$link) { + $link = adminer()->selectLink($val, $field); + } + if ($link === null) { + if (is_mail($val)) { + $link = "mailto:$val"; + } + if (is_url($val)) { + $link = $val; // IE 11 and all modern browsers hide referrer + } + } + $return = adminer()->editVal($val, $field); + if ($return !== null) { + if (!is_utf8($return)) { + $return = "\0"; // htmlspecialchars of binary data returns an empty string + } elseif ($text_length != "" && is_shortable($field)) { + $return = shorten_utf8($return, max(0, +$text_length)); // usage of LEFT() would reduce traffic but complicate query - expected average speedup: .001 s VS .01 s on local network + } else { + $return = h($return); + } + } + return adminer()->selectVal($return, $link, $field, $val); +} + +/** Check whether the field type is blob or equivalent +* @param Field $field +*/ +function is_blob(array $field): bool { + return preg_match('~blob|bytea|raw|file~', $field["type"]) && !in_array($field["type"], idx(driver()->structuredTypes(), lang(6), array())); +} + +/** Check whether the string is e-mail address */ +function is_mail(?string $email): bool { + $atom = '[-a-z0-9!#$%&\'*+/=?^_`{|}~]'; // characters of local-name + $domain = '[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])'; // one domain component + $pattern = "$atom+(\\.$atom+)*@($domain?\\.)+$domain"; + return is_string($email) && preg_match("(^$pattern(,\\s*$pattern)*\$)i", $email); +} + +/** Check whether the string is URL address */ +function is_url(?string $string): bool { + $domain = '[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])'; // one domain component //! IDN + return preg_match("~^(https?)://($domain?\\.)+$domain(:\\d+)?(/.*)?(\\?.*)?(#.*)?\$~i", $string); //! restrict path, query and fragment characters +} + +/** Check if field should be shortened +* @param Field $field +*/ +function is_shortable(array $field): bool { + return preg_match('~char|text|json|lob|geometry|point|linestring|polygon|string|bytea|hstore~', $field["type"]); +} + +/** Split server into host and (port or socket) +* @return array{0: string, 1: string} +*/ +function host_port(string $server) { + return (preg_match('~^(\[(.+)]|([^:]+)):([^:]+)$~', $server, $match) // [a:b] - IPv6 + ? array($match[2] . $match[3], $match[4]) + : array($server, '') + ); +} + +/** Get query to compute number of found rows +* @param list $where +* @param list $group +*/ +function count_rows(string $table, array $where, bool $is_group, array $group): string { + $query = " FROM " . table($table) . ($where ? " WHERE " . implode(" AND ", $where) : ""); + return ($is_group && (JUSH == "sql" || count($group) == 1) + ? "SELECT COUNT(DISTINCT " . implode(", ", $group) . ")$query" + : "SELECT COUNT(*)" . ($is_group ? " FROM (SELECT 1$query GROUP BY " . implode(", ", $group) . ") x" : $query) + ); +} + +/** Run query which can be killed by AJAX call after timing out +* @return string[] +*/ +function slow_query(string $query): array { + $db = adminer()->database(); + $timeout = adminer()->queryTimeout(); + $slow_query = driver()->slowQuery($query, $timeout); + $connection2 = null; + if (!$slow_query && support("kill")) { + $connection2 = connect(); + if ($connection2 && ($db == "" || $connection2->select_db($db))) { + $kill = get_val(connection_id(), 0, $connection2); // MySQL and MySQLi can use thread_id but it's not in PDO_MySQL + echo script("const timeout = setTimeout(() => { ajax('" . js_escape(ME) . "script=kill', function () {}, 'kill=$kill&token=" . get_token() . "'); }, 1000 * $timeout);"); + } + } + ob_flush(); + flush(); + $return = @get_key_vals(($slow_query ?: $query), $connection2, false); // @ - may be killed + if ($connection2) { + echo script("clearTimeout(timeout);"); + ob_flush(); + flush(); + } + return $return; +} + +/** Generate BREACH resistant CSRF token */ +function get_token(): string { + $rand = rand(1, 1e6); + return ($rand ^ $_SESSION["token"]) . ":$rand"; +} + +/** Verify if supplied CSRF token is valid */ +function verify_token(): bool { + list($token, $rand) = explode(":", $_POST["token"]); + return ($rand ^ $_SESSION["token"]) == $token; +} + +// used in compiled version +function lzw_decompress(string $binary): string { + // convert binary string to codes + $dictionary_count = 256; + $bits = 8; // ceil(log($dictionary_count, 2)) + $codes = array(); + $rest = 0; + $rest_length = 0; + for ($i=0; $i < strlen($binary); $i++) { + $rest = ($rest << 8) + ord($binary[$i]); + $rest_length += 8; + if ($rest_length >= $bits) { + $rest_length -= $bits; + $codes[] = $rest >> $rest_length; + $rest &= (1 << $rest_length) - 1; + $dictionary_count++; + if ($dictionary_count >> $bits) { + $bits++; + } + } + } + // decompression + /** @var list */ + $dictionary = range("\0", "\xFF"); + $return = ""; + $word = ""; + foreach ($codes as $i => $code) { + $element = $dictionary[$code]; + if (!isset($element)) { + $element = $word . $word[0]; + } + $return .= $element; + if ($i) { + $dictionary[] = $word . $element[0]; + } + $word = $element; + } + return $return; +} + +?> + element */ +function script(string $source, string $trailing = "\n"): string { + return "$source$trailing"; +} + +/** Return \n"; +} + +/** Get a nonce="" attribute with CSP nonce */ +function nonce(): string { + return ' nonce="' . get_nonce() . '"'; +} + +/** Get +* @param string|int $value +* @return string HTML +*/ +function input_hidden(string $name, $value = ""): string { + return "\n"; +} + +/** Get CSRF +* @return string HTML +*/ +function input_token(): string { + return input_hidden("token", get_token()); +} + +/** Get a target="_blank" attribute */ +function target_blank(): string { + return ' target="_blank" rel="noreferrer noopener"'; +} + +/** Escape for HTML */ +function h(?string $string): string { + return str_replace("\0", "�", htmlspecialchars($string, ENT_QUOTES, 'utf-8')); +} + +/** Convert \n to
*/ +function nl_br(string $string): string { + return str_replace("\n", "
", $string); // nl2br() uses XHTML before PHP 5.3 +} + +/** Generate HTML checkbox +* @param string|int $value +*/ +function checkbox(string $name, $value, ?bool $checked, string $label = "", string $onclick = "", string $class = "", string $labelled_by = ""): string { + $return = "" + . ($onclick ? script("qsl('input').onclick = function () { $onclick };", "") : "") + ; + return ($label != "" || $class ? "$return" . h($label) . "" : $return); +} + +/** Generate list of HTML options +* @param string[]|string[][] $options array of strings or arrays (creates optgroup) +* @param mixed $selected +* @param bool $use_keys always use array keys for value="", otherwise only string keys are used +*/ +function optionlist($options, $selected = null, bool $use_keys = false): string { + $return = ""; + foreach ($options as $k => $v) { + $opts = array($k => $v); + if (is_array($v)) { + $return .= ''; + $opts = $v; + } + foreach ($opts as $key => $val) { + $return .= '' . h($val) + ; + } + if (is_array($v)) { + $return .= ''; + } + } + return $return; +} + +/** Generate HTML " . $label_option . optionlist($options, $value) . "" + . ($onchange ? script("qsl('select').onchange = function () { $onchange };", "") : "") + ; +} + +/** Generate HTML radio list +* @param string[] $options +*/ +function html_radios(string $name, array $options, ?string $value = "", string $separator = ""): string { + $return = ""; + foreach ($options as $key => $val) { + $return .= "$separator"; + } + return $return; +} + +/** Get onclick confirmation */ +function confirm(string $message = "", string $selector = "qsl('input')"): string { + return script("$selector.onclick = () => confirm('" . ($message ? js_escape($message) : lang(7)) . "');", ""); +} + +/** Print header for hidden fieldset (close by ) +* @param bool $visible +*/ +function print_fieldset(string $id, string $legend, $visible = false): void { + echo "

"; + echo "$legend"; + echo script("qsl('a').onclick = partial(toggle, 'fieldset-$id');", ""); + echo ""; + echo "
\n"; + } + + /** Print command box in select + * @return bool whether to print default commands + */ + function selectCommandPrint(): bool { + return !information_schema(DB); + } + + /** Print import box in select + * @return bool whether to print default import + */ + function selectImportPrint(): bool { + return !information_schema(DB); + } + + /** Print extra text in the end of a select form + * @param string[] $emailFields fields holding e-mails + * @param string[] $columns selectable columns + */ + function selectEmailPrint(array $emailFields, array $columns): void { + } + + /** Process columns box in select + * @param string[] $columns selectable columns + * @param Index[] $indexes + * @return list> [[select_expressions], [group_expressions]] + */ + function selectColumnsProcess(array $columns, array $indexes): array { + $select = array(); // select expressions, empty for * + $group = array(); // expressions without aggregation - will be used for GROUP BY if an aggregation function is used + foreach ((array) $_GET["columns"] as $key => $val) { + if ($val["fun"] == "count" || ($val["col"] != "" && (!$val["fun"] || in_array($val["fun"], driver()->functions) || in_array($val["fun"], driver()->grouping)))) { + $select[$key] = apply_sql_function($val["fun"], ($val["col"] != "" ? idf_escape($val["col"]) : "*")); + if (!in_array($val["fun"], driver()->grouping)) { + $group[] = $select[$key]; + } + } + } + return array($select, $group); + } + + /** Process search box in select + * @param Field[] $fields + * @param Index[] $indexes + * @return list expressions to join by AND + */ + function selectSearchProcess(array $fields, array $indexes): array { + $return = array(); + foreach ($indexes as $i => $index) { + if ($index["type"] == "FULLTEXT" && idx($_GET["fulltext"], $i) != "") { + $return[] = "MATCH (" . implode(", ", array_map('Adminer\idf_escape', $index["columns"])) . ") AGAINST (" . q($_GET["fulltext"][$i]) . (isset($_GET["boolean"][$i]) ? " IN BOOLEAN MODE" : "") . ")"; + } + } + foreach ((array) $_GET["where"] as $key => $val) { + $col = $val["col"]; + if ("$col$val[val]" != "" && in_array($val["op"], adminer()->operators())) { + $conds = array(); + foreach (($col != "" ? array($col => $fields[$col]) : $fields) as $name => $field) { + $prefix = ""; + $cond = " $val[op]"; + if (preg_match('~IN$~', $val["op"])) { + $in = process_length($val["val"]); + $cond .= " " . ($in != "" ? $in : "(NULL)"); + } elseif ($val["op"] == "SQL") { + $cond = " $val[val]"; // SQL injection + } elseif (preg_match('~^(I?LIKE) %%$~', $val["op"], $match)) { + $cond = " $match[1] " . adminer()->processInput($field, "%$val[val]%"); + } elseif ($val["op"] == "FIND_IN_SET") { + $prefix = "$val[op](" . q($val["val"]) . ", "; + $cond = ")"; + } elseif (!preg_match('~NULL$~', $val["op"])) { + $cond .= " " . adminer()->processInput($field, $val["val"]); + } + if ($col != "" || ( // find anywhere + isset($field["privileges"]["where"]) + && (preg_match('~^[-\d.' . (preg_match('~IN$~', $val["op"]) ? ',' : '') . ']+$~', $val["val"]) || !preg_match('~' . number_type() . '|bit~', $field["type"])) + && (!preg_match("~[\x80-\xFF]~", $val["val"]) || preg_match('~char|text|enum|set~', $field["type"])) + && (!preg_match('~date|timestamp~', $field["type"]) || preg_match('~^\d+-\d+-\d+~', $val["val"])) + )) { + $conds[] = $prefix . driver()->convertSearch(idf_escape($name), $val, $field) . $cond; + } + } + $return[] = + (count($conds) == 1 ? $conds[0] : + ($conds ? "(" . implode(" OR ", $conds) . ")" : + "1 = 0" + )); + } + } + return $return; + } + + /** Process order box in select + * @param Field[] $fields + * @param Index[] $indexes + * @return list expressions to join by comma + */ + function selectOrderProcess(array $fields, array $indexes): array { + $return = array(); + foreach ((array) $_GET["order"] as $key => $val) { + if ($val != "") { + $return[] = (preg_match('~^((COUNT\(DISTINCT |[A-Z0-9_]+\()(`(?:[^`]|``)+`|"(?:[^"]|"")+")\)|COUNT\(\*\))$~', $val) ? $val : idf_escape($val)) //! MS SQL uses [] + . (isset($_GET["desc"][$key]) ? " DESC" : "") + ; + } + } + return $return; + } + + /** Process limit box in select */ + function selectLimitProcess(): int { + return (isset($_GET["limit"]) ? intval($_GET["limit"]) : 50); + } + + /** Process length box in select + * @return numeric-string number of characters to shorten texts, will be escaped, empty string means unlimited + */ + function selectLengthProcess(): string { + return (isset($_GET["text_length"]) ? "$_GET[text_length]" : "100"); + } + + /** Process extras in select form + * @param string[] $where AND conditions + * @param list[] $foreignKeys + * @return bool true if processed, false to process other parts of form + */ + function selectEmailProcess(array $where, array $foreignKeys): bool { + return false; + } + + /** Build SQL query used in select + * @param list $select result of selectColumnsProcess()[0] + * @param list $where result of selectSearchProcess() + * @param list $group result of selectColumnsProcess()[1] + * @param list $order result of selectOrderProcess() + * @param int $limit result of selectLimitProcess() + * @param int $page index of page starting at zero + * @return string empty string to use default query + */ + function selectQueryBuild(array $select, array $where, array $group, array $order, int $limit, ?int $page): string { + return ""; + } + + /** Query printed after execution in the message + * @param string $query executed query + * @param string $time elapsed time + */ + function messageQuery(string $query, string $time, bool $failed = false): string { + restart_session(); + $history = &get_session("queries"); + if (!idx($history, $_GET["db"])) { + $history[$_GET["db"]] = array(); + } + if (strlen($query) > 1e6) { + $query = preg_replace('~[\x80-\xFF]+$~', '', substr($query, 0, 1e6)) . "\n…"; // [\x80-\xFF] - valid UTF-8, \n - can end by one-line comment + } + $history[$_GET["db"]][] = array($query, time(), $time); // not DB - $_GET["db"] is changed in database.inc.php //! respect $_GET["ns"] + $sql_id = "sql-" . count($history[$_GET["db"]]); + $return = "" . lang(64) . " 🗐\n"; + if (!$failed && ($warnings = driver()->warnings())) { + $id = "warnings-" . count($history[$_GET["db"]]); + $return = "" . lang(46) . ", $return\n"; + } + return " " . @date("H:i:s") . "" // @ - time zone may be not set + . " $return' + ; + } + + /** Print before edit form + * @param Field[] $fields + * @param mixed $row + */ + function editRowPrint(string $table, array $fields, $row, ?bool $update): void { + } + + /** Functions displayed in edit form + * @param Field|array{null:bool} $field + * @return string[] + */ + function editFunctions(array $field): array { + $return = ($field["null"] ? "NULL/" : ""); + $update = isset($_GET["select"]) || where($_GET); + foreach (array(driver()->insertFunctions, driver()->editFunctions) as $key => $functions) { + if (!$key || (!isset($_GET["call"]) && $update)) { // relative functions + foreach ($functions as $pattern => $val) { + if (!$pattern || preg_match("~$pattern~", $field["type"])) { + $return .= "/$val"; + } + } + } + if ($key && $functions && !preg_match('~set|bool~', $field["type"]) && !is_blob($field)) { + $return .= "/SQL"; + } + } + if ($field["auto_increment"] && !$update) { + $return = lang(51); + } + return explode("/", $return); + } + + /** Get options to display edit field + * @param ?string $table null in call.inc.php + * @param Field $field + * @param string $attrs attributes to use inside the tag + * @param string|string[]|false|null $value false means original value + * @return string custom input field or empty string for default + */ + function editInput(?string $table, array $field, string $attrs, $value): string { + if ($field["type"] == "enum") { + return (isset($_GET["select"]) ? " " : "") + . enum_input("radio", $attrs, $field, $value, "NULL") + ; + } + return ""; + } + + /** Get hint for edit field + * @param ?string $table null in call.inc.php + * @param Field $field + */ + function editHint(?string $table, array $field, ?string $value): string { + return ""; + } + + /** Process sent input + * @param Field $field + * @return string expression to use in a query + */ + function processInput(array $field, string $value, ?string $function = ""): string { + if ($function == "SQL") { + return $value; // SQL injection + } + $name = $field["field"]; + $return = q($value); + if (preg_match('~^(now|getdate|uuid)$~', $function)) { + $return = "$function()"; + } elseif (preg_match('~^current_(date|timestamp)$~', $function)) { + $return = $function; + } elseif (preg_match('~^([+-]|\|\|)$~', $function)) { + $return = idf_escape($name) . " $function $return"; + } elseif (preg_match('~^[+-] interval$~', $function)) { + $return = idf_escape($name) . " $function " . (preg_match("~^(\\d+|'[0-9.: -]') [A-Z_]+\$~i", $value) && JUSH != "pgsql" ? $value : $return); + } elseif (preg_match('~^(addtime|subtime|concat)$~', $function)) { + $return = "$function(" . idf_escape($name) . ", $return)"; + } elseif (preg_match('~^(md5|sha1|password|encrypt)$~', $function)) { + $return = "$function($return)"; + } + return unconvert_field($field, $return); + } + + /** Return export output options + * @return string[] + */ + function dumpOutput(): array { + $return = array('text' => lang(65), 'file' => lang(66)); + if (function_exists('gzencode')) { + $return['gz'] = 'gzip'; + } + return $return; + } + + /** Return export format options + * @return string[] empty to disable export + */ + function dumpFormat(): array { + return (support("dump") ? array('sql' => 'SQL') : array()) + array('csv' => 'CSV,', 'csv;' => 'CSV;', 'tsv' => 'TSV'); + } + + /** Export database structure + * @return void prints data + */ + function dumpDatabase(string $db): void { + } + + /** Export table structure + * @param int $is_view 0 table, 1 view, 2 temporary view table + * @return void prints data + */ + function dumpTable(string $table, string $style, int $is_view = 0): void { + if ($_POST["format"] != "sql") { + echo "\xef\xbb\xbf"; // UTF-8 byte order mark + if ($style) { + dump_csv(array_keys(fields($table))); + } + } else { + if ($is_view == 2) { + $fields = array(); + foreach (fields($table) as $name => $field) { + $fields[] = idf_escape($name) . " $field[full_type]"; + } + $create = "CREATE TABLE " . table($table) . " (" . implode(", ", $fields) . ")"; + } else { + $create = create_sql($table, $_POST["auto_increment"], $style); + } + set_utf8mb4($create); + if ($style && $create) { + if ($style == "DROP+CREATE" || $is_view == 1) { + echo "DROP " . ($is_view == 2 ? "VIEW" : "TABLE") . " IF EXISTS " . table($table) . ";\n"; + } + if ($is_view == 1) { + $create = remove_definer($create); + } + echo "$create;\n\n"; + } + } + } + + /** Export table data + * @return void prints data + */ + function dumpData(string $table, string $style, string $query): void { + if ($style) { + $max_packet = (JUSH == "sqlite" ? 0 : 1048576); // default, minimum is 1024 + $fields = array(); + $identity_insert = false; + if ($_POST["format"] == "sql") { + if ($style == "TRUNCATE+INSERT") { + echo truncate_sql($table) . ";\n"; + } + $fields = fields($table); + if (JUSH == "mssql") { + foreach ($fields as $field) { + if ($field["auto_increment"]) { + echo "SET IDENTITY_INSERT " . table($table) . " ON;\n"; + $identity_insert = true; + break; + } + } + } + } + $result = connection()->query($query, 1); // 1 - MYSQLI_USE_RESULT + if ($result) { + $insert = ""; + $buffer = ""; + $keys = array(); + $generated = array(); + $suffix = ""; + $fetch_function = ($table != '' ? 'fetch_assoc' : 'fetch_row'); + $count = 0; + while ($row = $result->$fetch_function()) { + if (!$keys) { + $values = array(); + foreach ($row as $val) { + $field = $result->fetch_field(); + if (idx($fields[$field->name], 'generated')) { + $generated[$field->name] = true; + continue; + } + $keys[] = $field->name; + $key = idf_escape($field->name); + $values[] = "$key = VALUES($key)"; + } + $suffix = ($style == "INSERT+UPDATE" ? "\nON DUPLICATE KEY UPDATE " . implode(", ", $values) : "") . ";\n"; + } + if ($_POST["format"] != "sql") { + if ($style == "table") { + dump_csv($keys); + $style = "INSERT"; + } + dump_csv($row); + } else { + if (!$insert) { + $insert = "INSERT INTO " . table($table) . " (" . implode(", ", array_map('Adminer\idf_escape', $keys)) . ") VALUES"; + } + foreach ($row as $key => $val) { + if ($generated[$key]) { + unset($row[$key]); + continue; + } + $field = $fields[$key]; + $row[$key] = ($val !== null + ? unconvert_field($field, preg_match(number_type(), $field["type"]) && !preg_match('~\[~', $field["full_type"]) && is_numeric($val) ? $val : q(($val === false ? 0 : $val))) + : "NULL" + ); + } + $s = ($max_packet ? "\n" : " ") . "(" . implode(",\t", $row) . ")"; + if (!$buffer) { + $buffer = $insert . $s; + } elseif (JUSH == 'mssql' + ? $count % 1000 != 0 // https://learn.microsoft.com/en-us/sql/t-sql/queries/table-value-constructor-transact-sql#limitations-and-restrictions + : strlen($buffer) + 4 + strlen($s) + strlen($suffix) < $max_packet // 4 - length specification + ) { + $buffer .= ",$s"; + } else { + echo $buffer . $suffix; + $buffer = $insert . $s; + } + } + $count++; + } + if ($buffer) { + echo $buffer . $suffix; + } + } elseif ($_POST["format"] == "sql") { + echo "-- " . str_replace("\n", " ", connection()->error) . "\n"; + } + if ($identity_insert) { + echo "SET IDENTITY_INSERT " . table($table) . " OFF;\n"; + } + } + } + + /** Set export filename + * @return string filename without extension + */ + function dumpFilename(string $identifier): string { + return friendly_url($identifier != "" ? $identifier : (SERVER ?: "localhost")); + } + + /** Send headers for export + * @return string extension + */ + function dumpHeaders(string $identifier, bool $multi_table = false): string { + $output = $_POST["output"]; + $ext = (preg_match('~sql~', $_POST["format"]) ? "sql" : ($multi_table ? "tar" : "csv")); // multiple CSV packed to TAR + header("Content-Type: " . + ($output == "gz" ? "application/x-gzip" : + ($ext == "tar" ? "application/x-tar" : + ($ext == "sql" || $output != "file" ? "text/plain" : "text/csv") . "; charset=utf-8" + ))); + if ($output == "gz") { + ob_start(function ($string) { + // ob_start() callback receives an optional parameter $phase but gzencode() accepts optional parameter $level + return gzencode($string); + }, 1e6); + } + return $ext; + } + + /** Print text after export + * @return void prints data + */ + function dumpFooter(): void { + if ($_POST["format"] == "sql") { + echo "-- " . gmdate("Y-m-d H:i:s e") . "\n"; + } + } + + /** Set the path of the file for webserver load + * @return string path of the sql dump file + */ + function importServerPath(): string { + return "adminer.sql"; + } + + /** Print homepage + * @return bool whether to print default homepage + */ + function homepage(): bool { + echo '

" . adminer()->name() . " " . VERSION; + $new_version = $_COOKIE["adminer_version"]; + echo " " . (version_compare(VERSION, $new_version) < 0 ? h($new_version) : "") . ""; + echo "

\n"; + // this is matched by compile.php + switch_lang(); + if ($missing == "auth") { + $output = ""; + foreach ((array) $_SESSION["pwds"] as $vendor => $servers) { + foreach ($servers as $server => $usernames) { + $name = h(get_setting("vendor-$vendor-$server") ?: get_driver($vendor)); + foreach ($usernames as $username => $password) { + if ($password !== null) { + $dbs = $_SESSION["db"][$vendor][$server][$username]; + foreach (($dbs ? array_keys($dbs) : array("")) as $db) { + $output .= "
  • ($name) " . h("$username@" . ($server != "" ? adminer()->serverName($server) : "") . ($db != "" ? " - $db" : "")) . "\n"; + } + } + } + } + } + if ($output) { + echo "
      \n$output
    \n" . script("mixin(qs('#logins'), {onmouseover: menuOver, onmouseout: menuOut});"); + } + } else { + $tables = array(); + if ($_GET["ns"] !== "" && !$missing && DB != "") { + connection()->select_db(DB); + $tables = table_status('', true); + } + adminer()->syntaxHighlighting($tables); + adminer()->databasesPrint($missing); + $actions = array(); + if (DB == "" || !$missing) { + if (support("sql")) { + $actions[] = "" . lang(64) . ""; + $actions[] = "" . lang(75) . ""; + } + $actions[] = "" . lang(76) . ""; + } + $in_db = $_GET["ns"] !== "" && !$missing && DB != ""; + if ($in_db) { + $actions[] = '" . lang(77) . ""; + } + echo ($actions ? "

    " . lang(11) . "

    \n"; + } + } + } + } + + /** Set up syntax highlight for code and "; +} + +/** Generate HTML if $options are empty +* @param string[] $options +*/ +function select_input(string $attrs, array $options, ?string $value = "", string $onchange = "", string $placeholder = ""): string { + $tag = ($options ? "select" : "input"); + return "<$tag$attrs" . ($options + ? ">