Passed
Pull Request — 1.11.x (#7472)
by
unknown
09:59
created

chamilo_lp_import_from_zip()   C

Complexity

Conditions 12
Paths 10

Size

Total Lines 71
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 38
c 0
b 0
f 0
dl 0
loc 71
rs 6.9666
cc 12
nc 10
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CourseBundle\Component\CourseCopy\CourseArchiver;
6
use Chamilo\CourseBundle\Component\CourseCopy\CourseRestorer;
7
8
/**
9
 * Script managing the learnpath upload. To best treat the uploaded file, make sure we can identify it.
10
 *
11
 * @author Yannick Warnier <[email protected]>
12
 */
13
require_once __DIR__.'/../inc/global.inc.php';
14
api_protect_course_script();
15
16
/**
17
 * Imports a Chamilo CourseBackup zip that contains LP data into the current course.
18
 * Returns true only if something was actually restored (basic DB verification).
19
 */
20
function chamilo_lp_import_from_zip(string $zipPath, int $sessionId): bool
21
{
22
    $cid = (int) api_get_course_int_id();
23
24
    // Basic input validation
25
    if (!is_file($zipPath) || !is_readable($zipPath)) {
26
        return false;
27
    }
28
29
    // Minimal snapshot to detect real changes
30
    $snapshot = static function () use ($cid): array {
31
        $lp = Database::fetch_array(Database::query(
32
            "SELECT COUNT(*) AS cnt, COALESCE(MAX(iid), 0) AS max_iid
33
             FROM c_lp WHERE c_id = ".$cid
34
        ));
35
        $lpItem = Database::fetch_array(Database::query(
36
            "SELECT COUNT(*) AS cnt, COALESCE(MAX(iid), 0) AS max_iid
37
             FROM c_lp_item WHERE c_id = ".$cid
38
        ));
39
40
        return [
41
            'lp_cnt' => (int) ($lp['cnt'] ?? 0),
42
            'lp_max' => (int) ($lp['max_iid'] ?? 0),
43
            'lpi_cnt' => (int) ($lpItem['cnt'] ?? 0),
44
            'lpi_max' => (int) ($lpItem['max_iid'] ?? 0),
45
        ];
46
    };
47
48
    $before = $snapshot();
49
50
    // Store inside course_backups/
51
    $backupFile = CourseArchiver::importUploadedFile($zipPath);
52
    if ($backupFile === false || $backupFile === '') {
53
        return false;
54
    }
55
56
    // Guard: ensure file is really there before readCourse()
57
    $backupAbs = CourseArchiver::getBackupDir().$backupFile;
58
    if (!is_file($backupAbs) || !is_readable($backupAbs)) {
59
        return false;
60
    }
61
62
    // true => delete backup zip after extracting
63
    $course = CourseArchiver::readCourse($backupFile, true);
64
    if (!is_object($course)) {
65
        return false;
66
    }
67
68
    $restorer = new CourseRestorer($course);
69
    $restorer->set_file_option(FILE_OVERWRITE);
70
71
    // Restore only what LP import needs (avoid side effects from full course restore)
72
    $allowedTools = ['documents', 'learnpath_category', 'learnpaths', 'scorm_documents', 'assets'];
73
    if (isset($restorer->tools_to_restore) && is_array($restorer->tools_to_restore)) {
74
        $restorer->tools_to_restore = array_values(array_intersect($restorer->tools_to_restore, $allowedTools));
75
    }
76
77
    // Destination MUST be course code (api_get_course_id)
78
    $destination = (string) api_get_course_id();
79
    if ($destination === '') {
80
        return false;
81
    }
82
83
    $res = $restorer->restore($destination, (int) $sessionId);
84
    if ($res === false) {
85
        return false;
86
    }
87
88
    $after = $snapshot();
89
90
    return $after !== $before;
91
}
92
93
$course_dir = api_get_course_path().'/scorm';
94
$course_sys_dir = api_get_path(SYS_COURSE_PATH).$course_dir;
95
if (empty($_POST['current_dir'])) {
96
    $current_dir = '';
97
} else {
98
    $current_dir = api_replace_dangerous_char(trim($_POST['current_dir']));
99
}
100
$uncompress = 1;
101
102
$allowHtaccess = false;
103
if (api_get_configuration_value('allow_htaccess_import_from_scorm') && isset($_POST['allow_htaccess'])) {
104
    $allowHtaccess = true;
105
}
106
107
/*
108
 * Check the request method in place of a variable from POST
109
 * because if the file size exceed the maximum file upload
110
 * size set in php.ini, all variables from POST are cleared !
111
 */
112
$user_file = isset($_GET['user_file']) ? $_GET['user_file'] : [];
113
$user_file = $user_file ? $user_file : [];
114
$is_error = isset($user_file['error']) ? $user_file['error'] : false;
115
if (isset($_POST) && $is_error) {
116
    Display::addFlash(
117
        Display::return_message(get_lang('UplFileTooBig'))
118
    );
119
120
    return false;
121
    unset($_FILES['user_file']);
122
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST' && count($_FILES) > 0 && !empty($_FILES['user_file']['name'])) {
123
    // A file upload has been detected, now deal with the file...
124
    // Directory creation.
125
    $stopping_error = false;
126
    $s = $_FILES['user_file']['name'];
127
128
    // Get name of the zip file without the extension.
129
    $info = pathinfo($s);
130
    $filename = $info['basename'];
131
    $extension = $info['extension'];
132
    $file_base_name = str_replace('.'.$extension, '', $filename);
133
134
    $new_dir = api_replace_dangerous_char(trim($file_base_name));
135
    $type = learnpath::getPackageType($_FILES['user_file']['tmp_name'], $_FILES['user_file']['name']);
136
137
    $proximity = 'local';
138
    if (!empty($_REQUEST['content_proximity'])) {
139
        $proximity = Database::escape_string($_REQUEST['content_proximity']);
140
    }
141
142
    $maker = 'Scorm';
143
    if (!empty($_REQUEST['content_maker'])) {
144
        $maker = Database::escape_string($_REQUEST['content_maker']);
145
    }
146
147
    switch ($type) {
148
        case 'chamilo':
149
            if (empty($_configuration['allow_lp_chamilo_export'])) {
150
                Display::addFlash(Display::return_message(get_lang('ScormUnknownPackageFormat'), 'warning'));
151
                break;
152
            }
153
154
            $ok = chamilo_lp_import_from_zip($_FILES['user_file']['tmp_name'], api_get_session_id());
155
156
            if ($ok) {
157
                Display::addFlash(Display::return_message(get_lang('UplUploadSucceeded'), 'confirmation'));
158
            } else {
159
                Display::addFlash(Display::return_message(get_lang('UploadError'), 'error'));
160
            }
161
            break;
162
        case 'scorm':
163
            $oScorm = new scorm();
164
            $manifest = $oScorm->import_package(
165
                $_FILES['user_file'],
166
                $current_dir,
167
                [],
168
                false,
169
                null,
170
                $allowHtaccess
171
            );
172
            if (!empty($manifest)) {
173
                $oScorm->parse_manifest($manifest);
174
                $oScorm->import_manifest(api_get_course_id(), $_REQUEST['use_max_score']);
175
                Display::addFlash(Display::return_message(get_lang('UplUploadSucceeded')));
176
            }
177
            $oScorm->set_proximity($proximity);
178
            $oScorm->set_maker($maker);
179
            $oScorm->set_jslib('scorm_api.php');
180
            break;
181
        case 'aicc':
182
            $oAICC = new aicc();
183
            $config_dir = $oAICC->import_package($_FILES['user_file']);
184
            if (!empty($config_dir)) {
185
                $oAICC->parse_config_files($config_dir);
186
                $oAICC->import_aicc(api_get_course_id());
187
                Display::addFlash(Display::return_message(get_lang('UplUploadSucceeded')));
188
            }
189
            $oAICC->set_proximity($proximity);
190
            $oAICC->set_maker($maker);
191
            $oAICC->set_jslib('aicc_api.php');
192
            break;
193
        case 'oogie':
194
            require_once 'openoffice_presentation.class.php';
195
            $take_slide_name = empty($_POST['take_slide_name']) ? false : true;
196
            $o_ppt = new OpenofficePresentation($take_slide_name);
197
            $first_item_id = $o_ppt->convert_document($_FILES['user_file'], 'make_lp', $_POST['slide_size']);
198
            Display::addFlash(Display::return_message(get_lang('UplUploadSucceeded')));
199
            break;
200
        case 'woogie':
201
            require_once 'openoffice_text.class.php';
202
            $split_steps = (empty($_POST['split_steps']) || $_POST['split_steps'] == 'per_page') ? 'per_page' : 'per_chapter';
203
            $o_doc = new OpenofficeText($split_steps);
204
            $first_item_id = $o_doc->convert_document($_FILES['user_file']);
205
            Display::addFlash(Display::return_message(get_lang('UplUploadSucceeded')));
206
            break;
207
        case '':
208
        default:
209
            Display::addFlash(Display::return_message(get_lang('ScormUnknownPackageFormat'), 'warning'));
210
211
            return false;
212
            break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
213
    }
214
} elseif ($_SERVER['REQUEST_METHOD'] == 'POST' || ('bigUpload' === $_REQUEST['from'] && !empty($_REQUEST['name']))) {
215
    // end if is_uploaded_file
216
    // If file name given to get in /upload/, try importing this way.
217
    // A file upload has been detected, now deal with the file...
218
    // Directory creation.
219
    $stopping_error = false;
220
221
    // When it is used from bigupload input
222
    if ('bigUpload' === $_REQUEST['from']) {
223
        if (empty($_REQUEST['name'])) {
224
            return false;
225
        }
226
        $tempName = $_REQUEST['name'];
227
    } else {
228
        if (!isset($_POST['file_name'])) {
229
            return false;
230
        }
231
        $tempName = $_POST['file_name'];
232
    }
233
234
    // Escape path with basename so it can only be directly into the archive/ directory.
235
    $s = api_get_path(SYS_ARCHIVE_PATH).basename($tempName);
236
    // Get name of the zip file without the extension
237
    $info = pathinfo($s);
238
    $filename = $info['basename'];
239
    $extension = $info['extension'];
240
    $file_base_name = str_replace('.'.$extension, '', $filename);
241
    $new_dir = api_replace_dangerous_char(trim($file_base_name));
242
243
    $result = learnpath::verify_document_size($s);
244
    if ($result) {
245
        Display::addFlash(
246
            Display::return_message(get_lang('UplFileTooBig'))
247
        );
248
    }
249
    $type = learnpath::getPackageType($s, basename($s));
250
251
    switch ($type) {
252
        case 'chamilo':
253
            if (empty($_configuration['allow_lp_chamilo_export'])) {
254
                $is_error = true;
255
                Display::addFlash(Display::return_message(get_lang('UnknownPackageFormat'), 'error'));
256
                break;
257
            }
258
259
            $ok = chamilo_lp_import_from_zip($s, api_get_session_id());
260
            @unlink($s);
261
262
            if ($ok) {
263
                Display::addFlash(Display::return_message(get_lang('UplUploadSucceeded'), 'confirmation'));
264
            } else {
265
                $is_error = true;
266
                Display::addFlash(Display::return_message(get_lang('UploadError'), 'error'));
267
            }
268
            break;
269
        case 'scorm':
270
            $oScorm = new scorm();
271
            $manifest = $oScorm->import_local_package($s, $current_dir);
272
            // The file was treated, it can now be cleaned from the temp dir
273
            unlink($s);
274
            if (!empty($manifest)) {
275
                $oScorm->parse_manifest($manifest);
276
                $oScorm->import_manifest(api_get_course_id(), $_REQUEST['use_max_score']);
277
                Display::addFlash(Display::return_message(get_lang('UplUploadSucceeded')));
278
            }
279
280
            $proximity = '';
281
            if (!empty($_REQUEST['content_proximity'])) {
282
                $proximity = Database::escape_string($_REQUEST['content_proximity']);
283
            }
284
            $maker = '';
285
            if (!empty($_REQUEST['content_maker'])) {
286
                $maker = Database::escape_string($_REQUEST['content_maker']);
287
            }
288
            $oScorm->set_proximity($proximity);
289
            $oScorm->set_maker($maker);
290
            $oScorm->set_jslib('scorm_api.php');
291
            break;
292
        case 'aicc':
293
            $oAICC = new aicc();
294
            $config_dir = $oAICC->import_local_package($s, $current_dir);
295
            // The file was treated, it can now be cleaned from the temp dir
296
            unlink($s);
297
            if (!empty($config_dir)) {
298
                $oAICC->parse_config_files($config_dir);
299
                $oAICC->import_aicc(api_get_course_id());
300
                Display::addFlash(Display::return_message(get_lang('UplUploadSucceeded')));
301
            }
302
            $proximity = '';
303
            if (!empty($_REQUEST['content_proximity'])) {
304
                $proximity = Database::escape_string($_REQUEST['content_proximity']);
305
            }
306
            $maker = '';
307
            if (!empty($_REQUEST['content_maker'])) {
308
                $maker = Database::escape_string($_REQUEST['content_maker']);
309
            }
310
            $oAICC->set_proximity($proximity);
311
            $oAICC->set_maker($maker);
312
            $oAICC->set_jslib('aicc_api.php');
313
            break;
314
        case '':
315
        default:
316
            // There was an error, clean the file from the temp dir
317
            if (is_file($s)) {
318
                unlink($s);
319
            }
320
            Display::addFlash(
321
                Display::return_message(get_lang('ScormUnknownPackageFormat'), 'warning')
322
            );
323
324
            return false;
325
            break;
326
    }
327
}
328