diff --git a/app/commands/ConvertExerciseAttachments.php b/app/commands/ConvertExerciseAttachments.php index 14f9bff73..b85bb1c38 100644 --- a/app/commands/ConvertExerciseAttachments.php +++ b/app/commands/ConvertExerciseAttachments.php @@ -134,7 +134,7 @@ public function __construct( $this->fileStorageManager = $fileStorageManager; } - protected function configure() + protected function configure(): void { $this->addOption( 'apiBase', diff --git a/app/commands/DoctrineFixtures.php b/app/commands/DoctrineFixtures.php index 7ae069472..9c12b9036 100644 --- a/app/commands/DoctrineFixtures.php +++ b/app/commands/DoctrineFixtures.php @@ -4,6 +4,8 @@ use App\Model\Entity\Pipeline; use Doctrine\DBAL; +use Doctrine\DBAL\Platforms\AbstractMySQLPlatform; +use Doctrine\DBAL\Platforms\SQLitePlatform; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Id\AssignedGenerator; use Nette\Utils\Finder; @@ -64,7 +66,7 @@ public function __construct( /** * Register the 'db:fill' command in the framework */ - protected function configure() + protected function configure(): void { $this->addOption( 'test', @@ -121,50 +123,44 @@ protected function execute(InputInterface $input, OutputInterface $output): int */ protected function clearDatabase() { - $platform = $this->dbConnection->getDatabasePlatform()->getName(); + $platform = $this->dbConnection->getDatabasePlatform(); - if ($platform === 'mysql') { + if ($platform instanceof AbstractMySQLPlatform) { $this->dbConnection->executeQuery("SET FOREIGN_KEY_CHECKS = 0"); - } else { - if ($platform === 'sqlite') { - $this->dbConnection->executeQuery("PRAGMA foreign_keys = OFF"); - } + } elseif ($platform instanceof SQLitePlatform) { + $this->dbConnection->executeQuery("PRAGMA foreign_keys = OFF"); } - foreach ($this->dbConnection->getSchemaManager()->listTables() as $table) { + + foreach ($this->dbConnection->createSchemaManager()->introspectTables() as $table) { $tableName = $table->getName(); if ($tableName === "doctrine_migrations") { // do not clear migrations table... it is crucial continue; } - if ($platform === 'mysql') { + if ($platform instanceof AbstractMySQLPlatform) { if (!str_starts_with($tableName, '``')) { $tableName = '`' . $tableName . '`'; } - } else { - if ($platform === 'sqlite') { - if (!str_starts_with($tableName, '``')) { - $tableName = '"' . $tableName . '"'; - } + } elseif ($platform instanceof SQLitePlatform) { + if (!str_starts_with($tableName, '``')) { + $tableName = '"' . $tableName . '"'; } } - if ($platform === "mysql") { + + if ($platform instanceof AbstractMySQLPlatform) { $this->dbConnection->executeQuery(sprintf("TRUNCATE %s", $tableName)); - } else { - if ($platform === "sqlite") { - $this->dbConnection->executeQuery(sprintf("DELETE FROM %s", $tableName)); - } + } elseif ($platform instanceof SQLitePlatform) { + $this->dbConnection->executeQuery(sprintf("DELETE FROM %s", $tableName)); } } - if ($platform === 'pdo_mysql') { + if ($platform instanceof AbstractMySQLPlatform) { $this->dbConnection->executeQuery("SET FOREIGN_KEY_CHECKS = 1"); - } else { - if ($platform === 'sqlite') { - $this->dbConnection->executeQuery("PRAGMA foreign_keys = ON"); - } + } elseif ($platform instanceof SQLitePlatform) { + $this->dbConnection->executeQuery("PRAGMA foreign_keys = ON"); } } } diff --git a/app/commands/PlagiarismDetectionAccessToken.php b/app/commands/PlagiarismDetectionAccessToken.php index f16a64a88..f4a239991 100644 --- a/app/commands/PlagiarismDetectionAccessToken.php +++ b/app/commands/PlagiarismDetectionAccessToken.php @@ -38,7 +38,7 @@ public function __construct(AccessManager $accessManager, Users $users) $this->users = $users; } - protected function configure() + protected function configure(): void { $this->addArgument('userId', InputArgument::REQUIRED, 'ID of the admin owning the token.'); $this->addOption( diff --git a/app/commands/RemoveInactiveUsers.php b/app/commands/RemoveInactiveUsers.php index d6f4517e5..2508c773a 100644 --- a/app/commands/RemoveInactiveUsers.php +++ b/app/commands/RemoveInactiveUsers.php @@ -64,7 +64,7 @@ public function __construct(array $config, Users $users, AnonymizationHelper $an $this->anonymizationHelper = $anonymizationHelper; } - protected function configure() + protected function configure(): void { $this->addOption( 'report', diff --git a/app/commands/runtimes/FixConfigVariables.php b/app/commands/runtimes/FixConfigVariables.php index a7a0266aa..1479480a5 100644 --- a/app/commands/runtimes/FixConfigVariables.php +++ b/app/commands/runtimes/FixConfigVariables.php @@ -67,7 +67,7 @@ public function __construct( $this->exerciseConfigHelper = $exerciseConfigHelper; } - protected function configure() + protected function configure(): void { $this->addArgument( 'runtime', diff --git a/app/commands/runtimes/FixExerciseConfigs.php b/app/commands/runtimes/FixExerciseConfigs.php index 4ec18fa61..fb2d44095 100644 --- a/app/commands/runtimes/FixExerciseConfigs.php +++ b/app/commands/runtimes/FixExerciseConfigs.php @@ -53,7 +53,7 @@ public function __construct( $this->exerciseConfigs = $exerciseConfigs; } - protected function configure() + protected function configure(): void { $this->addArgument( 'runtime', diff --git a/app/commands/runtimes/RuntimeExport.php b/app/commands/runtimes/RuntimeExport.php index 0d1a3af27..258fcdb62 100644 --- a/app/commands/runtimes/RuntimeExport.php +++ b/app/commands/runtimes/RuntimeExport.php @@ -40,7 +40,7 @@ public function __construct( $this->fileManager = $fileManager; } - protected function configure() + protected function configure(): void { $this->addArgument('runtime', InputArgument::REQUIRED, 'ID of the runtime environment to be exported.') ->addArgument('saveAs', InputArgument::REQUIRED, 'Path to the output ZIP archive.'); diff --git a/app/commands/runtimes/RuntimeImport.php b/app/commands/runtimes/RuntimeImport.php index d21fcd2fc..828a539e6 100644 --- a/app/commands/runtimes/RuntimeImport.php +++ b/app/commands/runtimes/RuntimeImport.php @@ -73,7 +73,7 @@ public function __construct( $this->configValidator = $configValidator; } - protected function configure() + protected function configure(): void { $this->addArgument( 'zipFile', diff --git a/app/commands/security/ListExamEvents.php b/app/commands/security/ListExamEvents.php index 689fa2a67..d358efe83 100644 --- a/app/commands/security/ListExamEvents.php +++ b/app/commands/security/ListExamEvents.php @@ -45,7 +45,7 @@ public function __construct(GroupExamLocks $examLocks) $this->examLocks = $examLocks; } - protected function configure() + protected function configure(): void { $this->addOption( 'from', diff --git a/app/commands/security/ListSecurityEvents.php b/app/commands/security/ListSecurityEvents.php index c98738b93..9280ef83b 100644 --- a/app/commands/security/ListSecurityEvents.php +++ b/app/commands/security/ListSecurityEvents.php @@ -44,7 +44,7 @@ public function __construct(SecurityEvents $events) $this->events = $events; } - protected function configure() + protected function configure(): void { $this->addOption( 'from', diff --git a/app/config/config.local.neon.example b/app/config/config.local.neon.example index cb33f1ade..fd69a045e 100644 --- a/app/config/config.local.neon.example +++ b/app/config/config.local.neon.example @@ -97,11 +97,13 @@ parameters: # The most important part - a database system connection nettrine.dbal: - connection: - host: "localhost" - user: "recodex" - password: "someSecretPasswordYouNeedToSetYourself" - dbname: "recodex" + connections: + default: + host: "localhost" + user: "recodex" + password: "someSecretPasswordYouNeedToSetYourself" + dbname: "recodex" + charset: utf8mb4 # configure mailing module mail: diff --git a/app/config/config.neon b/app/config/config.neon index 516e851b5..2b7d4a033 100644 --- a/app/config/config.neon +++ b/app/config/config.neon @@ -279,14 +279,8 @@ acl: extensions: console: Contributte\Console\DI\ConsoleExtension(%consoleMode%) - nettrine.annotations: Nettrine\Annotations\DI\AnnotationsExtension - nettrine.cache: Nettrine\Cache\DI\CacheExtension nettrine.dbal: Nettrine\DBAL\DI\DbalExtension - nettrine.dbal.console: Nettrine\DBAL\DI\DbalConsoleExtension nettrine.orm: Nettrine\ORM\DI\OrmExtension - nettrine.orm.cache: Nettrine\ORM\DI\OrmCacheExtension - nettrine.orm.console: Nettrine\ORM\DI\OrmConsoleExtension(%consoleMode%) - nettrine.orm.annotations: Nettrine\ORM\DI\OrmAnnotationsExtension nettrine.migrations: Nettrine\Migrations\DI\MigrationsExtension nettrine.extensions.atlantic18: Nettrine\Extensions\Atlantic18\DI\Atlantic18BehaviorExtension fixtures: Zenify\DoctrineFixtures\DI\FixturesExtension @@ -486,39 +480,33 @@ nettrine.dbal: debug: panel: false sourcePaths: [%appDir%] - connection: - driver: pdo_mysql - host: localhost - dbname: 'recodex-api' - user: 'root' - password: '' - charset: utf8mb4 - types: - bit: Doctrine\DBAL\Types\BooleanType - datetime: DoctrineExtensions\DBAL\Types\UTCDateTimeType - uuid: Ramsey\Uuid\Doctrine\UuidType - defaultTableOptions: - charset: utf8mb4 - collate: utf8mb4_unicode_ci + types: + bit: Doctrine\DBAL\Types\BooleanType + datetime: DoctrineExtensions\DBAL\Types\UTCDateTimeType + uuid: Ramsey\Uuid\Doctrine\UuidType + connections: + default: + driver: pdo_mysql + host: localhost + # dbname: 'recodex-api' + # charset: utf8mb4 + defaultTableOptions: + charset: utf8mb4 + collate: utf8mb4_unicode_ci nettrine.orm: - configuration: - autoGenerateProxyClasses: true - customStringFunctions: - coalesce_sub: DoctrineExtensions\Query\Functions\CoalesceSubselectsFunction - type: DoctrineExtensions\Query\Functions\TypeFunction - -nettrine.orm.annotations: - mapping: - App\Model\Entity: %appDir%/model/entity - -nettrine.annotations: - ignore: - - LoggedIn - - POST - - GET - - PUT - - DELETE + managers: + default: + connection: default + mapping: + App: + directories: [%appDir%/model/entity] + namespace: App\Model\Entity + autoGenerateProxyClasses: true + lazyNativeObjects: true + customStringFunctions: + coalesce_sub: DoctrineExtensions\Query\Functions\CoalesceSubselectsFunction + type: DoctrineExtensions\Query\Functions\TypeFunction nettrine.extensions.atlantic18: softDeleteable: true @@ -534,4 +522,4 @@ fixtures: seed: 1 console: - name: ReCodEx Core API \ No newline at end of file + name: ReCodEx Core API diff --git a/app/model/entity/Assignment.php b/app/model/entity/Assignment.php index 235c79375..761ec2f36 100644 --- a/app/model/entity/Assignment.php +++ b/app/model/entity/Assignment.php @@ -14,21 +14,24 @@ use DateTime; use InvalidArgumentException; -/** - * @ORM\Entity - * @ORM\Table(indexes={@ORM\Index(name="first_deadline_idx", columns={"first_deadline"}), - * @ORM\Index(name="second_deadline_idx", columns={"second_deadline"})}) - * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false) - */ +#[ORM\Table] +#[ORM\Index(name: 'first_deadline_idx', columns: ['first_deadline'])] +#[ORM\Index(name: 'second_deadline_idx', columns: ['second_deadline'])] +#[ORM\Entity] +#[Gedmo\SoftDeleteable(fieldName: 'deletedAt', timeAware: false)] class Assignment extends AssignmentBase implements IExercise { use ExerciseData; /** - * @ORM\OneToMany(targetEntity="ExerciseFileLink", mappedBy="assignment", cascade={"persist", "remove"}, - * orphanRemoval=true) * @var Collection */ + #[ORM\OneToMany( + targetEntity: ExerciseFileLink::class, + mappedBy: 'assignment', + cascade: ['persist', 'remove'], + orphanRemoval: true + )] protected $exerciseFileLinks; /** @@ -133,23 +136,21 @@ public static function assignToGroup( } /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="float") - */ + #[ORM\Column(type: 'float')] protected $pointsPercentualThreshold; /** - * @ORM\ManyToMany(targetEntity="LocalizedAssignment", indexBy="locale") * @var Collection|Selectable */ + #[ORM\ManyToMany(targetEntity: LocalizedAssignment::class, indexBy: 'locale')] protected $localizedAssignments; public function getLocalizedAssignments(): Collection @@ -174,14 +175,10 @@ public function getLocalizedAssignmentByLocale(string $locale): ?LocalizedAssign return $first === false ? null : $first; } - /** - * @ORM\Column(type="smallint") - */ + #[ORM\Column(type: 'smallint')] protected $submissionsCountLimit; - /** - * @ORM\Column(type="datetime", nullable=true) - */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $visibleFrom; public function isVisibleToStudents() @@ -190,19 +187,13 @@ public function isVisibleToStudents() return $this->isPublic() && (!$this->visibleFrom || $this->visibleFrom <= (new DateTime())); } - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $firstDeadline; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $allowSecondDeadline; - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $secondDeadline; public function isAfterDeadline(?DateTime $now = null): bool @@ -226,19 +217,13 @@ public function isAfterFirstDeadline(?DateTime $now = null): bool return $this->firstDeadline < $now; } - /** - * @ORM\Column(type="smallint") - */ + #[ORM\Column(type: 'smallint')] protected $maxPointsBeforeFirstDeadline; - /** - * @ORM\Column(type="smallint") - */ + #[ORM\Column(type: 'smallint')] protected $maxPointsBeforeSecondDeadline; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $maxPointsDeadlineInterpolation = false; public function getMaxPoints(?DateTime $time = null): int @@ -278,43 +263,35 @@ public function hasAssignedPoints(): bool } /** - * @ORM\Column(type="boolean") * Whether a student can see the relative consumed time and memory (for each test). */ + #[ORM\Column(type: 'boolean')] protected $canViewLimitRatios = false; /** - * @ORM\Column(type="boolean") * Whether a student can see the absolute values of consumed time and memory (for each test). * This only applies if $canViewLimitRatios is true. */ + #[ORM\Column(type: 'boolean')] protected $canViewMeasuredValues = false; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $canViewJudgeStdout = false; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $canViewJudgeStderr = false; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $mergeJudgeLogs = false; /** - * @ORM\Column(type="boolean") * True if this is an assignment dedicated for an exam. * Exam assignments are visualized differently and have auto-synced visibility and deadline with exam period. */ + #[ORM\Column(type: 'boolean')] protected $exam = false; - /** - * @ORM\ManyToOne(targetEntity="Exercise", inversedBy="assignments") - */ + #[ORM\ManyToOne(targetEntity: Exercise::class, inversedBy: 'assignments')] protected $exercise; public function getExercise(): ?Exercise @@ -322,9 +299,7 @@ public function getExercise(): ?Exercise return $this->exercise->isDeleted() ? null : $this->exercise; } - /** - * @ORM\ManyToOne(targetEntity="Group", inversedBy="assignments") - */ + #[ORM\ManyToOne(targetEntity: Group::class, inversedBy: 'assignments')] protected $group; public function getGroup(): ?Group @@ -332,15 +307,11 @@ public function getGroup(): ?Group return $this->group->isDeleted() ? null : $this->group; } - /** - * @ORM\OneToMany(targetEntity="AssignmentSolution", mappedBy="assignment") - */ + #[ORM\OneToMany(targetEntity: AssignmentSolution::class, mappedBy: 'assignment')] protected $assignmentSolutions; - /** - * @ORM\ManyToMany(targetEntity="RuntimeEnvironment") - * @ORM\JoinTable(name="assignment_disabled_runtime_environments") - */ + #[ORM\JoinTable(name: 'assignment_disabled_runtime_environments')] + #[ORM\ManyToMany(targetEntity: RuntimeEnvironment::class)] protected $disabledRuntimeEnvironments; public function getRuntimeEnvironments(): ReadableCollection @@ -378,9 +349,7 @@ function (RuntimeEnvironment $environment) { )->getValues(); } - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $syncedAt; public function getSyncedAt(): DateTime @@ -648,9 +617,9 @@ public function syncWithExercise(array $options = []): void /** * @var PlagiarismDetectionBatch|null - * @ORM\ManyToOne(targetEntity="PlagiarismDetectionBatch") * Refers to last plagiarism detection batch which checked solutions of this assignment. */ + #[ORM\ManyToOne(targetEntity: PlagiarismDetectionBatch::class)] protected $plagiarismBatch = null; /* diff --git a/app/model/entity/AssignmentSolution.php b/app/model/entity/AssignmentSolution.php index e01c58224..222d3e887 100644 --- a/app/model/entity/AssignmentSolution.php +++ b/app/model/entity/AssignmentSolution.php @@ -7,9 +7,7 @@ use Doctrine\ORM\Mapping as ORM; use DateTime; -/** - * @ORM\Entity - */ +#[ORM\Entity] class AssignmentSolution { use FlagAccessor; @@ -17,23 +15,21 @@ class AssignmentSolution public const JOB_TYPE = "student"; /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="string", length=1024) - */ + #[ORM\Column(type: 'string', length: 1024)] protected $note; /** * @var ?Assignment - * @ORM\ManyToOne(targetEntity="Assignment", inversedBy="assignmentSolutions") */ + #[ORM\ManyToOne(targetEntity: Assignment::class, inversedBy: 'assignmentSolutions')] protected $assignment; public function getAssignment(): ?Assignment @@ -65,52 +61,46 @@ public function getMaxPoints() /** * @var Solution - * @ORM\ManyToOne(targetEntity="Solution", cascade={"persist", "remove"}, fetch="EAGER") */ + #[ORM\ManyToOne(targetEntity: Solution::class, cascade: ['persist', 'remove'], fetch: 'EAGER')] protected $solution; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $accepted; /** - * @ORM\Column(type="boolean") * If true, the student is requesting a code review for this solution. * One solution of one solver at most may have this flag set (similarly to accepted flag). * The flag is automatically reset when review is saved. */ + #[ORM\Column(type: 'boolean')] protected $reviewRequest = false; /** - * @ORM\Column(type="datetime", nullable=true) * Time when a review was started. */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $reviewStartedAt = null; /** - * @ORM\Column(type="datetime", nullable=true) * Time when a review was closed (and the students were duly notified the comments are complete). * Not null value also marks the solution as "reviewed" (replaces previous bool flag). */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $reviewedAt = null; /** - * @ORM\Column(type="integer") * Number of issues made in review comments. This is an aggregated cached value so it can be accessed faster. * The number of issues is computed when (and updated after) the review is closed. * When the review is open, the number of issues is kept 0, regardless of how many issue comments exist. */ + #[ORM\Column(type: 'integer')] protected $issues = 0; - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: 'integer')] protected $bonusPoints; - /** - * @ORM\Column(type="integer", nullable=true) - */ + #[ORM\Column(type: 'integer', nullable: true)] protected $overriddenPoints; /** @@ -148,10 +138,13 @@ public function getTotalPoints() /** * Note that order by annotation has to be present! - * - * @ORM\OneToMany(targetEntity="AssignmentSolutionSubmission", mappedBy="assignmentSolution", cascade={"remove"}) - * @ORM\OrderBy({"submittedAt" = "DESC"}) */ + #[ORM\OneToMany( + targetEntity: AssignmentSolutionSubmission::class, + mappedBy: 'assignmentSolution', + cascade: ['remove'] + )] + #[ORM\OrderBy(['submittedAt' => 'DESC'])] protected $submissions; /** @@ -159,9 +152,9 @@ public function getTotalPoints() * The reference should speed up loading in many cases since the last submission is the only one that counts. * However, this behavior might be altered in the future, so we can actively select which submission is relevant. * - * @ORM\OneToOne(targetEntity="AssignmentSolutionSubmission", fetch="EAGER", cascade={"persist"}) * @var AssignmentSolutionSubmission|null */ + #[ORM\OneToOne(targetEntity: AssignmentSolutionSubmission::class, fetch: 'EAGER', cascade: ['persist'])] protected $lastSubmission = null; /** @@ -180,21 +173,19 @@ function (AssignmentSolutionSubmission $submission) { * Incremental counter marking submission attempts of one user solving one assignment (one-based). * Each solution gets an unique marker (per user x assignment) which is immutable, * so it will hold even when some solutions get deleted. - * @ORM\Column(type="integer") */ + #[ORM\Column(type: 'integer')] protected $attemptIndex; - /** - * @ORM\OneToMany(targetEntity="ReviewComment", mappedBy="solution") - */ + #[ORM\OneToMany(targetEntity: ReviewComment::class, mappedBy: 'solution')] protected $reviewComments; /** * @var PlagiarismDetectionBatch|null - * @ORM\ManyToOne(targetEntity="PlagiarismDetectionBatch") * Refers to last plagiarism detection batch, in which similarities were detected for this solution. * If null, no similarities were detected (yet). */ + #[ORM\ManyToOne(targetEntity: PlagiarismDetectionBatch::class)] protected $plagiarismBatch = null; /** diff --git a/app/model/entity/AssignmentSolutionSubmission.php b/app/model/entity/AssignmentSolutionSubmission.php index b80e5b26e..853e78ed3 100644 --- a/app/model/entity/AssignmentSolutionSubmission.php +++ b/app/model/entity/AssignmentSolutionSubmission.php @@ -7,24 +7,25 @@ use Doctrine\ORM\Mapping as ORM; use App\Helpers\EvaluationStatus as ES; -/** - * @ORM\Entity - * @ORM\Table(indexes={@ORM\Index(name="assignment_solution_submission_submitted_at_idx", columns={"submitted_at"})}) - */ +#[ORM\Table] +#[ORM\Index(name: 'assignment_solution_submission_submitted_at_idx', columns: ['submitted_at'])] +#[ORM\Entity] class AssignmentSolutionSubmission extends Submission implements ES\IEvaluable { public const JOB_TYPE = "student"; - /** - * @ORM\ManyToOne(targetEntity="AssignmentSolution", inversedBy="submissions") - */ + #[ORM\ManyToOne(targetEntity: AssignmentSolution::class, inversedBy: 'submissions')] protected $assignmentSolution; /** - * @ORM\OneToOne(targetEntity="SubmissionFailure", cascade={"persist", "remove"}, - * inversedBy="assignmentSolutionSubmission", fetch="EAGER") * @var SubmissionFailure */ + #[ORM\OneToOne( + targetEntity: SubmissionFailure::class, + cascade: ['persist', 'remove'], + inversedBy: 'assignmentSolutionSubmission', + fetch: 'EAGER' + )] protected $failure; diff --git a/app/model/entity/AssignmentSolver.php b/app/model/entity/AssignmentSolver.php index 15ad99a7d..0dda81bd2 100644 --- a/app/model/entity/AssignmentSolver.php +++ b/app/model/entity/AssignmentSolver.php @@ -8,45 +8,46 @@ /** * This entity holds records related to all solutions/submissions of one user to one assignment. * The entity is created with the first solution (of a user/assignment) submitted. - * @ORM\Entity - * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(columns={"assignment_id", "solver_id"})}) */ +#[ORM\Table] +#[ORM\UniqueConstraint(columns: ['assignment_id', 'solver_id'])] +#[ORM\Entity] class AssignmentSolver implements JsonSerializable { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; /** * Assignment being solved. - * @ORM\ManyToOne(targetEntity="Assignment") */ + #[ORM\ManyToOne(targetEntity: Assignment::class)] protected $assignment; /** * User (student) who is attempting to solve the assignment. - * @ORM\ManyToOne(targetEntity="User") */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $solver; /** * A sequence for given assignment and user that counts, how many times a user have submitted a solution. * The update of this value is tricky, since it is incremented with every new solution and the value is * used to mark the solution (i.e., solution creation and the increment must be in a transaction). - * @ORM\Column(type="integer") */ + #[ORM\Column(type: 'integer')] protected $lastAttemptIndex; /** * Counts how many times one of the solutions have been evaluated (including re-evaluations). * This counter is mainly for statistical purposes. - * @ORM\Column(type="integer") */ + #[ORM\Column(type: 'integer')] protected $evaluationsCount; /** diff --git a/app/model/entity/AsyncJob.php b/app/model/entity/AsyncJob.php index 2f0fa2718..78104e7d8 100644 --- a/app/model/entity/AsyncJob.php +++ b/app/model/entity/AsyncJob.php @@ -8,24 +8,21 @@ use LogicException; use JsonSerializable; -/** - * @ORM\Entity - * @ORM\Table(indexes={ - * @ORM\Index(name="created_at_idx", columns={"created_at"}), - * @ORM\Index(name="scheduled_at_idx", columns={"scheduled_at"}), - * @ORM\Index(name="started_at_idx", columns={"started_at"}), - * @ORM\Index(name="finished_at_idx", columns={"finished_at"}) - * }) - */ +#[ORM\Table] +#[ORM\Index(name: 'created_at_idx', columns: ['created_at'])] +#[ORM\Index(name: 'scheduled_at_idx', columns: ['scheduled_at'])] +#[ORM\Index(name: 'started_at_idx', columns: ['started_at'])] +#[ORM\Index(name: 'finished_at_idx', columns: ['finished_at'])] +#[ORM\Entity] class AsyncJob implements JsonSerializable { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; public function getId(): ?string @@ -34,9 +31,9 @@ public function getId(): ?string } /** - * @ORM\ManyToOne(targetEntity="User") * @var User|null */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $createdBy; public function getCreatedBy(): ?User @@ -45,9 +42,9 @@ public function getCreatedBy(): ?User } /** - * @ORM\Column(type="datetime") * @var DateTime */ + #[ORM\Column(type: 'datetime')] protected $createdAt; public function getCreatedAt(): DateTime @@ -56,10 +53,10 @@ public function getCreatedAt(): DateTime } /** - * @ORM\Column(type="datetime", nullable=true) * @var DateTime|null * Time when the async task should be executed. If null, the task is executed as soon as possible. */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $scheduledAt = null; public function getScheduledAt(): ?DateTime @@ -80,9 +77,9 @@ public function setScheduledAt(DateTime $scheduledAt) } /** - * @ORM\Column(type="datetime", nullable=true) * @var DateTime|null */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $startedAt = null; public function getStartedAt(): ?DateTime @@ -91,10 +88,10 @@ public function getStartedAt(): ?DateTime } /** - * @ORM\Column(type="datetime", nullable=true) * @var DateTime|null * This is the time when the task was either processed, killed, or deferred as unsolvable. */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $finishedAt = null; public function getFinishedAt(): ?DateTime @@ -108,11 +105,11 @@ public function setFinishedNow() } /** - * @ORM\Column(type="integer") * @var int * Every time the task is taken for execution, this number is incremented. * A threshold of max. retries may be applied to avoid infinite re-execution of broken tasks. */ + #[ORM\Column(type: 'integer')] protected $retries = 0; public function getRetries(): int @@ -121,10 +118,10 @@ public function getRetries(): int } /** - * @ORM\Column(type="string", nullable=true) * @var string * ID of a worker who took this task. Once a task is assigned to a worker, it may not be relocated to another one. */ + #[ORM\Column(type: 'string', nullable: true)] protected $workerId = null; public function getWorkerId(): ?string @@ -157,9 +154,9 @@ public function allocateForWorker(string $workerId) } /** - * @ORM\Column(type="string") * @var string */ + #[ORM\Column(type: 'string')] protected $command; public function getCommand(): string @@ -168,10 +165,10 @@ public function getCommand(): string } /** - * @ORM\Column(type="string") * @var string * Arguments of command encoded in json. */ + #[ORM\Column(type: 'string')] protected $arguments = ''; /** @@ -195,10 +192,10 @@ public function setCommand(string $command, array $arguments = []) } /** - * @ORM\Column(type="string", nullable=true) * @var string|null * Last error message registered with this task. */ + #[ORM\Column(type: 'string', nullable: true)] protected $error = null; public function getError(): ?string @@ -234,9 +231,9 @@ public function appendError(string $error) } /** - * @ORM\ManyToOne(targetEntity="Assignment", cascade={"persist"}) * @var Assignment|null */ + #[ORM\ManyToOne(targetEntity: Assignment::class, cascade: ['persist'])] protected $associatedAssignment = null; public function getAssociatedAssignment(): ?Assignment diff --git a/app/model/entity/AttachmentFile.php b/app/model/entity/AttachmentFile.php index 69f33e7b6..1a86b6730 100644 --- a/app/model/entity/AttachmentFile.php +++ b/app/model/entity/AttachmentFile.php @@ -10,14 +10,10 @@ use JsonSerializable; use DateTime; -/** - * @ORM\Entity - */ +#[ORM\Entity] class AttachmentFile extends UploadedFile implements JsonSerializable { - /** - * @ORM\ManyToMany(targetEntity="Exercise", mappedBy="attachmentFiles") - */ + #[ORM\ManyToMany(targetEntity: Exercise::class, mappedBy: 'attachmentFiles')] protected $exercises; /** @@ -40,9 +36,7 @@ public function getExercisesAndIReallyMeanAllOkay() return $this->exercises; } - /** - * @ORM\ManyToMany(targetEntity="Assignment", mappedBy="attachmentFiles") - */ + #[ORM\ManyToMany(targetEntity: Assignment::class, mappedBy: 'attachmentFiles')] protected $assignments; /** diff --git a/app/model/entity/BooleanPipelineParameter.php b/app/model/entity/BooleanPipelineParameter.php index d2b3f50d6..6f3b3d089 100644 --- a/app/model/entity/BooleanPipelineParameter.php +++ b/app/model/entity/BooleanPipelineParameter.php @@ -5,14 +5,10 @@ use App\Exceptions\InvalidApiArgumentException; use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\Entity - */ +#[ORM\Entity] class BooleanPipelineParameter extends PipelineParameter { - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $booleanValue; public function getValue() diff --git a/app/model/entity/Comment.php b/app/model/entity/Comment.php index 4289dd6fc..7edf84ae4 100644 --- a/app/model/entity/Comment.php +++ b/app/model/entity/Comment.php @@ -6,30 +6,28 @@ use Doctrine\ORM\Mapping as ORM; use JsonSerializable; -/** - * @ORM\Entity - */ +#[ORM\Entity] class Comment implements JsonSerializable { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; /** * @var CommentThread - * @ORM\ManyToOne(targetEntity="CommentThread", inversedBy="comments") */ + #[ORM\ManyToOne(targetEntity: CommentThread::class, inversedBy: 'comments')] protected $commentThread; /** * @var User - * @ORM\ManyToOne(targetEntity="User") */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $user; public function getUser(): ?User @@ -37,9 +35,7 @@ public function getUser(): ?User return $this->user->isDeleted() ? null : $this->user; } - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $isPrivate; /** @@ -65,14 +61,10 @@ public function getThread() return $this->commentThread; } - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $postedAt; - /** - * @ORM\Column(type="text", length=65535) - */ + #[ORM\Column(type: 'text', length: 65535)] protected $text; public function jsonSerialize(): mixed diff --git a/app/model/entity/CommentThread.php b/app/model/entity/CommentThread.php index e0438cadd..8c8ce9843 100644 --- a/app/model/entity/CommentThread.php +++ b/app/model/entity/CommentThread.php @@ -8,21 +8,15 @@ use Doctrine\Common\Collections\Criteria; use JsonSerializable; -/** - * @ORM\Entity - */ +#[ORM\Entity] class CommentThread implements JsonSerializable { - /** - * @ORM\Id - * @ORM\Column(type="string", length=36, options={"fixed":true}) - */ + #[ORM\Id] + #[ORM\Column(type: 'string', length: 36, options: ['fixed' => true])] protected $id; - /** - * @ORM\OneToMany(targetEntity="Comment", mappedBy="commentThread") - * @ORM\OrderBy({ "postedAt" = "ASC" }) - */ + #[ORM\OneToMany(targetEntity: Comment::class, mappedBy: 'commentThread')] + #[ORM\OrderBy(['postedAt' => 'ASC'])] protected $comments; public function addComment(Comment $comment) diff --git a/app/model/entity/Exercise.php b/app/model/entity/Exercise.php index 0e50c6b09..f59ee49ab 100644 --- a/app/model/entity/Exercise.php +++ b/app/model/entity/Exercise.php @@ -12,10 +12,8 @@ use Gedmo\Mapping\Annotation as Gedmo; use App\Helpers\ExercisesConfig; -/** - * @ORM\Entity - * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false) - */ +#[ORM\Entity] +#[Gedmo\SoftDeleteable(fieldName: 'deletedAt', timeAware: false)] class Exercise implements IExercise { use ExerciseData; @@ -25,97 +23,77 @@ class Exercise implements IExercise use VersionableEntity; /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $difficulty; - /** - * @ORM\ManyToMany(targetEntity="RuntimeEnvironment") - */ + #[ORM\ManyToMany(targetEntity: RuntimeEnvironment::class)] protected $runtimeEnvironments; - /** - * @ORM\ManyToOne(targetEntity="Exercise") - * @ORM\JoinColumn(name="exercise_id", referencedColumnName="id") - */ + #[ORM\JoinColumn(name: 'exercise_id', referencedColumnName: 'id')] + #[ORM\ManyToOne(targetEntity: Exercise::class)] protected $exercise; - /** - * @ORM\OneToMany(targetEntity="ReferenceExerciseSolution", mappedBy="exercise") - */ + #[ORM\OneToMany(targetEntity: ReferenceExerciseSolution::class, mappedBy: 'exercise')] protected $referenceSolutions; - /** - * @ORM\ManyToOne(targetEntity="User", inversedBy="exercises") - */ + #[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'exercises')] protected $author; - /** - * @ORM\ManyToMany(targetEntity="User") - */ + #[ORM\ManyToMany(targetEntity: User::class)] protected $admins; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $isPublic; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $isLocked; - /** - * @ORM\Column(type="boolean", options={"default":0}) - */ + #[ORM\Column(type: 'boolean', options: ['default' => 0])] protected $isBroken = false; - /** - * @ORM\Column(type="text", length=65535) - */ + #[ORM\Column(type: 'text', length: 65535)] protected $validationError; - /** - * @ORM\ManyToMany(targetEntity="Group", inversedBy="exercises") - */ + #[ORM\ManyToMany(targetEntity: Group::class, inversedBy: 'exercises')] protected $groups; - /** - * @ORM\OneToMany(targetEntity="Assignment", mappedBy="exercise") - */ + #[ORM\OneToMany(targetEntity: Assignment::class, mappedBy: 'exercise')] protected $assignments; /** * @var Collection - * @ORM\OneToMany(targetEntity="ExerciseTag", mappedBy="exercise", - * cascade={"persist", "remove"}, orphanRemoval=true) */ + #[ORM\OneToMany( + targetEntity: ExerciseTag::class, + mappedBy: 'exercise', + cascade: ['persist', 'remove'], + orphanRemoval: true + )] protected $tags; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $mergeJudgeLogs; - /** - * @ORM\Column(type="datetime", nullable=true) - */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $archivedAt = null; /** - * @ORM\OneToMany(targetEntity="ExerciseFileLink", mappedBy="exercise", cascade={"persist", "remove"}, - * orphanRemoval=true) * @var Collection */ + #[ORM\OneToMany( + targetEntity: ExerciseFileLink::class, + mappedBy: 'exercise', + cascade: ['persist', 'remove'], + orphanRemoval: true + )] protected $fileLinks; /** diff --git a/app/model/entity/ExerciseConfig.php b/app/model/entity/ExerciseConfig.php index 6273d209d..09f0f12b8 100644 --- a/app/model/entity/ExerciseConfig.php +++ b/app/model/entity/ExerciseConfig.php @@ -8,39 +8,29 @@ use App\Helpers\Yaml; use DateTime; -/** - * @ORM\Entity - */ +#[ORM\Entity] class ExerciseConfig { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="text") - */ + #[ORM\Column(type: 'text')] protected $config; - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $createdAt; - /** - * @ORM\ManyToOne(targetEntity="ExerciseConfig") - * @ORM\JoinColumn(onDelete="SET NULL") - */ + #[ORM\JoinColumn(onDelete: 'SET NULL')] + #[ORM\ManyToOne(targetEntity: ExerciseConfig::class)] protected $createdFrom; - /** - * @ORM\ManyToOne(targetEntity="User") - */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $author; public function getAuthor(): ?User diff --git a/app/model/entity/ExerciseEnvironmentConfig.php b/app/model/entity/ExerciseEnvironmentConfig.php index 0b0bb2838..384e739fa 100644 --- a/app/model/entity/ExerciseEnvironmentConfig.php +++ b/app/model/entity/ExerciseEnvironmentConfig.php @@ -8,46 +8,36 @@ use App\Helpers\YamlException; use App\Helpers\Yaml; -/** - * @ORM\Entity - */ +#[ORM\Entity] class ExerciseEnvironmentConfig { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\ManyToOne(targetEntity="RuntimeEnvironment") - */ + #[ORM\ManyToOne(targetEntity: RuntimeEnvironment::class)] protected $runtimeEnvironment; - /** - * @ORM\Column(type="text", length=65535) - */ + #[ORM\Column(type: 'text', length: 65535)] protected $variablesTable; - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $createdAt; /** * Created from. - * @ORM\ManyToOne(targetEntity="ExerciseEnvironmentConfig") - * @ORM\JoinColumn(onDelete="SET NULL") * @var ExerciseEnvironmentConfig */ + #[ORM\JoinColumn(onDelete: 'SET NULL')] + #[ORM\ManyToOne(targetEntity: ExerciseEnvironmentConfig::class)] protected $createdFrom; - /** - * @ORM\ManyToOne(targetEntity="User") - */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $author; public function getAuthor(): ?User diff --git a/app/model/entity/ExerciseFile.php b/app/model/entity/ExerciseFile.php index 4c998e0ff..381e5ee3e 100644 --- a/app/model/entity/ExerciseFile.php +++ b/app/model/entity/ExerciseFile.php @@ -10,21 +10,19 @@ use JsonSerializable; use DateTime; -/** - * @ORM\Entity - */ +#[ORM\Entity] class ExerciseFile extends UploadedFile implements JsonSerializable { /** * Identifier used to store/retrieve the file in/from the storage. - * @ORM\Column(type="string") */ + #[ORM\Column(type: 'string')] protected $hashName; /** - * @ORM\ManyToMany(targetEntity="Exercise", mappedBy="exerciseFiles") * @var Collection */ + #[ORM\ManyToMany(targetEntity: Exercise::class, mappedBy: 'exerciseFiles')] protected $exercises; /** @@ -40,9 +38,9 @@ function (Exercise $exercise) { } /** - * @ORM\ManyToMany(targetEntity="Assignment", mappedBy="exerciseFiles") * @var Collection */ + #[ORM\ManyToMany(targetEntity: Assignment::class, mappedBy: 'exerciseFiles')] protected $assignments; /** @@ -58,9 +56,9 @@ function (Assignment $assignment) { } /** - * @ORM\ManyToMany(targetEntity="Pipeline", mappedBy="exerciseFiles") * @var Collection */ + #[ORM\ManyToMany(targetEntity: Pipeline::class, mappedBy: 'exerciseFiles')] protected $pipelines; /** diff --git a/app/model/entity/ExerciseFileLink.php b/app/model/entity/ExerciseFileLink.php index 2319c3367..eb056c12b 100644 --- a/app/model/entity/ExerciseFileLink.php +++ b/app/model/entity/ExerciseFileLink.php @@ -12,60 +12,55 @@ * exercise-assignment records. However, links are small, so they are copied eagerly (not by CoW). * I.e., when Assignment is created from Exercise, the links are copied (immediately) as well. * The link of an exercise may be updated, but the link of an assignment is immutable. - * @ORM\Entity - * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(columns={"key", "exercise_id"})}) * * Note: technically, there should be also unique constraint on (key, assignment_id); however, it causes more problems * than it solves. During sync operation, the assignment-related links are cleared and re-filled. Since the Doctrine * performs inserts before deletes, and we do not want to flush in the middle, it causes unique constraint violation. */ +#[ORM\Table] +#[ORM\UniqueConstraint(columns: ['key', 'exercise_id'])] +#[ORM\Entity] class ExerciseFileLink implements JsonSerializable { use CreatableEntity; /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; /** * The key (fixed ID) used to identify the file in exercise specification (for simple replacement). - * @ORM\Column(name="`key`", type="string", length=16) */ + #[ORM\Column(name: '`key`', type: 'string', length: 16)] protected $key; /** * New name under which the file is downloaded (null means the original name). - * @ORM\Column(type="string", nullable=true) */ + #[ORM\Column(type: 'string', nullable: true)] protected $saveName; /** * Minimal required user role to access the file (null means even non-logged-in users). - * @ORM\Column(type="string", nullable=true) */ + #[ORM\Column(type: 'string', nullable: true)] protected $requiredRole; - /** - * @ORM\ManyToOne(targetEntity="ExerciseFile") - * @ORM\JoinColumn(onDelete="CASCADE") - */ + #[ORM\JoinColumn(onDelete: 'CASCADE')] + #[ORM\ManyToOne(targetEntity: ExerciseFile::class)] protected $exerciseFile; - /** - * @ORM\ManyToOne(targetEntity="Exercise", inversedBy="fileLinks") - * @ORM\JoinColumn(onDelete="CASCADE") - */ + #[ORM\JoinColumn(onDelete: 'CASCADE')] + #[ORM\ManyToOne(targetEntity: Exercise::class, inversedBy: 'fileLinks')] protected $exercise; - /** - * @ORM\ManyToOne(targetEntity="Assignment", inversedBy="exerciseFileLinks") - * @ORM\JoinColumn(onDelete="CASCADE") - */ + #[ORM\JoinColumn(onDelete: 'CASCADE')] + #[ORM\ManyToOne(targetEntity: Assignment::class, inversedBy: 'exerciseFileLinks')] protected $assignment; /** diff --git a/app/model/entity/ExerciseLimits.php b/app/model/entity/ExerciseLimits.php index 3c3c253d6..fe9c8e289 100644 --- a/app/model/entity/ExerciseLimits.php +++ b/app/model/entity/ExerciseLimits.php @@ -9,39 +9,29 @@ use App\Helpers\Yaml; use DateTime; -/** - * @ORM\Entity - */ +#[ORM\Entity] class ExerciseLimits implements JsonSerializable { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="text") - */ + #[ORM\Column(type: 'text')] protected $limits; - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $createdAt; - /** - * @ORM\ManyToOne(targetEntity="ExerciseLimits") - * @ORM\JoinColumn(onDelete="SET NULL") - */ + #[ORM\JoinColumn(onDelete: 'SET NULL')] + #[ORM\ManyToOne(targetEntity: ExerciseLimits::class)] protected $createdFrom; - /** - * @ORM\ManyToOne(targetEntity="User") - */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $author; public function getAuthor(): ?User @@ -49,14 +39,10 @@ public function getAuthor(): ?User return $this->author->isDeleted() ? null : $this->author; } - /** - * @ORM\ManyToOne(targetEntity="RuntimeEnvironment") - */ + #[ORM\ManyToOne(targetEntity: RuntimeEnvironment::class)] protected $runtimeEnvironment; - /** - * @ORM\ManyToOne(targetEntity="HardwareGroup") - */ + #[ORM\ManyToOne(targetEntity: HardwareGroup::class)] protected $hardwareGroup; /** diff --git a/app/model/entity/ExerciseScoreConfig.php b/app/model/entity/ExerciseScoreConfig.php index d11a438e4..6e45db96a 100644 --- a/app/model/entity/ExerciseScoreConfig.php +++ b/app/model/entity/ExerciseScoreConfig.php @@ -8,20 +8,18 @@ use DateTime; use JsonSerializable; -/** - * @ORM\Entity - */ +#[ORM\Entity] class ExerciseScoreConfig implements JsonSerializable { use CreatableEntity; /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; /** @@ -33,9 +31,9 @@ public function getId(): ?string } /** - * @ORM\Column(type="string") * Identifier of the calculator */ + #[ORM\Column(type: 'string')] protected $calculator; public function getCalculator(): string @@ -44,9 +42,9 @@ public function getCalculator(): string } /** - * @ORM\Column(type="text", nullable=true) * Calculator configuration data. */ + #[ORM\Column(type: 'text', nullable: true)] protected $config; public function getConfig(): ?string @@ -73,10 +71,8 @@ public function configEquals($config): bool return $serialized === $this->config; } - /** - * @ORM\ManyToOne(targetEntity="ExerciseScoreConfig") - * @ORM\JoinColumn(onDelete="SET NULL") - */ + #[ORM\JoinColumn(onDelete: 'SET NULL')] + #[ORM\ManyToOne(targetEntity: ExerciseScoreConfig::class)] protected $createdFrom; /** diff --git a/app/model/entity/ExerciseTag.php b/app/model/entity/ExerciseTag.php index 1e1701d78..9ae19ee22 100644 --- a/app/model/entity/ExerciseTag.php +++ b/app/model/entity/ExerciseTag.php @@ -4,29 +4,22 @@ use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\Entity - * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(columns={"name", "exercise_id"})}) - */ +#[ORM\Table] +#[ORM\UniqueConstraint(columns: ['name', 'exercise_id'])] +#[ORM\Entity] class ExerciseTag { use CreatableEntity; - /** - * @ORM\Id - * @ORM\Column(type="integer") - * @ORM\GeneratedValue(strategy="AUTO") - */ + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue(strategy: 'AUTO')] protected $id; - /** - * @ORM\Column(type="string", length=32) - */ + #[ORM\Column(type: 'string', length: 32)] protected $name; - /** - * @ORM\ManyToOne(targetEntity="User") - */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $author; public function getAuthor(): ?User @@ -34,9 +27,7 @@ public function getAuthor(): ?User return $this->author->isDeleted() ? null : $this->author; } - /** - * @ORM\ManyToOne(targetEntity="Exercise") - */ + #[ORM\ManyToOne(targetEntity: Exercise::class)] protected $exercise; public function getExercise(): ?Exercise diff --git a/app/model/entity/ExerciseTest.php b/app/model/entity/ExerciseTest.php index 0bd6e91fd..04223c8f4 100644 --- a/app/model/entity/ExerciseTest.php +++ b/app/model/entity/ExerciseTest.php @@ -2,39 +2,28 @@ namespace App\Model\Entity; -use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; use DateTime; use JsonSerializable; -/** - * @ORM\Entity - */ +#[ORM\Entity] class ExerciseTest implements JsonSerializable { use CreatableEntity; use UpdatableEntity; - /** - * @ORM\Id - * @ORM\Column(type="integer") - * @ORM\GeneratedValue(strategy="AUTO") - */ + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue(strategy: 'AUTO')] protected $id; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $name; - /** - * @ORM\Column(type="text") - */ + #[ORM\Column(type: 'text')] protected $description; - /** - * @ORM\ManyToOne(targetEntity="User") - */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $author; public function getAuthor(): ?User diff --git a/app/model/entity/ExternalLogin.php b/app/model/entity/ExternalLogin.php index 4d6de1441..de7a4aae2 100644 --- a/app/model/entity/ExternalLogin.php +++ b/app/model/entity/ExternalLogin.php @@ -4,35 +4,28 @@ use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\Entity - * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(columns={"auth_service", "user_id"}), - * @ORM\UniqueConstraint(columns={"auth_service", "external_id"})}) - */ +#[ORM\Table] +#[ORM\UniqueConstraint(columns: ['auth_service', 'user_id'])] +#[ORM\UniqueConstraint(columns: ['auth_service', 'external_id'])] +#[ORM\Entity] class ExternalLogin { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="string", length=32) - */ + #[ORM\Column(type: 'string', length: 32)] protected $authService; - /** - * @ORM\Column(type="string", length=128) - */ + #[ORM\Column(type: 'string', length: 128)] protected $externalId; - /** - * @ORM\ManyToOne(targetEntity="User", inversedBy="externalLogins") - */ + #[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'externalLogins')] protected $user; public function __construct(User $user, string $authService, string $externalId) diff --git a/app/model/entity/ForgottenPassword.php b/app/model/entity/ForgottenPassword.php index 8eff35366..070c5e4f5 100644 --- a/app/model/entity/ForgottenPassword.php +++ b/app/model/entity/ForgottenPassword.php @@ -5,9 +5,7 @@ use DateTime; use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\Entity - */ +#[ORM\Entity] class ForgottenPassword { public function __construct( @@ -22,17 +20,15 @@ public function __construct( } /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\ManyToOne(targetEntity="User") - */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $user; public function getUser(): ?User @@ -40,19 +36,13 @@ public function getUser(): ?User return $this->user->isDeleted() ? null : $this->user; } - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $requestedAt; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $sentTo; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $IPaddress; /* diff --git a/app/model/entity/Group.php b/app/model/entity/Group.php index 32174be5c..47a9667b2 100644 --- a/app/model/entity/Group.php +++ b/app/model/entity/Group.php @@ -14,15 +14,15 @@ use DateTime; /** - * @ORM\Entity - * @ORM\Table(name="`group`") - * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false) * Regular groups have students and offer them assignments. There are two special group types: * - organizational (cannot have students nor assignments, but may have sub-groups) - * indicated by isOrganizational column (flag) + * indicated by isOrganizational column (flag) * - exam (activity in this group is restricted to very short period in time when an exam is scheduled) - * indicated by non-null values of examBegin and examEnd columns + * indicated by non-null values of examBegin and examEnd columns */ +#[ORM\Table(name: '`group`')] +#[ORM\Entity] +#[Gedmo\SoftDeleteable(fieldName: 'deletedAt', timeAware: false)] class Group { use DeletableEntity; @@ -78,44 +78,36 @@ public function __construct( } /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; /** - * @ORM\Column(type="string", nullable=true) * DEPRECATED in favor of external attributes */ + #[ORM\Column(type: 'string', nullable: true)] protected $externalId; /** - * @ORM\OneToMany(targetEntity="LocalizedGroup", mappedBy="group") * @var ArrayCollection */ + #[ORM\OneToMany(targetEntity: LocalizedGroup::class, mappedBy: 'group')] protected $localizedTexts; - /** - * @ORM\Column(type="float", nullable=true) - */ + #[ORM\Column(type: 'float', nullable: true)] protected $threshold; - /** - * @ORM\Column(type="integer", nullable=true) - */ + #[ORM\Column(type: 'integer', nullable: true)] protected $pointsLimit; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $publicStats; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $isPublic; public function isPublic(): bool @@ -133,16 +125,14 @@ public function statsArePublic(): bool return $this->publicStats; } - /** - * @ORM\Column(type="datetime", nullable=true) - */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $archivedAt = null; /** * Flag that helps determine whether a group has been archived explicitly. * That affects the modifications (moving and excavating group to/from archive). - * @ORM\Column(type="boolean") */ + #[ORM\Column(type: 'boolean')] protected $directlyArchived = false; /** @@ -209,55 +199,57 @@ public function isDirectlyArchived(): bool return $this->directlyArchived; } - /** - * @ORM\Column(type="boolean", options={"default":0}) - */ + #[ORM\Column(type: 'boolean', options: ['default' => 0])] protected $isOrganizational = false; /** - * @ORM\Column(type="boolean", options={"default":0}) * Students cannot leave detaining groups on their own (supervisor can remove them). */ + #[ORM\Column(type: 'boolean', options: ['default' => 0])] protected $isDetaining = false; /** - * @ORM\Column(type="boolean", options={"default":0}) * The group is dedicated to examination. This is used mainly for selective visualization * and to make the "exam" flag of the assignments set as default. * This flag is independent of the exam begin-end dates which are used for security purposes. */ + #[ORM\Column(type: 'boolean', options: ['default' => 0])] protected $isExam = false; /** - * @ORM\Column(type="datetime", nullable=true) * When an exam in this groups begins. In the exam period, a user must lock in a group to be allowed * submitting solutions. This is completely independent of the isExam flag. * @var DateTime|null */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $examBegin = null; /** - * @ORM\Column(type="datetime", nullable=true) * When an exam in this groups ends. In the exam period, a user must lock in a group to be allowed * submitting solutions. This is completely independent of the isExam flag. * @var DateTime|null */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $examEnd = null; /** - * @ORM\Column(type="string") * The type of lock for the exam. * (under strict lock, the user cannot read data from other groups). * @var string */ + #[ORM\Column(type: 'string')] protected $examLockType = GroupExamLockType::Visible->value; /** * @var Collection - * @ORM\OneToMany(targetEntity="GroupExam", mappedBy="group", - * cascade={"persist", "remove"}, orphanRemoval=true) - * @ORM\OrderBy({"begin" = "DESC"}) */ + #[ORM\OneToMany( + targetEntity: GroupExam::class, + mappedBy: 'group', + cascade: ['persist', 'remove'], + orphanRemoval: true + )] + #[ORM\OrderBy(['begin' => 'DESC'])] protected $exams; /** @@ -310,18 +302,19 @@ public function getExamLockType(): GroupExamLockType /** * @var Collection - * @ORM\OneToMany(targetEntity="GroupExternalAttribute", mappedBy="group", cascade={"all"}, orphanRemoval=true) */ + #[ORM\OneToMany( + targetEntity: GroupExternalAttribute::class, + mappedBy: 'group', + cascade: ['all'], + orphanRemoval: true + )] protected $externalAttributes; - /** - * @ORM\ManyToOne(targetEntity="Group", inversedBy="childGroups") - */ + #[ORM\ManyToOne(targetEntity: Group::class, inversedBy: 'childGroups')] protected $parentGroup; - /** - * @ORM\OneToMany(targetEntity="Group", mappedBy="parentGroup") - */ + #[ORM\OneToMany(targetEntity: Group::class, mappedBy: 'parentGroup')] protected $childGroups; /** @@ -340,15 +333,17 @@ function (Group $group) { /** * @var Collection - * @ORM\OneToMany(targetEntity="GroupInvitation", mappedBy="group", - * cascade={"persist", "remove"}, orphanRemoval=true) - * @ORM\OrderBy({"createdAt" = "DESC"}) */ + #[ORM\OneToMany( + targetEntity: GroupInvitation::class, + mappedBy: 'group', + cascade: ['persist', 'remove'], + orphanRemoval: true + )] + #[ORM\OrderBy(['createdAt' => 'DESC'])] protected $invitations; - /** - * @ORM\ManyToMany(targetEntity="Exercise", mappedBy="groups") - */ + #[ORM\ManyToMany(targetEntity: Exercise::class, mappedBy: 'groups')] protected $exercises; public function getExercises() @@ -360,9 +355,7 @@ function (Exercise $exercise) { ); } - /** - * @ORM\ManyToOne(targetEntity="Instance", inversedBy="groups") - */ + #[ORM\ManyToOne(targetEntity: Instance::class, inversedBy: 'groups')] protected $instance; public function getInstance(): ?Instance @@ -376,9 +369,7 @@ public function hasValidLicense() return $instance && $instance->hasValidLicense(); } - /** - * @ORM\OneToMany(targetEntity="GroupMembership", mappedBy="group", cascade={"all"}) - */ + #[ORM\OneToMany(targetEntity: GroupMembership::class, mappedBy: 'group', cascade: ['all'])] protected $memberships; /** @@ -721,9 +712,7 @@ public function isNonStudentMemberOfSubgroup(User $user): bool return false; } - /** - * @ORM\OneToMany(targetEntity="Assignment", mappedBy="group") - */ + #[ORM\OneToMany(targetEntity: Assignment::class, mappedBy: 'group')] protected $assignments; /** @@ -753,9 +742,7 @@ function (Assignment $assignment) { ); } - /** - * @ORM\OneToMany(targetEntity="ShadowAssignment", mappedBy="group") - */ + #[ORM\OneToMany(targetEntity: ShadowAssignment::class, mappedBy: 'group')] protected $shadowAssignments; /** diff --git a/app/model/entity/GroupExam.php b/app/model/entity/GroupExam.php index bd084e11a..c9e43b5ce 100644 --- a/app/model/entity/GroupExam.php +++ b/app/model/entity/GroupExam.php @@ -8,46 +8,47 @@ use JsonSerializable; /** - * @ORM\Entity - * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(columns={"group_id", "begin"})}) * Holds history record of an exam that took place in a group. * The `examBegin`, `examEnd` fields are copied from group to `begin`, `end` fields here, * `examLockType` is copied to `lockType` field. * This entity is created when the first user locks in (i.e., only exams with users are recorded in history). */ +#[ORM\Table] +#[ORM\UniqueConstraint(columns: ['group_id', 'begin'])] +#[ORM\Entity] class GroupExam implements JsonSerializable { /** - * @ORM\Id - * @ORM\Column(type="integer") - * @ORM\GeneratedValue(strategy="AUTO") * @var int|null */ + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue(strategy: 'AUTO')] protected $id; /** - * @ORM\ManyToOne(targetEntity="Group", inversedBy="exams") * @var Group */ + #[ORM\ManyToOne(targetEntity: Group::class, inversedBy: 'exams')] protected $group; /** - * @ORM\Column(type="datetime") * @var DateTime|null */ + #[ORM\Column(type: 'datetime')] protected $begin = null; /** - * @ORM\Column(type="datetime") * @var DateTime|null */ + #[ORM\Column(type: 'datetime')] protected $end = null; /** - * @ORM\Column(type="string") * Saved value from examLockType flag. * @var string */ + #[ORM\Column(type: 'string')] protected $lockType = GroupExamLockType::Visible->value; /** diff --git a/app/model/entity/GroupExamLock.php b/app/model/entity/GroupExamLock.php index 83c5ed954..793dfff30 100644 --- a/app/model/entity/GroupExamLock.php +++ b/app/model/entity/GroupExamLock.php @@ -7,43 +7,38 @@ use JsonSerializable; /** - * @ORM\Entity - * @ORM\Table(indexes={@ORM\Index(name="lock_created_at_idx", columns={"created_at"})}) * Logs locking events for a particular exam. Every time student acquires group-lock, this entity is created. * If the user is explicitly unlocked, the time of that event is also recorded. */ +#[ORM\Table] +#[ORM\Index(name: 'lock_created_at_idx', columns: ['created_at'])] +#[ORM\Entity] class GroupExamLock implements JsonSerializable { use CreatableEntity; - /** - * @ORM\Id - * @ORM\Column(type="integer") - * @ORM\GeneratedValue(strategy="AUTO") - */ + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue(strategy: 'AUTO')] protected $id; - /** - * @ORM\ManyToOne(targetEntity="GroupExam") - */ + #[ORM\ManyToOne(targetEntity: GroupExam::class)] protected $groupExam; - /** - * @ORM\ManyToOne(targetEntity="User") - */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $student; /** - * @ORM\Column(type="string") * remote IP address from which the user requested locking */ + #[ORM\Column(type: 'string')] protected $remoteAddr; /** - * @ORM\Column(type="datetime", nullable=true) * @var DateTime|null * If the student is explicitly unlocked, the time is recorded. */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $unlockedAt = null; /** diff --git a/app/model/entity/GroupExternalAttribute.php b/app/model/entity/GroupExternalAttribute.php index ac2c52725..b7ad0a869 100644 --- a/app/model/entity/GroupExternalAttribute.php +++ b/app/model/entity/GroupExternalAttribute.php @@ -6,46 +6,42 @@ use JsonSerializable; /** - * @ORM\Entity - * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(columns={"group_id", "service", "key", "value"})}, - * indexes={@ORM\Index(name="keys_idx", columns={"service", "key"})}) - * * Key-value attributes assigned to groups to connect them to 3rd party systems to simplify * external group management (creation, archiving) and student membership management. */ +#[ORM\Table] +#[ORM\Index(name: 'keys_idx', columns: ['service', 'key'])] +#[ORM\UniqueConstraint(columns: ['group_id', 'service', 'key', 'value'])] +#[ORM\Entity] class GroupExternalAttribute implements JsonSerializable { use CreatableEntity; /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\ManyToOne(targetEntity="Group", inversedBy="externalAttributes") - */ + #[ORM\ManyToOne(targetEntity: Group::class, inversedBy: 'externalAttributes')] protected $group; /** - * @ORM\Column(type="string", length=32) * Identifies 3rd party service which assigned the attribute. This is basically a namespace for keys. */ + #[ORM\Column(type: 'string', length: 32)] protected $service; /** - * @ORM\Column(name="`key`", type="string", length=32) * Key of the attribute under which it can be searched. */ + #[ORM\Column(name: '`key`', type: 'string', length: 32)] protected $key; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $value; /** diff --git a/app/model/entity/GroupInvitation.php b/app/model/entity/GroupInvitation.php index 3058ffa3f..4cd0b999a 100644 --- a/app/model/entity/GroupInvitation.php +++ b/app/model/entity/GroupInvitation.php @@ -6,44 +6,41 @@ use DateTime; use JsonSerializable; -/** - * @ORM\Entity - * @ORM\Table(indexes={@ORM\Index(name="grouped_created_at_idx", columns={"group_id", "created_at"})}) - */ +#[ORM\Table] +#[ORM\Index(name: 'grouped_created_at_idx', columns: ['group_id', 'created_at'])] +#[ORM\Entity] class GroupInvitation implements JsonSerializable { use CreatableEntity; /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; /** - * @ORM\Column(type="datetime", nullable=true) * @var DateTime */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $expireAt = null; - /** - * @ORM\ManyToOne(targetEntity="Group", inversedBy="invitations") - */ + #[ORM\ManyToOne(targetEntity: Group::class, inversedBy: 'invitations')] protected $group; /** - * @ORM\ManyToOne(targetEntity="User") * who created the invitation */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $host; /** - * @ORM\Column(type="string") * short remark for those who are about to use the link */ + #[ORM\Column(type: 'string')] protected $note; /** diff --git a/app/model/entity/GroupMembership.php b/app/model/entity/GroupMembership.php index 2f9d5a595..eb9b26de8 100644 --- a/app/model/entity/GroupMembership.php +++ b/app/model/entity/GroupMembership.php @@ -7,10 +7,9 @@ use JsonSerializable; use DateTime; -/** - * @ORM\Entity - * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(columns={"user_id", "group_id", "inherited_from_id"})}) - */ +#[ORM\Table] +#[ORM\UniqueConstraint(columns: ['user_id', 'group_id', 'inherited_from_id'])] +#[ORM\Entity] class GroupMembership implements JsonSerializable { public const TYPE_ADMIN = "admin"; @@ -44,42 +43,34 @@ public function __construct(Group $group, User $user, string $type, ?Group $inhe } /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\ManyToOne(targetEntity="User", inversedBy="memberships") - */ + #[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'memberships')] protected $user; - /** - * @ORM\ManyToOne(targetEntity="Group", inversedBy="memberships") - */ + #[ORM\ManyToOne(targetEntity: Group::class, inversedBy: 'memberships')] protected $group; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $type; - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $createdAt; /** - * @ORM\ManyToOne(targetEntity="Group") * When not null, it indicates the membership was inherited from ancestral group (id of which it holds). * Inheritance applies only for selected types of memberships (e.g., admin). * At present, explicit inherited memberships are used to capture inherited admin privileges * which are in place at the moment when a sub-groups are being placed to archive. * In the future, this technique may be used for performance optimizations as well. */ + #[ORM\ManyToOne(targetEntity: Group::class)] protected $inheritedFrom = null; public function setType(string $type) diff --git a/app/model/entity/HardwareGroup.php b/app/model/entity/HardwareGroup.php index 4b8b388bf..1ffdc98c5 100644 --- a/app/model/entity/HardwareGroup.php +++ b/app/model/entity/HardwareGroup.php @@ -6,30 +6,20 @@ use Doctrine\ORM\Mapping as ORM; use JsonSerializable; -/** - * @ORM\Entity - */ +#[ORM\Entity] class HardwareGroup implements JsonSerializable { - /** - * @ORM\Id - * @ORM\Column(type="string", length=32) - */ + #[ORM\Id] + #[ORM\Column(type: 'string', length: 32)] protected $id; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $name; - /** - * @ORM\Column(type="string", length=1024) - */ + #[ORM\Column(type: 'string', length: 1024)] protected $description; - /** - * @ORM\Column(type="text", length=65535) - */ + #[ORM\Column(type: 'text', length: 65535)] protected $metadata; diff --git a/app/model/entity/Instance.php b/app/model/entity/Instance.php index 6ac8834b6..9c2d791f2 100644 --- a/app/model/entity/Instance.php +++ b/app/model/entity/Instance.php @@ -8,10 +8,8 @@ use Doctrine\Common\Collections\ArrayCollection; use Gedmo\Mapping\Annotation as Gedmo; -/** - * @ORM\Entity - * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false) - */ +#[ORM\Entity] +#[Gedmo\SoftDeleteable(fieldName: 'deletedAt', timeAware: false)] class Instance { use UpdatableEntity; @@ -19,17 +17,15 @@ class Instance use CreatableEntity; /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $isOpen; /** @@ -40,14 +36,10 @@ public function isOpen(): bool return $this->isOpen; } - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $isAllowed; - /** - * @ORM\ManyToOne(targetEntity="User") - */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $admin; public function getAdmin(): ?User @@ -55,21 +47,19 @@ public function getAdmin(): ?User return $this->admin->isDeleted() ? null : $this->admin; } - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $needsLicence; /** - * @ORM\ManyToOne(targetEntity="Group", cascade={"persist"}) * @var Group */ + #[ORM\ManyToOne(targetEntity: Group::class, cascade: ['persist'])] protected $rootGroup; /** * @var ArrayCollection - * @ORM\OneToMany(targetEntity="Licence", mappedBy="instance") */ + #[ORM\OneToMany(targetEntity: Licence::class, mappedBy: 'instance')] protected $licences; public function addLicence(Licence $licence) @@ -91,9 +81,7 @@ public function hasValidLicense() return $this->needsLicence === false || $this->getValidLicences()->count() > 0; } - /** - * @ORM\ManyToMany(targetEntity="User", mappedBy="instances") - */ + #[ORM\ManyToMany(targetEntity: User::class, mappedBy: 'instances')] protected $members; public function addMember(User $user) @@ -101,9 +89,7 @@ public function addMember(User $user) $this->members->add($user); } - /** - * @ORM\OneToMany(targetEntity="Group", mappedBy="instance", cascade={"persist"}) - */ + #[ORM\OneToMany(targetEntity: Group::class, mappedBy: 'instance', cascade: ['persist'])] protected $groups; public function addGroup(Group $group) diff --git a/app/model/entity/Licence.php b/app/model/entity/Licence.php index 51f2a57b5..d6abbd8ba 100644 --- a/app/model/entity/Licence.php +++ b/app/model/entity/Licence.php @@ -4,27 +4,24 @@ use DateTime; use Doctrine\ORM\Mapping as ORM; -use Doctrine\Common\Collections\ArrayCollection; use JsonSerializable; -/** - * @ORM\Entity - */ +#[ORM\Entity] class Licence implements JsonSerializable { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; /** - * @ORM\ManyToOne(targetEntity="Instance", inversedBy="licences") * @var Instance */ + #[ORM\ManyToOne(targetEntity: Instance::class, inversedBy: 'licences')] protected $instance; public function getInstance(): ?Instance @@ -34,15 +31,15 @@ public function getInstance(): ?Instance /** * A licence can be manually marked as invalid by the admins. - * @ORM\Column(type="boolean") */ + #[ORM\Column(type: 'boolean')] protected $isValid; /** * The very last date on which this licence is valid (unless invalidated manually) - * @ORM\Column(type="datetime") * @var DateTime */ + #[ORM\Column(type: 'datetime')] protected $validUntil; /** @@ -60,8 +57,8 @@ public function isValid(?DateTime $when = null) /** * Internal note for the license. - * @ORM\Column(type="string") */ + #[ORM\Column(type: 'string')] protected $note; public function jsonSerialize(): mixed diff --git a/app/model/entity/LocalizedAssignment.php b/app/model/entity/LocalizedAssignment.php index 82ac6be82..1e9577151 100644 --- a/app/model/entity/LocalizedAssignment.php +++ b/app/model/entity/LocalizedAssignment.php @@ -6,23 +6,21 @@ use InvalidArgumentException; use JsonSerializable; -/** - * @ORM\Entity - */ +#[ORM\Entity] class LocalizedAssignment extends LocalizedEntity implements JsonSerializable { /** - * @ORM\ManyToOne(targetEntity="LocalizedAssignment") - * @ORM\JoinColumn(onDelete="SET NULL") * @var LocalizedAssignment */ + #[ORM\JoinColumn(onDelete: 'SET NULL')] + #[ORM\ManyToOne(targetEntity: LocalizedAssignment::class)] protected $createdFrom; /** * Separate text visible to students which is kept separately from the exercise specification, * so it will not be overwritten every time an assignment is synced with exercise. - * @ORM\Column(type="text") */ + #[ORM\Column(type: 'text')] protected $studentHint; public function __construct(string $locale, string $studentHint, ?LocalizedAssignment $createdFrom = null) diff --git a/app/model/entity/LocalizedExercise.php b/app/model/entity/LocalizedExercise.php index 5719b9cd1..ca228f9e4 100644 --- a/app/model/entity/LocalizedExercise.php +++ b/app/model/entity/LocalizedExercise.php @@ -6,9 +6,7 @@ use InvalidArgumentException; use JsonSerializable; -/** - * @ORM\Entity - */ +#[ORM\Entity] class LocalizedExercise extends LocalizedEntity implements JsonSerializable { public function __construct( @@ -27,34 +25,32 @@ public function __construct( $this->externalAssignmentLink = $externalAssignmentLink; } - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $name; /** * A short description of the exercise (for teachers) - * @ORM\Column(type="text") */ + #[ORM\Column(type: 'text')] protected $description; /** * Text of the assignment (for students) - * @ORM\Column(type="text") */ + #[ORM\Column(type: 'text')] protected $assignmentText; /** * A link to an external assignment for students - * @ORM\Column(type="string", length=1024, nullable=true) */ + #[ORM\Column(type: 'string', length: 1024, nullable: true)] protected $externalAssignmentLink; /** - * @ORM\ManyToOne(targetEntity="LocalizedExercise") - * @ORM\JoinColumn(onDelete="SET NULL") * @var LocalizedExercise */ + #[ORM\JoinColumn(onDelete: 'SET NULL')] + #[ORM\ManyToOne(targetEntity: LocalizedExercise::class)] protected $createdFrom; public function equals(LocalizedEntity $other): bool diff --git a/app/model/entity/LocalizedGroup.php b/app/model/entity/LocalizedGroup.php index ed2d28188..b8edb07df 100644 --- a/app/model/entity/LocalizedGroup.php +++ b/app/model/entity/LocalizedGroup.php @@ -5,31 +5,21 @@ use Doctrine\ORM\Mapping as ORM; use JsonSerializable; -/** - * @ORM\Entity - */ +#[ORM\Entity] class LocalizedGroup extends LocalizedEntity implements JsonSerializable { - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $name; - /** - * @ORM\Column(type="text") - */ + #[ORM\Column(type: 'text')] protected $description; - /** - * @ORM\ManyToOne(targetEntity="LocalizedGroup") - * @ORM\JoinColumn(onDelete="SET NULL") - */ + #[ORM\JoinColumn(onDelete: 'SET NULL')] + #[ORM\ManyToOne(targetEntity: LocalizedGroup::class)] protected $createdFrom; - /** - * @ORM\ManyToOne(targetEntity="Group", inversedBy="localizedTexts") - * @ORM\JoinColumn(nullable=true) - */ + #[ORM\JoinColumn(nullable: true)] + #[ORM\ManyToOne(targetEntity: Group::class, inversedBy: 'localizedTexts')] protected $group; public function __construct($locale, string $name, string $description, ?LocalizedGroup $createdFrom = null) diff --git a/app/model/entity/LocalizedNotification.php b/app/model/entity/LocalizedNotification.php index e40908814..9b4c99900 100644 --- a/app/model/entity/LocalizedNotification.php +++ b/app/model/entity/LocalizedNotification.php @@ -5,20 +5,14 @@ use Doctrine\ORM\Mapping as ORM; use JsonSerializable; -/** - * @ORM\Entity - */ +#[ORM\Entity] class LocalizedNotification extends LocalizedEntity implements JsonSerializable { - /** - * @ORM\Column(type="text") - */ + #[ORM\Column(type: 'text')] protected $text; - /** - * @ORM\ManyToOne(targetEntity="LocalizedNotification") - * @ORM\JoinColumn(onDelete="SET NULL") - */ + #[ORM\JoinColumn(onDelete: 'SET NULL')] + #[ORM\ManyToOne(targetEntity: LocalizedNotification::class)] protected $createdFrom; diff --git a/app/model/entity/LocalizedShadowAssignment.php b/app/model/entity/LocalizedShadowAssignment.php index 20eeb9c87..72daab8ec 100644 --- a/app/model/entity/LocalizedShadowAssignment.php +++ b/app/model/entity/LocalizedShadowAssignment.php @@ -6,9 +6,7 @@ use InvalidArgumentException; use JsonSerializable; -/** - * @ORM\Entity - */ +#[ORM\Entity] class LocalizedShadowAssignment extends LocalizedEntity implements JsonSerializable { public function __construct( @@ -25,28 +23,26 @@ public function __construct( $this->externalAssignmentLink = $externalAssignmentLink; } - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $name; /** * Text of the assignment (for students) - * @ORM\Column(type="text") */ + #[ORM\Column(type: 'text')] protected $assignmentText; /** * A link to an external assignment for students - * @ORM\Column(type="string", length=1024, nullable=true) */ + #[ORM\Column(type: 'string', length: 1024, nullable: true)] protected $externalAssignmentLink; /** - * @ORM\ManyToOne(targetEntity="LocalizedShadowAssignment") - * @ORM\JoinColumn(onDelete="SET NULL") * @var LocalizedShadowAssignment */ + #[ORM\JoinColumn(onDelete: 'SET NULL')] + #[ORM\ManyToOne(targetEntity: LocalizedShadowAssignment::class)] protected $createdFrom; public function equals(LocalizedEntity $other): bool diff --git a/app/model/entity/Login.php b/app/model/entity/Login.php index 189f97ad6..e2843deee 100644 --- a/app/model/entity/Login.php +++ b/app/model/entity/Login.php @@ -7,33 +7,25 @@ use Nette\Security\Passwords; use Nette\Utils\Validators; -/** - * @ORM\Entity - */ +#[ORM\Entity] class Login { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="string", length=128, unique=true) - */ + #[ORM\Column(type: 'string', length: 128, unique: true)] protected $username; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $passwordHash; - /** - * @ORM\OneToOne(targetEntity="User", inversedBy="login") - */ + #[ORM\OneToOne(targetEntity: User::class, inversedBy: 'login')] protected $user; /** diff --git a/app/model/entity/Notification.php b/app/model/entity/Notification.php index f7bbab059..0e1899121 100644 --- a/app/model/entity/Notification.php +++ b/app/model/entity/Notification.php @@ -10,26 +10,24 @@ use Doctrine\ORM\Mapping as ORM; use JsonSerializable; -/** - * @ORM\Entity - */ +#[ORM\Entity] class Notification implements JsonSerializable { use CreatableEntity; /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; /** * @var User - * @ORM\ManyToOne(targetEntity="User") */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $author; public function getAuthor(): ?User @@ -39,20 +37,20 @@ public function getAuthor(): ?User /** * @var DateTime - * @ORM\Column(type="datetime") */ + #[ORM\Column(type: 'datetime')] protected $visibleFrom; /** * @var DateTime - * @ORM\Column(type="datetime") */ + #[ORM\Column(type: 'datetime')] protected $visibleTo; /** * @var Collection|Selectable - * @ORM\ManyToMany(targetEntity="LocalizedNotification", indexBy="locale", cascade={"persist"}) */ + #[ORM\ManyToMany(targetEntity: LocalizedNotification::class, indexBy: 'locale', cascade: ['persist'])] protected $localizedTexts; public function getLocalizedTexts(): Collection @@ -77,9 +75,7 @@ public function getLocalizedTextByLocale(string $locale): ?LocalizedEntity return $first === false ? null : $first; } - /** - * @ORM\ManyToMany(targetEntity="Group") - */ + #[ORM\ManyToMany(targetEntity: Group::class)] protected $groups; /** @@ -112,14 +108,10 @@ function (Group $group) { )->getValues(); } - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $role; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $type; diff --git a/app/model/entity/Pipeline.php b/app/model/entity/Pipeline.php index 922c7cf55..42ff2a4f6 100644 --- a/app/model/entity/Pipeline.php +++ b/app/model/entity/Pipeline.php @@ -11,10 +11,8 @@ use Exception; use Gedmo\Mapping\Annotation as Gedmo; -/** - * @ORM\Entity - * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false) - */ +#[ORM\Entity] +#[Gedmo\SoftDeleteable(fieldName: 'deletedAt', timeAware: false)] class Pipeline { use CreatableEntity; @@ -23,33 +21,27 @@ class Pipeline use VersionableEntity; /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface|string */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $name; - /** - * @ORM\Column(type="text") - */ + #[ORM\Column(type: 'text')] protected $description; - /** - * @ORM\ManyToOne(targetEntity="PipelineConfig", inversedBy="pipelines", cascade={"persist"}) - */ + #[ORM\ManyToOne(targetEntity: PipelineConfig::class, inversedBy: 'pipelines', cascade: ['persist'])] protected $pipelineConfig; /** - * @ORM\ManyToOne(targetEntity="User") * If the pipeline has no author set, it is treated as predefined global pipeline used by everyone. */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $author; public function getAuthor(): ?User @@ -71,9 +63,7 @@ public function isGlobal(): bool return $this->getAuthor() === null; } - /** - * @ORM\ManyToOne(targetEntity="Pipeline") - */ + #[ORM\ManyToOne(targetEntity: Pipeline::class)] protected $createdFrom; public function getCreatedFrom(): ?Pipeline @@ -87,21 +77,24 @@ public function overrideCreatedFrom(?Pipeline $pipeline): void } /** - * @ORM\ManyToMany(targetEntity="ExerciseFile", inversedBy="pipelines") * @var Collection */ + #[ORM\ManyToMany(targetEntity: ExerciseFile::class, inversedBy: 'pipelines')] protected $exerciseFiles; /** - * @ORM\OneToMany(targetEntity="PipelineParameter", mappedBy="pipeline", indexBy="name", - * cascade={"persist"}, orphanRemoval=true) * @var Collection */ + #[ORM\OneToMany( + targetEntity: PipelineParameter::class, + mappedBy: 'pipeline', + indexBy: 'name', + cascade: ['persist'], + orphanRemoval: true + )] protected $parameters; - /** - * @ORM\ManyToMany(targetEntity="RuntimeEnvironment") - */ + #[ORM\ManyToMany(targetEntity: RuntimeEnvironment::class)] protected $runtimeEnvironments; public const DEFAULT_PARAMETERS = [ diff --git a/app/model/entity/PipelineConfig.php b/app/model/entity/PipelineConfig.php index 91c8ba7e0..1fb2231df 100644 --- a/app/model/entity/PipelineConfig.php +++ b/app/model/entity/PipelineConfig.php @@ -10,28 +10,22 @@ use App\Helpers\Yaml; use DateTime; -/** - * @ORM\Entity - */ +#[ORM\Entity] class PipelineConfig { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="text") - */ + #[ORM\Column(type: 'text')] protected $pipelineConfig; - /** - * @ORM\ManyToOne(targetEntity="User") - */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $author; public function getAuthor(): ?User @@ -39,20 +33,14 @@ public function getAuthor(): ?User return $this->author && $this->author->isDeleted() ? null : $this->author; } - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $createdAt; - /** - * @ORM\ManyToOne(targetEntity="PipelineConfig") - * @ORM\JoinColumn(onDelete="SET NULL") - */ + #[ORM\JoinColumn(onDelete: 'SET NULL')] + #[ORM\ManyToOne(targetEntity: PipelineConfig::class)] protected $createdFrom; - /** - * @ORM\OneToMany(targetEntity="Pipeline", mappedBy="pipelineConfig") - */ + #[ORM\OneToMany(targetEntity: Pipeline::class, mappedBy: 'pipelineConfig')] protected $pipelines; /** diff --git a/app/model/entity/PipelineParameter.php b/app/model/entity/PipelineParameter.php index c35f0b04f..361fac310 100644 --- a/app/model/entity/PipelineParameter.php +++ b/app/model/entity/PipelineParameter.php @@ -5,30 +5,24 @@ use Doctrine\ORM\Mapping as ORM; use JsonSerializable; -/** - * @ORM\Entity - * @ORM\InheritanceType("SINGLE_TABLE") - * @ORM\DiscriminatorColumn("discriminator") - */ +#[ORM\Entity] +#[ORM\InheritanceType('SINGLE_TABLE')] +#[ORM\DiscriminatorColumn('discriminator')] abstract class PipelineParameter implements JsonSerializable { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\ManyToOne(targetEntity="Pipeline", inversedBy="parameters") - */ + #[ORM\ManyToOne(targetEntity: Pipeline::class, inversedBy: 'parameters')] protected $pipeline; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $name; public function __construct(Pipeline $pipeline, string $name) diff --git a/app/model/entity/PlagiarismDetectedSimilarFile.php b/app/model/entity/PlagiarismDetectedSimilarFile.php index bd5540837..19d34cae1 100644 --- a/app/model/entity/PlagiarismDetectedSimilarFile.php +++ b/app/model/entity/PlagiarismDetectedSimilarFile.php @@ -6,10 +6,6 @@ use App\Helpers\Plagiarism\SimilarityFragments; /** - * @ORM\Entity - * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(columns={ - * "detected_similarity_id", "solution_file_id", "file_entry" - * })}) * A record representing a similarity detected in two compared files, which is part of one * detected similarity record. * The detected similarity holds the reference to the tested file, this entity holds reference @@ -17,52 +13,55 @@ * A similarity can comprise multiple text blocks, the details about similar code fragments are * encoded in internal JSON record 'fragments' (violating 1NF). */ +#[ORM\Table] +#[ORM\UniqueConstraint(columns: ['detected_similarity_id', 'solution_file_id', 'file_entry'])] +#[ORM\Entity] class PlagiarismDetectedSimilarFile { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; /** * @var PlagiarismDetectedSimilarity - * @ORM\ManyToOne(targetEntity="PlagiarismDetectedSimilarity") * Reference to a detected similarity record to which this file reference contribute. */ + #[ORM\ManyToOne(targetEntity: PlagiarismDetectedSimilarity::class)] protected $detectedSimilarity; /** * @var AssignmentSolution - * @ORM\ManyToOne(targetEntity="AssignmentSolution") * Another solution in which a similar code was detected. * Note: this is nullable in case other sources than assignment solutions are introduced in testing pool. */ + #[ORM\ManyToOne(targetEntity: AssignmentSolution::class)] protected $solution; /** * @var SolutionFile - * @ORM\ManyToOne(targetEntity="SolutionFile") * Reference to a solution file where similarities were found. * If missing, external sources for comparison were used (and fileEntry is the only identification) */ + #[ORM\ManyToOne(targetEntity: SolutionFile::class)] protected $solutionFile; /** - * @ORM\Column(type="string") * Either a relative path within a ZIP file (if the solution file refers to the only ZIP archive), * or a reference to external file source that were used for comparison (preferably an URL). */ + #[ORM\Column(type: 'string')] protected $fileEntry; /** - * @ORM\Column(type="text", length=65535) * JSON encoded structure containing the individual code fragments * (as byte-offset references to tested and similar files). */ + #[ORM\Column(type: 'text', length: 65535)] protected $fragments; /** diff --git a/app/model/entity/PlagiarismDetectedSimilarity.php b/app/model/entity/PlagiarismDetectedSimilarity.php index 7f72f6054..3b41dc69b 100644 --- a/app/model/entity/PlagiarismDetectedSimilarity.php +++ b/app/model/entity/PlagiarismDetectedSimilarity.php @@ -7,73 +7,76 @@ use Doctrine\Common\Collections\Collection; /** - * @ORM\Entity - * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(columns={ - * "batch_id", "author_id", "solution_file_id", "file_entry" - * })}) * A record (node) representing a similarity detected between a file and a set of files of a particular user. * This entity holds the tested file and a reference to the author of similar files (possible sources of plagiarism). * There should be at least one PlagiarismDetectedSimilarFile record associated with detected similarity * (i.e., all possible sources of plagiarism of one author). */ +#[ORM\Table] +#[ORM\UniqueConstraint(columns: ['batch_id', 'author_id', 'solution_file_id', 'file_entry'])] +#[ORM\Entity] class PlagiarismDetectedSimilarity { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; /** * @var PlagiarismDetectionBatch - * @ORM\ManyToOne(targetEntity="PlagiarismDetectionBatch") * Reference to a batch in which this similarity was detected. */ + #[ORM\ManyToOne(targetEntity: PlagiarismDetectionBatch::class)] protected $batch; /** * @var User - * @ORM\ManyToOne(targetEntity="User") - * Author of all solutions refered in related PlagiarismDetectedSimilarFile entities. + * Author of all solutions referred in related PlagiarismDetectedSimilarFile entities. * (i.e., this is just a denormalization pull-up to increase efficiency). */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $author; /** * @var AssignmentSolution - * @ORM\ManyToOne(targetEntity="AssignmentSolution") * The solution that was tested for similarities. */ + #[ORM\ManyToOne(targetEntity: AssignmentSolution::class)] protected $testedSolution; /** * @var SolutionFile - * @ORM\ManyToOne(targetEntity="SolutionFile") * Reference to a solution file that was tested for similarities (is a suspected plagiarism). */ + #[ORM\ManyToOne(targetEntity: SolutionFile::class)] protected $solutionFile; /** - * @ORM\Column(type="string") * A submitted file name (of the solution) that was tested for similarities. * This is filled only if solution file is a ZIP that was scanned internally. */ + #[ORM\Column(type: 'string')] protected $fileEntry; /** - * @ORM\Column(type="float") * Similarity score normalized from 0 (no similarity) to 1 (identical). */ + #[ORM\Column(type: 'float')] protected $similarity; /** - * @ORM\OneToMany(targetEntity="PlagiarismDetectedSimilarFile", mappedBy="detectedSimilarity", - * cascade={"persist"}, orphanRemoval=true) * @var Collection */ + #[ORM\OneToMany( + targetEntity: PlagiarismDetectedSimilarFile::class, + mappedBy: 'detectedSimilarity', + cascade: ['persist'], + orphanRemoval: true + )] protected $similarFiles; /** diff --git a/app/model/entity/PlagiarismDetectionBatch.php b/app/model/entity/PlagiarismDetectionBatch.php index ae97d6a42..e748661c1 100644 --- a/app/model/entity/PlagiarismDetectionBatch.php +++ b/app/model/entity/PlagiarismDetectionBatch.php @@ -7,47 +7,47 @@ use DateTime; /** - * @ORM\Entity * A record representing one processing batch of plagiarism detection. * The detection is performed by external tools (solutions are downloaded and results are uploaded via API). */ +#[ORM\Entity] class PlagiarismDetectionBatch implements JsonSerializable { use CreatableEntity; /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; /** - * @ORM\Column(type="string") * Identifier of the external tool that performed the detection. */ + #[ORM\Column(type: 'string')] protected $detectionTool; /** - * @ORM\Column(type="string") * Tool-specific parameters serialized into a string (e.g., CLI arguments use to invoke the tool) */ + #[ORM\Column(type: 'string')] protected $detectionToolParameters; /** * @var User - * @ORM\ManyToOne(targetEntity="User") * User responsible for the detection process. */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $supervisor; /** * @var DateTime - * @ORM\Column(type="datetime", nullable=true) * Time when all the plagiarism records were uploaded. If null, the upload is still pending. */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $uploadCompletedAt = null; /** diff --git a/app/model/entity/ReferenceExerciseSolution.php b/app/model/entity/ReferenceExerciseSolution.php index e119d8199..efa1ad471 100644 --- a/app/model/entity/ReferenceExerciseSolution.php +++ b/app/model/entity/ReferenceExerciseSolution.php @@ -7,23 +7,19 @@ use Doctrine\Common\Collections\ArrayCollection; use InvalidArgumentException; -/** - * @ORM\Entity - */ +#[ORM\Entity] class ReferenceExerciseSolution { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\ManyToOne(targetEntity="Exercise", inversedBy="referenceSolutions") - */ + #[ORM\ManyToOne(targetEntity: Exercise::class, inversedBy: 'referenceSolutions')] protected $exercise; public function getExercise(): ?Exercise @@ -31,19 +27,17 @@ public function getExercise(): ?Exercise return $this->exercise->isDeleted() ? null : $this->exercise; } - /** - * @ORM\Column(type="text") - */ + #[ORM\Column(type: 'text')] protected $description; - /** - * @ORM\OneToOne(targetEntity="Solution", cascade={"persist", "remove"}, fetch="EAGER") - */ + #[ORM\OneToOne(targetEntity: Solution::class, cascade: ['persist', 'remove'], fetch: 'EAGER')] protected $solution; - /** - * @ORM\OneToMany(targetEntity="ReferenceSolutionSubmission", mappedBy="referenceSolution", cascade={"remove"}) - */ + #[ORM\OneToMany( + targetEntity: ReferenceSolutionSubmission::class, + mappedBy: 'referenceSolution', + cascade: ['remove'] + )] protected $submissions; /** @@ -51,9 +45,9 @@ public function getExercise(): ?Exercise * The reference should speed up loading in many cases since the last submission is the only one that counts. * However, this behavior might be altered in the future, so we can actively select which submission is relevant. * - * @ORM\OneToOne(targetEntity="ReferenceSolutionSubmission", fetch="EAGER") * @var ReferenceSolutionSubmission|null */ + #[ORM\OneToOne(targetEntity: ReferenceSolutionSubmission::class, fetch: 'EAGER')] protected $lastSubmission = null; public const VISIBILITY_PROMOTED = 2; @@ -66,8 +60,8 @@ public function getExercise(): ?Exercise * Private temp denotes the solution should also be garbage collected in the future. * Promoted solutions are public ones explicitly marked as "you should see this" * (e.g., a sample solution of the author of the exercise). - * @ORM\Column(type="integer") */ + #[ORM\Column(type: 'integer')] protected $visibility = 0; /** diff --git a/app/model/entity/ReferenceSolutionSubmission.php b/app/model/entity/ReferenceSolutionSubmission.php index 91b67d74f..af7a9203c 100644 --- a/app/model/entity/ReferenceSolutionSubmission.php +++ b/app/model/entity/ReferenceSolutionSubmission.php @@ -9,22 +9,17 @@ use App\Helpers\EvaluationResults as ER; use App\Model\View\Helpers\SubmissionViewOptions; -/** - * @ORM\Entity - * @ORM\Table(indexes={@ORM\Index(name="ref_solution_submission_submitted_at_idx", columns={"submitted_at"})}) - */ +#[ORM\Table] +#[ORM\Index(name: 'ref_solution_submission_submitted_at_idx', columns: ['submitted_at'])] +#[ORM\Entity] class ReferenceSolutionSubmission extends Submission implements JsonSerializable, ES\IEvaluable { public const JOB_TYPE = "reference"; - /** - * @ORM\ManyToOne(targetEntity="ReferenceExerciseSolution", inversedBy="submissions") - */ + #[ORM\ManyToOne(targetEntity: ReferenceExerciseSolution::class, inversedBy: 'submissions')] protected $referenceSolution; - /** - * @ORM\ManyToOne(targetEntity="HardwareGroup") - */ + #[ORM\ManyToOne(targetEntity: HardwareGroup::class)] protected $hwGroup; @@ -34,10 +29,14 @@ public function setEvaluation(SolutionEvaluation $evaluation) } /** - * @ORM\OneToOne(targetEntity="SubmissionFailure", cascade={"persist", "remove"}, - * inversedBy="referenceSolutionSubmission", fetch="EAGER") * @var SubmissionFailure */ + #[ORM\OneToOne( + targetEntity: SubmissionFailure::class, + cascade: ['persist', 'remove'], + inversedBy: 'referenceSolutionSubmission', + fetch: 'EAGER' + )] protected $failure; public function jsonSerialize(): mixed diff --git a/app/model/entity/ReportedErrors.php b/app/model/entity/ReportedErrors.php index e5e6822cd..869231892 100644 --- a/app/model/entity/ReportedErrors.php +++ b/app/model/entity/ReportedErrors.php @@ -5,43 +5,31 @@ use DateTime; use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\Entity - */ +#[ORM\Entity] class ReportedErrors { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $type; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $recipients; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $subject; - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $sentAt; - /** - * @ORM\Column(type="text") - */ + #[ORM\Column(type: 'text')] protected $description; public function __construct(string $type, string $recipients, string $subject, string $description) diff --git a/app/model/entity/ReviewComment.php b/app/model/entity/ReviewComment.php index 622c90740..7703ce384 100644 --- a/app/model/entity/ReviewComment.php +++ b/app/model/entity/ReviewComment.php @@ -7,55 +7,51 @@ use DateTime; /** - * @ORM\Entity * Single comment within a review of an assignment solution. * A comment is tied to a particular line of code in a given file. */ +#[ORM\Entity] class ReviewComment implements JsonSerializable { use CreatableEntity; /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; /** * @var AssignmentSolution - * @ORM\ManyToOne(targetEntity="AssignmentSolution", cascade={"persist"}, inversedBy="reviewComments") */ + #[ORM\ManyToOne(targetEntity: AssignmentSolution::class, cascade: ['persist'], inversedBy: 'reviewComments')] protected $solution; /** * @var User - * @ORM\ManyToOne(targetEntity="User") */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $author; /** - * @ORM\Column(type="string") * File represented by name, possibly with a ZIP entity reference (file.zip#entry.name) */ + #[ORM\Column(type: 'string')] protected $file; - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: 'integer')] protected $line; - /** - * @ORM\Column(type="text", length=65535) - */ + #[ORM\Column(type: 'text', length: 65535)] protected $text; /** - * @ORM\Column(type="boolean") * Issues are important comments, that are expected to be resolved by the student. */ + #[ORM\Column(type: 'boolean')] protected $issue = false; /** diff --git a/app/model/entity/RuntimeEnvironment.php b/app/model/entity/RuntimeEnvironment.php index f49a2635f..44401bc34 100644 --- a/app/model/entity/RuntimeEnvironment.php +++ b/app/model/entity/RuntimeEnvironment.php @@ -8,32 +8,24 @@ use App\Helpers\YamlException; use App\Exceptions\ParseException as AppParseException; -/** - * @ORM\Entity - */ +#[ORM\Entity] class RuntimeEnvironment implements JsonSerializable { - /** - * @ORM\Id - * @ORM\Column(type="string", length=32) - */ + #[ORM\Id] + #[ORM\Column(type: 'string', length: 32)] protected $id; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $name; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $longName; /** * List of extensions in YAML format. No extension is also extension. * Example: [ "cpp", "hpp", "h", "" ] - * @ORM\Column(type="string") */ + #[ORM\Column(type: 'string')] protected $extensions; /** @@ -52,19 +44,13 @@ public function getExtensionsList() return $parsedConfig; } - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $platform; - /** - * @ORM\Column(type="string", length=1024) - */ + #[ORM\Column(type: 'string', length: 1024)] protected $description; - /** - * @ORM\Column(type="text", length=65535) - */ + #[ORM\Column(type: 'text', length: 65535)] protected $defaultVariables; /** diff --git a/app/model/entity/SecurityEvent.php b/app/model/entity/SecurityEvent.php index a183ae0bf..e448882c6 100644 --- a/app/model/entity/SecurityEvent.php +++ b/app/model/entity/SecurityEvent.php @@ -7,10 +7,11 @@ use JsonSerializable; /** - * @ORM\Entity - * @ORM\Table(indexes={@ORM\Index(name="event_created_at_idx", columns={"created_at"})}) * A logged security event such as user login or token refresh. */ +#[ORM\Table] +#[ORM\Index(name: 'event_created_at_idx', columns: ['created_at'])] +#[ORM\Entity] class SecurityEvent implements JsonSerializable { use CreatableEntity; @@ -22,33 +23,27 @@ class SecurityEvent implements JsonSerializable public const TYPE_INVALIDATE_TOKENS = 'invalid'; public const TYPE_CHANGE_PASSWORD = 'password'; - /** - * @ORM\Id - * @ORM\Column(type="integer") - * @ORM\GeneratedValue(strategy="AUTO") - */ + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue(strategy: 'AUTO')] protected $id; /** - * @ORM\Column(type="string") * Must match one of the TYPE constants */ + #[ORM\Column(type: 'string')] protected $type; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $remoteAddr; - /** - * @ORM\ManyToOne(targetEntity="User") - */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $user; /** - * @ORM\Column(type="text", length=65535) * Additional JSON encoded data (type-specific) */ + #[ORM\Column(type: 'text', length: 65535)] protected $data; /** diff --git a/app/model/entity/ShadowAssignment.php b/app/model/entity/ShadowAssignment.php index fb1586874..5c11ce219 100644 --- a/app/model/entity/ShadowAssignment.php +++ b/app/model/entity/ShadowAssignment.php @@ -10,10 +10,8 @@ use Gedmo\Mapping\Annotation as Gedmo; use DateTime; -/** - * @ORM\Entity - * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false) - */ +#[ORM\Entity] +#[Gedmo\SoftDeleteable(fieldName: 'deletedAt', timeAware: false)] class ShadowAssignment extends AssignmentBase { private function __construct( @@ -47,18 +45,18 @@ public static function createInGroup(Group $group, $isPublic = false) } /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; /** - * @ORM\ManyToMany(targetEntity="LocalizedShadowAssignment", indexBy="locale") * @var Collection|Selectable */ + #[ORM\ManyToMany(targetEntity: LocalizedShadowAssignment::class, indexBy: 'locale')] protected $localizedTexts; public function getLocalizedTexts(): Collection @@ -83,9 +81,7 @@ public function getLocalizedTextByLocale(string $locale): ?LocalizedEntity return $first === false ? null : $first; } - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: 'integer')] protected $maxPoints; public function getMaxPoints(): int @@ -93,9 +89,7 @@ public function getMaxPoints(): int return $this->maxPoints; } - /** - * @ORM\ManyToOne(targetEntity="Group", inversedBy="shadowAssignments") - */ + #[ORM\ManyToOne(targetEntity: Group::class, inversedBy: 'shadowAssignments')] protected $group; public function getGroup(): ?Group @@ -103,9 +97,7 @@ public function getGroup(): ?Group return $this->group->isDeleted() ? null : $this->group; } - /** - * @ORM\OneToMany(targetEntity="ShadowAssignmentPoints", mappedBy="shadowAssignment") - */ + #[ORM\OneToMany(targetEntity: ShadowAssignmentPoints::class, mappedBy: 'shadowAssignment')] protected $shadowAssignmentPointsCollection; public function getPointsByUser(User $user) @@ -115,9 +107,7 @@ public function getPointsByUser(User $user) return $first === false ? null : $first; } - /** - * @ORM\Column(type="datetime", nullable=true) - */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $deadline = null; /* diff --git a/app/model/entity/ShadowAssignmentPoints.php b/app/model/entity/ShadowAssignmentPoints.php index 83d488623..7956df221 100644 --- a/app/model/entity/ShadowAssignmentPoints.php +++ b/app/model/entity/ShadowAssignmentPoints.php @@ -5,10 +5,9 @@ use Doctrine\ORM\Mapping as ORM; use DateTime; -/** - * @ORM\Entity - * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(columns={"shadow_assignment_id", "awardee_id"})}) - */ +#[ORM\Table] +#[ORM\UniqueConstraint(columns: ['shadow_assignment_id', 'awardee_id'])] +#[ORM\Entity] class ShadowAssignmentPoints { use CreatableEntity; @@ -33,28 +32,24 @@ public function __construct( } /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: 'integer')] protected $points; - /** - * @ORM\Column(type="string", length=1024) - */ + #[ORM\Column(type: 'string', length: 1024)] protected $note; /** * @var ShadowAssignment - * @ORM\ManyToOne(targetEntity="ShadowAssignment") */ + #[ORM\ManyToOne(targetEntity: ShadowAssignment::class)] protected $shadowAssignment; public function getShadowAssignment(): ?ShadowAssignment @@ -63,9 +58,9 @@ public function getShadowAssignment(): ?ShadowAssignment } /** - * @ORM\ManyToOne(targetEntity="User") * Author is the person (typically teacher) who authorized the points. */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $author; public function getAuthor(): ?User @@ -74,9 +69,9 @@ public function getAuthor(): ?User } /** - * @ORM\ManyToOne(targetEntity="User") * Awardee is the person (typically student) who accepted (benefit from) the points. */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $awardee; public function getAwardee(): ?User @@ -84,9 +79,7 @@ public function getAwardee(): ?User return $this->awardee->isDeleted() ? null : $this->awardee; } - /** - * @ORM\Column(type="datetime", nullable=true) - */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $awardedAt; /* diff --git a/app/model/entity/SisGroupBinding.php b/app/model/entity/SisGroupBinding.php index 4dc50a370..5d5f20cf8 100644 --- a/app/model/entity/SisGroupBinding.php +++ b/app/model/entity/SisGroupBinding.php @@ -5,29 +5,27 @@ use Doctrine\ORM\Mapping as ORM; /** - * @ORM\Entity - * DEPRECATED will be replaced by group external attributes + * DEPRECATED (replaced by group external attributes) */ +#[ORM\Entity] class SisGroupBinding { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; /** - * @ORM\ManyToOne(targetEntity="Group") * @var Group */ + #[ORM\ManyToOne(targetEntity: Group::class)] protected $group; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $code; /** diff --git a/app/model/entity/SisValidTerm.php b/app/model/entity/SisValidTerm.php index 02281b39e..9d59f4b4b 100644 --- a/app/model/entity/SisValidTerm.php +++ b/app/model/entity/SisValidTerm.php @@ -6,43 +6,31 @@ use Doctrine\ORM\Mapping as ORM; use JsonSerializable; -/** - * @ORM\Entity - */ +#[ORM\Entity] class SisValidTerm implements JsonSerializable { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: 'integer')] protected $year; - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: 'integer')] protected $term; - /** - * @ORM\Column(type="datetime", nullable=true) - */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $beginning; - /** - * @ORM\Column(type="datetime", nullable=true) - */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $end; - /** - * @ORM\Column(type="datetime", nullable=true) - */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $advertiseUntil; public function __construct($year, $term) diff --git a/app/model/entity/Solution.php b/app/model/entity/Solution.php index 412f73370..2f6593f55 100644 --- a/app/model/entity/Solution.php +++ b/app/model/entity/Solution.php @@ -9,53 +9,42 @@ use DateTime; use App\Helpers\Yaml; -/** - * @ORM\Entity - * @ORM\Table(indexes={@ORM\Index(name="solution_created_at_idx", columns={"created_at"})}) - */ +#[ORM\Table] +#[ORM\Index(name: 'solution_created_at_idx', columns: ['created_at'])] +#[ORM\Entity] class Solution { use CreatableEntity; /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\ManyToOne(targetEntity="User") - */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $author; - /** - * @ORM\OneToMany(targetEntity="SolutionFile", mappedBy="solution") - */ + #[ORM\OneToMany(targetEntity: SolutionFile::class, mappedBy: 'solution')] protected $files; - /** - * @ORM\ManyToOne(targetEntity="RuntimeEnvironment") - */ + #[ORM\ManyToOne(targetEntity: RuntimeEnvironment::class)] protected $runtimeEnvironment; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $evaluated; - /** - * @ORM\Column(type="text") - */ + #[ORM\Column(type: 'text')] protected $solutionParams; /** - * @ORM\Column(type="string") * Subdirectory in path to the ZIP archive where all solution files are. * The subdir names are typically time-related (e.g., YYYY-MM) to optimize backup management. */ + #[ORM\Column(type: 'string')] protected $subdir; /** diff --git a/app/model/entity/SolutionEvaluation.php b/app/model/entity/SolutionEvaluation.php index 958777f0b..f385c1a29 100644 --- a/app/model/entity/SolutionEvaluation.php +++ b/app/model/entity/SolutionEvaluation.php @@ -9,34 +9,28 @@ use Doctrine\ORM\Mapping as ORM; use Doctrine\Common\Collections\ArrayCollection; -/** - * @ORM\Entity - */ +#[ORM\Entity] class SolutionEvaluation { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $evaluatedAt; /** * If true, the solution cannot be compiled. - * @ORM\Column(type="boolean") */ + #[ORM\Column(type: 'boolean')] protected $initFailed; - /** - * @ORM\Column(type="float") - */ + #[ORM\Column(type: 'float')] protected $score; public function getScore(): float @@ -44,9 +38,7 @@ public function getScore(): float return $this->score; } - /** - * @ORM\ManyToOne(targetEntity="ExerciseScoreConfig") - */ + #[ORM\ManyToOne(targetEntity: ExerciseScoreConfig::class)] protected $scoreConfig; public function getScoreConfig(): ?ExerciseScoreConfig @@ -65,19 +57,13 @@ public function setScore(float $score, ?ExerciseScoreConfig $scoreConfig = null) $this->scoreConfig = $scoreConfig; } - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: 'integer')] protected $points; - /** - * @ORM\Column(type="text") - */ + #[ORM\Column(type: 'text')] protected $initiationOutputs; - /** - * @ORM\OneToMany(targetEntity="TestResult", mappedBy="solutionEvaluation", cascade={"persist", "remove"}) - */ + #[ORM\OneToMany(targetEntity: TestResult::class, mappedBy: 'solutionEvaluation', cascade: ['persist', 'remove'])] protected $testResults; public function getDataForView(SubmissionViewOptions $options) diff --git a/app/model/entity/SolutionFile.php b/app/model/entity/SolutionFile.php index 83ff69122..375ae3b1a 100644 --- a/app/model/entity/SolutionFile.php +++ b/app/model/entity/SolutionFile.php @@ -7,15 +7,11 @@ use Doctrine\ORM\Mapping as ORM; use DateTime; -/** - * @ORM\Entity - */ +#[ORM\Entity] class SolutionFile extends UploadedFile { - /** - * @ORM\ManyToOne(targetEntity="Solution") - * @ORM\JoinColumn(onDelete="SET NULL") - */ + #[ORM\JoinColumn(onDelete: 'SET NULL')] + #[ORM\ManyToOne(targetEntity: Solution::class)] protected $solution; public function __construct($name, DateTime $uploadedAt, $fileSize, ?User $user, Solution $solution) diff --git a/app/model/entity/SolutionZipFile.php b/app/model/entity/SolutionZipFile.php index a4a1422cb..45c5d264c 100644 --- a/app/model/entity/SolutionZipFile.php +++ b/app/model/entity/SolutionZipFile.php @@ -9,10 +9,10 @@ use DateTime; /** - * @ORM\Entity * A special case of solution file which is used when the user submits single ZIP archive. * In such case it would be impractical to put it into another ZIP archive. */ +#[ORM\Entity] class SolutionZipFile extends SolutionFile implements JsonSerializable { public function __construct($name, DateTime $uploadedAt, $fileSize, ?User $user, Solution $solution) diff --git a/app/model/entity/StringPipelineParameter.php b/app/model/entity/StringPipelineParameter.php index 555f32d58..00db4eb73 100644 --- a/app/model/entity/StringPipelineParameter.php +++ b/app/model/entity/StringPipelineParameter.php @@ -5,14 +5,10 @@ use App\Exceptions\InvalidApiArgumentException; use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\Entity - */ +#[ORM\Entity] class StringPipelineParameter extends PipelineParameter { - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $stringValue; public function getValue() diff --git a/app/model/entity/SubmissionFailure.php b/app/model/entity/SubmissionFailure.php index cf76b1e35..4ac79ba19 100644 --- a/app/model/entity/SubmissionFailure.php +++ b/app/model/entity/SubmissionFailure.php @@ -6,9 +6,7 @@ use Doctrine\ORM\Mapping as ORM; use JsonSerializable; -/** - * @ORM\Entity - */ +#[ORM\Entity] class SubmissionFailure implements JsonSerializable { use CreatableEntity; @@ -39,43 +37,33 @@ class SubmissionFailure implements JsonSerializable public const TYPE_SOFT_CONFIG_ERROR = "soft_config_error"; /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $type; - /** - * @ORM\Column(type="text") - */ + #[ORM\Column(type: 'text')] protected $description; - /** - * @ORM\OneToOne(targetEntity="AssignmentSolutionSubmission", mappedBy="failure") - */ + #[ORM\OneToOne(targetEntity: AssignmentSolutionSubmission::class, mappedBy: 'failure')] protected $assignmentSolutionSubmission; - /** - * @ORM\OneToOne(targetEntity="ReferenceSolutionSubmission", mappedBy="failure") - */ + #[ORM\OneToOne(targetEntity: ReferenceSolutionSubmission::class, mappedBy: 'failure')] protected $referenceSolutionSubmission; /** - * @ORM\Column(type="datetime", nullable=true) * @var ?DateTime */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $resolvedAt; - /** - * @ORM\Column(type="string", nullable=true) - */ + #[ORM\Column(type: 'string', nullable: true)] protected $resolutionNote; /** diff --git a/app/model/entity/TestResult.php b/app/model/entity/TestResult.php index 0ee77d56d..559ccee4c 100644 --- a/app/model/entity/TestResult.php +++ b/app/model/entity/TestResult.php @@ -6,9 +6,7 @@ use App\Helpers\EvaluationResults as ER; use App\Model\View\Helpers\SubmissionViewOptions; -/** - * @ORM\Entity - */ +#[ORM\Entity] class TestResult { public function __construct( @@ -39,113 +37,75 @@ public function __construct( $this->judgeStderr = substr($result->getJudgeStderr(), 0, 65536); } - /** - * @ORM\Id - * @ORM\Column(type="integer") - * @ORM\GeneratedValue(strategy="AUTO") - */ + #[ORM\Id] + #[ORM\Column(type: 'integer')] + #[ORM\GeneratedValue(strategy: 'AUTO')] protected $id; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $testName; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $status; - /** - * @ORM\ManyToOne(targetEntity="SolutionEvaluation", inversedBy="testResults") - */ + #[ORM\ManyToOne(targetEntity: SolutionEvaluation::class, inversedBy: 'testResults')] protected $solutionEvaluation; - /** - * @ORM\Column(type="float") - */ + #[ORM\Column(type: 'float')] protected $score; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $memoryExceeded; - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: 'integer')] protected $usedMemory; - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: 'integer')] protected $usedMemoryLimit; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $wallTimeExceeded; - /** - * @ORM\Column(type="float") - */ + #[ORM\Column(type: 'float')] protected $usedWallTime; - /** - * @ORM\Column(type="float") - */ + #[ORM\Column(type: 'float')] protected $usedWallTimeLimit; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $cpuTimeExceeded; - /** - * @ORM\Column(type="float") - */ + #[ORM\Column(type: 'float')] protected $usedCpuTime; - /** - * @ORM\Column(type="float") - */ + #[ORM\Column(type: 'float')] protected $usedCpuTimeLimit; - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: 'integer')] protected $exitCode; /** - * @ORM\Column(type="boolean") * Whether the exit code corresponds to configured success exit codes. */ + #[ORM\Column(type: 'boolean')] protected $exitCodeOk; /** - * @ORM\Column(type="boolean") * Whether the exit code was produced by regular termination (not by signal, timeout, or sandbox error). */ + #[ORM\Column(type: 'boolean')] protected $exitCodeNative; - /** - * @ORM\Column(type="integer", nullable=true) - */ + #[ORM\Column(type: 'integer', nullable: true)] protected $exitSignal; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $message; - /** - * @ORM\Column(type="text", length=65535, nullable=true) - */ + #[ORM\Column(type: 'text', length: 65535, nullable: true)] protected $judgeStdout; - /** - * @ORM\Column(type="text", length=65535, nullable=true) - */ + #[ORM\Column(type: 'text', length: 65535, nullable: true)] protected $judgeStderr; public function getDataForView(SubmissionViewOptions $options) diff --git a/app/model/entity/UploadedFile.php b/app/model/entity/UploadedFile.php index 7f4e9e6e7..83e3b22d6 100644 --- a/app/model/entity/UploadedFile.php +++ b/app/model/entity/UploadedFile.php @@ -8,27 +8,25 @@ use JsonSerializable; use DateTime; -/** - * @ORM\Entity - * @ORM\InheritanceType("SINGLE_TABLE") - * @ORM\DiscriminatorColumn("discriminator") - * @ORM\Table(name="`uploaded_file`") - */ +#[ORM\Table(name: '`uploaded_file`')] +#[ORM\Entity] +#[ORM\InheritanceType('SINGLE_TABLE')] +#[ORM\DiscriminatorColumn('discriminator')] class UploadedFile implements JsonSerializable { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; /** * The name under which the file was uploaded - * @ORM\Column(type="string") */ + #[ORM\Column(type: 'string')] protected $name; /** @@ -40,19 +38,13 @@ public function getFileExtension(): string return pathinfo($this->name, PATHINFO_EXTENSION); } - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $uploadedAt; - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: 'integer')] protected $fileSize; - /** - * @ORM\ManyToOne(targetEntity="User") - */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $user; public function getUser(): ?User diff --git a/app/model/entity/UploadedPartialFile.php b/app/model/entity/UploadedPartialFile.php index 299e3f090..121b75155 100644 --- a/app/model/entity/UploadedPartialFile.php +++ b/app/model/entity/UploadedPartialFile.php @@ -8,19 +8,19 @@ use OverflowException; /** - * @ORM\Entity * This entity tracks an upload of a file per partes (chunked upload). * Once the file is uploaded completely, it will be converted into UploadedFile entity. */ +#[ORM\Entity] class UploadedPartialFile implements JsonSerializable { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; public function getId(): ?string @@ -30,8 +30,8 @@ public function getId(): ?string /** * The name under which the file was uploaded - * @ORM\Column(type="string") */ + #[ORM\Column(type: 'string')] protected $name; public function getName(): string @@ -48,19 +48,13 @@ public function getFileExtension(): string return pathinfo($this->name, PATHINFO_EXTENSION); } - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $startedAt; - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $updatedAt; - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: 'integer')] protected $totalSize; public function getTotalSize(): int @@ -68,9 +62,7 @@ public function getTotalSize(): int return $this->totalSize; } - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: 'integer')] protected $uploadedSize = 0; public function getUploadedSize(): int @@ -87,9 +79,7 @@ public function isUploadComplete(): bool return $this->totalSize === $this->uploadedSize; } - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: 'integer')] protected $chunks = 0; public function getChunks(): int @@ -97,9 +87,7 @@ public function getChunks(): int return $this->chunks; } - /** - * @ORM\ManyToOne(targetEntity="User") - */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $user; public function getUser(): ?User diff --git a/app/model/entity/User.php b/app/model/entity/User.php index bbc7559b6..7fc75332e 100644 --- a/app/model/entity/User.php +++ b/app/model/entity/User.php @@ -15,10 +15,8 @@ use DateTimeInterface; use DateTimeImmutable; -/** - * @ORM\Entity - * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false) - */ +#[ORM\Entity] +#[Gedmo\SoftDeleteable(fieldName: 'deletedAt', timeAware: false)] class User { use CreatableEntity; @@ -63,27 +61,21 @@ public function __construct( } /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $titlesBeforeName; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $firstName; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $lastName; public function getName() @@ -91,19 +83,13 @@ public function getName() return trim("{$this->titlesBeforeName} {$this->firstName} {$this->lastName} {$this->titlesAfterName}"); } - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $titlesAfterName; - /** - * @ORM\Column(type="string", unique=true) - */ + #[ORM\Column(type: 'string', unique: true)] protected $email; - /** - * @ORM\Column(type="string", nullable=true) - */ + #[ORM\Column(type: 'string', nullable: true)] protected $avatarUrl; /** @@ -116,9 +102,7 @@ public function setGravatar(bool $useGravatar = true) Gravatar::image($this->email, 200, "retro", "g", "png", false)->url(); } - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $isVerified; public function isVerified() @@ -131,9 +115,7 @@ public function setVerified($verified = true) $this->isVerified = $verified; } - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $isAllowed; public function isAllowed() @@ -141,9 +123,7 @@ public function isAllowed() return $this->isAllowed; } - /** - * @ORM\ManyToMany(targetEntity="Instance", inversedBy="members") - */ + #[ORM\ManyToMany(targetEntity: Instance::class, inversedBy: 'members')] protected $instances; public function belongsTo(Instance $instance) @@ -160,19 +140,13 @@ function (Instance $instance) { )->getValues(); } - /** - * @ORM\Column(type="datetime", nullable=true) - */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $tokenValidityThreshold; - /** - * @ORM\OneToOne(targetEntity="UserSettings", cascade={"persist"}) - */ + #[ORM\OneToOne(targetEntity: UserSettings::class, cascade: ['persist'])] protected $settings; - /** - * @ORM\OneToMany(targetEntity="GroupMembership", mappedBy="user", cascade={"all"}) - */ + #[ORM\OneToMany(targetEntity: GroupMembership::class, mappedBy: 'user', cascade: ['all'])] protected $memberships; protected function findMembership(Group $group, string $type) @@ -295,24 +269,16 @@ public function makeSupervisorOf(Group $group) $this->makeMemberOf($group, GroupMembership::TYPE_SUPERVISOR); } - /** - * @ORM\OneToMany(targetEntity="Exercise", mappedBy="author") - */ + #[ORM\OneToMany(targetEntity: Exercise::class, mappedBy: 'author')] protected $exercises; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $role; - /** - * @ORM\OneToMany(targetEntity="ExternalLogin", mappedBy="user", cascade={"all"}) - */ + #[ORM\OneToMany(targetEntity: ExternalLogin::class, mappedBy: 'user', cascade: ['all'])] protected $externalLogins; - /** - * @ORM\OneToOne(targetEntity="Login", mappedBy="user", cascade={"all"}) - */ + #[ORM\OneToOne(targetEntity: Login::class, mappedBy: 'user', cascade: ['all'])] protected $login; @@ -392,10 +358,10 @@ public function getConsolidatedExternalLogins(?array $filter = null) } /** - * @ORM\Column(type="datetime", nullable=true) * @var DateTime * When the last authentication or token renewal occurred. */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $lastAuthenticationAt = null; /** @@ -407,29 +373,26 @@ public function updateLastAuthenticationAt(?DateTime $time = null) $this->lastAuthenticationAt = $time ?? new DateTime(); } - /** - * @ORM\OneToOne(targetEntity="UserUiData", cascade={"persist", "remove"}, orphanRemoval=true) - */ + #[ORM\OneToOne(targetEntity: UserUiData::class, cascade: ['persist', 'remove'], orphanRemoval: true)] protected $uiData = null; /* * Additional security stuff, locking the user for one IP and/or one group. * This stuff is used when a student have an exam in particular group. */ - /** - * @ORM\Column(type="string", nullable=true) * IP address (either IPv4 or IPv6) the user is locked to. API requests from different addresses * will be treated as unauthorized. * @var string|null */ + #[ORM\Column(type: 'string', nullable: true)] protected $ipLock = null; /** - * @ORM\Column(type="datetime", nullable=true) * @var DateTime|null * When the current IP lock expires (null = never, or lock is not set). */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $ipLockExpiration = null; public function getIpLockRaw(): ?string @@ -498,25 +461,25 @@ public function verifyIpLock(string $currentIp): bool } /** - * @ORM\ManyToOne(targetEntity="Group") * If set, any user actions will be restricted to this group only. * (except for fundamental operations like listing groups or getting group name) * @var Group|null */ + #[ORM\ManyToOne(targetEntity: Group::class)] protected $groupLock = null; /** - * @ORM\Column(type="string") * String representation of the GroupExamLockType enum (copied from the group exam). * @var string */ + #[ORM\Column(type: 'string')] protected $groupLockType = GroupExamLockType::Visible->value; /** - * @ORM\Column(type="datetime", nullable=true) * @var DateTime|null * When the current group lock expires (null = never, or lock is not set). */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $groupLockExpiration = null; /** diff --git a/app/model/entity/UserCalendar.php b/app/model/entity/UserCalendar.php index 7ee2237f4..3d8841833 100644 --- a/app/model/entity/UserCalendar.php +++ b/app/model/entity/UserCalendar.php @@ -7,28 +7,24 @@ use JsonSerializable; /** - * @ORM\Entity * Entity holding information about iCal provider for user events. */ +#[ORM\Entity] class UserCalendar implements JsonSerializable { use CreatableEntity; - /** - * @ORM\Id - * @ORM\Column(type="string", length=32) - */ + #[ORM\Id] + #[ORM\Column(type: 'string', length: 32)] protected $id; - /** - * @ORM\ManyToOne(targetEntity="User") - */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $user; /** - * @ORM\Column(type="datetime", nullable=true) * @var DateTime|null */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $expiredAt = null; /** diff --git a/app/model/entity/UserSettings.php b/app/model/entity/UserSettings.php index a42154fe3..9896a3f16 100644 --- a/app/model/entity/UserSettings.php +++ b/app/model/entity/UserSettings.php @@ -5,9 +5,7 @@ use Doctrine\ORM\Mapping as ORM; use JsonSerializable; -/** - * @ORM\Entity - */ +#[ORM\Entity] class UserSettings implements JsonSerializable { use FlagAccessor; @@ -31,82 +29,55 @@ public function __construct(string $defaultLanguage = "en") } /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="string", length=32) - */ + #[ORM\Column(type: 'string', length: 32)] protected $defaultLanguage; /******************* * Emails settings * *******************/ - - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $newAssignmentEmails; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $assignmentDeadlineEmails; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $submissionEvaluatedEmails; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $solutionCommentsEmails; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $solutionReviewsEmails; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $assignmentCommentsEmails; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $pointsChangedEmails; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $assignmentSubmitAfterAcceptedEmails; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $assignmentSubmitAfterReviewedEmails; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $exerciseNotificationEmails; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $solutionAcceptedEmails = false; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $solutionReviewRequestedEmails = true; diff --git a/app/model/entity/UserUiData.php b/app/model/entity/UserUiData.php index 1190f8864..cd4a360f3 100644 --- a/app/model/entity/UserUiData.php +++ b/app/model/entity/UserUiData.php @@ -5,9 +5,9 @@ use Doctrine\ORM\Mapping as ORM; /** - * @ORM\Entity * Entity holding user-specific data stored by the UI. */ +#[ORM\Entity] class UserUiData { public function __construct($data) @@ -16,18 +16,18 @@ public function __construct($data) } /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; /** * Arbitrary user-specific JSON-structured data stored by the UI. - * @ORM\Column(type="text") */ + #[ORM\Column(type: 'text')] protected $data; /** diff --git a/app/model/entity/base/AssignmentBase.php b/app/model/entity/base/AssignmentBase.php index a82a1d80e..510e883d9 100644 --- a/app/model/entity/base/AssignmentBase.php +++ b/app/model/entity/base/AssignmentBase.php @@ -5,9 +5,7 @@ use Doctrine\ORM\Mapping as ORM; use Doctrine\Common\Collections\Collection; -/** - * @ORM\MappedSuperclass - */ +#[ORM\MappedSuperclass] abstract class AssignmentBase { use CreatableEntity; @@ -23,9 +21,7 @@ abstract public function getLocalizedTexts(): Collection; abstract public function getLocalizedTextByLocale(string $locale): ?LocalizedEntity; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $isPublic; public function isPublic(): bool @@ -33,9 +29,7 @@ public function isPublic(): bool return $this->isPublic; } - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $isBonus; public function isBonus(): bool diff --git a/app/model/entity/base/CreateableEntity.php b/app/model/entity/base/CreateableEntity.php index c0d4d7218..c86007fa0 100644 --- a/app/model/entity/base/CreateableEntity.php +++ b/app/model/entity/base/CreateableEntity.php @@ -8,9 +8,9 @@ trait CreatableEntity { /** - * @ORM\Column(type="datetime") * @var DateTime */ + #[ORM\Column(type: 'datetime')] protected $createdAt; public function getCreatedAt(): DateTime diff --git a/app/model/entity/base/DeleteableEntity.php b/app/model/entity/base/DeleteableEntity.php index d95f951b8..949ef0593 100644 --- a/app/model/entity/base/DeleteableEntity.php +++ b/app/model/entity/base/DeleteableEntity.php @@ -8,9 +8,9 @@ trait DeletableEntity { /** - * @ORM\Column(type="datetime", nullable=true) * @var DateTime */ + #[ORM\Column(type: 'datetime', nullable: true)] protected $deletedAt = null; public function getDeletedAt(): ?DateTime diff --git a/app/model/entity/base/ExerciseData.php b/app/model/entity/base/ExerciseData.php index cfce4433a..e86a3cd50 100644 --- a/app/model/entity/base/ExerciseData.php +++ b/app/model/entity/base/ExerciseData.php @@ -10,9 +10,7 @@ trait ExerciseData { - /** - * @ORM\Column(type="string", options={"default":"simpleExerciseConfig"}) - */ + #[ORM\Column(type: 'string', options: ['default' => 'simpleExerciseConfig'])] protected $configurationType; public function getConfigurationType(): string @@ -21,9 +19,9 @@ public function getConfigurationType(): string } /** - * @ORM\ManyToMany(targetEntity="LocalizedExercise", indexBy="locale") * @var Collection|Selectable */ + #[ORM\ManyToMany(targetEntity: LocalizedExercise::class, indexBy: 'locale')] protected $localizedTexts; public function getLocalizedTexts(): Collection @@ -63,9 +61,9 @@ public function getLocalizedTextByLocale(string $locale): ?LocalizedEntity } /** - * @ORM\ManyToMany(targetEntity="RuntimeEnvironment") * @var Collection */ + #[ORM\ManyToMany(targetEntity: RuntimeEnvironment::class)] protected $runtimeEnvironments; /** @@ -91,9 +89,9 @@ function (RuntimeEnvironment $environment) { } /** - * @ORM\ManyToMany(targetEntity="HardwareGroup") * @var Collection */ + #[ORM\ManyToMany(targetEntity: HardwareGroup::class)] protected $hardwareGroups; /** @@ -118,9 +116,9 @@ function (HardwareGroup $group) { } /** - * @ORM\ManyToMany(targetEntity="ExerciseLimits", cascade={"persist"}) * @var Collection */ + #[ORM\ManyToMany(targetEntity: ExerciseLimits::class, cascade: ['persist'])] protected $exerciseLimits; /** @@ -167,9 +165,9 @@ function (ExerciseLimits $exerciseLimits) use ($environment, $hwGroup) { } /** - * @ORM\ManyToMany(targetEntity="ExerciseEnvironmentConfig", cascade={"persist"}) * @var Collection|Selectable */ + #[ORM\ManyToMany(targetEntity: ExerciseEnvironmentConfig::class, cascade: ['persist'])] protected $exerciseEnvironmentConfigs; /** @@ -197,9 +195,7 @@ function (ExerciseEnvironmentConfig $runtimeConfig) use ($environment) { return $first === false ? null : $first; } - /** - * @ORM\ManyToOne(targetEntity="ExerciseConfig", cascade={"persist"}) - */ + #[ORM\ManyToOne(targetEntity: ExerciseConfig::class, cascade: ['persist'])] protected $exerciseConfig; public function getExerciseConfig(): ?ExerciseConfig @@ -207,9 +203,7 @@ public function getExerciseConfig(): ?ExerciseConfig return $this->exerciseConfig; } - /** - * @ORM\ManyToOne(targetEntity="ExerciseScoreConfig", cascade={"persist"}) - */ + #[ORM\ManyToOne(targetEntity: ExerciseScoreConfig::class, cascade: ['persist'])] protected $scoreConfig; public function getScoreConfig(): ExerciseScoreConfig @@ -218,9 +212,9 @@ public function getScoreConfig(): ExerciseScoreConfig } /** - * @ORM\ManyToMany(targetEntity="ExerciseTest", cascade={"persist"}) * @var Collection|Selectable */ + #[ORM\ManyToMany(targetEntity: ExerciseTest::class, cascade: ['persist'])] protected $exerciseTests; public function getExerciseTests(): Collection @@ -279,9 +273,9 @@ function (ExerciseTest $test) { } /** - * @ORM\ManyToMany(targetEntity="ExerciseFile") * @var Collection */ + #[ORM\ManyToMany(targetEntity: ExerciseFile::class)] protected $exerciseFiles; public function getExerciseFiles(): Collection @@ -327,9 +321,9 @@ public function getHashedExerciseFiles(): array } /** - * @ORM\ManyToMany(targetEntity="AttachmentFile") * @var Collection */ + #[ORM\ManyToMany(targetEntity: AttachmentFile::class)] protected $attachmentFiles; public function getAttachmentFiles(): Collection @@ -365,9 +359,9 @@ function (AttachmentFile $file) { } /** - * @ORM\Column(type="integer", nullable=true) * How many files may one submit in a solution. */ + #[ORM\Column(type: 'integer', nullable: true)] protected $solutionFilesLimit = null; public function getSolutionFilesLimit(): ?int @@ -381,9 +375,9 @@ public function setSolutionFilesLimit(?int $filesLimit) } /** - * @ORM\Column(type="integer", nullable=true) * Maximal allowed size (in bytes) of all files submitted for a solution. */ + #[ORM\Column(type: 'integer', nullable: true)] protected $solutionSizeLimit = null; public function getSolutionSizeLimit(): ?int diff --git a/app/model/entity/base/LocalizedEntity.php b/app/model/entity/base/LocalizedEntity.php index 799db31e2..86f875859 100644 --- a/app/model/entity/base/LocalizedEntity.php +++ b/app/model/entity/base/LocalizedEntity.php @@ -5,28 +5,22 @@ use DateTime; use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\MappedSuperclass - */ +#[ORM\MappedSuperclass] abstract class LocalizedEntity { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $createdAt; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string')] protected $locale; public function __construct(string $locale) diff --git a/app/model/entity/base/Submission.php b/app/model/entity/base/Submission.php index 25c40d1c7..76b0b6f58 100644 --- a/app/model/entity/base/Submission.php +++ b/app/model/entity/base/Submission.php @@ -7,28 +7,22 @@ use DateTime; use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\MappedSuperclass - */ +#[ORM\MappedSuperclass] abstract class Submission implements IEvaluable { /** - * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=\Ramsey\Uuid\Doctrine\UuidGenerator::class) * @var \Ramsey\Uuid\UuidInterface */ + #[ORM\Id] + #[ORM\Column(type: 'uuid', unique: true)] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\CustomIdGenerator(class: \Ramsey\Uuid\Doctrine\UuidGenerator::class)] protected $id; - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: 'datetime')] protected $submittedAt; - /** - * @ORM\ManyToOne(targetEntity="User") - */ + #[ORM\ManyToOne(targetEntity: User::class)] protected $submittedBy; public function getSubmittedBy(): ?User @@ -37,21 +31,19 @@ public function getSubmittedBy(): ?User } /** - * @ORM\OneToOne(targetEntity="SolutionEvaluation", cascade={"persist", "remove"}, fetch="EAGER") * @var SolutionEvaluation */ + #[ORM\OneToOne(targetEntity: SolutionEvaluation::class, cascade: ['persist', 'remove'], fetch: 'EAGER')] protected $evaluation; - /** - * @ORM\Column(type="boolean") - */ + #[ORM\Column(type: 'boolean')] protected $isDebug; /** - * @ORM\Column(type="string") * Bin subdirectory in paths to related files (job config, results zip). * The subdir names are typically time-related (e.g., YYYY-MM) to optimize backup management. */ + #[ORM\Column(type: 'string')] protected $subdir; diff --git a/app/model/entity/base/UpdateableEntity.php b/app/model/entity/base/UpdateableEntity.php index a2cef651d..4b7da8f04 100644 --- a/app/model/entity/base/UpdateableEntity.php +++ b/app/model/entity/base/UpdateableEntity.php @@ -8,9 +8,9 @@ trait UpdatableEntity { /** - * @ORM\Column(type="datetime") * @var DateTime */ + #[ORM\Column(type: 'datetime')] protected $updatedAt; public function getUpdatedAt(): DateTime diff --git a/app/model/entity/base/VersionableEntity.php b/app/model/entity/base/VersionableEntity.php index e51d1f1b2..baff7e08f 100644 --- a/app/model/entity/base/VersionableEntity.php +++ b/app/model/entity/base/VersionableEntity.php @@ -6,9 +6,7 @@ trait VersionableEntity { - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: 'integer')] protected $version = 1; public function getVersion(): int diff --git a/app/model/helpers/CustomCoalesceFunction.php b/app/model/helpers/CustomCoalesceFunction.php index cfdc4e4aa..e7f859a03 100644 --- a/app/model/helpers/CustomCoalesceFunction.php +++ b/app/model/helpers/CustomCoalesceFunction.php @@ -2,15 +2,16 @@ namespace DoctrineExtensions\Query\Functions; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\TokenType; use Doctrine\ORM\Query\AST\Functions\FunctionNode; +use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\Parser; /** - * "COALESCE_SUB" "(" "(" Subselect ")" {"," "(" Subselect ")" }* ")" + * "COALESCE_SUB" "(" "(" sub-select ")" {"," "(" sub-select ")" }* ")" * * This is actually a workaround since regular COALESCE statement does not - * support nested selects in DQL. This one expects only subselects. + * support nested selects in DQL. This one expects only sub-selects. * * Final SQL uses the same COALESCE function as the COALESCE statement in DQL. */ @@ -21,7 +22,7 @@ class CoalesceSubselectsFunction extends FunctionNode /** * @override */ - public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) + public function getSql(SqlWalker $sqlWalker): string { $platform = $sqlWalker->getConnection()->getDatabasePlatform(); @@ -37,7 +38,7 @@ public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) /** * @override */ - public function parse(\Doctrine\ORM\Query\Parser $parser) + public function parse(Parser $parser): void { $parser->match(TokenType::T_IDENTIFIER); $parser->match(TokenType::T_OPEN_PARENTHESIS); diff --git a/app/model/helpers/DqlTypeFunction.php b/app/model/helpers/DqlTypeFunction.php index 93acb8280..1ab2a6f8f 100644 --- a/app/model/helpers/DqlTypeFunction.php +++ b/app/model/helpers/DqlTypeFunction.php @@ -3,11 +3,10 @@ namespace DoctrineExtensions\Query\Functions; use Doctrine\ORM\Query\AST\Functions\FunctionNode; -use Doctrine\ORM\Query\Lexer; +use Doctrine\ORM\Query\TokenType; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\QueryException; use Doctrine\ORM\Query\SqlWalker; -use Doctrine\ORM\Query\TokenType; /** * Provides a way to access an entity's discriminator field in DQL @@ -46,10 +45,10 @@ class TypeFunction extends FunctionNode * @param SqlWalker $sqlWalker * @return string */ - public function getSql(SqlWalker $sqlWalker) + public function getSql(SqlWalker $sqlWalker): string { $qComp = $sqlWalker->getQueryComponent($this->dqlAlias); - /** @var \Doctrine\ORM\Mapping\ClassMetadataInfo $class */ + /** @var \Doctrine\ORM\Mapping\ClassMetadata */ $class = $qComp['metadata']; $tableAlias = $sqlWalker->getSQLTableAlias($class->getTableName(), $this->dqlAlias); @@ -65,7 +64,7 @@ public function getSql(SqlWalker $sqlWalker) /** * @param Parser $parser */ - public function parse(Parser $parser) + public function parse(Parser $parser): void { $parser->match(TokenType::T_IDENTIFIER); $parser->match(TokenType::T_OPEN_PARENTHESIS); diff --git a/app/model/helpers/OrderByCollationInjectionMysqlWalker.php b/app/model/helpers/OrderByCollationInjectionMysqlWalker.php index f36cd97ce..76d7d39cb 100644 --- a/app/model/helpers/OrderByCollationInjectionMysqlWalker.php +++ b/app/model/helpers/OrderByCollationInjectionMysqlWalker.php @@ -16,7 +16,7 @@ class OrderByCollationInjectionMysqlWalker extends SqlWalker public const HINT_COLLATION = 'orderByCollationInjectionMysqlWalker.collation'; public const HINT_COLLATION_FORBIDDEN_COLUMNS = 'orderByCollationInjectionMysqlWalker.forbiddenCols'; - private function isForbidden($orderByItemTokens) + private function isForbidden(array $orderByItemTokens) { $forbiddenColumns = $this->getQuery()->getHint(self::HINT_COLLATION_FORBIDDEN_COLUMNS); if ( @@ -33,14 +33,14 @@ private function isForbidden($orderByItemTokens) return false; } - public function walkOrderByItem($orderByItem) + public function walkOrderByItem($orderByItem): string { $sql = parent::walkOrderByItem($orderByItem); $collation = $this->getQuery()->getHint(self::HINT_COLLATION); $tokens = explode(' ', $sql); if ($collation && count($tokens) > 1 && !$this->isForbidden($tokens)) { - // 'colname ASC|DESC' => 'colname COLLATE colation ASC|DESC' + // 'col-name ASC|DESC' => 'col-name COLLATE collation ASC|DESC' $direction = array_pop($tokens); array_push($tokens, 'COLLATE', $collation, $direction); } diff --git a/app/model/helpers/UTCDateTimeType.php b/app/model/helpers/UTCDateTimeType.php index 3ce390124..bbf812f78 100644 --- a/app/model/helpers/UTCDateTimeType.php +++ b/app/model/helpers/UTCDateTimeType.php @@ -5,6 +5,9 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Types\ConversionException; use Doctrine\DBAL\Types\DateTimeType; +use DateTime; +use DateTimeImmutable; +use DateTimeZone; /** * Special type for storing and loading UTC datetime structures from database. @@ -16,35 +19,38 @@ class UTCDateTimeType extends DateTimeType private static function getUtc() { - return self::$utc ? self::$utc : self::$utc = new \DateTimeZone('UTC'); + return self::$utc ? self::$utc : self::$utc = new DateTimeZone('UTC'); } - public function convertToDatabaseValue($value, AbstractPlatform $platform) + public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string { - if ($value instanceof \DateTime) { + if ($value instanceof DateTimeImmutable) { + $value = DateTime::createFromImmutable($value); + } + if ($value instanceof DateTime) { $value->setTimezone(self::getUtc()); } return parent::convertToDatabaseValue($value, $platform); } - public function convertToPHPValue($value, AbstractPlatform $platform) + public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?DateTime { - if (null === $value || $value instanceof \DateTime) { + if (null === $value || $value instanceof DateTime) { return $value; } - $converted = \DateTime::createFromFormat( + $converted = DateTime::createFromFormat( $platform->getDateTimeFormatString(), $value, self::getUtc() ); if (!$converted) { - throw ConversionException::conversionFailedFormat( - $value, - $this->getName(), - $platform->getDateTimeFormatString() + $value = strlen($value) > 32 ? substr($value, 0, 20) . '...' : $value; + throw new ConversionException( + 'Could not convert database value "' . $value . '" to Doctrine Type datetime. Expected format: ' + . $platform->getDateTimeFormatString(), ); } diff --git a/app/model/repository/AssignmentSolutions.php b/app/model/repository/AssignmentSolutions.php index 4e1d502e7..90969a5b3 100644 --- a/app/model/repository/AssignmentSolutions.php +++ b/app/model/repository/AssignmentSolutions.php @@ -321,10 +321,9 @@ public function getSolutionStats(Assignment $assignment, User $user): array $conn = $this->em->getConnection(); $stmt = $conn->prepare($query); - return $stmt->executeQuery([ - 'assignmentId' => $assignment->getId(), - 'authorId' => $user->getId(), - ])->fetchAssociative(); + $stmt->bindValue('assignmentId', $assignment->getId()); + $stmt->bindValue('authorId', $user->getId()); + return $stmt->executeQuery()->fetchAssociative(); } /** diff --git a/app/model/repository/Assignments.php b/app/model/repository/Assignments.php index 1c7b2b9c7..869e999e2 100644 --- a/app/model/repository/Assignments.php +++ b/app/model/repository/Assignments.php @@ -61,14 +61,9 @@ public function findByDeadline(DateTime $from, DateTime $to): array ) ); - $qb->setParameters( - [ - "true" => true, - "from" => $from, - "to" => $to - ] - ); - + $qb->setParameter("true", true); + $qb->setParameter("from", $from); + $qb->setParameter("to", $to); return $qb->getQuery()->getResult(); } } diff --git a/app/model/repository/Comments.php b/app/model/repository/Comments.php index 2b1f2b5bc..a8c579b08 100644 --- a/app/model/repository/Comments.php +++ b/app/model/repository/Comments.php @@ -52,13 +52,8 @@ private function getCommentsCount(CommentThread $thread, User $user, bool $allVi $qb->andWhere('tc.user = :user'); } - $qb->setParameters( - [ - 'id' => $thread->getId(), - 'user' => $user->getId(), - ] - ); - + $qb->setParameter('id', $thread->getId()); + $qb->setParameter('user', $user->getId()); return (int)$qb->getQuery()->getSingleScalarResult(); } diff --git a/app/model/repository/Groups.php b/app/model/repository/Groups.php index ea160acc1..cdbce1fa9 100644 --- a/app/model/repository/Groups.php +++ b/app/model/repository/Groups.php @@ -69,13 +69,8 @@ public function findByName(string $locale, string $name, Instance $instance, ?Gr $textsQb->where($textsQb->expr()->eq("l.name", ":name")); $textsQb->andWhere($textsQb->expr()->eq("l.locale", ":locale")); - $textsQb->setParameters( - [ - "name" => $name, - "locale" => $locale - ] - ); - + $textsQb->setParameter("name", $name); + $textsQb->setParameter("locale", $locale); $texts = $textsQb->getQuery()->getResult(); if (count($texts) === 0) { @@ -113,7 +108,9 @@ public function findByName(string $locale, string $name, Instance $instance, ?Gr $groupsQb->andWhere($groupsQb->expr()->orX(...$criteria)); } - $groupsQb->setParameters($parameters); + foreach ($parameters as $key => $value) { + $groupsQb->setParameter($key, $value); + } return $groupsQb->getQuery()->getResult(); } diff --git a/app/model/repository/ShadowAssignments.php b/app/model/repository/ShadowAssignments.php index e82f7a123..8788d839e 100644 --- a/app/model/repository/ShadowAssignments.php +++ b/app/model/repository/ShadowAssignments.php @@ -33,7 +33,8 @@ public function findByDeadline(DateTime $from, DateTime $to): array ) ); - $qb->setParameters([ "from" => $from, "to" => $to ]); + $qb->setParameter("from", $from); + $qb->setParameter("to", $to); return $qb->getQuery()->getResult(); } } diff --git a/bin/async-worker b/bin/async-worker index 0c1188009..a57079828 100755 --- a/bin/async-worker +++ b/bin/async-worker @@ -1,5 +1,7 @@ #!/usr/bin/env php -createContainer() ->getByType(App\Async\Worker::class) - ->run($workerId)); + ->run($workerId); + +exit(0); diff --git a/composer.json b/composer.json index 0ccad8198..27ac6595e 100644 --- a/composer.json +++ b/composer.json @@ -26,11 +26,11 @@ } }, "require": { - "php": ">=8.3", + "php": ">=8.4", "bjeavons/zxcvbn-php": "^1.4", "contributte/console": "^0.11.0", "firebase/php-jwt": "^7.0", - "forxer/gravatar": "^5.0", + "forxer/gravatar": "^7.0", "guzzlehttp/guzzle": "^7.10", "eluceo/ical": "^2.16", "ext-yaml": ">=2.0", @@ -44,7 +44,6 @@ "nette/caching": "^3.4", "nette/database": "^3.2", "nette/di": "^3.2", - "nette/finder": "^3.0", "nette/forms": "^3.3", "nette/http": "^3.4", "nette/mail": "^4.0", @@ -53,12 +52,12 @@ "nette/safe-stream": "^3.0", "nette/security": "^3.2", "nette/utils": "^4.0", - "nettrine/dbal": "^0.9", - "nettrine/extensions-atlantic18": "^0.6.0", + "nettrine/dbal": "^0.10", + "nettrine/extensions-atlantic18": "^0.7", "nettrine/migrations": "^0.10", - "nettrine/orm": "^0.9", - "ramsey/uuid-doctrine": "^2.0", - "symfony/process": "^7.4", + "nettrine/orm": "^0.10", + "ramsey/uuid-doctrine": "^2.1", + "symfony/process": "^8.1", "tracy/tracy": "^2.11", "zircote/swagger-php": "^6.0" }, @@ -68,7 +67,8 @@ "nette/tester": "^2.6", "phpstan/phpstan": "^2.1", "phpstan/phpstan-nette": "^2.0", - "vrana/adminer": "^5.4" + "vrana/adminer": "^5.4", + "rector/rector": "^2.5" }, "minimum-stability": "dev", "prefer-stable": true diff --git a/composer.lock b/composer.lock index acb14d0f2..ddd77e616 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7d82ff187a7a3d32e06623520752b83c", + "content-hash": "d4516b3f633592cca4d1540e05395ce8", "packages": [ { "name": "bjeavons/zxcvbn-php", @@ -267,177 +267,6 @@ }, "time": "2024-07-08T12:26:09+00:00" }, - { - "name": "doctrine/annotations", - "version": "1.14.4", - "source": { - "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "253dca476f70808a5aeed3a47cc2cc88c5cab915" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/253dca476f70808a5aeed3a47cc2cc88c5cab915", - "reference": "253dca476f70808a5aeed3a47cc2cc88c5cab915", - "shasum": "" - }, - "require": { - "doctrine/lexer": "^1 || ^2", - "ext-tokenizer": "*", - "php": "^7.1 || ^8.0", - "psr/cache": "^1 || ^2 || ^3" - }, - "require-dev": { - "doctrine/cache": "^1.11 || ^2.0", - "doctrine/coding-standard": "^9 || ^12", - "phpstan/phpstan": "~1.4.10 || ^1.10.28", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "symfony/cache": "^4.4 || ^5.4 || ^6.4 || ^7", - "vimeo/psalm": "^4.30 || ^5.14" - }, - "suggest": { - "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Docblock Annotations Parser", - "homepage": "https://www.doctrine-project.org/projects/annotations.html", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "support": { - "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": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/cache.git", - "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", - "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", - "shasum": "" - }, - "require": { - "php": "~7.1 || ^8.0" - }, - "conflict": { - "doctrine/common": ">2.2,<2.4" - }, - "require-dev": { - "cache/integration-tests": "dev-master", - "doctrine/coding-standard": "^9", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psr/cache": "^1.0 || ^2.0 || ^3.0", - "symfony/cache": "^4.4 || ^5.4 || ^6", - "symfony/var-exporter": "^4.4 || ^5.4 || ^6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", - "homepage": "https://www.doctrine-project.org/projects/cache.html", - "keywords": [ - "abstraction", - "apcu", - "cache", - "caching", - "couchdb", - "memcached", - "php", - "redis", - "xcache" - ], - "support": { - "issues": "https://github.com/doctrine/cache/issues", - "source": "https://github.com/doctrine/cache/tree/2.2.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache", - "type": "tidelift" - } - ], - "abandoned": true, - "time": "2022-05-20T20:07:39+00:00" - }, { "name": "doctrine/collections", "version": "2.6.0", @@ -524,141 +353,42 @@ ], "time": "2026-01-15T10:01:58+00:00" }, - { - "name": "doctrine/common", - "version": "3.5.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/common.git", - "reference": "d9ea4a54ca2586db781f0265d36bea731ac66ec5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/d9ea4a54ca2586db781f0265d36bea731ac66ec5", - "reference": "d9ea4a54ca2586db781f0265d36bea731ac66ec5", - "shasum": "" - }, - "require": { - "doctrine/persistence": "^2.0 || ^3.0 || ^4.0", - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9.0 || ^10.0", - "doctrine/collections": "^1", - "phpstan/phpstan": "^1.4.1", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.0", - "squizlabs/php_codesniffer": "^3.0", - "symfony/phpunit-bridge": "^6.1", - "vimeo/psalm": "^4.4" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - }, - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - } - ], - "description": "PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, proxies and much more.", - "homepage": "https://www.doctrine-project.org/projects/common.html", - "keywords": [ - "common", - "doctrine", - "php" - ], - "support": { - "issues": "https://github.com/doctrine/common/issues", - "source": "https://github.com/doctrine/common/tree/3.5.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcommon", - "type": "tidelift" - } - ], - "time": "2025-01-01T22:12:03+00:00" - }, { "name": "doctrine/dbal", - "version": "3.10.5", + "version": "4.4.3", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "95d84866bf3c04b2ddca1df7c049714660959aef" + "reference": "61e730f1658814821a85f2402c945f3883407dec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/95d84866bf3c04b2ddca1df7c049714660959aef", - "reference": "95d84866bf3c04b2ddca1df7c049714660959aef", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/61e730f1658814821a85f2402c945f3883407dec", + "reference": "61e730f1658814821a85f2402c945f3883407dec", "shasum": "" }, "require": { - "composer-runtime-api": "^2", - "doctrine/deprecations": "^0.5.3|^1", - "doctrine/event-manager": "^1|^2", - "php": "^7.4 || ^8.0", + "doctrine/deprecations": "^1.1.5", + "php": "^8.2", "psr/cache": "^1|^2|^3", "psr/log": "^1|^2|^3" }, - "conflict": { - "doctrine/cache": "< 1.11" - }, "require-dev": { - "doctrine/cache": "^1.11|^2.0", "doctrine/coding-standard": "14.0.0", "fig/log-test": "^1", - "jetbrains/phpstorm-stubs": "2023.1", + "jetbrains/phpstorm-stubs": "2023.2", "phpstan/phpstan": "2.1.30", + "phpstan/phpstan-phpunit": "2.0.7", "phpstan/phpstan-strict-rules": "^2", - "phpunit/phpunit": "9.6.34", + "phpunit/phpunit": "11.5.50", "slevomat/coding-standard": "8.27.1", "squizlabs/php_codesniffer": "4.0.1", - "symfony/cache": "^5.4|^6.0|^7.0|^8.0", - "symfony/console": "^4.4|^5.4|^6.0|^7.0|^8.0" + "symfony/cache": "^6.3.8|^7.0|^8.0", + "symfony/console": "^5.4|^6.3|^7.0|^8.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." }, - "bin": [ - "bin/doctrine-dbal" - ], "type": "library", "autoload": { "psr-4": { @@ -711,7 +441,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.10.5" + "source": "https://github.com/doctrine/dbal/tree/4.4.3" }, "funding": [ { @@ -727,7 +457,7 @@ "type": "tidelift" } ], - "time": "2026-02-24T08:03:57+00:00" + "time": "2026-03-20T08:52:12+00:00" }, { "name": "doctrine/deprecations", @@ -1029,28 +759,27 @@ }, { "name": "doctrine/lexer", - "version": "2.1.1", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "861c870e8b75f7c8f69c146c7f89cc1c0f1b49b6" + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/861c870e8b75f7c8f69c146c7f89cc1c0f1b49b6", - "reference": "861c870e8b75f7c8f69c146c7f89cc1c0f1b49b6", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", "shasum": "" }, "require": { - "doctrine/deprecations": "^1.0", - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "require-dev": { - "doctrine/coding-standard": "^9 || ^12", - "phpstan/phpstan": "^1.3", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", "psalm/plugin-phpunit": "^0.18.3", - "vimeo/psalm": "^4.11 || ^5.21" + "vimeo/psalm": "^5.21" }, "type": "library", "autoload": { @@ -1087,7 +816,7 @@ ], "support": { "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/2.1.1" + "source": "https://github.com/doctrine/lexer/tree/3.0.1" }, "funding": [ { @@ -1103,7 +832,7 @@ "type": "tidelift" } ], - "time": "2024-02-05T11:35:39+00:00" + "time": "2024-02-05T11:56:58+00:00" }, { "name": "doctrine/migrations", @@ -1210,61 +939,48 @@ }, { "name": "doctrine/orm", - "version": "2.20.13", + "version": "3.6.7", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "f525f32e11efc60a34f5eecd88093f476c90f90e" + "reference": "bc217c0e19c3a9eadfa67697143b87c9ba01272c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/f525f32e11efc60a34f5eecd88093f476c90f90e", - "reference": "f525f32e11efc60a34f5eecd88093f476c90f90e", + "url": "https://api.github.com/repos/doctrine/orm/zipball/bc217c0e19c3a9eadfa67697143b87c9ba01272c", + "reference": "bc217c0e19c3a9eadfa67697143b87c9ba01272c", "shasum": "" }, "require": { "composer-runtime-api": "^2", - "doctrine/cache": "^1.12.1 || ^2.1.1", - "doctrine/collections": "^1.5 || ^2.1", - "doctrine/common": "^3.0.3", - "doctrine/dbal": "^2.13.1 || ^3.2", + "doctrine/collections": "^2.2", + "doctrine/dbal": "^3.8.2 || ^4", "doctrine/deprecations": "^0.5.3 || ^1", "doctrine/event-manager": "^1.2 || ^2", "doctrine/inflector": "^1.4 || ^2.0", "doctrine/instantiator": "^1.3 || ^2", - "doctrine/lexer": "^2 || ^3", - "doctrine/persistence": "^2.4 || ^3", + "doctrine/lexer": "^3", + "doctrine/persistence": "^3.3.1 || ^4", "ext-ctype": "*", - "php": "^7.1 || ^8.0", + "php": "^8.1", "psr/cache": "^1 || ^2 || ^3", - "symfony/console": "^4.2 || ^5.0 || ^6.0 || ^7.0 || ^8.0", - "symfony/polyfill-php72": "^1.23", - "symfony/polyfill-php80": "^1.16" - }, - "conflict": { - "doctrine/annotations": "<1.13 || >= 3.0" + "symfony/console": "^5.4 || ^6.0 || ^7.0 || ^8.0", + "symfony/var-exporter": "^6.3.9 || ^7.0 || ^8.0" }, "require-dev": { - "doctrine/annotations": "^1.13 || ^2", - "doctrine/coding-standard": "^9.0.2 || ^14.0", - "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/extension-installer": "~1.1.0 || ^1.4", - "phpstan/phpstan": "~1.4.10 || 2.1.23", - "phpstan/phpstan-deprecation-rules": "^1 || ^2", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", + "doctrine/coding-standard": "^14.0", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "2.1.23", + "phpstan/phpstan-deprecation-rules": "^2", + "phpunit/phpunit": "^10.5.0 || ^11.5", "psr/log": "^1 || ^2 || ^3", - "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 || ^8.0" + "symfony/cache": "^5.4 || ^6.2 || ^7.0 || ^8.0" }, "suggest": { "ext-dom": "Provides support for XSD validation for XML mapping files", - "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0", - "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" + "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0" }, - "bin": [ - "bin/doctrine" - ], "type": "library", "autoload": { "psr-4": { @@ -1305,40 +1021,38 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.20.13" + "source": "https://github.com/doctrine/orm/tree/3.6.7" }, - "time": "2026-05-25T05:46:05+00:00" + "time": "2026-05-25T16:45:47+00:00" }, { "name": "doctrine/persistence", - "version": "3.4.5", + "version": "4.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "703a29d8597336fb75f42eeabcdf3f2863156ca8" + "reference": "49ab73e0d3e2ac8d1f5ecda3dd8acd5503781e8b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/703a29d8597336fb75f42eeabcdf3f2863156ca8", - "reference": "703a29d8597336fb75f42eeabcdf3f2863156ca8", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/49ab73e0d3e2ac8d1f5ecda3dd8acd5503781e8b", + "reference": "49ab73e0d3e2ac8d1f5ecda3dd8acd5503781e8b", "shasum": "" }, "require": { + "doctrine/deprecations": "^1", "doctrine/event-manager": "^1 || ^2", - "php": "^7.2 || ^8.0", + "php": "^8.1", "psr/cache": "^1.0 || ^2.0 || ^3.0" }, - "conflict": { - "doctrine/common": "<2.10" - }, "require-dev": { - "doctrine/coding-standard": "^12 || ^14", - "doctrine/common": "^3.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" + "doctrine/coding-standard": "^14", + "phpstan/phpstan": "2.1.30", + "phpstan/phpstan-phpunit": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^10.5.58 || ^12", + "symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0 || ^8.0", + "symfony/finder": "^4.4 || ^5.4 || ^6.0 || ^7.0 || ^8.0" }, "type": "library", "autoload": { @@ -1387,7 +1101,7 @@ ], "support": { "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/3.4.5" + "source": "https://github.com/doctrine/persistence/tree/4.2.0" }, "funding": [ { @@ -1403,20 +1117,20 @@ "type": "tidelift" } ], - "time": "2026-06-13T19:29:35+00:00" + "time": "2026-04-26T12:12:52+00:00" }, { "name": "eluceo/ical", - "version": "2.16.0", + "version": "2.17.0", "source": { "type": "git", "url": "https://github.com/markuspoerschke/iCal.git", - "reference": "4bdc085e14d0a213d7b387a80793320e4f45d430" + "reference": "562c723163e19209cdf4ee018579f58b8ec8d78b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/markuspoerschke/iCal/zipball/4bdc085e14d0a213d7b387a80793320e4f45d430", - "reference": "4bdc085e14d0a213d7b387a80793320e4f45d430", + "url": "https://api.github.com/repos/markuspoerschke/iCal/zipball/562c723163e19209cdf4ee018579f58b8ec8d78b", + "reference": "562c723163e19209cdf4ee018579f58b8ec8d78b", "shasum": "" }, "require": { @@ -1463,7 +1177,7 @@ "issues": "https://github.com/markuspoerschke/iCal/issues", "source": "https://github.com/markuspoerschke/iCal" }, - "time": "2026-01-07T21:34:08+00:00" + "time": "2026-07-12T22:10:28+00:00" }, { "name": "fakerphp/faker", @@ -1596,24 +1310,26 @@ }, { "name": "forxer/gravatar", - "version": "5.3.0", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/forxer/gravatar.git", - "reference": "db92e2c531bc0a73db0f7a85f86e7bba15bb1960" + "reference": "1d4b07fc326a5d2a28622302638222449363afc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/forxer/gravatar/zipball/db92e2c531bc0a73db0f7a85f86e7bba15bb1960", - "reference": "db92e2c531bc0a73db0f7a85f86e7bba15bb1960", + "url": "https://api.github.com/repos/forxer/gravatar/zipball/1d4b07fc326a5d2a28622302638222449363afc1", + "reference": "1d4b07fc326a5d2a28622302638222449363afc1", "shasum": "" }, "require": { - "php": "^8.2" + "php": "^8.4" }, "require-dev": { - "laravel/pint": "^1.25.1", - "rector/rector": "^2.2.8" + "laravel/pint": "^1.29.0", + "pestphp/pest": "*", + "phpstan/phpstan": "^2.1", + "rector/rector": "^2.3.9" }, "type": "library", "autoload": { @@ -1640,9 +1356,9 @@ "support": { "email": "forxer@gmail.com", "issues": "https://github.com/forxer/gravatar/issues", - "source": "https://github.com/forxer/gravatar/tree/5.3.0" + "source": "https://github.com/forxer/gravatar/tree/7.0.0" }, - "time": "2025-11-15T09:06:06+00:00" + "time": "2026-03-22T06:29:06+00:00" }, { "name": "gedmo/doctrine-extensions", @@ -1778,22 +1494,22 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.13.1", + "version": "7.15.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "55901a76dfd2006a0cc012b9e3c5b487f796478d" + "reference": "90bd104afeb0fcc2190c9eb6fd8a441447e4b30d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/55901a76dfd2006a0cc012b9e3c5b487f796478d", - "reference": "55901a76dfd2006a0cc012b9e3c5b487f796478d", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/90bd104afeb0fcc2190c9eb6fd8a441447e4b30d", + "reference": "90bd104afeb0fcc2190c9eb6fd8a441447e4b30d", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^2.5", - "guzzlehttp/psr7": "^2.12.3", + "guzzlehttp/promises": "^2.5.1", + "guzzlehttp/psr7": "^2.13", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.5 || ^3.0", @@ -1805,8 +1521,8 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", - "guzzle/client-integration-tests": "3.0.2", - "guzzlehttp/test-server": "^0.6", + "guzzle/client-integration-tests": "3.0.3", + "guzzlehttp/test-server": "^0.7", "php-http/message-factory": "^1.1", "phpunit/phpunit": "^8.5.52 || ^9.6.34", "psr/log": "^1.1 || ^2.0 || ^3.0" @@ -1886,7 +1602,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.13.1" + "source": "https://github.com/guzzle/guzzle/tree/7.15.0" }, "funding": [ { @@ -1902,20 +1618,20 @@ "type": "tidelift" } ], - "time": "2026-06-29T20:14:18+00:00" + "time": "2026-07-17T12:26:48+00:00" }, { "name": "guzzlehttp/promises", - "version": "2.5.0", + "version": "2.5.1", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "4360e982f87f5f258bf872d094647791db2f4c8e" + "reference": "9ad1e4fc607446a055b95870c7f668e93b5cff29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/4360e982f87f5f258bf872d094647791db2f4c8e", - "reference": "4360e982f87f5f258bf872d094647791db2f4c8e", + "url": "https://api.github.com/repos/guzzle/promises/zipball/9ad1e4fc607446a055b95870c7f668e93b5cff29", + "reference": "9ad1e4fc607446a055b95870c7f668e93b5cff29", "shasum": "" }, "require": { @@ -1970,7 +1686,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.5.0" + "source": "https://github.com/guzzle/promises/tree/2.5.1" }, "funding": [ { @@ -1986,20 +1702,20 @@ "type": "tidelift" } ], - "time": "2026-06-02T12:23:43+00:00" + "time": "2026-07-08T15:48:39+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.12.3", + "version": "2.13.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "7ec62dc3f44aa218487dbed81a9bf9bc647be55d" + "reference": "dad89620b7a6edb60c15858442eb2e408b45d8f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/7ec62dc3f44aa218487dbed81a9bf9bc647be55d", - "reference": "7ec62dc3f44aa218487dbed81a9bf9bc647be55d", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/dad89620b7a6edb60c15858442eb2e408b45d8f4", + "reference": "dad89620b7a6edb60c15858442eb2e408b45d8f4", "shasum": "" }, "require": { @@ -2089,7 +1805,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.12.3" + "source": "https://github.com/guzzle/psr7/tree/2.13.0" }, "funding": [ { @@ -2105,7 +1821,7 @@ "type": "tidelift" } ], - "time": "2026-06-23T15:21:08+00:00" + "time": "2026-07-16T22:23:49+00:00" }, { "name": "latte/latte", @@ -2200,16 +1916,16 @@ }, { "name": "league/commonmark", - "version": "2.8.2", + "version": "2.8.3", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "59fb075d2101740c337c7216e3f32b36c204218b" + "reference": "1902f60f984235023acbe03db6ad614a37b3c3e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/59fb075d2101740c337c7216e3f32b36c204218b", - "reference": "59fb075d2101740c337c7216e3f32b36c204218b", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/1902f60f984235023acbe03db6ad614a37b3c3e7", + "reference": "1902f60f984235023acbe03db6ad614a37b3c3e7", "shasum": "" }, "require": { @@ -2231,8 +1947,8 @@ "github/gfm": "0.29.0", "michelf/php-markdown": "^1.4 || ^2.0", "nyholm/psr7": "^1.5", - "phpstan/phpstan": "^1.8.2", - "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", + "phpstan/phpstan": "^2.0.0", + "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0 || ^12.0.0 || ^13.0.0", "scrutinizer/ocular": "^1.8.1", "symfony/finder": "^5.3 | ^6.0 | ^7.0 || ^8.0", "symfony/process": "^5.4 | ^6.0 | ^7.0 || ^8.0", @@ -2303,7 +2019,7 @@ "type": "tidelift" } ], - "time": "2026-03-19T13:16:38+00:00" + "time": "2026-07-12T15:29:16+00:00" }, { "name": "league/config", @@ -3034,60 +2750,6 @@ }, "time": "2026-05-06T02:17:57+00:00" }, - { - "name": "nette/finder", - "version": "v3.0.0", - "source": { - "type": "git", - "url": "https://github.com/nette/finder.git", - "reference": "027395c638637de95c8e9fad49a7c51249404ed2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/finder/zipball/027395c638637de95c8e9fad49a7c51249404ed2", - "reference": "027395c638637de95c8e9fad49a7c51249404ed2", - "shasum": "" - }, - "require": { - "nette/utils": "^4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🔍 Nette Finder: find files and directories with an intuitive API.", - "homepage": "https://nette.org", - "keywords": [ - "filesystem", - "glob", - "iterator", - "nette" - ], - "support": { - "issues": "https://github.com/nette/finder/issues", - "source": "https://github.com/nette/finder/tree/v3.0.0" - }, - "abandoned": true, - "time": "2022-12-14T17:05:54+00:00" - }, { "name": "nette/forms", "version": "v3.3.0", @@ -3920,188 +3582,42 @@ }, "time": "2026-05-11T20:49:54+00:00" }, - { - "name": "nettrine/annotations", - "version": "v0.8.1", - "source": { - "type": "git", - "url": "https://github.com/contributte/doctrine-annotations.git", - "reference": "d284d9108f335ca2c9a9ee2ec16bebfbaabf0b35" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/contributte/doctrine-annotations/zipball/d284d9108f335ca2c9a9ee2ec16bebfbaabf0b35", - "reference": "d284d9108f335ca2c9a9ee2ec16bebfbaabf0b35", - "shasum": "" - }, - "require": { - "doctrine/annotations": "^1.6.1", - "nette/di": "^3.1.2", - "nettrine/cache": "^0.4.0 || ^0.5.0", - "php": ">=8.1" - }, - "require-dev": { - "contributte/phpstan": "^0.1", - "contributte/qa": "^0.4", - "contributte/tester": "^0.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.9.x-dev" - } - }, - "autoload": { - "psr-4": { - "Nettrine\\Annotations\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Milan Felix Šulc", - "homepage": "https://f3l1x.io" - } - ], - "description": "Doctrine Annotations for Nette Framework", - "homepage": "https://github.com/contributte/doctrine-annotations", - "keywords": [ - "annotations", - "doctrine", - "nette", - "nettrine" - ], - "support": { - "issues": "https://github.com/contributte/doctrine-annotations/issues", - "source": "https://github.com/contributte/doctrine-annotations/tree/v0.8.1" - }, - "funding": [ - { - "url": "https://contributte.org/partners.html", - "type": "custom" - }, - { - "url": "https://github.com/f3l1x", - "type": "github" - } - ], - "time": "2023-07-03T16:12:16+00:00" - }, - { - "name": "nettrine/cache", - "version": "v0.5.0", - "source": { - "type": "git", - "url": "https://github.com/contributte/doctrine-cache.git", - "reference": "85223ef25e1dd4e35471405aed254e9da983e4a3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/contributte/doctrine-cache/zipball/85223ef25e1dd4e35471405aed254e9da983e4a3", - "reference": "85223ef25e1dd4e35471405aed254e9da983e4a3", - "shasum": "" - }, - "require": { - "doctrine/cache": "^2.2.0", - "nette/di": "^3.2.4", - "php": ">=8.2", - "symfony/cache": "^7.2.1" - }, - "require-dev": { - "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.6.x-dev" - } - }, - "autoload": { - "psr-4": { - "Nettrine\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Milan Felix Šulc", - "homepage": "https://f3l1x.io" - } - ], - "description": "Doctrine Cache for Nette Framework", - "homepage": "https://github.com/contributte/doctrine-cache", - "keywords": [ - "cache", - "doctrine", - "nette", - "nettrine" - ], - "support": { - "issues": "https://github.com/contributte/doctrine-cache/issues", - "source": "https://github.com/contributte/doctrine-cache/tree/v0.5.0" - }, - "funding": [ - { - "url": "https://contributte.org/partners.html", - "type": "custom" - }, - { - "url": "https://github.com/f3l1x", - "type": "github" - } - ], - "abandoned": "symfony/cache", - "time": "2025-01-10T17:33:34+00:00" - }, { "name": "nettrine/dbal", - "version": "v0.9.0", + "version": "v0.10.3", "source": { "type": "git", "url": "https://github.com/contributte/doctrine-dbal.git", - "reference": "15bd7770b098edb6c47909990506bdd7f6449d49" + "reference": "b9858c27f6571956e8f5a9a78fc3f810dac25e88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/contributte/doctrine-dbal/zipball/15bd7770b098edb6c47909990506bdd7f6449d49", - "reference": "15bd7770b098edb6c47909990506bdd7f6449d49", + "url": "https://api.github.com/repos/contributte/doctrine-dbal/zipball/b9858c27f6571956e8f5a9a78fc3f810dac25e88", + "reference": "b9858c27f6571956e8f5a9a78fc3f810dac25e88", "shasum": "" }, "require": { - "doctrine/dbal": "^3.6.7", + "doctrine/dbal": "^4.2.1", "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" + "php": ">=8.2", + "psr/cache": "^3.0.0", + "psr/log": "^3.0" }, "require-dev": { "contributte/console": "^0.10.1", - "contributte/phpstan": "^0.1", - "contributte/qa": "^0.4", - "contributte/tester": "^0.3", + "contributte/phpstan": "^0.2.0", + "contributte/qa": "^0.4.0", + "contributte/tester": "^0.3.0", "ext-pdo": "*", "mockery/mockery": "^1.3.5", - "nettrine/orm": "^0.9.0", - "psr/log": "^3.0", + "monolog/monolog": "^3.8.0", + "symfony/cache": "^7.1.9", "tracy/tracy": "^2.10.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "0.9.x-dev" + "dev-master": "0.11.x-dev" } }, "autoload": { @@ -4132,7 +3648,7 @@ ], "support": { "issues": "https://github.com/contributte/doctrine-dbal/issues", - "source": "https://github.com/contributte/doctrine-dbal/tree/v0.9.0" + "source": "https://github.com/contributte/doctrine-dbal/tree/v0.10.3" }, "funding": [ { @@ -4144,37 +3660,37 @@ "type": "github" } ], - "time": "2024-07-22T07:03:27+00:00" + "time": "2026-01-02T19:10:30+00:00" }, { "name": "nettrine/extensions-atlantic18", - "version": "v0.6.0", + "version": "v0.7.1", "source": { "type": "git", "url": "https://github.com/contributte/doctrine-extensions-atlantic18.git", - "reference": "14c1812da3a430e36cb9bcbb4c19c9e502a4e58f" + "reference": "95a635150d45544fd2ba4ce917ad41d7afaf3824" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/contributte/doctrine-extensions-atlantic18/zipball/14c1812da3a430e36cb9bcbb4c19c9e502a4e58f", - "reference": "14c1812da3a430e36cb9bcbb4c19c9e502a4e58f", + "url": "https://api.github.com/repos/contributte/doctrine-extensions-atlantic18/zipball/95a635150d45544fd2ba4ce917ad41d7afaf3824", + "reference": "95a635150d45544fd2ba4ce917ad41d7afaf3824", "shasum": "" }, "require": { - "doctrine/annotations": "^1.6.0", - "doctrine/orm": "^2.8.0", - "gedmo/doctrine-extensions": "^3.0.3", - "nette/di": "^3.0.0", - "php": ">=7.2" + "doctrine/orm": "^3.3.0", + "gedmo/doctrine-extensions": "^3.22.0", + "nette/di": "^3.2.0", + "php": ">=8.2" }, "require-dev": { - "nettrine/orm": "^0.8.0", - "ninjify/nunjuck": "^0.4", - "ninjify/qa": "^0.12", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-deprecation-rules": "^0.12", - "phpstan/phpstan-nette": "^0.12", - "phpstan/phpstan-strict-rules": "^0.12" + "contributte/phpstan": "^0.2.0", + "contributte/qa": "^0.4.0", + "contributte/tester": "^0.3.0", + "nettrine/dbal": "^0.10.3", + "nettrine/orm": "^0.10.1", + "symfony/cache": "^7.2.0", + "symfony/translation-contracts": "^3.5.0", + "symfony/var-exporter": "^7.2.0" }, "type": "library", "extra": { @@ -4198,16 +3714,17 @@ } ], "description": "Doctrine2 behavioral extensions for Nette Framework", - "homepage": "https://github.com/nettrine/extensions-atlantic18", + "homepage": "https://github.com/contributte/doctrine-extensions-atlantic18", "keywords": [ "database", "doctrine", + "gedmo", "nette", "orm" ], "support": { "issues": "https://github.com/contributte/doctrine-extensions-atlantic18/issues", - "source": "https://github.com/contributte/doctrine-extensions-atlantic18/tree/v0.6.0" + "source": "https://github.com/contributte/doctrine-extensions-atlantic18/tree/v0.7.1" }, "funding": [ { @@ -4219,7 +3736,7 @@ "type": "github" } ], - "time": "2021-01-28T08:33:18+00:00" + "time": "2026-01-07T08:20:59+00:00" }, { "name": "nettrine/migrations", @@ -4295,44 +3812,44 @@ }, { "name": "nettrine/orm", - "version": "v0.9.0", + "version": "v0.10.1", "source": { "type": "git", "url": "https://github.com/contributte/doctrine-orm.git", - "reference": "f3afa2cf045259e1f4c996a693643510656ff95c" + "reference": "480480c92b0d2f35165fa3e478584cef60fac394" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/contributte/doctrine-orm/zipball/f3afa2cf045259e1f4c996a693643510656ff95c", - "reference": "f3afa2cf045259e1f4c996a693643510656ff95c", + "url": "https://api.github.com/repos/contributte/doctrine-orm/zipball/480480c92b0d2f35165fa3e478584cef60fac394", + "reference": "480480c92b0d2f35165fa3e478584cef60fac394", "shasum": "" }, "require": { - "doctrine/common": "^3.4.3", - "doctrine/orm": "^2.14.0", + "doctrine/orm": "^3.3.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 " + "nettrine/dbal": "^0.10.2 || ^0.11.0", + "php": ">=8.2", + "psr/cache": "^3.0.0", + "psr/log": "^3.0.2" }, "conflict": { - "doctrine/persistence": "<3.0.0", - "nette/di": "<3.0.6", - "nette/schema": "<1.1.0" + "doctrine/event-manager": "<2.0.0" }, "require-dev": { - "contributte/phpstan": "^0.1", + "contributte/phpstan": "^0.2.0", "contributte/qa": "^0.4", - "contributte/tester": "^0.3", - "mockery/mockery": "^1.3.1", + "contributte/tester": "^0.3.0", + "mockery/mockery": "^1.6.12", + "monolog/monolog": "^3.8.0", + "symfony/cache": "^7.1.9", + "symfony/console": "^7.1.8 ", + "symfony/var-exporter": "^7.0", "tracy/tracy": "^2.10.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "0.9.x-dev" + "dev-master": "0.11.x-dev" } }, "autoload": { @@ -4360,7 +3877,7 @@ ], "support": { "issues": "https://github.com/contributte/doctrine-orm/issues", - "source": "https://github.com/contributte/doctrine-orm/tree/v0.9.0" + "source": "https://github.com/contributte/doctrine-orm/tree/v0.10.1" }, "funding": [ { @@ -4372,7 +3889,7 @@ "type": "github" } ], - "time": "2024-08-20T09:11:52+00:00" + "time": "2026-01-06T16:53:40+00:00" }, { "name": "nikic/php-parser", @@ -4433,16 +3950,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "2.3.2", + "version": "2.3.3", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a" + "reference": "fb19eedd2bb67ff8cf7a5502ad329e701d6398a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a004701b11273a26cd7955a61d67a7f1e525a45a", - "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fb19eedd2bb67ff8cf7a5502ad329e701d6398a3", + "reference": "fb19eedd2bb67ff8cf7a5502ad329e701d6398a3", "shasum": "" }, "require": { @@ -4474,9 +3991,9 @@ "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.2" + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.3" }, - "time": "2026-01-25T14:56:51+00:00" + "time": "2026-07-08T07:01:06+00:00" }, { "name": "psr/cache", @@ -5405,16 +4922,16 @@ }, { "name": "sebastian/exporter", - "version": "8.1.0", + "version": "8.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "c0d29a945f8cf82f300a05e69874508e307ca4c6" + "reference": "cfaa77c750dcad6f44c9bac8f62ac486e1c82c26" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c0d29a945f8cf82f300a05e69874508e307ca4c6", - "reference": "c0d29a945f8cf82f300a05e69874508e307ca4c6", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/cfaa77c750dcad6f44c9bac8f62ac486e1c82c26", + "reference": "cfaa77c750dcad6f44c9bac8f62ac486e1c82c26", "shasum": "" }, "require": { @@ -5423,7 +4940,7 @@ "sebastian/recursion-context": "^8.0" }, "require-dev": { - "phpunit/phpunit": "^13.1.10" + "phpunit/phpunit": "^13.2.4" }, "type": "library", "extra": { @@ -5471,7 +4988,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/8.1.0" + "source": "https://github.com/sebastianbergmann/exporter/tree/8.1.1" }, "funding": [ { @@ -5491,7 +5008,7 @@ "type": "tidelift" } ], - "time": "2026-05-21T11:50:56+00:00" + "time": "2026-07-13T11:35:11+00:00" }, { "name": "sebastian/recursion-context", @@ -5571,34 +5088,29 @@ }, { "name": "symfony/cache", - "version": "v7.4.14", + "version": "v8.1.1", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "9adfcb2a7fc3924473b09f5a0b058dcc2cc7be9a" + "reference": "c14decc1b0755b1e8ab6babeef56e1880348e817" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/9adfcb2a7fc3924473b09f5a0b058dcc2cc7be9a", - "reference": "9adfcb2a7fc3924473b09f5a0b058dcc2cc7be9a", + "url": "https://api.github.com/repos/symfony/cache/zipball/c14decc1b0755b1e8ab6babeef56e1880348e817", + "reference": "c14decc1b0755b1e8ab6babeef56e1880348e817", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.4.1", "psr/cache": "^2.0|^3.0", "psr/log": "^1.1|^2|^3", "symfony/cache-contracts": "^3.6", - "symfony/deprecation-contracts": "^2.5|^3", "symfony/service-contracts": "^2.5|^3", - "symfony/var-exporter": "^6.4|^7.0|^8.0" + "symfony/var-exporter": "^8.1" }, "conflict": { - "doctrine/dbal": "<3.6", "ext-redis": "<6.1", - "ext-relay": "<0.12.1", - "symfony/dependency-injection": "<6.4", - "symfony/http-kernel": "<6.4", - "symfony/var-dumper": "<6.4" + "ext-relay": "<0.12.1" }, "provide": { "psr/cache-implementation": "2.0|3.0", @@ -5607,16 +5119,16 @@ }, "require-dev": { "cache/integration-tests": "dev-master", - "doctrine/dbal": "^3.6|^4", + "doctrine/dbal": "^4.3", "predis/predis": "^1.1|^2.0", "psr/simple-cache": "^1.0|^2.0|^3.0", - "symfony/clock": "^6.4|^7.0|^8.0", - "symfony/config": "^6.4|^7.0|^8.0", - "symfony/dependency-injection": "^6.4|^7.0|^8.0", - "symfony/filesystem": "^6.4|^7.0|^8.0", - "symfony/http-kernel": "^6.4|^7.0|^8.0", - "symfony/messenger": "^6.4|^7.0|^8.0", - "symfony/var-dumper": "^6.4|^7.0|^8.0" + "symfony/clock": "^7.4|^8.0", + "symfony/config": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/filesystem": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/messenger": "^7.4|^8.0", + "symfony/var-dumper": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -5651,7 +5163,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v7.4.14" + "source": "https://github.com/symfony/cache/tree/v8.1.1" }, "funding": [ { @@ -5671,7 +5183,7 @@ "type": "tidelift" } ], - "time": "2026-06-17T14:44:48+00:00" + "time": "2026-06-17T15:04:37+00:00" }, { "name": "symfony/cache-contracts", @@ -5755,47 +5267,49 @@ }, { "name": "symfony/console", - "version": "v7.4.14", + "version": "v8.1.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "92f58bc4bf97a92ed1b9f367f0cd44f20bde0e87" + "reference": "b711a8ab808b6c074c6b8caef70d0fd8d6b6d07d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/92f58bc4bf97a92ed1b9f367f0cd44f20bde0e87", - "reference": "92f58bc4bf97a92ed1b9f367f0cd44f20bde0e87", + "url": "https://api.github.com/repos/symfony/console/zipball/b711a8ab808b6c074c6b8caef70d0fd8d6b6d07d", + "reference": "b711a8ab808b6c074c6b8caef70d0fd8d6b6d07d", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.4.1", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/polyfill-php85": "^1.32", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^7.2|^8.0" + "symfony/string": "^7.4.6|^8.0.6" }, "conflict": { - "symfony/dependency-injection": "<6.4", - "symfony/dotenv": "<6.4", - "symfony/event-dispatcher": "<6.4", - "symfony/lock": "<6.4", - "symfony/process": "<6.4" + "symfony/dependency-injection": "<8.1", + "symfony/event-dispatcher": "<8.1" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0|^8.0", - "symfony/dependency-injection": "^6.4|^7.0|^8.0", - "symfony/event-dispatcher": "^6.4|^7.0|^8.0", - "symfony/http-foundation": "^6.4|^7.0|^8.0", - "symfony/http-kernel": "^6.4|^7.0|^8.0", - "symfony/lock": "^6.4|^7.0|^8.0", - "symfony/messenger": "^6.4|^7.0|^8.0", - "symfony/process": "^6.4|^7.0|^8.0", - "symfony/stopwatch": "^6.4|^7.0|^8.0", - "symfony/var-dumper": "^6.4|^7.0|^8.0" + "symfony/config": "^7.4|^8.0", + "symfony/dependency-injection": "^8.1", + "symfony/event-dispatcher": "^8.1", + "symfony/filesystem": "^7.4|^8.0", + "symfony/http-foundation": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/lock": "^7.4|^8.0", + "symfony/messenger": "^7.4|^8.0", + "symfony/mime": "^7.4|^8.0", + "symfony/process": "^7.4|^8.0", + "symfony/stopwatch": "^7.4|^8.0", + "symfony/uid": "^7.4|^8.0", + "symfony/validator": "^7.4|^8.0", + "symfony/var-dumper": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -5829,7 +5343,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.4.14" + "source": "https://github.com/symfony/console/tree/v8.1.1" }, "funding": [ { @@ -5849,7 +5363,7 @@ "type": "tidelift" } ], - "time": "2026-06-16T11:50:14+00:00" + "time": "2026-06-16T12:55:20+00:00" }, { "name": "symfony/deprecation-contracts", @@ -6413,34 +5927,49 @@ "time": "2026-05-27T06:59:30+00:00" }, { - "name": "symfony/polyfill-php72", - "version": "v1.31.0", + "name": "symfony/polyfill-php80", + "version": "v1.37.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce" + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce", - "reference": "fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", "shasum": "" }, "require": { "php": ">=7.2" }, - "type": "metapackage", + "type": "library", "extra": { "thanks": { "url": "https://github.com/symfony/polyfill", "name": "symfony/polyfill" } }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, { "name": "Nicolas Grekas", "email": "p@tchwork.com" @@ -6450,7 +5979,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", @@ -6459,7 +5988,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0" }, "funding": [ { @@ -6470,25 +5999,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-09T11:45:10+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { - "name": "symfony/polyfill-php80", - "version": "v1.37.0", + "name": "symfony/polyfill-php84", + "version": "v1.38.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" + "url": "https://github.com/symfony/polyfill-php84.git", + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", - "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", "shasum": "" }, "require": { @@ -6506,7 +6039,7 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" + "Symfony\\Polyfill\\Php84\\": "" }, "classmap": [ "Resources/stubs" @@ -6517,10 +6050,6 @@ "MIT" ], "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, { "name": "Nicolas Grekas", "email": "p@tchwork.com" @@ -6530,7 +6059,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", @@ -6539,7 +6068,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.38.1" }, "funding": [ { @@ -6559,20 +6088,20 @@ "type": "tidelift" } ], - "time": "2026-04-10T16:19:22+00:00" + "time": "2026-05-26T12:51:13+00:00" }, { - "name": "symfony/polyfill-php84", + "name": "symfony/polyfill-php85", "version": "v1.38.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa" + "url": "https://github.com/symfony/polyfill-php85.git", + "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", - "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", + "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", "shasum": "" }, "require": { @@ -6590,7 +6119,7 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Php84\\": "" + "Symfony\\Polyfill\\Php85\\": "" }, "classmap": [ "Resources/stubs" @@ -6610,7 +6139,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", + "description": "Symfony polyfill backporting some PHP 8.5+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", @@ -6619,7 +6148,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.38.1" + "source": "https://github.com/symfony/polyfill-php85/tree/v1.38.1" }, "funding": [ { @@ -6639,24 +6168,24 @@ "type": "tidelift" } ], - "time": "2026-05-26T12:51:13+00:00" + "time": "2026-05-26T02:25:22+00:00" }, { "name": "symfony/process", - "version": "v7.4.13", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "f5804be144caceb570f6747519999636b664f24c" + "reference": "c4a9e58f235a6bf7f97ffbfedae2687353ac79e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/f5804be144caceb570f6747519999636b664f24c", - "reference": "f5804be144caceb570f6747519999636b664f24c", + "url": "https://api.github.com/repos/symfony/process/zipball/c4a9e58f235a6bf7f97ffbfedae2687353ac79e5", + "reference": "c4a9e58f235a6bf7f97ffbfedae2687353ac79e5", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.4.1" }, "type": "library", "autoload": { @@ -6684,7 +6213,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.4.13" + "source": "https://github.com/symfony/process/tree/v8.1.0" }, "funding": [ { @@ -6704,7 +6233,7 @@ "type": "tidelift" } ], - "time": "2026-05-23T16:05:06+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/property-access", @@ -7439,16 +6968,16 @@ }, { "name": "zircote/swagger-php", - "version": "6.3.0", + "version": "6.4.0", "source": { "type": "git", "url": "https://github.com/zircote/swagger-php.git", - "reference": "90aa94ef8a321bc343fe025048c0071b88c188f5" + "reference": "d2006242dae81ae8833ad9a0ffb74e3254654cff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zircote/swagger-php/zipball/90aa94ef8a321bc343fe025048c0071b88c188f5", - "reference": "90aa94ef8a321bc343fe025048c0071b88c188f5", + "url": "https://api.github.com/repos/zircote/swagger-php/zipball/d2006242dae81ae8833ad9a0ffb74e3254654cff", + "reference": "d2006242dae81ae8833ad9a0ffb74e3254654cff", "shasum": "" }, "require": { @@ -7466,7 +6995,6 @@ "symfony/process": ">=6, <6.4.14" }, "require-dev": { - "composer/package-versions-deprecated": "^1.11", "doctrine/annotations": "^2.0", "friendsofphp/php-cs-fixer": "^3.62.0", "phpstan/phpstan": "^2.0", @@ -7517,7 +7045,7 @@ ], "support": { "issues": "https://github.com/zircote/swagger-php/issues", - "source": "https://github.com/zircote/swagger-php/tree/6.3.0" + "source": "https://github.com/zircote/swagger-php/tree/6.4.0" }, "funding": [ { @@ -7525,7 +7053,7 @@ "type": "github" } ], - "time": "2026-06-29T08:44:04+00:00" + "time": "2026-07-12T03:44:54+00:00" } ], "packages-dev": [ @@ -7920,18 +7448,78 @@ }, "time": "2026-07-02T10:28:46+00:00" }, + { + "name": "rector/rector", + "version": "2.5.7", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "ba22f8c087848278fed6b4910d4cf1108096d8d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/ba22f8c087848278fed6b4910d4cf1108096d8d3", + "reference": "ba22f8c087848278fed6b4910d4cf1108096d8d3", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0", + "phpstan/phpstan": "^2.2.2" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "suggest": { + "ext-dom": "To manipulate phpunit.xml via the custom-rule command" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "homepage": "https://getrector.com/", + "keywords": [ + "automation", + "dev", + "migration", + "refactoring" + ], + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/2.5.7" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2026-07-13T15:24:18+00:00" + }, { "name": "vrana/adminer", - "version": "v5.4.2", + "version": "v5.5.0", "source": { "type": "git", "url": "https://github.com/vrana/adminer.git", - "reference": "39b339b1b551d2cc100893047fac2498a83d8407" + "reference": "94dc72bba68fdb6e981abca35bafd315a7e776eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vrana/adminer/zipball/39b339b1b551d2cc100893047fac2498a83d8407", - "reference": "39b339b1b551d2cc100893047fac2498a83d8407", + "url": "https://api.github.com/repos/vrana/adminer/zipball/94dc72bba68fdb6e981abca35bafd315a7e776eb", + "reference": "94dc72bba68fdb6e981abca35bafd315a7e776eb", "shasum": "" }, "require": { @@ -7982,7 +7570,7 @@ "type": "patreon" } ], - "time": "2026-02-08T15:44:05+00:00" + "time": "2026-07-17T13:02:10+00:00" } ], "aliases": [], @@ -7994,7 +7582,7 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": ">=8.3", + "php": ">=8.4", "ext-yaml": ">=2.0", "ext-json": ">=1.7", "ext-zip": ">=1.15" diff --git a/migrations/Version20260717180905.php b/migrations/Version20260717180905.php new file mode 100644 index 000000000..1ce99a2ab --- /dev/null +++ b/migrations/Version20260717180905.php @@ -0,0 +1,193 @@ +addSql('ALTER TABLE assignment CHANGE id id CHAR(36) NOT NULL, CHANGE exercise_config_id exercise_config_id CHAR(36) DEFAULT NULL, CHANGE exercise_id exercise_id CHAR(36) DEFAULT NULL, CHANGE group_id group_id CHAR(36) DEFAULT NULL, CHANGE is_public is_public TINYINT NOT NULL, CHANGE is_bonus is_bonus TINYINT NOT NULL, CHANGE allow_second_deadline allow_second_deadline TINYINT NOT NULL, CHANGE can_view_limit_ratios can_view_limit_ratios TINYINT NOT NULL, CHANGE visible_from visible_from DATETIME DEFAULT NULL, CHANGE can_view_judge_stdout can_view_judge_stdout TINYINT NOT NULL, CHANGE score_config_id score_config_id CHAR(36) DEFAULT NULL, CHANGE can_view_judge_stderr can_view_judge_stderr TINYINT NOT NULL, CHANGE merge_judge_logs merge_judge_logs TINYINT NOT NULL, CHANGE plagiarism_batch_id plagiarism_batch_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE assignment_localized_assignment CHANGE assignment_id assignment_id CHAR(36) NOT NULL, CHANGE localized_assignment_id localized_assignment_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE assignment_disabled_runtime_environments CHANGE assignment_id assignment_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE assignment_localized_exercise CHANGE assignment_id assignment_id CHAR(36) NOT NULL, CHANGE localized_exercise_id localized_exercise_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE assignment_runtime_environment CHANGE assignment_id assignment_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE assignment_hardware_group CHANGE assignment_id assignment_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE assignment_exercise_limits CHANGE assignment_id assignment_id CHAR(36) NOT NULL, CHANGE exercise_limits_id exercise_limits_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE assignment_exercise_environment_config CHANGE assignment_id assignment_id CHAR(36) NOT NULL, CHANGE exercise_environment_config_id exercise_environment_config_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE assignment_exercise_test CHANGE assignment_id assignment_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE assignment_exercise_file CHANGE assignment_id assignment_id CHAR(36) NOT NULL, CHANGE exercise_file_id exercise_file_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE assignment_attachment_file CHANGE assignment_id assignment_id CHAR(36) NOT NULL, CHANGE attachment_file_id attachment_file_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE assignment_solution CHANGE id id CHAR(36) NOT NULL, CHANGE assignment_id assignment_id CHAR(36) DEFAULT NULL, CHANGE solution_id solution_id CHAR(36) DEFAULT NULL, CHANGE accepted accepted TINYINT NOT NULL, CHANGE last_submission_id last_submission_id CHAR(36) DEFAULT NULL, CHANGE plagiarism_batch_id plagiarism_batch_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE assignment_solution_submission CHANGE id id CHAR(36) NOT NULL, CHANGE assignment_solution_id assignment_solution_id CHAR(36) DEFAULT NULL, CHANGE evaluation_id evaluation_id CHAR(36) DEFAULT NULL, CHANGE submitted_by_id submitted_by_id CHAR(36) DEFAULT NULL, CHANGE submitted_at submitted_at DATETIME NOT NULL, CHANGE is_debug is_debug TINYINT NOT NULL, CHANGE failure_id failure_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE assignment_solver CHANGE id id CHAR(36) NOT NULL, CHANGE assignment_id assignment_id CHAR(36) DEFAULT NULL, CHANGE solver_id solver_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE async_job CHANGE id id CHAR(36) NOT NULL, CHANGE created_by_id created_by_id CHAR(36) DEFAULT NULL, CHANGE associated_assignment_id associated_assignment_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE comment CHANGE id id CHAR(36) NOT NULL, CHANGE user_id user_id CHAR(36) DEFAULT NULL, CHANGE is_private is_private TINYINT NOT NULL'); + $this->addSql('ALTER TABLE exercise CHANGE id id CHAR(36) NOT NULL, CHANGE exercise_id exercise_id CHAR(36) DEFAULT NULL, CHANGE author_id author_id CHAR(36) DEFAULT NULL, CHANGE exercise_config_id exercise_config_id CHAR(36) DEFAULT NULL, CHANGE is_public is_public TINYINT NOT NULL, CHANGE is_locked is_locked TINYINT NOT NULL, CHANGE is_broken is_broken TINYINT DEFAULT 0 NOT NULL, CHANGE score_config_id score_config_id CHAR(36) DEFAULT NULL, CHANGE merge_judge_logs merge_judge_logs TINYINT NOT NULL'); + $this->addSql('ALTER TABLE exercise_runtime_environment CHANGE exercise_id exercise_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE exercise_user CHANGE exercise_id exercise_id CHAR(36) NOT NULL, CHANGE user_id user_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE exercise_group CHANGE exercise_id exercise_id CHAR(36) NOT NULL, CHANGE group_id group_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE exercise_localized_exercise CHANGE exercise_id exercise_id CHAR(36) NOT NULL, CHANGE localized_exercise_id localized_exercise_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE exercise_hardware_group CHANGE exercise_id exercise_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE exercise_exercise_limits CHANGE exercise_id exercise_id CHAR(36) NOT NULL, CHANGE exercise_limits_id exercise_limits_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE exercise_exercise_environment_config CHANGE exercise_id exercise_id CHAR(36) NOT NULL, CHANGE exercise_environment_config_id exercise_environment_config_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE exercise_exercise_test CHANGE exercise_id exercise_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE exercise_exercise_file CHANGE exercise_id exercise_id CHAR(36) NOT NULL, CHANGE exercise_file_id exercise_file_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE exercise_attachment_file CHANGE exercise_id exercise_id CHAR(36) NOT NULL, CHANGE attachment_file_id attachment_file_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE exercise_config CHANGE id id CHAR(36) NOT NULL, CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL, CHANGE author_id author_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE exercise_environment_config CHANGE id id CHAR(36) NOT NULL, CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL, CHANGE author_id author_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE exercise_file_link CHANGE id id CHAR(36) NOT NULL, CHANGE exercise_file_id exercise_file_id CHAR(36) DEFAULT NULL, CHANGE exercise_id exercise_id CHAR(36) DEFAULT NULL, CHANGE assignment_id assignment_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE exercise_limits CHANGE id id CHAR(36) NOT NULL, CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL, CHANGE author_id author_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE exercise_score_config CHANGE id id CHAR(36) NOT NULL, CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL, CHANGE created_at created_at DATETIME NOT NULL'); + $this->addSql('ALTER TABLE exercise_tag CHANGE author_id author_id CHAR(36) DEFAULT NULL, CHANGE exercise_id exercise_id CHAR(36) DEFAULT NULL, CHANGE created_at created_at DATETIME NOT NULL'); + $this->addSql('ALTER TABLE exercise_test CHANGE author_id author_id CHAR(36) DEFAULT NULL, CHANGE created_at created_at DATETIME NOT NULL, CHANGE updated_at updated_at DATETIME NOT NULL'); + $this->addSql('ALTER TABLE external_login CHANGE id id CHAR(36) NOT NULL, CHANGE user_id user_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE forgotten_password CHANGE id id CHAR(36) NOT NULL, CHANGE user_id user_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE `group` CHANGE id id CHAR(36) NOT NULL, CHANGE parent_group_id parent_group_id CHAR(36) DEFAULT NULL, CHANGE instance_id instance_id CHAR(36) DEFAULT NULL, CHANGE public_stats public_stats TINYINT NOT NULL, CHANGE is_public is_public TINYINT NOT NULL, CHANGE is_organizational is_organizational TINYINT DEFAULT 0 NOT NULL, CHANGE is_detaining is_detaining TINYINT DEFAULT 0 NOT NULL'); + $this->addSql('ALTER TABLE group_exam CHANGE group_id group_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE group_exam_lock CHANGE student_id student_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE group_external_attribute CHANGE id id CHAR(36) NOT NULL, CHANGE group_id group_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE group_invitation CHANGE id id CHAR(36) NOT NULL, CHANGE group_id group_id CHAR(36) DEFAULT NULL, CHANGE host_id host_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE group_membership CHANGE id id CHAR(36) NOT NULL, CHANGE user_id user_id CHAR(36) DEFAULT NULL, CHANGE group_id group_id CHAR(36) DEFAULT NULL, CHANGE inherited_from_id inherited_from_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE instance CHANGE id id CHAR(36) NOT NULL, CHANGE admin_id admin_id CHAR(36) DEFAULT NULL, CHANGE root_group_id root_group_id CHAR(36) DEFAULT NULL, CHANGE is_open is_open TINYINT NOT NULL, CHANGE is_allowed is_allowed TINYINT NOT NULL, CHANGE needs_licence needs_licence TINYINT NOT NULL'); + $this->addSql('ALTER TABLE licence CHANGE id id CHAR(36) NOT NULL, CHANGE instance_id instance_id CHAR(36) DEFAULT NULL, CHANGE is_valid is_valid TINYINT NOT NULL'); + $this->addSql('ALTER TABLE localized_assignment CHANGE id id CHAR(36) NOT NULL, CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL, CHANGE created_at created_at DATETIME NOT NULL'); + $this->addSql('ALTER TABLE localized_exercise CHANGE id id CHAR(36) NOT NULL, CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE localized_group CHANGE id id CHAR(36) NOT NULL, CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL, CHANGE group_id group_id CHAR(36) DEFAULT NULL, CHANGE created_at created_at DATETIME NOT NULL'); + $this->addSql('ALTER TABLE localized_notification CHANGE id id CHAR(36) NOT NULL, CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL, CHANGE created_at created_at DATETIME NOT NULL'); + $this->addSql('ALTER TABLE localized_shadow_assignment CHANGE id id CHAR(36) NOT NULL, CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL, CHANGE created_at created_at DATETIME NOT NULL'); + $this->addSql('ALTER TABLE login CHANGE id id CHAR(36) NOT NULL, CHANGE user_id user_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE notification CHANGE id id CHAR(36) NOT NULL, CHANGE author_id author_id CHAR(36) DEFAULT NULL, CHANGE created_at created_at DATETIME NOT NULL, CHANGE visible_from visible_from DATETIME NOT NULL, CHANGE visible_to visible_to DATETIME NOT NULL'); + $this->addSql('ALTER TABLE notification_localized_notification CHANGE notification_id notification_id CHAR(36) NOT NULL, CHANGE localized_notification_id localized_notification_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE notification_group CHANGE notification_id notification_id CHAR(36) NOT NULL, CHANGE group_id group_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE pipeline CHANGE id id CHAR(36) NOT NULL, CHANGE pipeline_config_id pipeline_config_id CHAR(36) DEFAULT NULL, CHANGE author_id author_id CHAR(36) DEFAULT NULL, CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE pipeline_exercise_file CHANGE pipeline_id pipeline_id CHAR(36) NOT NULL, CHANGE exercise_file_id exercise_file_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE pipeline_runtime_environment CHANGE pipeline_id pipeline_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE pipeline_config CHANGE id id CHAR(36) NOT NULL, CHANGE author_id author_id CHAR(36) DEFAULT NULL, CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE pipeline_parameter CHANGE id id CHAR(36) NOT NULL, CHANGE pipeline_id pipeline_id CHAR(36) DEFAULT NULL, CHANGE boolean_value boolean_value TINYINT DEFAULT NULL'); + $this->addSql('ALTER TABLE plagiarism_detected_similar_file CHANGE id id CHAR(36) NOT NULL, CHANGE detected_similarity_id detected_similarity_id CHAR(36) DEFAULT NULL, CHANGE solution_id solution_id CHAR(36) DEFAULT NULL, CHANGE solution_file_id solution_file_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE plagiarism_detected_similarity CHANGE id id CHAR(36) NOT NULL, CHANGE batch_id batch_id CHAR(36) DEFAULT NULL, CHANGE author_id author_id CHAR(36) DEFAULT NULL, CHANGE tested_solution_id tested_solution_id CHAR(36) DEFAULT NULL, CHANGE solution_file_id solution_file_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE plagiarism_detection_batch CHANGE id id CHAR(36) NOT NULL, CHANGE supervisor_id supervisor_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE reference_exercise_solution CHANGE id id CHAR(36) NOT NULL, CHANGE exercise_id exercise_id CHAR(36) DEFAULT NULL, CHANGE solution_id solution_id CHAR(36) DEFAULT NULL, CHANGE last_submission_id last_submission_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE reference_solution_submission CHANGE id id CHAR(36) NOT NULL, CHANGE reference_solution_id reference_solution_id CHAR(36) DEFAULT NULL, CHANGE evaluation_id evaluation_id CHAR(36) DEFAULT NULL, CHANGE submitted_by_id submitted_by_id CHAR(36) DEFAULT NULL, CHANGE submitted_at submitted_at DATETIME NOT NULL, CHANGE is_debug is_debug TINYINT NOT NULL, CHANGE failure_id failure_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE reported_errors CHANGE id id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE review_comment CHANGE id id CHAR(36) NOT NULL, CHANGE solution_id solution_id CHAR(36) DEFAULT NULL, CHANGE author_id author_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE security_event CHANGE user_id user_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE shadow_assignment CHANGE id id CHAR(36) NOT NULL, CHANGE group_id group_id CHAR(36) DEFAULT NULL, CHANGE is_public is_public TINYINT NOT NULL, CHANGE is_bonus is_bonus TINYINT NOT NULL, CHANGE created_at created_at DATETIME NOT NULL, CHANGE updated_at updated_at DATETIME NOT NULL, CHANGE deleted_at deleted_at DATETIME DEFAULT NULL'); + $this->addSql('ALTER TABLE shadow_assignment_localized_shadow_assignment CHANGE shadow_assignment_id shadow_assignment_id CHAR(36) NOT NULL, CHANGE localized_shadow_assignment_id localized_shadow_assignment_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE shadow_assignment_points CHANGE id id CHAR(36) NOT NULL, CHANGE shadow_assignment_id shadow_assignment_id CHAR(36) DEFAULT NULL, CHANGE author_id author_id CHAR(36) DEFAULT NULL, CHANGE awardee_id awardee_id CHAR(36) DEFAULT NULL, CHANGE created_at created_at DATETIME NOT NULL, CHANGE awarded_at awarded_at DATETIME DEFAULT NULL, CHANGE updated_at updated_at DATETIME NOT NULL'); + $this->addSql('ALTER TABLE sis_group_binding CHANGE id id CHAR(36) NOT NULL, CHANGE group_id group_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE sis_valid_term CHANGE id id CHAR(36) NOT NULL, CHANGE beginning beginning DATETIME DEFAULT NULL, CHANGE end end DATETIME DEFAULT NULL, CHANGE advertise_until advertise_until DATETIME DEFAULT NULL'); + $this->addSql('ALTER TABLE solution CHANGE id id CHAR(36) NOT NULL, CHANGE author_id author_id CHAR(36) DEFAULT NULL, CHANGE evaluated evaluated TINYINT NOT NULL, CHANGE created_at created_at DATETIME NOT NULL'); + $this->addSql('ALTER TABLE solution_evaluation CHANGE id id CHAR(36) NOT NULL, CHANGE init_failed init_failed TINYINT NOT NULL, CHANGE score_config_id score_config_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE submission_failure CHANGE id id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE test_result CHANGE solution_evaluation_id solution_evaluation_id CHAR(36) DEFAULT NULL, CHANGE memory_exceeded memory_exceeded TINYINT NOT NULL, CHANGE wall_time_exceeded wall_time_exceeded TINYINT NOT NULL, CHANGE cpu_time_exceeded cpu_time_exceeded TINYINT NOT NULL'); + $this->addSql('ALTER TABLE uploaded_file CHANGE id id CHAR(36) NOT NULL, CHANGE user_id user_id CHAR(36) DEFAULT NULL, CHANGE solution_id solution_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE uploaded_partial_file CHANGE id id CHAR(36) NOT NULL, CHANGE user_id user_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE user CHANGE id id CHAR(36) NOT NULL, CHANGE settings_id settings_id CHAR(36) DEFAULT NULL, CHANGE is_verified is_verified TINYINT NOT NULL, CHANGE is_allowed is_allowed TINYINT NOT NULL, CHANGE token_validity_threshold token_validity_threshold DATETIME DEFAULT NULL, CHANGE last_authentication_at last_authentication_at DATETIME DEFAULT NULL, CHANGE ui_data_id ui_data_id CHAR(36) DEFAULT NULL, CHANGE group_lock_id group_lock_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE user_instance CHANGE user_id user_id CHAR(36) NOT NULL, CHANGE instance_id instance_id CHAR(36) NOT NULL'); + $this->addSql('ALTER TABLE user_calendar CHANGE user_id user_id CHAR(36) DEFAULT NULL'); + $this->addSql('ALTER TABLE user_settings CHANGE id id CHAR(36) NOT NULL, CHANGE new_assignment_emails new_assignment_emails TINYINT NOT NULL, CHANGE assignment_deadline_emails assignment_deadline_emails TINYINT NOT NULL, CHANGE submission_evaluated_emails submission_evaluated_emails TINYINT NOT NULL, CHANGE solution_comments_emails solution_comments_emails TINYINT NOT NULL, CHANGE points_changed_emails points_changed_emails TINYINT NOT NULL, CHANGE assignment_submit_after_accepted_emails assignment_submit_after_accepted_emails TINYINT NOT NULL, CHANGE assignment_submit_after_reviewed_emails assignment_submit_after_reviewed_emails TINYINT NOT NULL, CHANGE assignment_comments_emails assignment_comments_emails TINYINT NOT NULL'); + $this->addSql('ALTER TABLE user_ui_data CHANGE id id CHAR(36) NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE assignment CHANGE is_public is_public TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE is_bonus is_bonus TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE visible_from visible_from DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime)\', CHANGE allow_second_deadline allow_second_deadline TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE can_view_limit_ratios can_view_limit_ratios TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE can_view_judge_stdout can_view_judge_stdout TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE can_view_judge_stderr can_view_judge_stderr TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE merge_judge_logs merge_judge_logs TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE exercise_id exercise_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE group_id group_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE plagiarism_batch_id plagiarism_batch_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE exercise_config_id exercise_config_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE score_config_id score_config_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE assignment_attachment_file CHANGE assignment_id assignment_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE attachment_file_id attachment_file_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE assignment_disabled_runtime_environments CHANGE assignment_id assignment_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE assignment_exercise_environment_config CHANGE assignment_id assignment_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE exercise_environment_config_id exercise_environment_config_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE assignment_exercise_file CHANGE assignment_id assignment_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE exercise_file_id exercise_file_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE assignment_exercise_limits CHANGE assignment_id assignment_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE exercise_limits_id exercise_limits_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE assignment_exercise_test CHANGE assignment_id assignment_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE assignment_hardware_group CHANGE assignment_id assignment_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE assignment_localized_assignment CHANGE assignment_id assignment_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE localized_assignment_id localized_assignment_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE assignment_localized_exercise CHANGE assignment_id assignment_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE localized_exercise_id localized_exercise_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE assignment_runtime_environment CHANGE assignment_id assignment_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE assignment_solution CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE accepted accepted TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE assignment_id assignment_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE solution_id solution_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE last_submission_id last_submission_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE plagiarism_batch_id plagiarism_batch_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE assignment_solution_submission CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE submitted_at submitted_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE is_debug is_debug TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE submitted_by_id submitted_by_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE evaluation_id evaluation_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE assignment_solution_id assignment_solution_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE failure_id failure_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE assignment_solver CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE assignment_id assignment_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE solver_id solver_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE async_job CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE created_by_id created_by_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE associated_assignment_id associated_assignment_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE comment CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE is_private is_private TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE user_id user_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE is_public is_public TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE is_locked is_locked TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE is_broken is_broken TINYINT DEFAULT 0 NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE merge_judge_logs merge_judge_logs TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE exercise_id exercise_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE author_id author_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE exercise_config_id exercise_config_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE score_config_id score_config_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_attachment_file CHANGE exercise_id exercise_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE attachment_file_id attachment_file_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_config CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE author_id author_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_environment_config CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE author_id author_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_exercise_environment_config CHANGE exercise_id exercise_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE exercise_environment_config_id exercise_environment_config_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_exercise_file CHANGE exercise_id exercise_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE exercise_file_id exercise_file_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_exercise_limits CHANGE exercise_id exercise_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE exercise_limits_id exercise_limits_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_exercise_test CHANGE exercise_id exercise_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_file_link CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE exercise_file_id exercise_file_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE exercise_id exercise_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE assignment_id assignment_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_group CHANGE exercise_id exercise_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE group_id group_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_hardware_group CHANGE exercise_id exercise_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_limits CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE author_id author_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_localized_exercise CHANGE exercise_id exercise_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE localized_exercise_id localized_exercise_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_runtime_environment CHANGE exercise_id exercise_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_score_config CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE created_at created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_tag CHANGE created_at created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE author_id author_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE exercise_id exercise_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_test CHANGE created_at created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE updated_at updated_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE author_id author_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE exercise_user CHANGE exercise_id exercise_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE user_id user_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE external_login CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE user_id user_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE forgotten_password CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE user_id user_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE `group` CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE public_stats public_stats TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE is_public is_public TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE is_organizational is_organizational TINYINT DEFAULT 0 NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE is_detaining is_detaining TINYINT DEFAULT 0 NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE parent_group_id parent_group_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE instance_id instance_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE group_exam CHANGE group_id group_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE group_exam_lock CHANGE student_id student_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE group_external_attribute CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE group_id group_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE group_invitation CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE group_id group_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE host_id host_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE group_membership CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE user_id user_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE group_id group_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE inherited_from_id inherited_from_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE instance CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE is_open is_open TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE is_allowed is_allowed TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE needs_licence needs_licence TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE admin_id admin_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE root_group_id root_group_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE licence CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE is_valid is_valid TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE instance_id instance_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE localized_assignment CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE created_at created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE localized_exercise CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE localized_group CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE created_at created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE group_id group_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE localized_notification CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE created_at created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE localized_shadow_assignment CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE created_at created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE login CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE user_id user_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE notification CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE visible_from visible_from DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE visible_to visible_to DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE created_at created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE author_id author_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE notification_group CHANGE notification_id notification_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE group_id group_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE notification_localized_notification CHANGE notification_id notification_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE localized_notification_id localized_notification_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE pipeline CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE pipeline_config_id pipeline_config_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE author_id author_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE pipeline_config CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE author_id author_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE created_from_id created_from_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE pipeline_exercise_file CHANGE pipeline_id pipeline_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE exercise_file_id exercise_file_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE pipeline_parameter CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE pipeline_id pipeline_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE boolean_value boolean_value TINYINT DEFAULT NULL COMMENT \'(DC2Type:boolean)\''); + $this->addSql('ALTER TABLE pipeline_runtime_environment CHANGE pipeline_id pipeline_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE plagiarism_detected_similarity CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE batch_id batch_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE author_id author_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE tested_solution_id tested_solution_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE solution_file_id solution_file_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE plagiarism_detected_similar_file CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE detected_similarity_id detected_similarity_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE solution_id solution_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE solution_file_id solution_file_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE plagiarism_detection_batch CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE supervisor_id supervisor_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE reference_exercise_solution CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE exercise_id exercise_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE solution_id solution_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE last_submission_id last_submission_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE reference_solution_submission CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE submitted_at submitted_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE is_debug is_debug TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE submitted_by_id submitted_by_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE evaluation_id evaluation_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE reference_solution_id reference_solution_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE failure_id failure_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE reported_errors CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE review_comment CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE solution_id solution_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE author_id author_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE security_event CHANGE user_id user_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE shadow_assignment CHANGE is_public is_public TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE is_bonus is_bonus TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE created_at created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE updated_at updated_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE deleted_at deleted_at DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime)\', CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE group_id group_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE shadow_assignment_localized_shadow_assignment CHANGE shadow_assignment_id shadow_assignment_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE localized_shadow_assignment_id localized_shadow_assignment_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE shadow_assignment_points CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE awarded_at awarded_at DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime)\', CHANGE created_at created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE updated_at updated_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE shadow_assignment_id shadow_assignment_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE author_id author_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE awardee_id awardee_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE sis_group_binding CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE group_id group_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE sis_valid_term CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE beginning beginning DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime)\', CHANGE end end DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime)\', CHANGE advertise_until advertise_until DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime)\''); + $this->addSql('ALTER TABLE solution CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE evaluated evaluated TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE created_at created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', CHANGE author_id author_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE solution_evaluation CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE init_failed init_failed TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE score_config_id score_config_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE submission_failure CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE test_result CHANGE memory_exceeded memory_exceeded TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE wall_time_exceeded wall_time_exceeded TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE cpu_time_exceeded cpu_time_exceeded TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE solution_evaluation_id solution_evaluation_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE `uploaded_file` CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE user_id user_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE solution_id solution_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE uploaded_partial_file CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE user_id user_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE user CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE is_verified is_verified TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE is_allowed is_allowed TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE token_validity_threshold token_validity_threshold DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime)\', CHANGE last_authentication_at last_authentication_at DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime)\', CHANGE settings_id settings_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE ui_data_id ui_data_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\', CHANGE group_lock_id group_lock_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE user_calendar CHANGE user_id user_id CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE user_instance CHANGE user_id user_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE instance_id instance_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + $this->addSql('ALTER TABLE user_settings CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', CHANGE new_assignment_emails new_assignment_emails TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE assignment_deadline_emails assignment_deadline_emails TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE submission_evaluated_emails submission_evaluated_emails TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE solution_comments_emails solution_comments_emails TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE assignment_comments_emails assignment_comments_emails TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE points_changed_emails points_changed_emails TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE assignment_submit_after_accepted_emails assignment_submit_after_accepted_emails TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\', CHANGE assignment_submit_after_reviewed_emails assignment_submit_after_reviewed_emails TINYINT NOT NULL COMMENT \'(DC2Type:boolean)\''); + $this->addSql('ALTER TABLE user_ui_data CHANGE id id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\''); + } +} diff --git a/tests/SubmissionEvaluation/UniversalScoreCalculator.phpt b/tests/SubmissionEvaluation/UniversalScoreCalculator.phpt index 067e574e4..9ab729a84 100644 --- a/tests/SubmissionEvaluation/UniversalScoreCalculator.phpt +++ b/tests/SubmissionEvaluation/UniversalScoreCalculator.phpt @@ -6,6 +6,7 @@ require_once __DIR__ . '/TestResultMock.php'; use Tester\Assert; use App\Helpers\Evaluation\UniversalScoreCalculator; use App\Exceptions\SubmissionEvaluationFailedException; + /** * @testCase */ @@ -30,7 +31,7 @@ class TestUniversalScoreCalculator extends Tester\TestCase } } - $res = [ 'type' => $name ]; + $res = ['type' => $name]; if ($children) { $res['children'] = $children; } @@ -76,7 +77,7 @@ class TestUniversalScoreCalculator extends Tester\TestCase $expectedChildren = $expected['children']; $actualChildren = $actual['children']; Assert::equal(count($expectedChildren), count($actualChildren)); - + foreach ($expectedChildren as $key => $expectedChild) { $actualChild = $actualChildren[$key]; if (is_array($actualChild) && is_array($expectedChild)) { @@ -132,7 +133,7 @@ class TestUniversalScoreCalculator extends Tester\TestCase /** * Instantiate the calculator and perform score computation (using sample config if not provided). */ - private function computeScore(array $results, array $config = null) + private function computeScore(array $results, ?array $config = null) { if ($config === null) { $config = $this->getTestConfig(); @@ -185,7 +186,7 @@ class TestUniversalScoreCalculator extends Tester\TestCase public function testMalformedNodeMissingType() { $this->_testBadConfig( - [ 'children' => [ $this->getTestConfig() ]] + ['children' => [$this->getTestConfig()]] ); } @@ -210,13 +211,13 @@ class TestUniversalScoreCalculator extends Tester\TestCase } public function testInvalidNumberOfChildrenBinary() - { + { $this->_testBadConfig(self::sub(1, 2, 3)); } public function testInvalidNumberOfChildrenLeaf() { - $this->_testBadConfig( [ 'type' => 'test-result', 'children' => [ self::sum(1, 2, 3) ]] ); + $this->_testBadConfig(['type' => 'test-result', 'children' => [self::sum(1, 2, 3)]]); } public function testUnknownReference() @@ -241,7 +242,7 @@ class TestUniversalScoreCalculator extends Tester\TestCase self::compareConfigs($config, $normalized); } - public function testNormalizationWithUnkonwParams() + public function testNormalizationWithUnknownParams() { $config = $this->getTestConfig(); self::addDataExtensions($config); diff --git a/tests/base/PresenterTestHelper.php b/tests/base/PresenterTestHelper.php index 25dfcd48f..fb4b85ea4 100644 --- a/tests/base/PresenterTestHelper.php +++ b/tests/base/PresenterTestHelper.php @@ -5,6 +5,7 @@ use App\Security\AccessManager; use App\Security\TokenScope; use Doctrine\Common\EventManager; +use Doctrine\DBAL\DriverManager; use Doctrine\ORM\Configuration; use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManagerInterface; @@ -16,7 +17,6 @@ use Nette\Utils\FileSystem; use Nette\Utils\Json; use Nette\Utils\JsonException; -use Nettrine\ORM\Decorator\SimpleEntityManagerDecorator; use Symfony\Component\Process\Process; class PresenterTestHelper @@ -34,12 +34,13 @@ private static function createEntityManager( string $dbPath, Configuration $configuration, EventManager $eventManager - ): SimpleEntityManagerDecorator { - return new SimpleEntityManagerDecorator(EntityManager::create( - ["driver" => "pdo_sqlite", "path" => $dbPath], + ): EntityManager { + $connection = DriverManager::getConnection(["driver" => "pdo_sqlite", "path" => $dbPath], $configuration); + return new EntityManager( + $connection, $configuration, $eventManager - )); + ); } public static function replaceService(Container $container, $service, $type = null) @@ -99,7 +100,7 @@ public static function fillDatabase(Container $container, string $group = "demo" $originalEm->getConfiguration(), $originalEm->getEventManager() ); - static::replaceService($container, $schemaEm, SimpleEntityManagerDecorator::class); + static::replaceService($container, $schemaEm, EntityManagerInterface::class); $schemaTool = new Doctrine\ORM\Tools\SchemaTool($schemaEm); $schemaTool->dropSchema($schemaEm->getMetadataFactory()->getAllMetadata()); @@ -127,7 +128,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, SimpleEntityManagerDecorator::class); + static::replaceService($container, $originalEm, EntityManagerInterface::class); } flock($lockHandle, LOCK_UN); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index d92a88c61..046db8c86 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -35,11 +35,6 @@ function (int $severity, string $message, string $file, int $line) use (&$__prev ->register(); $configurator->addConfig(__DIR__ . '/../app/config/config.neon'); - -if (getenv("TRAVIS")) { - $configurator->addConfig(__DIR__ . '/config.travis.neon'); -} else { - $configurator->addConfig(__DIR__ . '/config.tests.neon'); -} +$configurator->addConfig(__DIR__ . '/config.tests.neon'); return $configurator->createContainer(); diff --git a/tests/config.tests.neon b/tests/config.tests.neon index 455296103..3237a7f69 100644 --- a/tests/config.tests.neon +++ b/tests/config.tests.neon @@ -3,10 +3,11 @@ parameters: verificationKey: "recodex-1234567890-1234567890-1234567890" nettrine.dbal: - connection: - url: 'sqlite://:memory:' - charset: UTF-8 - driver: pdo_sqlite + connections: + default: + driver: pdo_sqlite + url: "sqlite:///:memory:" + services: cacheStorage: factory: Nette\Caching\Storages\MemoryStorage diff --git a/tests/config.travis.neon b/tests/config.travis.neon deleted file mode 100644 index bb11ac106..000000000 --- a/tests/config.travis.neon +++ /dev/null @@ -1,3 +0,0 @@ -doctrine: - url: 'sqlite://:memory:' - charset: UTF-8