|
85 | 85 | </div> |
86 | 86 | </div>'; |
87 | 87 |
|
88 | | - |
89 | 88 | // Course settings panel (top section of the page) |
90 | 89 | $courseSettingsPanel = []; |
91 | 90 |
|
|
133 | 132 | $showOnlyTheseFields |
134 | 133 | ); |
135 | 134 |
|
136 | | -$extraReady = isset($extra['jquery_ready_content']) ? $extra['jquery_ready_content'] : ''; |
| 135 | +if (!empty($extra['jquery_ready_content'])) { |
| 136 | + $htmlHeadXtra[] = $extra['jquery_ready_content']; |
| 137 | +} |
137 | 138 |
|
138 | | -// JS: hide legacy header, open first panel, init extra-fields and picture preview |
139 | 139 | $htmlHeadXtra[] = ' |
| 140 | +<style> |
| 141 | +.display-panel-collapse__header { |
| 142 | + width: 100%; |
| 143 | +} |
| 144 | +
|
| 145 | +.display-panel-collapse__header a { |
| 146 | + display: flex; |
| 147 | + align-items: center; |
| 148 | + width: 100%; |
| 149 | + gap: .5rem; |
| 150 | +} |
| 151 | +
|
| 152 | +.display-panel-collapse__header a .mdi { |
| 153 | + line-height: 1; |
| 154 | +} |
| 155 | +</style> |
140 | 156 | <script> |
141 | 157 | window.addEventListener("load", function () { |
142 | | - // Init course extra-fields widgets (tags, etc.) |
143 | | - '.$extraReady.' |
144 | | -
|
145 | 158 | var form = document.getElementById("update_course"); |
146 | 159 | if (!form) { |
147 | | - console.log("[COURSE SETTINGS] No form with id update_course found"); |
148 | 160 | return; |
149 | 161 | } |
150 | 162 |
|
151 | | - // First new collapsible panel: <div class=\"display-panel-collapse field\"> |
152 | 163 | var firstPanel = form.querySelector(".display-panel-collapse.field"); |
153 | | - console.log("[COURSE SETTINGS] First panel found:", !!firstPanel); |
154 | | -
|
155 | 164 | if (!firstPanel) { |
156 | 165 | return; |
157 | 166 | } |
158 | 167 |
|
159 | | - // Hide legacy blocks before the first new panel |
| 168 | + // Preview image element |
| 169 | + var picturePreview = document.getElementById("course-picture-preview"); |
| 170 | +
|
160 | 171 | var node = firstPanel.previousElementSibling; |
161 | 172 | var hiddenCount = 0; |
162 | 173 |
|
|
178 | 189 | header.classList.remove("mdi-chevron-down"); |
179 | 190 | header.classList.add("mdi-chevron-up"); |
180 | 191 | body.classList.add("active"); |
181 | | - console.log("[COURSE SETTINGS] First panel forced open"); |
182 | 192 | } else { |
183 | 193 | console.log("[COURSE SETTINGS] Header/body not found inside firstPanel"); |
184 | 194 | } |
185 | 195 |
|
186 | | - // --- Live preview for course picture --- |
187 | | - var pictureInput = document.getElementById("picture"); |
188 | | - var picturePreview = document.getElementById("course-picture-preview"); |
| 196 | + // Ensure previously saved picture is visible |
| 197 | + if (picturePreview && picturePreview.getAttribute("src")) { |
| 198 | + picturePreview.style.display = "block"; |
| 199 | + } |
| 200 | +
|
| 201 | + // Live preview for course picture |
| 202 | + if (form && picturePreview) { |
| 203 | + form.addEventListener("change", function (event) { |
| 204 | + var input = event.target; |
| 205 | + if (!input || input.tagName !== "INPUT" || input.type !== "file") { |
| 206 | + return; |
| 207 | + } |
189 | 208 |
|
190 | | - if (pictureInput && picturePreview) { |
191 | | - pictureInput.addEventListener("change", function (event) { |
192 | | - var file = event.target.files && event.target.files[0]; |
193 | | - if (!file || !file.type || !file.type.match(/^image\\//)) { |
| 209 | + var inputName = input.getAttribute("name") || ""; |
| 210 | + if (inputName.indexOf("picture") === -1) { |
| 211 | + return; |
| 212 | + } |
| 213 | +
|
| 214 | + var file = input.files && input.files[0]; |
| 215 | +
|
| 216 | + if (!file) { |
| 217 | + picturePreview.removeAttribute("src"); |
| 218 | + picturePreview.style.display = "none"; |
| 219 | + return; |
| 220 | + } |
| 221 | +
|
| 222 | + // Only handle image files |
| 223 | + if (!file.type || !file.type.match(/^image\\//)) { |
194 | 224 | return; |
195 | 225 | } |
196 | 226 |
|
197 | 227 | var reader = new FileReader(); |
198 | 228 | reader.onload = function (e) { |
199 | 229 | picturePreview.src = e.target.result; |
| 230 | + picturePreview.style.display = "block"; |
| 231 | + picturePreview.removeAttribute("hidden"); |
200 | 232 | }; |
201 | 233 | reader.readAsDataURL(file); |
202 | 234 | }); |
| 235 | + } else { |
| 236 | + console.log("[COURSE SETTINGS] Form or preview not found, live preview disabled"); |
203 | 237 | } |
204 | 238 | }); |
205 | 239 | </script>'; |
|
215 | 249 | // Course picture (upload + preview + delete) |
216 | 250 | $allowed_picture_types = api_get_supported_image_extensions(false); |
217 | 251 |
|
218 | | -// Current picture preview (if any) |
219 | | -if (!empty($image)) { |
220 | | - // Use addElement("html", ...) so the element belongs to the form |
221 | | - $picturePreviewElement = $form->addElement( |
222 | | - 'html', |
223 | | - $image |
224 | | - ); |
225 | | - $courseSettingsPanel[] = $picturePreviewElement; |
| 252 | +$acceptPictureTypes = ''; |
| 253 | +if (!empty($allowed_picture_types) && is_array($allowed_picture_types)) { |
| 254 | + $acceptPictureTypes = '.'.implode(',.', $allowed_picture_types); |
226 | 255 | } |
227 | 256 |
|
228 | | -// File input for new picture |
229 | 257 | $pictureElement = $form->addFile( |
230 | 258 | 'picture', |
231 | 259 | get_lang('Add a picture'), |
232 | 260 | [ |
233 | 261 | 'id' => 'picture', |
234 | 262 | 'class' => 'picture-form', |
235 | 263 | 'crop_image' => true, |
| 264 | + 'accept' => !empty($acceptPictureTypes) ? $acceptPictureTypes : 'image/*', |
236 | 265 | ] |
237 | 266 | ); |
238 | 267 | $courseSettingsPanel[] = $pictureElement; |
239 | 268 |
|
| 269 | +if (!empty($image)) { |
| 270 | + $picturePreviewElement = $form->createElement( |
| 271 | + 'html', |
| 272 | + $image |
| 273 | + ); |
| 274 | + $courseSettingsPanel[] = $picturePreviewElement; |
| 275 | +} |
| 276 | + |
240 | 277 | // Validation rules for picture type |
241 | 278 | $form->addRule( |
242 | 279 | 'picture', |
|
1147 | 1184 | ? $updateValues['course_registration_password'] |
1148 | 1185 | : $courseEntity->getRegistrationCode(); |
1149 | 1186 |
|
| 1187 | + $visibility = $updateValues['visibility'] ?? $courseEntity->getVisibility(); |
| 1188 | + $deletePicture = !empty($updateValues['delete_picture'] ?? null); |
| 1189 | + |
1150 | 1190 | $request = Container::getRequest(); |
1151 | | - /** @var UploadedFile $uploadFile */ |
| 1191 | + /** @var UploadedFile|null $uploadFile */ |
1152 | 1192 | $uploadFile = $request->files->get('picture'); |
1153 | 1193 |
|
1154 | 1194 | // Handle course picture upload / update |
1155 | 1195 | if (null !== $uploadFile) { |
1156 | | - $hasIllustration = $illustrationRepo->hasIllustration($courseEntity); |
1157 | | - if ($hasIllustration) { |
| 1196 | + // Replace existing illustration with the new one |
| 1197 | + if ($illustrationRepo->hasIllustration($courseEntity)) { |
1158 | 1198 | $illustrationRepo->deleteIllustration($courseEntity); |
1159 | 1199 | } |
1160 | 1200 |
|
|
1179 | 1219 | $uploadFile->getFilename() |
1180 | 1220 | ); |
1181 | 1221 | } |
1182 | | - } |
1183 | 1222 |
|
1184 | | - $visibility = $updateValues['visibility'] ?? ''; |
1185 | | - $deletePicture = $updateValues['delete_picture'] ?? ''; |
| 1223 | + $deletePicture = false; |
| 1224 | + } |
1186 | 1225 |
|
1187 | 1226 | if ($deletePicture) { |
1188 | | - $illustrationRepo->deleteIllustration($courseEntity); |
| 1227 | + if ($illustrationRepo->hasIllustration($courseEntity)) { |
| 1228 | + $illustrationRepo->deleteIllustration($courseEntity); |
| 1229 | + } |
1189 | 1230 | } |
1190 | 1231 |
|
1191 | 1232 | $access_url_id = api_get_current_access_url_id(); |
|
0 commit comments