Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
/**
17
 * @package   moodlecore
18
 * @subpackage backup-imscc
19
 * @copyright 2009 Mauro Rondinelli (mauro.rondinelli [AT] uvcms.com)
20
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
21
 */
22
 
23
defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
24
 
25
require_once($CFG->dirroot . '/backup/cc/entities.class.php');
26
require_once($CFG->dirroot . '/backup/cc/entity.label.class.php');
27
require_once($CFG->dirroot . '/backup/cc/entity.resource.class.php');
28
require_once($CFG->dirroot . '/backup/cc/entity.forum.class.php');
29
require_once($CFG->dirroot . '/backup/cc/entity.quiz.class.php');
30
 
31
class cc2moodle {
32
 
33
    const CC_TYPE_FORUM              = 'imsdt_xmlv1p0';
34
    const CC_TYPE_QUIZ               = 'imsqti_xmlv1p2/imscc_xmlv1p0/assessment';
35
    const CC_TYPE_QUESTION_BANK      = 'imsqti_xmlv1p2/imscc_xmlv1p0/question-bank';
36
    const CC_TYPE_WEBLINK            = 'imswl_xmlv1p0';
37
    const CC_TYPE_WEBCONTENT         = 'webcontent';
38
    const CC_TYPE_ASSOCIATED_CONTENT = 'associatedcontent/imscc_xmlv1p0/learning-application-resource';
39
    const CC_TYPE_EMPTY              = '';
40
 
41
    public static $restypes = array('associatedcontent/imscc_xmlv1p0/learning-application-resource', 'webcontent');
42
    public static $forumns  = array('dt' => 'http://www.imsglobal.org/xsd/imsdt_v1p0');
43
    public static $quizns   = array('xmlns' => 'http://www.imsglobal.org/xsd/ims_qtiasiv1p2');
44
    public static $resourcens = array('wl' => 'http://www.imsglobal.org/xsd/imswl_v1p0');
45
    /**
46
     *
47
     * @return array
48
     */
49
    public static function getquizns() {
50
        return static::$quizns;
51
    }
52
 
53
    /**
54
     *
55
     * @return array
56
     */
57
    public static function getforumns() {
58
        return static::$forumns;
59
    }
60
 
61
    /**
62
     *
63
     * @return array
64
     */
65
    public static function getresourcens() {
66
        return static::$resourcens;
67
    }
68
 
69
    public static function get_manifest($folder) {
70
        if (!is_dir($folder)) {
71
            return false;
72
        }
73
 
74
        // Before iterate over directories, try to find one manifest at top level
75
        if (file_exists($folder . '/imsmanifest.xml')) {
76
            return $folder . '/imsmanifest.xml';
77
        }
78
 
79
        $result = false;
80
        try {
81
            $dirIter = new RecursiveDirectoryIterator($folder, RecursiveDirectoryIterator::KEY_AS_PATHNAME);
82
            $recIter = new RecursiveIteratorIterator($dirIter, RecursiveIteratorIterator::CHILD_FIRST);
83
            foreach ($recIter as $info) {
84
                if ($info->isFile() && ($info->getFilename() == 'imsmanifest.xml')) {
85
                    $result = $info->getPathname();
86
                    break;
87
                }
88
            }
89
        } catch (Exception $e) {}
90
 
91
        return $result;
92
    }
93
 
94
    public static $instances = array();
95
    public static $manifest;
96
    public static $path_to_manifest_folder;
97
 
98
    public static $namespaces = array('imscc'    => 'http://www.imsglobal.org/xsd/imscc/imscp_v1p1',
99
                                      'lomimscc' => 'http://ltsc.ieee.org/xsd/imscc/LOM',
100
                                      'lom'      => 'http://ltsc.ieee.org/xsd/LOM',
101
                                      'voc'      => 'http://ltsc.ieee.org/xsd/LOM/vocab',
102
                                      'xsi'      => 'http://www.w3.org/2001/XMLSchema-instance',
103
                                      'cc'       => 'http://www.imsglobal.org/xsd/imsccauth_v1p0');
104
 
105
    function __construct($path_to_manifest) {
106
 
107
        static::$manifest = new DOMDocument();
108
        static::$manifest->validateOnParse = false;
109
 
110
        static::$path_to_manifest_folder = dirname($path_to_manifest);
111
 
112
        static::log_action('Proccess start');
113
        static::log_action('Load the manifest file: ' . $path_to_manifest);
114
 
115
        if (!static::$manifest->load($path_to_manifest, LIBXML_NONET)) {
116
            static::log_action('Cannot load the manifest file: ' . $path_to_manifest, true);
117
        }
118
    }
119
 
120
    public function is_auth() {
121
 
122
        $xpath = static::newx_path(static::$manifest, static::$namespaces);
123
 
124
        $count_auth = $xpath->evaluate('count(/imscc:manifest/cc:authorizations)');
125
 
126
        if ($count_auth > 0) {
127
            $response = true;
128
        } else {
129
            $response = false;
130
        }
131
 
132
        return $response;
133
    }
134
 
135
    protected function get_metadata($section, $key) {
136
 
137
        $xpath = static::newx_path(static::$manifest, static::$namespaces);
138
 
139
        $metadata = $xpath->query('/imscc:manifest/imscc:metadata/lomimscc:lom/lomimscc:' . $section . '/lomimscc:' . $key . '/lomimscc:string');
140
        $value = !empty($metadata->item(0)->nodeValue) ? $metadata->item(0)->nodeValue : '';
141
 
142
        return $value;
143
    }
144
 
145
    public function generate_moodle_xml() {
146
 
147
        global $CFG, $OUTPUT;
148
 
149
        $cdir = static::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'course_files';
150
 
151
        if (!file_exists($cdir)) {
152
            mkdir($cdir, $CFG->directorypermissions, true);
153
        }
154
 
155
        $sheet_base = static::loadsheet(SHEET_BASE);
156
 
157
        // MOODLE_BACKUP / INFO / DETAILS / MOD
158
        $node_info_details_mod = $this->create_code_info_details_mod();
159
 
160
        // MOODLE_BACKUP / BLOCKS / BLOCK
161
        $node_course_blocks_block = $this->create_node_course_blocks_block();
162
 
163
        // MOODLE_BACKUP / COURSES / SECTIONS / SECTION
164
        $node_course_sections_section = $this->create_node_course_sections_section();
165
 
166
        // MOODLE_BACKUP / COURSES / QUESTION_CATEGORIES
167
        $node_course_question_categories = $this->create_node_question_categories();
168
 
169
        // MOODLE_BACKUP / COURSES / MODULES / MOD
170
        $node_course_modules_mod = $this->create_node_course_modules_mod();
171
 
172
        // MOODLE_BACKUP / COURSE / HEADER
173
        $node_course_header = $this->create_node_course_header();
174
 
175
        // GENERAL INFO
176
        $filename = optional_param('file', 'not_available.zip', PARAM_RAW);
177
        $filename = basename($filename);
178
 
179
        $www_root = $CFG->wwwroot;
180
 
181
        $find_tags = array('[#zip_filename#]',
182
                           '[#www_root#]',
183
                           '[#node_course_header#]',
184
                           '[#node_info_details_mod#]',
185
                           '[#node_course_blocks_block#]',
186
                           '[#node_course_sections_section#]',
187
                           '[#node_course_question_categories#]',
188
                           '[#node_course_modules#]');
189
 
190
        $replace_values = array($filename,
191
                                $www_root,
192
                                $node_course_header,
193
                                $node_info_details_mod,
194
                                $node_course_blocks_block,
195
                                $node_course_sections_section,
196
                                $node_course_question_categories,
197
                                $node_course_modules_mod);
198
 
199
        $result_xml = str_replace($find_tags, $replace_values, $sheet_base);
200
 
201
        // COPY RESOURSE FILES
202
        $entities = new entities();
203
 
204
        $entities->move_all_files();
205
 
206
        if (array_key_exists("index", self::$instances)) {
207
 
208
            if (!file_put_contents(static::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'moodle.xml', $result_xml)) {
209
                static::log_action('Cannot save the moodle manifest file: ' . static::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'moodle.xml', true);
210
            } else {
211
                $status = true;
212
            }
213
 
214
        } else {
215
            $status = false;
216
            echo $OUTPUT->notification('The course is empty');
217
            static::log_action('The course is empty', false);
218
        }
219
 
220
        return $status;
221
 
222
    }
223
 
224
    protected function get_sections_numbers($instances) {
225
 
226
        $count = 0;
227
 
228
        if (array_key_exists("index", $instances)) {
229
            foreach ($instances["index"] as $instance) {
230
                if ($instance["deep"] == ROOT_DEEP) {
231
                    $count++;
232
                }
233
            }
234
        }
235
 
236
        return $count;
237
    }
238
 
239
    protected function create_node_course_header() {
240
 
241
        $node_course_header = '';
242
        $sheet_course_header = static::loadsheet(SHEET_COURSE_HEADER);
243
 
244
        $course_title = trim($this->get_metadata('general', 'title'));
245
        $course_title = empty($course_title) ? 'Untitled Course' : $course_title;
246
        $course_description = $this->get_metadata('general', 'description');
247
        $section_count = $this->get_sections_numbers(static::$instances) - 1;
248
 
249
        if ($section_count == -1) {
250
            $section_count = 0;
251
        }
252
 
253
        if (empty($course_title)) {
254
            $this->log_action('The course title not found', true);
255
        }
256
 
257
        $course_short_name = $this->create_course_code($course_title);
258
 
259
        $find_tags = array('[#course_name#]',
260
                           '[#course_short_name#]',
261
                           '[#course_description#]',
262
                           '[#date_now#]',
263
                           '[#section_count#]');
264
 
265
        $replace_values = array(entities::safexml($course_title),
266
                                entities::safexml($course_short_name),
267
                                entities::safexml($course_description),
268
                                time(),
269
                                $section_count);
270
 
271
        $node_course_header = str_replace($find_tags, $replace_values, $sheet_course_header);
272
 
273
        return $node_course_header;
274
    }
275
 
276
    protected function create_node_question_categories() {
277
 
278
        $quiz = new cc_quiz();
279
 
280
        static::log_action('Creating node: QUESTION_CATEGORIES');
281
 
282
        $node_course_question_categories = $quiz->generate_node_question_categories();
283
 
284
        return $node_course_question_categories;
285
    }
286
 
287
    protected function create_node_course_modules_mod() {
288
 
289
        $labels = new cc_label();
290
        $resources = new cc_resource();
291
        $forums = new cc_forum();
292
        $quiz = new cc_quiz();
293
 
294
        static::log_action('Creating node: COURSE/MODULES/MOD');
295
 
296
        // LABELS
297
        $node_course_modules_mod_label = $labels->generate_node();
298
 
299
        // RESOURCES (WEB CONTENT AND WEB LINK)
300
        $node_course_modules_mod_resource = $resources->generate_node();
301
 
302
        // FORUMS
303
        $node_course_modules_mod_forum = $forums->generate_node();
304
 
305
        // QUIZ
306
        $node_course_modules_mod_quiz = $quiz->generate_node_course_modules_mod();
307
        //TODO: label
308
        $node_course_modules = $node_course_modules_mod_label . $node_course_modules_mod_resource . $node_course_modules_mod_forum . $node_course_modules_mod_quiz;
309
 
310
        return $node_course_modules;
311
    }
312
 
313
 
314
    protected function create_node_course_sections_section() {
315
 
316
        static::log_action('Creating node: COURSE/SECTIONS/SECTION');
317
 
318
        $node_course_sections_section = '';
319
        $sheet_course_sections_section = static::loadsheet(SHEET_COURSE_SECTIONS_SECTION);
320
 
321
        $topics = $this->get_nodes_by_criteria('deep', ROOT_DEEP);
322
 
323
        $i = 0;
324
 
325
        if (!empty($topics)) {
326
 
327
            foreach ($topics as $topic) {
328
 
329
                $i++;
330
                $node_node_course_sections_section_mods_mod = $this->create_node_course_sections_section_mods_mod($topic['index']);
331
 
332
                if ($topic['moodle_type'] == MOODLE_TYPE_LABEL) {
333
 
334
                    $find_tags = array('[#section_id#]',
335
                                       '[#section_number#]',
336
                                       '[#section_summary#]',
337
                                       '[#node_course_sections_section_mods_mod#]');
338
 
339
                    $replace_values = array($i,
340
                                            $i - 1,
341
                                            entities::safexml($topic['title']),
342
                                            $node_node_course_sections_section_mods_mod);
343
 
344
                } else {
345
 
346
                    $find_tags = array('[#section_id#]',
347
                                       '[#section_number#]',
348
                                       '[#section_summary#]',
349
                                       '[#node_course_sections_section_mods_mod#]');
350
 
351
                    $replace_values = array($i,
352
                                            $i - 1,
353
                                            '',
354
                                            $node_node_course_sections_section_mods_mod);
355
 
356
                }
357
 
358
                $node_course_sections_section .= str_replace($find_tags, $replace_values, $sheet_course_sections_section);
359
            }
360
        }
361
 
362
 
363
        return $node_course_sections_section;
364
    }
365
 
366
    protected function create_node_course_blocks_block() {
367
 
368
        global $CFG;
369
 
370
        static::log_action('Creating node: COURSE/BLOCKS/BLOCK');
371
 
372
        $sheet_course_blocks_block = static::loadsheet(SHEET_COURSE_BLOCKS_BLOCK);
373
        $node_course_blocks_block = '';
374
 
375
        $format_config = $CFG->dirroot . '/course/format/weeks/config.php';
376
 
377
        if (@is_file($format_config) && is_readable($format_config)) {
378
            require ($format_config);
379
        }
380
 
381
        if (!empty($format['defaultblocks'])) {
382
            $blocknames = $format['defaultblocks'];
383
        } else {
384
            if (isset($CFG->defaultblocks)) {
385
                $blocknames = $CFG->defaultblocks;
386
            } else {
387
                $blocknames = 'activity_modules,search_forums,course_list:news_items,calendar_upcoming,recent_activity';
388
            }
389
        }
390
 
391
        $blocknames = explode(':', $blocknames);
392
        $blocks_left = explode(',', $blocknames[0]);
393
        $blocks_right = explode(',', $blocknames[1]);
394
 
395
        $find_tags = array('[#block_id#]',
396
                           '[#block_name#]',
397
                           '[#block_position#]',
398
                           '[#block_weight#]');
399
 
400
        $i = 0;
401
        $weight = 0;
402
 
403
        foreach ($blocks_left as $block) {
404
            $i++;
405
            $weight++;
406
 
407
            $replace_values = array($i,
408
                                    $block,
409
                                    'l',
410
                                    $weight);
411
 
412
            $node_course_blocks_block .= str_replace($find_tags, $replace_values, $sheet_course_blocks_block);
413
        }
414
 
415
        $weight = 0;
416
 
417
        foreach ($blocks_right as $block) {
418
 
419
            $i++;
420
            $weight ++;
421
 
422
            $replace_values = array($i,
423
                                    $block,
424
                                    'r',
425
                                    $weight);
426
 
427
            $node_course_blocks_block .= str_replace($find_tags, $replace_values, $sheet_course_blocks_block);
428
        }
429
 
430
        return $node_course_blocks_block;
431
 
432
    }
433
 
434
    /**
435
    *
436
    * Is activity visible or not
437
    * @param string $identifier
438
    * @return number
439
    */
440
    protected function get_module_visible($identifier) {
441
        //Should item be hidden or not
442
        $mod_visible = 1;
443
        if (!empty($identifier)) {
444
            $xpath = static::newx_path(static::$manifest, static::$namespaces);
445
            $query  = '/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . $identifier . '"]';
446
            $query .= '//lom:intendedEndUserRole/voc:vocabulary/lom:value';
447
            $intendeduserrole = $xpath->query($query);
448
            if (!empty($intendeduserrole) && ($intendeduserrole->length > 0)) {
449
                $role = trim($intendeduserrole->item(0)->nodeValue);
450
                if (strcasecmp('Instructor', $role) == 0) {
451
                    $mod_visible = 0;
452
                }
453
            }
454
        }
455
        return $mod_visible;
456
    }
457
 
458
    protected function create_node_course_sections_section_mods_mod($root_parent) {
459
 
460
        $sheet_course_sections_section_mods_mod = static::loadsheet(SHEET_COURSE_SECTIONS_SECTION_MODS_MOD);
461
        $childs = $this->get_nodes_by_criteria('root_parent', $root_parent);
462
 
463
        if ($childs) {
464
 
465
            $node_course_sections_section_mods_mod = '';
466
 
467
            foreach ($childs as $child) {
468
 
469
                if ($child['moodle_type'] == MOODLE_TYPE_LABEL) {
470
                    if ($child['index'] == $child['root_parent']) {
471
                        $is_summary = true;
472
                    } else {
473
                        $is_summary = false;
474
                    }
475
                } else {
476
                    $is_summary = false;
477
                }
478
 
479
                if (!$is_summary) {
480
 
481
                    $indent = $child['deep'] - ROOT_DEEP;
482
 
483
                    if ($indent > 0) {
484
                        $indent = $indent - 1;
485
                    }
486
 
487
                    $find_tags = array('[#mod_id#]',
488
                                       '[#mod_instance_id#]',
489
                                       '[#mod_type#]',
490
                                       '[#date_now#]',
491
                                       '[#mod_indent#]',
492
                                       '[#mod_visible#]');
493
 
494
                    $replace_values = array($child['index'],
495
                                            $child['instance'],
496
                                            $child['moodle_type'],
497
                                            time(),
498
                                            $indent,
499
                                            $this->get_module_visible($child['resource_indentifier']));
500
 
501
                    $node_course_sections_section_mods_mod .= str_replace($find_tags, $replace_values, $sheet_course_sections_section_mods_mod);
502
                }
503
            }
504
 
505
            $response = $node_course_sections_section_mods_mod;
506
 
507
        } else {
508
            $response = '';
509
        }
510
 
511
        return $response;
512
 
513
    }
514
 
515
    public function get_nodes_by_criteria($key, $value) {
516
 
517
        $response = array();
518
 
519
        if (array_key_exists('index', static::$instances)) {
520
            foreach (static::$instances['index'] as $item) {
521
                if ($item[$key] == $value) {
522
                    $response[] = $item;
523
                }
524
            }
525
        }
526
 
527
        return $response;
528
    }
529
 
530
    //Modified here
531
    protected function create_code_info_details_mod() {
532
 
533
        static::log_action('Creating node: INFO/DETAILS/MOD');
534
 
535
        $xpath = static::newx_path(static::$manifest, static::$namespaces);
536
 
537
        $items = $xpath->query('/imscc:manifest/imscc:organizations/imscc:organization/imscc:item | /imscc:manifest/imscc:resources/imscc:resource[@type="' . static::CC_TYPE_QUESTION_BANK . '"]');
538
 
539
        $this->create_instances($items);
540
 
541
        $count_quiz = $this->count_instances(MOODLE_TYPE_QUIZ);
542
        $count_forum = $this->count_instances(MOODLE_TYPE_FORUM);
543
        $count_resource = $this->count_instances(MOODLE_TYPE_RESOURCE);
544
        $count_label = $this->count_instances(MOODLE_TYPE_LABEL);
545
 
546
        $sheet_info_details_mod_instances_instance = static::loadsheet(SHEET_INFO_DETAILS_MOD_INSTANCE);
547
 
548
        if ($count_resource > 0) {
549
            $resource_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_resource, static::$instances['instances'][MOODLE_TYPE_RESOURCE]);
550
        }
551
        if ($count_quiz > 0) {
552
            $quiz_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_quiz, static::$instances['instances'][MOODLE_TYPE_QUIZ]);
553
        }
554
        if ($count_forum > 0) {
555
            $forum_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_forum, static::$instances['instances'][MOODLE_TYPE_FORUM]);
556
        }
557
        if ($count_label > 0) {
558
            $label_instance = $this->create_mod_info_details_mod_instances_instance($sheet_info_details_mod_instances_instance, $count_label, static::$instances['instances'][MOODLE_TYPE_LABEL]);
559
        }
560
 
561
        $resource_mod = $count_resource ? $this->create_mod_info_details_mod(MOODLE_TYPE_RESOURCE, $resource_instance) : '';
562
        $quiz_mod = $count_quiz ? $this->create_mod_info_details_mod(MOODLE_TYPE_QUIZ, $quiz_instance) : '';
563
        $forum_mod = $count_forum ? $this->create_mod_info_details_mod(MOODLE_TYPE_FORUM, $forum_instance) : '';
564
        $label_mod = $count_label ? $this->create_mod_info_details_mod(MOODLE_TYPE_LABEL, $label_instance) : '';
565
 
566
        //TODO: label
567
        return $label_mod . $resource_mod . $quiz_mod . $forum_mod;
568
 
569
    }
570
 
571
    protected function create_mod_info_details_mod($mod_type, $node_info_details_mod_instances_instance) {
572
 
573
        $sheet_info_details_mod = static::loadsheet(SHEET_INFO_DETAILS_MOD);
574
 
575
        $find_tags = array('[#mod_type#]' ,'[#node_info_details_mod_instances_instance#]');
576
        $replace_values = array($mod_type , $node_info_details_mod_instances_instance);
577
 
578
        return str_replace($find_tags, $replace_values, $sheet_info_details_mod);
579
    }
580
 
581
    protected function create_mod_info_details_mod_instances_instance($sheet, $instances_quantity, $instances) {
582
 
583
        $instance = '';
584
 
585
        $find_tags = array('[#mod_instance_id#]',
586
                           '[#mod_name#]',
587
                           '[#mod_user_info#]');
588
 
589
        for ($i = 1; $i <= $instances_quantity; $i++) {
590
 
591
            $user_info = ($instances[$i - 1]['common_cartriedge_type'] == static::CC_TYPE_FORUM) ? 'true' : 'false';
592
            if ($instances[$i - 1]['common_cartriedge_type'] == static::CC_TYPE_EMPTY) {
593
                if ($instances[$i - 1]['deep'] <= ROOT_DEEP ) {
594
                    continue;
595
                }
596
            }
597
 
598
            $replace_values = array($instances[$i - 1]['instance'],
599
                                    entities::safexml($instances[$i - 1]['title']),
600
                                    $user_info);
601
 
602
            $instance .= str_replace($find_tags, $replace_values, $sheet);
603
        }
604
 
605
        return $instance;
606
 
607
    }
608
 
609
    protected function create_instances($items, $level = 0, &$array_index = 0, $index_root = 0) {
610
 
611
        $level++;
612
        $i = 1;
613
 
614
        if ($items) {
615
 
616
            $xpath = self::newx_path(static::$manifest, static::$namespaces);
617
 
618
            foreach ($items as $item) {
619
 
620
                $array_index++;
621
 
622
                if ($item->nodeName == "item")  {
623
                    $identifierref = '';
624
                    if ($item->hasAttribute('identifierref')) {
625
                      $identifierref = $item->getAttribute('identifierref');
626
                    }
627
 
628
                    $title = '';
629
                    $titles = $xpath->query('imscc:title', $item);
630
                    if ($titles->length > 0) {
631
                        $title = $titles->item(0)->nodeValue;
632
                    }
633
 
634
                    $cc_type = $this->get_item_cc_type($identifierref);
635
                    $moodle_type = $this->convert_to_moodle_type($cc_type);
636
                    //Fix the label issue - MDL-33523
637
                    if (empty($identifierref) && empty($title)) {
638
                      $moodle_type = TYPE_UNKNOWN;
639
                    }
640
                }
641
                elseif ($item->nodeName == "resource")  {
642
 
643
                    $identifierref = $xpath->query('@identifier', $item);
644
                    $identifierref = !empty($identifierref->item(0)->nodeValue) ? $identifierref->item(0)->nodeValue : '';
645
 
646
                    $cc_type = $this->get_item_cc_type($identifierref);
647
                    $moodle_type = $this->convert_to_moodle_type($cc_type);
648
 
649
                    $title = 'Quiz Bank ' . ($this->count_instances($moodle_type) + 1);
650
 
651
                }
652
 
653
                if ($level == ROOT_DEEP) {
654
                    $index_root = $array_index;
655
                }
656
 
657
                static::$instances['index'][$array_index]['common_cartriedge_type'] = $cc_type;
658
                static::$instances['index'][$array_index]['moodle_type'] = $moodle_type;
659
                static::$instances['index'][$array_index]['title'] = $title ? $title : '';
660
                static::$instances['index'][$array_index]['root_parent'] = $index_root;
661
                static::$instances['index'][$array_index]['index'] = $array_index;
662
                static::$instances['index'][$array_index]['deep'] = $level;
663
                static::$instances['index'][$array_index]['instance'] = $this->count_instances($moodle_type);
664
                static::$instances['index'][$array_index]['resource_indentifier'] = $identifierref;
665
 
666
                static::$instances['instances'][$moodle_type][] = array('title' => $title,
667
                                                                        'instance' => static::$instances['index'][$array_index]['instance'],
668
                                                                        'common_cartriedge_type' => $cc_type,
669
                                                                        'resource_indentifier' => $identifierref,
670
                                                                        'deep' => $level);
671
 
672
                $more_items = $xpath->query('imscc:item', $item);
673
 
674
                if ($more_items->length > 0) {
675
                    $this->create_instances($more_items, $level, $array_index, $index_root);
676
                }
677
 
678
                $i++;
679
 
680
            }
681
        }
682
    }
683
 
684
    public function count_instances($type) {
685
 
686
        $quantity = 0;
687
 
688
        if (array_key_exists('index', static::$instances)) {
689
            if (static::$instances['index'] && $type) {
690
 
691
                foreach (static::$instances['index'] as $instance) {
692
                    if (!empty($instance['moodle_type'])) {
693
                        $types[] = $instance['moodle_type'];
694
                    }
695
                }
696
 
697
                $quantity_instances = array_count_values($types);
698
                $quantity = array_key_exists($type, $quantity_instances) ? $quantity_instances[$type] : 0;
699
            }
700
        }
701
 
702
        return $quantity;
703
    }
704
 
705
    public function convert_to_moodle_type($cc_type) {
706
        $type = TYPE_UNKNOWN;
707
 
708
        if ($cc_type == static::CC_TYPE_FORUM) {
709
            $type = MOODLE_TYPE_FORUM;
710
        }
711
 
712
        if ($cc_type == static::CC_TYPE_QUIZ) {
713
            $type = MOODLE_TYPE_QUIZ;
714
        }
715
 
716
        if ($cc_type == static::CC_TYPE_WEBLINK) {
717
            $type = MOODLE_TYPE_RESOURCE;
718
        }
719
 
720
        if ($cc_type == static::CC_TYPE_WEBCONTENT) {
721
            $type = MOODLE_TYPE_RESOURCE;
722
        }
723
 
724
        if ($cc_type == static::CC_TYPE_ASSOCIATED_CONTENT) {
725
            $type = MOODLE_TYPE_RESOURCE;
726
        }
727
 
728
        if ($cc_type == static::CC_TYPE_QUESTION_BANK) {
729
            $type = MOODLE_TYPE_QUESTION_BANK;
730
        }
731
        //TODO: label
732
        if ($cc_type == static::CC_TYPE_EMPTY) {
733
            $type = MOODLE_TYPE_LABEL;
734
        }
735
 
736
        return $type;
737
    }
738
 
739
    public function get_item_cc_type($identifier) {
740
 
741
        $xpath = static::newx_path(static::$manifest, static::$namespaces);
742
 
743
        $nodes = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . $identifier . '"]/@type');
744
 
745
        if ($nodes && !empty($nodes->item(0)->nodeValue)) {
746
            return $nodes->item(0)->nodeValue;
747
        } else {
748
            return '';
749
        }
750
    }
751
 
752
    public static function newx_path(DOMDocument $manifest, $namespaces = '') {
753
 
754
        $xpath = new DOMXPath($manifest);
755
 
756
        if (!empty($namespaces)) {
757
            foreach ($namespaces as $prefix => $ns) {
758
                if (!$xpath->registerNamespace($prefix, $ns)) {
759
                    static::log_action('Cannot register the namespace: ' . $prefix . ':' . $ns, true);
760
                }
761
            }
762
        }
763
 
764
        return $xpath;
765
    }
766
 
767
    public static function loadsheet($file) {
768
 
769
        $content = (is_readable($file) && ($content = file_get_contents($file))) ? $content : false;
770
 
771
        static::log_action('Loading sheet: ' . $file);
772
 
773
        if (!$content) {
774
            static::log_action('Cannot load the xml sheet: ' . $file, true);
775
        }
776
 
777
        static::log_action('Load OK!');
778
 
779
        return $content;
780
    }
781
 
782
    public static function log_file() {
783
        return static::$path_to_manifest_folder . DIRECTORY_SEPARATOR . 'cc2moodle.log';
784
    }
785
 
786
    public static function log_action($text, $critical_error = false) {
787
 
788
        $full_message = strtoupper(date("j/n/Y g:i:s a")) . " - " . $text . "\r";
789
 
790
        file_put_contents(static::log_file(), $full_message, FILE_APPEND);
791
 
792
        if ($critical_error) {
793
            static::critical_error($text);
794
        }
795
    }
796
 
797
    protected static function critical_error($text) {
798
 
799
        $path_to_log = static::log_file();
800
 
801
        echo '
802
 
803
        <p>
804
        <hr />A critical error has been found!
805
 
806
        <p>' . $text . '</p>
807
 
808
 
809
        <p>
810
        The process has been stopped. Please see the <a href="' . $path_to_log . '">log file</a> for more information.</p>
811
 
812
        <p>Log: ' . $path_to_log . '</p>
813
 
814
        <hr />
815
 
816
        </p>
817
        ';
818
 
819
        die();
820
    }
821
 
822
    protected function create_course_code($title) {
823
        //Making sure that text of the short name does not go over the DB limit.
824
        //and leaving the space to add additional characters by the platform
825
        $code = substr(strtoupper(str_replace(' ', '', trim($title))),0,94);
826
        return $code;
827
    }
828
}