Skip to content

Commit 7ba7aee

Browse files
Merge pull request #8601 from christianbeeznest/fixes-plugin-buycourse10
Plugin: Fix BuyCourses purchase and course limit bugs
2 parents 996c4f1 + 1c24e1a commit 7ba7aee

4 files changed

Lines changed: 124 additions & 36 deletions

File tree

public/main/user/user.php

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -481,19 +481,26 @@
481481
}
482482
}
483483

484-
// Global hosting limit: precompute a simple snapshot for UI purposes only.
485-
$globalLimitUsersPerCourse = 0;
486-
$currentUsersForGlobalLimit = 0;
487-
$courseIsFullForGlobalLimit = false;
484+
// Users-per-course limit: precompute a simple snapshot for UI purposes only.
485+
$usersPerCourseLimit = 0;
486+
$currentUsersForCourseLimit = 0;
487+
$courseIsFullForUsersPerCourseLimit = false;
488488

489489
if ($canEdit && 0 === (int) $sessionId) {
490-
// Read the global limit through CourseManager helper to keep logic centralized.
491-
$globalLimitUsersPerCourse = (int) CourseManager::getGlobalUsersPerCourseLimit();
490+
if (method_exists('CourseManager', 'getEffectiveUsersPerCourseLimit')) {
491+
$usersPerCourseLimit = (int) CourseManager::getEffectiveUsersPerCourseLimit($courseId);
492+
} else {
493+
$usersPerCourseLimit = (int) CourseManager::getGlobalUsersPerCourseLimit();
494+
}
495+
496+
if ($usersPerCourseLimit > 0) {
497+
if (method_exists('CourseManager', 'countStudentsForUsersPerCourseLimit')) {
498+
$currentUsersForCourseLimit = (int) CourseManager::countStudentsForUsersPerCourseLimit($courseId);
499+
} else {
500+
$currentUsersForCourseLimit = (int) CourseManager::countUsersForGlobalLimit($courseId);
501+
}
492502

493-
if ($globalLimitUsersPerCourse > 0) {
494-
// Count current users for the limit, excluding HR relation type.
495-
$currentUsersForGlobalLimit = (int) CourseManager::countUsersForGlobalLimit($courseId);
496-
$courseIsFullForGlobalLimit = $currentUsersForGlobalLimit >= $globalLimitUsersPerCourse;
503+
$courseIsFullForUsersPerCourseLimit = $currentUsersForCourseLimit >= $usersPerCourseLimit;
497504
}
498505
}
499506

@@ -628,10 +635,10 @@
628635

629636
$actionsLeft = '';
630637
if ($canEdit) {
631-
// When the global hosting limit is enabled and already reached (no session),
638+
// When the users-per-course limit is enabled and already reached (no session),
632639
// we hide the "Add" icon to avoid actions that would add more users.
633640
$canShowAddIcon = true;
634-
if (0 === (int) $sessionId && $globalLimitUsersPerCourse > 0 && $courseIsFullForGlobalLimit) {
641+
if (0 === (int) $sessionId && $usersPerCourseLimit > 0 && $courseIsFullForUsersPerCourseLimit) {
635642
$canShowAddIcon = false;
636643
}
637644

@@ -683,15 +690,20 @@
683690
echo UserManager::getUserSubscriptionTab($selectedTab);
684691
echo Display::toolbarAction('toolbar', [$actionsLeft, $actionsRight]);
685692

686-
// When the course is full according to the global limit (no session),
693+
// When the course is full according to the effective limit (global or BuyCourses),
687694
// show an explicit warning so teachers understand why the Add icon is hidden.
688-
if ($canEdit && 0 === (int) $sessionId && $globalLimitUsersPerCourse > 0 && $courseIsFullForGlobalLimit) {
689-
$msg = sprintf(
690-
get_lang(
691-
'This course already reached the global limit of %d users set by the administrators. To add more users, please ask an administrator to raise this limit or use sessions.'
692-
),
693-
$globalLimitUsersPerCourse
694-
);
695+
if ($canEdit && 0 === (int) $sessionId && $usersPerCourseLimit > 0 && $courseIsFullForUsersPerCourseLimit) {
696+
if (method_exists('CourseManager', 'getUsersPerCourseLimitCancelMessage')) {
697+
$msg = CourseManager::getUsersPerCourseLimitCancelMessage($courseId);
698+
} else {
699+
$msg = sprintf(
700+
get_lang(
701+
'This operation would exceed the limit of %d users allowed for this course.'
702+
),
703+
$usersPerCourseLimit
704+
);
705+
}
706+
695707
echo Display::return_message($msg, 'warning');
696708
}
697709
}

public/plugin/BuyCourses/src/buy_course_plugin.class.php

Lines changed: 90 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6246,19 +6246,45 @@ private function saveUserExtraFieldTextValue(int $userId, int $extraFieldId, str
62466246
$checkResult = Database::query($checkSql);
62476247

62486248
if ($checkResult && Database::num_rows($checkResult) > 0) {
6249-
Database::query("UPDATE $table
6250-
SET $valueColumn = '$escapedValue'
6251-
WHERE field_id = $extraFieldId
6252-
AND item_id = $userId");
6249+
$updateData = [
6250+
$valueColumn => $value,
6251+
];
6252+
6253+
if (in_array('updated_at', $this->getExtraFieldValueTimestampColumns(), true)) {
6254+
$updateData['updated_at'] = api_get_utc_datetime();
6255+
}
6256+
6257+
Database::update(
6258+
$table,
6259+
$updateData,
6260+
[
6261+
'field_id = ? AND item_id = ?' => [$extraFieldId, $userId],
6262+
]
6263+
);
62536264

62546265
return;
62556266
}
62566267

6257-
Database::insert($table, [
6268+
$insertData = [
62586269
'field_id' => $extraFieldId,
62596270
'item_id' => $userId,
62606271
$valueColumn => $value,
6261-
]);
6272+
];
6273+
6274+
$timestampColumns = $this->getExtraFieldValueTimestampColumns();
6275+
if (!empty($timestampColumns)) {
6276+
$now = api_get_utc_datetime();
6277+
6278+
if (in_array('created_at', $timestampColumns, true)) {
6279+
$insertData['created_at'] = $now;
6280+
}
6281+
6282+
if (in_array('updated_at', $timestampColumns, true)) {
6283+
$insertData['updated_at'] = $now;
6284+
}
6285+
}
6286+
6287+
Database::insert($table, $insertData);
62626288
}
62636289

62646290
/**
@@ -9194,6 +9220,35 @@ private function getExtraFieldValueColumn(): string
91949220
throw new RuntimeException('No supported value column found in extra_field_values.');
91959221
}
91969222

9223+
/**
9224+
* Return timestamp columns available on extra_field_values.
9225+
* Some Chamilo 2 installations enforce NOT NULL created_at/updated_at.
9226+
*
9227+
* @return string[]
9228+
*/
9229+
private function getExtraFieldValueTimestampColumns(): array
9230+
{
9231+
static $columns = null;
9232+
9233+
if (null !== $columns) {
9234+
return $columns;
9235+
}
9236+
9237+
$columns = [];
9238+
$table = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
9239+
$result = Database::query("SHOW COLUMNS FROM $table");
9240+
9241+
while ($row = Database::fetch_array($result, 'ASSOC')) {
9242+
$fieldName = (string) ($row['Field'] ?? '');
9243+
9244+
if (in_array($fieldName, ['created_at', 'updated_at'], true)) {
9245+
$columns[] = $fieldName;
9246+
}
9247+
}
9248+
9249+
return $columns;
9250+
}
9251+
91979252
/**
91989253
* Return all benefit relations configured for a service.
91999254
*/
@@ -9237,9 +9292,7 @@ public function saveUserExtraFieldJsonValue(int $userId, int $extraFieldId, arra
92379292

92389293
$table = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
92399294
$valueColumn = $this->getExtraFieldValueColumn();
9240-
$jsonValue = Database::escape_string(
9241-
json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
9242-
);
9295+
$jsonValue = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
92439296

92449297
$checkSql = "SELECT id
92459298
FROM $table
@@ -9249,11 +9302,21 @@ public function saveUserExtraFieldJsonValue(int $userId, int $extraFieldId, arra
92499302
$checkResult = Database::query($checkSql);
92509303

92519304
if ($checkResult && Database::num_rows($checkResult) > 0) {
9252-
$sql = "UPDATE $table
9253-
SET $valueColumn = '$jsonValue'
9254-
WHERE field_id = $extraFieldId
9255-
AND item_id = $userId";
9256-
Database::query($sql);
9305+
$updateData = [
9306+
$valueColumn => $jsonValue,
9307+
];
9308+
9309+
if (in_array('updated_at', $this->getExtraFieldValueTimestampColumns(), true)) {
9310+
$updateData['updated_at'] = api_get_utc_datetime();
9311+
}
9312+
9313+
Database::update(
9314+
$table,
9315+
$updateData,
9316+
[
9317+
'field_id = ? AND item_id = ?' => [$extraFieldId, $userId],
9318+
]
9319+
);
92579320

92589321
return;
92599322
}
@@ -9264,6 +9327,19 @@ public function saveUserExtraFieldJsonValue(int $userId, int $extraFieldId, arra
92649327
$valueColumn => $jsonValue,
92659328
];
92669329

9330+
$timestampColumns = $this->getExtraFieldValueTimestampColumns();
9331+
if (!empty($timestampColumns)) {
9332+
$now = api_get_utc_datetime();
9333+
9334+
if (in_array('created_at', $timestampColumns, true)) {
9335+
$insertData['created_at'] = $now;
9336+
}
9337+
9338+
if (in_array('updated_at', $timestampColumns, true)) {
9339+
$insertData['updated_at'] = $now;
9340+
}
9341+
}
9342+
92679343
Database::insert($table, $insertData);
92689344
}
92699345

public/plugin/BuyCourses/view/catalog.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@
498498

499499
{% if service.has_blocking_sale|default(false) %}
500500
<span
501-
class="inline-flex w-full items-center justify-center gap-2 rounded-xl bg-gray-20 px-4 py-2.5 text-sm font-semibold text-gray-50"
501+
class="inline-flex w-full items-center justify-center gap-2 rounded-xl bg-primary/15 px-4 py-2.5 text-sm font-semibold text-primary"
502502
>
503503
<em class="fa fa-check-circle fa-fw"></em>
504504
{{ 'Already purchased'|get_lang }}

public/plugin/BuyCourses/view/index_products.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@
237237
</a>
238238

239239
{% if service.has_blocking_sale|default(false) %}
240-
<span class="inline-flex w-full items-center justify-center gap-2 rounded-xl bg-gray-20 px-4 py-2.5 text-sm font-semibold text-gray-50">
240+
<span class="inline-flex w-full items-center justify-center gap-2 rounded-xl bg-primary/15 px-4 py-2.5 text-sm font-semibold text-primary">
241241
<em class="fa fa-check-circle fa-fw"></em>
242242
{{ 'Already purchased'|get_lang }}
243243
</span>

0 commit comments

Comments
 (0)