Skip to content

Commit f490bdd

Browse files
Merge pull request #7060 from christianbeeznest/GH-6207
Admin: Restore MultiURL settings eye toggle per URL - refs #6207
2 parents 7a91fa0 + cdfba22 commit f490bdd

File tree

7 files changed

+1339
-188
lines changed

7 files changed

+1339
-188
lines changed

public/main/inc/lib/urlmanager.lib.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Chamilo\CoreBundle\Entity\AccessUrlRelSession;
88
use Chamilo\CoreBundle\Entity\AccessUrlRelUser;
99
use Chamilo\CoreBundle\Entity\AccessUrlRelUserGroup;
10+
use Chamilo\CoreBundle\Entity\SettingsCurrent;
1011
use Chamilo\CoreBundle\Entity\UserAuthSource;
1112
use Chamilo\CoreBundle\Framework\Container;
1213
use Doctrine\ORM\NonUniqueResultException;
@@ -98,12 +99,13 @@ public static function delete($id)
9899

99100
/*
100101
* $tableCourseCategory = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
101-
$sql = "DELETE FROM $tableCourseCategory WHERE access_url_id = ".$id;
102-
Database::query($sql);
103-
*/
102+
* $sql = "DELETE FROM $tableCourseCategory WHERE access_url_id = ".$id;
103+
* Database::query($sql);
104+
*/
104105
$em = Container::getEntityManager();
105106

106107
$relEntities = [
108+
SettingsCurrent::class,
107109
AccessUrlRelCourse::class,
108110
AccessUrlRelSession::class,
109111
AccessUrlRelUserGroup::class,

src/CoreBundle/Controller/Admin/SettingsController.php

Lines changed: 162 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
namespace Chamilo\CoreBundle\Controller\Admin;
88

99
use Chamilo\CoreBundle\Controller\BaseController;
10+
use Chamilo\CoreBundle\Entity\AccessUrl;
1011
use Chamilo\CoreBundle\Entity\SearchEngineField;
1112
use Chamilo\CoreBundle\Entity\SettingsCurrent;
1213
use 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
{
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/* For licensing terms, see /license.txt */
6+
7+
namespace Chamilo\CoreBundle\Migrations\Schema\V200;
8+
9+
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo;
10+
use Doctrine\DBAL\Schema\Schema;
11+
12+
final class Version20251213154100 extends AbstractMigrationChamilo
13+
{
14+
public function getDescription(): string
15+
{
16+
return 'Set settings.access_url_locked to 0 for all rows (MultiURL default unlock).';
17+
}
18+
19+
public function up(Schema $schema): void
20+
{
21+
$this->addSql('UPDATE settings SET access_url_locked = 0 WHERE access_url_locked IS NULL OR access_url_locked = 1');
22+
}
23+
24+
public function down(Schema $schema): void
25+
{
26+
// Revert to previous "locked everywhere" behavior (not recommended, but reversible).
27+
$this->addSql('UPDATE settings SET access_url_locked = 1 WHERE access_url_locked = 0');
28+
}
29+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/* For licensing terms, see /license.txt */
6+
7+
namespace Chamilo\CoreBundle\Migrations\Schema\V200;
8+
9+
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo;
10+
use Doctrine\DBAL\Schema\Schema;
11+
12+
final class Version20251215074200 extends AbstractMigrationChamilo
13+
{
14+
public function getDescription(): string
15+
{
16+
return 'MultiURL: lock selected global settings (access_url_locked = 1).';
17+
}
18+
19+
public function up(Schema $schema): void
20+
{
21+
$this->addSql("
22+
UPDATE settings
23+
SET access_url_locked = 1
24+
WHERE variable IN (
25+
'permissions_for_new_directories',
26+
'permissions_for_new_files',
27+
'course_creation_form_set_extra_fields_mandatory',
28+
'access_url_specific_files',
29+
'cron_remind_course_finished_activate',
30+
'cron_remind_course_expiration_frequency',
31+
'cron_remind_course_expiration_activate',
32+
'donotlistcampus',
33+
'server_type',
34+
'chamilo_database_version',
35+
'unoconv_binaries',
36+
'session_admin_access_to_all_users_on_all_urls',
37+
'split_users_upload_directory',
38+
'multiple_url_hide_disabled_settings',
39+
'login_is_email',
40+
'proxy_settings',
41+
'login_max_attempt_before_blocking_account',
42+
'permanently_remove_deleted_files',
43+
'allow_use_sub_language'
44+
)
45+
");
46+
}
47+
48+
public function down(Schema $schema): void
49+
{
50+
// Unlock back (sub-URLs editable) for the same list.
51+
$this->addSql("
52+
UPDATE settings
53+
SET access_url_locked = 0
54+
WHERE variable IN (
55+
'permissions_for_new_directories',
56+
'permissions_for_new_files',
57+
'course_creation_form_set_extra_fields_mandatory',
58+
'access_url_specific_files',
59+
'cron_remind_course_finished_activate',
60+
'cron_remind_course_expiration_frequency',
61+
'cron_remind_course_expiration_activate',
62+
'donotlistcampus',
63+
'server_type',
64+
'chamilo_database_version',
65+
'unoconv_binaries',
66+
'session_admin_access_to_all_users_on_all_urls',
67+
'split_users_upload_directory',
68+
'multiple_url_hide_disabled_settings',
69+
'login_is_email',
70+
'proxy_settings',
71+
'login_max_attempt_before_blocking_account',
72+
'permanently_remove_deleted_files',
73+
'allow_use_sub_language'
74+
)
75+
");
76+
}
77+
}

0 commit comments

Comments
 (0)