Skip to content

Commit 3967504

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents d9d4376 + 680ccf9 commit 3967504

File tree

3 files changed

+67
-35
lines changed

3 files changed

+67
-35
lines changed

assets/vue/composables/fileUtils.js

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,52 @@
11
export function useFileUtils() {
22
const isFile = (fileData) => {
3-
return fileData.resourceNode && fileData.resourceNode.firstResourceFile
3+
return !!fileData?.resourceNode?.firstResourceFile
4+
}
5+
6+
const safeMime = (fileData) => {
7+
// normalize: strip params like "; charset=UTF-8"
8+
const raw = fileData?.resourceNode?.firstResourceFile?.mimeType || ""
9+
return String(raw).split(";")[0].trim()
10+
}
11+
12+
const fileName = (fileData) => {
13+
// prefer originalName; fallback to node title
14+
return fileData?.resourceNode?.firstResourceFile?.originalName || fileData?.resourceNode?.title || ""
15+
}
16+
17+
const ext = (fileData) => {
18+
const name = fileName(fileData)
19+
const m = /\.([A-Za-z0-9]+)$/.exec(name)
20+
return m ? m[1].toLowerCase() : ""
421
}
522

623
const isImage = (fileData) => {
7-
return isFile(fileData) && fileData.resourceNode.firstResourceFile.image
24+
return isFile(fileData) && !!fileData.resourceNode.firstResourceFile.image
825
}
926

1027
const isVideo = (fileData) => {
11-
return isFile(fileData) && fileData.resourceNode.firstResourceFile.video
28+
return isFile(fileData) && !!fileData.resourceNode.firstResourceFile.video
1229
}
1330

1431
const isAudio = (fileData) => {
15-
const mimeType = fileData.resourceNode.firstResourceFile.mimeType
16-
return isFile(fileData) && mimeType.split("/")[0].toLowerCase() === "audio"
32+
if (!isFile(fileData)) return false
33+
const top = safeMime(fileData).split("/")[0]?.toLowerCase() || ""
34+
return top === "audio" || !!fileData.resourceNode.firstResourceFile.audio
1735
}
1836

1937
const isHtml = (fileData) => {
20-
if (!isFile(fileData)) {
21-
return false
22-
}
23-
const mimeType = fileData.resourceNode.firstResourceFile.mimeType || ""
24-
const [type, sub] = mimeType.split("/")
25-
return (type?.toLowerCase() === "text" && sub?.toLowerCase() === "html") || sub?.toLowerCase() === "html"
38+
if (!isFile(fileData)) return false
39+
40+
const mime = safeMime(fileData).toLowerCase()
41+
const e = ext(fileData)
42+
43+
// MIME-based detection
44+
const byMime = mime.includes("text/html") || mime.includes("application/html") || mime.includes("application/xhtml")
45+
46+
// Extension-based fallback when MIME is missing/wrong
47+
const byExt = e === "html" || e === "htm" || e === "xhtml"
48+
49+
return byMime || byExt
2650
}
2751

2852
const isPreviewable = (fileData) => {

src/CoreBundle/Controller/ResourceController.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,13 +589,21 @@ private function processFile(Request $request, ResourceNode $resourceNode, strin
589589

590590
$fileName = $resourceFile->getOriginalName();
591591
$fileSize = $resourceFile->getSize();
592-
$mimeType = $resourceFile->getMimeType();
592+
$mimeType = $resourceFile->getMimeType() ?: '';
593593
[$start, $end, $length] = $this->getRange($request, $fileSize);
594594
$resourceNodeRepo = $this->getResourceNodeRepository();
595595

596596
// Convert the file name to ASCII using iconv
597597
$fileName = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $fileName);
598598

599+
// MIME normalization for HTML
600+
$looksLikeHtmlByExt = (bool) preg_match('/\.x?html?$/i', (string) $fileName);
601+
if ($mimeType === '' || stripos($mimeType, 'html') === false) {
602+
if ($looksLikeHtmlByExt) {
603+
$mimeType = 'text/html; charset=UTF-8';
604+
}
605+
}
606+
599607
switch ($mode) {
600608
case 'download':
601609
$forceDownload = true;
@@ -652,7 +660,7 @@ private function processFile(Request $request, ResourceNode $resourceNode, strin
652660
$fileName
653661
);
654662
$response->headers->set('Content-Disposition', $disposition);
655-
$response->headers->set('Content-Type', 'text/html');
663+
$response->headers->set('Content-Type', 'text/html; charset=UTF-8');
656664

657665
// @todo move into a function/class
658666
if ('true' === $this->getSettingsManager()->getSetting('editor.translate_html')) {

src/CourseBundle/Component/CourseCopy/CourseBuilder.php

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ public function build(
464464
*
465465
* @param array<int> $ids
466466
*/
467-
private function build_learnpath_category(
467+
public function build_learnpath_category(
468468
object $legacyCourse,
469469
?CourseEntity $courseEntity,
470470
?SessionEntity $sessionEntity,
@@ -505,7 +505,7 @@ private function build_learnpath_category(
505505
*
506506
* @param array<int> $idList
507507
*/
508-
private function build_learnpaths(
508+
public function build_learnpaths(
509509
object $legacyCourse,
510510
?CourseEntity $courseEntity,
511511
?SessionEntity $sessionEntity,
@@ -616,7 +616,7 @@ private function build_learnpaths(
616616
/**
617617
* Export Gradebook (categories + evaluations + links).
618618
*/
619-
private function build_gradebook(
619+
public function build_gradebook(
620620
object $legacyCourse,
621621
?CourseEntity $courseEntity,
622622
?SessionEntity $sessionEntity
@@ -729,7 +729,7 @@ private function serializeGradebookCategory(GradebookCategory $c): array
729729
*
730730
* @param array<int> $ids
731731
*/
732-
private function build_works(
732+
public function build_works(
733733
object $legacyCourse,
734734
?CourseEntity $courseEntity,
735735
?SessionEntity $sessionEntity,
@@ -801,7 +801,7 @@ private function build_works(
801801
*
802802
* @param array<int> $ids
803803
*/
804-
private function build_attendance(
804+
public function build_attendance(
805805
object $legacyCourse,
806806
?CourseEntity $courseEntity,
807807
?SessionEntity $sessionEntity,
@@ -867,7 +867,7 @@ private function build_attendance(
867867
*
868868
* @param array<int> $ids
869869
*/
870-
private function build_thematic(
870+
public function build_thematic(
871871
object $legacyCourse,
872872
?CourseEntity $courseEntity,
873873
?SessionEntity $sessionEntity,
@@ -959,7 +959,7 @@ private function build_thematic(
959959
*
960960
* @param array<int> $ids
961961
*/
962-
private function build_wiki(
962+
public function build_wiki(
963963
object $legacyCourse,
964964
?CourseEntity $courseEntity,
965965
?SessionEntity $sessionEntity,
@@ -1017,7 +1017,7 @@ private function build_wiki(
10171017
*
10181018
* @param array<int> $ids
10191019
*/
1020-
private function build_glossary(
1020+
public function build_glossary(
10211021
object $legacyCourse,
10221022
?CourseEntity $courseEntity,
10231023
?SessionEntity $sessionEntity,
@@ -1062,7 +1062,7 @@ private function build_glossary(
10621062
*
10631063
* @param array<int> $ids
10641064
*/
1065-
private function build_course_descriptions(
1065+
public function build_course_descriptions(
10661066
object $legacyCourse,
10671067
?CourseEntity $courseEntity,
10681068
?SessionEntity $sessionEntity,
@@ -1108,7 +1108,7 @@ private function build_course_descriptions(
11081108
*
11091109
* @param array<int> $ids
11101110
*/
1111-
private function build_events(
1111+
public function build_events(
11121112
object $legacyCourse,
11131113
?CourseEntity $courseEntity,
11141114
?SessionEntity $sessionEntity,
@@ -1213,7 +1213,7 @@ private function build_events(
12131213
*
12141214
* @param array<int> $ids
12151215
*/
1216-
private function build_announcements(
1216+
public function build_announcements(
12171217
object $legacyCourse,
12181218
?CourseEntity $courseEntity,
12191219
?SessionEntity $sessionEntity,
@@ -1351,7 +1351,7 @@ private function tryAddAsset(string $relPath, string $absPath, int $size = 0): v
13511351
*
13521352
* @return array<int>
13531353
*/
1354-
private function build_surveys(
1354+
public function build_surveys(
13551355
object $legacyCourse,
13561356
?CourseEntity $courseEntity,
13571357
?SessionEntity $sessionEntity,
@@ -1444,7 +1444,7 @@ private function build_surveys(
14441444
*
14451445
* @param array<int> $questionIds
14461446
*/
1447-
private function build_survey_questions(
1447+
public function build_survey_questions(
14481448
object $legacyCourse,
14491449
?CourseEntity $courseEntity,
14501450
?SessionEntity $sessionEntity,
@@ -1528,7 +1528,7 @@ private function build_survey_questions(
15281528
*
15291529
* @return array<int>
15301530
*/
1531-
private function build_quizzes(
1531+
public function build_quizzes(
15321532
object $legacyCourse,
15331533
?CourseEntity $courseEntity,
15341534
?SessionEntity $sessionEntity,
@@ -1641,7 +1641,7 @@ private function safeCount(mixed $v): int
16411641
*
16421642
* @param array<int> $questionIds
16431643
*/
1644-
private function build_quiz_questions(
1644+
public function build_quiz_questions(
16451645
object $legacyCourse,
16461646
?CourseEntity $courseEntity,
16471647
?SessionEntity $sessionEntity,
@@ -1764,7 +1764,7 @@ private function exportQuestionsWithAnswers(object $legacyCourse, array $questio
17641764
/**
17651765
* Export Link category as legacy item.
17661766
*/
1767-
private function build_link_category(CLinkCategory $category): void
1767+
public function build_link_category(CLinkCategory $category): void
17681768
{
17691769
$id = (int) $category->getIid();
17701770
if ($id <= 0) {
@@ -1786,7 +1786,7 @@ private function build_link_category(CLinkCategory $category): void
17861786
*
17871787
* @param array<int> $ids
17881788
*/
1789-
private function build_links(
1789+
public function build_links(
17901790
object $legacyCourse,
17911791
?CourseEntity $courseEntity,
17921792
?SessionEntity $sessionEntity,
@@ -1949,7 +1949,7 @@ private function makeIdFilter(array $idsFilter): Closure
19491949
* Export Tool intro only for the course_homepage tool.
19501950
* Prefers the session-specific intro when both (session and base) exist.
19511951
*/
1952-
private function build_tool_intro(
1952+
public function build_tool_intro(
19531953
object $legacyCourse,
19541954
?CourseEntity $courseEntity,
19551955
?SessionEntity $sessionEntity
@@ -2020,7 +2020,7 @@ private function build_tool_intro(
20202020
*
20212021
* @param array<int> $ids
20222022
*/
2023-
private function build_forum_category(
2023+
public function build_forum_category(
20242024
object $legacyCourse,
20252025
CourseEntity $courseEntity,
20262026
?SessionEntity $sessionEntity,
@@ -2056,7 +2056,7 @@ private function build_forum_category(
20562056
*
20572057
* @param array<int> $ids
20582058
*/
2059-
private function build_forums(
2059+
public function build_forums(
20602060
object $legacyCourse,
20612061
CourseEntity $courseEntity,
20622062
?SessionEntity $sessionEntity,
@@ -2104,7 +2104,7 @@ private function build_forums(
21042104
*
21052105
* @param array<int> $ids
21062106
*/
2107-
private function build_forum_topics(
2107+
public function build_forum_topics(
21082108
object $legacyCourse,
21092109
CourseEntity $courseEntity,
21102110
?SessionEntity $sessionEntity,
@@ -2147,7 +2147,7 @@ private function build_forum_topics(
21472147
*
21482148
* @param array<int> $ids
21492149
*/
2150-
private function build_forum_posts(
2150+
public function build_forum_posts(
21512151
object $legacyCourse,
21522152
CourseEntity $courseEntity,
21532153
?SessionEntity $sessionEntity,

0 commit comments

Comments
 (0)