From d4720b4070d8faf269954f9ae6e12e2e84cef62e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kruli=C5=A1?= Date: Fri, 28 Mar 2025 23:47:03 +0100 Subject: [PATCH 1/3] Fixing InvalidArgument exception issues. --- .../AssignmentSolutionReviewsPresenter.php | 13 ---- .../AssignmentSolutionsPresenter.php | 10 +-- .../presenters/AssignmentsPresenter.php | 19 +++--- .../presenters/ExerciseFilesPresenter.php | 21 ++----- .../presenters/ExercisesConfigPresenter.php | 39 +++++------- .../presenters/ExercisesPresenter.php | 46 +++++++------- app/V1Module/presenters/GroupsPresenter.php | 63 +++++++++++-------- app/V1Module/presenters/LoginPresenter.php | 13 +--- .../presenters/NotificationsPresenter.php | 25 +++----- .../presenters/PipelinesPresenter.php | 10 +-- .../ReferenceExerciseSolutionsPresenter.php | 23 ++----- .../presenters/RegistrationPresenter.php | 19 ++---- app/V1Module/presenters/SecurityPresenter.php | 17 +---- .../presenters/ShadowAssignmentsPresenter.php | 18 +++--- app/V1Module/presenters/SisPresenter.php | 45 +++++++------ app/V1Module/presenters/SubmitPresenter.php | 34 +++------- .../presenters/UploadedFilesPresenter.php | 27 ++++---- app/V1Module/presenters/UsersPresenter.php | 37 ++++++----- .../presenters/WorkerFilesPresenter.php | 15 +---- .../presenters/base/BasePresenter.php | 11 +--- app/V1Module/security/AccessToken.php | 2 +- app/V1Module/security/InvitationToken.php | 7 +-- app/V1Module/security/UserStorage.php | 2 +- app/async/Dispatcher.php | 3 +- app/exceptions/InvalidArgumentException.php | 2 +- .../EmailVerificationHelper.php | 4 +- .../ScoreCalculatorAccessor.php | 2 +- .../ExternalServiceAuthenticator.php | 2 +- app/helpers/ExternalLogin/UserData.php | 4 +- app/helpers/FileStorageManager.php | 9 +-- app/helpers/MetaFormats/MetaFormat.php | 9 +-- app/helpers/MetaFormats/RequestParamData.php | 9 ++- app/helpers/Pagination.php | 14 ++--- app/helpers/SisHelper/SisHelper.php | 18 +++--- .../SubmissionHelper/SubmissionHelper.php | 25 ++++---- app/helpers/Swagger/AnnotationHelper.php | 50 +++++++-------- app/model/entity/BooleanPipelineParameter.php | 4 +- app/model/entity/GroupExternalAttribute.php | 2 - app/model/entity/Login.php | 8 +-- app/model/entity/Pipeline.php | 6 +- app/model/entity/StringPipelineParameter.php | 4 +- app/model/helpers/PaginationDBHelper.php | 21 +++---- recodex-api.spec | 4 +- tests/AccessToken/AccessToken.phpt | 1 - tests/Exceptions/Exceptions.phpt | 8 +-- tests/Presenters/ExerciseFilesPresenter.phpt | 22 +++---- .../Presenters/ExercisesConfigPresenter.phpt | 14 ++--- tests/Presenters/ExercisesPresenter.phpt | 11 ++-- tests/Presenters/ExtensionsPresenter.phpt | 32 ++++++---- tests/Presenters/GroupsPresenter.phpt | 54 ++++++++-------- tests/Presenters/PipelinesPresenter.phpt | 12 ++-- tests/Presenters/UsersPresenter.phpt | 4 +- tests/Security/UserLocking.phpt | 2 +- 53 files changed, 380 insertions(+), 496 deletions(-) diff --git a/app/V1Module/presenters/AssignmentSolutionReviewsPresenter.php b/app/V1Module/presenters/AssignmentSolutionReviewsPresenter.php index 181a6634e..53c26b039 100644 --- a/app/V1Module/presenters/AssignmentSolutionReviewsPresenter.php +++ b/app/V1Module/presenters/AssignmentSolutionReviewsPresenter.php @@ -3,27 +3,14 @@ namespace App\V1Module\Presenters; use App\Helpers\MetaFormats\Attributes\Post; -use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; -use App\Helpers\MetaFormats\Validators\VArray; use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; -use App\Helpers\MetaFormats\Validators\VEmail; use App\Helpers\MetaFormats\Validators\VInt; -use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; -use App\Helpers\MetaFormats\Validators\VTimestamp; -use App\Helpers\MetaFormats\Validators\VUuid; use App\Exceptions\BadRequestException; use App\Exceptions\InternalServerException; -use App\Exceptions\InvalidArgumentException; -use App\Exceptions\InvalidStateException; -use App\Exceptions\NotFoundException; -use App\Exceptions\NotReadyException; use App\Exceptions\ForbiddenRequestException; use App\Helpers\Notifications\ReviewsEmailsSender; -use App\Helpers\Validators; use App\Model\Entity\AssignmentSolution; use App\Model\Entity\ReviewComment; use App\Model\Repository\AssignmentSolutions; diff --git a/app/V1Module/presenters/AssignmentSolutionsPresenter.php b/app/V1Module/presenters/AssignmentSolutionsPresenter.php index f7fd82e61..8b7bf5231 100644 --- a/app/V1Module/presenters/AssignmentSolutionsPresenter.php +++ b/app/V1Module/presenters/AssignmentSolutionsPresenter.php @@ -17,7 +17,7 @@ use App\Helpers\MetaFormats\Validators\VUuid; use App\Exceptions\BadRequestException; use App\Exceptions\InternalServerException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\InvalidStateException; use App\Exceptions\NotFoundException; use App\Exceptions\NotReadyException; @@ -341,7 +341,7 @@ public function checkSetBonusPoints(string $id) * Returns array of solution entities that has been changed by this. * @POST * @throws NotFoundException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws InvalidStateException */ #[Post("bonusPoints", new VInt(), "New amount of bonus points, can be negative number")] @@ -381,8 +381,8 @@ public function actionSetBonusPoints(string $id) if (empty($overriddenPoints)) { $solution->setOverriddenPoints(null); } else { - throw new InvalidArgumentException( - "overridenPoints", + throw new InvalidApiArgumentException( + 'overridenPoints', "The value '$overriddenPoints' is not null|numericint" ); } @@ -524,7 +524,7 @@ public function actionSetFlag(string $id, string $flag) throw new NotFoundException("Group for assignment '$id' was not found"); } - $resSolutions = [ $id => $this->assignmentSolutionViewFactory->getSolutionData($solution) ]; + $resSolutions = [$id => $this->assignmentSolutionViewFactory->getSolutionData($solution)]; if ($resetedSolution) { $resSolutions[$resetedSolution->getId()] = $this->assignmentSolutionViewFactory->getSolutionData($resetedSolution); diff --git a/app/V1Module/presenters/AssignmentsPresenter.php b/app/V1Module/presenters/AssignmentsPresenter.php index 287b9931a..81c0c8951 100644 --- a/app/V1Module/presenters/AssignmentsPresenter.php +++ b/app/V1Module/presenters/AssignmentsPresenter.php @@ -3,21 +3,17 @@ namespace App\V1Module\Presenters; use App\Helpers\MetaFormats\Attributes\Post; -use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; use App\Helpers\MetaFormats\Validators\VArray; use App\Helpers\MetaFormats\Validators\VBool; use App\Helpers\MetaFormats\Validators\VDouble; -use App\Helpers\MetaFormats\Validators\VEmail; use App\Helpers\MetaFormats\Validators\VInt; use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; use App\Helpers\MetaFormats\Validators\VTimestamp; -use App\Helpers\MetaFormats\Validators\VUuid; use App\Exceptions\BadRequestException; use App\Exceptions\ForbiddenRequestException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\InvalidStateException; use App\Exceptions\NotFoundException; use App\Exceptions\FrontendErrorMappings; @@ -209,7 +205,7 @@ public function checkUpdateDetail(string $id) * Update details of an assignment * @POST * @throws BadRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws NotFoundException */ #[Post("version", new VInt(), "Version of the edited assignment")] @@ -312,7 +308,7 @@ public function actionUpdateDetail(string $id) // localized texts cannot be empty if (count($req->getPost("localizedTexts")) == 0) { - throw new InvalidArgumentException("No entry for localized texts given."); + throw new InvalidApiArgumentException('localizedTexts', "No entry for localized texts given."); } if ($this->isRequestJson()) { @@ -334,7 +330,7 @@ public function actionUpdateDetail(string $id) if ($req->getPost($name) !== null) { $value = (int)$req->getPost($name); if ($value < $min || $value > $max) { - throw new InvalidArgumentException("Attribute '$name' value $value is out of range [$min,$max]."); + throw new InvalidApiArgumentException($name, "Value $value is out of range [$min,$max]."); } } } @@ -381,7 +377,8 @@ public function actionUpdateDetail(string $id) $maxPointsDeadlineInterpolation = false; } if ($allowSecondDeadline && $firstDeadlineTimestamp >= $secondDeadlineTimestamp) { - throw new InvalidArgumentException( + throw new InvalidApiArgumentException( + 'secondDeadline', "When the second deadline is allowed, it must be after the first deadline." ); } @@ -435,7 +432,7 @@ public function actionUpdateDetail(string $id) $lang = $localization["locale"]; if (array_key_exists($lang, $localizedTexts)) { - throw new InvalidArgumentException("Duplicate entry for language $lang in localizedTexts"); + throw new InvalidApiArgumentException('localizedTexts', "Duplicate entry for language '$lang'"); } // create all new localized texts @@ -443,7 +440,7 @@ public function actionUpdateDetail(string $id) $localizedExercise = $assignmentExercise ? $assignmentExercise->getLocalizedTextByLocale($lang) : null; $externalAssignmentLink = trim(Arrays::get($localization, "link", "")); if ($externalAssignmentLink !== "" && !Validators::isUrl($externalAssignmentLink)) { - throw new InvalidArgumentException("External assignment link is not a valid URL"); + throw new InvalidApiArgumentException('link', "External assignment link is not a valid URL"); } $localizedTexts[$lang] = new LocalizedExercise( diff --git a/app/V1Module/presenters/ExerciseFilesPresenter.php b/app/V1Module/presenters/ExerciseFilesPresenter.php index 538f3a5cf..45f0619cc 100644 --- a/app/V1Module/presenters/ExerciseFilesPresenter.php +++ b/app/V1Module/presenters/ExerciseFilesPresenter.php @@ -3,20 +3,11 @@ namespace App\V1Module\Presenters; use App\Helpers\MetaFormats\Attributes\Post; -use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; -use App\Helpers\MetaFormats\Validators\VArray; -use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; -use App\Helpers\MetaFormats\Validators\VEmail; -use App\Helpers\MetaFormats\Validators\VInt; use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; -use App\Helpers\MetaFormats\Validators\VTimestamp; -use App\Helpers\MetaFormats\Validators\VUuid; use App\Exceptions\ForbiddenRequestException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\NotFoundException; use App\Exceptions\SubmissionFailedException; use App\Helpers\ExerciseConfig\ExerciseConfigChecker; @@ -99,7 +90,7 @@ public function checkUploadSupplementaryFiles(string $id) * Associate supplementary files with an exercise and upload them to remote file server * @POST * @throws ForbiddenRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws SubmissionFailedException */ #[Post("files", new VMixed(), "Identifiers of supplementary files", nullable: true)] @@ -140,16 +131,16 @@ public function actionUploadSupplementaryFiles(string $id) $fileCountLimit = $this->restrictionsConfig->getSupplementaryFileCountLimit(); if ($totalFileCount > $fileCountLimit) { - throw new InvalidArgumentException( - "files", + throw new InvalidApiArgumentException( + 'files', "The number of files would exceed the configured limit ($fileCountLimit)" ); } $sizeLimit = $this->restrictionsConfig->getSupplementaryFileSizeLimit(); if ($totalFileSize > $sizeLimit) { - throw new InvalidArgumentException( - "files", + throw new InvalidApiArgumentException( + 'files', "The total size of files would exceed the configured limit ($sizeLimit)" ); } diff --git a/app/V1Module/presenters/ExercisesConfigPresenter.php b/app/V1Module/presenters/ExercisesConfigPresenter.php index 90cda8602..dfdb5a0fb 100644 --- a/app/V1Module/presenters/ExercisesConfigPresenter.php +++ b/app/V1Module/presenters/ExercisesConfigPresenter.php @@ -3,23 +3,15 @@ namespace App\V1Module\Presenters; use App\Helpers\MetaFormats\Attributes\Post; -use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; use App\Helpers\MetaFormats\Validators\VArray; -use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; -use App\Helpers\MetaFormats\Validators\VEmail; -use App\Helpers\MetaFormats\Validators\VInt; use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; -use App\Helpers\MetaFormats\Validators\VTimestamp; -use App\Helpers\MetaFormats\Validators\VUuid; use App\Exceptions\ApiException; use App\Exceptions\ExerciseCompilationException; use App\Exceptions\ExerciseConfigException; use App\Exceptions\ForbiddenRequestException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\NotFoundException; use App\Exceptions\ParseException; use App\Helpers\ExerciseConfig\Helper; @@ -197,7 +189,7 @@ public function checkUpdateEnvironmentConfigs(string $id) * Configurations can be added or deleted here, based on what is provided in arguments. * @POST * @throws ForbiddenRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws ExerciseConfigException * @throws NotFoundException */ @@ -214,7 +206,7 @@ public function actionUpdateEnvironmentConfigs(string $id) // configurations cannot be empty if (count($environmentConfigs) == 0) { - throw new InvalidArgumentException("No entry for runtime configurations given."); + throw new InvalidApiArgumentException('environmentConfigs', "No entry for runtime configurations given."); } $runtimeEnvironments = new ArrayCollection(); @@ -228,7 +220,10 @@ public function actionUpdateEnvironmentConfigs(string $id) // check for duplicate environments if (array_key_exists($environmentId, $configs)) { - throw new InvalidArgumentException("Duplicate entry for configuration '$environmentId''"); + throw new InvalidApiArgumentException( + 'environmentConfigs', + "Duplicate entry for configuration '$environmentId''" + ); } // load variables table for this runtime configuration @@ -593,8 +588,8 @@ public function actionGetLimits(string $id) // fill existing limits into result structure foreach ($exercise->getExerciseLimits() as $limit) { - $limits[$limit->getHardwareGroup()->getId()][$limit->getRuntimeEnvironment()->getId( - )] = $limit->getParsedLimits(); + $limits[$limit->getHardwareGroup()->getId()][$limit->getRuntimeEnvironment()->getId()] + = $limit->getParsedLimits(); } $this->sendSuccessResponse($limits); } @@ -766,7 +761,7 @@ public function checkSetTests(string $id) * Set tests for exercise based on given identification. * @POST * @throws ForbiddenRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws ExerciseConfigException */ #[Post("tests", new VArray(), "An array of tests which will belong to exercise")] @@ -792,18 +787,18 @@ public function actionSetTests(string $id) foreach ($tests as $test) { // Perform checks on the test name... if (!array_key_exists("name", $test)) { - throw new InvalidArgumentException("tests", "name item not found in particular test"); + throw new InvalidApiArgumentException('tests', "name item not found in particular test"); } $name = trim($test["name"]); if (!preg_match('/^[-a-zA-Z0-9_()\[\].! ]+$/', $name)) { - throw new InvalidArgumentException("tests", "test name contains illicit characters"); + throw new InvalidApiArgumentException('tests', "test name contains illicit characters"); } if (strlen($name) > 64) { - throw new InvalidArgumentException("tests", "test name too long (exceeds 64 characters)"); + throw new InvalidApiArgumentException('tests', "test name too long (exceeds 64 characters)"); } if (array_key_exists($name, $newTests)) { - throw new InvalidArgumentException("tests", "two tests with the same name '$name' were specified"); + throw new InvalidApiArgumentException('tests', "two tests with the same name '$name' were specified"); } $id = Arrays::get($test, "id", null); @@ -816,7 +811,7 @@ public function actionSetTests(string $id) $testsModified = true; if ($exercise->getExerciseTestByName($name)) { - throw new InvalidArgumentException("tests", "given test name '$name' is already taken"); + throw new InvalidApiArgumentException('tests', "given test name '$name' is already taken"); } $testEntity = new ExerciseTest($name, $description, $this->getCurrentUser()); @@ -841,8 +836,8 @@ public function actionSetTests(string $id) $testCountLimit = $this->exerciseRestrictionsConfig->getTestCountLimit(); if (count($newTests) > $testCountLimit) { - throw new InvalidArgumentException( - "tests", + throw new InvalidApiArgumentException( + 'tests', "The number of tests exceeds the configured limit ($testCountLimit)" ); } diff --git a/app/V1Module/presenters/ExercisesPresenter.php b/app/V1Module/presenters/ExercisesPresenter.php index 82e58bdf7..b0b0b569c 100644 --- a/app/V1Module/presenters/ExercisesPresenter.php +++ b/app/V1Module/presenters/ExercisesPresenter.php @@ -5,20 +5,16 @@ use App\Helpers\MetaFormats\Attributes\Post; use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; use App\Helpers\MetaFormats\Validators\VArray; use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; -use App\Helpers\MetaFormats\Validators\VEmail; use App\Helpers\MetaFormats\Validators\VInt; use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; -use App\Helpers\MetaFormats\Validators\VTimestamp; use App\Helpers\MetaFormats\Validators\VUuid; use App\Exceptions\ApiException; use App\Exceptions\BadRequestException; use App\Exceptions\ForbiddenRequestException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\NotFoundException; use App\Exceptions\ParseException; use App\Exceptions\FrontendErrorMappings; @@ -27,7 +23,6 @@ use App\Helpers\ExerciseConfig\ExerciseConfigChecker; use App\Helpers\ExerciseConfig\Updater; use App\Helpers\Localizations; -use App\Helpers\Pagination; use App\Helpers\Evaluation\ScoreCalculatorAccessor; use App\Helpers\Validators; use App\Helpers\Notifications\ExerciseNotificationSender; @@ -36,7 +31,6 @@ use App\Model\Entity\ExerciseScoreConfig; use App\Model\Entity\ExerciseConfig; use App\Model\Entity\ExerciseTag; -use App\Model\Entity\Pipeline; use App\Model\Entity\LocalizedExercise; use App\Model\Entity\User; use App\Model\Repository\Exercises; @@ -337,9 +331,9 @@ public function checkUpdateDetail(string $id) * @POST * @throws BadRequestException * @throws ForbiddenRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws BadRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ #[Post("version", new VInt(), "Version of the edited exercise")] #[Post( @@ -409,7 +403,10 @@ public function actionUpdateDetail(string $id) $configurationType = $req->getPost("configurationType"); if ($configurationType) { if (!Compiler::checkConfigurationType($configurationType)) { - throw new InvalidArgumentException("Invalid configuration type '{$configurationType}'"); + throw new InvalidApiArgumentException( + 'configurationType', + "Invalid configuration type '{$configurationType}'" + ); } $exercise->setConfigurationType($configurationType); } @@ -420,7 +417,7 @@ public function actionUpdateDetail(string $id) // localized texts cannot be empty if (count($localizedTexts) == 0) { - throw new InvalidArgumentException("No entry for localized texts given."); + throw new InvalidApiArgumentException('localizedTexts', "No entry for localized texts given."); } // go through given localizations and construct database entities @@ -431,19 +428,19 @@ public function actionUpdateDetail(string $id) $localization ) || !array_key_exists("text", $localization) ) { - throw new InvalidArgumentException("Malformed localized text entry"); + throw new InvalidApiArgumentException('localizedTexts', "Malformed localized text entry"); } $lang = $localization["locale"]; if (array_key_exists($lang, $localizations)) { - throw new InvalidArgumentException("Duplicate entry for language $lang"); + throw new InvalidApiArgumentException("Duplicate entry for language $lang"); } // create all new localized texts $externalAssignmentLink = trim(Arrays::get($localization, "link", "")); if ($externalAssignmentLink !== "" && !Validators::isUrl($externalAssignmentLink)) { - throw new InvalidArgumentException("External assignment link is not a valid URL"); + throw new InvalidApiArgumentException('link', "External assignment link is not a valid URL"); } $localization["description"] = $localization["description"] ?? ""; @@ -695,7 +692,7 @@ public function checkAttachGroup(string $id, string $groupId) /** * Attach exercise to group with given identification. * @POST - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ #[Path("id", new VString(), "Identifier of the exercise", required: true)] #[Path("groupId", new VString(), "Identifier of the group to which exercise should be attached", required: true)] @@ -705,7 +702,7 @@ public function actionAttachGroup(string $id, string $groupId) $group = $this->groups->findOrThrow($groupId); if ($exercise->getGroups()->contains($group)) { - throw new InvalidArgumentException("groupId", "group is already attached to the exercise"); + throw new InvalidApiArgumentException('groupId', "group is already attached to the exercise"); } $exercise->addGroup($group); @@ -729,7 +726,7 @@ public function checkDetachGroup(string $id, string $groupId) /** * Detach exercise from given group. * @DELETE - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ #[Path("id", new VString(), "Identifier of the exercise", required: true)] #[Path("groupId", new VString(), "Identifier of the group which should be detached from exercise", required: true)] @@ -739,7 +736,7 @@ public function actionDetachGroup(string $id, string $groupId) $group = $this->groups->findOrThrow($groupId); if (!$exercise->getGroups()->contains($group)) { - throw new InvalidArgumentException("groupId", "given group is not attached to the exercise"); + throw new InvalidApiArgumentException('groupId', "given group is not attached to the exercise"); } $exercise->removeGroup($group); @@ -801,7 +798,8 @@ public function checkTagsUpdateGlobal(string $tag) #[Query( "force", new VBool(), - "If true, the rename will be allowed even if the new tag name exists (tags will be merged). Otherwise, name collisions will result in error.", + "If true, the rename will be allowed even if the new tag name exists (tags will be merged). " + . "Otherwise, name collisions will result in error.", required: false, )] #[Path("tag", new VString(), "Tag to be updated", required: true)] @@ -813,12 +811,12 @@ public function actionTagsUpdateGlobal(string $tag, string $renameTo = null, boo } if (!$this->exerciseTags->verifyTagName($renameTo)) { - throw new InvalidArgumentException("renameTo", "tag name contains illicit characters"); + throw new InvalidApiArgumentException('renameTo', "tag name contains illicit characters"); } if (!$force && $this->exerciseTags->tagExists($renameTo)) { - throw new InvalidArgumentException( - "renameTo", + throw new InvalidApiArgumentException( + 'renameTo', "new tag name collides with existing name (use force to override)" ); } @@ -871,14 +869,14 @@ public function checkAddTag(string $id) * @throws BadRequestException * @throws NotFoundException * @throws ForbiddenRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ #[Path("id", new VString(), required: true)] #[Path("name", new VString(1, 32), "Name of the newly added tag to given exercise", required: true)] public function actionAddTag(string $id, string $name) { if (!$this->exerciseTags->verifyTagName($name)) { - throw new InvalidArgumentException("name", "tag name contains illicit characters"); + throw new InvalidApiArgumentException('name', "tag name contains illicit characters"); } $exercise = $this->exercises->findOrThrow($id); diff --git a/app/V1Module/presenters/GroupsPresenter.php b/app/V1Module/presenters/GroupsPresenter.php index 84e8d2010..025ef4071 100644 --- a/app/V1Module/presenters/GroupsPresenter.php +++ b/app/V1Module/presenters/GroupsPresenter.php @@ -5,17 +5,14 @@ use App\Helpers\MetaFormats\Attributes\Post; use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; use App\Helpers\MetaFormats\Validators\VArray; use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; -use App\Helpers\MetaFormats\Validators\VEmail; use App\Helpers\MetaFormats\Validators\VInt; use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; use App\Helpers\MetaFormats\Validators\VTimestamp; use App\Helpers\MetaFormats\Validators\VUuid; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\NotFoundException; use App\Exceptions\BadRequestException; use App\Exceptions\ForbiddenRequestException; @@ -188,7 +185,8 @@ class GroupsPresenter extends BasePresenter #[Query( "ancestors", new VBool(), - "If true, returns an ancestral closure of the initial result set. Included ancestral groups do not respect other filters (archived, search, ...).", + "If true, returns an ancestral closure of the initial result set. " + . "Included ancestral groups do not respect other filters (archived, search, ...).", required: false, )] #[Query( @@ -206,9 +204,9 @@ class GroupsPresenter extends BasePresenter required: false, )] public function actionDefault( - string $instanceId = null, + ?string $instanceId = null, bool $ancestors = false, - string $search = null, + ?string $search = null, bool $archived = false, bool $onlyArchived = false ) { @@ -230,11 +228,14 @@ private function setGroupPoints(Request $req, Group $group): void $threshold = $req->getPost("threshold"); $pointsLimit = $req->getPost("pointsLimit"); if ($threshold !== null && $pointsLimit !== null) { - throw new InvalidArgumentException("A group may have either a threshold or points limit, not both."); + throw new InvalidApiArgumentException( + 'threshold', + "A group may have either a threshold or points limit, not both." + ); } if ($threshold !== null) { if ($threshold <= 0 || $threshold > 100) { - throw new InvalidArgumentException("A threshold must be in the (0, 100] (%) range."); + throw new InvalidApiArgumentException('threshold', "A threshold must be in the (0, 100] (%) range."); } $group->setThreshold($threshold / 100); } else { @@ -242,7 +243,7 @@ private function setGroupPoints(Request $req, Group $group): void } if ($pointsLimit !== null) { if ($pointsLimit <= 0) { - throw new InvalidArgumentException("A points limit must be a positive number."); + throw new InvalidApiArgumentException('pointsLimit', "A points limit must be a positive number."); } $group->setPointsLimit($pointsLimit); } else { @@ -254,7 +255,7 @@ private function setGroupPoints(Request $req, Group $group): void * Create a new group * @POST * @throws ForbiddenRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ #[Post("instanceId", new VUuid(), "An identifier of the instance where the group should be created")] #[Post( @@ -301,7 +302,10 @@ public function actionAddGroup() $parentGroup = !$parentGroupId ? $instance->getRootGroup() : $this->groups->findOrThrow($parentGroupId); if ($parentGroup->isArchived()) { - throw new InvalidArgumentException("It is not permitted to create subgroups in archived groups"); + throw new InvalidApiArgumentException( + 'parentGroupId', + "It is not permitted to create subgroups in archived groups" + ); } if (!$this->groupAcl->canAddSubgroup($parentGroup)) { @@ -317,7 +321,10 @@ public function actionAddGroup() $noAdmin = filter_var($req->getPost("noAdmin"), FILTER_VALIDATE_BOOLEAN); if ($isOrganizational && $isExam) { - throw new InvalidArgumentException("A group cannot be both organizational and exam."); + throw new InvalidApiArgumentException( + 'isOrganizational, isExam', + "A group cannot be both organizational and exam." + ); } $group = new Group( @@ -381,7 +388,7 @@ public function checkUpdateGroup(string $id) /** * Update group info * @POST - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ #[Post( "externalId", @@ -820,8 +827,8 @@ public function checkRemoveGroup(string $id) if ($group->getInstance() !== null && $group->getInstance()->getRootGroup() === $group) { throw new ForbiddenRequestException( "Group '$id' is the root group of instance '" - . $group->getInstance()->getId() - . "' and root groups cannot be deleted." + . $group->getInstance()->getId() + . "' and root groups cannot be deleted." ); } } @@ -950,14 +957,15 @@ public function actionAddMember(string $id, string $userId) $type = $this->getRequest()->getPost("type"); if ($type === GroupMembership::TYPE_STUDENT || !in_array($type, GroupMembership::KNOWN_TYPES)) { - throw new InvalidArgumentException("Unknown membership type '$type'"); + throw new InvalidApiArgumentException('type', "Unknown membership type '$type'"); } $membership = $group->getMembershipOfUser($user); if ($membership) { // update type of existing membership (if it is not a student) if ($membership->getType() === GroupMembership::TYPE_STUDENT) { - throw new InvalidArgumentException( + throw new InvalidApiArgumentException( + 'userId', "The user is a student of the group and students cannot be made also members" ); } @@ -995,10 +1003,11 @@ public function actionRemoveMember(string $id, string $userId) $membership = $group->getMembershipOfUser($user); if (!$membership) { - throw new InvalidArgumentException("The user is not a member of the group"); + throw new InvalidApiArgumentException('userId', "The user is not a member of the group"); } if ($membership->getType() === GroupMembership::TYPE_STUDENT) { - throw new InvalidArgumentException( + throw new InvalidApiArgumentException( + 'userId', "The user is a student of the group and students must be removed by separate endpoint" ); } @@ -1195,7 +1204,7 @@ public function checkAddStudent(string $id, string $userId) } if ($group->isOrganizational()) { - throw new InvalidArgumentException("It is forbidden to add students to organizational groups"); + throw new InvalidApiArgumentException('id', "It is forbidden to add students to organizational groups"); } } @@ -1294,7 +1303,7 @@ public function checkUnlockStudent(string $id, string $userId) $group = $this->groups->findOrThrow($id); $user = $this->users->findOrThrow($userId); if ($user->getGroupLock()?->getId() !== $group->getId()) { - throw new InvalidArgumentException("The user is not locked in given group."); + throw new InvalidApiArgumentException('userId', "The user is not locked in given group."); } if (!$this->groupAcl->canUnlockStudent($group, $user)) { @@ -1329,7 +1338,7 @@ public function actionUnlockStudent(string $id, string $userId) /** * @param Request $req * @param Group $group - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ private function updateLocalizations(Request $req, Group $group): void { @@ -1349,14 +1358,18 @@ private function updateLocalizations(Request $req, Group $group): void foreach ($otherGroups as $otherGroup) { if ($otherGroup !== $group) { - throw new InvalidArgumentException( + throw new InvalidApiArgumentException( + 'name', "There is already a group of this name, please choose a different one." ); } } if (array_key_exists($lang, $localizations)) { - throw new InvalidArgumentException(sprintf("Duplicate entry for locale %s", $lang)); + throw new InvalidApiArgumentException( + 'localizedTexts', + sprintf("Duplicate entry for locale %s", $lang) + ); } $name = $item["name"] ?: ""; diff --git a/app/V1Module/presenters/LoginPresenter.php b/app/V1Module/presenters/LoginPresenter.php index 47e3c526a..8d76c69ce 100644 --- a/app/V1Module/presenters/LoginPresenter.php +++ b/app/V1Module/presenters/LoginPresenter.php @@ -3,23 +3,16 @@ namespace App\V1Module\Presenters; use App\Helpers\MetaFormats\Attributes\Post; -use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; use App\Helpers\MetaFormats\Validators\VArray; -use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; use App\Helpers\MetaFormats\Validators\VEmail; use App\Helpers\MetaFormats\Validators\VInt; -use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; -use App\Helpers\MetaFormats\Validators\VTimestamp; -use App\Helpers\MetaFormats\Validators\VUuid; use App\Exceptions\BadRequestException; use App\Exceptions\ForbiddenRequestException; use App\Exceptions\FrontendErrorMappings; use App\Exceptions\InvalidAccessTokenException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\WrongCredentialsException; use App\Helpers\ExternalLogin\ExternalServiceAuthenticator; use App\Model\Entity\SecurityEvent; @@ -250,7 +243,7 @@ public function checkIssueRestrictedToken() * @LoggedIn * @throws BadRequestException * @throws ForbiddenRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ #[Post("effectiveRole", new VString(), "Effective user role contained within issued token", required: false)] #[Post("scopes", new VArray(), "A list of requested scopes")] @@ -327,7 +320,7 @@ private function validateEffectiveRole(?string $effectiveRole) } if (!$this->roles->validateRole($effectiveRole)) { - throw new InvalidArgumentException("effectiveRole", "Unknown user role '$effectiveRole'"); + throw new InvalidApiArgumentException('effectiveRole', "Unknown user role '$effectiveRole'"); } $role = $this->getCurrentUser()->getRole(); diff --git a/app/V1Module/presenters/NotificationsPresenter.php b/app/V1Module/presenters/NotificationsPresenter.php index 3f28aae06..67a590d51 100644 --- a/app/V1Module/presenters/NotificationsPresenter.php +++ b/app/V1Module/presenters/NotificationsPresenter.php @@ -5,18 +5,11 @@ use App\Helpers\MetaFormats\Attributes\Post; use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; use App\Helpers\MetaFormats\Validators\VArray; -use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; -use App\Helpers\MetaFormats\Validators\VEmail; -use App\Helpers\MetaFormats\Validators\VInt; -use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; use App\Helpers\MetaFormats\Validators\VTimestamp; -use App\Helpers\MetaFormats\Validators\VUuid; use App\Exceptions\ForbiddenRequestException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\NotFoundException; use App\Helpers\Localizations; use App\Model\Entity\LocalizedNotification; @@ -119,7 +112,7 @@ public function checkCreate() * @POST * @throws NotFoundException * @throws ForbiddenRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ #[Post("groupsIds", new VArray(), "Identification of groups")] #[Post("visibleFrom", new VTimestamp(), "Date from which is notification visible")] @@ -140,7 +133,7 @@ public function actionCreate() * @param Notification $notification * @throws ForbiddenRequestException * @throws NotFoundException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ private function updateNotification(Notification $notification) { @@ -167,7 +160,7 @@ private function updateNotification(Notification $notification) $type = $req->getPost("type"); if (!$this->roles->validateRole($role)) { - throw new InvalidArgumentException("role", "Unknown role"); + throw new InvalidApiArgumentException('role', "Unknown role '$role'"); } $notification->setVisibleFrom(DateTime::createFromFormat('U', $visibleFromTimestamp)); @@ -182,7 +175,7 @@ private function updateNotification(Notification $notification) /** * Helper function which takes care of localized notification texts * @param Notification $notification - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ private function updateNotificationLocalizations(Notification $notification) { @@ -192,18 +185,18 @@ private function updateNotificationLocalizations(Notification $notification) // localized texts cannot be empty if (count($localizedTexts) == 0) { - throw new InvalidArgumentException("localizedTexts", "No entry for localized texts given."); + throw new InvalidApiArgumentException('localizedTexts', "No entry for localized texts given."); } // go through given localizations and construct database entities foreach ($localizedTexts as $localization) { if (!array_key_exists("locale", $localization) || !array_key_exists("text", $localization)) { - throw new InvalidArgumentException("Malformed localized text entry"); + throw new InvalidApiArgumentException('localizedTexts', "Malformed localized text entry"); } $lang = $localization["locale"]; if (array_key_exists($lang, $localizations)) { - throw new InvalidArgumentException("Duplicate entry for language $lang"); + throw new InvalidApiArgumentException('lang', "Duplicate entry for language $lang"); } $localization["text"] = $localization["text"] ?? ""; @@ -231,7 +224,7 @@ public function checkUpdate(string $id) * @POST * @throws NotFoundException * @throws ForbiddenRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ #[Post("groupsIds", new VArray(), "Identification of groups")] #[Post("visibleFrom", new VTimestamp(), "Date from which is notification visible")] diff --git a/app/V1Module/presenters/PipelinesPresenter.php b/app/V1Module/presenters/PipelinesPresenter.php index c3d22bb0c..d2f797e77 100644 --- a/app/V1Module/presenters/PipelinesPresenter.php +++ b/app/V1Module/presenters/PipelinesPresenter.php @@ -5,20 +5,15 @@ use App\Helpers\MetaFormats\Attributes\Post; use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; use App\Helpers\MetaFormats\Validators\VArray; use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; -use App\Helpers\MetaFormats\Validators\VEmail; use App\Helpers\MetaFormats\Validators\VInt; use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; -use App\Helpers\MetaFormats\Validators\VTimestamp; -use App\Helpers\MetaFormats\Validators\VUuid; use App\Exceptions\BadRequestException; use App\Exceptions\ExerciseConfigException; use App\Exceptions\ForbiddenRequestException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\NotFoundException; use App\Exceptions\SubmissionFailedException; use App\Exceptions\FrontendErrorMappings; @@ -39,7 +34,6 @@ use App\Model\Repository\Pipelines; use App\Model\Entity\Pipeline; use App\Helpers\ExerciseConfig\Validator as ConfigValidator; -use Exception; /** * Endpoints for pipelines manipulation @@ -324,7 +318,7 @@ public function checkUpdatePipeline(string $id) * @throws NotFoundException * @throws BadRequestException * @throws ExerciseConfigException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ #[Post("name", new VString(2), "Name of the pipeline")] #[Post("version", new VInt(), "Version of the edited pipeline")] diff --git a/app/V1Module/presenters/ReferenceExerciseSolutionsPresenter.php b/app/V1Module/presenters/ReferenceExerciseSolutionsPresenter.php index bf31298b3..80401894b 100644 --- a/app/V1Module/presenters/ReferenceExerciseSolutionsPresenter.php +++ b/app/V1Module/presenters/ReferenceExerciseSolutionsPresenter.php @@ -3,33 +3,24 @@ namespace App\V1Module\Presenters; use App\Helpers\MetaFormats\Attributes\Post; -use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; use App\Helpers\MetaFormats\Validators\VArray; use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; -use App\Helpers\MetaFormats\Validators\VEmail; use App\Helpers\MetaFormats\Validators\VInt; use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; -use App\Helpers\MetaFormats\Validators\VTimestamp; -use App\Helpers\MetaFormats\Validators\VUuid; use App\Exceptions\BadRequestException; use App\Exceptions\ExerciseCompilationException; -use App\Exceptions\ExerciseCompilationSoftException; use App\Exceptions\ExerciseConfigException; use App\Exceptions\InternalServerException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\NotReadyException; use App\Exceptions\ParseException; -use App\Exceptions\SubmissionFailedException; use App\Exceptions\SubmissionEvaluationFailedException; use App\Exceptions\ForbiddenRequestException; use App\Exceptions\NotFoundException; use App\Helpers\EntityMetadata\Solution\SolutionParams; use App\Helpers\EvaluationLoadingHelper; -use App\Helpers\ExerciseConfig\Compilation\CompilationParams; use App\Helpers\ExerciseConfig\Helper as ExerciseConfigHelper; use App\Helpers\FailureHelper; use App\Helpers\MonitorConfig; @@ -38,10 +29,6 @@ use App\Helpers\FileStorageManager; use App\Helpers\FileStorage\FileStorageException; use App\Model\Entity\Exercise; -use App\Model\Entity\HardwareGroup; -use App\Model\Entity\SolutionFile; -use App\Model\Entity\SubmissionFailure; -use App\Model\Entity\UploadedFile; use App\Model\Entity\ReferenceExerciseSolution; use App\Model\Entity\ReferenceSolutionSubmission; use App\Model\Repository\Exercises; @@ -374,7 +361,7 @@ public function checkPreSubmit(string $exerciseId) * points and other important things that should be provided by user during submit. * @POST * @throws NotFoundException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws ExerciseConfigException * @throws BadRequestException */ @@ -391,7 +378,7 @@ public function actionPreSubmit(string $exerciseId) // retrieve and check uploaded files $uploadedFiles = $this->files->findAllById($this->getRequest()->getPost("files")); if (count($uploadedFiles) === 0) { - throw new InvalidArgumentException("files", "No files were uploaded"); + throw new InvalidApiArgumentException('files', "No files were uploaded"); } // prepare file names into separate array and sum total upload size @@ -572,7 +559,7 @@ private function finishSubmission( $hwGroups = $referenceSolution->getExercise()->getHardwareGroups(); foreach ($hwGroups->getValues() as $hwGroup) { try { - [ $submission, $jobConfig ] = $this->submissionHelper->submitReference( + [$submission, $jobConfig] = $this->submissionHelper->submitReference( $referenceSolution, $hwGroup, $this->getCurrentUser(), @@ -760,7 +747,7 @@ public function actionSetVisibility(string $solutionId) $this->sendSuccessResponse( $this->referenceSolutionAcl->canViewDetail($solution) ? - $this->referenceSolutionViewFactory->getReferenceSolution($solution) : null + $this->referenceSolutionViewFactory->getReferenceSolution($solution) : null ); } } diff --git a/app/V1Module/presenters/RegistrationPresenter.php b/app/V1Module/presenters/RegistrationPresenter.php index ca281ef07..a8b299806 100644 --- a/app/V1Module/presenters/RegistrationPresenter.php +++ b/app/V1Module/presenters/RegistrationPresenter.php @@ -3,20 +3,11 @@ namespace App\V1Module\Presenters; use App\Helpers\MetaFormats\Attributes\Post; -use App\Helpers\MetaFormats\Attributes\Query; -use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; -use App\Helpers\MetaFormats\Validators\VArray; -use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; use App\Helpers\MetaFormats\Validators\VEmail; -use App\Helpers\MetaFormats\Validators\VInt; use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; -use App\Helpers\MetaFormats\Validators\VTimestamp; -use App\Helpers\MetaFormats\Validators\VUuid; use App\Exceptions\FrontendErrorMappings; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\WrongCredentialsException; use App\Exceptions\ForbiddenRequestException; use App\Exceptions\BadRequestException; @@ -36,13 +27,11 @@ use App\Helpers\InvitationHelper; use App\Helpers\MetaFormats\Attributes\Format; use App\Helpers\MetaFormats\FormatDefinitions\UserFormat; -use App\Helpers\MetaFormats\Attributes\ParamAttribute; use App\Security\Roles; use App\Security\ACL\IUserPermissions; use App\Security\ACL\IGroupPermissions; use Nette\Http\IResponse; use Nette\Security\Passwords; -use Tracy\ILogger; use ZxcvbnPhp\Zxcvbn; /** @@ -163,7 +152,7 @@ public function checkCreateAccount() * @POST * @throws BadRequestException * @throws WrongCredentialsException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ #[Post("email", new VEmail(), "An email that will serve as a login name")] #[Post("firstName", new VString(2), "First name")] @@ -272,7 +261,7 @@ public function checkCreateInvitation() * Create an invitation for a user and send it over via email * @POST * @throws BadRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ #[Format(UserFormat::class)] public function actionCreateInvitation() @@ -330,7 +319,7 @@ public function actionCreateInvitation() * Accept invitation and create corresponding user account. * @POST * @throws BadRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ #[Post("token", new VString(1), "Token issued in create invitation process.")] #[Post("password", new VString(1), "A password for authentication")] diff --git a/app/V1Module/presenters/SecurityPresenter.php b/app/V1Module/presenters/SecurityPresenter.php index 7ff6a1aee..5b543aef1 100644 --- a/app/V1Module/presenters/SecurityPresenter.php +++ b/app/V1Module/presenters/SecurityPresenter.php @@ -3,19 +3,8 @@ namespace App\V1Module\Presenters; use App\Helpers\MetaFormats\Attributes\Post; -use App\Helpers\MetaFormats\Attributes\Query; -use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; -use App\Helpers\MetaFormats\Validators\VArray; -use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; -use App\Helpers\MetaFormats\Validators\VEmail; -use App\Helpers\MetaFormats\Validators\VInt; use App\Helpers\MetaFormats\Validators\VMixed; -use App\Helpers\MetaFormats\Validators\VString; -use App\Helpers\MetaFormats\Validators\VTimestamp; -use App\Helpers\MetaFormats\Validators\VUuid; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use Exception; use Nette\Application\IPresenterFactory; use Nette\Routing\Router; @@ -55,12 +44,12 @@ public function actionCheck() ); if (!$requestParams) { - throw new InvalidArgumentException("url"); + throw new InvalidApiArgumentException("url"); } $presenterName = $requestParams["presenter"] ?? null; if (!$presenterName) { - throw new InvalidArgumentException("url"); + throw new InvalidApiArgumentException("url"); } $presenter = $this->presenterFactory->createPresenter($presenterName); diff --git a/app/V1Module/presenters/ShadowAssignmentsPresenter.php b/app/V1Module/presenters/ShadowAssignmentsPresenter.php index 51a356ac4..36ef5cdb5 100644 --- a/app/V1Module/presenters/ShadowAssignmentsPresenter.php +++ b/app/V1Module/presenters/ShadowAssignmentsPresenter.php @@ -3,21 +3,16 @@ namespace App\V1Module\Presenters; use App\Helpers\MetaFormats\Attributes\Post; -use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; use App\Helpers\MetaFormats\Validators\VArray; use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; -use App\Helpers\MetaFormats\Validators\VEmail; use App\Helpers\MetaFormats\Validators\VInt; use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; use App\Helpers\MetaFormats\Validators\VTimestamp; -use App\Helpers\MetaFormats\Validators\VUuid; use App\Exceptions\BadRequestException; use App\Exceptions\ForbiddenRequestException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\InvalidStateException; use App\Exceptions\NotFoundException; use App\Exceptions\FrontendErrorMappings; @@ -150,7 +145,7 @@ public function checkUpdateDetail(string $id) * Update details of an shadow assignment * @POST * @throws BadRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws NotFoundException */ #[Post("version", new VInt(), "Version of the edited assignment")] @@ -192,7 +187,7 @@ public function actionUpdateDetail(string $id) // localized texts cannot be empty if (count($req->getPost("localizedTexts")) == 0) { - throw new InvalidArgumentException("No entry for localized texts given."); + throw new InvalidApiArgumentException('localizedTexts', "No entry for localized texts given."); } // old values of some attributes @@ -219,13 +214,16 @@ public function actionUpdateDetail(string $id) $lang = $localization["locale"]; if (array_key_exists($lang, $localizedTexts)) { - throw new InvalidArgumentException("Duplicate entry for language '$lang' in localizedTexts"); + throw new InvalidApiArgumentException( + 'localizedTexts', + "Duplicate entry for language '$lang' in localizedTexts" + ); } // create all new localized texts $externalAssignmentLink = trim(Arrays::get($localization, "link", "")); if ($externalAssignmentLink !== "" && !Validators::isUrl($externalAssignmentLink)) { - throw new InvalidArgumentException("External assignment link is not a valid URL"); + throw new InvalidApiArgumentException('link', "External assignment link is not a valid URL"); } $localized = new LocalizedShadowAssignment( diff --git a/app/V1Module/presenters/SisPresenter.php b/app/V1Module/presenters/SisPresenter.php index 7a0a019d2..b183af385 100644 --- a/app/V1Module/presenters/SisPresenter.php +++ b/app/V1Module/presenters/SisPresenter.php @@ -3,22 +3,15 @@ namespace App\V1Module\Presenters; use App\Helpers\MetaFormats\Attributes\Post; -use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; -use App\Helpers\MetaFormats\Validators\VArray; -use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; -use App\Helpers\MetaFormats\Validators\VEmail; use App\Helpers\MetaFormats\Validators\VInt; use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; use App\Helpers\MetaFormats\Validators\VTimestamp; -use App\Helpers\MetaFormats\Validators\VUuid; use App\Exceptions\ApiException; use App\Exceptions\BadRequestException; use App\Exceptions\ForbiddenRequestException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\NotFoundException; use App\Helpers\SisCourseRecord; use App\Helpers\SisHelper; @@ -147,7 +140,7 @@ public function checkRegisterTerm() /** * Register a new term * @POST - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws ForbiddenRequestException * @throws BadRequestException */ @@ -162,7 +155,7 @@ public function actionRegisterTerm() $this->sendSuccessResponse("OK"); } - // Throws InvalidArgumentException when given term is invalid + // Throws InvalidApiArgumentException when given term is invalid $this->sisHelper->getCourses($this->getSisUserIdOrThrow($this->getCurrentUser()), $year, $term); $termEntity = new SisValidTerm($year, $term); @@ -183,7 +176,7 @@ public function checkEditTerm(string $id) /** * Set details of a term * @POST - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws NotFoundException */ #[Post("beginning", new VTimestamp())] @@ -203,12 +196,12 @@ public function actionEditTerm(string $id) } if ($beginning > $end) { - throw new InvalidArgumentException("beginning", "The beginning must precede the end"); + throw new InvalidApiArgumentException('beginning', "The beginning must precede the end"); } if ($advertiseUntil !== null && ($advertiseUntil > $end || $advertiseUntil < $beginning)) { - throw new InvalidArgumentException( - "advertiseUntil", + throw new InvalidApiArgumentException( + 'advertiseUntil', "The 'advertiseUntil' timestamp must be within the semester" ); } @@ -259,7 +252,7 @@ public function checkSubscribedGroups($userId, $year, $term) * Each course holds bound group IDs and group objects are returned in a separate array. * Whole ancestral closure of groups is returned, so the webapp may properly assemble hiarichial group names. * @GET - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws BadRequestException */ #[Path("userId", new VString(), required: true)] @@ -287,8 +280,8 @@ public function actionSubscribedCourses($userId, $year, $term) $group = $binding->getGroup(); if ( - !array_key_exists($group->getId(), $groups) && !$group->isOrganizational( - ) && !$group->isArchived() + !array_key_exists($group->getId(), $groups) + && !$group->isOrganizational() && !$group->isArchived() ) { $groups[$group->getId()] = $group; $courseGroupIds[] = $group->getId(); @@ -326,7 +319,7 @@ public function checkSupervisedCourses($userId, $year, $term) * Each course holds bound group IDs and group objects are returned in a separate array. * Whole ancestral closure of groups is returned, so the webapp may properly assemble hiarichial group names. * @GET - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws NotFoundException * @throws BadRequestException */ @@ -420,7 +413,7 @@ private function makeCaptionsUnique(array &$captions, Group $parentGroup) * @POST * @throws BadRequestException * @throws ForbiddenRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws Exception */ #[Post("parentGroupId", new VMixed(), nullable: true)] @@ -434,7 +427,10 @@ public function actionCreateGroup($courseId) $parentGroup = $this->groups->findOrThrow($parentGroupId); if ($parentGroup->isArchived()) { - throw new InvalidArgumentException("It is not permitted to create subgroups in archived groups"); + throw new InvalidApiArgumentException( + 'parentGroupId', + "It is not permitted to create subgroups in archived groups" + ); } $remoteCourse = $this->findRemoteCourseOrThrow($courseId, $sisUserId); @@ -506,7 +502,10 @@ public function actionBindGroup($courseId) $group = $this->groups->findOrThrow($this->getRequest()->getPost("groupId")); if ($group->isArchived()) { - throw new InvalidArgumentException("It is not permitted to create subgroups in archived groups"); + throw new InvalidApiArgumentException( + 'groupId', + "It is not permitted to create subgroups in archived groups" + ); } if (!$this->sisAcl->canBindGroup($group, $remoteCourse)) { @@ -527,7 +526,7 @@ public function actionBindGroup($courseId) * @DELETE * @throws BadRequestException * @throws ForbiddenRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws NotFoundException */ #[Path("courseId", new VString(), "an identifier of a SIS course", required: true)] @@ -598,7 +597,7 @@ protected function getSisUserIdOrThrow(User $user) * @param string $sisUserId * @return SisCourseRecord|mixed * @throws BadRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ private function findRemoteCourseOrThrow($remoteGroupId, $sisUserId) { diff --git a/app/V1Module/presenters/SubmitPresenter.php b/app/V1Module/presenters/SubmitPresenter.php index 9e27b82ce..2cb922237 100644 --- a/app/V1Module/presenters/SubmitPresenter.php +++ b/app/V1Module/presenters/SubmitPresenter.php @@ -5,40 +5,25 @@ use App\Helpers\MetaFormats\Attributes\Post; use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; use App\Helpers\MetaFormats\Validators\VArray; use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; -use App\Helpers\MetaFormats\Validators\VEmail; -use App\Helpers\MetaFormats\Validators\VInt; use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; -use App\Helpers\MetaFormats\Validators\VTimestamp; -use App\Helpers\MetaFormats\Validators\VUuid; -use App\Exceptions\ExerciseCompilationException; -use App\Exceptions\ExerciseCompilationSoftException; use App\Exceptions\ExerciseConfigException; use App\Exceptions\ForbiddenRequestException; use App\Exceptions\ParseException; -use App\Exceptions\SubmissionFailedException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\NotFoundException; -use App\Helpers\FileStorage\FileStorageException; use App\Helpers\FileStorageManager; use App\Helpers\EntityMetadata\Solution\SolutionParams; -use App\Helpers\ExerciseConfig\Compilation\CompilationParams; use App\Helpers\ExerciseConfig\Helper as ExerciseConfigHelper; use App\Helpers\FailureHelper; use App\Helpers\MonitorConfig; use App\Helpers\SubmissionHelper; use App\Helpers\JobConfig\Generator as JobConfigGenerator; -use App\Model\Entity\AssignmentSolutionSubmission; use App\Model\Entity\Solution; -use App\Model\Entity\SolutionFile; use App\Model\Entity\AssignmentSolution; use App\Model\Entity\Assignment; -use App\Model\Entity\AssignmentSolver; -use App\Model\Entity\SubmissionFailure; use App\Model\Entity\UploadedFile; use App\Model\Entity\User; use App\Model\Repository\Assignments; @@ -56,7 +41,6 @@ use App\Async\Dispatcher; use App\Async\Handler\ResubmitAllAsyncJobHandler; use Exception; -use Nette\Http\IResponse; /** * Endpoints for submitting an assignment @@ -245,7 +229,7 @@ public function actionCanSubmit(string $id, string $userId = null) * Submit a solution of an assignment * @POST * @throws ForbiddenRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws NotFoundException * @throws ParseException */ @@ -317,13 +301,13 @@ public function actionSubmit(string $id) * @param bool $isDebug * @return array The response that can be sent to the client * @throws ForbiddenRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws ParseException * @throws Exception */ private function finishSubmission(AssignmentSolution $solution, bool $isDebug = false) { - [ $submission, $jobConfig ] = $this->submissionHelper->submit($solution, $this->getCurrentUser(), $isDebug); + [$submission, $jobConfig] = $this->submissionHelper->submit($solution, $this->getCurrentUser(), $isDebug); // The solution needs to reload submissions (it is tedious and error prone to update them manually) $this->solutions->refresh($solution); @@ -357,7 +341,7 @@ public function checkResubmit(string $id) * Resubmit a solution (i.e., create a new submission) * @POST * @throws ForbiddenRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws NotFoundException * @throws ParseException */ @@ -393,7 +377,7 @@ public function actionResubmitAllAsyncJobStatus(string $id) $assignment = $this->assignments->findOrThrow($id); $asyncJobs = $this->asyncJobs->findPendingJobs(ResubmitAllAsyncJobHandler::ID, false, null, $assignment); $failedJobs = $this->asyncJobs->findFailedJobs(ResubmitAllAsyncJobHandler::ID, null, $assignment); - $this->sendSuccessResponse([ 'pending' => $asyncJobs, 'failed' => $failedJobs ]); + $this->sendSuccessResponse(['pending' => $asyncJobs, 'failed' => $failedJobs]); } public function checkResubmitAll(string $id) @@ -425,9 +409,9 @@ public function actionResubmitAll(string $id) $this->getCurrentUser(), $assignment ); - $asyncJobs = [ $asyncJob ]; + $asyncJobs = [$asyncJob]; } - $this->sendSuccessResponse([ 'pending' => $asyncJobs, 'failed' => $failedJobs ]); + $this->sendSuccessResponse(['pending' => $asyncJobs, 'failed' => $failedJobs]); } public function checkPreSubmit(string $id, string $userId = null) @@ -447,7 +431,7 @@ public function checkPreSubmit(string $id, string $userId = null) * submit. * @POST * @throws ExerciseConfigException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws NotFoundException */ #[Post("files", new VArray())] diff --git a/app/V1Module/presenters/UploadedFilesPresenter.php b/app/V1Module/presenters/UploadedFilesPresenter.php index 77a986d00..caf5b5b9e 100644 --- a/app/V1Module/presenters/UploadedFilesPresenter.php +++ b/app/V1Module/presenters/UploadedFilesPresenter.php @@ -5,21 +5,14 @@ use App\Helpers\MetaFormats\Attributes\Post; use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; -use App\Helpers\MetaFormats\Validators\VArray; -use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; -use App\Helpers\MetaFormats\Validators\VEmail; use App\Helpers\MetaFormats\Validators\VInt; -use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; -use App\Helpers\MetaFormats\Validators\VTimestamp; use App\Helpers\MetaFormats\Validators\VUuid; use App\Exceptions\CannotReceiveUploadedFileException; use App\Exceptions\BadRequestException; use App\Exceptions\ForbiddenRequestException; use App\Exceptions\InternalServerException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\NotFoundException; use App\Exceptions\FrontendErrorMappings; use App\Helpers\FileStorage\FileStorageException; @@ -155,7 +148,7 @@ public function checkDownload(string $id, ?string $entry = null, ?string $simila // similar solution refers to anoter solution which has detected similarities in this file // (so whoever can see plagiarisms of the original solution may see this file) $similarSolution = $this->assignmentSolutions->findOrThrow($similarSolutionId); - $fileSolution = $this->assignmentSolutions->findOneBy([ 'solution' => $file->getSolution() ]); + $fileSolution = $this->assignmentSolutions->findOneBy(['solution' => $file->getSolution()]); if ( $fileSolution && @@ -189,7 +182,8 @@ public function checkDownload(string $id, ?string $entry = null, ?string $simila #[Query( "similarSolutionId", new VUuid(), - "Id of an assignment solution which has detected possible plagiarism in this file. This is basically a shortcut (hint) for ACLs.", + "Id of an assignment solution which has detected possible plagiarism in this file. " + . "This is basically a shortcut (hint) for ACLs.", required: false, )] #[Path("id", new VString(), "Identifier of the file", required: true)] @@ -204,7 +198,7 @@ public function actionDownload(string $id, ?string $entry = null) throw new NotFoundException( "File not found in the storage", FrontendErrorMappings::E404_000__NOT_FOUND, - [ 'entry' => $entry ], + ['entry' => $entry], $ex ); } @@ -236,7 +230,8 @@ public function checkContent(string $id, ?string $entry = null, ?string $similar #[Query( "similarSolutionId", new VUuid(), - "Id of an assignment solution which has detected possible plagiarism in this file. This is basically a shortcut (hint) for ACLs.", + "Id of an assignment solution which has detected possible plagiarism in this file. " + . "This is basically a shortcut (hint) for ACLs.", required: false, )] #[Path("id", new VString(), "Identifier of the file", required: true)] @@ -251,7 +246,7 @@ public function actionContent(string $id, ?string $entry = null) throw new NotFoundException( "File not found in the storage", FrontendErrorMappings::E404_000__NOT_FOUND, - [ 'entry' => $entry ], + ['entry' => $entry], $ex ); } @@ -319,7 +314,7 @@ public function checkUpload() /** * Upload a file * @POST - * @throws InvalidArgumentException for files with invalid names + * @throws InvalidApiArgumentException for files with invalid names * @throws ForbiddenRequestException * @throws BadRequestException * @throws CannotReceiveUploadedFileException @@ -436,7 +431,7 @@ public function checkAppendPartial(string $id) /** * Add another chunk to partial upload. * @PUT - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws ForbiddenRequestException * @throws BadRequestException * @throws CannotReceiveUploadedFileException @@ -449,7 +444,7 @@ public function actionAppendPartial(string $id, int $offset) $partialFile = $this->uploadedPartialFiles->findOrThrow($id); if ($partialFile->getUploadedSize() !== $offset) { - throw new InvalidArgumentException( + throw new InvalidApiArgumentException( 'offset', "The offset must corresponds with the actual upload size of the partial file." ); diff --git a/app/V1Module/presenters/UsersPresenter.php b/app/V1Module/presenters/UsersPresenter.php index 7ace3f00f..f0d49d9e5 100644 --- a/app/V1Module/presenters/UsersPresenter.php +++ b/app/V1Module/presenters/UsersPresenter.php @@ -5,19 +5,15 @@ use App\Helpers\MetaFormats\Attributes\Post; use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; use App\Helpers\MetaFormats\Validators\VArray; use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; use App\Helpers\MetaFormats\Validators\VEmail; use App\Helpers\MetaFormats\Validators\VInt; use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; -use App\Helpers\MetaFormats\Validators\VTimestamp; -use App\Helpers\MetaFormats\Validators\VUuid; use App\Exceptions\ForbiddenRequestException; use App\Exceptions\FrontendErrorMappings; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\NotFoundException; use App\Exceptions\WrongCredentialsException; use App\Model\Entity\ExternalLogin; @@ -245,7 +241,7 @@ public function checkUpdateProfile(string $id) * @POST * @throws BadRequestException * @throws ForbiddenRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws WrongCredentialsException * @throws NotFoundException */ @@ -307,7 +303,7 @@ public function actionUpdateProfile(string $id) * @param User $user * @param null|string $email * @throws BadRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ private function changeUserEmail(User $user, ?string $email) { @@ -323,7 +319,7 @@ private function changeUserEmail(User $user, ?string $email) } if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) { - throw new InvalidArgumentException('email', "Provided email is not in correct format"); + throw new InvalidApiArgumentException('email', "Provided email is not in correct format"); } $oldEmail = $user->getEmail(); @@ -388,7 +384,7 @@ private function changePersonalData( * @param null|string $oldPassword * @param null|string $password * @param null|string $passwordConfirm - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws WrongCredentialsException */ private function changeUserPassword( @@ -404,7 +400,7 @@ private function changeUserPassword( if (!$password || !$passwordConfirm) { // old password was provided but the new ones not, illegal state - throw new InvalidArgumentException('password|passwordConfirm', "New password was not provided"); + throw new InvalidApiArgumentException('password|passwordConfirm', "New password was not provided"); } // passwords need to be handled differently @@ -492,13 +488,15 @@ public function checkUpdateSettings(string $id) #[Post( "assignmentSubmitAfterAcceptedEmails", new VBool(), - "Flag if email should be sent to group supervisor if a student submits new solution for already accepted assignment", + "Flag if email should be sent to the group supervisor if a student submits new solution " + . "for already accepted assignment", required: false, )] #[Post( "assignmentSubmitAfterReviewedEmails", new VBool(), - "Flag if email should be sent to group supervisor if a student submits new solution for already reviewed and not accepted assignment", + "Flag if email should be sent to group supervisor if a student submits new solution " + . "for already reviewed and not accepted assignment", required: false, )] #[Post( @@ -516,7 +514,8 @@ public function checkUpdateSettings(string $id) #[Post( "solutionReviewRequestedEmails", new VBool(), - "Flag if notification should be send to a teacher when a solution reviewRequested flag is chagned in a supervised/admined group.", + "Flag if notification should be send to a teacher when a solution reviewRequested flag is changed " + . "in a supervised/admin-ed group.", required: false, )] #[Path("id", new VString(), "Identifier of the user", required: true)] @@ -632,7 +631,7 @@ public function checkCreateLocalAccount(string $id) * If user is registered externally, add local account as another login method. * Created password is empty and has to be changed in order to use it. * @POST - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ #[Path("id", new VString(), required: true)] public function actionCreateLocalAccount(string $id) @@ -752,7 +751,7 @@ public function checkSetRole(string $id) /** * Set a given role to the given user. * @POST - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws NotFoundException */ #[Post("role", new VString(1), "Role which should be assigned to the user")] @@ -763,7 +762,7 @@ public function actionSetRole(string $id) $role = $this->getRequest()->getPost("role"); // validate role if (!$this->roles->validateRole($role)) { - throw new InvalidArgumentException("role", "Unknown user role '$role'"); + throw new InvalidApiArgumentException('role', "Unknown user role '$role'"); } $user->setRole($role); @@ -822,7 +821,7 @@ public function checkSetAllowed(string $id) /** * Set "isAllowed" flag of the given user. The flag determines whether a user may perform any operation of the API. * @POST - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws NotFoundException */ #[Post("isAllowed", new VBool(), "Whether the user is allowed (active) or not.")] @@ -849,7 +848,7 @@ public function checkUpdateExternalLogin(string $id, string $service) /** * Add or update existing external ID of given authentication service. * @POST - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ #[Post("externalId", new VString(1, 128))] #[Path("id", new VString(), "identifier of the user", required: true)] @@ -864,7 +863,7 @@ public function actionUpdateExternalLogin(string $id, string $service) if ($anotherUser) { if ($anotherUser->getId() !== $id) { // oopsie, this external ID is alreay used for a different user - throw new InvalidArgumentException('externalId', "This ID is already used by another user."); + throw new InvalidApiArgumentException('externalId', "This ID is already used by another user."); } // otherwise the external ID is already set to this user, so there is nothing to change... } else { diff --git a/app/V1Module/presenters/WorkerFilesPresenter.php b/app/V1Module/presenters/WorkerFilesPresenter.php index c9a7b5b6e..9fd219a90 100644 --- a/app/V1Module/presenters/WorkerFilesPresenter.php +++ b/app/V1Module/presenters/WorkerFilesPresenter.php @@ -2,26 +2,15 @@ namespace App\V1Module\Presenters; -use App\Helpers\MetaFormats\Attributes\Post; -use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; -use App\Helpers\MetaFormats\Validators\VArray; -use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; -use App\Helpers\MetaFormats\Validators\VEmail; -use App\Helpers\MetaFormats\Validators\VInt; -use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; -use App\Helpers\MetaFormats\Validators\VTimestamp; -use App\Helpers\MetaFormats\Validators\VUuid; use App\Helpers\BasicAuthHelper; use App\Helpers\WorkerFilesConfig; use App\Helpers\FileStorageManager; use App\Exceptions\HttpBasicAuthException; use App\Exceptions\NotFoundException; use App\Exceptions\WrongCredentialsException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\ForbiddenRequestException; use App\Exceptions\UploadedFileException; use App\Model\Repository\AssignmentSolutionSubmissions; @@ -71,7 +60,7 @@ private function getSubmissionsRepository(string $type) } elseif ($type === AssignmentSolutionSubmission::JOB_TYPE) { return $this->assignmentSubmissions; } else { - throw new InvalidArgumentException("Invalid submission type '$type'"); + throw new InvalidApiArgumentException('type', "Invalid submission type '$type'"); } } diff --git a/app/V1Module/presenters/base/BasePresenter.php b/app/V1Module/presenters/base/BasePresenter.php index bd3d2000d..e2d87e631 100644 --- a/app/V1Module/presenters/base/BasePresenter.php +++ b/app/V1Module/presenters/base/BasePresenter.php @@ -11,7 +11,6 @@ use App\Exceptions\ForbiddenRequestException; use App\Exceptions\WrongHttpMethodException; use App\Exceptions\NotImplementedException; -use App\Exceptions\InvalidArgumentException; use App\Exceptions\InternalServerException; use App\Exceptions\FrontendErrorMappings; use App\Security\AccessManager; @@ -20,21 +19,17 @@ use App\Helpers\UserActions; use App\Helpers\Validators; use App\Helpers\FileStorage\IImmutableFile; -use App\Helpers\AnnotationsParser; use App\Helpers\MetaFormats\FormatCache; use App\Helpers\MetaFormats\MetaFormat; -use App\Helpers\MetaFormats\MetaRequest; use App\Helpers\MetaFormats\RequestParamData; use App\Helpers\MetaFormats\Type; use App\Responses\StorageFileResponse; use App\Responses\ZipFilesResponse; use Nette\Application\Application; use Nette\Http\IResponse; -use Nette\Utils\Arrays; use Tracy\ILogger; use ReflectionClass; use ReflectionMethod; -use LogicException; use ReflectionException; class BasePresenter extends \App\Presenters\BasePresenter @@ -244,8 +239,8 @@ private function processParamsLoose(array $paramData) * @param ?array $valueDictionary If not null, a nested format instance will be created. The values will be taken * from here instead of the request object. Format validation ignores parameter type (path, query or post). * A top-level format will be created if null. - * @throws \App\Exceptions\InternalServerException Thrown when the format definition is corrupted/absent. - * @throws \App\Exceptions\BadRequestException Thrown when the request parameter values do not conform to the definition. + * @throws InternalServerException Thrown when the format definition is corrupted/absent. + * @throws BadRequestException Thrown when the request parameter values do not conform to the definition. * @return MetaFormat Returns a format instance with values filled from the request object. */ private function processParamsFormat(string $format, ?array $valueDictionary): MetaFormat @@ -265,7 +260,7 @@ private function processParamsFormat(string $format, ?array $valueDictionary): M // top-level format if ($valueDictionary === null) { $value = $this->getValueFromParamData($requestParamData); - // nested format + // nested format } else { // Instead of retrieving the values with the getRequest call, use the provided $valueDictionary. // This makes the nested format ignore the parameter type (path, query, post) which is intended. diff --git a/app/V1Module/security/AccessToken.php b/app/V1Module/security/AccessToken.php index bfc3ee345..0dc3015d3 100644 --- a/app/V1Module/security/AccessToken.php +++ b/app/V1Module/security/AccessToken.php @@ -3,9 +3,9 @@ namespace App\Security; use App\Exceptions\InvalidAccessTokenException; -use App\Exceptions\InvalidArgumentException; use Firebase\JWT\JWT; use stdClass; +use InvalidArgumentException; class AccessToken { diff --git a/app/V1Module/security/InvitationToken.php b/app/V1Module/security/InvitationToken.php index a81ee740c..ceaa1086f 100644 --- a/app/V1Module/security/InvitationToken.php +++ b/app/V1Module/security/InvitationToken.php @@ -3,7 +3,6 @@ namespace App\Security; use App\Exceptions\InvalidAccessTokenException; -use App\Exceptions\InvalidArgumentException; use Firebase\JWT\JWT; use DateTime; @@ -39,7 +38,7 @@ public static function create( "eml" => $email, "iat" => time(), "exp" => time() + $expirationTime, - "usr" => [ $titlesBefore, $firstName, $lastName, $titlesAfter ], + "usr" => [$titlesBefore, $firstName, $lastName, $titlesAfter], "grp" => $groupsIds, ]); } @@ -51,7 +50,7 @@ public static function create( */ public function __construct(array $payload) { - $props = [ "iid" => "string", "eml" => "string", "iat" => "integer", "exp" => "integer", "usr" => "array"]; + $props = ["iid" => "string", "eml" => "string", "iat" => "integer", "exp" => "integer", "usr" => "array"]; foreach ($props as $name => $type) { if (!array_key_exists($name, $payload) || gettype($payload[$name]) !== $type) { throw new InvalidAccessTokenException( @@ -118,7 +117,7 @@ public function getEmail(): string public function getUserData(): array { list($titlesBefore, $firstName, $lastName, $titlesAfter) = $this->payload["usr"]; - return [ $this->payload["eml"], $firstName, $lastName, $titlesBefore, $titlesAfter ]; + return [$this->payload["eml"], $firstName, $lastName, $titlesBefore, $titlesAfter]; } /** diff --git a/app/V1Module/security/UserStorage.php b/app/V1Module/security/UserStorage.php index 7005e5199..6e546068c 100644 --- a/app/V1Module/security/UserStorage.php +++ b/app/V1Module/security/UserStorage.php @@ -3,10 +3,10 @@ namespace App\Security; use App\Exceptions\InvalidAccessTokenException; -use App\Exceptions\InvalidArgumentException; use App\Model\Entity\User; use Nette; use Nette\Security\IIdentity; +use InvalidArgumentException; class UserStorage implements Nette\Security\UserStorage { diff --git a/app/async/Dispatcher.php b/app/async/Dispatcher.php index 6840a1b60..3633538eb 100644 --- a/app/async/Dispatcher.php +++ b/app/async/Dispatcher.php @@ -5,7 +5,6 @@ use App\Model\Entity\AsyncJob; use App\Model\Repository\AsyncJobs; use Doctrine\ORM\EntityManagerInterface; -use Nette\Utils\Arrays; use Nette; use InvalidArgumentException; use DateTime; @@ -59,7 +58,7 @@ public function __construct($config, array $knownHandlers, AsyncJobs $asyncJobs, * @param DateTime|null $scheduleAt when the job should be executed (null == immediately) * @throws InvalidArgumentException */ - public function schedule(AsyncJob $job, DateTime $scheduleAt = null) + public function schedule(AsyncJob $job, ?DateTime $scheduleAt = null) { $command = $job->getCommand(); if (!array_key_exists($command, $this->knownHandlers)) { diff --git a/app/exceptions/InvalidArgumentException.php b/app/exceptions/InvalidArgumentException.php index a62f10952..017fceb05 100644 --- a/app/exceptions/InvalidArgumentException.php +++ b/app/exceptions/InvalidArgumentException.php @@ -8,7 +8,7 @@ * Used if there is something very wrong with some particular parameter. * It may be wrong type or missing argument or something similar. */ -class InvalidArgumentException extends ApiException +class InvalidApiArgumentException extends ApiException { /** * Creates exception with invalid argument name and some further description. diff --git a/app/helpers/Emails/EmailVerificationHelper/EmailVerificationHelper.php b/app/helpers/Emails/EmailVerificationHelper/EmailVerificationHelper.php index 04957c34e..b436eb3db 100644 --- a/app/helpers/Emails/EmailVerificationHelper/EmailVerificationHelper.php +++ b/app/helpers/Emails/EmailVerificationHelper/EmailVerificationHelper.php @@ -4,7 +4,7 @@ use App\Exceptions\ForbiddenRequestException; use App\Exceptions\InvalidAccessTokenException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\InvalidStateException; use App\Helpers\Emails\EmailLatteFactory; use App\Helpers\Emails\EmailLocalizationHelper; @@ -103,7 +103,7 @@ public function process(User $user, bool $firstTime = false) * @return bool * @throws ForbiddenRequestException * @throws InvalidAccessTokenException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ public function verify(User $user, AccessToken $token) { diff --git a/app/helpers/Evaluation/ScoreCalculators/ScoreCalculatorAccessor.php b/app/helpers/Evaluation/ScoreCalculators/ScoreCalculatorAccessor.php index 8612786c5..f90cbe004 100644 --- a/app/helpers/Evaluation/ScoreCalculators/ScoreCalculatorAccessor.php +++ b/app/helpers/Evaluation/ScoreCalculators/ScoreCalculatorAccessor.php @@ -2,10 +2,10 @@ namespace App\Helpers\Evaluation; -use App\Exceptions\InvalidArgumentException; use App\Helpers\Evaluation\IScoreCalculator; use Nette; use Nette\Utils\Arrays; +use InvalidArgumentException; /** * Provides access to different implementations of score calculation diff --git a/app/helpers/ExternalLogin/ExternalServiceAuthenticator.php b/app/helpers/ExternalLogin/ExternalServiceAuthenticator.php index e332af03f..b9e4e6fc1 100644 --- a/app/helpers/ExternalLogin/ExternalServiceAuthenticator.php +++ b/app/helpers/ExternalLogin/ExternalServiceAuthenticator.php @@ -6,7 +6,6 @@ use App\Exceptions\FrontendErrorMappings; use App\Exceptions\WrongCredentialsException; use App\Exceptions\InvalidExternalTokenException; -use App\Exceptions\InvalidArgumentException; use App\Exceptions\ForbiddenRequestException; use App\Model\Entity\Instance; use App\Model\Entity\User; @@ -23,6 +22,7 @@ use Firebase\JWT\Key; use DomainException; use UnexpectedValueException; +use InvalidArgumentException; /** * Mapper of service identification to object instance diff --git a/app/helpers/ExternalLogin/UserData.php b/app/helpers/ExternalLogin/UserData.php index 58f765208..b173e9d09 100644 --- a/app/helpers/ExternalLogin/UserData.php +++ b/app/helpers/ExternalLogin/UserData.php @@ -2,9 +2,9 @@ namespace App\Helpers\ExternalLogin; -use App\Exceptions\InvalidArgumentException; use App\Model\Entity\Instance; use App\Model\Entity\User; +use InvalidArgumentException; /** * Common data about user every identity provider should know. @@ -52,7 +52,7 @@ public function getRole(): ?string * @param array|object $data from decoded token * @param string|null $defaultRole role set if no role is available in the data */ - public function __construct($data, string $defaultRole = null) + public function __construct($data, ?string $defaultRole = null) { $data = (array)$data; diff --git a/app/helpers/FileStorageManager.php b/app/helpers/FileStorageManager.php index 697badd3e..a8065c33e 100644 --- a/app/helpers/FileStorageManager.php +++ b/app/helpers/FileStorageManager.php @@ -8,16 +8,13 @@ use App\Helpers\FileStorage\FileStorageException; use App\Model\Entity\Submission; use App\Model\Entity\Solution; -use App\Model\Entity\ReferenceExerciseSolution; -use App\Model\Entity\AssignmentSolution; use App\Model\Entity\AssignmentSolutionSubmission; use App\Model\Entity\ReferenceSolutionSubmission; use App\Model\Entity\UploadedFile; use App\Model\Entity\UploadedPartialFile; use App\Model\Entity\AttachmentFile; use App\Helpers\TmpFilesHelper; -use App\Exceptions\InvalidArgumentException; -use Nette\Utils\Arrays; +use App\Exceptions\InvalidApiArgumentException; use Nette\Http\FileUpload; use Nette; use DateTime; @@ -192,14 +189,14 @@ private function getUploadedFilePath(UploadedFile $file): string * Store uploaded file data for associated UploadedFile db record. * @param UploadedFile $fileRecord database entity that corresponds to the uploaded file * @param FileUpload $fileData wrapper of the actual uploaded file to be saved - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws FileStorageException */ public function storeUploadedFile(UploadedFile $fileRecord, FileUpload $fileData) { $path = $this->getUploadedFilePath($fileRecord); if (!$fileData->isOk()) { - throw new InvalidArgumentException("fileData", "File was not uploaded successfully"); + throw new InvalidApiArgumentException('fileData', "File was not uploaded successfully"); } // copy (moving may not be safe), no overwrite diff --git a/app/helpers/MetaFormats/MetaFormat.php b/app/helpers/MetaFormats/MetaFormat.php index a3a508a41..48f4dcf98 100644 --- a/app/helpers/MetaFormats/MetaFormat.php +++ b/app/helpers/MetaFormats/MetaFormat.php @@ -3,6 +3,7 @@ namespace App\Helpers\MetaFormats; use App\Exceptions\InternalServerException; +use App\Exceptions\InvalidApiArgumentException; class MetaFormat { @@ -11,8 +12,8 @@ class MetaFormat * The method has no return value. * @param string $fieldName The name of the field. * @param mixed $value The value to be assigned. - * @throws \App\Exceptions\InternalServerException Thrown when the field was not found. - * @throws \App\Exceptions\InvalidArgumentException Thrown when the value is not assignable. + * @throws InternalServerException Thrown when the field was not found. + * @throws InvalidApiArgumentException Thrown when the value is not assignable. */ public function checkIfAssignable(string $fieldName, mixed $value) { @@ -30,8 +31,8 @@ public function checkIfAssignable(string $fieldName, mixed $value) * The exception details why the value does not conform to the format. * @param string $fieldName The name of the field. * @param mixed $value The value to be assigned. - * @throws \App\Exceptions\InternalServerException Thrown when the field was not found. - * @throws \App\Exceptions\InvalidArgumentException Thrown when the value is not assignable. + * @throws InternalServerException Thrown when the field was not found. + * @throws InvalidApiArgumentException Thrown when the value is not assignable. */ public function checkedAssign(string $fieldName, mixed $value) { diff --git a/app/helpers/MetaFormats/RequestParamData.php b/app/helpers/MetaFormats/RequestParamData.php index b06f8e0b3..a095c3b95 100644 --- a/app/helpers/MetaFormats/RequestParamData.php +++ b/app/helpers/MetaFormats/RequestParamData.php @@ -3,12 +3,11 @@ namespace App\Helpers\MetaFormats; use App\Exceptions\InternalServerException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Helpers\MetaFormats\Validators\BaseValidator; use App\Helpers\MetaFormats\Validators\VArray; use App\Helpers\MetaFormats\Validators\VObject; use App\Helpers\Swagger\AnnotationParameterData; -use Exception; /** * Data class containing metadata for request parameters. @@ -45,7 +44,7 @@ public function __construct( * Checks whether a value meets this definition. If the definition is not met, an exception is thrown. * The method has no return value. * @param mixed $value The value to be checked. - * @throws \App\Exceptions\InvalidArgumentException Thrown when the value does not meet the definition. + * @throws InvalidApiArgumentException Thrown when the value does not meet the definition. */ public function conformsToDefinition(mixed $value) { @@ -58,7 +57,7 @@ public function conformsToDefinition(mixed $value) // required parameters can be null only if explicitly nullable if (!$this->nullable) { - throw new InvalidArgumentException( + throw new InvalidApiArgumentException( $this->name, "The parameter is not nullable and thus cannot be null." ); @@ -73,7 +72,7 @@ public function conformsToDefinition(mixed $value) foreach ($this->validators as $validator) { if (!$validator->validate($value)) { $type = $validator::SWAGGER_TYPE; - throw new InvalidArgumentException( + throw new InvalidApiArgumentException( $this->name, "The provided value did not pass the validation of type '{$type}'." ); diff --git a/app/helpers/Pagination.php b/app/helpers/Pagination.php index 4d6005127..ffdad95ad 100644 --- a/app/helpers/Pagination.php +++ b/app/helpers/Pagination.php @@ -3,7 +3,7 @@ namespace App\Helpers; use Nette\Utils\Strings; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\InternalServerException; /** @@ -57,15 +57,15 @@ class Pagination * identifier is prefixed with '!', DESC ordering is used instead of ASC. * @param array $filters Array of filters and their values. Filters are endpoint-specific. * @param array|null $knownFilters Array of known filter names. If present, unknown filters will trigger exception. - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ public function __construct( int $offset = 0, - int $limit = null, - string $locale = null, - string $orderBy = null, + ?int $limit = null, + ?string $locale = null, + ?string $orderBy = null, array $filters = [], - array $knownFilters = null + ?array $knownFilters = null ) { $this->offset = $offset < 0 ? 0 : $offset; $this->limit = $limit < 0 ? null : $limit; @@ -78,7 +78,7 @@ public function __construct( $knownFilters = array_flip($knownFilters); foreach ($filters as $name => $unused) { if (!array_key_exists($name, $knownFilters)) { - throw new InvalidArgumentException("filter", "unknown filter '$name'"); + throw new InvalidApiArgumentException('filter', "unknown filter '$name'"); } } } diff --git a/app/helpers/SisHelper/SisHelper.php b/app/helpers/SisHelper/SisHelper.php index 7648029da..55d2e9377 100644 --- a/app/helpers/SisHelper/SisHelper.php +++ b/app/helpers/SisHelper/SisHelper.php @@ -2,10 +2,12 @@ namespace App\Helpers; -use App\Exceptions\InvalidArgumentException; +use InvalidArgumentException; use Generator; use Nette; -use GuzzleHttp; +use GuzzleHttp\HandlerStack; +use GuzzleHttp\Client; +use GuzzleHttp\Exception\ClientException; use Nette\Utils\Json; class SisHelper @@ -24,9 +26,9 @@ class SisHelper * @param string $apiBase * @param string $faculty * @param string $secret - * @param GuzzleHttp\HandlerStack|null $handler An optional HTTP handler (mainly for unit testing purposes) + * @param HandlerStack|null $handler An optional HTTP handler (mainly for unit testing purposes) */ - public function __construct($apiBase, $faculty, $secret, GuzzleHttp\HandlerStack $handler = null) + public function __construct($apiBase, $faculty, $secret, ?HandlerStack $handler = null) { $this->apiBase = $apiBase; $this->faculty = $faculty; @@ -44,7 +46,7 @@ public function __construct($apiBase, $faculty, $secret, GuzzleHttp\HandlerStack $options['handler'] = $handler; } - $this->client = new GuzzleHttp\Client($options); + $this->client = new Client($options); } /** @@ -73,11 +75,11 @@ public function getCourses($sisUserId, $year = null, $term = 1) try { $response = $this->client->get('', ['query' => $params]); - } catch (GuzzleHttp\Exception\ClientException $e) { - throw new InvalidArgumentException("Invalid year or semester number"); + } catch (ClientException $e) { + throw new InvalidArgumentException("Invalid year or semester number", 0, $e); } - $data = Json::decode($response->getBody()->getContents(), Json::FORCE_ARRAY); + $data = Json::decode($response->getBody()->getContents(), true); foreach ($data["events"] as $course) { yield SisCourseRecord::fromArray($sisUserId, $course); diff --git a/app/helpers/SubmissionHelper/SubmissionHelper.php b/app/helpers/SubmissionHelper/SubmissionHelper.php index ea32f66bc..437be6ec6 100644 --- a/app/helpers/SubmissionHelper/SubmissionHelper.php +++ b/app/helpers/SubmissionHelper/SubmissionHelper.php @@ -6,7 +6,7 @@ use App\Exceptions\SubmissionFailedException; use App\Exceptions\ForbiddenRequestException; use App\Exceptions\ParseException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\ExerciseCompilationException; use App\Exceptions\ExerciseCompilationSoftException; use App\Exceptions\ExerciseConfigException; @@ -199,10 +199,10 @@ public function getFilesSize(array $uploadedFiles): int /** * Retrieve uploaded files and verify, they can be used for submission. * @param string[] $ids - * @param string $reqArgumentName arg name for InvalidArgumentException if the IDs are not valid + * @param string $reqArgumentName arg name for InvalidApiArgumentException if the IDs are not valid * (so we do not have to catch and re-throw an exception) * @return UploadedFile[] - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws ForbiddenRequestException */ public function getUploadedFiles( @@ -214,7 +214,7 @@ public function getUploadedFiles( // retrieve and check uploaded files $files = $this->uploadedFiles->findAllById($ids); if (count($files) === 0) { - throw new InvalidArgumentException($reqArgumentName, "No files were uploaded"); + throw new InvalidApiArgumentException($reqArgumentName, "No files were uploaded"); } // preform basic checks on uploaded files @@ -228,11 +228,14 @@ public function getUploadedFiles( // perform size/count limits checks on submitted files if ($countLimit !== null && count($files) > $countLimit) { - throw new InvalidArgumentException($reqArgumentName, "Number of uploaded files exceeds assignment limits"); + throw new InvalidApiArgumentException( + $reqArgumentName, + "Number of uploaded files exceeds assignment limits" + ); } if ($sizeLimit !== null && $this->getFilesSize($files) > $sizeLimit) { - throw new InvalidArgumentException( + throw new InvalidApiArgumentException( $reqArgumentName, "Total size of uploaded files exceeds assignment limits" ); @@ -294,7 +297,7 @@ public function prepareUploadedFilesForSubmit(array $files, Solution $solution) * @param bool $isDebug * @return array tuple containing created entities [ AssignmentSolutionSubmission, JobConfig ] * @throws ForbiddenRequestException - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException * @throws ParseException * @throws Exception */ @@ -305,7 +308,7 @@ public function submit(AssignmentSolution $solution, User $user, bool $isDebug = } if ($solution->getId() === null) { - throw new InvalidArgumentException("The solution object is missing an id"); + throw new InvalidApiArgumentException('solution', "The solution object is missing an id"); } // check for the license of instance of user @@ -313,7 +316,7 @@ public function submit(AssignmentSolution $solution, User $user, bool $isDebug = if ($assignment->getGroup() && $assignment->getGroup()->hasValidLicence() === false) { throw new ForbiddenRequestException( "Your institution does not have a valid licence and you cannot submit solutions for any assignment " . - "in this group '{$assignment->getGroup()->getId()}'. Contact your supervisor for assistance.", + "in this group '{$assignment->getGroup()->getId()}'. Contact your supervisor for assistance.", IResponse::S402_PAYMENT_REQUIRED ); } @@ -363,7 +366,7 @@ public function submit(AssignmentSolution $solution, User $user, bool $isDebug = // If the submission was accepted we now have the URL where to look for the results later -> persist it $this->assignmentSubmissions->persist($submission); - return [ $submission, $jobConfig ]; + return [$submission, $jobConfig]; } /** @@ -443,6 +446,6 @@ public function submitReference( } $this->referenceSubmissions->flush(); - return [ $submission, $jobConfig ]; + return [$submission, $jobConfig]; } } diff --git a/app/helpers/Swagger/AnnotationHelper.php b/app/helpers/Swagger/AnnotationHelper.php index 942cc4aab..5d6d0ae59 100644 --- a/app/helpers/Swagger/AnnotationHelper.php +++ b/app/helpers/Swagger/AnnotationHelper.php @@ -2,16 +2,16 @@ namespace App\Helpers\Swagger; -use App\Exceptions\InvalidArgumentException; use App\Helpers\MetaFormats\FormatCache; use App\Helpers\MetaFormats\MetaFormatHelper; use App\V1Module\Router\MethodRoute; use App\V1Module\RouterFactory; +use Nette\Routing\RouteList; use ReflectionClass; use ReflectionException; use ReflectionMethod; use Exception; -use Nette\Routing\RouteList; +use InvalidArgumentException; /** * Parser that can parse the annotations of existing recodex endpoints. @@ -20,27 +20,27 @@ class AnnotationHelper { private static $nullableSuffix = '|null'; private static $typeMap = [ - 'bool' => 'boolean', - 'boolean' => 'boolean', - 'array' => 'array', - 'int' => 'integer', - 'integer' => 'integer', - 'float' => 'number', - 'number' => 'number', - 'numeric' => 'number', - 'numericint' => 'integer', - 'timestamp' => 'integer', - 'string' => 'string', - 'unicode' => 'string', - 'email' => 'string', - 'url' => 'string', - 'uri' => 'string', - 'pattern' => null, - 'alnum' => 'string', - 'alpha' => 'string', - 'digit' => 'string', - 'lower' => 'string', - 'upper' => 'string', + 'bool' => 'boolean', + 'boolean' => 'boolean', + 'array' => 'array', + 'int' => 'integer', + 'integer' => 'integer', + 'float' => 'number', + 'number' => 'number', + 'numeric' => 'number', + 'numericint' => 'integer', + 'timestamp' => 'integer', + 'string' => 'string', + 'unicode' => 'string', + 'email' => 'string', + 'url' => 'string', + 'uri' => 'string', + 'pattern' => null, + 'alnum' => 'string', + 'alpha' => 'string', + 'digit' => 'string', + 'lower' => 'string', + 'upper' => 'string', ]; private static $presenterNamespace = 'App\V1Module\Presenters\\'; @@ -362,7 +362,7 @@ public static function extractAttributeData(string $className, string $methodNam // if the endpoint is linked to a format, use the format class if ($format !== null) { $attributeData = FormatCache::getFieldDefinitions($format); - // otherwise use loose param attributes + // otherwise use loose param attributes } else { $attributeData = MetaFormatHelper::extractRequestParamData($reflectionMethod); } @@ -472,7 +472,7 @@ public static function getPropertyValue(mixed $object, string $propertyName): mi return $property->getValue($object); } - /** + /** * Extracts the route string from a route object. Replaces '<..>' in the route with '{...}'. * @param mixed $routeObj */ diff --git a/app/model/entity/BooleanPipelineParameter.php b/app/model/entity/BooleanPipelineParameter.php index 9cd323054..d2b3f50d6 100644 --- a/app/model/entity/BooleanPipelineParameter.php +++ b/app/model/entity/BooleanPipelineParameter.php @@ -2,7 +2,7 @@ namespace App\Model\Entity; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use Doctrine\ORM\Mapping as ORM; /** @@ -25,7 +25,7 @@ public function setValue($value) $value = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); if ($value === null) { - throw new InvalidArgumentException(sprintf("Invalid value for parameter %s", $this->name)); + throw new InvalidApiArgumentException($this->name, "Not a boolean parameter."); } $this->booleanValue = $value; diff --git a/app/model/entity/GroupExternalAttribute.php b/app/model/entity/GroupExternalAttribute.php index 5180874a5..5e64b4b57 100644 --- a/app/model/entity/GroupExternalAttribute.php +++ b/app/model/entity/GroupExternalAttribute.php @@ -3,8 +3,6 @@ namespace App\Model\Entity; use Doctrine\ORM\Mapping as ORM; -use App\Exceptions\InvalidArgumentException; -use Nette\Utils\Validators; use JsonSerializable; /** diff --git a/app/model/entity/Login.php b/app/model/entity/Login.php index 8ec99e20e..effb4d6e8 100644 --- a/app/model/entity/Login.php +++ b/app/model/entity/Login.php @@ -3,7 +3,7 @@ namespace App\Model\Entity; use Doctrine\ORM\Mapping as ORM; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use Nette\Security\Passwords; use Nette\Utils\Validators; @@ -127,12 +127,12 @@ public function passwordsMatch($password, Passwords $passwordsService) * @return Login * @param Passwords|null $passwordsService injection of a service (we do not want to inject directly into entities) * if null, the service is constructed inplace (special case to make fixtures work) - * @throws InvalidArgumentException + * @throws InvalidApiArgumentException */ - public static function createLogin(User $user, string $email, string $password, Passwords $passwordsService = null) + public static function createLogin(User $user, string $email, string $password, ?Passwords $passwordsService = null) { if (Validators::isEmail($email) === false) { - throw new InvalidArgumentException("email", "Username must be a valid email address."); + throw new InvalidApiArgumentException('email', "Username must be a valid email address."); } if ($passwordsService === null) { diff --git a/app/model/entity/Pipeline.php b/app/model/entity/Pipeline.php index 3f6fda03b..a04cb8007 100644 --- a/app/model/entity/Pipeline.php +++ b/app/model/entity/Pipeline.php @@ -2,7 +2,7 @@ namespace App\Model\Entity; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Helpers\ExerciseConfig\Pipeline as ExerciseConfigPipeline; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; @@ -265,7 +265,7 @@ public function setParameters($parameters) { foreach ($parameters as $name => $value) { if (!array_key_exists($name, static::DEFAULT_PARAMETERS)) { - throw new InvalidArgumentException(sprintf("Unknown parameter %s", $name)); + throw new InvalidApiArgumentException($name, "Unknown parameter"); } if ($this->parameters->containsKey($name)) { @@ -279,7 +279,7 @@ public function setParameters($parameters) if (is_string($default)) { $parameter = new StringPipelineParameter($this, $name); } else { - throw new InvalidArgumentException(sprintf("Unsupported value type for parameter %s", $name)); + throw new InvalidApiArgumentException($name, "Unsupported value type"); } } diff --git a/app/model/entity/StringPipelineParameter.php b/app/model/entity/StringPipelineParameter.php index 3ddc407fc..555f32d58 100644 --- a/app/model/entity/StringPipelineParameter.php +++ b/app/model/entity/StringPipelineParameter.php @@ -2,7 +2,7 @@ namespace App\Model\Entity; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use Doctrine\ORM\Mapping as ORM; /** @@ -23,7 +23,7 @@ public function getValue() public function setValue($value) { if (!is_string($value)) { - throw new InvalidArgumentException(sprintf("Invalid value for parameter %s", $this->name)); + throw new InvalidApiArgumentException($this->name, "String value expected"); } $this->stringValue = $value; diff --git a/app/model/helpers/PaginationDBHelper.php b/app/model/helpers/PaginationDBHelper.php index 0f7ad761d..e97839609 100644 --- a/app/model/helpers/PaginationDBHelper.php +++ b/app/model/helpers/PaginationDBHelper.php @@ -4,7 +4,7 @@ use App\Helpers\Pagination; use Doctrine\ORM\QueryBuilder; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use Doctrine\ORM\Query; use DoctrineExtensions\Query\OrderByCollationInjectionMysqlWalker; @@ -82,12 +82,13 @@ private function addSearchCondition(QueryBuilder $qb, string $searchToken, strin /** * Createa and initialize the helper. - * @param array $orderByColumns Known order by names (sent from UI), each holdin a list of corresponding order by DB columns. + * @param array $orderByColumns Known order by names (sent from UI), each holding a list + * of corresponding order by DB columns. * @param array $searchCols List of columns which are tested by fultext search filter. * @param string|null $localizedTextsClass Name of an entity class which is used for localization texts. * If null, no localization is expected. */ - public function __construct(array $orderByColumns, array $searchCols, string $localizedTextsClass = null) + public function __construct(array $orderByColumns, array $searchCols, ?string $localizedTextsClass = null) { $this->orderByColumns = $orderByColumns; $this->searchCols = $searchCols; @@ -100,7 +101,7 @@ public function __construct(array $orderByColumns, array $searchCols, string $lo * @param string $search Search query string. * @param string|null $alias Alias of the main table use in the query builder. If null, alias is auto-detected. */ - public function applySearchFilter(QueryBuilder $qb, string $search, string $alias = null) + public function applySearchFilter(QueryBuilder $qb, string $search, ?string $alias = null) { // Make sure we know the alias of the main table. if (!$alias) { @@ -120,7 +121,7 @@ public function applySearchFilter(QueryBuilder $qb, string $search, string $alia * @param Pagination $pagination Pagination object which holds the filter and order by parameters. * @param string|null $alias Alias of the main table use in the query builder. If null, alias is auto-detected. */ - public function apply(QueryBuilder $qb, Pagination $pagination, string $alias = null) + public function apply(QueryBuilder $qb, Pagination $pagination, ?string $alias = null) { // Make sure we know the alias of the main table. if (!$alias) { @@ -132,16 +133,15 @@ public function apply(QueryBuilder $qb, Pagination $pagination, string $alias = if ($this->searchCols && $pagination->hasFilter("search")) { $search = trim($pagination->getFilter("search")); if (!$search) { - throw new InvalidArgumentException("filter", "search query value is empty"); + throw new InvalidApiArgumentException('filter', "search query value is empty"); } $this->applySearchFilter($qb, $search, $alias); } // Set final ordering ... if ( - $this->orderByColumns && $pagination->getOrderBy() && !empty( - $this->orderByColumns[$pagination->getOrderBy()] - ) + $this->orderByColumns && $pagination->getOrderBy() + && !empty($this->orderByColumns[$pagination->getOrderBy()]) ) { foreach ($this->orderByColumns[$pagination->getOrderBy()] as $orderBy) { $qb->addOrderBy($orderBy, $pagination->isOrderAscending() ? 'ASC' : 'DESC'); @@ -163,8 +163,7 @@ public function getResult(QueryBuilder $qb, Pagination $pagination) $query = $qb->getQuery(); $locale = $pagination->getLocale(); if ( - $locale && !empty(self::$knownCollations[$locale]) && $pagination->getOrderBy( - ) + $locale && !empty(self::$knownCollations[$locale]) && $pagination->getOrderBy() ) { // collation correction based on given locale $query->setHint( Query::HINT_CUSTOM_OUTPUT_WALKER, diff --git a/recodex-api.spec b/recodex-api.spec index 8ba7e4166..157f26e51 100644 --- a/recodex-api.spec +++ b/recodex-api.spec @@ -2,8 +2,8 @@ %define short_name api %define install_dir /opt/%{name} %define version 2.15.0 -%define unmangled_version e5f2db258979c6136d734a25ec0f361ad0859a10 -%define release 1 +%define unmangled_version 83a252463975fc7f66f056a5cf213c2c5e2662d4 +%define release 2 Summary: ReCodEx core API component Name: %{name} diff --git a/tests/AccessToken/AccessToken.phpt b/tests/AccessToken/AccessToken.phpt index c6c14896f..758287ed1 100644 --- a/tests/AccessToken/AccessToken.phpt +++ b/tests/AccessToken/AccessToken.phpt @@ -2,7 +2,6 @@ include "../bootstrap.php"; -use App\Exceptions\InvalidArgumentException; use App\Security\AccessToken; use Tester\Assert; use App\Exceptions\InvalidAccessTokenException; diff --git a/tests/Exceptions/Exceptions.phpt b/tests/Exceptions/Exceptions.phpt index 17e6c0a3e..fae955514 100644 --- a/tests/Exceptions/Exceptions.phpt +++ b/tests/Exceptions/Exceptions.phpt @@ -10,7 +10,7 @@ use App\Exceptions\ForbiddenRequestException; use App\Exceptions\HttpBasicAuthException; use App\Exceptions\InternalServerException; use App\Exceptions\InvalidAccessTokenException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\InvalidMembershipException; use App\Exceptions\InvalidStateException; use App\Exceptions\JobConfigLoadingException; @@ -139,18 +139,18 @@ class TestExceptions extends Tester\TestCase ); } - public function testInvalidArgumentException() + public function testInvalidApiArgumentException() { Assert::exception( function () { try { - throw new InvalidArgumentException("message"); + throw new InvalidApiArgumentException("message"); } catch (Exception $e) { Assert::true(strlen($e->getMessage()) > 0); throw $e; } }, - InvalidArgumentException::class + InvalidApiArgumentException::class ); } diff --git a/tests/Presenters/ExerciseFilesPresenter.phpt b/tests/Presenters/ExerciseFilesPresenter.phpt index a4bd24504..b8c3fbd72 100644 --- a/tests/Presenters/ExerciseFilesPresenter.phpt +++ b/tests/Presenters/ExerciseFilesPresenter.phpt @@ -122,8 +122,8 @@ class TestExerciseFilesPresenter extends Tester\TestCase "V1:ExerciseFiles", "POST", [ - "action" => 'uploadSupplementaryFiles', - 'id' => $exercise->getId() + "action" => 'uploadSupplementaryFiles', + 'id' => $exercise->getId() ], [ 'files' => $files @@ -184,8 +184,8 @@ class TestExerciseFilesPresenter extends Tester\TestCase "V1:ExerciseFiles", "POST", [ - "action" => 'uploadSupplementaryFiles', - 'id' => $exercise->getId() + "action" => 'uploadSupplementaryFiles', + 'id' => $exercise->getId() ], [ 'files' => $files @@ -193,7 +193,7 @@ class TestExerciseFilesPresenter extends Tester\TestCase ) ); }, - \App\Exceptions\InvalidArgumentException::class + \App\Exceptions\InvalidApiArgumentException::class ); } @@ -240,8 +240,8 @@ class TestExerciseFilesPresenter extends Tester\TestCase "V1:ExerciseFiles", "POST", [ - "action" => 'uploadSupplementaryFiles', - 'id' => $exercise->getId() + "action" => 'uploadSupplementaryFiles', + 'id' => $exercise->getId() ], [ 'files' => $files @@ -249,7 +249,7 @@ class TestExerciseFilesPresenter extends Tester\TestCase ) ); }, - \App\Exceptions\InvalidArgumentException::class + \App\Exceptions\InvalidApiArgumentException::class ); } @@ -499,10 +499,10 @@ class TestExerciseFilesPresenter extends Tester\TestCase "V1:ExerciseFiles", "POST", [ - "action" => 'uploadAttachmentFiles', - 'id' => $exercise->getId() + "action" => 'uploadAttachmentFiles', + 'id' => $exercise->getId() ], - [ 'files' => $files ] + ['files' => $files] ) ); diff --git a/tests/Presenters/ExercisesConfigPresenter.phpt b/tests/Presenters/ExercisesConfigPresenter.phpt index b66840d54..b263f122a 100644 --- a/tests/Presenters/ExercisesConfigPresenter.phpt +++ b/tests/Presenters/ExercisesConfigPresenter.phpt @@ -208,8 +208,7 @@ class TestExercisesConfigPresenter extends Tester\TestCase "pipelines" => [ [ "name" => $compilationPipeline->getId(), - "variables" => [ - ] + "variables" => [] ] ] ], @@ -236,8 +235,7 @@ class TestExercisesConfigPresenter extends Tester\TestCase "pipelines" => [ [ "name" => $compilationPipeline->getId(), - "variables" => [ - ] + "variables" => [] ] ] ], @@ -579,10 +577,10 @@ class TestExercisesConfigPresenter extends Tester\TestCase $this->presenter, 'V1:ExercisesConfig', 'GET', - [ 'action' => 'getScoreConfig', 'id' => $exercise->getId() ] + ['action' => 'getScoreConfig', 'id' => $exercise->getId()] ); $resultConfig = $payload->getConfigParsed(); - Assert::equal(['testWeights' => [ 'Test 1' => 100, 'Test 2' => 100 ]], $resultConfig); + Assert::equal(['testWeights' => ['Test 1' => 100, 'Test 2' => 100]], $resultConfig); } public function testSetScoreConfig() @@ -596,7 +594,7 @@ class TestExercisesConfigPresenter extends Tester\TestCase 'Test 1' => 100, 'Test 2' => 100, 'Test 3' => 100, - ] ]; + ]]; $payload = PresenterTestHelper::performPresenterRequest( $this->presenter, @@ -733,7 +731,7 @@ class TestExercisesConfigPresenter extends Tester\TestCase function () use ($request) { $this->presenter->run($request); }, - App\Exceptions\InvalidArgumentException::class + App\Exceptions\InvalidApiArgumentException::class ); } } diff --git a/tests/Presenters/ExercisesPresenter.phpt b/tests/Presenters/ExercisesPresenter.phpt index 3da90ca52..e2f6c4580 100644 --- a/tests/Presenters/ExercisesPresenter.phpt +++ b/tests/Presenters/ExercisesPresenter.phpt @@ -4,12 +4,11 @@ $container = require_once __DIR__ . "/../bootstrap.php"; use App\Exceptions\BadRequestException; use App\Exceptions\NotFoundException; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\ForbiddenRequestException; use App\Model\Entity\Exercise; use App\Model\Entity\ExerciseTag; use App\Model\Entity\LocalizedExercise; -use App\Model\Entity\Pipeline; use App\Model\Entity\Group; use App\Model\Repository\Users; use App\Helpers\Notifications\ExerciseNotificationSender; @@ -153,7 +152,7 @@ class TestExercisesPresenter extends Tester\TestCase $request = new Nette\Application\Request('V1:Exercises', 'GET', [ 'action' => 'default', - 'filters' => [ 'archived' => 'all' ] + 'filters' => ['archived' => 'all'] ]); $response = $this->presenter->run($request); Assert::type(Nette\Application\Responses\JsonResponse::class, $response); @@ -185,7 +184,7 @@ class TestExercisesPresenter extends Tester\TestCase $request = new Nette\Application\Request('V1:Exercises', 'GET', [ 'action' => 'default', - 'filters' => [ 'archived' => 'only' ] + 'filters' => ['archived' => 'only'] ]); $response = $this->presenter->run($request); Assert::type(Nette\Application\Responses\JsonResponse::class, $response); @@ -867,7 +866,7 @@ class TestExercisesPresenter extends Tester\TestCase ['action' => 'tagsUpdateGlobal', 'tag' => 'tag3', 'renameTo' => 'tag2'] ); }, - InvalidArgumentException::class + InvalidApiArgumentException::class ); } @@ -1089,7 +1088,7 @@ class TestExercisesPresenter extends Tester\TestCase 'V1:Exercises', 'POST', ['action' => 'setAdmins', 'id' => $exercise->getId()], - ['admins' => [ $anotherSupervisor->getId() ]] + ['admins' => [$anotherSupervisor->getId()]] ); $this->presenter->exercises->refresh($exercise); diff --git a/tests/Presenters/ExtensionsPresenter.phpt b/tests/Presenters/ExtensionsPresenter.phpt index 9e0f33e1f..108559137 100644 --- a/tests/Presenters/ExtensionsPresenter.phpt +++ b/tests/Presenters/ExtensionsPresenter.phpt @@ -72,9 +72,9 @@ class TestExtensionsPresenter extends Tester\TestCase 'caption' => $caption, 'url' => $url, 'urlTokenExpiration' => 42, - 'token' => [ 'expiration' => 54321, 'scopes' => $scopes, 'user' => $user ], + 'token' => ['expiration' => 54321, 'scopes' => $scopes, 'user' => $user], 'instances' => $instances, - 'user' => [ 'roles' => $roles, 'externalLogins' => $externalLogins ], + 'user' => ['roles' => $roles, 'externalLogins' => $externalLogins], ]; $this->presenter->extensions = new Extensions($this->extensionsConfig); @@ -116,7 +116,7 @@ class TestExtensionsPresenter extends Tester\TestCase $currentUser = PresenterTestHelper::getUser($this->container, "submitUser1@example.com"); $instanceId = $currentUser->getInstances()->first()->getId(); - $this->injectExtension('test', 'Test', 'https://test.example.com/{token}/{locale}', [], null, [ $instanceId ]); + $this->injectExtension('test', 'Test', 'https://test.example.com/{token}/{locale}', [], null, [$instanceId]); $payload = PresenterTestHelper::performPresenterRequest( $this->presenter, @@ -197,7 +197,7 @@ class TestExtensionsPresenter extends Tester\TestCase $currentUser = PresenterTestHelper::getUser($this->container, "submitUser1@example.com"); $instanceId = $currentUser->getInstances()->first()->getId(); - $this->injectExtension('test', 'Test', 'https://', [], null, [], [ 'supervisor' ]); + $this->injectExtension('test', 'Test', 'https://', [], null, [], ['supervisor']); Assert::exception( function () use ($instanceId) { @@ -242,10 +242,11 @@ class TestExtensionsPresenter extends Tester\TestCase $currentUser = PresenterTestHelper::getUser($this->container, "submitUser1@example.com"); $instanceId = $currentUser->getInstances()->first()->getId(); PresenterTestHelper::login($this->container, "submitUser1@example.com", [TokenScope::EXTENSIONS], 42, [ - "instance" => $instanceId, "extension" => "test" + "instance" => $instanceId, + "extension" => "test" ]); - $this->injectExtension('test', 'Test', 'https://', [ TokenScope::USERS ]); + $this->injectExtension('test', 'Test', 'https://', [TokenScope::USERS]); $payload = PresenterTestHelper::performPresenterRequest( $this->presenter, @@ -268,10 +269,11 @@ class TestExtensionsPresenter extends Tester\TestCase $currentUser = PresenterTestHelper::getUser($this->container, "submitUser1@example.com"); $instanceId = $currentUser->getInstances()->first()->getId(); PresenterTestHelper::login($this->container, "submitUser1@example.com", [TokenScope::EXTENSIONS], 42, [ - "instance" => $instanceId, "extension" => "test" + "instance" => $instanceId, + "extension" => "test" ]); - $this->injectExtension('test', 'Test', 'https://', [ TokenScope::USERS ], $admin->getId()); + $this->injectExtension('test', 'Test', 'https://', [TokenScope::USERS], $admin->getId()); $payload = PresenterTestHelper::performPresenterRequest( $this->presenter, @@ -293,7 +295,8 @@ class TestExtensionsPresenter extends Tester\TestCase $currentUser = PresenterTestHelper::getUser($this->container, "submitUser1@example.com"); $instanceId = $currentUser->getInstances()->first()->getId(); PresenterTestHelper::login($this->container, "submitUser1@example.com", [TokenScope::MASTER], 42, [ - "instance" => $instanceId, "extension" => "test" + "instance" => $instanceId, + "extension" => "test" ]); $this->injectExtension('test', 'Test', 'https://'); @@ -326,7 +329,7 @@ class TestExtensionsPresenter extends Tester\TestCase ['action' => 'token', 'extId' => 'test'] ); }, - App\Exceptions\InvalidArgumentException::class + InvalidArgumentException::class ); } @@ -335,7 +338,8 @@ class TestExtensionsPresenter extends Tester\TestCase $currentUser = PresenterTestHelper::getUser($this->container, "submitUser1@example.com"); $instanceId = $currentUser->getInstances()->first()->getId(); PresenterTestHelper::login($this->container, "submitUser1@example.com", [TokenScope::EXTENSIONS], 42, [ - "instance" => $instanceId, "extension" => "ext1" + "instance" => $instanceId, + "extension" => "ext1" ]); $this->injectExtension('test', 'Test', 'https://'); @@ -358,7 +362,8 @@ class TestExtensionsPresenter extends Tester\TestCase $currentUser = PresenterTestHelper::getUser($this->container, "submitUser1@example.com"); $instanceId = $currentUser->getInstances()->first()->getId(); PresenterTestHelper::login($this->container, "submitUser1@example.com", [TokenScope::EXTENSIONS], 42, [ - "instance" => '', "extension" => "test" + "instance" => '', + "extension" => "test" ]); $this->injectExtension('test', 'Test', 'https://'); @@ -381,7 +386,8 @@ class TestExtensionsPresenter extends Tester\TestCase $currentUser = PresenterTestHelper::getUser($this->container, "submitUser1@example.com"); $instanceId = $currentUser->getInstances()->first()->getId(); PresenterTestHelper::login($this->container, "submitUser1@example.com", [TokenScope::EXTENSIONS], 42, [ - "instance" => $instanceId, "extension" => "test" + "instance" => $instanceId, + "extension" => "test" ]); Assert::exception( diff --git a/tests/Presenters/GroupsPresenter.phpt b/tests/Presenters/GroupsPresenter.phpt index b1b00e318..477dab8e6 100644 --- a/tests/Presenters/GroupsPresenter.phpt +++ b/tests/Presenters/GroupsPresenter.phpt @@ -243,9 +243,9 @@ class TestGroupsPresenter extends Tester\TestCase 'V1:Groups', 'POST', [ - 'action' => 'addStudent', - 'id' => $group->getId(), - 'userId' => $user->getId() + 'action' => 'addStudent', + 'id' => $group->getId(), + 'userId' => $user->getId() ] ); @@ -275,9 +275,9 @@ class TestGroupsPresenter extends Tester\TestCase 'V1:Groups', 'POST', [ - 'action' => 'addStudent', - 'id' => $group->getId(), - 'userId' => $user->getId() + 'action' => 'addStudent', + 'id' => $group->getId(), + 'userId' => $user->getId() ] ); @@ -305,9 +305,9 @@ class TestGroupsPresenter extends Tester\TestCase 'V1:Groups', 'DELETE', [ - 'action' => 'removeStudent', - 'id' => $group->getId(), - 'userId' => $user->getId() + 'action' => 'removeStudent', + 'id' => $group->getId(), + 'userId' => $user->getId() ] ); @@ -338,9 +338,9 @@ class TestGroupsPresenter extends Tester\TestCase 'V1:Groups', 'DELETE', [ - 'action' => 'removeStudent', - 'id' => $group->getId(), - 'userId' => $user->getId() + 'action' => 'removeStudent', + 'id' => $group->getId(), + 'userId' => $user->getId() ] ); @@ -374,9 +374,9 @@ class TestGroupsPresenter extends Tester\TestCase 'V1:Groups', 'DELETE', [ - 'action' => 'removeStudent', - 'id' => $group->getId(), - 'userId' => $user->getId() + 'action' => 'removeStudent', + 'id' => $group->getId(), + 'userId' => $user->getId() ] ); @@ -749,7 +749,7 @@ class TestGroupsPresenter extends Tester\TestCase ] ); }, - \App\Exceptions\InvalidArgumentException::class + \App\Exceptions\InvalidApiArgumentException::class ); } @@ -1004,11 +1004,11 @@ class TestGroupsPresenter extends Tester\TestCase 'V1:Groups', 'POST', [ - 'action' => 'addMember', - 'id' => $group->getId(), - 'userId' => $user->getId() + 'action' => 'addMember', + 'id' => $group->getId(), + 'userId' => $user->getId() ], - [ 'type' => 'supervisor' ] + ['type' => 'supervisor'] ); /** @var \Nette\Application\Responses\JsonResponse $response */ @@ -1037,11 +1037,11 @@ class TestGroupsPresenter extends Tester\TestCase 'V1:Groups', 'POST', [ - 'action' => 'addMember', - 'id' => $group->getId(), - 'userId' => $user->getId() + 'action' => 'addMember', + 'id' => $group->getId(), + 'userId' => $user->getId() ], - [ 'type' => 'supervisor' ] + ['type' => 'supervisor'] ); Assert::exception( @@ -1068,9 +1068,9 @@ class TestGroupsPresenter extends Tester\TestCase 'V1:Groups', 'DELETE', [ - 'action' => 'removeMember', - 'id' => $group->getId(), - 'userId' => $user->getId() + 'action' => 'removeMember', + 'id' => $group->getId(), + 'userId' => $user->getId() ] ); diff --git a/tests/Presenters/PipelinesPresenter.phpt b/tests/Presenters/PipelinesPresenter.phpt index 6845c269b..101161a7d 100644 --- a/tests/Presenters/PipelinesPresenter.phpt +++ b/tests/Presenters/PipelinesPresenter.phpt @@ -2,7 +2,7 @@ $container = require_once __DIR__ . "/../bootstrap.php"; -use App\Exceptions\InvalidArgumentException; +use App\Exceptions\InvalidApiArgumentException; use App\Exceptions\NotFoundException; use App\Helpers\FileStorageManager; use App\Helpers\TmpFilesHelper; @@ -58,8 +58,8 @@ class TestPipelinesPresenter extends Tester\TestCase $this->presenter = PresenterTestHelper::createPresenter($this->container, PipelinesPresenter::class); // set autogenerated IDs in pipelines -// $metadata = $this->em->getClassMetadata(Pipeline::class); -// $metadata->setIdGenerator(new UuidGenerator()); + // $metadata = $this->em->getClassMetadata(Pipeline::class); + // $metadata->setIdGenerator(new UuidGenerator()); } protected function tearDown() @@ -335,7 +335,7 @@ class TestPipelinesPresenter extends Tester\TestCase function () use ($request) { $this->presenter->run($request); }, - InvalidArgumentException::class + InvalidApiArgumentException::class ); } @@ -402,8 +402,8 @@ class TestPipelinesPresenter extends Tester\TestCase "V1:Pipelines", "POST", [ - "action" => 'uploadSupplementaryFiles', - 'id' => $pipeline->getId() + "action" => 'uploadSupplementaryFiles', + 'id' => $pipeline->getId() ], [ 'files' => $files diff --git a/tests/Presenters/UsersPresenter.phpt b/tests/Presenters/UsersPresenter.phpt index 1b9d7467a..c0b32a956 100644 --- a/tests/Presenters/UsersPresenter.phpt +++ b/tests/Presenters/UsersPresenter.phpt @@ -384,7 +384,7 @@ class TestUsersPresenter extends Tester\TestCase function () use ($request) { $this->presenter->run($request); }, - App\Exceptions\InvalidArgumentException::class + App\Exceptions\InvalidApiArgumentException::class ); } @@ -412,7 +412,7 @@ class TestUsersPresenter extends Tester\TestCase function () use ($request) { $this->presenter->run($request); }, - App\Exceptions\InvalidArgumentException::class + App\Exceptions\InvalidApiArgumentException::class ); } diff --git a/tests/Security/UserLocking.phpt b/tests/Security/UserLocking.phpt index 787323472..cfa6fda25 100644 --- a/tests/Security/UserLocking.phpt +++ b/tests/Security/UserLocking.phpt @@ -316,7 +316,7 @@ class UserLocking extends Tester\TestCase ['action' => 'unlockStudent', 'id' => $group->getId(), 'userId' => $student->getId()] ); }, - App\Exceptions\InvalidArgumentException::class + App\Exceptions\InvalidApiArgumentException::class ); } From fe8f94b131bff217237c4a83fc1684deffacff5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kruli=C5=A1?= Date: Sat, 29 Mar 2025 00:13:36 +0100 Subject: [PATCH 2/3] Fixing a TODO at VBool verification. --- .../presenters/InstancesPresenter.php | 17 ++++------------- app/helpers/MetaFormats/Validators/VBool.php | 19 +++++++++---------- tests/Presenters/InstancesPresenter.phpt | 2 +- 3 files changed, 14 insertions(+), 24 deletions(-) diff --git a/app/V1Module/presenters/InstancesPresenter.php b/app/V1Module/presenters/InstancesPresenter.php index 17cc60b8d..18b80c2a8 100644 --- a/app/V1Module/presenters/InstancesPresenter.php +++ b/app/V1Module/presenters/InstancesPresenter.php @@ -3,18 +3,11 @@ namespace App\V1Module\Presenters; use App\Helpers\MetaFormats\Attributes\Post; -use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; -use App\Helpers\MetaFormats\Type; -use App\Helpers\MetaFormats\Validators\VArray; use App\Helpers\MetaFormats\Validators\VBool; -use App\Helpers\MetaFormats\Validators\VDouble; -use App\Helpers\MetaFormats\Validators\VEmail; -use App\Helpers\MetaFormats\Validators\VInt; use App\Helpers\MetaFormats\Validators\VMixed; use App\Helpers\MetaFormats\Validators\VString; use App\Helpers\MetaFormats\Validators\VTimestamp; -use App\Helpers\MetaFormats\Validators\VUuid; use App\Exceptions\ForbiddenRequestException; use App\Exceptions\NotFoundException; use App\Model\Entity\LocalizedGroup; @@ -164,12 +157,10 @@ public function actionUpdateInstance(string $id) $instance = $this->instances->findOrThrow($id); $req = $this->getRequest(); - $isOpen = $req->getPost("isOpen") ? filter_var( - $req->getPost("isOpen"), - FILTER_VALIDATE_BOOLEAN - ) : $instance->isOpen(); - - $instance->setIsOpen($isOpen); + $isOpen = $req->getPost("isOpen"); + if ($isOpen !== null) { + $instance->setIsOpen($isOpen); + } $this->instances->persist($instance); $this->sendSuccessResponse($this->instanceViewFactory->getInstance($instance, $this->getCurrentUser())); } diff --git a/app/helpers/MetaFormats/Validators/VBool.php b/app/helpers/MetaFormats/Validators/VBool.php index bf0defee6..3f55e63c2 100644 --- a/app/helpers/MetaFormats/Validators/VBool.php +++ b/app/helpers/MetaFormats/Validators/VBool.php @@ -20,17 +20,16 @@ public function validate(mixed $value): bool return true; } - if ($this->strict) { - ///TODO: replace this with 'return false;' once the testUpdateInstance test issue is fixed. - return $value === 'false'; + if (!$this->strict) { + // FILTER_VALIDATE_BOOL is not used because it additionally allows "on", "yes", "off", "no" and "" + return $value === 0 + || $value === 1 + || $value === "0" + || $value === "1" + || $value === "false" + || $value === "true"; } - // FILTER_VALIDATE_BOOL is not used because it additionally allows "on", "yes", "off", "no" and "" - return $value === 0 - || $value === 1 - || $value === "0" - || $value === "1" - || $value === "false" - || $value === "true"; + return false; } } diff --git a/tests/Presenters/InstancesPresenter.phpt b/tests/Presenters/InstancesPresenter.phpt index 68b8e585c..000bd3ae2 100644 --- a/tests/Presenters/InstancesPresenter.phpt +++ b/tests/Presenters/InstancesPresenter.phpt @@ -121,7 +121,7 @@ class TestInstancesPresenter extends Tester\TestCase 'V1:Instances', 'POST', ['action' => 'updateInstance', 'id' => $instance->getId()], - ['isOpen' => 'false'] + ['isOpen' => false] ); $response = $this->presenter->run($request); Assert::type(Nette\Application\Responses\JsonResponse::class, $response); From a9b1ea229c55b6ccc25f90da5e188b68c09b9619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kruli=C5=A1?= Date: Mon, 31 Mar 2025 15:24:01 +0200 Subject: [PATCH 3/3] Fixing few typos. --- app/V1Module/router/RouterFactory.php | 4 ++-- app/model/entity/Exercise.php | 6 +++--- app/model/entity/ExerciseScoreConfig.php | 2 +- app/model/entity/ExerciseTag.php | 2 +- app/model/entity/ExerciseTest.php | 4 ++-- app/model/entity/Group.php | 6 +++--- app/model/entity/GroupExamLock.php | 2 +- app/model/entity/GroupExternalAttribute.php | 2 +- app/model/entity/GroupInvitation.php | 4 ++-- app/model/entity/Instance.php | 6 +++--- app/model/entity/Notification.php | 2 +- app/model/entity/Pipeline.php | 6 +++--- app/model/entity/PlagiarismDetectionBatch.php | 2 +- app/model/entity/ReviewComment.php | 2 +- app/model/entity/SecurityEvent.php | 2 +- app/model/entity/ShadowAssignmentPoints.php | 4 ++-- app/model/entity/Solution.php | 2 +- app/model/entity/SubmissionFailure.php | 2 +- app/model/entity/User.php | 4 ++-- app/model/entity/UserCalendar.php | 2 +- app/model/entity/base/AssignmentBase.php | 6 +++--- app/model/entity/base/CreateableEntity.php | 2 +- app/model/entity/base/DeleteableEntity.php | 3 +-- app/model/entity/base/UpdateableEntity.php | 3 +-- 24 files changed, 39 insertions(+), 41 deletions(-) diff --git a/app/V1Module/router/RouterFactory.php b/app/V1Module/router/RouterFactory.php index b67a4b496..e8da44161 100644 --- a/app/V1Module/router/RouterFactory.php +++ b/app/V1Module/router/RouterFactory.php @@ -38,7 +38,7 @@ public static function createRouter() $router[] = self::createAssignmentsRoutes("$prefix/exercise-assignments"); $router[] = self::createGroupsRoutes("$prefix/groups"); $router[] = self::createGroupInvitationsRoutes("$prefix/group-invitations"); - $router[] = self::createGroupAtrributesRoutes("$prefix/group-attributes"); + $router[] = self::createGroupAttributesRoutes("$prefix/group-attributes"); $router[] = self::createInstancesRoutes("$prefix/instances"); $router[] = self::createReferenceSolutionsRoutes("$prefix/reference-solutions"); $router[] = self::createAssignmentSolutionsRoutes("$prefix/assignment-solutions"); @@ -306,7 +306,7 @@ private static function createGroupInvitationsRoutes(string $prefix): RouteList * @param string $prefix Route prefix * @return RouteList All endpoint routes */ - private static function createGroupAtrributesRoutes(string $prefix): RouteList + private static function createGroupAttributesRoutes(string $prefix): RouteList { $router = new RouteList(); diff --git a/app/model/entity/Exercise.php b/app/model/entity/Exercise.php index bdf7416d9..c0fce91c9 100644 --- a/app/model/entity/Exercise.php +++ b/app/model/entity/Exercise.php @@ -20,9 +20,9 @@ class Exercise implements IExercise { use ExerciseData; - use CreateableEntity; - use UpdateableEntity; - use DeleteableEntity; + use CreatableEntity; + use UpdatableEntity; + use DeletableEntity; use VersionableEntity; /** diff --git a/app/model/entity/ExerciseScoreConfig.php b/app/model/entity/ExerciseScoreConfig.php index 42acd1d44..b75cb2bd1 100644 --- a/app/model/entity/ExerciseScoreConfig.php +++ b/app/model/entity/ExerciseScoreConfig.php @@ -13,7 +13,7 @@ */ class ExerciseScoreConfig implements JsonSerializable { - use CreateableEntity; + use CreatableEntity; /** * @ORM\Id diff --git a/app/model/entity/ExerciseTag.php b/app/model/entity/ExerciseTag.php index 5727b52f9..1e1701d78 100644 --- a/app/model/entity/ExerciseTag.php +++ b/app/model/entity/ExerciseTag.php @@ -10,7 +10,7 @@ */ class ExerciseTag { - use CreateableEntity; + use CreatableEntity; /** * @ORM\Id diff --git a/app/model/entity/ExerciseTest.php b/app/model/entity/ExerciseTest.php index 329268122..0bd6e91fd 100644 --- a/app/model/entity/ExerciseTest.php +++ b/app/model/entity/ExerciseTest.php @@ -12,8 +12,8 @@ */ class ExerciseTest implements JsonSerializable { - use CreateableEntity; - use UpdateableEntity; + use CreatableEntity; + use UpdatableEntity; /** * @ORM\Id diff --git a/app/model/entity/Group.php b/app/model/entity/Group.php index 2c679618e..c49a3165e 100644 --- a/app/model/entity/Group.php +++ b/app/model/entity/Group.php @@ -24,7 +24,7 @@ */ class Group { - use DeleteableEntity; + use DeletableEntity; public function __construct( string $externalId, @@ -227,7 +227,7 @@ public function isDirectlyArchived(): bool */ 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. @@ -632,7 +632,7 @@ private function getAdminIdsInternal(bool $inherited): array $admins = []; // key is user ID, value is true while ($group !== null) { // getMembershipsInternal inherited flag goes: true = only inherited, false = only direct, null = all - $directAdmins = $group->getMembershipsInternal([ GroupMembership::TYPE_ADMIN ], $inherited ? null : false); + $directAdmins = $group->getMembershipsInternal([GroupMembership::TYPE_ADMIN], $inherited ? null : false); foreach ($directAdmins as $membership) { $admins[$membership->getUser()->getId()] = true; } diff --git a/app/model/entity/GroupExamLock.php b/app/model/entity/GroupExamLock.php index 3a0999820..83c5ed954 100644 --- a/app/model/entity/GroupExamLock.php +++ b/app/model/entity/GroupExamLock.php @@ -14,7 +14,7 @@ */ class GroupExamLock implements JsonSerializable { - use CreateableEntity; + use CreatableEntity; /** * @ORM\Id diff --git a/app/model/entity/GroupExternalAttribute.php b/app/model/entity/GroupExternalAttribute.php index 5e64b4b57..b003e8343 100644 --- a/app/model/entity/GroupExternalAttribute.php +++ b/app/model/entity/GroupExternalAttribute.php @@ -15,7 +15,7 @@ */ class GroupExternalAttribute implements JsonSerializable { - use CreateableEntity; + use CreatableEntity; /** * @ORM\Id diff --git a/app/model/entity/GroupInvitation.php b/app/model/entity/GroupInvitation.php index b9dd5b065..f4caa8787 100644 --- a/app/model/entity/GroupInvitation.php +++ b/app/model/entity/GroupInvitation.php @@ -12,7 +12,7 @@ */ class GroupInvitation implements JsonSerializable { - use CreateableEntity; + use CreatableEntity; /** * @ORM\Id @@ -23,7 +23,7 @@ class GroupInvitation implements JsonSerializable */ protected $id; - /** + /** * @ORM\Column(type="datetime", nullable=true) * @var DateTime */ diff --git a/app/model/entity/Instance.php b/app/model/entity/Instance.php index 899d0b370..0da8d6977 100644 --- a/app/model/entity/Instance.php +++ b/app/model/entity/Instance.php @@ -14,9 +14,9 @@ */ class Instance { - use UpdateableEntity; - use DeleteableEntity; - use CreateableEntity; + use UpdatableEntity; + use DeletableEntity; + use CreatableEntity; /** * @ORM\Id diff --git a/app/model/entity/Notification.php b/app/model/entity/Notification.php index de3b6f195..f7bbab059 100644 --- a/app/model/entity/Notification.php +++ b/app/model/entity/Notification.php @@ -15,7 +15,7 @@ */ class Notification implements JsonSerializable { - use CreateableEntity; + use CreatableEntity; /** * @ORM\Id diff --git a/app/model/entity/Pipeline.php b/app/model/entity/Pipeline.php index a04cb8007..ba40908d5 100644 --- a/app/model/entity/Pipeline.php +++ b/app/model/entity/Pipeline.php @@ -17,9 +17,9 @@ */ class Pipeline { - use CreateableEntity; - use UpdateableEntity; - use DeleteableEntity; + use CreatableEntity; + use UpdatableEntity; + use DeletableEntity; use VersionableEntity; /** diff --git a/app/model/entity/PlagiarismDetectionBatch.php b/app/model/entity/PlagiarismDetectionBatch.php index de7abdc25..e1e6892de 100644 --- a/app/model/entity/PlagiarismDetectionBatch.php +++ b/app/model/entity/PlagiarismDetectionBatch.php @@ -13,7 +13,7 @@ */ class PlagiarismDetectionBatch implements JsonSerializable { - use CreateableEntity; + use CreatableEntity; /** * @ORM\Id diff --git a/app/model/entity/ReviewComment.php b/app/model/entity/ReviewComment.php index 1a19fb187..1f3f87c29 100644 --- a/app/model/entity/ReviewComment.php +++ b/app/model/entity/ReviewComment.php @@ -15,7 +15,7 @@ */ class ReviewComment implements JsonSerializable { - use CreateableEntity; + use CreatableEntity; /** * @ORM\Id diff --git a/app/model/entity/SecurityEvent.php b/app/model/entity/SecurityEvent.php index 5c33e399a..594f5e6c1 100644 --- a/app/model/entity/SecurityEvent.php +++ b/app/model/entity/SecurityEvent.php @@ -13,7 +13,7 @@ */ class SecurityEvent implements JsonSerializable { - use CreateableEntity; + use CreatableEntity; public const TYPE_LOGIN = 'login'; public const TYPE_LOGIN_EXTERNAL = 'loginext'; diff --git a/app/model/entity/ShadowAssignmentPoints.php b/app/model/entity/ShadowAssignmentPoints.php index edec8b3ff..83d488623 100644 --- a/app/model/entity/ShadowAssignmentPoints.php +++ b/app/model/entity/ShadowAssignmentPoints.php @@ -11,8 +11,8 @@ */ class ShadowAssignmentPoints { - use CreateableEntity; - use UpdateableEntity; + use CreatableEntity; + use UpdatableEntity; public function __construct( int $points, diff --git a/app/model/entity/Solution.php b/app/model/entity/Solution.php index 200c0d704..4ecdd2c43 100644 --- a/app/model/entity/Solution.php +++ b/app/model/entity/Solution.php @@ -16,7 +16,7 @@ */ class Solution { - use CreateableEntity; + use CreatableEntity; /** * @ORM\Id diff --git a/app/model/entity/SubmissionFailure.php b/app/model/entity/SubmissionFailure.php index 3ed7700ec..50b8a5a96 100644 --- a/app/model/entity/SubmissionFailure.php +++ b/app/model/entity/SubmissionFailure.php @@ -11,7 +11,7 @@ */ class SubmissionFailure implements JsonSerializable { - use CreateableEntity; + use CreatableEntity; /** * Broker rejected the submission. This happens when there is no worker who can evaluate it. diff --git a/app/model/entity/User.php b/app/model/entity/User.php index 11c303a52..8530dd63e 100644 --- a/app/model/entity/User.php +++ b/app/model/entity/User.php @@ -20,8 +20,8 @@ */ class User { - use CreateableEntity; - use DeleteableEntity; + use CreatableEntity; + use DeletableEntity; public function __construct( string $email, diff --git a/app/model/entity/UserCalendar.php b/app/model/entity/UserCalendar.php index 17ce0a4cd..7ee2237f4 100644 --- a/app/model/entity/UserCalendar.php +++ b/app/model/entity/UserCalendar.php @@ -12,7 +12,7 @@ */ class UserCalendar implements JsonSerializable { - use CreateableEntity; + use CreatableEntity; /** * @ORM\Id diff --git a/app/model/entity/base/AssignmentBase.php b/app/model/entity/base/AssignmentBase.php index 224e873f7..a82a1d80e 100644 --- a/app/model/entity/base/AssignmentBase.php +++ b/app/model/entity/base/AssignmentBase.php @@ -10,10 +10,10 @@ */ abstract class AssignmentBase { - use CreateableEntity; + use CreatableEntity; use VersionableEntity; - use UpdateableEntity; - use DeleteableEntity; + use UpdatableEntity; + use DeletableEntity; abstract public function getGroup(): ?Group; diff --git a/app/model/entity/base/CreateableEntity.php b/app/model/entity/base/CreateableEntity.php index 6e5a78c62..c0d4d7218 100644 --- a/app/model/entity/base/CreateableEntity.php +++ b/app/model/entity/base/CreateableEntity.php @@ -5,7 +5,7 @@ use DateTime; use Doctrine\ORM\Mapping as ORM; -trait CreateableEntity +trait CreatableEntity { /** * @ORM\Column(type="datetime") diff --git a/app/model/entity/base/DeleteableEntity.php b/app/model/entity/base/DeleteableEntity.php index 677740b0b..d95f951b8 100644 --- a/app/model/entity/base/DeleteableEntity.php +++ b/app/model/entity/base/DeleteableEntity.php @@ -5,9 +5,8 @@ use DateTime; use Doctrine\ORM\Mapping as ORM; -trait DeleteableEntity +trait DeletableEntity { - /** * @ORM\Column(type="datetime", nullable=true) * @var DateTime diff --git a/app/model/entity/base/UpdateableEntity.php b/app/model/entity/base/UpdateableEntity.php index 5bf5d28fc..a2cef651d 100644 --- a/app/model/entity/base/UpdateableEntity.php +++ b/app/model/entity/base/UpdateableEntity.php @@ -5,9 +5,8 @@ use DateTime; use Doctrine\ORM\Mapping as ORM; -trait UpdateableEntity +trait UpdatableEntity { - /** * @ORM\Column(type="datetime") * @var DateTime