View source
<?php
namespace Drupal\opigno_tincan_activity;
use Drupal\Core\Database\Connection;
use Drupal\Core\Link;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Url;
use Drupal\opigno_module\Entity\OpignoActivityInterface;
use Drupal\opigno_tincan_api\OpignoTincanApiTinCanVerbs;
use TinCan\Activity;
use TinCan\RemoteLRS;
use TinCan\Statement;
use TinCan\Util;
use TinCan\Verb;
class TincanContentAnswerAssistant {
protected $connection;
public function __construct(Connection $connection) {
$this->connection = $connection;
}
public function getRegistration(OpignoActivityInterface $activity, AccountProxyInterface $user) {
if (!empty($activity) && !empty($user)) {
$connection = $this->connection;
$result = $connection
->select('opigno_tincan_activity_answers', 't')
->fields('t', [])
->condition('opigno_activity_id', $activity
->id())
->condition('uid', $user
->id())
->execute()
->fetchObject();
if ($result) {
return $result->registration;
}
else {
$registration = Util::getUUID();
$this
->saveRegistration($registration, $activity, $user);
return $registration;
}
}
return FALSE;
}
public function saveRegistration($registration, OpignoActivityInterface $activity, AccountProxyInterface $user) {
$connection = $this->connection;
try {
$connection
->insert('opigno_tincan_activity_answers')
->fields([
'uid' => $user
->id(),
'opigno_activity_id' => $activity
->id(),
'registration' => $registration,
])
->execute();
} catch (\Exception $e) {
return $e;
}
}
public function score($activity_id, $registration, $max_score) {
return $this
->getScoreFromLrs($activity_id, $registration, $max_score);
}
protected function getScoreFromLrs($activity_id, $registration, $max_score) {
$messenger = \Drupal::messenger();
$lrs = $this
->getLrsConnection();
if (!$lrs) {
$messenger
->addWarning(t('Connection to the LRS failed'));
return 0;
}
if (empty($registration)) {
$messenger
->addWarning(t('There was an error while answering the question, please go back and try again.'));
return 0;
}
if (empty($activity_id)) {
$messenger
->addWarning(t('Error while obtaining the activity ID. Maybe a malformed TinCan package.'));
return 0;
}
$score_statement = $this
->getStatementFinalScore($lrs, $registration, $activity_id);
if (!$score_statement) {
$messenger
->addWarning(t('Can not get score from LRS. Check your LRS settings.'));
return 0;
}
return $this
->getScoreFromStatement($score_statement, $max_score);
}
protected function getLrsConnection() {
$messenger = \Drupal::messenger();
if (!class_exists('TinCan\\Version')) {
$messenger
->addError('Please install the @tincanphp_library using Composer, with the command: <em>composer require rusticisoftware/tincan:@stable</em>.', [
'@tincanphp_library' => Link::fromTextAndUrl('TinCanPHP library', Url::fromUri('https://github.com/RusticiSoftware/TinCanPHP')),
]);
return FALSE;
}
$config = \Drupal::config('opigno_tincan_api.settings');
$endpoint = $config
->get('opigno_tincan_api_endpoint');
$username = $config
->get('opigno_tincan_api_username');
$password = $config
->get('opigno_tincan_api_password');
if (empty($endpoint) || empty($username) || empty($password)) {
$messenger
->addWarning('Please configure first the Opigno TinCan API module. Go to @url', [
'@url' => Link::createFromRoute(t('the setting page'), 'opigno_tincan_api.settings_form')
->toString(),
]);
return FALSE;
}
return new RemoteLRS($endpoint, '1.0.1', $username, $password);
}
protected function getStatementFinalScore(RemoteLRS $lrs, $registration_uuid, $activity_id) {
$activity = new Activity();
$activity
->setId($activity_id);
$verb_passed = new Verb();
$verb_passed
->setId(OpignoTincanApiTinCanVerbs::$passed['id']);
$result = $lrs
->queryStatements([
'activity' => $activity,
'registration' => $registration_uuid,
'verb' => $verb_passed,
'limit' => 1,
]);
$statements = [];
if (!empty($result->content) && is_object($result->content)) {
$statements = $result->content
->getStatements();
if (count($statements) === 0) {
$verb_failed = new Verb();
$verb_failed
->setId(OpignoTincanApiTinCanVerbs::$failed['id']);
$result = $lrs
->queryStatements([
'activity' => $activity,
'registration' => $registration_uuid,
'verb' => $verb_failed,
'limit' => 1,
]);
if (!empty($result->content) && is_object($result->content)) {
$statements = $result->content
->getStatements();
}
}
}
if (count($statements) > 0) {
return $statements[0];
}
else {
return FALSE;
}
}
protected function getScoreFromStatement(Statement $statement, $max_score) {
$result = $statement
->getResult();
if (!isset($result)) {
return 0;
}
$score = $result
->getScore();
if (isset($score)) {
$scaled = $score
->getScaled();
if (isset($scaled) && $scaled >= 0) {
return $scaled * $max_score;
}
$raw = $score
->getRaw();
$max = $score
->getMax();
$min = $score
->getMin();
if (!isset($min)) {
$min = 0;
}
if (isset($raw) && isset($max)) {
return (double) ($raw - $min) / ($max - $min) * $max_score;
}
}
$success = $result
->getSuccess();
if (isset($success)) {
return $max_score;
}
return 0;
}
}