Completed
Push — master ( 17e47f...c8c08e )
by Julito
65:46 queued 26:40
created

hotpotatoes.lib.php ➔ HotPotGCt()   D

Complexity

Conditions 9
Paths 8

Size

Total Lines 29
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 18
nc 8
nop 3
dl 0
loc 29
rs 4.909
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * Code library for HotPotatoes integration.
6
 * @package chamilo.exercise
7
 * @author Istvan Mandak (original author)
8
 */
9
10
/* TODO: This is a global variable with too simple name, conflicts are possible.
11
Better eliminate it. Correct the test unit too. */
12
$dbTable = Database::get_course_table(TABLE_DOCUMENT);
13
14
/**
15
 * Creates a hotpotato directory.
16
 *
17
 * If a directory of that name already exists, don't create any. If a file of that name exists, remove it and create a directory.
18
 * @param   string      Wanted path
19
 * @return  boolean     Always true so far
20
 */
21
function hotpotatoes_init($base_work_dir)
22
{
23
    //global $_course, $_user;
24
    $document_path = $base_work_dir.'/';
25
    if (!is_dir($document_path)) {
26
        if (is_file($document_path)) {
27
            @unlink($document_path);
28
        }
29
        @mkdir($document_path, api_get_permissions_for_new_directories());
30
        return true;
31
    } else {
32
        return false;
33
    }
34
    //why create a .htaccess here?
35
    //if (!is_file($document_path.".htacces"))
36
    //{
37
    //        if (!($fp = fopen($document_path.".htaccess", "w"))) {
38
    //    }
39
    //    $str = "order deny,allow\nallow from all";
40
    //    if (!fwrite($fp,$str)) { }
41
    //}
42
}
43
44
/**
45
 * Gets the title of the quiz file given as parameter.
46
 * @param   string    File name
47
 * @param   string    File path
48
 * @return  string    The exercise title
49
 */
50
function GetQuizName($fname, $fpath)
51
{
52
    $title = GetComment($fname);
53
    if (trim($title) == '') {
54
        if (file_exists($fpath.$fname)) {
55
            if (!($fp = @fopen($fpath.$fname, 'r'))) {
56
                //die('Could not open Quiz input.');
57
                return basename($fname);
58
            }
59
60
            $contents = @fread($fp, filesize($fpath.$fname));
61
            @fclose($fp);
62
63
            $title = api_get_title_html($contents);
64
        }
65
    }
66
    if ($title == '') {
67
        $title = basename($fname);
68
    }
69
    return (string)$title;
70
}
71
72
/**
73
 * Gets the comment about a file from the corresponding database record.
74
 * @param   string    File path
75
 * @return  string    Comment from the database record
76
 * Added conditional to the table if is empty.
77
 */
78
function GetComment($path, $course_code = '')
79
{
80
    $dbTable = Database::get_course_table(TABLE_DOCUMENT);
81
    $course_info = api_get_course_info($course_code);
82
    $path = Database::escape_string($path);
83
    if (!empty($course_info) && !empty($path)) {
84
        $query = "SELECT comment FROM $dbTable WHERE c_id = {$course_info['real_id']}";
85
        $result = Database::query($query);
86
        while ($row = Database::fetch_array($result)) {
87
            return $row[0];
88
        }
89
    }
90
    return null;
91
}
92
93
/**
94
 * Sets the comment in the database for a particular path.
95
 * @param    string    File path
96
 * @param    string    Comment to set
97
 * @return   string    Result of the database operation (Database::query will output some message directly on error anyway)
98
 */
99
function SetComment($path, $comment)
100
{
101
    $dbTable = Database::get_course_table(TABLE_DOCUMENT);
102
    $path = Database::escape_string($path);
103
    $comment = Database::escape_string($comment);
104
    $course_id = api_get_course_int_id();
105
    $query = "UPDATE $dbTable SET comment='$comment'
106
              WHERE $course_id AND path='$path'";
107
    $result = Database::query($query);
108
109
    return $result;
110
}
111
112
/**
113
 * Reads the file contents into a string.
114
 * @param    string    Urlencoded path
115
 * @return   string    The file contents or false on security error
116
 */
117
function ReadFileCont($full_file_path)
118
{
119
    if (empty($full_file_path)) {
120
        return false;
121
    }
122
    if (Security::check_abs_path(dirname($full_file_path).'/', api_get_path(SYS_COURSE_PATH))) {
123
        if (is_file($full_file_path)) {
124
            if (!($fp = fopen(urldecode($full_file_path), 'r'))) {
125
                return '';
126
            }
127
            $contents = fread($fp, filesize($full_file_path));
128
            fclose($fp);
129
            return $contents;
130
        }
131
    }
132
    return false;
133
}
134
135
/**
136
 * Writes the file contents into the given file path.
137
 * @param    string    Urlencoded path
138
 * @param    string    The file contents
139
 * @return   boolean   True on success, false on security error
140
 */
141
function WriteFileCont($full_file_path, $content)
142
{
143
    // Check if this is not an attack, trying to get into other directories or something like that.
144
    $_course = api_get_course_info();
145
    if (Security::check_abs_path(dirname($full_file_path).'/', api_get_path(SYS_COURSE_PATH).$_course['path'].'/')) {
146
        // Check if this is not an attack, trying to upload a php file or something like that.
147
        if (basename($full_file_path) != Security::filter_filename(basename($full_file_path))) {
148
            return false;
149
        }
150
        if (!($fp = fopen(urldecode($full_file_path), 'w'))) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
151
            //die('Could not open Quiz input.');
152
        }
153
        fwrite($fp, $content);
154
        fclose($fp);
155
        return true;
156
    }
157
    return false;
158
}
159
160
/**
161
 * Gets the name of an img whose path is given (without directories or extensions).
162
 * @param    string    An image tag (<img src="...." ...>)
163
 * @return   string    The image file name or an empty string
164
 */
165
function GetImgName($imgtag)
166
{
167
    // Select src tag from img tag.
168
    $match = array();
169
    //preg_match('/(src=(["\'])1.*(["\'])1)/i', $imgtag, $match);            //src
170
    preg_match('/src(\s)*=(\s)*[\'"]([^\'"]*)[\'"]/i', $imgtag, $match); //get the img src as contained between " or '
171
    //list($key, $srctag) = each($match);
172
    $src = $match[3];
173
    //$src = substr($srctag, 5, (strlen($srctag) - 7));
174
    if (stristr($src, 'http') === false) {
175
    // Valid or invalid image name.
176
        if ($src == '') {
177
            return '';
178
        } else {
179
            $tmp_src = basename($src) ;
180
            if ($tmp_src == '') {
181
                return $src;
182
            } else {
183
                return $tmp_src;
184
            }
185
        }
186
    } else {
187
        // The img tag contained "http", which means it is probably external. Ignore it.
188
        return '';
189
    }
190
}
191
192
/**
193
 * Gets the source path of an image tag.
194
 * @param    string    An image tag
195
 * @return   string    The image source or ""
196
 */
197
function GetSrcName($imgtag)
198
{
199
    // Select src tag from img tag.
200
    $match = array();
201
    preg_match("|(src=\".*\" )|U", $imgtag, $match);            //src
202
    list($key, $srctag) = each($match);
0 ignored issues
show
Unused Code introduced by
The assignment to $key is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
203
    $src = substr($srctag, 5, (strlen($srctag) - 7));
204
    if (stristr($src, 'http') === false) {
205
    // valid or invalid image name
206
        return $src;
207
    } else {
208
        return '';
209
    }
210
}
211
212
/**
213
 * Gets the image parameters from an image path.
214
 * @param    string       File name
215
 * @param    string       File path
216
 * @param    reference    Reference to a list of image parameters (emptied, then used to return results)
217
 * @param    reference    Reference to a counter of images (emptied, then used to return results)
218
 */
219
function GetImgParams($fname, $fpath, &$imgparams, &$imgcount)
220
{
221
    // Select img tags from context.
222
    $imgparams = array();
223
    //phpinfo();
224
    $contents = ReadFileCont("$fpath"."$fname");
225
    $matches = array();
226
    preg_match_all('(<img .*>)', $contents, $matches);
227
    $imgcount = 0;
228
    while (list($int, $match) = each($matches)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $int is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
229
        // Each match consists of a key and a value.
230
        while (list($key, $imgtag) = each($match)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $key is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
231
            $imgname = GetImgName($imgtag);
232
            if ($imgname != '' && !in_array($imgname, $imgparams)) {
233
                array_push($imgparams, $imgname);    // name (+ type) of the images in the html test
234
                $imgcount = $imgcount + 1;            // number of images in the html test
235
            }
236
        }
237
    }
238
}
239
240
/**
241
 * Generates a list of hidden fields with the image params given as parameter to this function.
242
 * @param    array    List of image parameters
243
 * @return   string   String containing the hidden parameters built from the list given
244
 */
245
function GenerateHiddenList($imgparams)
246
{
247
    $list = '';
248
    if (is_array($imgparams)) {
249
        while (list($int, $string) = each($imgparams)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $int is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
250
            $list .= "<input type=\"hidden\" name=\"imgparams[]\" value=\"$string\" />\n";
251
        }
252
    }
253
    return $list;
254
}
255
256
/**
257
 * Searches for a node in the given array.
258
 * @param    reference    Reference to the array to search
259
 * @param    string       Node we are looking for in the array
260
 * @return   mixed        Node name or false if not found
261
 */
262
function myarraysearch(&$array, $node)
263
{
264
    $match = false;
265
    $tmp_array = array();
266
    for ($i = 0; $i < count($array); $i++) {
267
        if (!strcmp($array[$i], $node)) {
268
            $match = $node;
269
        } else {
270
            array_push($tmp_array, $array[$i]);
271
        }
272
    }
273
    $array = $tmp_array;
274
    return $match;
275
}
276
277
/**
278
 * Searches an image name into an array.
279
 * @param    reference        Reference to an array to search
280
 * @param    string           String to look for
281
 * @return   mixed            String given if found, false otherwise
282
 * @uses     myarraysearch    This function is just an additional layer on the myarraysearch() function
283
 */
284
function CheckImageName(&$imgparams, $string)
285
{
286
    $checked = myarraysearch($imgparams, $string);
287
    return $checked;
288
}
289
290
/**
291
 * Replaces an image tag by ???
292
 * @param    string    The content to replace
293
 * @return   string    The modified content
294
 */
295
function ReplaceImgTag($content)
296
{
297
    $newcontent = $content;
298
    $matches = array();
299
    preg_match_all('(<img .*>)', $content, $matches);
300
    while (list($int, $match) = each($matches)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $int is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
301
        while (list($key, $imgtag) = each($match)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $key is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
302
            $imgname = GetSrcName($imgtag);
303
            if ($imgname == '') {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
304
                // Valid or invalid image name.
305
            } else {
306
                $prehref = $imgname;
307
                $posthref = basename($imgname);
308
                $newcontent = str_replace($prehref, $posthref, $newcontent);
309
            }
310
        }
311
    }
312
    return $newcontent;
313
}
314
315
/**
316
 * Fills the folder name up to a certain length with "0".
317
 * @param    string    Original folder name
318
 * @param    integer   Length to reach
319
 * @return   string    Modified folder name
320
 */
321
function FillFolderName($name, $nsize)
322
{
323
    $str = '';
324
    for ($i = 0; $i < $nsize - strlen($name); $i++) {
325
        $str .= '0';
326
    }
327
    $str .= $name;
328
    return $str;
329
}
330
331
/**
332
 * Generates the HotPotato folder tree.
333
 * @param    string    Folder path
334
 * @return   string    Folder name (modified)
335
 */
336
function GenerateHpFolder($folder)
337
{
338
    $filelist = array();
339 View Code Duplication
    if ($dir = @opendir($folder)) {
340
        while (($file = readdir($dir)) !== false) {
341
            if ($file != '.') {
342
                if ($file != '..') {
343
                    $full_name = $folder.'/'.$file;
344
                    if (is_dir($full_name)) {
345
                        $filelist[] = $file;
346
                    }
347
               }
348
            }
349
        }
350
    }
351
    $w = 0;
352
    do {
353
        $name = FillFolderName(mt_rand(1, 99999), 6);
354
        $checked = myarraysearch($filelist, $name);
355
        // As long as we find the name in the array, continue looping. As soon as we have a new element, quit.
356
        if ($checked) {
357
            $w = 1;
358
        } else {
359
            $w = 0;
360
        }
361
    } while ($w == 1);
362
    return $name;
363
}
364
365
/**
366
 * Gets the folder name (strips down path).
367
 * @param    string    Path
368
 * @return   string    Folder name stripped down
369
 */
370
function GetFolderName($fname)
371
{
372
    $name = explode('/', $fname);
373
    $name = $name[sizeof($name) - 2];
374
    return $name;
375
}
376
377
/**
378
 * Gets the folder path (with out the name of the folder itself) ?
379
 * @param    string    Path
380
 * @return   string    Path stripped down
381
 */
382
function GetFolderPath($fname)
383
{
384
    $str = '';
385
    $name = explode('/', $fname);
386
    for ($i = 0; $i < sizeof($name) - 1; $i++) {
387
        $str = $str.$name[$i].'/';
388
    }
389
    return $str;
390
}
391
392
/**
393
 * Checks if there are subfolders.
394
 * @param    string    Path
395
 * @return   integer   1 if a subfolder was found, 0 otherwise
396
 */
397
function CheckSubFolder($path)
398
{
399
    $folder = GetFolderPath($path);
400
    $dflag = 0;
401 View Code Duplication
    if ($dir = @opendir($folder)) {
402
        while (($file = readdir($dir)) !== false) {
403
            if ($file != '.') {
404
                if ($file != '..') {
405
                    $full_name = $folder.'/'.$file;
406
                    if (is_dir($full_name)) {
407
                        $dflag = 1;    // first directory
408
                    }
409
                }
410
            }
411
        }
412
    }
413
    return $dflag;
414
}
415
416
/**
417
 * Hotpotato Garbage Collector
418
 * @param    string     Path
419
 * @param    integer    Flag
420
 * @param    integer    User id
421
 * @return   void       No return value, but echoes results
422
 */
423
function HotPotGCt($folder, $flag, $user_id)
424
{
425
    // Garbage Collector
426
    $filelist = array();
427
    if ($dir = @opendir($folder)) {
428
        while (($file = readdir($dir)) !== false) {
429
            if ($file != '.') {
430
                if ($file != '..') {
431
                    $full_name = $folder.'/'.$file;
432
                    if (is_dir($full_name)) {
433
                        HotPotGCt($folder.'/'.$file, $flag, $user_id);
434
                    } else {
435
                        $filelist[] = $file;
436
                    }
437
                }
438
            }
439
        }
440
        closedir($dir);
441
    }
442
    while (list($key, $val) = each($filelist)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $key is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
443
        if (stristr($val, $user_id.'.t.html')) {
444
            if ($flag == 1) {
445
                my_delete($folder.'/'.$val);
446
            } else {
447
                echo $folder.'/'.$val.'<br />';
448
            }
449
        }
450
    }
451
}
452
453
/**
454
 * Deletes an attempt from TABLE_STATISTIC_TRACK_E_HOTPOTATOES
455
 * @param int $id
456
 */
457
function deleteAttempt($id)
458
{
459
    $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTPOTATOES);
460
    $id = intval($id);
461
    $sql = "DELETE FROM $table WHERE id = $id";
462
    Database::query($sql);
463
}
464