diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fbb073 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/vendor/ +/composer.lock diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..1edd9de --- /dev/null +++ b/composer.json @@ -0,0 +1,20 @@ +{ + "name": "oat-sa/lib-em-php-lti-events", + "minimum-stability": "dev", + "require": { + "symfony/validator": "5.3.*", + "symfony/serializer": "5.3.*", + "doctrine/annotations": "1.14.x-dev", + "oat-sa/lib-lti1p3-ags": "^1.2", + "symfony/property-access": "5.3.*", + "oat-sa/lib-lti1p3-core": "^6.6", + "oat-sa/lib-lti1p3-proctoring": "^0.4", + "oat-sa/lib-lti1p3-basic-outcome": "^4.1", + "oat-sa/lib-lti1p3-nrps": "^7.0" + }, + "autoload": { + "psr-4": { + "OAT\\Library\\EnvironmentManagementLtiEvents\\": "src/" + } + } +} diff --git a/src/Event/Ags/CreateLineItemEvent.php b/src/Event/Ags/CreateLineItemEvent.php new file mode 100644 index 0000000..02ade8b --- /dev/null +++ b/src/Event/Ags/CreateLineItemEvent.php @@ -0,0 +1,34 @@ +registrationId; + } + + public function getLineItem(): LineItemInterface + { + return $this->lineItem; + } + + public function getLineItemsContainerUrl(): string + { + return $this->lineItemsContainerUrl; + } +} diff --git a/src/Event/Ags/DeleteLineItemEvent.php b/src/Event/Ags/DeleteLineItemEvent.php new file mode 100644 index 0000000..56b28c8 --- /dev/null +++ b/src/Event/Ags/DeleteLineItemEvent.php @@ -0,0 +1,27 @@ +registrationId; + } + + public function getLineItemUrl(): string + { + return $this->lineItemUrl; + } +} diff --git a/src/Event/Ags/GetLineItemEvent.php b/src/Event/Ags/GetLineItemEvent.php new file mode 100644 index 0000000..21dec39 --- /dev/null +++ b/src/Event/Ags/GetLineItemEvent.php @@ -0,0 +1,33 @@ +registrationId; + } + + public function getLineItemUrl(): string + { + return $this->lineItemUrl; + } + + public function getScopes(): array + { + return $this->scopes; + } +} diff --git a/src/Event/Ags/ListLineItemsEvent.php b/src/Event/Ags/ListLineItemsEvent.php new file mode 100644 index 0000000..ecb4e31 --- /dev/null +++ b/src/Event/Ags/ListLineItemsEvent.php @@ -0,0 +1,63 @@ +registrationId; + } + + public function getLineItemsContainerUrl(): string + { + return $this->lineItemsContainerUrl; + } + + public function getResourceIdentifier(): ?string + { + return $this->resourceIdentifier; + } + + public function getResourceLinkIdentifier(): ?string + { + return $this->resourceLinkIdentifier; + } + + public function getTag(): ?string + { + return $this->tag; + } + + public function getLimit(): ?int + { + return $this->limit; + } + + public function getOffset(): ?int + { + return $this->offset; + } + + public function getScopes(): ?array + { + return $this->scopes; + } +} diff --git a/src/Event/Ags/ListResultsEvent.php b/src/Event/Ags/ListResultsEvent.php new file mode 100644 index 0000000..4538d19 --- /dev/null +++ b/src/Event/Ags/ListResultsEvent.php @@ -0,0 +1,45 @@ +registrationId; + } + + public function getLineItemUrl(): string + { + return $this->lineItemUrl; + } + + public function getUserIdentifier(): ?string + { + return $this->userIdentifier; + } + + public function getLimit(): ?int + { + return $this->limit; + } + + public function getOffset(): ?int + { + return $this->offset; + } +} diff --git a/src/Event/Ags/PublishScoreEvent.php b/src/Event/Ags/PublishScoreEvent.php new file mode 100644 index 0000000..52b0260 --- /dev/null +++ b/src/Event/Ags/PublishScoreEvent.php @@ -0,0 +1,34 @@ +registrationId; + } + + public function getScore(): ScoreInterface + { + return $this->score; + } + + public function getLineItemUrl(): string + { + return $this->lineItemUrl; + } +} diff --git a/src/Event/Ags/UpdateLineItemEvent.php b/src/Event/Ags/UpdateLineItemEvent.php new file mode 100644 index 0000000..6e4d935 --- /dev/null +++ b/src/Event/Ags/UpdateLineItemEvent.php @@ -0,0 +1,34 @@ +registrationId; + } + + public function getLineItem(): LineItemInterface + { + return $this->lineItem; + } + + public function getLineItemUrl(): ?string + { + return $this->lineItemUrl; + } +} diff --git a/src/Event/BasicOutcome/DeleteResultEvent.php b/src/Event/BasicOutcome/DeleteResultEvent.php new file mode 100644 index 0000000..7eb17ea --- /dev/null +++ b/src/Event/BasicOutcome/DeleteResultEvent.php @@ -0,0 +1,33 @@ +registrationId; + } + + public function getLisOutcomeServiceUrl(): string + { + return $this->lisOutcomeServiceUrl; + } + + public function getLisResultSourcedId(): string + { + return $this->lisResultSourcedId; + } +} diff --git a/src/Event/BasicOutcome/ReadResultEvent.php b/src/Event/BasicOutcome/ReadResultEvent.php new file mode 100644 index 0000000..64c2d1c --- /dev/null +++ b/src/Event/BasicOutcome/ReadResultEvent.php @@ -0,0 +1,33 @@ +registrationId; + } + + public function getLisOutcomeServiceUrl(): string + { + return $this->lisOutcomeServiceUrl; + } + + public function getLisResultSourcedId(): string + { + return $this->lisResultSourcedId; + } +} diff --git a/src/Event/BasicOutcome/ReplaceResultEvent.php b/src/Event/BasicOutcome/ReplaceResultEvent.php new file mode 100644 index 0000000..521f5b0 --- /dev/null +++ b/src/Event/BasicOutcome/ReplaceResultEvent.php @@ -0,0 +1,45 @@ +registrationId; + } + + public function getLisOutcomeServiceUrl(): string + { + return $this->lisOutcomeServiceUrl; + } + + public function getLisResultSourcedId(): string + { + return $this->lisResultSourcedId; + } + + public function getScore(): float + { + return $this->score; + } + + public function getLanguage(): string + { + return $this->language; + } +} diff --git a/src/Event/BasicOutcome/SendBasicOutcomeEvent.php b/src/Event/BasicOutcome/SendBasicOutcomeEvent.php new file mode 100644 index 0000000..ffe1014 --- /dev/null +++ b/src/Event/BasicOutcome/SendBasicOutcomeEvent.php @@ -0,0 +1,34 @@ +registrationId; + } + + public function getLisOutcomeServiceUrl(): string + { + return $this->lisOutcomeServiceUrl; + } + + public function getXml(): string + { + return $this->xml; + } +} + diff --git a/src/Event/Core/RequestEvent.php b/src/Event/Core/RequestEvent.php new file mode 100644 index 0000000..2293e5e --- /dev/null +++ b/src/Event/Core/RequestEvent.php @@ -0,0 +1,45 @@ +registrationId; + } + + public function getMethod(): string + { + return $this->method; + } + + public function getUri(): string + { + return $this->uri; + } + + public function getOptions(): array + { + return $this->options; + } + + public function getScopes(): array + { + return $this->scopes; + } +} diff --git a/src/Event/EventInterface.php b/src/Event/EventInterface.php new file mode 100644 index 0000000..062c836 --- /dev/null +++ b/src/Event/EventInterface.php @@ -0,0 +1,45 @@ +registrationId; + } + + public function getMembershipServiceUrl(): string + { + return $this->membershipServiceUrl; + } + + public function getRole(): ?string + { + return $this->role; + } + + public function getLimit(): ?int + { + return $this->limit; + } +} diff --git a/src/Event/Nrps/GetResourceLinkMembershipEvent.php b/src/Event/Nrps/GetResourceLinkMembershipEvent.php new file mode 100644 index 0000000..ae406a8 --- /dev/null +++ b/src/Event/Nrps/GetResourceLinkMembershipEvent.php @@ -0,0 +1,45 @@ +registrationId; + } + + public function getMembershipServiceUrl(): string + { + return $this->membershipServiceUrl; + } + + public function getResourceLinkIdentifier(): string + { + return $this->resourceLinkIdentifier; + } + + public function getRole(): ?string + { + return $this->role; + } + + public function getLimit(): ?int + { + return $this->limit; + } +} diff --git a/src/Event/Proctoring/SendControlEvent.php b/src/Event/Proctoring/SendControlEvent.php new file mode 100644 index 0000000..1fc392e --- /dev/null +++ b/src/Event/Proctoring/SendControlEvent.php @@ -0,0 +1,34 @@ +registrationId; + } + + public function getControl(): AcsControlInterface + { + return $this->control; + } + + public function getAcsUrl(): string + { + return $this->acsUrl; + } +} diff --git a/src/Factory/LtiSerializerFactory.php b/src/Factory/LtiSerializerFactory.php new file mode 100644 index 0000000..807ed92 --- /dev/null +++ b/src/Factory/LtiSerializerFactory.php @@ -0,0 +1,51 @@ + $object->getScoreMaximum(), + self::PARAM_LABEL => $object->getLabel(), + self::PARAM_IDENTIFIER => $object->getIdentifier(), + self::PARAM_RESOURCE_IDENTIFIER => $object->getResourceIdentifier(), + self::PARAM_RESOURCE_LINK_IDENTIFIER => $object->getResourceLinkIdentifier(), + self::PARAM_TAG => $object->getTag(), + self::PARAM_START_DATE_TIME => $this->normalizer->normalize($object->getStartDateTime(), $format, $context), + self::PARAM_END_DATE_TIME => $this->normalizer->normalize($object->getEndDateTime(), $format, $context), + self::PARAM_SUBMISSION_REVIEW => $this->normalizer->normalize($object->getSubmissionReview(), $format, $context), + self::PARAM_ADDITIONAL_PROPERTIES => $this->normalizer->normalize($object->getAdditionalProperties(), $format, $context), + ]; + } + + public function supportsNormalization($data, string $format = null): bool + { + return $data instanceof LineItemInterface; + } + + public function denormalize($data, string $type, string $format = null, array $context = []): ?LineItemInterface + { + if ($data === null) { + return null; + } + + return new LineItem( + $data[self::PARAM_SCORE_MAXIMUM], + $data[self::PARAM_LABEL], + $data[self::PARAM_IDENTIFIER] ?? null, + $data[self::PARAM_RESOURCE_IDENTIFIER] ?? null, + $data[self::PARAM_RESOURCE_LINK_IDENTIFIER] ?? null, + $data[self::PARAM_TAG] ?? null, + ($data[self::PARAM_START_DATE_TIME] ?? null) !== null ? $this->denormalizer->denormalize($data[self::PARAM_START_DATE_TIME] ?? null, DateTime::class, $format, $context) : null, + ($data[self::PARAM_END_DATE_TIME] ?? null) !== null ? $this->denormalizer->denormalize($data[self::PARAM_END_DATE_TIME] ?? null, DateTime::class, $format, $context) : null, + ($data[self::PARAM_SUBMISSION_REVIEW] ?? null) !== null ? $this->denormalizer->denormalize($data[self::PARAM_SUBMISSION_REVIEW] ?? null, LineItemSubmissionReview::class, $format, $context) : null, + $this->denormalizer->denormalize($data[self::PARAM_ADDITIONAL_PROPERTIES] ?? [], Collection::class, $format, $context)->all(), + ); + } + + public function supportsDenormalization($data, string $type, string $format = null): bool + { + return in_array($type, [ + LineItemInterface::class, + LineItem::class, + ]); + } +} \ No newline at end of file diff --git a/src/Normalizer/Ags/ScoreNormalizer.php b/src/Normalizer/Ags/ScoreNormalizer.php new file mode 100644 index 0000000..479bb5b --- /dev/null +++ b/src/Normalizer/Ags/ScoreNormalizer.php @@ -0,0 +1,79 @@ + $object->getUserIdentifier(), + self::PARAM_ACTIVITY_PROGRESS_STATUS => $object->getActivityProgressStatus(), + self::PARAM_GRADING_PROGRESS_STATUS => $object->getGradingProgressStatus(), + self::PARAM_LINE_ITEM_IDENTIFIER => $object->getLineItemIdentifier(), + self::PARAM_SCORE_GIVEN => $object->getScoreGiven(), + self::PARAM_SCORE_MAXIMUM => $object->getScoreMaximum(), + self::PARAM_COMMENT => $object->getComment(), + self::PARAM_TIMESTAMP => $object->getTimestamp(), + self::PARAM_ADDITIONAL_PROPERTIES => $this->normalizer->normalize($object->getAdditionalProperties(), $format, $context), + ]; + } + + public function supportsNormalization($data, string $format = null): bool + { + return $data instanceof ScoreInterface; + } + + public function denormalize($data, string $type, string $format = null, array $context = []): Score + { + return new Score( + $data[self::PARAM_USER_IDENTIFIER], + $data[self::PARAM_ACTIVITY_PROGRESS_STATUS] ?? ScoreInterface::ACTIVITY_PROGRESS_STATUS_INITIALIZED, + $data[self::PARAM_GRADING_PROGRESS_STATUS] ?? Score::GRADING_PROGRESS_STATUS_NOT_READY, + $data[self::PARAM_LINE_ITEM_IDENTIFIER] ?? null, + $data[self::PARAM_SCORE_GIVEN] ?? null, + $data[self::PARAM_SCORE_MAXIMUM] ?? null, + $data[self::PARAM_COMMENT] ?? null, + $data[self::PARAM_TIMESTAMP] ?? null, + $this->denormalizer->denormalize($data[self::PARAM_ADDITIONAL_PROPERTIES] ?? [], Collection::class, $format, $context), + ); + } + + public function supportsDenormalization($data, string $type, string $format = null): bool + { + return in_array($type, [ + ScoreInterface::class, + Score::class, + ]); + } +} diff --git a/src/Normalizer/Ags/SubmissionReviewNormalizer.php b/src/Normalizer/Ags/SubmissionReviewNormalizer.php new file mode 100644 index 0000000..9a909ed --- /dev/null +++ b/src/Normalizer/Ags/SubmissionReviewNormalizer.php @@ -0,0 +1,55 @@ + $object->getReviewableStatuses(), + self::PARAM_LABEL => $object->getLabel(), + self::PARAM_URL => $object->getUrl(), + self::PARAM_CUSTOM_PROPERTIES => $object->getCustomProperties(), + ]; + } + + public function supportsNormalization($data, string $format = null): bool + { + return $data instanceof LineItemSubmissionReviewInterface; + } + + public function denormalize($data, string $type, string $format = null, array $context = []): ?LineItemSubmissionReview + { + if ($data === null) { + return null; + } + + return new LineItemSubmissionReview( + $data[self::PARAM_REVIEWABLE_STATUSES], + $data[self::PARAM_LABEL] ?? null, + $data[self::PARAM_URL] ?? null, + $data[self::PARAM_CUSTOM_PROPERTIES] ?? [], + ); + } + + public function supportsDenormalization($data, string $type, string $format = null): bool + { + return $type === LineItemSubmissionReviewInterface::class; + } +} diff --git a/src/Normalizer/Core/CollectionNormalizer.php b/src/Normalizer/Core/CollectionNormalizer.php new file mode 100644 index 0000000..9e8373e --- /dev/null +++ b/src/Normalizer/Core/CollectionNormalizer.php @@ -0,0 +1,47 @@ + $object->all(), + ]; + } + + public function supportsNormalization($data, string $format = null): bool + { + return $data instanceof CollectionInterface; + } + + public function denormalize($data, string $type, string $format = null, array $context = []): Collection + { + $collection = new Collection(); + + $collection->add($data[self::PARAM_ITEMS]); + + return $collection; + } + + public function supportsDenormalization($data, string $type, string $format = null): bool + { + return in_array($type, [ + CollectionInterface::class, + Collection::class, + ]); + } +} diff --git a/src/Normalizer/Core/ResourceLinkNormalizer.php b/src/Normalizer/Core/ResourceLinkNormalizer.php new file mode 100644 index 0000000..c350d92 --- /dev/null +++ b/src/Normalizer/Core/ResourceLinkNormalizer.php @@ -0,0 +1,45 @@ + $object->getIdentifier(), + self::PARAM_PROPERTIES => $object->getProperties()->all(), + ]; + } + + public function supportsNormalization($data, string $format = null): bool + { + return $data instanceof LtiResourceLinkInterface; + } + + public function denormalize($data, string $type, string $format = null, array $context = []): LtiResourceLink + { + return new LtiResourceLink( + $data[self::PARAM_IDENTIFIER], + $data[self::PARAM_PROPERTIES] ?? [], + ); + } + + public function supportsDenormalization($data, string $type, string $format = null) + { + return $type === LtiResourceLink::class; + } +} diff --git a/src/Normalizer/Proctoring/AcsControlNormalizer.php b/src/Normalizer/Proctoring/AcsControlNormalizer.php new file mode 100644 index 0000000..71be81f --- /dev/null +++ b/src/Normalizer/Proctoring/AcsControlNormalizer.php @@ -0,0 +1,73 @@ + $this->normalizer->normalize($object->getResourceLink(), $format, $context), + self::PARAM_USER_IDENTIFIER => $object->getUserIdentifier(), + self::PARAM_ACTION => $object->getAction(), + self::PARAM_INCIDENT_TIME => $object->getIncidentTime(), + self::PARAM_ATTEMPT_NUMBER => $object->getAttemptNumber(), + self::PARAM_EXTRA_TIME => $object->getExtraTime(), + self::PARAM_INCIDENT_SEVERITY => $object->getIncidentSeverity(), + self::PARAM_REASON_CODE => $object->getReasonCode(), + self::PARAM_REASON_MESSAGE => $object->getReasonMessage(), + ]; + } + + public function supportsNormalization($data, string $format = null): bool + { + return $data instanceof AcsControlInterface; + } + + public function denormalize($data, string $type, string $format = null, array $context = []): AcsControl + { + return new AcsControl( + $this->denormalizer->denormalize($data[self::PARAM_RESOURCE_LINK], AcsControl::class, $format, $context), + $data[self::PARAM_USER_IDENTIFIER], + $data[self::PARAM_ACTION], + $data[self::PARAM_INCIDENT_TIME], + $data[self::PARAM_ATTEMPT_NUMBER], + $data[self::PARAM_EXTRA_TIME], + $data[self::PARAM_INCIDENT_SEVERITY], + $data[self::PARAM_REASON_CODE], + $data[self::PARAM_REASON_MESSAGE], + ); + } + + public function supportsDenormalization($data, string $type, string $format = null): bool + { + return $type === AcsControl::class; + } +} diff --git a/src/Serializer/Ags/LineItemContainerSerializer.php b/src/Serializer/Ags/LineItemContainerSerializer.php new file mode 100644 index 0000000..9a0c59d --- /dev/null +++ b/src/Serializer/Ags/LineItemContainerSerializer.php @@ -0,0 +1,41 @@ +lineItemCollectionSerializer->deserialize($data['lineItems']), + $data['relationLink'] ?? null, + ); + } +} diff --git a/src/Serializer/Ags/ResultContainerSerializer.php b/src/Serializer/Ags/ResultContainerSerializer.php new file mode 100644 index 0000000..68891fc --- /dev/null +++ b/src/Serializer/Ags/ResultContainerSerializer.php @@ -0,0 +1,41 @@ +resultCollectionSerializer->deserialize($data['results']), + $data['relationLink'] ?? null, + ); + } +}