Fix profile field encoding (#7420)

* Fix profile field encoding

* Update MIGRATE-DEV.md

* Fix profile field encoding

---------

Co-authored-by: Lucas Bartholemy <luke-@users.noreply.github.com>
This commit is contained in:
Yuriy Bakhtin 2025-02-06 19:57:29 +01:00 committed by GitHub
parent ae3502fe82
commit ad0b0c8b86
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 115 additions and 76 deletions

View File

@ -11,6 +11,7 @@ HumHub Changelog
- Fix #7400: Fixed `Default user profile visibility` field visibility in the user settings
- Fix #7404: Marketplace - Allow symlinked `@app/modules` directory
- Fix: Always allow admins to edit/delete content in the other Profile stream
- Fix #7414: Fix profile field encoding
- Fix #7419: Reset modal window after close
1.17.0 (January 13, 2025)

View File

@ -1,8 +1,16 @@
Module Migration Guide
======================
Version 1.17.1
---------------
Version 1.17 (Unreleased)
### Behaviour change
- Method signature changed - `humhub\modules\user\models\fieldtype\BaseType::getUserValue(User $user, bool $raw = true, bool $encode = true): ?string`
Version 1.17
-------------------------
### Behaviour change

View File

@ -413,9 +413,10 @@ class Profile extends ActiveRecord
*
* @param string $field
* @param bool $raw
* @param bool $encode
* @return string|null
*/
public function getFieldValue(string $field, bool $raw = false): ?string
public function getFieldValue(string $field, bool $raw = false, bool $encode = true): ?string
{
if (!$this->hasAttribute($field) || !$this->user) {
return null;
@ -423,6 +424,6 @@ class Profile extends ActiveRecord
$profileField = ProfileField::findOne(['internal_name' => $field]);
return $profileField?->getUserValue($this->user, $raw);
return $profileField?->getUserValue($this->user, $raw, $encode);
}
}

View File

@ -309,11 +309,11 @@ class ProfileField extends ActiveRecord
*
* @param User $user
* @param bool $raw
* @return string
* @return string|null
*/
public function getUserValue(User $user, $raw = true): ?string
public function getUserValue(User $user, bool $raw = true, bool $encode = true): ?string
{
return $this->fieldType->getUserValue($user, $raw);
return $this->fieldType->getUserValue($user, $raw, $encode);
}
/**

View File

@ -699,7 +699,7 @@ class User extends ContentContainerActiveRecord implements IdentityInterface
}
if ($this->profile !== null) {
return $this->profile->getFieldValue(Yii::$app->settings->get('displayNameSubFormat', '')) ?? '';
return $this->profile->getFieldValue(Yii::$app->settings->get('displayNameSubFormat', ''), false, false) ?? '';
}
return '';

View File

@ -352,17 +352,14 @@ class BaseType extends Model
*
* @param User $user
* @param bool $raw
* @return string
* @param bool $encode
* @return string|null
*/
public function getUserValue(User $user, $raw = true): ?string
public function getUserValue(User $user, bool $raw = true, bool $encode = true): ?string
{
$internalName = $this->profileField->internal_name;
$value = $user->profile->{$this->profileField->internal_name} ?? '';
if ($raw) {
return $user->profile->$internalName;
} else {
return Html::encode($user->profile->$internalName);
}
return $encode ? Html::encode($value) : $value;
}
/**

View File

@ -34,9 +34,9 @@ abstract class BaseTypeVirtual extends BaseType
/**
* @inheritdoc
*/
final public function getUserValue(User $user, $raw = true): ?string
final public function getUserValue(User $user, bool $raw = true, bool $encode = true): ?string
{
return $this->getVirtualUserValue($user, $raw);
return $this->getVirtualUserValue($user, $raw, $encode);
}
/**
@ -71,13 +71,14 @@ abstract class BaseTypeVirtual extends BaseType
}
/**
* Returns the readonly virutal value for the given User
* Returns the readonly virtual value for the given User
*
* @param User $user
* @param bool $raw
* @return mixed
* @param bool $encode
* @return string
*/
abstract protected function getVirtualUserValue($user, $raw = true);
abstract protected function getVirtualUserValue(User $user, bool $raw = true, bool $encode = true): string;
/**
* @inheritDoc

View File

@ -177,7 +177,7 @@ class Birthday extends BaseType
/**
* @inheritdoc
*/
public function getUserValue(User $user, $raw = true): ?string
public function getUserValue(User $user, bool $raw = true, bool $encode = true): ?string
{
$internalName = $this->profileField->internal_name;
$birthdayDate = \DateTime::createFromFormat(

View File

@ -8,6 +8,7 @@
namespace humhub\modules\user\models\fieldtype;
use humhub\libs\Html;
use humhub\modules\user\models\Profile;
use humhub\modules\user\models\User;
use Yii;
@ -108,16 +109,19 @@ class Checkbox extends BaseType
/**
* @inheritdoc
*/
public function getUserValue(User $user, $raw = true): ?string
public function getUserValue(User $user, bool $raw = true, bool $encode = true): ?string
{
$internalName = $this->profileField->internal_name;
$value = $user->profile->$internalName;
if (!$raw && !empty($value)) {
$labels = $this->getLabels();
return $labels[$internalName];
if (empty($value)) {
return '';
}
return $value;
if (!$raw) {
$value = $this->getLabels()[$internalName] ?? '';
}
return $encode ? Html::encode($value) : $value;
}
}

View File

@ -164,14 +164,13 @@ class CheckboxList extends BaseType
/**
* @inheritdoc
*/
public function getUserValue(User $user, $raw = true): ?string
public function getUserValue(User $user, bool $raw = true, bool $encode = true): ?string
{
$internalName = $this->profileField->internal_name;
$internalNameOther = $internalName . '_other_selection';
$value = $user->profile->$internalName;
if (!$raw && $value !== null) {
$options = $this->getSelectItems();
$translatedValues = [];
if (is_string($value)) {
@ -179,15 +178,14 @@ class CheckboxList extends BaseType
}
foreach ($value as $v) {
if ($v === 'other' && !empty($user->profile->$internalNameOther)) {
$translatedValues[] = Html::encode($user->profile->$internalNameOther);
$translatedValues[] = $user->profile->$internalNameOther;
} elseif (isset($options[$v])) {
$translatedValues[] = Html::encode(Yii::t($this->profileField->getTranslationCategory(), $options[$v]));
$translatedValues[] = Yii::t($this->profileField->getTranslationCategory(), $options[$v]);
}
}
return implode(', ', $translatedValues);
$value = implode(', ', $translatedValues);
}
return $value;
return $encode ? Html::encode($value) : $value;
}
}

View File

@ -89,16 +89,20 @@ class CountrySelect extends Select
/**
* @inheritdoc
*/
public function getUserValue(User $user, $raw = true): ?string
public function getUserValue(User $user, bool $raw = true, bool $encode = true): ?string
{
$internalName = $this->profileField->internal_name;
$value = $user->profile->$internalName;
$value = $user->profile->$internalName ?? '';
if (!$raw) {
return Html::encode(Iso3166Codes::country($value));
if (empty($value)) {
return '';
}
return $value;
if (!$raw) {
$value = Iso3166Codes::country($value);
}
return $encode ? Html::encode($value) : $value;
}
/**

View File

@ -79,20 +79,25 @@ class Date extends BaseType
/**
* @inheritdoc
*/
public function getUserValue(User $user, $raw = true): ?string
public function getUserValue(User $user, bool $raw = true, bool $encode = true): ?string
{
$internalName = $this->profileField->internal_name;
$value = $user->profile->$internalName ?? '';
$date = \DateTime::createFromFormat(
'Y-m-d',
$user->profile->$internalName ?? '',
$value,
new DateTimeZone(Yii::$app->formatter->timeZone),
);
if ($date === false) {
return "";
return '';
}
return $raw ? Html::encode($user->profile->$internalName) : Yii::$app->formatter->asDate($date, 'long');
if (!$raw) {
$value = Yii::$app->formatter->asDate($date, 'long');
}
return $encode ? Html::encode($value) : $value;
}
}

View File

@ -110,21 +110,25 @@ class DateTime extends BaseType
/**
* @inheritdoc
*/
public function getUserValue(User $user, $raw = true): ?string
public function getUserValue(User $user, bool $raw = true, bool $encode = true): ?string
{
$internalName = $this->profileField->internal_name;
$value = $user->profile->$internalName ?? '';
$date = \DateTime::createFromFormat(
'Y-m-d H:i:s',
$user->profile->$internalName ?? '',
$value,
new DateTimeZone(Yii::$app->formatter->timeZone),
);
if ($date === false) {
return "";
return '';
}
return $raw ? Html::encode($user->profile->$internalName) : Yii::$app->formatter->asDatetime($date, 'long');
if (!$raw) {
$value = Yii::$app->formatter->asDatetime($date, 'long');
}
return $encode ? Html::encode($value) : $value;
}
}

View File

@ -115,19 +115,19 @@ class Select extends BaseType
/**
* @inheritdoc
*/
public function getUserValue(User $user, $raw = true): ?string
public function getUserValue(User $user, bool $raw = true, bool $encode = true): ?string
{
$internalName = $this->profileField->internal_name;
$value = $user->profile->$internalName;
$value = $user->profile->$internalName ?? '';
if (!$raw) {
$options = $this->getSelectItems();
if (isset($options[$value])) {
return Html::encode(Yii::t($this->profileField->getTranslationCategory(), $options[$value]));
$value = Yii::t($this->profileField->getTranslationCategory(), $options[$value]);
}
}
return $value;
return $encode ? Html::encode($value) : $value;
}
}

View File

@ -31,13 +31,13 @@ class Template extends BaseType
];
}
public function getUserValue($user, $raw = true): ?string
public function getUserValue($user, bool $raw = true, bool $encode = true): ?string
{
$variables = ArrayHelper::map(
$user->profile->getProfileFields(null, [static::class]),
'internal_name',
function (ProfileField $profileField) use ($user) {
return $profileField->getUserValue($user);
function (ProfileField $profileField) use ($user, $raw, $encode) {
return $profileField->getUserValue($user, $raw, $encode);
},
);

View File

@ -207,17 +207,17 @@ class Text extends BaseType
/**
* @inheritdoc
*/
public function getUserValue(User $user, $raw = true): string
public function getUserValue(User $user, bool $raw = true, bool $encode = true): ?string
{
$internalName = $this->profileField->internal_name;
$value = $user->profile->$internalName;
$value = $user->profile->$internalName ?? '';
if (!$raw && (in_array($this->validator, [self::VALIDATOR_EMAIL, self::VALIDATOR_URL]) || !empty($this->linkPrefix))) {
$linkPrefix = ($this->validator === self::VALIDATOR_EMAIL) ? 'mailto:' : $this->linkPrefix;
return Html::a(Html::encode($value), $linkPrefix . $value);
return Html::a($encode ? Html::encode($value) : $value, $linkPrefix . $value);
}
return Html::encode($value);
return $encode ? Html::encode($value) : $value;
}
}

View File

@ -9,6 +9,7 @@
namespace humhub\modules\user\models\fieldtype;
use humhub\libs\Html;
use humhub\modules\user\models\User;
/**
* UserEmail is a virtual profile field
@ -19,18 +20,20 @@ use humhub\libs\Html;
class UserEmail extends BaseTypeVirtual
{
/**
* @inheritDoc
* @inheritdoc
*/
public function getVirtualUserValue($user, $raw = true)
protected function getVirtualUserValue(User $user, bool $raw = true, bool $encode = true): string
{
if (empty($user->email)) {
return '';
}
if ($raw) {
return Html::encode($user->email);
} else {
return Html::a(Html::encode($user->email), 'mailto:' . $user->email);
$value = $encode ? Html::encode($user->email) : $user->email;
if (!$raw) {
return Html::a($value, 'mailto:' . $user->email);
}
return $value;
}
}

View File

@ -9,6 +9,7 @@
namespace humhub\modules\user\models\fieldtype;
use humhub\libs\Html;
use humhub\modules\user\models\User;
use Yii;
use yii\base\InvalidConfigException;
@ -21,15 +22,20 @@ use yii\base\InvalidConfigException;
class UserLastLogin extends BaseTypeVirtual
{
/**
* @inheritDoc
* @inheritdoc
* @throws InvalidConfigException
*/
public function getVirtualUserValue($user, $raw = true)
protected function getVirtualUserValue(User $user, bool $raw = true, bool $encode = true): string
{
if (empty($user->last_login)) {
$value = $user->last_login;
if (empty($value)) {
return '-';
}
return Yii::$app->formatter->asDate($user->last_login, 'long');
if (!$raw) {
$value = Yii::$app->formatter->asDate($value, 'long');
}
return $encode ? Html::encode($value) : $value;
}
}

View File

@ -9,6 +9,7 @@
namespace humhub\modules\user\models\fieldtype;
use humhub\libs\Html;
use humhub\modules\user\models\User;
use Yii;
/**
@ -20,14 +21,19 @@ use Yii;
class UserMemberSince extends BaseTypeVirtual
{
/**
* @inheritDoc
* @inheritdoc
*/
public function getVirtualUserValue($user, $raw = true)
public function getVirtualUserValue(User $user, bool $raw = true, bool $encode = true): string
{
if (empty($user->created_at)) {
$value = $user->created_at;
if (empty($value)) {
return '';
}
return Yii::$app->formatter->asDate($user->created_at, 'long');
if (!$raw) {
$value = Yii::$app->formatter->asDate($value, 'long');
}
return $encode ? Html::encode($value) : $value;
}
}

View File

@ -9,6 +9,7 @@
namespace humhub\modules\user\models\fieldtype;
use humhub\libs\Html;
use humhub\modules\user\models\User;
/**
* UserName is a virtual profile field
@ -21,12 +22,12 @@ class UserName extends BaseTypeVirtual
/**
* @inheritDoc
*/
public function getVirtualUserValue($user, $raw = true)
public function getVirtualUserValue(User $user, bool $raw = true, bool $encode = true): string
{
if (empty($user->username)) {
return '';
}
return Html::encode($user->username);
return $encode ? Html::encode($user->username) : $user->username;
}
}

View File

@ -42,7 +42,7 @@ $categories = $user->profile->getProfileFieldCategories();
</label>
<div class="col-sm-9 field-value">
<?= ($field->field_type_class === MarkdownEditor::class) ?
RichText::output($field->getUserValue($user, true)) :
RichText::output($field->getUserValue($user, true, false)) :
$field->getUserValue($user, false) ?>
</div>
</div>