Skip to content

User: Fix signup notification translations - refs #22823 #6564

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Aug 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 167 additions & 34 deletions public/main/inc/lib/usermanager.lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
use Chamilo\CoreBundle\Event\UserCreatedEvent;
use Chamilo\CoreBundle\Event\UserUpdatedEvent;
use Chamilo\CoreBundle\Framework\Container;
use Chamilo\CoreBundle\Repository\LanguageRepository;
use Chamilo\CoreBundle\Repository\Node\UserRepository;
use Chamilo\CoreBundle\Helpers\NameConventionHelper;
use ChamiloSession as Session;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Contracts\Translation\TranslatorInterface;

/**
* This library provides functions for user management.
Expand Down Expand Up @@ -534,50 +536,44 @@ public static function create_user(
}
}

/** @var TranslatorInterface $translator */
$translator = Container::$container->get('translator');
$currentLocale = $translator->getLocale();

if ($sendEmailToAllAdmins) {
$adminList = self::get_all_administrators();
// variables for the default template
$renderer = FormValidator::getDefaultRenderer();
// Form template
$elementTemplate = ' {label}: {element} <br />';
$renderer->setElementTemplate($elementTemplate);
/** @var FormValidator $form */
$form->freeze(null, $elementTemplate);
$form->removeElement('submit');
$form->removeElement('pass1');
$form->removeElement('pass2');
$formData = $form->returnForm();
$url = api_get_path(WEB_CODE_PATH).'admin/user_information.php?user_id='.$user->getId();
$params = [
'complete_name' => stripslashes(api_get_person_name($firstName, $lastName)),
'user_added' => $user,
'link' => Display::url($url, $url),
'form' => $formData,
'user_language' => $user->getLocale(),
];
$emailBody = $tpl->render(
'@ChamiloCore/Mailer/Legacy/content_registration_platform_to_admin.html.twig',
$params
);

if (!empty($emailBodyTemplate) &&
isset($emailTemplate['content_registration_platform_to_admin.tpl']) &&
!empty($emailTemplate['content_registration_platform_to_admin.tpl'])
) {
$emailBody = $mailTemplateManager->parseTemplate(
$emailTemplate['content_registration_platform_to_admin.tpl'],
$userInfo
foreach ($adminList as $adminId => $adminData) {
$adminLocale = $adminData['locale'] ?? 'en_US';
$translator->setLocale($adminLocale);

$profileHtml = self::renderRegistrationProfileHtml($user, $extra ?? [], $adminLocale);
$userLanguageName = self::resolveLanguageName($user->getLocale());

$params = [
'complete_name' => stripslashes(api_get_person_name($firstName, $lastName)),
'user_added' => $user,
'link' => Display::url($url, $url),
'form' => $profileHtml,
'user_language' => $userLanguageName,
];

$emailBody = $tpl->render(
'@ChamiloCore/Mailer/Legacy/content_registration_platform_to_admin.html.twig',
$params
);
}

$subject = get_lang('The user has been added');
foreach ($adminList as $adminId => $data) {
$subject = get_lang('The user has been added', $adminLocale);

MessageManager::send_message_simple(
$adminId,
$subject,
$emailBody,
$userId
);

$translator->setLocale($currentLocale);
}
}
}
Expand Down Expand Up @@ -606,6 +602,143 @@ public static function create_user(
return $userId;
}

/**
* Returns the human-readable language name for a given ISO code.
*
* Accepts ISO 639-1/2 codes (e.g. "en", "es", "eng"). If $iso is null or the
* code is unknown, an empty string is returned.
*
* @param string|null $iso Two- or three-letter ISO 639 language code.
* @return string Language name in English (e.g. "English", "Spanish").
*/
private static function resolveLanguageName(?string $iso): string
{
if (empty($iso)) {
return '';
}

/** @var LanguageRepository $langRepo */
$langRepo = Container::$container->get(LanguageRepository::class);
$entity = $langRepo->findOneBy(['isocode' => $iso]);

return $entity ? $entity->getOriginalName() : $iso;
}

/**
* Build the “profile” HTML (core + dynamic extra fields) for the admin email, localized in $adminLocale.
*
* @param User $user
* @param array $extraParams Raw POST values from registration (keys: "extra_*").
* @param string $adminLocale e.g. "es_ES", "fr_FR".
*/
private static function renderRegistrationProfileHtml(User $user, array $extraParams, string $adminLocale): string
{
$statusLabel = ((int) $user->getStatus() === COURSEMANAGER)
? get_lang('Teach courses', $adminLocale)
: get_lang('Follow courses', $adminLocale);

$languageName = $user->getLocale();
$langRepo = Container::$container->get(LanguageRepository::class);
if ($langRepo && ($lang = $langRepo->findOneBy(['isocode' => $user->getLocale()]))) {
$languageName = $lang->getOriginalName();
}

$corePairs = [
get_lang('e-mail', $adminLocale) => (string) $user->getEmail(),
get_lang('First name', $adminLocale) => (string) $user->getFirstname(),
get_lang('Last name', $adminLocale) => (string) $user->getLastname(),
get_lang('Username', $adminLocale) => (string) $user->getUsername(),
get_lang('Official code', $adminLocale) => (string) ($user->getOfficialCode() ?? ''),
get_lang('Phone', $adminLocale) => (string) ($user->getPhone() ?? ''),
get_lang('User address', $adminLocale) => (string) ($user->getAddress() ?? ''),
get_lang('Language', $adminLocale) => (string) $languageName,
get_lang('What do you want to do?', $adminLocale) => $statusLabel,
];

if ($user->getDateOfBirth() instanceof \DateTimeInterface) {
$corePairs[get_lang('Date of birth', $adminLocale)] = $user->getDateOfBirth()->format('Y-m-d');
}

$efv = new \ExtraFieldValue('user');
$ef = new \ExtraField('user');

$extraPairs = [];
$presentVars = [];
$rows = $efv->getAllValuesByItem((int) $user->getId());

if (is_array($rows)) {
foreach ($rows as $row) {
$fieldId = (int)$row['id'];
$variable = (string)$row['variable'];
$presentVars[$variable] = true;

$tr = $efv->get_values_by_handler_and_field_id((int) $user->getId(), $fieldId, true);
$val = null;

if ($tr && array_key_exists('value', $tr)) {
$val = $tr['value'];
} else {
$val = $row['value'];
}

$type = (int)$row['value_type'];
if ($type === \ExtraField::FIELD_TYPE_CHECKBOX) {
$val = ((string)$val === '1') ? get_lang('Yes', $adminLocale) : get_lang('No', $adminLocale);
}
if ($type === \ExtraField::FIELD_TYPE_TAG && is_array($val)) {
$val = implode(', ', array_map(fn($t) => is_array($t) ? (string)($t['value'] ?? '') : (string)$t, $val));
}
if (is_string($val)) {
$val = str_replace(['<br />','<br>','<br/>'], ', ', $val);
}

$label = !empty($row['display_text'])
? get_lang($row['display_text'], $adminLocale)
: get_lang(ucwords(str_replace('_',' ',$variable)), $adminLocale);

if ($val !== '' && $val !== null) {
$extraPairs[$label] = (string)$val;
}
}
}

foreach ($extraParams as $k => $v) {
if (strpos($k, 'extra_') !== 0) continue;
$variable = substr($k, 6);
if (isset($presentVars[$variable])) continue;

$def = $ef->get_handler_field_info_by_field_variable($variable);
$label = $def && !empty($def['display_text'])
? get_lang($def['display_text'], $adminLocale)
: get_lang(ucwords(str_replace('_',' ',$variable)), $adminLocale);

$val = $v;
if (is_array($val)) {
$val = implode(', ', array_map('strval', $val));
} elseif ($val === '1') {
$val = get_lang('Yes', $adminLocale);
} elseif ($val === '0') {
$val = get_lang('No', $adminLocale);
}

if ($val !== '' && $val !== null) {
$extraPairs[$label] = (string)$val;
}
}

$html = '<div class="form-horizontal">';
foreach ($corePairs as $k => $v) {
if ($v === '' || $v === null) continue;
$html .= '<div>'.$k.': '.\Security::remove_XSS((string)$v).'</div>';
}
foreach ($extraPairs as $k => $v) {
$html .= '<div>'.$k.': '.\Security::remove_XSS((string)$v).'</div>';
}
$html .= '</div>';

return $html;
}

/**
* Can user be deleted? This function checks whether there's a course
* in which the given user is the
Expand Down Expand Up @@ -3797,15 +3930,15 @@ public static function get_all_administrators()
$tbl_url_rel_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
$access_url_id = api_get_current_access_url_id();
if (api_get_multiple_access_url()) {
$sql = "SELECT admin.user_id, username, firstname, lastname, email, active
$sql = "SELECT admin.user_id, username, firstname, lastname, email, active, locale
FROM $tbl_url_rel_user as url
INNER JOIN $table_admin as admin
ON (admin.user_id=url.user_id)
INNER JOIN $table_user u
ON (u.id=admin.user_id)
WHERE access_url_id ='".$access_url_id."'";
} else {
$sql = "SELECT admin.user_id, username, firstname, lastname, email, active
$sql = "SELECT admin.user_id, username, firstname, lastname, email, active, locale
FROM $table_admin as admin
INNER JOIN $table_user u
ON (u.id=admin.user_id)";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{% autoescape false %}
<p>{{ 'User %s with language %s registered to the site'|trans|format(complete_name, user_language) }} </p>
<p>{{ 'His profile is'|trans }} </p>
<div class="row">
<div class="col-xs-12 col-md-12">
<div class="form-horizontal">
{{ form }}
<p>{{ 'User %s with language %s registered to the site'|trans|format(complete_name, user_language) }}</p>
<p>{{ 'His profile is'|trans }}</p>

<div class="row">
<div class="col-xs-12 col-md-12">
<div class="form-horizontal">
{{ form|raw }}
</div>
</div>
</div>
</div>

<p>{{ 'You can assign a tutor in this link %s'|trans|format(link)}} </p>

{% include '@ChamiloCore/Mailer/Legacy/_admin_signature_footer.html.twig' %}
<p>{{ 'You can assign a tutor in this link %s'|trans|format(link) }}</p>
{% include '@ChamiloCore/Mailer/Legacy/_admin_signature_footer.html.twig' %}
{% endautoescape %}
Loading