AutorÃa | Ultima modificación | Ver Log |
<?phpnamespace Packback\Lti1p3;class LtiAssignmentsGradesService extends LtiAbstractService{public const CONTENTTYPE_SCORE = 'application/vnd.ims.lis.v1.score+json';public const CONTENTTYPE_LINEITEM = 'application/vnd.ims.lis.v2.lineitem+json';public const CONTENTTYPE_LINEITEMCONTAINER = 'application/vnd.ims.lis.v2.lineitemcontainer+json';public const CONTENTTYPE_RESULTCONTAINER = 'application/vnd.ims.lis.v2.resultcontainer+json';public function getScope(): array{return $this->getServiceData()['scope'];}// https://www.imsglobal.org/spec/lti-ags/v2p0#assignment-and-grade-service-claim// When an LTI message is launching a resource associated to one and only one lineitem,// the claim must include the endpoint URL for accessing the associated line item;// in all other cases, this property must be either blank or not included in the claim.public function getResourceLaunchLineItem(): ?LtiLineitem{$serviceData = $this->getServiceData();if (empty($serviceData['lineitem'])) {return null;}return LtiLineitem::new()->setId($serviceData['lineitem']);}public function putGrade(LtiGrade $grade, ?LtiLineitem $lineitem = null){$this->validateScopes([LtiConstants::AGS_SCOPE_SCORE]);$lineitem = $this->ensureLineItemExists($lineitem);$scoreUrl = $this->appendLineItemPath($lineitem, '/scores');$request = new ServiceRequest(ServiceRequest::METHOD_POST,$scoreUrl,ServiceRequest::TYPE_SYNC_GRADE);$request->setBody($grade);$request->setContentType(static::CONTENTTYPE_SCORE);return $this->makeServiceRequest($request);}public function findLineItem(LtiLineitem $newLineItem): ?LtiLineitem{$lineitems = $this->getLineItems();foreach ($lineitems as $lineitem) {if ($this->isMatchingLineitem($lineitem, $newLineItem)) {return new LtiLineitem($lineitem);}}return null;}public function updateLineitem(LtiLineitem $lineitemToUpdate): LtiLineitem{$request = new ServiceRequest(ServiceRequest::METHOD_PUT,$lineitemToUpdate->getId(),ServiceRequest::TYPE_UPDATE_LINEITEM);$request->setBody($lineitemToUpdate)->setContentType(static::CONTENTTYPE_LINEITEM)->setAccept(static::CONTENTTYPE_LINEITEM);$updatedLineitem = $this->makeServiceRequest($request);return new LtiLineitem($updatedLineitem['body']);}public function createLineitem(LtiLineitem $newLineItem): LtiLineitem{$request = new ServiceRequest(ServiceRequest::METHOD_POST,$this->getServiceData()['lineitems'],ServiceRequest::TYPE_CREATE_LINEITEM);$request->setBody($newLineItem)->setContentType(static::CONTENTTYPE_LINEITEM)->setAccept(static::CONTENTTYPE_LINEITEM);$createdLineItem = $this->makeServiceRequest($request);return new LtiLineitem($createdLineItem['body']);}public function deleteLineitem(): array{$request = new ServiceRequest(ServiceRequest::METHOD_DELETE,$this->getServiceData()['lineitem'],ServiceRequest::TYPE_DELETE_LINEITEM);return $this->makeServiceRequest($request);}public function findOrCreateLineitem(LtiLineitem $newLineItem): LtiLineitem{return $this->findLineItem($newLineItem) ?? $this->createLineitem($newLineItem);}public function getGrades(?LtiLineitem $lineitem = null){$lineitem = $this->ensureLineItemExists($lineitem);$resultsUrl = $this->appendLineItemPath($lineitem, '/results');$request = new ServiceRequest(ServiceRequest::METHOD_GET,$resultsUrl,ServiceRequest::TYPE_GET_GRADES);$request->setAccept(static::CONTENTTYPE_RESULTCONTAINER);return $this->getAll($request);}public function getLineItems(): array{$this->validateScopes([LtiConstants::AGS_SCOPE_LINEITEM, LtiConstants::AGS_SCOPE_LINEITEM_READONLY]);$request = new ServiceRequest(ServiceRequest::METHOD_GET,$this->getServiceData()['lineitems'],ServiceRequest::TYPE_GET_LINEITEMS);$request->setAccept(static::CONTENTTYPE_LINEITEMCONTAINER);$lineitems = $this->getAll($request);// If there is only one item, then wrap it in an array so the foreach worksif (isset($lineitems['body']['id'])) {$lineitems['body'] = [$lineitems['body']];}return $lineitems;}public function getLineItem(string $url): LtiLineitem{$this->validateScopes([LtiConstants::AGS_SCOPE_LINEITEM, LtiConstants::AGS_SCOPE_LINEITEM_READONLY]);$request = new ServiceRequest(ServiceRequest::METHOD_GET,$url,ServiceRequest::TYPE_GET_LINEITEM);$request->setAccept(static::CONTENTTYPE_LINEITEM);$response = $this->makeServiceRequest($request)['body'];return new LtiLineitem($response);}private function ensureLineItemExists(?LtiLineitem $lineitem = null): LtiLineitem{// If no line item is passed in, attempt to use the one associated with// this launch.if (!isset($lineitem)) {$lineitem = $this->getResourceLaunchLineItem();}// If none exists still, create a default line item.if (!isset($lineitem)) {$defaultLineitem = LtiLineitem::new()->setLabel('default')->setScoreMaximum(100);$lineitem = $this->createLineitem($defaultLineitem);}// If the line item does not contain an ID, find or create it.if (empty($lineitem->getId())) {$lineitem = $this->findOrCreateLineitem($lineitem);}return $lineitem;}private function isMatchingLineitem(array $lineitem, LtiLineitem $newLineItem): bool{return $newLineItem->getTag() == ($lineitem['tag'] ?? null) &&$newLineItem->getResourceId() == ($lineitem['resourceId'] ?? null) &&$newLineItem->getResourceLinkId() == ($lineitem['resourceLinkId'] ?? null);}private function appendLineItemPath(LtiLineitem $lineItem, string $suffix): string{$url = $lineItem->getId();$pos = strpos($url, '?');if ($pos === false) {$url = $url.$suffix;} else {$url = substr_replace($url, $suffix, $pos, 0);}return $url;}}