Skip to content

Commit 3af62bb

Browse files
committed
After review 0
1 parent ad863ed commit 3af62bb

9 files changed

Lines changed: 34 additions & 22 deletions

File tree

assets/vue/api.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const redirectToLogin = () => {
2929
return;
3030
}
3131
isAuthenticationRedirectInProgress = true;
32-
const redirectTarget = `${window.location.pathname}${window.location.search}${window.location.hash}`;
32+
const redirectTarget = `${window.location.pathname}${window.location.search}`;
3333
const search = new URLSearchParams({ redirect: redirectTarget }).toString();
3434
window.location.href = `${AUTHENTICATION_REDIRECT_PATH}?${search}`;
3535
};

assets/vue/components/campaigns/ViewCampaignModal.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@
9393
type="checkbox"
9494
:value="list.id"
9595
class="h-4 w-4 rounded border-slate-300 text-slate-900 accent-ext-wf1"
96-
data-testid="send-btn"
9796
>
9897
<span>{{ list.name }}</span>
9998
</label>

assets/vue/components/public-pages/PublicPageEditor.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -547,9 +547,10 @@ const applyLoadedDataToForm = (page = null) => {
547547
const ownerIdFromPage = page?.owner?.id ? String(page.owner.id) : ''
548548
form.value.ownerId = getDataValue('owner_id', ownerIdFromPage)
549549
550+
const pageDataItems = Array.isArray(page?.data) ? page.data : []
550551
const config = {}
551552
form.value.attributes.split(',').forEach((attributeId) => {
552-
const attribute = page.data.find(
553+
const attribute = pageDataItems.find(
553554
(attr) => attr.key === `attribute${String(attributeId).padStart(3, '0')}`
554555
)
555556
@@ -631,7 +632,7 @@ const persistDataItems = async () => {
631632
['button', form.value.button],
632633
['htmlchoice', form.value.htmlChoice],
633634
['emaildoubleentry', form.value.displayEmailConfirmationField === '1' ? 'yes' : 'no'],
634-
['showcategories', form.value.displayListCategories ? 'yes' : 'no'],
635+
['showcategories', form.value.displayListCategories === '1' ? 'yes' : 'no'],
635636
['lists', selectedListIds],
636637
['preselectlist', normalizedPreselectedId],
637638
['subscribesubject', form.value.subscribeSubject],

assets/vue/components/public-pages/PublicPagesDirectory.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
<tr class="hover:bg-slate-50 transition-colors">
3434
<td class="px-6 py-4 text-slate-600">{{ page.id }}</td>
3535
<td class="px-6 py-4 font-medium text-slate-900">{{ page.title || `Subscribe page #${page.id}` }}</td>
36-
<td class="px-6 py-4 text-slate-700">{{ page.owner.loginName }}</td>
36+
<td class="px-6 py-4 text-slate-700">{{ page.owner?.loginName || page.owner?.email || 'No owner' }}</td>
3737
<td class="px-6 py-4">
3838
<label class="inline-flex items-center cursor-pointer">
3939
<input
@@ -122,7 +122,7 @@
122122
<div>
123123
<p class="text-xs uppercase tracking-wide text-slate-500">#{{ page.id }}</p>
124124
<p class="font-semibold text-slate-900">{{ page.title || `Subscribe page #${page.id}` }}</p>
125-
<p class="text-xs text-slate-500 mt-1">Owner: {{ page.owner.loginName }}</p>
125+
<p class="text-xs text-slate-500 mt-1">Owner: {{ page.owner?.loginName || page.owner?.email || 'No owner' }}</p>
126126
</div>
127127
<div class="text-xs text-slate-500">
128128
{{ isRowBusy(page.id) ? 'Updating...' : '' }}

config/packages/security.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ security:
2121
access_control:
2222
- { path: ^/(?:app(?:_test)?\.php/)?login(?:/|$), roles: PUBLIC_ACCESS }
2323
- { path: ^/(?:app(?:_test)?\.php/)?api/v2(?:/|$), roles: PUBLIC_ACCESS }
24-
- { path: ^/(?:app(?:_test)?\.php/)?subscribe, roles: PUBLIC_ACCESS }
25-
- { path: ^/(?:app(?:_test)?\.php/)?unsubscribe, roles: PUBLIC_ACCESS }
24+
- { path: ^/(?:app(?:_test)?\.php/)?subscribe(?:/|$), roles: PUBLIC_ACCESS }
25+
- { path: ^/(?:app(?:_test)?\.php/)?unsubscribe(?:/|$), roles: PUBLIC_ACCESS }
2626
- { path: ^/, roles: ROLE_ADMIN }

src/Controller/PublicSubscribeController.php

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use PhpList\WebFrontend\Service\LanguageService;
1616
use PhpList\WebFrontend\Service\PublicSubscribeFormBuilder;
1717
use PhpList\WebFrontend\Service\PublicSubscribeFormValidator;
18+
use RuntimeException;
1819
use Symfony\Component\DependencyInjection\Attribute\Autowire;
1920
use Symfony\Component\HttpFoundation\Request;
2021
use Symfony\Component\HttpFoundation\Response;
@@ -65,19 +66,26 @@ public function unsubscribe(Request $request, int $pageId): Response
6566
]);
6667
}
6768

68-
#[Route('/subscribe/styles/{fileName}', name: 'subscribe_styles')]
69-
public function getStylesheets(string $fileName): Response
70-
{
71-
$applicationRoot = (new ApplicationStructure())->getApplicationRoot();
72-
return $this->file($applicationRoot . '/public/build/' . $fileName);
73-
}
74-
75-
#[Route('/subscribe/images/{fileName}', name: 'subscribe_images')]
76-
#[Route('/unsubscribe/images/{fileName}', name: 'unsubscribe_images')]
69+
#[Route('/subscribe/images/{fileName}', name: 'sub_images', requirements: ['fileName' => '[A-Za-z0-9._-]+'])]
70+
#[Route('/subscribe/styles/{fileName}', name: 'sub_styles', requirements: ['fileName' => '[A-Za-z0-9._-]+'])]
71+
#[Route('/unsubscribe/images/{fileName}', name: 'unsub_images', requirements: ['fileName' => '[A-Za-z0-9._-]+'])]
7772
public function getImages(string $fileName): Response
7873
{
7974
$applicationRoot = (new ApplicationStructure())->getApplicationRoot();
80-
return $this->file($applicationRoot . '/public/' . $fileName);
75+
76+
$baseDir = realpath($applicationRoot . '/public/build');
77+
78+
if ($baseDir === false) {
79+
throw new RuntimeException('Build directory not found.');
80+
}
81+
82+
$path = realpath($baseDir . DIRECTORY_SEPARATOR . $fileName);
83+
84+
if ($path === false || !str_starts_with($path, $baseDir . DIRECTORY_SEPARATOR)) {
85+
throw $this->createNotFoundException();
86+
}
87+
88+
return $this->file($path);
8189
}
8290

8391
#[Route('/subscribe/{pageId}', name: 'subscribe', requirements: ['pageId' => '\d+'], methods: ['GET', 'POST'])]

src/Service/ListSelectionService.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ public function parseAvailableListIds(string|array|null $rawListIds): array
2727
public function validateSelection(array $selectedLists, array $availableListIds): ?string
2828
{
2929
if ($selectedLists === []) {
30-
return 'Please select a newsletter to subscribe to.';
30+
return 'error.select_newsletter';
3131
}
3232

3333
$allowedListLookup = array_fill_keys($availableListIds, true);
3434
foreach ($selectedLists as $selectedListId) {
3535
if (!isset($allowedListLookup[$selectedListId])) {
36-
return 'One or more selected lists are not available.';
36+
return 'error.invalid_selected_lists';
3737
}
3838
}
3939

src/Service/PhpListTranslationLoader.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,16 @@ private function extractVariables(string $filePath): array
6767

6868
private function mapLocaleToPhpListFile(string $locale): string
6969
{
70+
$normalized = strtolower(str_replace('-', '_', $locale));
71+
$baseLocale = strtok($normalized, '_') ?: 'en';
72+
7073
$map = [
7174
'en' => 'english.php',
7275
'es' => 'spanish.php',
7376
'fr' => 'french.php',
7477
];
7578

76-
return $map[$locale] ?? 'english.php';
79+
return $map[$baseLocale] ?? 'english.php';
7780
}
7881
}
7982

src/Service/PublicSubscribeFormValidator.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ public function validateFormData(
3131
$errors = [];
3232
$email = trim((string) ($formData['email'] ?? ''));
3333
$emailConfirm = trim((string) ($formData['email_confirm'] ?? ''));
34-
$selectedLists = array_values(array_unique(array_map('intval', $formData['selected_lists'] ?? [])));
34+
$rawSelectedLists = is_array($formData['selected_lists'] ?? null) ? $formData['selected_lists'] : [];
35+
$selectedLists = array_values(array_unique(array_map('intval', $rawSelectedLists)));
3536

3637
if (($formData['honeypot'] ?? '') !== '') {
3738
$errors[] = 'Submission rejected.';

0 commit comments

Comments
 (0)