Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
26eee07
fix(speakers): stop gating populated speaker-profile fields on the ac…
smarcet Sep 3, 2026
b64a6b9
fix(speakers): honor account visibility toggle on name/photo Member f…
smarcet Sep 3, 2026
654ca0e
fix(speakers): remove residual unconditional name fallback in base se…
smarcet Sep 5, 2026
6cb6647
fix(presentations): bypass account visibility toggle for admin/track-…
smarcet Sep 5, 2026
ba5636b
fix(speakers): add override_permission to the photo fallback and fix …
smarcet Sep 7, 2026
01ac6a2
test(speakers): cover the base-serializer name-fallback regression at…
smarcet Sep 7, 2026
417c68b
fix(speakers): scope the Rule 9 toggle bypass to admin and self, not …
smarcet Sep 7, 2026
0caf27c
style(speakers): normalize whitespace in PresentationSpeakerBaseSeria…
smarcet Sep 7, 2026
c54152c
fix(speakers): pass override_permission at every internal caller of t…
smarcet Sep 7, 2026
91190cb
test(speakers): pin the Member name fallback for admin merge and audi…
smarcet Sep 7, 2026
dcb227a
test(speakers): annotate Mockery helpers for PHPStan and pin the name…
smarcet Sep 7, 2026
b0246a3
fix(speakers): resolve the caller before bypassing the name toggle in…
smarcet Sep 7, 2026
b3c4823
test(speakers): pin the CC and owner_name caller rules for the Member…
smarcet Sep 7, 2026
47a9080
fix(speakers): pass override_permission at the reopen-notification re…
smarcet Sep 8, 2026
33dcb24
test(speakers): pin the Member name fallback in the reopen notificati…
smarcet Sep 8, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public function format($subject, $change_set): ?string
});
} else if ($old_value instanceof PresentationSpeaker || $new_value instanceof PresentationSpeaker) {
$res[] = self::formatEntity($class_name, $prop_name, $old_value, $new_value, function ($value) {
return " \"{$value->getFullName()} ({$value->getEmail()})\" ";
return " \"{$value->getFullName(true)} ({$value->getEmail()})\" ";
});
} else if ($old_value instanceof File || $new_value instanceof File) {
$res[] = self::formatEntity($class_name, $prop_name, $old_value, $new_value, function ($value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function format($subject, array $change_set): ?string
try {
$speaker = $subject->getSpeaker();
$speaker_email = $speaker ? ($speaker->getEmail() ?? 'unknown') : 'unknown';
$speaker_name = $speaker ? sprintf("%s %s", $speaker->getFirstName() ?? '', $speaker->getLastName() ?? '') : 'Unknown';
$speaker_name = $speaker ? sprintf("%s %s", $speaker->getFirstName(true) ?? '', $speaker->getLastName(true) ?? '') : 'Unknown';
$speaker_name = trim($speaker_name) ?: $speaker_name;
$speaker_id = $speaker ? ($speaker->getId() ?? 'unknown') : 'unknown';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function format($subject, array $change_set): ?string
}

try {
$full_name = sprintf("%s %s", $subject->getFirstName() ?? 'Unknown', $subject->getLastName() ?? 'Unknown');
$full_name = sprintf("%s %s", $subject->getFirstName(true) ?? 'Unknown', $subject->getLastName(true) ?? 'Unknown');
$email = $subject->getEmail() ?? 'unknown';
$speaker_id = $subject->getId() ?? 'unknown';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function format($subject, array $change_set): ?string
$id = $subject->getId() ?? 'unknown';

$speaker = $subject->getSpeaker();
$speaker_name = $speaker ? sprintf("%s %s", $speaker->getFirstName() ?? '', $speaker->getLastName() ?? '') : 'Unknown Speaker';
$speaker_name = $speaker ? sprintf("%s %s", $speaker->getFirstName(true) ?? '', $speaker->getLastName(true) ?? '') : 'Unknown Speaker';
$speaker_email = $speaker ? ($speaker->getEmail() ?? 'unknown') : 'unknown';
$speaker_name = trim($speaker_name) ?: $speaker_email;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function format($subject, array $change_set): ?string

try {
$speaker = $subject->getSpeaker();
$speaker_name = $speaker ? sprintf("%s %s", $speaker->getFirstName() ?? '', $speaker->getLastName() ?? '') : 'Unknown';
$speaker_name = $speaker ? sprintf("%s %s", $speaker->getFirstName(true) ?? '', $speaker->getLastName(true) ?? '') : 'Unknown';
$speaker_email = $speaker ? ($speaker->getEmail() ?? 'unknown') : 'unknown';
$speaker_name = trim($speaker_name) ?: $speaker_email;
$speaker_id = $speaker ? ($speaker->getId() ?? 'unknown') : 'unknown';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function format($subject, array $change_set): ?string
try {
$email = $subject->getEmail() ?? 'unknown';
$speaker = $subject->getSpeaker();
$speaker_name = $speaker ? sprintf("%s %s", $speaker->getFirstName() ?? '', $speaker->getLastName() ?? '') : 'Unknown';
$speaker_name = $speaker ? sprintf("%s %s", $speaker->getFirstName(true) ?? '', $speaker->getLastName(true) ?? '') : 'Unknown';
$speaker_name = trim($speaker_name) ?: 'Unknown';
$is_confirmed = $subject->isConfirmed();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function format($subject, array $change_set): ?string
$full_name = trim(sprintf("%s %s", $first_name, $last_name)) ?: 'Unknown';
$is_sent = $subject->isSent();
$speaker = $subject->getSpeaker();
$speaker_name = $speaker ? sprintf("%s %s", $speaker->getFirstName() ?? '', $speaker->getLastName() ?? '') : 'None';
$speaker_name = $speaker ? sprintf("%s %s", $speaker->getFirstName(true) ?? '', $speaker->getLastName(true) ?? '') : 'None';
$speaker_name = trim($speaker_name) ?: 'None';
$id = $subject->getId() ?? 'unknown';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public function __construct(Presentation $presentation, PresentationSpeaker $spe
}
$payload[IMailTemplatesConstants::reset_password_link] = sprintf("%s/auth/password/reset", $idp_base_url);
$payload[IMailTemplatesConstants::support_email] = $support_email;
$payload[IMailTemplatesConstants::speaker_full_name] = $speaker->getFullName(' ');
$payload[IMailTemplatesConstants::speaker_full_name] = $speaker->getFullName(true);
if(empty($payload[IMailTemplatesConstants::speaker_full_name])){
$payload[IMailTemplatesConstants::speaker_full_name] = $speaker->getEmail();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public function __construct(PresentationSpeaker $moderator, Presentation $presen

$payload = [];

$payload[IMailTemplatesConstants::speaker_full_name] = $moderator->getFullName(" ");
$payload[IMailTemplatesConstants::speaker_full_name] = $moderator->getFullName(true);
$payload[IMailTemplatesConstants::speaker_email] = $moderator->getEmail();
$payload[IMailTemplatesConstants::creator_full_name] = $creator->getFullName();
$payload[IMailTemplatesConstants::creator_email] = $creator->getEmail();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public function __construct(PresentationSpeaker $speaker, Presentation $presenta

$payload = [];

$payload[IMailTemplatesConstants::speaker_full_name] = $speaker->getFullName(" ");
$payload[IMailTemplatesConstants::speaker_full_name] = $speaker->getFullName(true);
$payload[IMailTemplatesConstants::speaker_email] = $speaker->getEmail();
$payload[IMailTemplatesConstants::creator_full_name] = $creator->getFullName();
$payload[IMailTemplatesConstants::creator_email] = $creator->getEmail();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,11 @@ public function __construct
}

$speaker_email = $speaker->getEmail();
$speaker_full_name = $speaker->getFullName();
// The Member name fallback may bypass the account visibility toggle only when the delivery
// is self-addressed. With submitter copies on, this same payload is CC'd to the creators of
// the speaker's presentations - non-admin third parties - so the fallback must honor the
// toggle (policy/profile-data-handling.md Rule 9) and the greeting falls back to the email.
$speaker_full_name = $speaker->getFullName(count($cc_email) === 0);

// set to email if fullname is empty
if(empty($speaker_full_name)){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public function __construct
if(empty($submitter_full_name)){
// check if we have a first and last name at speaker level
if($submitter->hasSpeaker()){
$submitter_full_name = $submitter->getSpeaker()->getFullName();
$submitter_full_name = $submitter->getSpeaker()->getFullName(true);
}
if(empty($submitter_full_name)) {
// fallback to email
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function __construct(PresentationSpeaker $speaker)
throw new \InvalidArgumentException('cfp.support_email is null.');

$payload = [];
$payload[IMailTemplatesConstants::speaker_full_name] = $speaker->getFullName();
$payload[IMailTemplatesConstants::speaker_full_name] = $speaker->getFullName(true);
$payload[IMailTemplatesConstants::speaker_email] = $speaker->getEmail();
$payload[IMailTemplatesConstants::speaker_management_link] = $speaker_management_base_url;
$bio_edit_link = sprintf("%s/app/profile", $speaker_management_base_url);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ public function __construct(SpeakerEditPermissionRequest $request)
{
$payload = [];
$payload[IMailTemplatesConstants::requested_by_full_name] = $request->getRequestedBy()->getFullName();
// the recipient is the requester (a non-admin third party), so the speaker's Member name
// fallback must honor the account visibility toggle (policy/profile-data-handling.md
// Rule 9). Deliberately NOT passing override_permission.
$payload[IMailTemplatesConstants::speaker_full_name] = $request->getSpeaker()->getFullName();
$payload[IMailTemplatesConstants::speaker_management_link] = EmailUtils::getSpeakerManagementLink();
$payload[IMailTemplatesConstants::tenant_name] = Config::get("app.tenant_name");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ public function __construct(SpeakerEditPermissionRequest $request)
{
$payload = [];
$payload[IMailTemplatesConstants::requested_by_full_name] = $request->getRequestedBy()->getFullName();
// the recipient is the requester (a non-admin third party), so the speaker's Member name
// fallback must honor the account visibility toggle (policy/profile-data-handling.md
// Rule 9). Deliberately NOT passing override_permission.
$payload[IMailTemplatesConstants::speaker_full_name] = $request->getSpeaker()->getFullName();
$payload[IMailTemplatesConstants::speaker_management_link] = EmailUtils::getSpeakerManagementLink();
$payload[IMailTemplatesConstants::tenant_name] = Config::get("app.tenant_name");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ public function __construct(SpeakerEditPermissionRequest $request, string $token
{
$payload = [];
$payload[IMailTemplatesConstants::requested_by_full_name] = $request->getRequestedBy()->getFullName();
$payload[IMailTemplatesConstants::speaker_full_name] = $request->getSpeaker()->getFullName();
// self-addressed: the recipient is the speaker, so the Member name fallback bypasses the
// account visibility toggle (policy/profile-data-handling.md Rule 9 scope)
$payload[IMailTemplatesConstants::speaker_full_name] = $request->getSpeaker()->getFullName(true);
$payload[IMailTemplatesConstants::token] = $token;
$payload[IMailTemplatesConstants::link] = $request->getConfirmationLink($request->getSpeaker()->getId(), $token);
$payload[IMailTemplatesConstants::tenant_name] = Config::get("app.tenant_name");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public function __construct(Presentation $presentation, PresentationSpeaker $spe
$summit = $presentation->getSummit();

$payload = [];
$payload[IMailTemplatesConstants::speaker_full_name] = $speaker->getFullName(" ");
$payload[IMailTemplatesConstants::speaker_full_name] = $speaker->getFullName(true);
$payload[IMailTemplatesConstants::speaker_email] = $speaker->getEmail();
$payload[IMailTemplatesConstants::presentation_title] = $presentation->getTitle();
$payload[IMailTemplatesConstants::presentation_id] = $presentation->getId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ public function serialize($expand = null, array $fields = [], array $relations =
if(is_null($speaker)) continue;
$res[] = [
'id' => $speaker->getId(),
'first_name' => $speaker->getFirstName(),
'last_name' => $speaker->getLastName(),
'first_name' => $speaker->getFirstName(true),
'last_name' => $speaker->getLastName(true),
'email' => $speaker->getEmail(),
];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public function serialize($expand = null, array $fields = [], array $relations =
if(in_array("moderator_id",$fields))
$values['moderator_id'] = $presentation->getModerator()->getId();
if(in_array("moderator_full_name",$fields))
$values['moderator_full_name'] = $presentation->getModerator()->getFullName();
$values['moderator_full_name'] = $presentation->getModerator()->getFullName(true);
if(in_array("moderator_email",$fields))
$values['moderator_email'] = $presentation->getModerator()->getEmail();
if(in_array("moderator_title",$fields))
Expand Down Expand Up @@ -122,7 +122,7 @@ public function serialize($expand = null, array $fields = [], array $relations =

foreach ($presentation->getSpeakers() as $speaker) {
$speaker_ids[] = $speaker->getId();
$speaker_fullnames[] = $speaker->getFullName();
$speaker_fullnames[] = $speaker->getFullName(true);
$speaker_emails[] = $speaker->getEmail();
$speaker_titles[] = trim($speaker->getTitle());
$speaker_companies[] = trim($speaker->getCompany());
Expand Down Expand Up @@ -164,7 +164,7 @@ public function serialize($expand = null, array $fields = [], array $relations =
if(in_array("submitter_id",$fields))
$values['submitter_id'] = $submitter->getId();
if(in_array("submitter_full_name",$fields))
$values['submitter_full_name'] = $submitter->getFullName();
$values['submitter_full_name'] = $submitter->getFullName(true);
if(in_array("submitter_email",$fields))
$values['submitter_email'] = $submitter->getEmail();
if(in_array("submitter_title",$fields))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ public function serialize($expand = null, array $fields = [], array $relations =
];
}

// Co-speaker / moderator names below are rendered to non-admin recipients (the submitter
// and the other speakers of this presentation), so the Member name fallback must honor the
// account visibility toggle here (policy/profile-data-handling.md Rule 9), exactly as the
// CFP portal's public serializer does for the same speaker (Rule 5). Deliberately NOT
// passing override_permission to getFullName().
$speakers = [];
foreach ($presentation->getSpeakers() as $speaker){
$speakers[] = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public function serialize($expand = null, array $fields = [], array $relations =

if ($presentation->hasModerator()) {
$values['moderator_id'] = $presentation->getModerator()->getId();
$values['moderator_full_name'] = $presentation->getModerator()->getFullName();
$values['moderator_full_name'] = $presentation->getModerator()->getFullName(true);
$values['moderator_email'] = $presentation->getModerator()->getEmail();
$values['moderator_title'] = trim($presentation->getModerator()->getTitle());
$values['moderator_company'] = trim($presentation->getModerator()->getCompany());
Expand All @@ -119,7 +119,7 @@ public function serialize($expand = null, array $fields = [], array $relations =

foreach ($presentation->getSpeakers() as $speaker) {
$speaker_ids[] = $speaker->getId();
$speaker_fullnames[] = $speaker->getFullName();
$speaker_fullnames[] = $speaker->getFullName(true);
$speaker_emails[] = $speaker->getEmail();
$speaker_titles[] = trim($speaker->getTitle());
$speaker_companies[] = trim($speaker->getCompany());
Expand All @@ -145,7 +145,7 @@ public function serialize($expand = null, array $fields = [], array $relations =
if ($creator->hasSpeaker()) {
$submitter = $creator->getSpeaker();
$values['submitter_id'] = $submitter->getId();
$values['submitter_full_name'] = $submitter->getFullName();
$values['submitter_full_name'] = $submitter->getFullName(true);
$values['submitter_email'] = $submitter->getEmail();
$values['submitter_title'] = $submitter->getTitle();
$values['submitter_company'] = $submitter->getCompany();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* limitations under the License.
**/

use App\ModelSerializers\Traits\AccountVisibilityToggleBypass;
use Libs\ModelSerializers\AbstractSerializer;
use models\summit\SpeakerSummitRegistrationDiscountCode;
/**
Expand All @@ -21,6 +22,8 @@
class SpeakerSummitRegistrationDiscountCodeSerializer
extends SummitRegistrationDiscountCodeSerializer
{
use AccountVisibilityToggleBypass;

protected static $array_mappings = [
'Type' => 'type:json_string',
'SpeakerId' => 'speaker_id:json_int',
Expand Down Expand Up @@ -64,7 +67,11 @@ public function serialize($expand = null, array $fields = [], array $relations =
break;
case 'owner_name': {
if($code->hasSpeaker()){
$values['owner_name'] = $code->getSpeaker()->getFullName();
// admin tooling or the owner themself may bypass the account
// visibility toggle on the Member name fallback; anyone else who
// reaches this serializer indirectly must not (policy Rule 9)
$speaker = $code->getSpeaker();
$values['owner_name'] = $speaker->getFullName($this->canBypassAccountVisibilityToggle($speaker));
}
}
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* limitations under the License.
**/

use App\ModelSerializers\Traits\AccountVisibilityToggleBypass;
use Libs\ModelSerializers\AbstractSerializer;
use models\summit\SpeakerSummitRegistrationPromoCode;
/**
Expand All @@ -21,6 +22,8 @@
class SpeakerSummitRegistrationPromoCodeSerializer
extends SummitRegistrationPromoCodeSerializer
{
use AccountVisibilityToggleBypass;

protected static $array_mappings = [
'Type' => 'type:json_string',
'SpeakerId' => 'speaker_id:json_int',
Expand Down Expand Up @@ -64,7 +67,11 @@ public function serialize($expand = null, array $fields = [], array $relations =
break;
case 'owner_name': {
if($code->hasSpeaker()){
$values['owner_name'] = $code->getSpeaker()->getFullName();
// admin tooling or the owner themself may bypass the account
// visibility toggle on the Member name fallback; anyone else who
// reaches this serializer indirectly must not (policy Rule 9)
$speaker = $code->getSpeaker();
$values['owner_name'] = $speaker->getFullName($this->canBypassAccountVisibilityToggle($speaker));
}
}
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function serialize($expand = null, array $fields = [], array $relations =
$owner_name = [];
$owner_email = [];
foreach($code->getOwners() as $owner){
$owner_name[] = $owner->getSpeaker()->getFullName();
$owner_name[] = $owner->getSpeaker()->getFullName(true);
$owner_email[] = $owner->getSpeaker()->getEmail();

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function serialize($expand = null, array $fields = [], array $relations =
$owner_name = [];
$owner_email = [];
foreach($code->getOwners() as $owner){
$owner_name[] = $owner->getSpeaker()->getFullName();
$owner_name[] = $owner->getSpeaker()->getFullName(true);
$owner_email[] = $owner->getSpeaker()->getEmail();

}
Expand Down
Loading
Loading