77namespace Chamilo \CoreBundle \Controller \Admin ;
88
99use Chamilo \CoreBundle \Controller \BaseController ;
10+ use Chamilo \CoreBundle \Entity \AccessUrl ;
1011use Chamilo \CoreBundle \Entity \SearchEngineField ;
1112use Chamilo \CoreBundle \Entity \SettingsCurrent ;
1213use Chamilo \CoreBundle \Entity \SettingsValueTemplate ;
@@ -47,7 +48,85 @@ public function index(): Response
4748 }
4849
4950 /**
50- * Edit configuration with given namespace.
51+ * Toggle access_url_changeable for a given setting variable.
52+ * Only platform admins on the main URL (ID = 1) are allowed to change it,
53+ */
54+ #[IsGranted('ROLE_ADMIN ' )]
55+ #[Route('/settings/toggle_changeable ' , name: 'settings_toggle_changeable ' , methods: ['POST ' ])]
56+ public function toggleChangeable (Request $ request , AccessUrlHelper $ accessUrlHelper ): JsonResponse
57+ {
58+ // Security: only admins.
59+ if (!$ this ->isGranted ('ROLE_ADMIN ' )) {
60+ return $ this ->json ([
61+ 'error ' => 'Only platform admins can modify this flag. ' ,
62+ ], 403 );
63+ }
64+
65+ $ currentUrl = $ accessUrlHelper ->getCurrent ();
66+ if (!$ currentUrl ) {
67+ return $ this ->json ([
68+ 'error ' => 'Access URL not resolved. ' ,
69+ ], 500 );
70+ }
71+
72+ $ currentUrlId = (int ) $ currentUrl ->getId ();
73+
74+ if (1 !== $ currentUrlId ) {
75+ return $ this ->json ([
76+ 'error ' => 'Only the main URL (ID 1) can toggle this setting. ' ,
77+ ], 403 );
78+ }
79+
80+ $ payload = json_decode ($ request ->getContent (), true );
81+
82+ if (!\is_array ($ payload ) || !isset ($ payload ['variable ' ], $ payload ['status ' ])) {
83+ return $ this ->json ([
84+ 'error ' => 'Invalid payload. ' ,
85+ ], 400 );
86+ }
87+
88+ $ variable = trim ((string ) $ payload ['variable ' ]);
89+ $ status = (int ) $ payload ['status ' ];
90+ $ status = $ status === 1 ? 1 : 0 ;
91+
92+ if ('' === $ variable ) {
93+ return $ this ->json ([
94+ 'error ' => 'Invalid variable. ' ,
95+ ], 400 );
96+ }
97+
98+ $ repo = $ this ->entityManager ->getRepository (SettingsCurrent::class);
99+
100+ // We search by variable + current main AccessUrl entity.
101+ $ setting = $ repo ->findOneBy ([
102+ 'variable ' => $ variable ,
103+ 'url ' => $ currentUrl ,
104+ ]);
105+
106+ if (!$ setting ) {
107+ return $ this ->json ([
108+ 'error ' => 'Setting not found. ' ,
109+ ], 404 );
110+ }
111+
112+ try {
113+ $ setting ->setAccessUrlChangeable ($ status );
114+ $ this ->entityManager ->flush ();
115+
116+ return $ this ->json ([
117+ 'result ' => 1 ,
118+ 'status ' => $ status ,
119+ ]);
120+ } catch (\Throwable $ e ) {
121+ return $ this ->json ([
122+ 'error ' => 'Unable to update setting. ' ,
123+ 'details ' => $ e ->getMessage (),
124+ ], 500 );
125+ }
126+ }
127+
128+ /**
129+ * Edit configuration with given namespace (search page).
51130 */
52131 #[IsGranted('ROLE_ADMIN ' )]
53132 #[Route('/settings/search_settings ' , name: 'chamilo_platform_settings_search ' )]
@@ -75,6 +154,47 @@ public function searchSetting(Request $request, AccessUrlHelper $accessUrlHelper
75154 $ schemas = $ manager ->getSchemas ();
76155 [$ ordered , $ labelMap ] = $ this ->computeOrderedNamespacesByTranslatedLabel ($ schemas , $ request );
77156
157+ // Template map for current URL (existing behavior – JSON helper)
158+ $ settingsRepo = $ this ->entityManager ->getRepository (SettingsCurrent::class);
159+
160+ // Build template map: current URL overrides main URL when missing.
161+ $ currentUrlId = (int ) $ url ->getId ();
162+ $ mainUrl = $ this ->entityManager ->getRepository (AccessUrl::class)->find (1 );
163+
164+ if ($ mainUrl instanceof AccessUrl && 1 !== $ currentUrlId ) {
165+ $ mainRows = $ settingsRepo ->findBy (['url ' => $ mainUrl ]);
166+ foreach ($ mainRows as $ s ) {
167+ if ($ s ->getValueTemplate ()) {
168+ $ templateMap [$ s ->getVariable ()] = $ s ->getValueTemplate ()->getId ();
169+ }
170+ }
171+ }
172+
173+ $ currentRows = $ settingsRepo ->findBy (['url ' => $ url ]);
174+ foreach ($ currentRows as $ s ) {
175+ if ($ s ->getValueTemplate ()) {
176+ $ templateMap [$ s ->getVariable ()] = $ s ->getValueTemplate ()->getId ();
177+ }
178+ }
179+
180+ // MultiURL changeable flags: read from main URL (ID = 1) only
181+ $ changeableMap = [];
182+ $ mainUrlRows = $ settingsRepo ->createQueryBuilder ('sc ' )
183+ ->join ('sc.url ' , 'u ' )
184+ ->andWhere ('u.id = :mainId ' )
185+ ->setParameter ('mainId ' , 1 )
186+ ->getQuery ()
187+ ->getResult ();
188+
189+ foreach ($ mainUrlRows as $ row ) {
190+ if ($ row instanceof SettingsCurrent) {
191+ $ changeableMap [$ row ->getVariable ()] = $ row ->getAccessUrlChangeable ();
192+ }
193+ }
194+
195+ // Only platform admins on the main URL can toggle the MultiURL flag.
196+ $ canToggleMultiUrlSetting = $ this ->isGranted ('ROLE_ADMIN ' ) && 1 === $ currentUrlId ;
197+
78198 if ('' === $ keyword ) {
79199 return $ this ->render ('@ChamiloCore/Admin/Settings/search.html.twig ' , [
80200 'keyword ' => $ keyword ,
@@ -86,17 +206,12 @@ public function searchSetting(Request $request, AccessUrlHelper $accessUrlHelper
86206 'template_map_by_category ' => $ templateMapByCategory ,
87207 'ordered_namespaces ' => $ ordered ,
88208 'namespace_labels ' => $ labelMap ,
209+ 'changeable_map ' => $ changeableMap ,
210+ 'current_url_id ' => $ currentUrlId ,
211+ 'can_toggle_multiurl_setting ' => $ canToggleMultiUrlSetting ,
89212 ]);
90213 }
91214
92- $ settingsRepo = $ this ->entityManager ->getRepository (SettingsCurrent::class);
93- $ settingsWithTemplate = $ settingsRepo ->findBy (['url ' => $ url ]);
94- foreach ($ settingsWithTemplate as $ s ) {
95- if ($ s ->getValueTemplate ()) {
96- $ templateMap [$ s ->getVariable ()] = $ s ->getValueTemplate ()->getId ();
97- }
98- }
99-
100215 $ settingsFromKeyword = $ manager ->getParametersFromKeywordOrderedByCategory ($ keyword );
101216 if (!empty ($ settingsFromKeyword )) {
102217 foreach ($ settingsFromKeyword as $ category => $ parameterList ) {
@@ -145,6 +260,9 @@ public function searchSetting(Request $request, AccessUrlHelper $accessUrlHelper
145260 'template_map_by_category ' => $ templateMapByCategory ,
146261 'ordered_namespaces ' => $ ordered ,
147262 'namespace_labels ' => $ labelMap ,
263+ 'changeable_map ' => $ changeableMap ,
264+ 'current_url_id ' => $ currentUrlId ,
265+ 'can_toggle_multiurl_setting ' => $ canToggleMultiUrlSetting ,
148266 ]);
149267 }
150268
@@ -230,17 +348,48 @@ public function updateSetting(Request $request, AccessUrlHelper $accessUrlHelper
230348 $ templateMap = [];
231349 $ settingsRepo = $ this ->entityManager ->getRepository (SettingsCurrent::class);
232350
233- $ settingsWithTemplate = $ settingsRepo ->findBy (['url ' => $ url ]);
351+ $ currentUrlId = (int ) $ url ->getId ();
352+ $ mainUrl = $ this ->entityManager ->getRepository (AccessUrl::class)->find (1 );
234353
354+ // Build template map: fallback to main URL templates when sub-URL has no row for a locked setting.
355+ if ($ mainUrl instanceof AccessUrl && 1 !== $ currentUrlId ) {
356+ $ mainRows = $ settingsRepo ->findBy (['url ' => $ mainUrl ]);
357+ foreach ($ mainRows as $ s ) {
358+ if ($ s ->getValueTemplate ()) {
359+ $ templateMap [$ s ->getVariable ()] = $ s ->getValueTemplate ()->getId ();
360+ }
361+ }
362+ }
363+
364+ $ settingsWithTemplate = $ settingsRepo ->findBy (['url ' => $ url ]);
235365 foreach ($ settingsWithTemplate as $ s ) {
236366 if ($ s ->getValueTemplate ()) {
237367 $ templateMap [$ s ->getVariable ()] = $ s ->getValueTemplate ()->getId ();
238368 }
239369 }
370+
371+ // MultiURL changeable flags: read from main URL (ID = 1) only
372+ $ changeableMap = [];
373+ $ mainUrlRows = $ settingsRepo ->createQueryBuilder ('sc ' )
374+ ->join ('sc.url ' , 'u ' )
375+ ->andWhere ('u.id = :mainId ' )
376+ ->setParameter ('mainId ' , 1 )
377+ ->getQuery ()
378+ ->getResult ();
379+
380+ foreach ($ mainUrlRows as $ row ) {
381+ if ($ row instanceof SettingsCurrent) {
382+ $ changeableMap [$ row ->getVariable ()] = $ row ->getAccessUrlChangeable ();
383+ }
384+ }
385+
240386 $ platform = [
241387 'server_type ' => (string ) $ manager ->getSetting ('platform.server_type ' , true ),
242388 ];
243389
390+ // Only platform admins on the main URL can toggle the MultiURL flag.
391+ $ canToggleMultiUrlSetting = $ this ->isGranted ('ROLE_ADMIN ' ) && 1 === $ currentUrlId ;
392+
244393 return $ this ->render ('@ChamiloCore/Admin/Settings/default.html.twig ' , [
245394 'schemas ' => $ schemas ,
246395 'settings ' => $ settings ,
@@ -251,6 +400,9 @@ public function updateSetting(Request $request, AccessUrlHelper $accessUrlHelper
251400 'ordered_namespaces ' => $ ordered ,
252401 'namespace_labels ' => $ labelMap ,
253402 'platform ' => $ platform ,
403+ 'changeable_map ' => $ changeableMap ,
404+ 'current_url_id ' => $ currentUrlId ,
405+ 'can_toggle_multiurl_setting ' => $ canToggleMultiUrlSetting ,
254406 'search_diagnostics ' => $ searchDiagnostics ,
255407 ]);
256408 }
@@ -369,12 +521,6 @@ private function computeOrderedNamespacesByTranslatedLabel(array $schemas, Reque
369521
370522 /**
371523 * Build environment diagnostics for the "search" settings page.
372- *
373- * This replicates the legacy Chamilo 1 behaviour:
374- * - Check Xapian PHP extension
375- * - Check the index directory and permissions
376- * - Check custom search fields
377- * - Check external converters (pdftotext, ps2pdf, ...)
378524 */
379525 private function buildSearchDiagnostics (SettingsManager $ manager ): array
380526 {
0 commit comments