Passed
Pull Request — 1.11.x (#5852)
by Angel Fernando Quiroz
13:18
created

Compilatio::getProxyPort()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use GuzzleHttp\Client;
6
use GuzzleHttp\Psr7\Utils;
7
8
/**
9
 * Build the communication with the SOAP server Compilatio.net
10
 * call several methods for the file management in Compilatio.net.
11
 *
12
 * @version: 2.0
13
 */
14
class Compilatio
15
{
16
    /** Identification key for the Compilatio account*/
17
    public $key;
18
    /**
19
     * @var string
20
     */
21
    protected $baseUrl;
22
    /** Webservice connection*/
23
    public $soapcli;
24
    private $transportMode;
25
    private $maxFileSize;
26
    private $wgetUri;
27
    private $wgetLogin;
28
    private $wgetPassword;
29
    private $proxyHost;
30
    private $proxyPort;
31
32
    /**
33
     * @var Client
34
     */
35
    public $client;
36
37
    /**
38
     * Compilatio constructor.
39
     */
40
    public function __construct()
41
    {
42
        $settings = $this->getSettings();
43
44
        $this->transportMode = $settings['transport_mode'];
45
        $this->maxFileSize = $settings['max_filesize'];
46
        $this->wgetUri = $settings['wget_uri'];
47
        $this->wgetLogin = $settings['wget_login'];
48
        $this->wgetPassword = $settings['wget_password'];
49
        $this->key = $settings['key'];
50
        $this->baseUrl = $settings['soap_url'];
51
52
        if (!empty($settings['proxy_host'])) {
53
            $this->proxyHost = $settings['proxy_host'];
54
            $this->proxyPort = $settings['proxy_port'];
55
        }
56
57
        $clientConfig = [
58
            'base_uri' => api_remove_trailing_slash($this->baseUrl).'/',
59
            'headers' => [
60
                'X-Auth-Token' => $this->key,
61
                'Accept' => 'application/json',
62
            ],
63
        ];
64
65
        if ($this->proxyPort) {
66
            $clientConfig['proxy'] = $this->proxyHost.':'.$this->proxyPort;
67
        }
68
69
        $this->client = new Client($clientConfig);
70
    }
71
72
    /**
73
     * @throws Exception
74
     */
75
    protected function getSettings(): array
76
    {
77
        if (empty(api_get_configuration_value('allow_compilatio_tool')) ||
78
            empty(api_get_configuration_value('compilatio_tool'))
79
        ) {
80
            throw new Exception('Compilatio not available');
81
        }
82
83
        $compilatioTool = api_get_configuration_value('compilatio_tool');
84
85
        if (!isset($compilatioTool['settings'])) {
86
            throw new Exception('Compilatio config available');
87
        }
88
89
        $settings = $compilatioTool['settings'];
90
91
        if (empty($settings['key'])) {
92
            throw new Exception('API key not available');
93
        }
94
95
        if (empty($settings['soap_url'])) {
96
            throw new Exception('WS urlsoap not available');
97
        }
98
99
        return $settings;
100
    }
101
102
    /**
103
     * @return string
104
     */
105
    public function getKey()
106
    {
107
        return $this->key;
108
    }
109
110
    /**
111
     * @param mixed $key
112
     *
113
     * @return Compilatio
114
     */
115
    public function setKey($key)
116
    {
117
        $this->key = $key;
118
119
        return $this;
120
    }
121
122
    /**
123
     * @return mixed
124
     */
125
    public function getMaxFileSize()
126
    {
127
        return $this->maxFileSize;
128
    }
129
130
    /**
131
     * @return mixed
132
     */
133
    public function getProxyHost()
134
    {
135
        return $this->proxyHost;
136
    }
137
138
    /**
139
     * @return mixed
140
     */
141
    public function getProxyPort()
142
    {
143
        return $this->proxyPort;
144
    }
145
146
    /**
147
     * Method for the file load.
148
     */
149
    public function sendDoc(
150
        string $title,
151
        string $description,
152
        string $filename,
153
        string $filepath
154
    ) {
155
        $user = api_get_user_entity(api_get_user_id());
156
157
        $postData = [
158
            'folder_id' => '',
159
            'title' => $title,
160
            'filename' => basename($filename),
161
            'indexed' => 'true',
162
            'user_notes' => [
163
                'description' => $description
164
            ],
165
            'authors' => [
166
                [
167
                    'firstname' => $user->getFirstname(),
168
                    'lastname' => $user->getlastname(),
169
                    'email_address' => $user->getEmail(),
170
                ]
171
            ],
172
            'depositor' => [
173
                'firstname' => $user->getFirstname(),
174
                'lastname' => $user->getlastname(),
175
                'email_address' => $user->getEmail(),
176
            ]
177
        ];
178
179
        try {
180
            $responseBody = $this->client
181
                ->post(
182
                    'private/documents',
183
                    [
184
                        'multipart' => [
185
                            [
186
                                'name'     => 'postData',
187
                                'contents' => json_encode($postData)
188
                            ],
189
                            [
190
                                'name'     => 'file',
191
                                'contents' => Utils::tryFopen($filepath, 'r'),
192
                            ]
193
                        ]
194
                    ]
195
                )
196
                ->getBody()
197
            ;
198
        } catch (Exception $e) {
199
            throw new Exception($e->getMessage());
200
        }
201
202
        $body = json_decode((string) $responseBody, true);
203
204
        return $body['data']['document']['id'];
205
    }
206
207
    /**
208
     * Method for recover a document's information.
209
     *
210
     * @throws Exception
211
     */
212
    public function getDoc(string $documentId): array
213
    {
214
        try {
215
            $responseBody = $this->client
216
                ->get(
217
                    "private/documents/$documentId"
218
                )
219
                ->getBody()
220
            ;
221
        } catch (Exception $e) {
222
            throw new Exception($e->getMessage());
223
        }
224
225
        $responseJson = json_decode((string) $responseBody, true);
226
        $dataDocument = $responseJson['data']['document'];
227
228
        $documentInfo = [
229
            'report_url' => $dataDocument['report_url'],
230
        ];
231
232
        if (isset($dataDocument['analyses']['anasim']['state'])) {
233
            $documentInfo['analysis_status'] = $dataDocument['analyses']['anasim']['state'];
234
        }
235
236
        if (isset($dataDocument['light_reports']['anasim']['scores']['global_score_percent'])) {
237
            $documentInfo['report_percent'] = $dataDocument['light_reports']['anasim']['scores']['global_score_percent'];
238
        }
239
240
        return $documentInfo;
241
    }
242
243
    /**
244
     *  Method for deleting a Compialtio's account document.
245
     */
246
    public function deldoc(string $documentId)
247
    {
248
249
    }
250
251
    /**
252
     * Method for start the analysis for a document.
253
     *
254
     * @throws Exception
255
     */
256
    public function startAnalyse(string $compilatioId): string
257
    {
258
        try {
259
            $responseBody = $this->client
260
                ->post(
261
                    'private/analyses',
262
                    [
263
                        'json' => [
264
                            'doc_id' => $compilatioId,
265
                            'recipe_name' => 'anasim'
266
                        ],
267
                    ]
268
                )
269
                ->getBody()
270
            ;
271
        } catch (Exception $e) {
272
            throw new Exception($e->getMessage());
273
        }
274
275
        $body = json_decode((string) $responseBody, true);
276
277
        return $body['data']['analysis']['state'];
278
    }
279
280
    /**
281
     * Method for identify a file extension and the possibility that the document can be managed by Compilatio.
282
     */
283
    public static function verifiFileType(string $filename): bool
284
    {
285
        $types = ['doc', 'docx', 'rtf', 'xls', 'xlsx', 'ppt', 'pptx', 'odt', 'pdf', 'txt', 'htm', 'html'];
286
        $extension = substr($filename, strrpos($filename, '.') + 1);
287
        $extension = strtolower($extension);
288
289
        return in_array($extension, $types);
290
    }
291
292
    /**
293
     * Method for display the PomprseuilmankBar (% de plagiat).
294
     */
295
    public static function getPomprankBarv31(
296
        int $index,
297
        int $weakThreshold,
298
        int $highThreshold
299
    ): string {
300
        $index = round($index);
301
        $class = 'danger';
302
        if ($index < $weakThreshold) {
303
            $class = 'success';
304
        } elseif ($index < $highThreshold) {
305
            $class = 'warning';
306
        }
307
308
        return Display::bar_progress($index, true, null, $class);
309
    }
310
311
    /**
312
     * Function for delete a document of the compilatio table if plagiarismTool is Compilatio.
313
     */
314
    public static function plagiarismDeleteDoc(int $courseId, int $itemId)
315
    {
316
        if (api_get_configuration_value('allow_compilatio_tool') !== false) {
317
            $table = Database::get_course_table(TABLE_PLAGIARISM);
318
            $params = [$courseId, $itemId];
319
            Database::delete($table, ['c_id = ? AND document_id = ?' => $params]);
320
        }
321
    }
322
323
    public function saveDocument(int $courseId, int $documentId, string $compilatioId)
324
    {
325
        $table = Database::get_course_table(TABLE_PLAGIARISM);
326
        $params = [
327
            'c_id' => $courseId,
328
            'document_id' => $documentId,
329
            'compilatio_id' => $compilatioId,
330
        ];
331
        Database::insert($table, $params);
332
    }
333
334
    public function getCompilatioId(int $documentId, int $courseId): ?string
335
    {
336
        $table = Database::get_course_table(TABLE_PLAGIARISM);
337
        $sql = "SELECT compilatio_id FROM $table
338
                WHERE document_id = $documentId AND c_id= $courseId";
339
        $result = Database::query($sql);
340
        $result = Database::fetch_object($result);
341
342
        return $result ? (string)$result->compilatio_id : null;
343
    }
344
345
    public function giveWorkIdState(int $workId): string
346
    {
347
        $courseId = api_get_course_int_id();
348
        $compilatioId = $this->getCompilatioId($workId, $courseId);
349
350
        // if the compilatio's hash is not a valide hash md5,
351
        // we return à specific status (cf : IsInCompilatio() )
352
        $actionCompilatio = get_lang('CompilatioDocumentTextNotImage').'<br/>'.
353
            get_lang('CompilatioDocumentNotCorrupt');
354
        $status = '';
355
        if (!empty($compilatioId)) {
356
            // if compilatio_id is a hash md5, we call the function of the compilatio's
357
            // webservice who return the document's status
358
            $soapRes = $this->getDoc($compilatioId);
359
            $status = $soapRes['analysis_status'] ?? '';
360
361
            $spinnerIcon = Display::returnFontAwesomeIcon('spinner', null, true, 'fa-spin');
362
363
            switch ($status) {
364
                case 'finished':
365
                    $actionCompilatio .= self::getPomprankBarv31($soapRes['report_percent'], 10, 35)
366
                        .PHP_EOL
367
                        .Display::url(
368
                            get_lang('CompilatioAnalysis'),
369
                            $soapRes['report_url'],
370
                            ['class' => 'btn btn-primary btn-xs', 'target' => '_blank']
371
                        );
372
                    break;
373
                case 'running':
374
                    $actionCompilatio .= "<div style='font-weight:bold;text-align:left'>"
375
                        .get_lang('CompilatioAnalysisInProgress')
376
                        ."</div>";
377
                    $actionCompilatio .= "<div style='font-size:80%;font-style:italic;margin-bottom:5px;'>"
378
                        .get_lang('CompilatioAnalysisPercentage')
379
                        ."</div>";
380
                    $actionCompilatio .= $spinnerIcon.PHP_EOL .get_lang('CompilatioAnalysisEnding');
381
                    break;
382
                case 'waiting':
383
                    $actionCompilatio .= $spinnerIcon.PHP_EOL.get_lang('CompilatioWaitingAnalysis');
384
                    break;
385
                case 'canceled':
386
                    $actionCompilatio .= get_lang('Cancelled');
387
                    break;
388
                case 'scheduled':
389
                    $actionCompilatio .= $spinnerIcon.PHP_EOL.get_lang('CompilatioAwaitingAnalysis');
390
                    break;
391
            }
392
        }
393
394
        return $workId.'|'.$actionCompilatio.'|'.$status.'|';
395
    }
396
}
397