Chamilo is a learning management system focused on ease of use and accessibility
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
chamilo-lms/main/inc/lib/Compilatio.php

390 lines
11 KiB

<?php
/* For licensing terms, see /license.txt */
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Utils;
/**
* Build the communication with the SOAP server Compilatio.net
* call several methods for the file management in Compilatio.net.
*
* @version: 2.0
*/
class Compilatio
{
/** Identification key for the Compilatio account*/
public $key;
/**
* @var string
*/
protected $baseUrl;
/** Webservice connection*/
private $maxFileSize;
private $proxyHost;
private $proxyPort;
/**
* @var Client
*/
public $client;
/**
* Compilatio constructor.
*
* @throws Exception
*/
public function __construct()
{
$settings = $this->getSettings();
$this->maxFileSize = $settings['max_filesize'];
$this->key = $settings['key'];
$this->baseUrl = $settings['api_url'];
if (!empty($settings['proxy_host'])) {
$this->proxyHost = $settings['proxy_host'];
$this->proxyPort = $settings['proxy_port'];
}
$clientConfig = [
'base_uri' => api_remove_trailing_slash($this->baseUrl).'/',
'headers' => [
'X-Auth-Token' => $this->key,
'Accept' => 'application/json',
],
];
if ($this->proxyPort) {
$clientConfig['proxy'] = $this->proxyHost.':'.$this->proxyPort;
}
$this->client = new Client($clientConfig);
}
/**
* @throws Exception
*/
protected function getSettings(): array
{
if (empty(api_get_configuration_value('allow_compilatio_tool')) ||
empty(api_get_configuration_value('compilatio_tool'))
) {
throw new Exception('Compilatio not available');
}
$compilatioTool = api_get_configuration_value('compilatio_tool');
if (!isset($compilatioTool['settings'])) {
throw new Exception('Compilatio config available');
}
$settings = $compilatioTool['settings'];
if (empty($settings['key'])) {
throw new Exception('API key not available');
}
if (empty($settings['api_url'])) {
throw new Exception('Api URL not available');
}
return $settings;
}
/**
* @return string
*/
public function getKey()
{
return $this->key;
}
/**
* @param mixed $key
*
* @return Compilatio
*/
public function setKey($key)
{
$this->key = $key;
return $this;
}
/**
* @return mixed
*/
public function getMaxFileSize()
{
return $this->maxFileSize;
}
/**
* @return mixed
*/
public function getProxyHost()
{
return $this->proxyHost;
}
/**
* @return mixed
*/
public function getProxyPort()
{
return $this->proxyPort;
}
/**
* Method for the file load.
*/
public function sendDoc(
string $title,
string $description,
string $filename,
string $filepath
) {
$user = api_get_user_entity(api_get_user_id());
$postData = [
'folder_id' => '',
'title' => $title,
'filename' => basename($filename),
'indexed' => 'true',
'user_notes' => [
'description' => $description
],
'authors' => [
[
'firstname' => $user->getFirstname(),
'lastname' => $user->getlastname(),
'email_address' => $user->getEmail(),
]
],
'depositor' => [
'firstname' => $user->getFirstname(),
'lastname' => $user->getlastname(),
'email_address' => $user->getEmail(),
]
];
try {
$responseBody = $this->client
->post(
'private/documents',
[
'multipart' => [
[
'name' => 'postData',
'contents' => json_encode($postData)
],
[
'name' => 'file',
'contents' => Utils::tryFopen($filepath, 'r'),
]
]
]
)
->getBody()
;
} catch (Exception $e) {
throw new Exception($e->getMessage());
}
$body = json_decode((string) $responseBody, true);
return $body['data']['document']['id'];
}
/**
* Method for recover a document's information.
*
* @throws Exception
*/
public function getDoc(string $documentId): array
{
try {
$responseBody = $this->client
->get(
"private/documents/$documentId"
)
->getBody()
;
} catch (Exception $e) {
throw new Exception($e->getMessage());
}
$responseJson = json_decode((string) $responseBody, true);
$dataDocument = $responseJson['data']['document'];
$documentInfo = [
'report_url' => $dataDocument['report_url'],
];
if (isset($dataDocument['analyses']['anasim']['state'])) {
$documentInfo['analysis_status'] = $dataDocument['analyses']['anasim']['state'];
}
if (isset($dataDocument['light_reports']['anasim']['scores']['global_score_percent'])) {
$documentInfo['report_percent'] = $dataDocument['light_reports']['anasim']['scores']['global_score_percent'];
}
return $documentInfo;
}
/**
* Method for deleting a Compialtio's account document.
*/
public function deldoc(string $documentId)
{
}
/**
* Method for start the analysis for a document.
*
* @throws Exception
*/
public function startAnalyse(string $compilatioId): string
{
try {
$responseBody = $this->client
->post(
'private/analyses',
[
'json' => [
'doc_id' => $compilatioId,
'recipe_name' => 'anasim'
],
]
)
->getBody()
;
} catch (Exception $e) {
throw new Exception($e->getMessage());
}
$body = json_decode((string) $responseBody, true);
return $body['data']['analysis']['state'];
}
/**
* Method for identify a file extension and the possibility that the document can be managed by Compilatio.
*/
public static function verifiFileType(string $filename): bool
{
$types = ['doc', 'docx', 'rtf', 'xls', 'xlsx', 'ppt', 'pptx', 'odt', 'pdf', 'txt', 'htm', 'html'];
$extension = substr($filename, strrpos($filename, '.') + 1);
$extension = strtolower($extension);
return in_array($extension, $types);
}
/**
* Method for display the PomprseuilmankBar (% de plagiat).
*/
public static function getPomprankBarv31(
int $index,
int $weakThreshold,
int $highThreshold
): string {
$index = round($index);
$class = 'danger';
if ($index < $weakThreshold) {
$class = 'success';
} elseif ($index < $highThreshold) {
$class = 'warning';
}
return Display::bar_progress($index, true, null, $class);
}
/**
* Function for delete a document of the compilatio table if plagiarismTool is Compilatio.
*/
public static function plagiarismDeleteDoc(int $courseId, int $itemId)
{
if (api_get_configuration_value('allow_compilatio_tool') !== false) {
$table = Database::get_course_table(TABLE_PLAGIARISM);
$params = [$courseId, $itemId];
Database::delete($table, ['c_id = ? AND document_id = ?' => $params]);
}
}
public function saveDocument(int $courseId, int $documentId, string $compilatioId)
{
$table = Database::get_course_table(TABLE_PLAGIARISM);
$params = [
'c_id' => $courseId,
'document_id' => $documentId,
'compilatio_id' => $compilatioId,
];
Database::insert($table, $params);
}
public function getCompilatioId(int $documentId, int $courseId): ?string
{
$table = Database::get_course_table(TABLE_PLAGIARISM);
$sql = "SELECT compilatio_id FROM $table
WHERE document_id = $documentId AND c_id= $courseId";
$result = Database::query($sql);
$result = Database::fetch_object($result);
return $result ? (string)$result->compilatio_id : null;
}
public function giveWorkIdState(int $workId): string
{
$courseId = api_get_course_int_id();
$compilatioId = $this->getCompilatioId($workId, $courseId);
// if the compilatio's hash is not a valide hash md5,
// we return à specific status (cf : IsInCompilatio() )
// Not used since implementation of RestAPI but there if needed later
//$actionCompilatio = get_lang('CompilatioDocumentTextNotImage').'<br/>'.
// get_lang('CompilatioDocumentNotCorrupt');
$status = '';
if (!empty($compilatioId)) {
// if compilatio_id is a hash md5, we call the function of the compilatio's
// webservice who return the document's status
$soapRes = $this->getDoc($compilatioId);
$status = $soapRes['analysis_status'] ?? '';
$spinnerIcon = Display::returnFontAwesomeIcon('spinner', null, true, 'fa-spin');
switch ($status) {
case 'finished':
$actionCompilatio .= self::getPomprankBarv31($soapRes['report_percent'], 10, 35)
.PHP_EOL
.Display::url(
get_lang('CompilatioAnalysis'),
$soapRes['report_url'],
['class' => 'btn btn-primary btn-xs', 'target' => '_blank']
);
break;
case 'running':
$actionCompilatio .= "<div style='font-weight:bold;text-align:left'>"
.get_lang('CompilatioAnalysisInProgress')
."</div>";
$actionCompilatio .= "<div style='font-size:80%;font-style:italic;margin-bottom:5px;'>"
.get_lang('CompilatioAnalysisPercentage')
."</div>";
$actionCompilatio .= $spinnerIcon.PHP_EOL .get_lang('CompilatioAnalysisEnding');
break;
case 'waiting':
$actionCompilatio .= $spinnerIcon.PHP_EOL.get_lang('CompilatioWaitingAnalysis');
break;
case 'canceled':
$actionCompilatio .= get_lang('Cancelled');
break;
case 'scheduled':
$actionCompilatio .= $spinnerIcon.PHP_EOL.get_lang('CompilatioAwaitingAnalysis');
break;
}
}
return $workId.'|'.$actionCompilatio.'|'.$status.'|';
}
}