Skip to content

Commit d665b75

Browse files
committed
Merge branch 'master' of github.com:chamilo/chamilo-lms
2 parents c767dbc + 09a9146 commit d665b75

File tree

2 files changed

+93
-75
lines changed

2 files changed

+93
-75
lines changed

src/CoreBundle/Controller/Admin/SettingsController.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,16 @@ public function searchSetting(Request $request, AccessUrlHelper $accessUrlHelper
106106
$templateMapByCategory[$category][$var] = $templateMap[$var];
107107
}
108108
}
109-
$settings = $manager->load($category);
109+
110+
// Convert category to schema alias and validate it BEFORE loading/creating the form
110111
$schemaAlias = $manager->convertNameSpaceToService($category);
112+
113+
// skip unknown/legacy categories (e.g., "tools")
114+
if (!isset($schemas[$schemaAlias])) {
115+
continue;
116+
}
117+
118+
$settings = $manager->load($category);
111119
$form = $this->getSettingsFormFactory()->create($schemaAlias);
112120

113121
foreach (array_keys($settings->getParameters()) as $name) {
@@ -147,6 +155,17 @@ public function updateSetting(Request $request, AccessUrlHelper $accessUrlHelper
147155
$schemaAlias = $manager->convertNameSpaceToService($namespace);
148156

149157
$keyword = (string) $request->query->get('keyword', '');
158+
159+
// Validate schema BEFORE load/create to avoid NonExistingServiceException
160+
$schemas = $manager->getSchemas();
161+
if (!isset($schemas[$schemaAlias])) {
162+
$this->addFlash('warning', sprintf('Unknown settings category "%s". Showing Platform settings.', $namespace));
163+
164+
return $this->redirectToRoute('chamilo_platform_settings', [
165+
'namespace' => 'platform',
166+
]);
167+
}
168+
150169
$settings = $manager->load($namespace);
151170

152171
$form = $this->getSettingsFormFactory()->create(
@@ -193,7 +212,6 @@ public function updateSetting(Request $request, AccessUrlHelper $accessUrlHelper
193212
]);
194213
}
195214

196-
$schemas = $manager->getSchemas();
197215
[$ordered, $labelMap] = $this->computeOrderedNamespacesByTranslatedLabel($schemas, $request);
198216

199217
$templateMap = [];

src/CoreBundle/Resources/views/Admin/Settings/search.html.twig

Lines changed: 73 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
{% extends "@ChamiloCore/Layout/layout_one_col.html.twig" %}
22
{% from '@ChamiloCore/Admin/Settings/actions.html.twig' import update %}
33
{% set namespace = app.request.get('namespace') %}
4-
{% set content_width = 'max-w-4xl mx-auto' %}
4+
{# Use full width for inner containers #}
5+
{% set content_width = 'w-full' %}
56

67
{% block content %}
7-
<div class="flex">
8-
<div class="w-1/5">
8+
{# Two-column layout: fixed sidebar + fluid content #}
9+
<div class="flex gap-6">
10+
<div class="w-64 shrink-0">
911
{% include '@ChamiloCore/Admin/Settings/menu.html.twig' %}
1012
</div>
11-
<div class="w-4/5">
13+
<div class="flex-1 min-w-0">
1214
<div class="q-card p-4">
1315

1416
{{ form_start(search_form, {
@@ -19,88 +21,85 @@
1921
{{ form_widget(search_form) }}
2022
{{ form_end(search_form) }}
2123

22-
<div class="my-6 row">
24+
<div class="my-6 space-y-10">
2325
{% for category, form in form_list %}
24-
<div class="col-md-12">
2526

26-
<div class="{% if not loop.first %}mt-12 {% endif %}mb-4 pb-2 border-b border-gray-25">
27-
{% set label = namespace_labels[category]
28-
?? (category == 'cas' ? 'CAS'
29-
: (category == 'lp' ? 'Learning path'|trans
30-
: (category|capitalize)|trans)) %}
27+
<div class="{% if not loop.first %}mt-12 {% endif %}mb-4 pb-2 border-b border-gray-25">
28+
{% set label = namespace_labels[category]
29+
?? (category == 'cas' ? 'CAS'
30+
: (category == 'lp' ? 'Learning path'|trans
31+
: (category|capitalize)|trans)) %}
32+
<h3 class="text-gray-90 text-h6 font-semibold tracking-wide">
33+
{{ category == 'cas' ? label : label|title }}
34+
</h3>
35+
</div>
3136

32-
<h3 class="text-gray-90 text-h6 font-semibold tracking-wide">
33-
{{ category == 'cas' ? label : label|title }}
34-
</h3>
35-
</div>
37+
<div class="box box-primary">
38+
<div class="box-body min-w-0">
39+
{{ form_errors(form) }}
40+
41+
{# Make inner form container full width, no max constraint #}
42+
<div class="{{ content_width }} max-w-none">
43+
44+
{{ form_start(form, {
45+
action: path('chamilo_platform_settings', { 'namespace': category, 'keyword': keyword }),
46+
method: 'POST',
47+
attr: { class: 'form-horizontal', novalidate: 'novalidate' }
48+
}) }}
49+
50+
<input type="hidden" name="_partial" value="1"/>
51+
52+
{% for field in form %}
53+
{% set fieldName = field.vars.name %}
54+
{% set isHidden = 'hidden' in field.vars.block_prefixes %}
55+
{% if isHidden %}
56+
{{ form_widget(field) }}
57+
{% else %}
58+
<div class="mb-6 p-5 rounded-lg border border-gray-50 shadow-sm bg-white hover:shadow transition">
59+
<div class="flex justify-between items-start mb-3 border-l-4 border-primary pl-4">
60+
<h4 class="text-gray-90 text-body-1 font-semibold">{{ field.vars.label|trans }}</h4>
61+
62+
{# Optional JSON template helper link #}
63+
{% set templateId = null %}
64+
{% if template_map is defined and template_map[fieldName] is defined %}
65+
{% set templateId = template_map[fieldName] %}
66+
{% elseif template_map_by_category is defined
67+
and template_map_by_category[category] is defined
68+
and template_map_by_category[category][fieldName] is defined %}
69+
{% set templateId = template_map_by_category[category][fieldName] %}
70+
{% endif %}
3671

37-
<div class="box box-primary">
38-
<div class="box-body">
39-
40-
{{ form_errors(form) }}
41-
42-
<div class="{{ content_width }}">
43-
44-
{{ form_start(form, {
45-
action: path('chamilo_platform_settings', { 'namespace': category, 'keyword': keyword }),
46-
method: 'POST',
47-
attr: { class: 'form-horizontal', novalidate: 'novalidate' }
48-
}) }}
49-
50-
<input type="hidden" name="_partial" value="1"/>
51-
{% for field in form %}
52-
{% set fieldName = field.vars.name %}
53-
{% set isHidden = 'hidden' in field.vars.block_prefixes %}
54-
{% if isHidden %}
55-
{{ form_widget(field) }}
56-
{% else %}
57-
<div class="mb-6 p-5 rounded-lg border border-gray-50 shadow-sm bg-white hover:shadow transition">
58-
<div class="flex justify-between items-start mb-3 border-l-4 border-primary pl-4">
59-
<h4 class="text-gray-90 text-body-1 font-semibold">{{ field.vars.label|trans }}</h4>
60-
61-
{% set templateId = null %}
62-
{% if template_map is defined and template_map[fieldName] is defined %}
63-
{% set templateId = template_map[fieldName] %}
64-
{% elseif template_map_by_category is defined
65-
and template_map_by_category[category] is defined
66-
and template_map_by_category[category][fieldName] is defined %}
67-
{% set templateId = template_map_by_category[category][fieldName] %}
68-
{% endif %}
69-
70-
{% if templateId %}
71-
<a href="javascript:void(0)" class="text-info hover:text-info-dark show-template flex items-center gap-2"
72-
data-template-id="{{ templateId }}" title="{{ 'Show JSON Template'|trans }}">
73-
<i class="mdi mdi-information-outline text-info text-lg"></i>
74-
<span class="text-body-2">{{ 'Show JSON Template'|trans }}</span>
75-
</a>
76-
{% endif %}
77-
</div>
78-
79-
<div class="mb-2">
80-
{{ form_widget(field, { attr: {
81-
class: 'w-full rounded border border-gray-25 focus:border-primary focus:ring focus:ring-primary/30 transition'
82-
} }) }}
83-
</div>
84-
85-
{% if field.vars.help is not empty %}
86-
<p class="text-gray-50 text-body-2 italic pl-3">{{ field.vars.help|raw }}</p>
72+
{% if templateId %}
73+
<a href="javascript:void(0)" class="text-info hover:text-info-dark show-template flex items-center gap-2"
74+
data-template-id="{{ templateId }}" title="{{ 'Show JSON Template'|trans }}">
75+
<i class="mdi mdi-information-outline text-info text-lg"></i>
76+
<span class="text-body-2">{{ 'Show JSON Template'|trans }}</span>
77+
</a>
8778
{% endif %}
79+
</div>
8880

89-
{{ form_errors(field) }}
81+
<div class="mb-2">
82+
{{ form_widget(field, { attr: {
83+
class: 'w-full max-w-none rounded border border-gray-25 focus:border-primary focus:ring focus:ring-primary/30 transition'
84+
} }) }}
9085
</div>
91-
{% endif %}
92-
{% endfor %}
9386

94-
{{ form_rest(form) }}
87+
{% if field.vars.help is not empty %}
88+
<p class="text-gray-50 text-body-2 italic pl-3">{{ field.vars.help|raw }}</p>
89+
{% endif %}
9590

96-
<div class="mt-4 mb-10">
97-
{{ update() }}
98-
</div>
91+
{{ form_errors(field) }}
92+
</div>
93+
{% endif %}
94+
{% endfor %}
9995

100-
{{ form_end(form, { render_rest: false }) }}
96+
{{ form_rest(form) }}
10197

98+
<div class="mt-4 mb-10">
99+
{{ update() }}
102100
</div>
103101

102+
{{ form_end(form, { render_rest: false }) }}
104103
</div>
105104
</div>
106105
</div>
@@ -110,6 +109,7 @@
110109
</div>
111110
</div>
112111

112+
{# Simple modal to preview JSON templates #}
113113
<div id="jsonTemplateOverlay" class="fixed inset-0 bg-gray-90/50 hidden z-40"></div>
114114

115115
<div id="jsonTemplateModal" class="fixed inset-0 hidden z-50 flex items-center justify-center">

0 commit comments

Comments
 (0)