Compilatio.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Build the comunication with the SOAP server Compilatio.net
  5. * call severals methods for the file management in Compilatio.net.
  6. *
  7. * @version: 2.0
  8. */
  9. class Compilatio
  10. {
  11. /** Identification key for the Compilatio account*/
  12. public $key;
  13. /** Webservice connection*/
  14. public $soapcli;
  15. private $transportMode;
  16. private $maxFileSize;
  17. private $wgetUri;
  18. private $wgetLogin;
  19. private $wgetPassword;
  20. private $proxyHost;
  21. private $proxyPort;
  22. /**
  23. * Compilatio constructor.
  24. */
  25. public function __construct()
  26. {
  27. if (empty(api_get_configuration_value('allow_compilatio_tool')) ||
  28. empty(api_get_configuration_value('compilatio_tool'))
  29. ) {
  30. throw new Exception('Compilatio not available');
  31. }
  32. $settings = api_get_configuration_value('compilatio_tool');
  33. if (isset($settings['settings'])) {
  34. $settings = $settings['settings'];
  35. } else {
  36. throw new Exception('Compilatio config available');
  37. }
  38. $key = $this->key = $settings['key'];
  39. $urlsoap = $settings['soap_url'];
  40. $proxyHost = $this->proxyHost = $settings['proxy_host'];
  41. $proxyPort = $this->proxyPort = $settings['proxy_port'];
  42. $this->transportMode = $settings['transport_mode'];
  43. $this->maxFileSize = $settings['max_filesize'];
  44. $this->wgetUri = $settings['wget_uri'];
  45. $this->wgetLogin = $settings['wget_login'];
  46. $this->wgetPassword = $settings['wget_password'];
  47. $soapVersion = 2;
  48. try {
  49. if (!empty($key)) {
  50. $this->key = $key;
  51. if (!empty($urlsoap)) {
  52. if (!empty($proxyHost)) {
  53. $param = [
  54. 'trace' => false,
  55. 'soap_version' => $soapVersion,
  56. 'exceptions' => true,
  57. 'proxy_host' => '"'.$proxyHost.'"',
  58. 'proxy_port' => $proxyPort,
  59. ];
  60. } else {
  61. $param = [
  62. 'trace' => false,
  63. 'soap_version' => $soapVersion,
  64. 'exceptions' => true,
  65. ];
  66. }
  67. $this->soapcli = new SoapClient($urlsoap, $param);
  68. } else {
  69. throw new Exception('WS urlsoap not available');
  70. }
  71. } else {
  72. throw new Exception('API key not available');
  73. }
  74. } catch (SoapFault $fault) {
  75. $this->soapcli = "Error constructor compilatio $fault->faultcode $fault->faultstring ";
  76. } catch (Exception $e) {
  77. $this->soapcli = "Error constructor compilatio with urlsoap $urlsoap ".$e->getMessage();
  78. }
  79. }
  80. /**
  81. * @return string
  82. */
  83. public function getKey()
  84. {
  85. return $this->key;
  86. }
  87. /**
  88. * @param mixed $key
  89. *
  90. * @return Compilatio
  91. */
  92. public function setKey($key)
  93. {
  94. $this->key = $key;
  95. return $this;
  96. }
  97. /**
  98. * @return mixed
  99. */
  100. public function getTransportMode()
  101. {
  102. return $this->transportMode;
  103. }
  104. /**
  105. * @param mixed $transportMode
  106. *
  107. * @return Compilatio
  108. */
  109. public function setTransportMode($transportMode)
  110. {
  111. $this->transportMode = $transportMode;
  112. return $this;
  113. }
  114. /**
  115. * @return mixed
  116. */
  117. public function getMaxFileSize()
  118. {
  119. return $this->maxFileSize;
  120. }
  121. /**
  122. * @param mixed $maxFileSize
  123. *
  124. * @return Compilatio
  125. */
  126. public function setMaxFileSize($maxFileSize)
  127. {
  128. $this->maxFileSize = $maxFileSize;
  129. return $this;
  130. }
  131. /**
  132. * @return mixed
  133. */
  134. public function getWgetUri()
  135. {
  136. return $this->wgetUri;
  137. }
  138. /**
  139. * @param mixed $wgetUri
  140. *
  141. * @return Compilatio
  142. */
  143. public function setWgetUri($wgetUri)
  144. {
  145. $this->wgetUri = $wgetUri;
  146. return $this;
  147. }
  148. /**
  149. * @return mixed
  150. */
  151. public function getWgetLogin()
  152. {
  153. return $this->wgetLogin;
  154. }
  155. /**
  156. * @param mixed $wgetLogin
  157. *
  158. * @return Compilatio
  159. */
  160. public function setWgetLogin($wgetLogin)
  161. {
  162. $this->wgetLogin = $wgetLogin;
  163. return $this;
  164. }
  165. /**
  166. * @return mixed
  167. */
  168. public function getWgetPassword()
  169. {
  170. return $this->wgetPassword;
  171. }
  172. /**
  173. * @param mixed $wgetPassword
  174. *
  175. * @return Compilatio
  176. */
  177. public function setWgetPassword($wgetPassword)
  178. {
  179. $this->wgetPassword = $wgetPassword;
  180. return $this;
  181. }
  182. /**
  183. * @return mixed
  184. */
  185. public function getProxyHost()
  186. {
  187. return $this->proxyHost;
  188. }
  189. /**
  190. * @param mixed $proxyHost
  191. *
  192. * @return Compilatio
  193. */
  194. public function setProxyHost($proxyHost)
  195. {
  196. $this->proxyHost = $proxyHost;
  197. return $this;
  198. }
  199. /**
  200. * @return mixed
  201. */
  202. public function getProxyPort()
  203. {
  204. return $this->proxyPort;
  205. }
  206. /**
  207. * @param mixed $proxyPort
  208. *
  209. * @return Compilatio
  210. */
  211. public function setProxyPort($proxyPort)
  212. {
  213. $this->proxyPort = $proxyPort;
  214. return $this;
  215. }
  216. /**
  217. * Method for the file load.
  218. *
  219. * @param $title
  220. * @param $description
  221. * @param $filename
  222. * @param $mimeType
  223. * @param $content
  224. *
  225. * @return string
  226. */
  227. public function sendDoc($title, $description, $filename, $mimeType, $content)
  228. {
  229. try {
  230. if (!is_object($this->soapcli)) {
  231. return "Error in constructor compilatio() $this->soapcli";
  232. }
  233. $idDocument = $this->soapcli->__call(
  234. 'addDocumentBase64',
  235. [
  236. $this->key,
  237. utf8_encode(urlencode($title)),
  238. utf8_encode(urlencode($description)),
  239. utf8_encode(urlencode($filename)),
  240. utf8_encode($mimeType),
  241. base64_encode($content),
  242. ]
  243. );
  244. return $idDocument;
  245. } catch (SoapFault $fault) {
  246. return "Erreur sendDoc()".$fault->faultcode." ".$fault->faultstring;
  247. }
  248. }
  249. /**
  250. * Method for recover a document's information.
  251. *
  252. * @param $compiHash
  253. *
  254. * @return string
  255. */
  256. public function getDoc($compiHash)
  257. {
  258. try {
  259. if (!is_object($this->soapcli)) {
  260. return "Error in constructor compilatio() ".$this->soapcli;
  261. }
  262. $param = [$this->key, $compiHash];
  263. $idDocument = $this->soapcli->__call('getDocument', $param);
  264. return $idDocument;
  265. } catch (SoapFault $fault) {
  266. return "Erreur getDoc()".$fault->faultcode." ".$fault->faultstring;
  267. }
  268. }
  269. /**
  270. * method for recover an url document's report.
  271. *
  272. * @param $compiHash
  273. *
  274. * @return string
  275. */
  276. public function getReportUrl($compiHash)
  277. {
  278. try {
  279. if (!is_object($this->soapcli)) {
  280. return "Error in constructor compilatio() ".$this->soapcli;
  281. }
  282. $param = [$this->key, $compiHash];
  283. $idDocument = $this->soapcli->__call('getDocumentReportUrl', $param);
  284. return $idDocument;
  285. } catch (SoapFault $fault) {
  286. return "Erreur getReportUrl()".$fault->faultcode." ".$fault->faultstring;
  287. }
  288. }
  289. /**
  290. * Method for deleting a Compialtio's account document.
  291. *
  292. * @param $compiHash
  293. *
  294. * @return string
  295. */
  296. public function deldoc($compiHash)
  297. {
  298. try {
  299. if (!is_object($this->soapcli)) {
  300. return "Error in constructor compilatio() ".$this->soapcli;
  301. }
  302. $param = [$this->key, $compiHash];
  303. $this->soapcli->__call('deleteDocument', $param);
  304. } catch (SoapFault $fault) {
  305. return "Erreur deldoc()".$fault->faultcode." ".$fault->faultstring;
  306. }
  307. }
  308. /**
  309. * Method for start the analysis for a document.
  310. *
  311. * @param $compiHash
  312. *
  313. * @return string
  314. */
  315. public function startAnalyse($compiHash)
  316. {
  317. try {
  318. if (!is_object($this->soapcli)) {
  319. return "Error in constructor compilatio() ".$this->soapcli;
  320. }
  321. $param = [$this->key, $compiHash];
  322. $this->soapcli->__call('startDocumentAnalyse', $param);
  323. } catch (SoapFault $fault) {
  324. return "Erreur startAnalyse()".$fault->faultcode." ".$fault->faultstring;
  325. }
  326. }
  327. /**
  328. * Method for recover the account's quota.
  329. *
  330. * @return string
  331. */
  332. public function getQuotas()
  333. {
  334. try {
  335. if (!is_object($this->soapcli)) {
  336. return "Error in constructor compilatio() ".$this->soapcli;
  337. }
  338. $param = [$this->key];
  339. $resultat = $this->soapcli->__call('getAccountQuotas', $param);
  340. return $resultat;
  341. } catch (SoapFault $fault) {
  342. return "Erreur getQuotas()".$fault->faultcode." ".$fault->faultstring;
  343. }
  344. }
  345. /**
  346. * Method for identify a file extension and the possibility that the document can be managed by Compilatio.
  347. *
  348. * @param $filename
  349. *
  350. * @return bool
  351. */
  352. public static function verifiFileType($filename)
  353. {
  354. $types = ['doc', 'docx', 'rtf', 'xls', 'xlsx', 'ppt', 'pptx', 'odt', 'pdf', 'txt', 'htm', 'html'];
  355. $extension = substr($filename, strrpos($filename, '.') + 1);
  356. $extension = strtolower($extension);
  357. return in_array($extension, $types);
  358. }
  359. /**
  360. * Fonction affichage de la barre de progression d'analyse version 3.1.
  361. *
  362. * @param string $status From the document
  363. * @param int $pour
  364. * @param array $text Array includes the extract from the text
  365. *
  366. * @return string
  367. */
  368. public static function getProgressionAnalyseDocv31($status, $pour = 0, $text = [])
  369. {
  370. $loading = Display::returnFontAwesomeIcon('spinner', null, true, 'fa-spin');
  371. $loading .= '&nbsp;';
  372. //$refreshReturn = Display::url('javascript:window.location.reload(false);', $loading);
  373. switch ($status) {
  374. case 'ANALYSE_IN_QUEUE':
  375. $content = $loading.$text['analysisinqueue'];
  376. break;
  377. case 'ANALYSE_PROCESSING':
  378. $content = $loading.$text['analysisinfinalization'];
  379. break;
  380. default:
  381. $content = Display::bar_progress($pour, true);
  382. break;
  383. }
  384. return $content;
  385. }
  386. /**
  387. * Method for display the PomprseuilmankBar (% de plagiat).
  388. *
  389. * @param $index
  390. * @param $weakThreshold
  391. * @param $highThreshold
  392. *
  393. * @return string
  394. */
  395. public static function getPomprankBarv31(
  396. $index,
  397. $weakThreshold,
  398. $highThreshold
  399. ) {
  400. $index = round($index);
  401. $pour = round((50 * $index) / 100);
  402. $return = '';
  403. $class = 'error';
  404. if ($index < $weakThreshold) {
  405. $class = 'success';
  406. } else {
  407. if ($index >= $weakThreshold && $index < $highThreshold) {
  408. $class = 'warning';
  409. }
  410. }
  411. $return .= Display::bar_progress($index, true, null, $class);
  412. return $return;
  413. }
  414. /**
  415. * Method for validation of hash.
  416. *
  417. * @param string $hash
  418. *
  419. * @return bool
  420. */
  421. public static function isMd5($hash)
  422. {
  423. return preg_match('`^[a-f0-9]{32}$`', $hash);
  424. }
  425. /**
  426. * function for delete a document of the compilatio table if plagiarismTool is Compilatio.
  427. *
  428. * @param int $courseId
  429. * @param int $itemId
  430. *
  431. * @return bool
  432. */
  433. public static function plagiarismDeleteDoc($courseId, $itemId)
  434. {
  435. if (api_get_configuration_value('allow_compilatio_tool') === false) {
  436. return false;
  437. }
  438. $table = Database:: get_course_table(TABLE_PLAGIARISM);
  439. $params = [$courseId, $itemId];
  440. Database::delete($table, ['c_id = ? AND document_id = ?' => $params]);
  441. return true;
  442. }
  443. /**
  444. * @param int $courseId
  445. * @param int $documentId
  446. * @param int $compilatioId
  447. */
  448. public function saveDocument($courseId, $documentId, $compilatioId)
  449. {
  450. $documentId = (int) $documentId;
  451. $courseId = (int) $courseId;
  452. $table = Database::get_course_table(TABLE_PLAGIARISM);
  453. $params = [
  454. 'c_id' => $courseId,
  455. 'document_id' => $documentId,
  456. 'compilatio_id' => $compilatioId,
  457. ];
  458. Database::insert($table, $params);
  459. }
  460. /**
  461. * @param int $documentId
  462. * @param int $courseId
  463. *
  464. * @return string md5 value
  465. */
  466. public function getCompilatioId($documentId, $courseId)
  467. {
  468. $documentId = (int) $documentId;
  469. $courseId = (int) $courseId;
  470. $table = Database::get_course_table(TABLE_PLAGIARISM);
  471. $sql = "SELECT compilatio_id FROM $table
  472. WHERE document_id = $documentId AND c_id= $courseId";
  473. $result = Database::query($sql);
  474. $result = Database::fetch_object($result);
  475. if ($result) {
  476. return (string) $result->compilatio_id;
  477. }
  478. return 0;
  479. }
  480. /**
  481. * @param int $workId
  482. *
  483. * @return string
  484. */
  485. public function giveWorkIdState($workId)
  486. {
  487. $compilatioImgFolder = api_get_path(WEB_CODE_PATH).'plagiarism/compilatio/img/';
  488. $courseId = api_get_course_int_id();
  489. $compilatioId = $this->getCompilatioId($workId, $courseId);
  490. $actionCompilatio = '';
  491. $status = '';
  492. if (!empty($compilatioId)) {
  493. if (self::isMd5($compilatioId)) {
  494. // if compilatio_id is a hash md5, we call the function of the compilatio's
  495. // webservice who return the document's status
  496. $soapRes = $this->getDoc($compilatioId);
  497. if (isset($soapRes->documentStatus)) {
  498. $status = $soapRes->documentStatus->status;
  499. }
  500. } else {
  501. // if the compilatio's hash is not a valide hash md5,
  502. // we return à specific status (cf : IsInCompilatio() )
  503. $status = 'NOT_IN_COMPILATIO';
  504. $actionCompilatio = get_lang('Verify that it contains text (and not only images)').'<br/>'.
  505. get_lang('and that it is not corrupted');
  506. }
  507. switch ($status) {
  508. case 'ANALYSE_COMPLETE':
  509. $urlRapport = $this->getReportUrl($compilatioId);
  510. $actionCompilatio .= self::getPomprankBarv31(
  511. $soapRes->documentStatus->indice,
  512. 10,
  513. 35
  514. )
  515. .Display::url(
  516. get_lang('Analyse'),
  517. $urlRapport,
  518. ['class' => 'btn btn-primary btn-xs', 'target' => '_blank']
  519. );
  520. break;
  521. case 'ANALYSE_PROCESSING':
  522. $actionCompilatio .= "<div style='font-weight:bold;text-align:left'>"
  523. .get_lang('AnalyseInProgress')
  524. ."</div>";
  525. $actionCompilatio .= "<div style='font-size:80%;font-style:italic;margin-bottom:5px;'>"
  526. .get_lang('AnalysePercentage')
  527. ."</div>";
  528. $text = [];
  529. $text['analysisinqueue'] = get_lang('Pending Analysis');
  530. $text['analysisinfinalization'] = get_lang('AnalyseEnding');
  531. $text['refresh'] = get_lang('Refresh');
  532. $actionCompilatio .= self::getProgressionAnalyseDocv31(
  533. $status,
  534. $soapRes->documentStatus->progression,
  535. $text
  536. );
  537. break;
  538. case 'ANALYSE_IN_QUEUE':
  539. $loading = Display::returnFontAwesomeIcon('spinner', null, true, 'fa-spin');
  540. $actionCompilatio .= $loading.'&nbsp;'.get_lang('Waiting for analysis');
  541. break;
  542. case 'BAD_FILETYPE':
  543. $actionCompilatio .= get_lang('File format not supported')
  544. .'<br/>'
  545. .get_lang('If the file is in pdf format, check that it is not protected by modification.');
  546. break;
  547. case 'BAD_FILESIZE':
  548. $actionCompilatio .= get_lang('The file is too big to upload.');
  549. break;
  550. }
  551. }
  552. $result = $workId.'|'.$actionCompilatio.'|'.$status.'|';
  553. return $result;
  554. }
  555. }