Skip to content

Commit fdecfa6

Browse files
Merge remote-tracking branch 'upstream/master' into ras-22643
2 parents 92dd498 + 54bef79 commit fdecfa6

21 files changed

+562
-187
lines changed

assets/css/app.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,11 @@ form .field {
820820
}
821821
}
822822

823+
img.course-tool__icon {
824+
@apply w-full h-full shadow object-cover;
825+
border-radius: 0.5rem;
826+
}
827+
823828
.row {
824829
@apply flex flex-wrap -mx-4;
825830
}

assets/vue/components/links/LinkForm.vue

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,10 @@
4848
v-if="formData.showOnHomepage"
4949
class="mt-4 space-y-4"
5050
>
51-
<div
52-
v-if="formData.customImageUrl"
53-
class="mb-2"
54-
>
51+
<div v-if="currentPreviewImage">
5552
<p class="text-gray-600 font-semibold">{{ t("Current icon") }}</p>
5653
<img
57-
:src="formData.customImageUrl"
54+
:src="currentPreviewImage"
5855
alt="Custom Image"
5956
class="w-24 h-24 object-cover rounded-xl border shadow"
6057
/>
@@ -75,6 +72,7 @@
7572
proudlyDisplayPoweredByUppy: false,
7673
height: 350,
7774
hideUploadButton: true,
75+
autoOpenFileEditor: true,
7876
note: t('Click the image to crop it (1:1 ratio, 120x120 px recommended).'),
7977
}"
8078
/>
@@ -109,7 +107,7 @@ import { RESOURCE_LINK_PUBLISHED } from "../../constants/entity/resourcelink"
109107
import linkService from "../../services/linkService"
110108
import { useRoute, useRouter } from "vue-router"
111109
import { useI18n } from "vue-i18n"
112-
import { onMounted, reactive, ref } from "vue"
110+
import { computed, onMounted, reactive, ref, watch } from "vue"
113111
import { useCidReq } from "../../composables/cidReq"
114112
import BaseButton from "../basecomponents/BaseButton.vue"
115113
import { required, url } from "@vuelidate/validators"
@@ -133,7 +131,22 @@ const { cid, sid } = useCidReq()
133131
const router = useRouter()
134132
const route = useRoute()
135133
const selectedFile = ref(null)
136-
const uppy = new Uppy({ restrictions: { maxNumberOfFiles: 1, allowedFileTypes: ["image/*"] } })
134+
const objectUrl = ref(null)
135+
136+
const currentPreviewImage = computed(() => {
137+
if (selectedFile.value) {
138+
if (objectUrl.value) window.URL.revokeObjectURL(objectUrl.value)
139+
objectUrl.value = window.URL.createObjectURL(selectedFile.value)
140+
return objectUrl.value
141+
}
142+
return formData.customImageUrl
143+
})
144+
145+
const uppy = new Uppy({
146+
restrictions: { maxNumberOfFiles: 1, allowedFileTypes: ["image/*"] },
147+
autoProceed: false,
148+
debug: false,
149+
})
137150
.use(ImageEditor, {
138151
actions: {
139152
revert: true,
@@ -142,18 +155,34 @@ const uppy = new Uppy({ restrictions: { maxNumberOfFiles: 1, allowedFileTypes: [
142155
zoomIn: true,
143156
zoomOut: true,
144157
},
158+
quality: 1,
159+
cropperOptions: {
160+
aspectRatio: 1,
161+
croppedCanvasOptions: {
162+
width: 120,
163+
height: 120,
164+
imageSmoothingEnabled: true,
165+
imageSmoothingQuality: "high",
166+
},
167+
},
145168
})
146169
.on("file-added", async (file) => {
147-
selectedFile.value = file.data
148170
formData.removeImage = false
149171
150-
const imageEditor = uppy.getPlugin("ImageEditor")
151-
if (imageEditor) {
152-
await imageEditor.openEditor(file.id)
172+
const editor = uppy.getPlugin("ImageEditor")
173+
if (editor?.openEditor) await editor.openEditor(file.id)
174+
})
175+
.on("file-editor:complete", (updatedFile) => {
176+
if (updatedFile?.data) {
177+
const uniqueName = `customicon-${Date.now()}.png`
178+
selectedFile.value = new File([updatedFile.data], uniqueName, {
179+
type: updatedFile.type || "image/png",
180+
})
153181
}
154182
})
155183
.on("file-removed", () => {
156184
selectedFile.value = null
185+
formData.removeImage = true
157186
})
158187
159188
const props = defineProps({
@@ -171,7 +200,7 @@ const resourceLinkList = ref(
171200
{
172201
sid,
173202
cid,
174-
visibility: RESOURCE_LINK_PUBLISHED, // visible by default
203+
visibility: RESOURCE_LINK_PUBLISHED,
175204
},
176205
]),
177206
)
@@ -198,6 +227,13 @@ const rules = {
198227
}
199228
const v$ = useVuelidate(rules, formData)
200229
230+
watch(selectedFile, (file, oldFile) => {
231+
if (!file && objectUrl.value) {
232+
window.URL.revokeObjectURL(objectUrl.value)
233+
objectUrl.value = null
234+
}
235+
})
236+
201237
onMounted(() => {
202238
fetchCategories()
203239
fetchLink()
@@ -279,15 +315,7 @@ const submitForm = async () => {
279315
formDataImage.append("removeImage", formData.removeImage ? "true" : "false")
280316
281317
if (selectedFile.value) {
282-
let fileToUpload = selectedFile.value
283-
284-
if (!(fileToUpload instanceof File)) {
285-
fileToUpload = new File([fileToUpload], "custom-icon.png", {
286-
type: fileToUpload.type || "image/png",
287-
})
288-
}
289-
290-
formDataImage.append("customImage", fileToUpload)
318+
formDataImage.append("customImage", selectedFile.value)
291319
}
292320
293321
await linkService.uploadImage(linkId, formDataImage)

public/main/gradebook/gradebook_display_certificate.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,11 @@ function confirmation() {
335335
echo '<td width="50%">'.get_lang('Score').' : '.$valueCertificate['score_certificate'].'</td>';
336336
echo '<td width="30%">'.get_lang('Date').' : '.api_convert_and_format_date($valueCertificate['created_at']).'</td>';
337337
echo '<td width="20%">';
338-
$url = api_get_path(WEB_PATH).'certificates/index.php?id='.$valueCertificate['id'].'&user_id='.$value['user_id'];
338+
$url = '';
339+
if (!empty($valueCertificate['path_certificate']) && $valueCertificate['publish']) {
340+
$hash = pathinfo($valueCertificate['path_certificate'], PATHINFO_FILENAME);
341+
$url = api_get_path(WEB_PATH).'certificates/'.$hash.'.html';
342+
}
339343
$certificateUrl = Display::url(
340344
get_lang('Certificate'),
341345
$url,

public/main/gradebook/lib/GradebookUtils.php

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,8 @@ public static function get_list_gradebook_certificates_by_user_id(
717717
gc.path_certificate,
718718
gc.cat_id,
719719
gc.user_id,
720-
gc.id
720+
gc.id,
721+
gc.publish
721722
FROM '.$table_certificate.' gc
722723
WHERE gc.user_id = "'.$user_id.'" ';
723724
if (!is_null($cat_id) && $cat_id > 0) {
@@ -1382,12 +1383,24 @@ public static function getUserCertificatesInCourses(
13821383
continue;
13831384
}
13841385

1386+
$path = $certificateInfo['path_certificate'] ?? '';
1387+
$publish = $certificateInfo['publish'] ?? 0;
1388+
$hash = pathinfo($path, PATHINFO_FILENAME);
1389+
1390+
$link = '';
1391+
$pdf = '';
1392+
1393+
if (!empty($hash) && $publish) {
1394+
$link = api_get_path(WEB_PATH) . "certificates/{$hash}.html";
1395+
$pdf = api_get_path(WEB_PATH)."certificates/{$hash}.pdf";
1396+
}
1397+
13851398
$courseList[] = [
13861399
'course' => $courseInfo['title'],
13871400
'score' => $certificateInfo['score_certificate'],
13881401
'date' => api_format_date($certificateInfo['created_at'], DATE_FORMAT_SHORT),
1389-
'link' => api_get_path(WEB_PATH)."certificates/index.php?id={$certificateInfo['id']}",
1390-
'pdf' => api_get_path(WEB_PATH)."certificates/index.php?id={$certificateInfo['id']}&user_id={$userId}&action=export",
1402+
'link' => $link,
1403+
'pdf' => $pdf,
13911404
];
13921405
}
13931406

@@ -1461,13 +1474,13 @@ public static function getUserCertificatesInSessions($userId, $includeNonPublicC
14611474
if (empty($certificateInfo)) {
14621475
continue;
14631476
}
1464-
1477+
$hash = pathinfo($certificateInfo['path_certificate'], PATHINFO_FILENAME);
14651478
$sessionList[] = [
14661479
'session' => $session['session_name'],
14671480
'course' => $course['title'],
14681481
'score' => $certificateInfo['score_certificate'],
14691482
'date' => api_format_date($certificateInfo['created_at'], DATE_FORMAT_SHORT),
1470-
'link' => api_get_path(WEB_PATH)."certificates/index.php?id={$certificateInfo['id']}",
1483+
'link' => api_get_path(WEB_PATH)."certificates/{$hash}.html",
14711484
];
14721485
}
14731486
}

public/main/gradebook/lib/be/category.class.php

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,31 +2097,42 @@ public static function generateUserCertificate(
20972097
}
20982098
}
20992099

2100-
if (!empty($fileWasGenerated)) {
2101-
$url = api_get_path(WEB_PATH).'certificates/index.php?id='.$my_certificate['id'].'&user_id='.$user_id;
2102-
$certificates = Display::toolbarButton(
2103-
get_lang('Display certificate'),
2104-
$url,
2105-
'eye',
2106-
'primary',
2107-
['target' => '_blank']
2108-
);
2100+
if (!empty($fileWasGenerated) && !empty($my_certificate['publish'])) {
2101+
$certificates = '';
2102+
$exportToPDF = null;
2103+
$pdfUrl = null;
2104+
2105+
if (!empty($my_certificate['pathCertificate'])) {
2106+
$hash = pathinfo($my_certificate['pathCertificate'], PATHINFO_FILENAME);
2107+
2108+
$url = api_get_path(WEB_PATH) . 'certificates/' . $hash . '.html';
2109+
$pdfUrl = api_get_path(WEB_PATH) . 'certificates/' . $hash . '.pdf';
2110+
2111+
$certificates = Display::toolbarButton(
2112+
get_lang('Display certificate'),
2113+
$url,
2114+
'eye',
2115+
'primary',
2116+
['target' => '_blank']
2117+
);
21092118

2110-
$exportToPDF = Display::url(
2111-
Display::getMdiIcon(ActionIcon::EXPORT_PDF, 'ch-tool-icon', null, ICON_SIZE_MEDIUM, get_lang('Export to PDF')),
2112-
"$url&action=export"
2113-
);
2119+
$exportToPDF = Display::url(
2120+
Display::getMdiIcon(ActionIcon::EXPORT_PDF, 'ch-tool-icon', null, ICON_SIZE_MEDIUM, get_lang('Export to PDF')),
2121+
$pdfUrl,
2122+
['target' => '_blank']
2123+
);
2124+
}
21142125

2115-
$hideExportLink = api_get_setting('hide_certificate_export_link');
2116-
$hideExportLinkStudent = api_get_setting('hide_certificate_export_link_students');
2126+
$hideExportLink = api_get_setting('gradebook.hide_certificate_export_link');
2127+
$hideExportLinkStudent = api_get_setting('gradebook.hide_certificate_export_link_students');
21172128
if ('true' === $hideExportLink || (api_is_student() && 'true' === $hideExportLinkStudent)) {
21182129
$exportToPDF = null;
21192130
}
21202131

21212132
$html = [
21222133
'certificate_link' => $certificates,
21232134
'pdf_link' => $exportToPDF,
2124-
'pdf_url' => "$url&action=export",
2135+
'pdf_url' => $pdfUrl,
21252136
];
21262137
}
21272138

public/main/inc/lib/api.lib.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@
9393
// SESSION VISIBILITY CONSTANTS
9494
define('SESSION_VISIBLE_READ_ONLY', 1);
9595
define('SESSION_VISIBLE', 2);
96+
/**
97+
* @deprecated Use Session::INVISIBLE
98+
*/
9699
define('SESSION_INVISIBLE', 3); // not available
97100
define('SESSION_AVAILABLE', 4);
98101

@@ -2503,6 +2506,8 @@ function api_get_session_info($id)
25032506
/**
25042507
* Gets the session visibility by session id.
25052508
*
2509+
* @deprecated Use Session::setAccessVisibilityByUser() instead.
2510+
*
25062511
* @param int $session_id
25072512
* @param int $courseId
25082513
* @param bool $ignore_visibility_for_admins

public/main/inc/lib/certificate.lib.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,11 @@ public static function sendNotification(
300300
}
301301

302302
$currentUserInfo = api_get_user_info();
303-
$url = api_get_path(WEB_PATH).
304-
'certificates/index.php?id='.$certificateInfo['id'].'&user_id='.$certificateInfo['user_id'];
303+
$url = '';
304+
if (!empty($certificateInfo['path_certificate'])) {
305+
$hash = pathinfo($certificateInfo['path_certificate'], PATHINFO_FILENAME);
306+
$url = api_get_path(WEB_PATH) . 'certificates/' . $hash . '.html';
307+
}
305308
$link = Display::url($url, $url);
306309

307310
$replace = [

public/main/inc/lib/document.lib.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1245,7 +1245,10 @@ public static function get_all_info_to_certificate($user_id, $courseId, $session
12451245
$url = '';
12461246
if ($info_grade_certificate) {
12471247
$date_certificate = $info_grade_certificate['created_at'];
1248-
$url = api_get_path(WEB_PATH).'certificates/index.php?id='.$info_grade_certificate['id'];
1248+
if (!empty($info_grade_certificate['path_certificate'])) {
1249+
$hash = pathinfo($info_grade_certificate['path_certificate'], PATHINFO_FILENAME);
1250+
$url = api_get_path(WEB_PATH) . 'certificates/' . $hash . '.html';
1251+
}
12491252
}
12501253
$date_no_time = api_convert_and_format_date(api_get_utc_datetime(), DATE_FORMAT_LONG_NO_DAY);
12511254
if (!empty($date_certificate)) {

public/main/inc/lib/usermanager.lib.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2721,10 +2721,12 @@ public static function get_sessions_by_category(
27212721
/**
27222722
* Gives a list of [session_id-course_code] => [status] for the current user.
27232723
*
2724-
* @param int $user_id
2725-
* @param int $sessionLimit
2724+
* @param int $user_id
2725+
* @param int $sessionLimit
27262726
*
27272727
* @return array list of statuses (session_id-course_code => status)
2728+
*
2729+
* @throws Exception
27282730
*/
27292731
public static function get_personal_session_course_list($user_id, $sessionLimit = null)
27302732
{

public/main/my_space/session_filter.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,9 +383,8 @@
383383
echo get_lang('Date').' : '.api_convert_and_format_date($valueCertificate['created_at']);
384384
echo '</td>';
385385
echo '<td width="20%">';
386-
$url = api_get_path(WEB_PATH).'certificates/index.php?'.
387-
'id='.$valueCertificate['id'].
388-
'&user_id='.$value['user_id'];
386+
$hash = pathinfo($valueCertificate['path_certificate'], PATHINFO_FILENAME);
387+
$url = api_get_path(WEB_PATH)."certificates/{$hash}.html";
389388
$certificateUrl = Display::url(
390389
get_lang('Certificate'),
391390
$url,

0 commit comments

Comments
 (0)