Skip to content

Commit 94fe61c

Browse files
committed
In progress
1 parent 33811bf commit 94fe61c

File tree

8 files changed

+333
-187
lines changed

8 files changed

+333
-187
lines changed

config/services/providers.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,8 @@ services:
1717
PhpList\Core\Domain\Subscription\Service\Provider\SelectOrRadioValueProvider: ~
1818
PhpList\Core\Domain\Subscription\Service\Provider\ScalarValueProvider: ~
1919

20+
PhpList\Core\Domain\Configuration\Service\Provider\DefaultConfigProvider:
21+
calls:
22+
- [ setTranslator, [ '@translator' ] ]
23+
2024
PhpList\Core\Domain\Configuration\Service\Provider\ConfigProvider:

resources/translations/messages.en.xlf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@
7979
</trans-unit>
8080

8181
<trans-unit id="identity.subscription_confirmation">
82-
<source>Please confirm your subscription</source>
83-
<target>Please confirm your subscription</target>
82+
<source>Request for confirmation</source>
83+
<target>Request for confirmation</target>
8484
</trans-unit>
8585

8686
<trans-unit id="identity.subscription_confirmation.text">
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Configuration\Service;
6+
7+
class PlaceholderResolver
8+
{
9+
/** @var array<string, callable():string> */
10+
private array $providers = [];
11+
12+
public function register(string $token, callable $provider): void
13+
{
14+
// tokens like [UNSUBSCRIBEURL] (case-insensitive)
15+
$this->providers[strtoupper($token)] = $provider;
16+
}
17+
18+
public function resolve(?string $input): ?string
19+
{
20+
if ($input === null || $input === '') return $input;
21+
22+
// Replace [TOKEN] (case-insensitive)
23+
return preg_replace_callback('/\[(\w+)\]/i', function ($m) {
24+
$key = strtoupper($m[1]);
25+
if (!isset($this->providers[$key])) {
26+
return $m[0];
27+
}
28+
return (string) ($this->providers[$key])();
29+
}, $input);
30+
}
31+
}

src/Domain/Configuration/Service/Provider/DefaultConfigProvider.php

Lines changed: 186 additions & 179 deletions
Large diffs are not rendered by default.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Configuration\Service;
6+
7+
class UrlBuilder
8+
{
9+
public function withUid(string $baseUrl, string $uid): string
10+
{
11+
$parts = parse_url($baseUrl) ?: [];
12+
$query = [];
13+
if (!empty($parts['query'])) {
14+
parse_str($parts['query'], $query);
15+
}
16+
$query['uid'] = $uid;
17+
18+
$parts['query'] = http_build_query($query);
19+
20+
// rebuild url
21+
$scheme = $parts['scheme'] ?? 'https';
22+
$host = $parts['host'] ?? '';
23+
$port = isset($parts['port']) ? ':'.$parts['port'] : '';
24+
$path = $parts['path'] ?? '';
25+
$queryStr = $parts['query'] ? '?'.$parts['query'] : '';
26+
$frag = isset($parts['fragment']) ? '#'.$parts['fragment'] : '';
27+
28+
return "{$scheme}://{$host}{$port}{$path}{$queryStr}{$frag}";
29+
}
30+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Configuration\Service;
6+
7+
use PhpList\Core\Domain\Configuration\Model\ConfigOption;
8+
use PhpList\Core\Domain\Configuration\Service\Provider\ConfigProvider;
9+
use PhpList\Core\Domain\Subscription\Repository\SubscriberAttributeValueRepository;
10+
use PhpList\Core\Domain\Subscription\Repository\SubscriberRepository;
11+
12+
class UserPersonalizer
13+
{
14+
private const PHP_SPACE = ' ';
15+
16+
public function __construct(
17+
private readonly ConfigProvider $config,
18+
private readonly UrlBuilder $urlBuilder,
19+
private readonly SubscriberRepository $subscriberRepository,
20+
private readonly SubscriberAttributeValueRepository $attributes,
21+
) {}
22+
23+
public function personalize(string $value, string $email): string
24+
{
25+
$user = $this->subscriberRepository->findOneByEmail($email);
26+
if (!$user) {
27+
return $value;
28+
}
29+
30+
$resolver = new PlaceholderResolver();
31+
$resolver->register('EMAIL', fn() => $user->getEmail());
32+
33+
$resolver->register('UNSUBSCRIBEURL', function () use ($user) {
34+
$base = $this->config->getValue(ConfigOption::UnsubscribeUrl) ?? '';
35+
return $this->urlBuilder->withUid($base, $user->getUniqueId()) . self::PHP_SPACE;
36+
});
37+
38+
$resolver->register('CONFIRMATIONURL', function () use ($user) {
39+
$base = $this->config->getValue(ConfigOption::ConfirmationUrl) ?? '';
40+
return $this->urlBuilder->withUid($base, $user->getUniqueId()) . self::PHP_SPACE;
41+
});
42+
$resolver->register('PREFERENCESURL', function () use ($user) {
43+
$base = $this->config->getValue(ConfigOption::PreferencesUrl) ?? '';
44+
return $this->urlBuilder->withUid($base, $user->getUniqueId()) . self::PHP_SPACE;
45+
});
46+
47+
$resolver->register(
48+
'SUBSCRIBEURL',
49+
fn() => ($this->config->getValue(ConfigOption::SubscribeUrl) ?? '') . self::PHP_SPACE
50+
);
51+
$resolver->register('DOMAIN', fn() => $this->config->getValue(ConfigOption::Domain) ?? '');
52+
$resolver->register('WEBSITE', fn() => $this->config->getValue(ConfigOption::Website) ?? '');
53+
54+
// attribute placeholders (e.g., [FIRSTNAME], [CITY], etc.)
55+
$attrs = $this->attributes->forEmail($user->getEmail()); // returns array<string,string>
56+
foreach ($attrs as $k => $v) {
57+
$resolver->register(strtoupper($k), fn() => $v);
58+
}
59+
60+
$out = $resolver->resolve($value);
61+
// Do not trim to preserve trailing spaces as in legacy behavior
62+
return (string) $out;
63+
}
64+
}

src/Domain/Messaging/MessageHandler/SubscriberConfirmationMessageHandler.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace PhpList\Core\Domain\Messaging\MessageHandler;
66

7+
use PhpList\Core\Domain\Configuration\Model\ConfigOption;
8+
use PhpList\Core\Domain\Configuration\Service\Provider\ConfigProvider;
79
use PhpList\Core\Domain\Messaging\Message\SubscriberConfirmationMessage;
810
use PhpList\Core\Domain\Messaging\Service\EmailService;
911
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
@@ -18,12 +20,18 @@ class SubscriberConfirmationMessageHandler
1820
{
1921
private EmailService $emailService;
2022
private TranslatorInterface $translator;
23+
private ConfigProvider $configProvider;
2124
private string $confirmationUrl;
2225

23-
public function __construct(EmailService $emailService, TranslatorInterface $translator, string $confirmationUrl)
24-
{
26+
public function __construct(
27+
EmailService $emailService,
28+
TranslatorInterface $translator,
29+
ConfigProvider $configProvider,
30+
string $confirmationUrl
31+
) {
2532
$this->emailService = $emailService;
2633
$this->translator = $translator;
34+
$this->configProvider = $configProvider;
2735
$this->confirmationUrl = $confirmationUrl;
2836
}
2937

@@ -33,8 +41,10 @@ public function __construct(EmailService $emailService, TranslatorInterface $tra
3341
public function __invoke(SubscriberConfirmationMessage $message): void
3442
{
3543
$confirmationLink = $this->generateConfirmationLink($message->getUniqueId());
36-
37-
$subject = $this->translator->trans('Please confirm your subscription');
44+
$subject = $this->configProvider->getValue(
45+
key: ConfigOption::SubscribeEmailSubject,
46+
default: $this->translator->trans('Request for confirmation')
47+
);
3848

3949
$textContent = $this->translator->trans(
4050
"Thank you for subscribing!\n\n" .

src/Domain/Subscription/Service/SubscriberCsvImporter.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,8 @@ private function sendSubscribeEmail(string $subscriberEmail, array $listIds): vo
214214
}
215215
$listOfLists = implode(', ', $listNames);
216216

217-
$subject = $this->configProvider->getValue('subscribesubject', 'Subscription');
218-
$message = $this->configProvider->getValue('subscribemessage', 'You have been subscribed to: [LISTS]');
217+
$subject = $this->configProvider->getValue(ConfigOption::SubscribeEmailSubject, 'Subscription');
218+
$message = $this->configProvider->getValue(ConfigOption::SubscribeMessage, 'You have been subscribed to: [LISTS]');
219219
$message = str_replace('[LISTS]', $listOfLists, (string)$message);
220220

221221
$email = (new Email())

0 commit comments

Comments
 (0)