Compilatio.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  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. * Date: 26/05/16
  8. * @version:1.0
  9. */
  10. class Compilatio
  11. {
  12. /** Identification key for the Compilatio account*/
  13. public $key;
  14. /** Webservice connection*/
  15. public $soapcli;
  16. private $transportMode;
  17. private $maxFileSize;
  18. private $wgetUri;
  19. private $wgetLogin;
  20. private $wgetPassword;
  21. private $proxyHost;
  22. private $proxyPort;
  23. /**
  24. * Compilatio constructor.
  25. *
  26. */
  27. public function __construct()
  28. {
  29. if (empty(api_get_configuration_value('allow_compilatio_tool')) ||
  30. empty(api_get_configuration_value('compilatio_tool'))
  31. ) {
  32. throw new Exception('Compilation not available');
  33. }
  34. $settings = api_get_configuration_value('compilatio_tool');
  35. $key = $this->key = $settings['key'];
  36. $urlsoap = $settings['soap_url'];
  37. $proxyHost = $this->proxyHost = $settings['proxy_host'];
  38. $proxyPort = $this->proxyPort = $settings['proxy_port'];
  39. $this->transportMode = $settings['transport_mode'];
  40. $this->maxFileSize = $settings['max_filesize'];
  41. $this->wgetUri = $settings['wget_uri'];
  42. $this->wgetLogin = $settings['wget_login'];
  43. $this->wgetPassword = $settings['wget_password'];
  44. try {
  45. if (!empty($key)) {
  46. $this->key = $key;
  47. if (!empty($urlsoap)) {
  48. if (!empty($proxyHost)) {
  49. $param = array(
  50. 'trace' => false,
  51. 'soap_version' => SOAP_1_2,
  52. 'exceptions' => true,
  53. 'proxy_host' => '"'.$proxyHost.'"',
  54. 'proxy_port' => $proxyPort,
  55. );
  56. } else {
  57. $param = array(
  58. 'trace' => false,
  59. 'soap_version' => SOAP_1_2,
  60. 'exceptions' => true,
  61. );
  62. }
  63. $this->soapcli = new SoapClient($urlsoap, $param);
  64. } else {
  65. $this->soapcli = 'WS urlsoap not available';
  66. }
  67. } else {
  68. $this->soapcli = 'API key not available';
  69. }
  70. } catch (SoapFault $fault) {
  71. $this->soapcli = "Error constructor compilatio ".$fault->faultcode." ".$fault->faultstring;
  72. } catch (Exception $e) {
  73. $this->soapcli = "Error constructor compilatio with urlsoap".$urlsoap;
  74. }
  75. }
  76. /**
  77. * @return string
  78. */
  79. public function getKey()
  80. {
  81. return $this->key;
  82. }
  83. /**
  84. * @param mixed $key
  85. *
  86. * @return Compilatio
  87. */
  88. public function setKey($key)
  89. {
  90. $this->key = $key;
  91. return $this;
  92. }
  93. /**
  94. * @return mixed
  95. */
  96. public function getTransportMode()
  97. {
  98. return $this->transportMode;
  99. }
  100. /**
  101. * @param mixed $transportMode
  102. *
  103. * @return Compilatio
  104. */
  105. public function setTransportMode($transportMode)
  106. {
  107. $this->transportMode = $transportMode;
  108. return $this;
  109. }
  110. /**
  111. * @return mixed
  112. */
  113. public function getMaxFileSize()
  114. {
  115. return $this->maxFileSize;
  116. }
  117. /**
  118. * @param mixed $maxFileSize
  119. *
  120. * @return Compilatio
  121. */
  122. public function setMaxFileSize($maxFileSize)
  123. {
  124. $this->maxFileSize = $maxFileSize;
  125. return $this;
  126. }
  127. /**
  128. * @return mixed
  129. */
  130. public function getWgetUri()
  131. {
  132. return $this->wgetUri;
  133. }
  134. /**
  135. * @param mixed $wgetUri
  136. *
  137. * @return Compilatio
  138. */
  139. public function setWgetUri($wgetUri)
  140. {
  141. $this->wgetUri = $wgetUri;
  142. return $this;
  143. }
  144. /**
  145. * @return mixed
  146. */
  147. public function getWgetLogin()
  148. {
  149. return $this->wgetLogin;
  150. }
  151. /**
  152. * @param mixed $wgetLogin
  153. *
  154. * @return Compilatio
  155. */
  156. public function setWgetLogin($wgetLogin)
  157. {
  158. $this->wgetLogin = $wgetLogin;
  159. return $this;
  160. }
  161. /**
  162. * @return mixed
  163. */
  164. public function getWgetPassword()
  165. {
  166. return $this->wgetPassword;
  167. }
  168. /**
  169. * @param mixed $wgetPassword
  170. *
  171. * @return Compilatio
  172. */
  173. public function setWgetPassword($wgetPassword)
  174. {
  175. $this->wgetPassword = $wgetPassword;
  176. return $this;
  177. }
  178. /**
  179. * @return mixed
  180. */
  181. public function getProxyHost()
  182. {
  183. return $this->proxyHost;
  184. }
  185. /**
  186. * @param mixed $proxyHost
  187. *
  188. * @return Compilatio
  189. */
  190. public function setProxyHost($proxyHost)
  191. {
  192. $this->proxyHost = $proxyHost;
  193. return $this;
  194. }
  195. /**
  196. * @return mixed
  197. */
  198. public function getProxyPort()
  199. {
  200. return $this->proxyPort;
  201. }
  202. /**
  203. * @param mixed $proxyPort
  204. *
  205. * @return Compilatio
  206. */
  207. public function setProxyPort($proxyPort)
  208. {
  209. $this->proxyPort = $proxyPort;
  210. return $this;
  211. }
  212. /**
  213. * Method for the file load
  214. *
  215. * @param $title
  216. * @param $description
  217. * @param $filename
  218. * @param $mimeType
  219. * @param $content
  220. *
  221. * @return string
  222. */
  223. public function sendDoc($title, $description, $filename, $mimeType, $content)
  224. {
  225. try {
  226. if (!is_object($this->soapcli)) {
  227. return ("Error in constructor compilatio() ".$this->soapcli);
  228. }
  229. $idDocument = $this->soapcli->__call(
  230. 'addDocumentBase64',
  231. array(
  232. $this->key,
  233. utf8_encode(urlencode($title)),
  234. utf8_encode(urlencode($description)),
  235. utf8_encode(urlencode($filename)),
  236. utf8_encode($mimeType),
  237. base64_encode($content),
  238. )
  239. );
  240. return $idDocument;
  241. } catch (SoapFault $fault) {
  242. return ("Erreur sendDoc()".$fault->faultcode." ".$fault->faultstring);
  243. }
  244. }
  245. /**
  246. * Method for recover a document's information
  247. *
  248. * @param $compiHash
  249. *
  250. * @return string
  251. */
  252. public function getDoc($compiHash)
  253. {
  254. try {
  255. if (!is_object($this->soapcli)) {
  256. return ("Error in constructor compilatio() ".$this->soapcli);
  257. }
  258. $param = array($this->key, $compiHash);
  259. $idDocument = $this->soapcli->__call('getDocument', $param);
  260. return $idDocument;
  261. } catch (SoapFault $fault) {
  262. return ("Erreur getDoc()".$fault->faultcode." ".$fault->faultstring);
  263. }
  264. }
  265. /**
  266. * method for recover an url document's report
  267. *
  268. * @param $compiHash
  269. *
  270. * @return string
  271. */
  272. public function getReportUrl($compiHash)
  273. {
  274. try {
  275. if (!is_object($this->soapcli)) {
  276. return ("Error in constructor compilatio() ".$this->soapcli);
  277. }
  278. $param = array($this->key, $compiHash);
  279. $idDocument = $this->soapcli->__call('getDocumentReportUrl', $param);
  280. return $idDocument;
  281. } catch (SoapFault $fault) {
  282. return ("Erreur getReportUrl()".$fault->faultcode." ".$fault->faultstring);
  283. }
  284. }
  285. /**
  286. * Method for deleting a Compialtio's account document
  287. *
  288. * @param $compiHash
  289. *
  290. * @return string
  291. */
  292. public function deldoc($compiHash)
  293. {
  294. try {
  295. if (!is_object($this->soapcli)) {
  296. return ("Error in constructor compilatio() ".$this->soapcli);
  297. }
  298. $param = array($this->key, $compiHash);
  299. $this->soapcli->__call('deleteDocument', $param);
  300. } catch (SoapFault $fault) {
  301. return ("Erreur deldoc()".$fault->faultcode." ".$fault->faultstring);
  302. }
  303. }
  304. /**
  305. * Method for start the analysis for a document
  306. *
  307. * @param $compiHash
  308. *
  309. * @return string
  310. */
  311. public function startAnalyse($compiHash)
  312. {
  313. try {
  314. if (!is_object($this->soapcli)) {
  315. return ("Error in constructor compilatio() ".$this->soapcli);
  316. }
  317. $param = array($this->key, $compiHash);
  318. $this->soapcli->__call('startDocumentAnalyse', $param);
  319. } catch (SoapFault $fault) {
  320. return ("Erreur startAnalyse()".$fault->faultcode." ".$fault->faultstring);
  321. }
  322. }
  323. /**
  324. * Method for recover the account's quota
  325. * @return string
  326. */
  327. public function getQuotas()
  328. {
  329. try {
  330. if (!is_object($this->soapcli)) {
  331. return ("Error in constructor compilatio() ".$this->soapcli);
  332. }
  333. $param = array($this->key);
  334. $resultat = $this->soapcli->__call('getAccountQuotas', $param);
  335. return $resultat;
  336. } catch (SoapFault $fault) {
  337. return ("Erreur getQuotas()".$fault->faultcode." ".$fault->faultstring);
  338. }
  339. }
  340. /**
  341. * Method for identify a file extension and the possibility that the document can be managed by Compilatio
  342. *
  343. * @param $filename
  344. *
  345. * @return bool
  346. */
  347. public static function verifiFileType($filename)
  348. {
  349. $types = array('doc', 'docx', 'rtf', 'xls', 'xlsx', 'ppt', 'pptx', 'odt', 'pdf', 'txt', 'htm', 'html');
  350. $extension = substr($filename, strrpos($filename, '.') + 1);
  351. $extension = strtolower($extension);
  352. return in_array($extension, $types);
  353. }
  354. /**
  355. * Fonction affichage de la barre de progression d'analyse version 3.1
  356. *
  357. * @param string $status From the document
  358. * @param $pour
  359. * @param string $imagesPath
  360. * @param array $text Array includes the extract from the text
  361. *
  362. * @return unknown_type
  363. */
  364. public static function getProgressionAnalyseDocv31($status, $pour = 0, $imagesPath = '', $text = [])
  365. {
  366. $refreshReturn = "<a href='javascript:window.location.reload(false);'><img src='"
  367. .$imagesPath
  368. ."ajax-loader_green.gif' title='"
  369. .$text['refresh']
  370. ."' alt='"
  371. .$text['refresh']
  372. ."'/></a> ";
  373. $startReturn = "<table cellpadding='0' cellspacing='0' style='border:0;margin:0;padding:0;'><tr>";
  374. $startReturn .= "<td width='25' style='border:0;margin:0;padding:0;'>&nbsp;</td>";
  375. $startReturn .= "<td valign='middle' align='right' style='border:0;margin:0;padding-right:10px;'>"
  376. .$refreshReturn
  377. ."</td>";
  378. $startReturn .= "<td style='border:0;margin:0;padding:0;'>";
  379. $startReturnLittleWidth = "<table cellpadding='0' cellspacing='0' style='border:0;margin:0;padding:0;'><tr>";
  380. $startReturnLittleWidth .= "<td width='25' valign='middle' align='right' style='border:0;margin:0;padding:0;'>"
  381. .$refreshReturn
  382. ."</td>";
  383. $finretour = "</td></tr></table>";
  384. if ($status == 'ANALYSE_IN_QUEUE') {
  385. return $startReturn."<span style='font-size:11px'>".$text['analysisinqueue']."</span>".$finretour;
  386. }
  387. if ($status == 'ANALYSE_PROCESSING') {
  388. if ($pour == 100) {
  389. return $startReturn
  390. ."<span style='font-size:11px'>"
  391. .$text['analysisinfinalization']
  392. ."</span>"
  393. .$finretour;
  394. } else {
  395. return $startReturnLittleWidth
  396. ."<td align=\"right\" style=\"border:0;margin:0;padding-right:10px;\">"
  397. .$pour
  398. ."%</td><td style=\"border:0;margin:0;padding:0;\"><div style=\"background"
  399. .":transparent url("
  400. .$imagesPath
  401. ."mini-jauge_fond.png) no-repeat scroll 0;height:12px;padding:0 0 0 2px;width:55px;\"><div style=\""
  402. ."background:transparent url("
  403. .$imagesPath
  404. ."mini-jauge_gris.png) no-repeat scroll 0;height:12px;width:"
  405. .$pour / 2
  406. ."px;\"></div></div>"
  407. .$finretour;
  408. }
  409. }
  410. }
  411. /**
  412. * Method for display the PomprseuilmankBar (% de plagiat)
  413. *
  414. * @param $percentagePumping
  415. * @param $weakThreshold
  416. * @param $highThreshold
  417. * @param $imagesPath
  418. * @param $text : array includes the extract from the text
  419. *
  420. * @return unknown_type
  421. */
  422. public static function getPomprankBarv31($pourcentagePompage, $weakThreshold, $highThreshold, $chemin_images = '', $texte = '')
  423. {
  424. $pourcentagePompage = round($pourcentagePompage);
  425. $pour = round((50 * $pourcentagePompage) / 100);
  426. $return = '';
  427. if ($pourcentagePompage < $weakThreshold) {
  428. $couleur = "vert";
  429. } else {
  430. if ($pourcentagePompage >= $weakThreshold && $pourcentagePompage < $highThreshold) {
  431. $couleur = "orange";
  432. } else {
  433. $couleur = "rouge";
  434. }
  435. }
  436. $return .= "<div style='float:left;margin-right:2px;'><img src='"
  437. .$chemin_images."mini-drapeau_$couleur.png' title='"
  438. .$texte['result']
  439. ."' alt='faible' width='15' height='15' /></div>";
  440. $return .= "<div style='float:left; margin-right:5px;width:45px;text-align:right;'>"
  441. .$pourcentagePompage
  442. ." %</div>";
  443. $return .= "<div style='float:left;background:transparent url("
  444. .$chemin_images
  445. ."mini-jauge_fond.png) no-repeat scroll 0;height:12px;margin-top:5px;padding:0 0 0 2px;width:55px;'>";
  446. $return .= "<div style='float:left;background:transparent url("
  447. .$chemin_images
  448. ."mini-jauge_"
  449. .$couleur
  450. .".png) no-repeat scroll 0;height:12px;width:"
  451. .$pour
  452. ."px'></div></div>";
  453. return $return;
  454. }
  455. /**
  456. * Method for validation of hash
  457. * @param $hash
  458. * @return bool
  459. *
  460. */
  461. public static function isMd5($hash)
  462. {
  463. return preg_match('`^[a-f0-9]{32}$`', $hash);
  464. }
  465. /*
  466. * Method for identify Internet media type
  467. * @param $filename
  468. */
  469. public static function typeMime($filename)
  470. {
  471. if (preg_match("@Opera(/| )([0-9].[0-9]{1,2})@", $_SERVER['HTTP_USER_AGENT'], $resultats)) {
  472. $navigateur = "Opera";
  473. } elseif (preg_match("@MSIE ([0-9].[0-9]{1,2})@", $_SERVER['HTTP_USER_AGENT'], $resultats)) {
  474. $navigateur = "Internet Explorer";
  475. } else {
  476. $navigateur = "Mozilla";
  477. $mime = parse_ini_file("mime.ini");
  478. $extension = substr($filename, strrpos($filename, ".") + 1);
  479. }
  480. if (array_key_exists($extension, $mime)) {
  481. $type = $mime[$extension];
  482. } else {
  483. $type = ($navigateur != "Mozilla") ? 'application/octetstream' : 'application/octet-stream';
  484. }
  485. return $type;
  486. }
  487. /**
  488. * function for delete a document of the compilatio table if plagiarismTool is Compilatio
  489. * @param int $courseId
  490. * @param int $itemId
  491. */
  492. public static function plagiarismDeleteDoc($courseId, $itemId)
  493. {
  494. if (api_get_configuration_value('allow_compilatio_tool')) {
  495. return false;
  496. }
  497. $table = Database:: get_course_table(TABLE_PLAGIARISM);
  498. $params = [$courseId, $itemId];
  499. Database::delete($table, ['c_id = ? AND document_id = ?' => $params]);
  500. }
  501. /**
  502. * @param int $courseId
  503. * @param int $documentId
  504. * @param int $compilatioId
  505. */
  506. public function saveDocument($courseId, $documentId, $compilatioId)
  507. {
  508. $documentId = (int) $documentId;
  509. $courseId = (int) $courseId;
  510. $compilatioId = (int) $compilatioId;
  511. $table = Database::get_course_table(TABLE_PLAGIARISM);
  512. $params = [
  513. 'c_id' => $courseId,
  514. 'document_id' => $documentId,
  515. 'compilatio_id' => $compilatioId,
  516. ];
  517. Database::insert($table, $params);
  518. }
  519. /**
  520. * @param int $itemId
  521. * @param int $courseId
  522. *
  523. * @return int
  524. */
  525. public function getCompilatioId($itemId, $courseId)
  526. {
  527. $itemId = (int) $itemId;
  528. $courseId = (int) $courseId;
  529. $table = Database::get_course_table(TABLE_PLAGIARISM);
  530. $sql = "SELECT compilatio_id FROM $table
  531. WHERE document_id = $itemId AND c_id= $courseId";
  532. $compiSqlResult = Database::query($sql);
  533. $result = Database::fetch_object($compiSqlResult);
  534. if ($result) {
  535. return (int) $result->compilatio_id;
  536. }
  537. return 0;
  538. }
  539. /**
  540. * @param $workId
  541. *
  542. * @return string
  543. */
  544. public function giveWorkIdState($workId)
  545. {
  546. $text = '';
  547. $compilatioImgFolder = api_get_path(WEB_CODE_PATH).'plagiarism/compilatio/img/';
  548. $courseId = api_get_course_int_id();
  549. $compilatioId = $this->getCompilatioId($workId, $courseId);
  550. $actionCompilatio = '';
  551. if (!empty($compilatioId)) {
  552. if (self::isMd5($compilatioId)) {
  553. // if compilatio_id is a hash md5, we call the function of the compilatio's webservice who return the document's status
  554. $soapRes = $this->getDoc($compilatioId);
  555. $status = '';
  556. if (isset($soapRes->documentStatus)) {
  557. $status = $soapRes->documentStatus->status;
  558. }
  559. } else {
  560. // if the compilatio's hash is not a valide hash md5, we return à specific status (cf : IsInCompilatio() )
  561. $status = 'NOT_IN_COMPILATIO';
  562. $actionCompilatio = "<div style='font-style:italic'>"
  563. .get_lang('compilatioDocumentTextNotImage')
  564. ."<br/>"
  565. .get_lang('compilatioDocumentNotCorrupt')
  566. ."</div>";
  567. }
  568. if ($status === 'ANALYSE_COMPLETE') {
  569. $urlRapport = $this->getReportUrl($compilatioId);
  570. $actionCompilatio .= self::getPomprankBarv31(
  571. $soapRes->documentStatus->indice,
  572. 10,
  573. 35,
  574. $compilatioImgFolder,
  575. $text
  576. )
  577. ."<br/><a href='"
  578. .$urlRapport
  579. ."' target='_blank'>"
  580. .get_lang('compilatioSeeReport')
  581. ."</a>";
  582. } elseif ($status === 'ANALYSE_PROCESSING') {
  583. $actionCompilatio .= "<div style='font-weight:bold;text-align:left'>"
  584. .get_lang('compilatioAnalysisInProgress')
  585. ."</div>";
  586. $actionCompilatio .= "<div style='font-size:80%;font-style:italic;margin-bottom:5px;'>"
  587. .get_lang('compilatioAnalysisPercentage')
  588. ."</div>";
  589. $text['analysisinqueue'] = get_lang('compilatioWaitingAnalysis');
  590. $text['analysisinfinalization'] = get_lang('compilatioAnalysisEnding');
  591. $text['refresh'] = get_lang('Refresh');
  592. $actionCompilatio .= self::getProgressionAnalyseDocv31(
  593. $status,
  594. $soapRes->documentStatus->progression,
  595. $compilatioImgFolder,
  596. $text
  597. );
  598. } elseif ($status == 'ANALYSE_IN_QUEUE') {
  599. $actionCompilatio .= "<img src='"
  600. .$compilatioImgFolder
  601. ."/ajax-loader2.gif' style='margin-right:10px;' />"
  602. .get_lang('compilatioAwaitingAnalysis');
  603. } elseif ($status == 'BAD_FILETYPE') {
  604. $actionCompilatio .= "<div style='font-style:italic'>"
  605. .get_lang('compilatioFileisnotsupported')
  606. ."<br/>"
  607. .get_lang('compilatioProtectedPdfVerification')
  608. ."</div>";
  609. } elseif ($status == 'BAD_FILESIZE') {
  610. $actionCompilatio .= "<div style='font-style:italic'>"
  611. .get_lang('compilatioTooHeavyDocument')
  612. ."</div>";
  613. } elseif ($status != 'NOT_IN_COMPILATIO') {
  614. $actionCompilatio .= "<div style='font-style:italic'>"
  615. .get_lang('compilatioMomentarilyUnavailableResult')
  616. ." : [ "
  617. .$status
  618. ."].</div>";
  619. }
  620. }
  621. $result = $workId.'|'.$actionCompilatio.'|'.$status.'|';
  622. return $result;
  623. }
  624. }