diff --git a/CHANGELOG.md b/CHANGELOG.md index ac413c39b96..4cf9d540b0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -759,6 +759,7 @@ - Updated Fabric.js to v7. ([#19628](https://github.com/craftcms/cms/pull/19628)) ### Bug Fixes +- Fixed a bug where workflow notifications showed an empty title (“”) for untitled drafts, such as new entries submitted for review before they had a title. - Fixed a bug where spreadsheet cells containing line breaks or tabs were split across several Table field cells when pasted, with their quotes left in. - Fixed a bug where site error templates weren’t rendered, and unknown site URLs returned an empty 404 response. ([#20448](https://github.com/craftcms/cms/pull/20448)) - Fixed a bug where `config/redirects.php` rules weren’t applied. ([#20448](https://github.com/craftcms/cms/pull/20448)) diff --git a/src/Workflow/UserReview/SendUserReviewNotifications.php b/src/Workflow/UserReview/SendUserReviewNotifications.php index 2fcfb6c0f44..0ecdf1c8cca 100644 --- a/src/Workflow/UserReview/SendUserReviewNotifications.php +++ b/src/Workflow/UserReview/SendUserReviewNotifications.php @@ -60,7 +60,7 @@ private function sendApproved(WorkflowTransitioned $event, ?WorkflowStageData $s $recipients, 'workflow_approved', t('Draft approved'), - t('“{entry}” completed its approval workflow.', ['entry' => $event->draft->title]), + t('“{entry}” completed its approval workflow.', ['entry' => $event->draft->getUiLabel()]), ); } @@ -72,7 +72,7 @@ private function sendChangesRequested(WorkflowTransitioned $event, ?WorkflowStag collect([$event->run->author]), 'workflow_changes_requested', t('Changes requested'), - t('{user} requested changes to “{entry}”.', ['user' => $this->actorName($event), 'entry' => $event->draft->title]), + t('{user} requested changes to “{entry}”.', ['user' => $this->actorName($event), 'entry' => $event->draft->getUiLabel()]), ); } @@ -92,7 +92,7 @@ private function sendReviewRequested(WorkflowTransitioned $event, ?WorkflowStage 'workflow_review_requested', t('Review requested'), t('“{entry}” is awaiting your approval in {stage}.', [ - 'entry' => $event->draft->title, + 'entry' => $event->draft->getUiLabel(), 'stage' => t($stage->name), ]), ); @@ -110,7 +110,7 @@ private function sendCommented(WorkflowCommented $event): void $recipients, 'workflow_review_commented', t('New review comment'), - t('{user} commented on the review for “{entry}”.', ['user' => $this->actorName($event), 'entry' => $event->draft->title]), + t('{user} commented on the review for “{entry}”.', ['user' => $this->actorName($event), 'entry' => $event->draft->getUiLabel()]), ); } @@ -122,7 +122,7 @@ private function sendInvalidated(WorkflowTransitioned $event, ?WorkflowStageData collect([$event->run->author]), 'workflow_invalidated', t('Approval reset'), - t('The review for “{entry}” was reset because its workflow changed.', ['entry' => $event->draft->title]), + t('The review for “{entry}” was reset because its workflow changed.', ['entry' => $event->draft->getUiLabel()]), ); } @@ -171,7 +171,7 @@ private function send(WorkflowTransitioned|WorkflowCommented $event, ?WorkflowSt title: $title, message: $message, workflowName: (string) $event->run->activityRootEvent->data['workflow']['name'], - entryTitle: (string) $event->draft->title, + entryTitle: $event->draft->getUiLabel(), entryUrl: Uri::of($event->draft->getCpEditUrl())->withFragment('workflow')->value(), stageName: $stage === null ? null : t($stage->name), note: $event->note, diff --git a/tests/Feature/Workflow/WorkflowsTest.php b/tests/Feature/Workflow/WorkflowsTest.php index 8087b734186..838a99c2105 100644 --- a/tests/Feature/Workflow/WorkflowsTest.php +++ b/tests/Feature/Workflow/WorkflowsTest.php @@ -946,6 +946,17 @@ function (ElementInterface $draft) use (&$applied): ElementInterface { ->and($notification->data['url'])->toEndWith('#workflow'); }); +it('names untitled drafts in review notifications', function () { + $this->draft->title = null; + expect(Elements::saveElement($this->draft, runValidation: false, updateSearchIndex: false))->toBeTrue(); + $group = reviewerGroup([$this->reviewers[0]]); + workflowFor($this->entry, [userReviewStage('Review', $group)]); + submitAs($this->workflows, $this->draft, $this->author); + + expect($this->reviewers[0]->notifications()->latest()->firstOrFail()->data['message']) + ->toBe('“Untitled entry” is awaiting your approval in Review.'); +}); + it('requests user review after an asynchronous stage advances', function () { app(WorkflowStageTypes::class)->register(TestAutomatedWorkflowStage::class); $group = reviewerGroup([$this->reviewers[0]]);