Passed
Push — master ( 68f627...939207 )
by
unknown
12:17 queued 03:34
created

FolderExport   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 141
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 77
c 1
b 0
f 0
dl 0
loc 141
rs 10
wmc 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getData() 0 35 3
A export() 0 18 1
A getMimeType() 0 15 1
A createFolderXml() 0 18 1
A getFilesForFolder() 0 21 4
1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CourseBundle\Component\CourseCopy\Moodle\Activities;
8
9
use const PATHINFO_EXTENSION;
10
use const PHP_EOL;
11
12
/**
13
 * Handles the export of folders within a course.
14
 */
15
class FolderExport extends ActivityExport
16
{
17
    /**
18
     * Export a folder to the specified directory.
19
     *
20
     * @param int    $activityId the ID of the folder (0 means virtual "Documents" root)
21
     * @param string $exportDir  destination base directory of the export
22
     * @param int    $moduleId   module id used to name the activity folder
23
     * @param int    $sectionId  moodle section id where the activity will live
24
     */
25
    public function export($activityId, $exportDir, $moduleId, $sectionId): void
26
    {
27
        // Prepare destination directory for the activity
28
        $folderDir = $this->prepareActivityDirectory($exportDir, 'folder', (int) $moduleId);
29
30
        // Gather data
31
        $folderData = $this->getData((int) $activityId, (int) $sectionId);
32
33
        // Generate activity files
34
        $this->createFolderXml($folderData, $folderDir);
35
        $this->createModuleXml($folderData, $folderDir);
36
        $this->createGradesXml($folderData, $folderDir);
37
        $this->createFiltersXml($folderData, $folderDir);
38
        $this->createGradeHistoryXml($folderData, $folderDir);
39
        $this->createInforefXml($this->getFilesForFolder((int) $activityId), $folderDir);
40
        $this->createRolesXml($folderData, $folderDir);
41
        $this->createCommentsXml($folderData, $folderDir);
42
        $this->createCalendarXml($folderData, $folderDir);
43
    }
44
45
    /**
46
     * Build the data structure consumed by the XML builders.
47
     */
48
    public function getData(int $folderId, int $sectionId): ?array
49
    {
50
        // Virtual "Documents" folder at section level
51
        if (0 === $folderId) {
52
            return [
53
                'id' => 0,
54
                'moduleid' => 0,
55
                'modulename' => 'folder',
56
                'contextid' => 0,
57
                'name' => 'Documents',
58
                'sectionid' => $sectionId,
59
                'sectionnumber' => 0,
60
                'timemodified' => time(),
61
                'users' => [],
62
                'files' => [],
63
            ];
64
        }
65
66
        // Real folder coming from course resources
67
        $folder = $this->course->resources[RESOURCE_DOCUMENT][$folderId] ?? null;
68
        if (null === $folder) {
69
            return null;
70
        }
71
72
        return [
73
            'id' => $folderId,
74
            'moduleid' => (int) $folder->source_id,
75
            'modulename' => 'folder',
76
            'contextid' => (int) $folder->source_id,
77
            'name' => (string) $folder->title,
78
            'sectionid' => $sectionId,
79
            'sectionnumber' => 0,
80
            'timemodified' => time(),
81
            'users' => [],
82
            'files' => [],
83
        ];
84
    }
85
86
    /**
87
     * Write folder.xml for the activity.
88
     */
89
    private function createFolderXml(array $folderData, string $folderDir): void
90
    {
91
        $xmlContent = '<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL;
92
        $xmlContent .= '<activity id="'.$folderData['id'].'" moduleid="'.$folderData['moduleid'].'" modulename="folder" contextid="'.$folderData['contextid'].'">'.PHP_EOL;
93
        $xmlContent .= '  <folder id="'.$folderData['id'].'">'.PHP_EOL;
94
        $xmlContent .= '    <name>'.htmlspecialchars((string) $folderData['name']).'</name>'.PHP_EOL;
95
        $xmlContent .= '    <intro></intro>'.PHP_EOL;
96
        $xmlContent .= '    <introformat>1</introformat>'.PHP_EOL;
97
        $xmlContent .= '    <revision>1</revision>'.PHP_EOL;
98
        $xmlContent .= '    <timemodified>'.$folderData['timemodified'].'</timemodified>'.PHP_EOL;
99
        $xmlContent .= '    <display>0</display>'.PHP_EOL;
100
        $xmlContent .= '    <showexpanded>1</showexpanded>'.PHP_EOL;
101
        $xmlContent .= '    <showdownloadfolder>1</showdownloadfolder>'.PHP_EOL;
102
        $xmlContent .= '    <forcedownload>1</forcedownload>'.PHP_EOL;
103
        $xmlContent .= '  </folder>'.PHP_EOL;
104
        $xmlContent .= '</activity>';
105
106
        $this->createXmlFile('folder', $xmlContent, $folderDir);
107
    }
108
109
    /**
110
     * List files included under the exported folder.
111
     * For folderId=0 we include all root-level documents (Documents root).
112
     *
113
     * @return array{users: array<int>, files: array<int,array<string,int|string>>}
114
     */
115
    private function getFilesForFolder(int $folderId): array
116
    {
117
        $files = [];
118
119
        if (0 === $folderId) {
120
            $docBucket = $this->course->resources[RESOURCE_DOCUMENT] ?? [];
121
            foreach ($docBucket as $doc) {
122
                if (($doc->file_type ?? '') === 'file') {
123
                    $files[] = [
124
                        'id' => (int) $doc->source_id,
125
                        'contenthash' => hash('sha1', basename((string) $doc->path)),
126
                        'filename' => basename((string) $doc->path),
127
                        'filepath' => '/Documents/',
128
                        'filesize' => (int) $doc->size,
129
                        'mimetype' => $this->getMimeType((string) $doc->path),
130
                    ];
131
                }
132
            }
133
        }
134
135
        return ['users' => [], 'files' => $files];
136
    }
137
138
    /**
139
     * Basic mimetype resolver for common extensions.
140
     */
141
    private function getMimeType(string $filename): string
142
    {
143
        $ext = strtolower((string) pathinfo($filename, PATHINFO_EXTENSION));
144
        $mimetypes = [
145
            'pdf' => 'application/pdf',
146
            'png' => 'image/png',
147
            'jpg' => 'image/jpeg',
148
            'jpeg' => 'image/jpeg',
149
            'doc' => 'application/msword',
150
            'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
151
            'txt' => 'text/plain',
152
            'html' => 'text/html',
153
        ];
154
155
        return $mimetypes[$ext] ?? 'application/octet-stream';
156
    }
157
}
158