Skip to content
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
7 changes: 7 additions & 0 deletions com.woltlab.wcf/option.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,13 @@ silhouette:wcf.acp.option.avatar_default_type.silhouette</selectoptions>
<optiontype>boolean</optiontype>
<defaultvalue>1</defaultvalue>
</option>
<option name="user_cover_photo_default_type">
<categoryname>user.profile</categoryname>
<optiontype>select</optiontype>
<defaultvalue>generated</defaultvalue>
<selectoptions>generated:wcf.acp.option.user_cover_photo_default_type.generated
style:wcf.acp.option.user_cover_photo_default_type.style</selectoptions>
</option>
<!-- /user.profile -->
<!-- user.list.members -->
<option name="members_list_users_per_page">
Expand Down
2 changes: 1 addition & 1 deletion com.woltlab.wcf/templates/userProfileHeader.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
{if $view->canEditCoverPhoto()}
<ul class="userProfileManageCoverPhoto buttonGroup buttonList smallButtons">
<li>
<button type="button" data-edit-cover-photo="{link controller="UserCoverPhoto" id=$user->userID}{/link}" data-default-cover-photo="{$__wcf->styleHandler->getStyle()->getCoverPhotoUrl()}" class="button small">
<button type="button" data-edit-cover-photo="{link controller="UserCoverPhoto" id=$user->userID}{/link}" data-default-cover-photo="{$view->user->getDefaultCoverPhoto()->getURL()}" class="button small">
{icon name='camera'}
<span>{lang}wcf.user.coverPhoto.edit{/lang}</span>
</button>
Expand Down
1 change: 1 addition & 0 deletions constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@
\define('OG_IMAGE', '');
\define('HEAD_CODE', '');
\define('AVATAR_DEFAULT_TYPE', 'initials');
\define('USER_COVER_PHOTO_DEFAULT_TYPE', 'generated');
\define('ARTICLE_ENABLE_VISIT_TRACKING', 1);
\define('ENABLE_AD_ROTATION', 1);
\define('ENABLE_POLLING', 1);
Expand Down
1 change: 1 addition & 0 deletions phpstan-ambient.neon
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ parameters:
- OG_IMAGE
- HEAD_CODE
- AVATAR_DEFAULT_TYPE
- USER_COVER_PHOTO_DEFAULT_TYPE
- ARTICLE_ENABLE_VISIT_TRACKING
- ENABLE_AD_ROTATION
- ENABLE_POLLING
Expand Down
19 changes: 18 additions & 1 deletion wcfsetup/install/files/lib/data/user/UserProfile.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use wcf\data\user\avatar\IUserAvatar;
use wcf\data\user\avatar\StaticAvatar;
use wcf\data\user\cover\photo\DefaultUserCoverPhoto;
use wcf\data\user\cover\photo\GeneratedUserCoverPhoto;
use wcf\data\user\cover\photo\IUserCoverPhoto;
use wcf\data\user\cover\photo\UserCoverPhoto;
use wcf\data\user\group\UserGroup;
Expand Down Expand Up @@ -437,13 +438,29 @@ public function getCoverPhoto(bool $isACP = false)

// use default cover photo
if ($this->coverPhoto === null) {
$this->coverPhoto = new DefaultUserCoverPhoto();
$this->coverPhoto = $this->getDefaultCoverPhoto();
}
}

return $this->coverPhoto;
}

/**
* Returns the cover photo that is shown if the user has no cover photo. Depending
* on the option `USER_COVER_PHOTO_DEFAULT_TYPE`, this is either the cover photo of
* the style or an individual cover photo that is generated for each user.
*
* @since 6.3
*/
public function getDefaultCoverPhoto(): IUserCoverPhoto
{
if (\USER_COVER_PHOTO_DEFAULT_TYPE === 'generated') {
return new GeneratedUserCoverPhoto($this->username);
}

return new DefaultUserCoverPhoto();
}

/**
* Returns true if the active user can view the cover photo of this user.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace wcf\data\user\cover\photo;

use wcf\system\image\cover\photo\generator\CoverPhotoGenerator;

/**
* Represents a default cover photo that is generated for each user individually.
*
* @author Marcel Werk
* @copyright 2001-2026 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.3
*/
final class GeneratedUserCoverPhoto extends DefaultUserCoverPhoto
{
private string $url;

public function __construct(
private readonly string $username,
) {}

#[\Override]
public function getURL(?bool $forceWebP = null): string
{
if (!isset($this->url)) {
$this->url = CoverPhotoGenerator::forActiveStyle()->getDataUri('user-' . \mb_strtolower($this->username));
}

return $this->url;
}
}
Loading
Loading