Skip to content

Commit 32dd599

Browse files
committed
Merge branch 'master' of github.com:chamilo/chamilo-lms
2 parents e762d41 + 5d860ae commit 32dd599

File tree

10 files changed

+519
-78
lines changed

10 files changed

+519
-78
lines changed

public/main/exercise/exercise.class.php

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9213,6 +9213,13 @@ public static function exerciseGridResource(
92139213
// 2. Get query builder from repo.
92149214
$qb = $repo->getResourcesByCourse($course, $session);
92159215

9216+
if (!empty($sessionId)) {
9217+
$qb->andWhere('(links.session = :sess OR links.session IS NULL)')
9218+
->setParameter('sess', $session);
9219+
} else {
9220+
$qb->andWhere('links.session IS NULL');
9221+
}
9222+
92169223
if (!empty($categoryId)) {
92179224
$qb->andWhere($qb->expr()->eq('resource.quizCategory', $categoryId));
92189225
} else {
@@ -9267,12 +9274,8 @@ public static function exerciseGridResource(
92679274
$qb->setParameter('keyword', '%'.$keyword.'%');
92689275
}
92699276

9270-
// Only for administrators
92719277
if (!$is_allowedToEdit) {
9272-
$qb
9273-
->leftJoin('resource.resourceNode', 'rn')
9274-
->leftJoin('rn.resourceLinks', 'rl')
9275-
->andWhere('rl.visibility = :published')
9278+
$qb->andWhere('links.visibility = :published')
92769279
->setParameter('published', ResourceLink::VISIBILITY_PUBLISHED);
92779280
}
92789281

@@ -9316,30 +9319,26 @@ public static function exerciseGridResource(
93169319

93179320
$sessionId = api_get_session_id();
93189321
$allowToEditBaseCourse = true;
9319-
$visibility = $visibilityInCourse = $exerciseEntity->isVisible($course);
9320-
$visibilityInSession = false;
9321-
if (!empty($sessionId)) {
9322-
// If we are in a session, the test is invisible
9323-
// in the base course, it is included in a LP
9324-
// *and* the setting to show it is *not*
9325-
// specifically set to true, then hide it.
9326-
if (false === $visibility) {
9327-
if (!$visibilitySetting) {
9328-
if ($exercise->exercise_was_added_in_lp) {
9329-
continue;
9330-
}
9331-
}
9332-
}
9333-
9334-
$visibility = $visibilityInSession = $exerciseEntity->isVisible($course, $session);
9322+
$visibleBase = $exerciseEntity->isVisible($course);
9323+
$visibleSess = !empty($sessionId) ? $exerciseEntity->isVisible($course, $session) : null;
9324+
if ($visibleSess === true) {
9325+
$visibleForStudent = true;
9326+
} elseif ($visibleSess === false) {
9327+
$visibleForStudent = false;
9328+
} else {
9329+
$visibleForStudent = $visibleBase;
93359330
}
93369331

9337-
// Validation when belongs to a session
9338-
$isBaseCourseExercise = true;
9339-
if (!($visibilityInCourse && $visibilityInSession)) {
9340-
$isBaseCourseExercise = false;
9332+
$visibleForTeacher = true;
9333+
9334+
if (!$is_allowedToEdit && !empty($sessionId)) {
9335+
$visibilitySetting = ('true' === api_get_setting('lp.show_hidden_exercise_added_to_lp'));
9336+
if (!$visibleBase && !$visibilitySetting && $exercise->exercise_was_added_in_lp) {
9337+
continue;
9338+
}
93419339
}
93429340

9341+
$isBaseCourseExercise = $visibleBase && ($visibleSess === null || $visibleSess === true);
93439342
if (!empty($sessionId) && $isBaseCourseExercise) {
93449343
$allowToEditBaseCourse = false;
93459344
}
@@ -9414,10 +9413,7 @@ public static function exerciseGridResource(
94149413
);
94159414
}
94169415

9417-
$style = '';
9418-
if (!$visibility) {
9419-
$style = 'color:grey';
9420-
}
9416+
$style = $visibleForStudent ? '' : 'color:grey';
94219417

94229418
$title = $cut_title;
94239419

@@ -9710,12 +9706,7 @@ public static function exerciseGridResource(
97109706
$currentRow['count_questions'] = $number_of_questions;
97119707
} else {
97129708
// Student only.
9713-
$visibility = $exerciseEntity->isVisible($course, null);
9714-
if (false === $visibility && !empty($sessionId)) {
9715-
$visibility = $exerciseEntity->isVisible($course, $session);
9716-
}
9717-
9718-
if (false === $visibility) {
9709+
if (!$visibleForStudent) {
97199710
continue;
97209711
}
97219712

public/main/exercise/exercise_submit.php

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,11 +1441,25 @@ function save_question_list(question_list) {
14411441
var remind_list = $(\'*[name*="remind_list"]\').serialize();
14421442
var hotspot = $(\'*[name*="hotspot[\'+qid+\']"]\').serialize();
14431443
var dc = $(\'*[name*="choiceDegreeCertainty[\'+qid+\']"]\').serialize();
1444-
var dataStr = "'.$params.'&type=simple&question_id="+qid
1445-
+"&"+my_choice
1446-
+ (hotspot ? "&"+hotspot : "")
1447-
+ (remind_list ? "&"+remind_list : "")
1448-
+ (dc ? "&"+dc : "");
1444+
1445+
var editorContent = getContentFromEditor("choice"+qid);
1446+
var free_choice = "";
1447+
if (editorContent) {
1448+
var obj = {};
1449+
obj["choice["+qid+"]"] = editorContent;
1450+
my_choice = $.param(obj);
1451+
var fo = {};
1452+
fo["free_choice["+qid+"]"] = editorContent;
1453+
free_choice = $.param(fo);
1454+
}
1455+
1456+
var dataStr = "'.$params.'&type=simple&question_id="+qid
1457+
+"&"+my_choice
1458+
+ (hotspot ? "&"+hotspot : "")
1459+
+ (remind_list ? "&"+remind_list : "")
1460+
+ (dc ? "&"+dc : "")
1461+
+ (free_choice ? "&"+free_choice : "");
1462+
14491463
return $.ajax({
14501464
type: "POST",
14511465
url: "'.api_get_path(WEB_AJAX_PATH).'exercise.ajax.php?'.api_get_cidreq().'&a=save_exercise_by_now",

public/main/inc/ajax/exercise.ajax.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -643,10 +643,15 @@
643643
$my_choice = 'assets:' . count($uploadAnswerAssetIds[$my_question_id] ?? []);
644644
}
645645
// Getting free choice data.
646-
if (in_array($objQuestionTmp->type, [FREE_ANSWER, ORAL_EXPRESSION]) && 'all' == $type) {
647-
$my_choice = isset($_REQUEST['free_choice'][$my_question_id]) && !empty($_REQUEST['free_choice'][$my_question_id])
648-
? $_REQUEST['free_choice'][$my_question_id]
649-
: null;
646+
if (in_array($objQuestionTmp->type, [FREE_ANSWER, ORAL_EXPRESSION])) {
647+
if ('all' === $type) {
648+
$my_choice = $_REQUEST['free_choice'][$my_question_id] ?? $my_choice;
649+
} elseif ('simple' === $type && isset($_REQUEST['free_choice'][$my_question_id]) && $_REQUEST['free_choice'][$my_question_id] !== '') {
650+
$my_choice = $_REQUEST['free_choice'][$my_question_id];
651+
}
652+
if (is_string($my_choice)) {
653+
$my_choice = trim($my_choice);
654+
}
650655
}
651656

652657
if ('all' === $type) {

src/CoreBundle/DataFixtures/SettingsCurrentFixtures.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3704,6 +3704,11 @@ public static function getNewConfigurationSettings(): array
37043704
'title' => 'Image generator',
37053705
'comment' => 'Generates images based on prompts or content using AI.',
37063706
],
3707+
[
3708+
'name' => 'disclose_ai_assistance',
3709+
'title' => 'Disclose AI assistance',
3710+
'comment' => 'Show a tag on any content or feedback that has been generated or co-generated by any AI system, evidencing to the user that the content was built with the help of some AI system. Details about which AI system was used in which case are kept inside the database for audit, but are not directly accessible by the final user.',
3711+
],
37073712
],
37083713
];
37093714
}

src/CoreBundle/Entity/AiRequests.php

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@
1212
use Doctrine\ORM\Mapping as ORM;
1313
use Symfony\Component\Validator\Constraints as Assert;
1414

15-
#[ORM\Table(name: 'ai_requests')]
15+
#[ORM\Table(
16+
name: 'ai_requests',
17+
indexes: [
18+
new ORM\Index(columns: ['tool_name', 'tool_item_id'], name: 'idx_ai_requests_lookup'),
19+
]
20+
)]
1621
#[ORM\Entity(repositoryClass: AiRequestsRepository::class)]
1722
class AiRequests
1823
{
@@ -29,6 +34,9 @@ class AiRequests
2934
#[ORM\Column(type: 'string', length: 255)]
3035
private string $toolName;
3136

37+
#[ORM\Column(type: 'bigint', nullable: true)]
38+
private ?int $toolItemId = null;
39+
3240
#[Assert\NotBlank]
3341
#[ORM\Column(type: 'datetime')]
3442
private DateTimeInterface $requestedAt;
@@ -50,6 +58,12 @@ class AiRequests
5058
#[ORM\Column(type: 'string', length: 50)]
5159
private string $aiProvider;
5260

61+
#[ORM\Column(type: 'string', length: 255, nullable: true)]
62+
private ?string $aiModel = null;
63+
64+
#[ORM\Column(type: 'text', nullable: true)]
65+
private ?string $aiEndpoint = null;
66+
5367
public function __construct()
5468
{
5569
$this->requestedAt = new DateTime();
@@ -84,6 +98,18 @@ public function setToolName(string $toolName): self
8498
return $this;
8599
}
86100

101+
public function getToolItemId(): ?int
102+
{
103+
return $this->toolItemId;
104+
}
105+
106+
public function setToolItemId(?int $toolItemId): self
107+
{
108+
$this->toolItemId = $toolItemId;
109+
110+
return $this;
111+
}
112+
87113
public function getRequestedAt(): DateTimeInterface
88114
{
89115
return $this->requestedAt;
@@ -148,4 +174,28 @@ public function setAiProvider(string $aiProvider): self
148174

149175
return $this;
150176
}
177+
178+
public function getAiModel(): ?string
179+
{
180+
return $this->aiModel;
181+
}
182+
183+
public function setAiModel(?string $aiModel): self
184+
{
185+
$this->aiModel = $aiModel;
186+
187+
return $this;
188+
}
189+
190+
public function getAiEndpoint(): ?string
191+
{
192+
return $this->aiEndpoint;
193+
}
194+
195+
public function setAiEndpoint(?string $aiEndpoint): self
196+
{
197+
$this->aiEndpoint = $aiEndpoint;
198+
199+
return $this;
200+
}
151201
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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 Version20250905071600 extends AbstractMigrationChamilo
13+
{
14+
public function getDescription(): string
15+
{
16+
return 'Extend ai_requests with tool_item_id, ai_model, ai_endpoint and add composite index for lookup.';
17+
}
18+
19+
public function up(Schema $schema): void
20+
{
21+
$schemaManager = $this->connection->createSchemaManager();
22+
$table = $schemaManager->introspectTable('ai_requests');
23+
24+
$hasToolItemId = $table->hasColumn('tool_item_id');
25+
$hasAiModel = $table->hasColumn('ai_model');
26+
$hasAiEndpoint = $table->hasColumn('ai_endpoint');
27+
28+
if (!$hasToolItemId) {
29+
$this->addSql('ALTER TABLE ai_requests ADD tool_item_id BIGINT NULL AFTER tool_name');
30+
}
31+
32+
if (!$hasAiModel) {
33+
$this->addSql('ALTER TABLE ai_requests ADD ai_model VARCHAR(255) NULL');
34+
}
35+
36+
if (!$hasAiEndpoint) {
37+
$this->addSql('ALTER TABLE ai_requests ADD ai_endpoint TEXT NULL');
38+
}
39+
40+
// Add composite index for quick lookups when rendering
41+
$indexes = array_map(static fn($i) => $i->getName(), $table->getIndexes());
42+
if (!in_array('idx_ai_requests_lookup', $indexes, true)) {
43+
$this->addSql('CREATE INDEX idx_ai_requests_lookup ON ai_requests (tool_name, tool_item_id)');
44+
}
45+
}
46+
47+
public function down(Schema $schema): void
48+
{
49+
$schemaManager = $this->connection->createSchemaManager();
50+
$table = $schemaManager->introspectTable('ai_requests');
51+
52+
$indexes = array_map(static fn($i) => $i->getName(), $table->getIndexes());
53+
if (in_array('idx_ai_requests_lookup', $indexes, true)) {
54+
$this->addSql('DROP INDEX idx_ai_requests_lookup ON ai_requests');
55+
}
56+
57+
if ($table->hasColumn('ai_endpoint')) {
58+
$this->addSql('ALTER TABLE ai_requests DROP COLUMN ai_endpoint');
59+
}
60+
if ($table->hasColumn('ai_model')) {
61+
$this->addSql('ALTER TABLE ai_requests DROP COLUMN ai_model');
62+
}
63+
if ($table->hasColumn('tool_item_id')) {
64+
$this->addSql('ALTER TABLE ai_requests DROP COLUMN tool_item_id');
65+
}
66+
}
67+
}

0 commit comments

Comments
 (0)