diff --git a/api/rector.php b/api/rector.php index 4e4d1f933e..d1a5abcf87 100644 --- a/api/rector.php +++ b/api/rector.php @@ -19,6 +19,7 @@ use Rector\Privatization\Rector\Class_\FinalizeTestCaseClassRector; use Rector\Renaming\Rector\FuncCall\RenameFunctionRector; use Rector\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector; +use Rector\Symfony\Symfony73\Rector\Class_\ConstraintOptionsToNamedArgumentsRector; use Rector\TypeDeclaration\Rector\StmtsAwareInterface\DeclareStrictTypesRector; // @noinspection PhpUnhandledExceptionInspection @@ -42,6 +43,7 @@ AddInstanceofAssertForNullableInstanceRector::class, AssertEmptyNullableObjectToAssertInstanceofRector::class, CombineIfRector::class, + ConstraintOptionsToNamedArgumentsRector::class, DeclareStrictTypesRector::class, DisallowedEmptyRuleFixerRector::class, ExplicitBoolCompareRector::class, diff --git a/api/src/DTO/Invitation.php b/api/src/DTO/Invitation.php index 9978b32f27..34f8607654 100644 --- a/api/src/DTO/Invitation.php +++ b/api/src/DTO/Invitation.php @@ -21,35 +21,36 @@ #[ApiResource( operations: [ new Get( - provider: InvitationProvider::class, - uriTemplate: '/invitations/{inviteKey}/find{._format}', // TO DISCUSS: Wouldn't '/{inviteKey}{._format}' be more REST-like + // TO DISCUSS: Wouldn't '/{inviteKey}{._format}' be more REST-like + uriTemplate: '/invitations/{inviteKey}/find{._format}', + openapi: new OpenApiOperation(description: 'Use myInviteKey to find an invitation in the dev environment.'), normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, - openapi: new OpenApiOperation(description: 'Use myInviteKey to find an invitation in the dev environment.') + provider: InvitationProvider::class ), new Patch( - provider: InvitationProvider::class, - processor: InvitationAcceptProcessor::class, - output: Invitation::class, - security: 'is_authenticated()', uriTemplate: '/invitations/{inviteKey}/'.self::ACCEPT.'{._format}', - denormalizationContext: ['groups' => ['write']], - normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, openapi: new OpenApiOperation(summary: 'Accept an Invitation.', description: 'Use myInviteKey2 to accept an invitation in dev environment.'), - validationContext: ['groups' => ['Default', 'accept']] + normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, + denormalizationContext: ['groups' => ['write']], + security: 'is_authenticated()', + validationContext: ['groups' => ['Default', 'accept']], + output: Invitation::class, + provider: InvitationProvider::class, + processor: InvitationAcceptProcessor::class ), new Patch( - provider: InvitationProvider::class, - processor: InvitationRejectProcessor::class, - output: Invitation::class, uriTemplate: '/invitations/{inviteKey}/'.self::REJECT.'{._format}', - denormalizationContext: ['groups' => ['write']], + openapi: new OpenApiOperation(summary: 'Reject an Invitation.', description: 'Use myInviteKey to reject an invitation in dev environment.'), normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, - openapi: new OpenApiOperation(summary: 'Reject an Invitation.', description: 'Use myInviteKey to reject an invitation in dev environment.') + denormalizationContext: ['groups' => ['write']], + output: Invitation::class, + provider: InvitationProvider::class, + processor: InvitationRejectProcessor::class ), new GetCollection( - provider: InvitationProvider::class, + openapi: false, security: 'false', - openapi: false + provider: InvitationProvider::class ), ], )] diff --git a/api/src/DTO/ResetPassword.php b/api/src/DTO/ResetPassword.php index 3445e30fad..70ad8a6277 100644 --- a/api/src/DTO/ResetPassword.php +++ b/api/src/DTO/ResetPassword.php @@ -18,26 +18,26 @@ #[ApiResource( operations: [ new Get( - provider: ResetPasswordProvider::class, uriTemplate: '/reset_password/{id}{._format}', // TO DISCUSS: default uri would be /reset_password (plural). Shall we keep or fix? security: 'true', + provider: ResetPasswordProvider::class, ), new Patch( - provider: ResetPasswordProvider::class, - processor: ResetPasswordUpdateProcessor::class, uriTemplate: '/reset_password/{id}{._format}', + denormalizationContext: ['groups' => ['update']], security: 'true', - denormalizationContext: ['groups' => ['update']] + provider: ResetPasswordProvider::class, + processor: ResetPasswordUpdateProcessor::class ), new Post( - processor: ResetPasswordCreateProcessor::class, uriTemplate: '/reset_password{._format}', - security: 'true', status: 204, - output: false, - denormalizationContext: ['groups' => ['create']], + openapi: new OpenApiOperation(summary: 'Request Password-Reset-Mail', description: 'Password-Reset-Link will be sent to the given email'), normalizationContext: ['groups' => ['read']], - openapi: new OpenApiOperation(summary: 'Request Password-Reset-Mail', description: 'Password-Reset-Link will be sent to the given email') + denormalizationContext: ['groups' => ['create']], + security: 'true', + output: false, + processor: ResetPasswordCreateProcessor::class ), ], routePrefix: '/auth' diff --git a/api/src/DTO/UserActivation.php b/api/src/DTO/UserActivation.php index 08dde47868..66e0e5fadc 100644 --- a/api/src/DTO/UserActivation.php +++ b/api/src/DTO/UserActivation.php @@ -13,13 +13,13 @@ #[ApiResource( operations: [ new Post( - processor: ResendActivationProcessor::class, uriTemplate: '/resend_activation{._format}', - security: 'true', status: 204, - output: false, + openapi: new OpenApiOperation(summary: 'Request activation email again', description: 'Activation email will be sent to the given email again.'), denormalizationContext: ['groups' => ['create']], - openapi: new OpenApiOperation(summary: 'Request activation email again', description: 'Activation email will be sent to the given email again.') + security: 'true', + output: false, + processor: ResendActivationProcessor::class ), ], routePrefix: '/auth' diff --git a/api/src/DTO/ValidationError.php b/api/src/DTO/ValidationError.php index d919dd832e..b1fad9df21 100644 --- a/api/src/DTO/ValidationError.php +++ b/api/src/DTO/ValidationError.php @@ -15,11 +15,11 @@ public function __construct( private readonly string $type = 'about:blank', ) { parent::__construct( - type: $this->type, title: $this->title, - status: $this->status, detail: $this->detail, + status: $this->status, instance: $this->instance, + type: $this->type, ); } diff --git a/api/src/Entity/Activity.php b/api/src/Entity/Activity.php index 2423dd9445..203ed4a8f7 100644 --- a/api/src/Entity/Activity.php +++ b/api/src/Entity/Activity.php @@ -41,8 +41,8 @@ validationContext: ['groups' => ['Default', 'update']] ), new Delete( - processor: ActivityRemoveProcessor::class, - security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)' + security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', + processor: ActivityRemoveProcessor::class ), new GetCollection( normalizationContext: self::COLLECTION_NORMALIZATION_CONTEXT, @@ -65,11 +65,11 @@ ] ), new Post( - processor: ActivityCreateProcessor::class, - validationContext: ['groups' => ['Default', 'create']], - denormalizationContext: ['groups' => ['write', 'create']], normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, - securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.category === null' + denormalizationContext: ['groups' => ['write', 'create']], + securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.category === null', + validationContext: ['groups' => ['Default', 'create']], + processor: ActivityCreateProcessor::class ), ], denormalizationContext: ['groups' => ['write']], diff --git a/api/src/Entity/ActivityProgressLabel.php b/api/src/Entity/ActivityProgressLabel.php index fb01d4c5e2..77c165de1b 100644 --- a/api/src/Entity/ActivityProgressLabel.php +++ b/api/src/Entity/ActivityProgressLabel.php @@ -38,9 +38,9 @@ validationContext: ['groups' => ['Default', 'update']] ), new Delete( - validate: true, + security: 'is_granted("CAMP_MANAGER", object)', validationContext: ['groups' => ['delete']], - security: 'is_granted("CAMP_MANAGER", object)' + validate: true ), new GetCollection( security: 'is_authenticated()' @@ -61,10 +61,10 @@ ] ), new Post( - validationContext: ['groups' => ['Default', 'create']], - denormalizationContext: ['groups' => ['write', 'create']], normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, - securityPostDenormalize: 'is_granted("CAMP_MANAGER", object) or object.camp === null' + denormalizationContext: ['groups' => ['write', 'create']], + securityPostDenormalize: 'is_granted("CAMP_MANAGER", object) or object.camp === null', + validationContext: ['groups' => ['Default', 'create']] ), ], denormalizationContext: ['groups' => ['write']], diff --git a/api/src/Entity/Camp.php b/api/src/Entity/Camp.php index 0330f4ee40..befb6e2488 100644 --- a/api/src/Entity/Camp.php +++ b/api/src/Entity/Camp.php @@ -34,29 +34,29 @@ #[ApiResource( operations: [ new Get( + normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, security: 'is_granted("CAMP_COLLABORATOR", object) or is_granted("CAMP_IS_PUBLIC", object)', - normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, ), new Patch( - processor: CampUpdateProcessor::class, - security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', - denormalizationContext: ['groups' => ['write', 'update']], normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, + denormalizationContext: ['groups' => ['write', 'update']], + security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', + processor: CampUpdateProcessor::class, ), new Delete( - processor: CampRemoveProcessor::class, security: 'is_granted("CAMP_MANAGER", object)', + processor: CampRemoveProcessor::class, ), new GetCollection( security: 'is_authenticated()' ), new Post( - processor: CampCreateProcessor::class, + normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, + denormalizationContext: ['groups' => ['write', 'create']], security: 'is_authenticated()', validationContext: ['groups' => ['Default', 'create', 'Camp:create']], - denormalizationContext: ['groups' => ['write', 'create']], - normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, + processor: CampCreateProcessor::class, ), ], denormalizationContext: ['groups' => ['write']], diff --git a/api/src/Entity/CampCollaboration.php b/api/src/Entity/CampCollaboration.php index 4dbf94508e..61d9b626c1 100644 --- a/api/src/Entity/CampCollaboration.php +++ b/api/src/Entity/CampCollaboration.php @@ -38,28 +38,28 @@ security: 'is_granted("CAMP_COLLABORATOR", object) or is_granted("CAMP_IS_PUBLIC", object)' ), new Patch( - processor: CampCollaborationUpdateProcessor::class, - denormalizationContext: ['groups' => ['write', 'update']], normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, + denormalizationContext: ['groups' => ['write', 'update']], security: '(is_authenticated() && user === object.user) or is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', - validationContext: ['groups' => ['Default', 'update']] + validationContext: ['groups' => ['Default', 'update']], + processor: CampCollaborationUpdateProcessor::class ), new Delete( - validate: true, + security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', validationContext: ['groups' => ['delete']], - security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)' + validate: true ), new Patch( - processor: CampCollaborationResendInvitationProcessor::class, - security: '(is_authenticated() && user === object.user) or is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', uriTemplate: 'camp_collaborations/{id}/'.self::RESEND_INVITATION, - denormalizationContext: ['groups' => ['resend_invitation']], openapi: new OpenApiOperation(summary: 'Send the invitation email for this CampCollaboration again. Only possible, if the status is already invited.'), - validationContext: ['groups' => ['Default', 'resend_invitation']] + denormalizationContext: ['groups' => ['resend_invitation']], + security: '(is_authenticated() && user === object.user) or is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', + validationContext: ['groups' => ['Default', 'resend_invitation']], + processor: CampCollaborationResendInvitationProcessor::class ), new GetCollection( - security: 'is_fully_authenticated()', - normalizationContext: self::COLLECTION_NORMALIZATION_CONTEXT + normalizationContext: self::COLLECTION_NORMALIZATION_CONTEXT, + security: 'is_fully_authenticated()' ), new GetCollection( uriTemplate: self::CAMP_SUBRESOURCE_URI_TEMPLATE, @@ -71,15 +71,15 @@ is_granted("CAMP_IS_PUBLIC", camp)' ), ], - security: 'is_fully_authenticated()', - normalizationContext: self::COLLECTION_NORMALIZATION_CONTEXT + normalizationContext: self::COLLECTION_NORMALIZATION_CONTEXT, + security: 'is_fully_authenticated()' ), new Post( - processor: CampCollaborationCreateProcessor::class, - denormalizationContext: ['groups' => ['write', 'create']], - normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, openapi: new OpenApiOperation(description: 'Also sends an invitation email to the inviteEmail address, if specified.'), - securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.camp === null' + normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, + denormalizationContext: ['groups' => ['write', 'create']], + securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.camp === null', + processor: CampCollaborationCreateProcessor::class ), ], denormalizationContext: ['groups' => ['write']], diff --git a/api/src/Entity/Category.php b/api/src/Entity/Category.php index be7c0ed353..132f985b6e 100644 --- a/api/src/Entity/Category.php +++ b/api/src/Entity/Category.php @@ -39,39 +39,39 @@ is_granted("CAMP_IS_PUBLIC", object)' ), new Patch( - denormalizationContext: ['groups' => ['write', 'update']], normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, + denormalizationContext: ['groups' => ['write', 'update']], security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)' ), new Delete( - processor: CategoryRemoveProcessor::class, security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', - validate: true, validationContext: ['groups' => ['delete']], + validate: true, + processor: CategoryRemoveProcessor::class, ), new GetCollection( security: 'is_authenticated()' ), new Post( - processor: CategoryCreateProcessor::class, - denormalizationContext: ['groups' => ['write', 'create']], normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, - securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.camp === null' + denormalizationContext: ['groups' => ['write', 'create']], + securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.camp === null', + processor: CategoryCreateProcessor::class ), new GetCollection( uriTemplate: self::CAMP_SUBRESOURCE_URI_TEMPLATE, uriVariables: [ 'campId' => new Link( - fromClass: Camp::class, toProperty: 'camp', + fromClass: Camp::class, security: 'is_granted("CAMP_COLLABORATOR", camp) or is_granted("CAMP_IS_PUBLIC", camp)' ), ], + normalizationContext: self::COLLECTION_NORMALIZATION_CONTEXT, extraProperties: [ 'filter_by_current_user' => false, ], - normalizationContext: self::COLLECTION_NORMALIZATION_CONTEXT, ), ], denormalizationContext: ['groups' => ['write']], diff --git a/api/src/Entity/Checklist.php b/api/src/Entity/Checklist.php index d72ffdc545..f5bfb23ea1 100644 --- a/api/src/Entity/Checklist.php +++ b/api/src/Entity/Checklist.php @@ -43,18 +43,18 @@ security: '(is_granted("CHECKLIST_IS_PROTOTYPE", object) and is_granted("ROLE_ADMIN")) or (is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)) ', - validate: true, validationContext: ['groups' => ['delete']], + validate: true, ), new GetCollection( security: 'is_authenticated()' ), new Post( - processor: ChecklistCreateProcessor::class, denormalizationContext: ['groups' => ['write', 'create']], securityPostDenormalize: '(is_granted("CHECKLIST_IS_PROTOTYPE", object) and is_granted("ROLE_ADMIN")) or (!is_granted("CHECKLIST_IS_PROTOTYPE", object) and (is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.camp === null)) - ' + ', + processor: ChecklistCreateProcessor::class ), new GetCollection( uriTemplate: self::CAMP_SUBRESOURCE_URI_TEMPLATE, diff --git a/api/src/Entity/ChecklistItem.php b/api/src/Entity/ChecklistItem.php index 2015148433..18c58e4c0e 100644 --- a/api/src/Entity/ChecklistItem.php +++ b/api/src/Entity/ChecklistItem.php @@ -46,8 +46,8 @@ new Delete( security: '(is_granted("CHECKLIST_IS_PROTOTYPE", object) and is_granted("ROLE_ADMIN")) or (is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object))', - validate: true, validationContext: ['groups' => ['delete']], + validate: true, ), new GetCollection( security: 'is_authenticated()', @@ -63,8 +63,8 @@ uriTemplate: self::CHECKLIST_SUBRESOURCE_URI_TEMPLATE, uriVariables: [ 'checklistId' => new Link( - fromClass: Checklist::class, toProperty: 'checklist', + fromClass: Checklist::class, security: 'is_granted("CHECKLIST_IS_PROTOTYPE", checklist) or is_granted("CAMP_IS_PUBLIC", checklist) or is_granted("CAMP_COLLABORATOR", checklist)' diff --git a/api/src/Entity/Comment.php b/api/src/Entity/Comment.php index 7a48955fe8..7aed79ae1e 100644 --- a/api/src/Entity/Comment.php +++ b/api/src/Entity/Comment.php @@ -37,9 +37,9 @@ security: 'is_authenticated()' ), new Post( - processor: CommentCreateProcessor::class, denormalizationContext: ['groups' => ['create', 'write']], securityPostDenormalize: 'is_granted("CAMP_COLLABORATOR", object)', + processor: CommentCreateProcessor::class, ), new GetCollection( uriTemplate: self::ACTIVITY_SUBRESOURCE_URI_TEMPLATE, diff --git a/api/src/Entity/ContentNode/ChecklistNode.php b/api/src/Entity/ContentNode/ChecklistNode.php index 3de65e186a..20da316c49 100644 --- a/api/src/Entity/ContentNode/ChecklistNode.php +++ b/api/src/Entity/ContentNode/ChecklistNode.php @@ -28,10 +28,10 @@ is_granted("CAMP_IS_PUBLIC", object)' ), new Patch( - processor: ChecklistNodePersistProcessor::class, denormalizationContext: ['groups' => ['write', 'update']], security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', - validationContext: ['groups' => ['Default', 'update']] + validationContext: ['groups' => ['Default', 'update']], + processor: ChecklistNodePersistProcessor::class ), new Delete( security: '(is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)) and object.parent !== null' @@ -41,10 +41,10 @@ provider: ContentNodeCollectionProvider::class ), new Post( - processor: ChecklistNodePersistProcessor::class, denormalizationContext: ['groups' => ['write', 'create']], securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.parent === null', validationContext: ['groups' => ['Default', 'create']], + processor: ChecklistNodePersistProcessor::class, ), ], denormalizationContext: ['groups' => ['write']], diff --git a/api/src/Entity/ContentNode/ColumnLayout.php b/api/src/Entity/ContentNode/ColumnLayout.php index 88a0fd2647..ff52d04a69 100644 --- a/api/src/Entity/ContentNode/ColumnLayout.php +++ b/api/src/Entity/ContentNode/ColumnLayout.php @@ -30,10 +30,10 @@ is_granted("CAMP_IS_PUBLIC", object)' ), new Patch( - processor: ContentNodePersistProcessor::class, denormalizationContext: ['groups' => ['write', 'update']], security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', - validationContext: ['groups' => ['Default', 'update']] + validationContext: ['groups' => ['Default', 'update']], + processor: ContentNodePersistProcessor::class ), new Delete( security: '(is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)) and object.parent !== null' @@ -43,10 +43,10 @@ provider: ContentNodeCollectionProvider::class ), new Post( - processor: ContentNodePersistProcessor::class, denormalizationContext: ['groups' => ['write', 'create']], securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.parent === null', - validationContext: ['groups' => ['Default', 'create']] + validationContext: ['groups' => ['Default', 'create']], + processor: ContentNodePersistProcessor::class ), ], denormalizationContext: ['groups' => ['write']], diff --git a/api/src/Entity/ContentNode/MaterialNode.php b/api/src/Entity/ContentNode/MaterialNode.php index 662e9de983..7259e70ac3 100644 --- a/api/src/Entity/ContentNode/MaterialNode.php +++ b/api/src/Entity/ContentNode/MaterialNode.php @@ -28,10 +28,10 @@ is_granted("CAMP_IS_PUBLIC", object)' ), new Patch( - processor: ContentNodePersistProcessor::class, denormalizationContext: ['groups' => ['write', 'update']], security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', - validationContext: ['groups' => ['Default', 'update']] + validationContext: ['groups' => ['Default', 'update']], + processor: ContentNodePersistProcessor::class ), new Delete( security: '(is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)) and object.parent !== null' @@ -41,10 +41,10 @@ provider: ContentNodeCollectionProvider::class ), new Post( - processor: ContentNodePersistProcessor::class, denormalizationContext: ['groups' => ['write', 'create']], securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.parent === null', - validationContext: ['groups' => ['Default', 'create']] + validationContext: ['groups' => ['Default', 'create']], + processor: ContentNodePersistProcessor::class ), ], denormalizationContext: ['groups' => ['write']], diff --git a/api/src/Entity/ContentNode/MultiSelect.php b/api/src/Entity/ContentNode/MultiSelect.php index ddb51c55a3..0cd381612e 100644 --- a/api/src/Entity/ContentNode/MultiSelect.php +++ b/api/src/Entity/ContentNode/MultiSelect.php @@ -26,10 +26,10 @@ is_granted("CAMP_IS_PUBLIC", object)' ), new Patch( - processor: ContentNodePersistProcessor::class, denormalizationContext: ['groups' => ['write', 'update']], security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', - validationContext: ['groups' => ['Default', 'update']] + validationContext: ['groups' => ['Default', 'update']], + processor: ContentNodePersistProcessor::class ), new Delete( security: '(is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)) and object.parent !== null' // disallow delete when contentNode is a root node @@ -39,10 +39,10 @@ provider: ContentNodeCollectionProvider::class ), new Post( - processor: MultiSelectCreateProcessor::class, denormalizationContext: ['groups' => ['write', 'create']], securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.parent === null', - validationContext: ['groups' => ['Default', 'create']] + validationContext: ['groups' => ['Default', 'create']], + processor: MultiSelectCreateProcessor::class ), ], denormalizationContext: ['groups' => ['write']], diff --git a/api/src/Entity/ContentNode/ResponsiveLayout.php b/api/src/Entity/ContentNode/ResponsiveLayout.php index 1740dc89f1..c3d0fbfc90 100644 --- a/api/src/Entity/ContentNode/ResponsiveLayout.php +++ b/api/src/Entity/ContentNode/ResponsiveLayout.php @@ -29,10 +29,10 @@ is_granted("CAMP_IS_PUBLIC", object)' ), new Patch( - processor: ContentNodePersistProcessor::class, denormalizationContext: ['groups' => ['write', 'update']], security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', - validationContext: ['groups' => ['Default', 'update']] + validationContext: ['groups' => ['Default', 'update']], + processor: ContentNodePersistProcessor::class ), new Delete( security: '(is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)) and object.parent !== null' @@ -42,10 +42,10 @@ provider: ContentNodeCollectionProvider::class ), new Post( - processor: ContentNodePersistProcessor::class, denormalizationContext: ['groups' => ['write', 'create']], securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.parent === null', - validationContext: ['groups' => ['Default', 'create']] + validationContext: ['groups' => ['Default', 'create']], + processor: ContentNodePersistProcessor::class ), ], denormalizationContext: ['groups' => ['write']], diff --git a/api/src/Entity/ContentNode/SingleText.php b/api/src/Entity/ContentNode/SingleText.php index f328be2eac..a98e0b75df 100644 --- a/api/src/Entity/ContentNode/SingleText.php +++ b/api/src/Entity/ContentNode/SingleText.php @@ -25,10 +25,10 @@ is_granted("CAMP_IS_PUBLIC", object)' ), new Patch( - processor: SingleTextPersistProcessor::class, denormalizationContext: ['groups' => ['write', 'update']], security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', - validationContext: ['groups' => ['Default', 'update']] + validationContext: ['groups' => ['Default', 'update']], + processor: SingleTextPersistProcessor::class ), new Delete( security: '(is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)) and object.parent !== null' @@ -38,10 +38,10 @@ provider: ContentNodeCollectionProvider::class ), new Post( - processor: SingleTextPersistProcessor::class, denormalizationContext: ['groups' => ['write', 'create']], securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.parent === null', - validationContext: ['groups' => ['Default', 'create']] + validationContext: ['groups' => ['Default', 'create']], + processor: SingleTextPersistProcessor::class ), ], denormalizationContext: ['groups' => ['write']], diff --git a/api/src/Entity/ContentNode/Storyboard.php b/api/src/Entity/ContentNode/Storyboard.php index bd93533e18..d4b8eca6e1 100644 --- a/api/src/Entity/ContentNode/Storyboard.php +++ b/api/src/Entity/ContentNode/Storyboard.php @@ -25,10 +25,10 @@ is_granted("CAMP_IS_PUBLIC", object)' ), new Patch( - processor: StoryboardPersistProcessor::class, denormalizationContext: ['groups' => ['write', 'update']], security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', - validationContext: ['groups' => ['Default', 'update']] + validationContext: ['groups' => ['Default', 'update']], + processor: StoryboardPersistProcessor::class ), new Delete( security: '(is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)) and object.parent !== null' @@ -38,10 +38,10 @@ provider: ContentNodeCollectionProvider::class ), new Post( - processor: StoryboardPersistProcessor::class, denormalizationContext: ['groups' => ['write', 'create']], securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.parent === null', - validationContext: ['groups' => ['Default', 'create']] + validationContext: ['groups' => ['Default', 'create']], + processor: StoryboardPersistProcessor::class ), ], denormalizationContext: ['groups' => ['write']], diff --git a/api/src/Entity/MaterialItem.php b/api/src/Entity/MaterialItem.php index 6f48613033..b9a24b0d79 100644 --- a/api/src/Entity/MaterialItem.php +++ b/api/src/Entity/MaterialItem.php @@ -37,8 +37,8 @@ is_granted("CAMP_IS_PUBLIC", object)' ), new Patch( - validationContext: ['groups' => MaterialItemUpdateGroupSequence::class], - security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)' + security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', + validationContext: ['groups' => MaterialItemUpdateGroupSequence::class] ), new Delete( security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)' @@ -48,9 +48,9 @@ provider: MaterialItemCollectionProvider::class ), new Post( - processor: MaterialItemCreateProcessor::class, denormalizationContext: ['groups' => ['write', 'create']], securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or (object.period === null and object.materialNode === null)', + processor: MaterialItemCreateProcessor::class, ), ], denormalizationContext: ['groups' => ['write']], diff --git a/api/src/Entity/MaterialList.php b/api/src/Entity/MaterialList.php index 41b913fbc1..3b934e0406 100644 --- a/api/src/Entity/MaterialList.php +++ b/api/src/Entity/MaterialList.php @@ -36,8 +36,8 @@ ), new Delete( security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', - validate: true, - validationContext: ['groups' => ['delete']] + validationContext: ['groups' => ['delete']], + validate: true ), new GetCollection( security: 'is_authenticated()' diff --git a/api/src/Entity/Period.php b/api/src/Entity/Period.php index 86d2f22a83..89b5a448f7 100644 --- a/api/src/Entity/Period.php +++ b/api/src/Entity/Period.php @@ -35,26 +35,26 @@ #[ApiResource( operations: [ new Get( + normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, security: 'is_granted("CAMP_COLLABORATOR", object) or is_granted("CAMP_IS_PUBLIC", object)', - normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, ), new Patch( - processor: PeriodPersistProcessor::class, - security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)' + security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', + processor: PeriodPersistProcessor::class ), new Delete( security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', - validate: true, - validationContext: ['groups' => ['delete', 'Period:delete']] + validationContext: ['groups' => ['delete', 'Period:delete']], + validate: true ), new GetCollection( security: 'is_authenticated()' ), new Post( - processor: PeriodPersistProcessor::class, denormalizationContext: ['groups' => ['write', 'create']], - securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.camp === null' + securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.camp === null', + processor: PeriodPersistProcessor::class ), ], denormalizationContext: ['groups' => ['write']], diff --git a/api/src/Entity/Profile.php b/api/src/Entity/Profile.php index 41cb51c9cf..af3a61ea1b 100644 --- a/api/src/Entity/Profile.php +++ b/api/src/Entity/Profile.php @@ -27,9 +27,9 @@ security: 'is_authenticated()' ), new Patch( - processor: ProfileUpdateProcessor::class, denormalizationContext: ['groups' => ['write', 'update']], - security: 'object.user === user' + security: 'object.user === user', + processor: ProfileUpdateProcessor::class ), new GetCollection( security: 'is_authenticated()' diff --git a/api/src/Entity/ScheduleEntry.php b/api/src/Entity/ScheduleEntry.php index d90d118f52..e82584c14d 100644 --- a/api/src/Entity/ScheduleEntry.php +++ b/api/src/Entity/ScheduleEntry.php @@ -40,8 +40,8 @@ ), new Delete( security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)', - validate: true, - validationContext: ['groups' => ['delete', 'ScheduleEntry:delete']] + validationContext: ['groups' => ['delete', 'ScheduleEntry:delete']], + validate: true ), new GetCollection( security: 'is_authenticated()' @@ -62,8 +62,8 @@ ] ), new Post( - denormalizationContext: ['groups' => ['write', 'create']], normalizationContext: self::ITEM_NORMALIZATION_CONTEXT, + denormalizationContext: ['groups' => ['write', 'create']], securityPostDenormalize: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object) or object.activity === null', validationContext: ['groups' => ScheduleEntryPostGroupSequence::class] ), diff --git a/api/src/Entity/User.php b/api/src/Entity/User.php index 9356dc1919..7697f979e2 100644 --- a/api/src/Entity/User.php +++ b/api/src/Entity/User.php @@ -30,17 +30,17 @@ #[ApiResource( operations: [ new Patch( - processor: UserActivateProcessor::class, uriTemplate: 'users/{id}/activate{._format}', denormalizationContext: ['groups' => ['activate']], - output: User::class + output: User::class, + processor: UserActivateProcessor::class ), new Get( security: 'is_authenticated()' ), new Patch( - processor: UserUpdateProcessor::class, - security: 'object === user' + security: 'object === user', + processor: UserUpdateProcessor::class ), new Delete( security: 'false' @@ -49,11 +49,12 @@ security: 'false' ), new Post( - processor: UserCreateProcessor::class, - security: 'true', // allow unauthenticated clients to create (register) users - validationContext: ['groups' => ['Default', 'create']], normalizationContext: ['groups' => ['read', 'User:create']], - denormalizationContext: ['groups' => ['write', 'create']] + denormalizationContext: ['groups' => ['write', 'create']], + security: 'true', + // allow unauthenticated clients to create (register) users + validationContext: ['groups' => ['Default', 'create']], + processor: UserCreateProcessor::class ), ], denormalizationContext: ['groups' => ['write']], diff --git a/api/src/OpenApi/OAuthDecorator.php b/api/src/OpenApi/OAuthDecorator.php index d5f4b82712..cdaea0f5e4 100644 --- a/api/src/OpenApi/OAuthDecorator.php +++ b/api/src/OpenApi/OAuthDecorator.php @@ -20,6 +20,12 @@ public function __invoke(array $context = []): OpenApi { get: new Model\Operation( operationId: 'oauthGoogleRedirect', tags: ['OAuth'], + responses: [ + '302' => [ + 'description' => 'Redirect to the Google OAuth authorization endpoint', + ], + ], + summary: 'Log in using Google Oauth.', parameters: [ new Model\Parameter( name: 'callback', @@ -29,12 +35,6 @@ public function __invoke(array $context = []): OpenApi { ] ), ], - responses: [ - '302' => [ - 'description' => 'Redirect to the Google OAuth authorization endpoint', - ], - ], - summary: 'Log in using Google Oauth.', ), ); $openApi->getPaths()->addPath('/auth/google', $pathItemGoogle); @@ -44,6 +44,12 @@ public function __invoke(array $context = []): OpenApi { get: new Model\Operation( operationId: 'oauthPbsmidataRedirect', tags: ['OAuth'], + responses: [ + '302' => [ + 'description' => 'Redirect to the PBS MiData OAuth authorization endpoint', + ], + ], + summary: 'Log in using PBS MiData Oauth.', parameters: [ new Model\Parameter( name: 'callback', @@ -53,12 +59,6 @@ public function __invoke(array $context = []): OpenApi { ] ), ], - responses: [ - '302' => [ - 'description' => 'Redirect to the PBS MiData OAuth authorization endpoint', - ], - ], - summary: 'Log in using PBS MiData Oauth.', ), ); $openApi->getPaths()->addPath('/auth/pbsmidata', $pathItemPbsmidata); @@ -68,6 +68,12 @@ public function __invoke(array $context = []): OpenApi { get: new Model\Operation( operationId: 'oauthCevidbRedirect', tags: ['OAuth'], + responses: [ + '302' => [ + 'description' => 'Redirect to the CeviDB OAuth authorization endpoint', + ], + ], + summary: 'Log in using CeviDB Oauth.', parameters: [ new Model\Parameter( name: 'callback', @@ -77,12 +83,6 @@ public function __invoke(array $context = []): OpenApi { ] ), ], - responses: [ - '302' => [ - 'description' => 'Redirect to the CeviDB OAuth authorization endpoint', - ], - ], - summary: 'Log in using CeviDB Oauth.', ), ); $openApi->getPaths()->addPath('/auth/cevidb', $pathItemCevidb); @@ -92,6 +92,12 @@ public function __invoke(array $context = []): OpenApi { get: new Model\Operation( operationId: 'oauthJubladbRedirect', tags: ['OAuth'], + responses: [ + '302' => [ + 'description' => 'Redirect to the JublaDB OAuth authorization endpoint', + ], + ], + summary: 'Log in using JublaDB Oauth.', parameters: [ new Model\Parameter( name: 'callback', @@ -101,12 +107,6 @@ public function __invoke(array $context = []): OpenApi { ] ), ], - responses: [ - '302' => [ - 'description' => 'Redirect to the JublaDB OAuth authorization endpoint', - ], - ], - summary: 'Log in using JublaDB Oauth.', ), ); $openApi->getPaths()->addPath('/auth/jubladb', $pathItemJubladb); diff --git a/api/src/Security/Voter/CampIsPublicVoter.php b/api/src/Security/Voter/CampIsPublicVoter.php index 3a0c06add9..b06db69de2 100644 --- a/api/src/Security/Voter/CampIsPublicVoter.php +++ b/api/src/Security/Voter/CampIsPublicVoter.php @@ -8,6 +8,7 @@ use App\Util\GetCampFromContentNodeTrait; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Authorization\Voter\Vote; use Symfony\Component\Security\Core\Authorization\Voter\Voter; /** @@ -26,7 +27,7 @@ protected function supports($attribute, $subject): bool { && ($subject instanceof BelongsToCampInterface || $subject instanceof BelongsToContentNodeTreeInterface); } - protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool { + protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool { $camp = $this->getCampFromInterface($subject, $this->em); if (null === $camp) { diff --git a/api/src/Security/Voter/CampRoleVoter.php b/api/src/Security/Voter/CampRoleVoter.php index f1895a013a..d010595c6c 100644 --- a/api/src/Security/Voter/CampRoleVoter.php +++ b/api/src/Security/Voter/CampRoleVoter.php @@ -10,6 +10,7 @@ use App\Util\GetCampFromContentNodeTrait; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Authorization\Voter\Vote; use Symfony\Component\Security\Core\Authorization\Voter\Voter; /** @@ -35,7 +36,7 @@ protected function supports($attribute, $subject): bool { && ($subject instanceof BelongsToCampInterface || $subject instanceof BelongsToContentNodeTreeInterface); } - protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool { + protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool { $user = $token->getUser(); if (!$user instanceof User) { return false; diff --git a/api/src/Security/Voter/ChecklistIsPrototypeVoter.php b/api/src/Security/Voter/ChecklistIsPrototypeVoter.php index ec7f4c49b3..10a5e17f0f 100644 --- a/api/src/Security/Voter/ChecklistIsPrototypeVoter.php +++ b/api/src/Security/Voter/ChecklistIsPrototypeVoter.php @@ -5,6 +5,7 @@ use App\Entity\Checklist; use App\Entity\ChecklistItem; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Authorization\Voter\Vote; use Symfony\Component\Security\Core\Authorization\Voter\Voter; /** @@ -18,7 +19,7 @@ protected function supports($attribute, $subject): bool { && ($subject instanceof Checklist || $subject instanceof ChecklistItem); } - protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool { + protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool { if ($subject instanceof Checklist) { $checklist = $subject; } diff --git a/api/src/Serializer/PreventAutomaticEmbeddingPropertyMetadataFactory.php b/api/src/Serializer/PreventAutomaticEmbeddingPropertyMetadataFactory.php index 500c9cd9cc..affd0c9cfa 100644 --- a/api/src/Serializer/PreventAutomaticEmbeddingPropertyMetadataFactory.php +++ b/api/src/Serializer/PreventAutomaticEmbeddingPropertyMetadataFactory.php @@ -89,8 +89,8 @@ public function create(string $resourceClass, string $property, array $options = property: $apiProperty->getProperty(), policy: $apiProperty->getPolicy(), serialize: $apiProperty->getSerialize(), - extraProperties: $apiProperty->getExtraProperties(), hydra: $apiProperty->getHydra(), + extraProperties: $apiProperty->getExtraProperties(), ); } } diff --git a/api/src/State/ValidationErrorProvider.php b/api/src/State/ValidationErrorProvider.php index d7dbb00896..3bf0e9b000 100644 --- a/api/src/State/ValidationErrorProvider.php +++ b/api/src/State/ValidationErrorProvider.php @@ -67,12 +67,12 @@ public function provide(Operation $operation, array $uriVariables = [], array $c } return new ValidationError( - type: $error->getType(), title: $error->getTitle(), status: $status, detail: $error->getDetail(), instance: $error->getInstance(), - violations: $violationInfos + violations: $violationInfos, + type: $error->getType() ); } } diff --git a/api/tests/Api/Activities/DeleteActivityTest.php b/api/tests/Api/Activities/DeleteActivityTest.php index a7f7887e89..d961d666df 100644 --- a/api/tests/Api/Activities/DeleteActivityTest.php +++ b/api/tests/Api/Activities/DeleteActivityTest.php @@ -147,7 +147,6 @@ public function testDeleteActivityAlsoNullifiesCommentReferencesAndSetsOrphanDes $client->disableReboot(); $activity = static::$fixtures['activity1']; - $comments = $activity->comments; $client->request('DELETE', $this->getIriFor($activity)); $this->assertResponseStatusCodeSame(204); diff --git a/api/tests/Api/Camps/CreateCampTest.php b/api/tests/Api/Camps/CreateCampTest.php index 9500db9e53..15af72536d 100644 --- a/api/tests/Api/Camps/CreateCampTest.php +++ b/api/tests/Api/Camps/CreateCampTest.php @@ -683,7 +683,6 @@ public function testCreateCampFromPrototype() { } public function testCreateCampFromSharedCamp() { - /** @var Camp $campPrototype */ $campShared = self::getFixture('campShared'); $response = static::createClientWithCredentials()->request('POST', '/camps', ['json' => $this->getExampleWritePayload([ diff --git a/api/tests/Api/ChecklistItems/ListChecklistItemsTest.php b/api/tests/Api/ChecklistItems/ListChecklistItemsTest.php index 0a5af08cfb..8c8c0e65d4 100644 --- a/api/tests/Api/ChecklistItems/ListChecklistItemsTest.php +++ b/api/tests/Api/ChecklistItems/ListChecklistItemsTest.php @@ -21,7 +21,7 @@ public function testListChecklistItemsWithoutFilterIsNotAllowedForLoggedInUser() // precondition: There is a checklist-item that the user doesn't have access to $this->assertNotEmpty(static::$fixtures['checklistItemUnrelated_1_1']); - $response = static::createClientWithCredentials()->request('GET', '/checklist_items'); + static::createClientWithCredentials()->request('GET', '/checklist_items'); $this->assertResponseStatusCodeSame(400); } diff --git a/api/tests/Api/Comments/ListCommentsTest.php b/api/tests/Api/Comments/ListCommentsTest.php index 7f658c1f7e..5976e532c2 100644 --- a/api/tests/Api/Comments/ListCommentsTest.php +++ b/api/tests/Api/Comments/ListCommentsTest.php @@ -21,6 +21,7 @@ public function testListCommentsIsDeniedForAnonymousUser() { } public function testListCommentsIsAllowedForLoggedInUser() { + /** @noRector */ $response = static::createClientWithCredentials()->request('GET', '/comments'); $this->assertResponseStatusCodeSame(200); diff --git a/api/tests/Api/ContentNodes/ContentNode/ListContentNodesTest.php b/api/tests/Api/ContentNodes/ContentNode/ListContentNodesTest.php index 57792859c5..3c1e05db21 100644 --- a/api/tests/Api/ContentNodes/ContentNode/ListContentNodesTest.php +++ b/api/tests/Api/ContentNodes/ContentNode/ListContentNodesTest.php @@ -20,7 +20,7 @@ public function testListContentNodesIsDeniedForAnonymousUser() { } public function testListContentNodesWithoutFilterIsNotAllowedForLoggedInUser() { - $response = static::createClientWithCredentials()->request('GET', '/content_nodes'); + static::createClientWithCredentials()->request('GET', '/content_nodes'); $this->assertResponseStatusCodeSame(400); } diff --git a/api/tests/Api/ContentNodes/ListContentNodeTestCase.php b/api/tests/Api/ContentNodes/ListContentNodeTestCase.php index ee6efe90c2..5afbe666b1 100644 --- a/api/tests/Api/ContentNodes/ListContentNodeTestCase.php +++ b/api/tests/Api/ContentNodes/ListContentNodeTestCase.php @@ -52,7 +52,7 @@ public function testListForInvitedCollaborator() { $this->assertJsonContainsItems($response, $this->contentNodesCampShared); $this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campUnrelated'); - $response = $this->list(user: static::$fixtures['user6invited']); + $this->list(user: static::$fixtures['user6invited']); $this->assertResponseStatusCodeSame(400); $this->assertJsonContains(['status' => 400]); } @@ -69,7 +69,7 @@ public function testListForInactiveCollaborator() { $this->assertJsonContainsItems($response, $this->contentNodesCampShared); $this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campUnrelated'); - $response = $this->list(user: static::$fixtures['user5inactive']); + $this->list(user: static::$fixtures['user5inactive']); $this->assertResponseStatusCodeSame(400); $this->assertJsonContains(['status' => 400]); } @@ -91,7 +91,7 @@ public function testListForUnrelatedUser() { $this->assertJsonContainsItems($response, $this->contentNodesCampShared); $this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('camp1'); - $response = $this->list(user: static::$fixtures['user4unrelated']); + $this->list(user: static::$fixtures['user4unrelated']); $this->assertResponseStatusCodeSame(400); $this->assertJsonContains(['status' => 400]); } @@ -118,7 +118,7 @@ public function testListForGuest() { $this->assertJsonContainsItems($response, $this->contentNodesCampShared); $this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campUnrelated'); - $response = $this->list(user: static::$fixtures['user3guest']); + $this->list(user: static::$fixtures['user3guest']); $this->assertResponseStatusCodeSame(400); $this->assertJsonContains(['status' => 400]); } @@ -145,7 +145,7 @@ public function testListForMember() { $this->assertJsonContainsItems($response, $this->contentNodesCampShared); $this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campUnrelated'); - $response = $this->list(user: static::$fixtures['user2member']); + $this->list(user: static::$fixtures['user2member']); $this->assertResponseStatusCodeSame(400); $this->assertJsonContains(['status' => 400]); } @@ -172,7 +172,7 @@ public function testListForManager() { $this->assertJsonContainsItems($response, $this->contentNodesCampShared); $this->endpoint = $this->endpointBase.'?camp='.$this->getIriFor('campUnrelated'); - $response = $this->list(user: static::$fixtures['user1manager']); + $this->list(user: static::$fixtures['user1manager']); $this->assertResponseStatusCodeSame(400); $this->assertJsonContains(['status' => 400]); } diff --git a/api/tests/Api/MaterialItems/ListMaterialItemsTest.php b/api/tests/Api/MaterialItems/ListMaterialItemsTest.php index 92ccbdcabb..9dd4edc70f 100644 --- a/api/tests/Api/MaterialItems/ListMaterialItemsTest.php +++ b/api/tests/Api/MaterialItems/ListMaterialItemsTest.php @@ -21,7 +21,7 @@ public function testListMaterialItemsWithoutFilterIsNotAllowedForLoggedInUser() // precondition: There is a material item that the user doesn't have access to $this->assertNotEmpty(static::$fixtures['materialItem1period1campUnrelated']); - $response = static::createClientWithCredentials()->request('GET', '/material_items'); + static::createClientWithCredentials()->request('GET', '/material_items'); $this->assertResponseStatusCodeSame(400); } diff --git a/api/tests/Api/SnapshotTests/EndpointPerformanceTest.php b/api/tests/Api/SnapshotTests/EndpointPerformanceTest.php index c0b644f37e..b7e5dde291 100644 --- a/api/tests/Api/SnapshotTests/EndpointPerformanceTest.php +++ b/api/tests/Api/SnapshotTests/EndpointPerformanceTest.php @@ -70,7 +70,7 @@ public function testPerformanceDidNotChangeForStableEndpoints() { $not200Responses = array_filter($responseCodes, fn ($value) => 200 != $value); assertThat($not200Responses, equalTo([])); - if (static::isPerformanceTestDebugOutput()) { + if (self::isPerformanceTestDebugOutput()) { var_dump($queryExecutionTime); } @@ -99,7 +99,7 @@ public function testNumberOfQueriesDidNotChangeForContentNodeCollectionEndpoints assertThat($statusCode, equalTo(200)); - if (static::isPerformanceTestDebugOutput()) { + if (self::isPerformanceTestDebugOutput()) { echo "{$collectionEndpoint}: {$executionTimeSeconds}\n"; } @@ -133,7 +133,7 @@ public function testNumberOfQueriesDidNotChangeForContentNodeItemEndpoints(strin assertThat($statusCode, equalTo(200)); - if (static::isPerformanceTestDebugOutput()) { + if (self::isPerformanceTestDebugOutput()) { echo "{$collectionEndpoint}: {$executionTimeSeconds}\n"; } diff --git a/api/tests/Api/SnapshotTests/Extension/FilterEagerLoadingExtensionIntegrationTest.php b/api/tests/Api/SnapshotTests/Extension/FilterEagerLoadingExtensionIntegrationTest.php index 51bd7e5666..8c7cfb6718 100644 --- a/api/tests/Api/SnapshotTests/Extension/FilterEagerLoadingExtensionIntegrationTest.php +++ b/api/tests/Api/SnapshotTests/Extension/FilterEagerLoadingExtensionIntegrationTest.php @@ -58,7 +58,7 @@ public function testOptimizeQueryWhenFilterHitsToManyJoin() { $queryBuilder->expr()->lte('a2.title', ':text'), $queryBuilder->expr()->orX( $queryBuilder->expr()->in('a2.title', [':text']), - $queryBuilder->expr()->eq($queryBuilder->expr()->lower('a2.title'), ':text') + $queryBuilder->expr()->eq((string) $queryBuilder->expr()->lower('a2.title'), ':text') ) ) ) diff --git a/api/tests/Api/SnapshotTests/ResponseSnapshotTest.php b/api/tests/Api/SnapshotTests/ResponseSnapshotTest.php index 57b703cc44..9cf12fd710 100644 --- a/api/tests/Api/SnapshotTests/ResponseSnapshotTest.php +++ b/api/tests/Api/SnapshotTests/ResponseSnapshotTest.php @@ -156,7 +156,7 @@ public static function getCollectionEndpointsFiltered() { static::bootKernel(); $client = static::createClientWithCredentials(); $client->disableReboot(); - $response = $client->request('GET', '/'); + $client->request('GET', '/'); return [ [$client, '/content_nodes?camp=/camps/'.self::getFixtureFor('/camps')->getId()], diff --git a/api/tests/HttpCache/PurgeHttpCacheListenerTest.php b/api/tests/HttpCache/PurgeHttpCacheListenerTest.php index 97bed56215..17d9580638 100644 --- a/api/tests/HttpCache/PurgeHttpCacheListenerTest.php +++ b/api/tests/HttpCache/PurgeHttpCacheListenerTest.php @@ -320,7 +320,7 @@ public function testNotAResourceClass(): void { $dummyClassMetadata = new ClassMetadata(ContainNonResource::class); $emProphecy->getClassMetadata(NotAResource::class)->willReturn($dummyClassMetadata); $em = $emProphecy->reveal(); - $eventArgs = new OnFlushEventArgs($em); + new OnFlushEventArgs($em); $propertyAccessorProphecy = $this->prophesize(PropertyAccessorInterface::class); @@ -373,7 +373,7 @@ public function testPropertyIsNotAResourceClass(): void { $dummyClassMetadata->mapOneToMany(['fieldName' => 'collectionOfNotAResource', 'targetEntity' => NotAResource::class, 'mappedBy' => 'resource']); $emProphecy->getClassMetadata(ContainNonResource::class)->willReturn($dummyClassMetadata); $em = $emProphecy->reveal(); - $eventArgs = new OnFlushEventArgs($em); + new OnFlushEventArgs($em); $propertyAccessorProphecy = $this->prophesize(PropertyAccessorInterface::class); $propertyAccessorProphecy->isReadable(Argument::type(ContainNonResource::class), 'notAResource')->willReturn(true); diff --git a/api/tests/Metadata/Resource/Factory/UriTemplateFactoryTest.php b/api/tests/Metadata/Resource/Factory/UriTemplateFactoryTest.php index 802993a090..5baffa74b2 100644 --- a/api/tests/Metadata/Resource/Factory/UriTemplateFactoryTest.php +++ b/api/tests/Metadata/Resource/Factory/UriTemplateFactoryTest.php @@ -53,7 +53,7 @@ protected function setUp(): void { $this->resourceNameCollectionFactory->method('create')->willReturnCallback(fn (): ResourceNameCollection => $this->resourceNameCollection); $this->resourceMetadataCollectionFactory->method('create')->with('Dummy')->willReturnCallback(fn () => $this->resourceMetadataCollection); - $this->iriConverter->method('getIriFromResource')->willReturnCallback(function (object|string $resourceClass): ?string { + $this->iriConverter->method('getIriFromResource')->willReturnCallback(function (object|string $resourceClass): string { return '/'.lcfirst($resourceClass).'s'; }); } @@ -116,8 +116,8 @@ public function testCreatesTemplatedUriWithFilterQueryParameter() { name: '_api_/dummys/{id}{._format}_get' ), new GetCollection( - name: '_api_/dummys{._format}_get_collection', - filters: ['some_filter_identifier'] + filters: ['some_filter_identifier'], + name: '_api_/dummys{._format}_get_collection' ), ]))); $filter = $this->createMock(FilterInterface::class); @@ -157,9 +157,9 @@ public function testCreatesTemplatedUriWithAdvancedPaginationQueryParameters() { name: '_api_/dummys/{id}{._format}_get' ), new GetCollection( - name: '_api_/dummys{._format}_get_collection', paginationClientEnabled: true, - paginationClientItemsPerPage: true + paginationClientItemsPerPage: true, + name: '_api_/dummys{._format}_get_collection' ), ]))); $this->createFactory(); @@ -181,12 +181,12 @@ public function testCreatesTemplatedUriWithActionPathParameters() { name: '_api_/dummys/{id}{._format}_get' ), new Get( - name: '_api_/dummys/{id}/find{._format}_get', uriTemplate: '/dummys/{inviteKey}/find{._format}', + name: '_api_/dummys/{id}/find{._format}_get', ), new Patch( - name: '_api_/dummys/{id}/accept{._format}_get', uriTemplate: '/dummys/{inviteKey}/accept{._format}', + name: '_api_/dummys/{id}/accept{._format}_get', ), ]))); $this->createFactory(); diff --git a/api/tests/State/CategoryCreateProcessorTest.php b/api/tests/State/CategoryCreateProcessorTest.php index c937de5816..9607ad6779 100644 --- a/api/tests/State/CategoryCreateProcessorTest.php +++ b/api/tests/State/CategoryCreateProcessorTest.php @@ -34,7 +34,7 @@ protected function setUp(): void { public function testCreatesNewContentNodeBeforeCreate() { // given $repositoryMock = $this->createMock(EntityRepository::class); - $repositoryMock->method('findOneBy')->willReturnCallback(function (array $criteria): ?object { + $repositoryMock->method('findOneBy')->willReturnCallback(function (array $criteria): object { $result = new ContentType(); $result->name = $criteria['name']; diff --git a/api/tests/Validator/ColumnLayout/AssertColumWidthsSumTo12ValidatorTest.php b/api/tests/Validator/ColumnLayout/AssertColumWidthsSumTo12ValidatorTest.php index e842e7821a..caaf4fa0c9 100644 --- a/api/tests/Validator/ColumnLayout/AssertColumWidthsSumTo12ValidatorTest.php +++ b/api/tests/Validator/ColumnLayout/AssertColumWidthsSumTo12ValidatorTest.php @@ -55,7 +55,7 @@ public function testInvalid() { $this->validator->validate($data, new AssertColumWidthsSumTo12()); // then - $this->buildViolation(self::message)->setParameter('{{ sum }}', 11)->assertRaised(); + $this->buildViolation(self::message)->setParameter('{{ sum }}', '11')->assertRaised(); } public function testMissingWidthIsCountedZero() { @@ -68,7 +68,7 @@ public function testMissingWidthIsCountedZero() { $this->validator->validate($data, new AssertColumWidthsSumTo12()); // then - $this->buildViolation(self::message)->setParameter('{{ sum }}', 0)->assertRaised(); + $this->buildViolation(self::message)->setParameter('{{ sum }}', '0')->assertRaised(); } protected function createValidator(): ConstraintValidatorInterface {