tao-test/app/ltiDeliveryProvider/model/tasks/SendLtiOutcomeTask.php

129 lines
5.6 KiB
PHP

<?php
/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2014-2020 (original work) Open Assessment Technologies SA;
*
*/
declare(strict_types=1);
namespace oat\ltiDeliveryProvider\model\tasks;
use common_report_Report;
use oat\oatbox\extension\AbstractAction;
use oat\oatbox\log\LoggerAwareTrait;
use oat\taoDelivery\model\execution\ServiceProxy;
use oat\taoLti\models\classes\LtiOutcome\LtiOutcomeXmlFactory;
use oat\taoLti\models\classes\LtiService;
use oat\taoOutcomeUi\model\ResultsService;
use oat\taoResultServer\models\classes\ResultAliasServiceInterface;
use taoResultServer_models_classes_OutcomeVariable;
class SendLtiOutcomeTask extends AbstractAction
{
use LoggerAwareTrait;
const VARIABLE_IDENTIFIER = 'LtiOutcome';
public function __invoke($params)
{
$report = new common_report_Report(common_report_Report::TYPE_ERROR);
$deliveryResultIdentifier = $params['deliveryResultIdentifier'];
$consumerKey = $params['consumerKey'];
$serviceUrl = $params['serviceUrl'];
try {
$deliveryExecution = ServiceProxy::singleton()->getDeliveryExecution($deliveryResultIdentifier);
$resultsService = ResultsService::singleton();
$implementation = $resultsService->getReadableImplementation($deliveryExecution->getDelivery());
$resultsService->setImplementation($implementation);
$variables = $resultsService->getVariableDataFromDeliveryResult($deliveryResultIdentifier, [taoResultServer_models_classes_OutcomeVariable::class]);
$submitted = 0;
/** @var taoResultServer_models_classes_OutcomeVariable $variable */
foreach ($variables as $variable) {
if (self::VARIABLE_IDENTIFIER == $variable->getIdentifier()) {
$this->sendLtiOutcome($variable, $deliveryResultIdentifier, $consumerKey, $serviceUrl);
$submitted++;
break;
}
}
if (0 === $submitted) {
throw new \common_Exception('No LTI Outcome has been submitter for execution' . $deliveryResultIdentifier);
}
} catch (\Exception $exception) {
$report->setMessage($exception->getMessage());
}
$report->setType(common_report_Report::TYPE_SUCCESS);
return $report;
}
/**
* @param taoResultServer_models_classes_OutcomeVariable $testVariable
* @param $deliveryResultIdentifier
* @param $consumerKey
* @param $serviceUrl
* @return bool
* @throws \common_exception_Error
* @throws \oat\taoLti\models\classes\LtiException
*/
private function sendLtiOutcome(taoResultServer_models_classes_OutcomeVariable $testVariable, $deliveryResultIdentifier, $consumerKey, $serviceUrl)
{
$grade = (string)$testVariable->getValue();
/** @var ResultAliasServiceInterface $resultAliasService */
$resultAliasService = $this->getServiceLocator()->get(ResultAliasServiceInterface::SERVICE_ID);
$deliveryResultAlias = $resultAliasService->getResultAlias($deliveryResultIdentifier);
$deliveryResultIdentifier = empty($deliveryResultAlias) ? $deliveryResultIdentifier : current($deliveryResultAlias);
$message = $this->getLtiOutcomeXmlFactory()->buildReplaceResultRequest($deliveryResultIdentifier, $grade, uniqid('', true));
$credentialResource = LtiService::singleton()->getCredential($consumerKey);
$credentials = new \tao_models_classes_oauth_Credentials($credentialResource);
//Building POX raw http message
$unSignedOutComeRequest = new \common_http_Request($serviceUrl, 'POST', []);
$unSignedOutComeRequest->setBody($message);
$signingService = new \tao_models_classes_oauth_Service();
$signedRequest = $signingService->sign($unSignedOutComeRequest, $credentials, true);
//Hack for moodle compatibility, the header is ignored for the signature computation
$signedRequest->setHeader("Content-Type", "application/xml");
$response = $signedRequest->send();
if ('200' != $response->httpCode) {
$this->logWarning("Request sent (Body)\n" . $signedRequest->getBody() . "\n");
$this->logWarning("Request sent (Headers)\n" . serialize($signedRequest->getHeaders()) . "\n");
$this->logWarning("\nHTTP Code received: " . $response->httpCode . "\n");
$this->logWarning("\nHTTP From: " . $response->effectiveUrl . "\n");
$this->logWarning("\nHTTP Content received: " . $response->responseData . "\n");
throw new \common_exception_Error('An HTTP level problem occurred when sending the outcome to the service url');
} else {
$this->logInfo('Submited LTI score with id "' . $deliveryResultIdentifier . '"');
}
return true;
}
private function getLtiOutcomeXmlFactory(): LtiOutcomeXmlFactory
{
return $this->getServiceLocator()->get(LtiOutcomeXmlFactory::class);
}
}