Skip to content

Commit 3bcf040

Browse files
committed
AttributeValueProvider for dynamic tables
1 parent 183af8f commit 3bcf040

File tree

11 files changed

+372
-68
lines changed

11 files changed

+372
-68
lines changed

config/services/providers.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ services:
33
autowire: true
44
autoconfigure: true
55

6-
PhpList\Core\Core\ConfigProvider:
6+
PhpList\Core\Core\ParameterProvider:
77
arguments:
88
$config: '%app.config%'
99

@@ -12,3 +12,9 @@ services:
1212
autoconfigure: true
1313
arguments:
1414
$confPath: '%app.phplist_isp_conf_path%'
15+
16+
PhpList\Core\Domain\Subscription\Service\Provider\CheckboxGroupValueProvider: ~
17+
PhpList\Core\Domain\Subscription\Service\Provider\SelectOrRadioValueProvider: ~
18+
PhpList\Core\Domain\Subscription\Service\Provider\ScalarValueProvider: ~
19+
20+
PhpList\Core\Domain\Configuration\Service\Provider\ConfigProvider:

config/services/repositories.yml

Lines changed: 40 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,156 +1,137 @@
11
services:
2+
PhpList\Core\Domain\Analytics\Repository\LinkTrackRepository:
3+
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
4+
arguments:
5+
- PhpList\Core\Domain\Analytics\Model\LinkTrack
6+
PhpList\Core\Domain\Analytics\Repository\UserMessageViewRepository:
7+
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
8+
arguments:
9+
- PhpList\Core\Domain\Analytics\Model\UserMessageView
10+
PhpList\Core\Domain\Analytics\Repository\LinkTrackUmlClickRepository:
11+
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
12+
arguments:
13+
- PhpList\Core\Domain\Analytics\Model\LinkTrackUmlClick
14+
15+
216
PhpList\Core\Domain\Configuration\Repository\ConfigRepository:
317
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
418
arguments:
519
- PhpList\Core\Domain\Configuration\Model\Config
6-
720
PhpList\Core\Domain\Configuration\Repository\EventLogRepository:
821
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
922
arguments:
1023
- PhpList\Core\Domain\Configuration\Model\EventLog
1124

25+
1226
PhpList\Core\Domain\Identity\Repository\AdministratorRepository:
1327
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
1428
arguments:
1529
- PhpList\Core\Domain\Identity\Model\Administrator
1630
- Doctrine\ORM\Mapping\ClassMetadata\ClassMetadata
1731
- PhpList\Core\Security\HashGenerator
18-
1932
PhpList\Core\Domain\Identity\Repository\AdminAttributeValueRepository:
2033
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
2134
arguments:
2235
- PhpList\Core\Domain\Identity\Model\AdminAttributeValue
23-
2436
PhpList\Core\Domain\Identity\Repository\AdminAttributeDefinitionRepository:
2537
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
2638
arguments:
2739
- PhpList\Core\Domain\Identity\Model\AdminAttributeDefinition
28-
2940
PhpList\Core\Domain\Identity\Repository\AdministratorTokenRepository:
3041
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
3142
arguments:
3243
- PhpList\Core\Domain\Identity\Model\AdministratorToken
33-
3444
PhpList\Core\Domain\Identity\Repository\AdminPasswordRequestRepository:
3545
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
3646
arguments:
3747
- PhpList\Core\Domain\Identity\Model\AdminPasswordRequest
3848

49+
3950
PhpList\Core\Domain\Subscription\Repository\SubscriberListRepository:
4051
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
4152
arguments:
4253
- PhpList\Core\Domain\Subscription\Model\SubscriberList
43-
4454
PhpList\Core\Domain\Subscription\Repository\SubscriberRepository:
4555
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
4656
arguments:
4757
- PhpList\Core\Domain\Subscription\Model\Subscriber
48-
4958
PhpList\Core\Domain\Subscription\Repository\SubscriberAttributeValueRepository:
5059
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
5160
arguments:
5261
- PhpList\Core\Domain\Subscription\Model\SubscriberAttributeValue
53-
5462
PhpList\Core\Domain\Subscription\Repository\SubscriberAttributeDefinitionRepository:
5563
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
5664
arguments:
5765
- PhpList\Core\Domain\Subscription\Model\SubscriberAttributeDefinition
58-
5966
PhpList\Core\Domain\Subscription\Repository\SubscriptionRepository:
6067
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
6168
arguments:
6269
- PhpList\Core\Domain\Subscription\Model\Subscription
70+
PhpList\Core\Domain\Subscription\Repository\DynamicListAttrRepository:
71+
arguments:
72+
$prefix: '%env(default:phplist_ DATABASE_PREFIX)%'
73+
PhpList\Core\Domain\Subscription\Repository\SubscriberHistoryRepository:
74+
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
75+
arguments:
76+
- PhpList\Core\Domain\Subscription\Model\SubscriberHistory
77+
PhpList\Core\Domain\Subscription\Repository\UserBlacklistRepository:
78+
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
79+
arguments:
80+
- PhpList\Core\Domain\Subscription\Model\UserBlacklist
81+
PhpList\Core\Domain\Subscription\Repository\UserBlacklistDataRepository:
82+
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
83+
arguments:
84+
- PhpList\Core\Domain\Subscription\Model\UserBlacklistData
85+
PhpList\Core\Domain\Subscription\Repository\SubscriberPageRepository:
86+
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
87+
arguments:
88+
- PhpList\Core\Domain\Subscription\Model\SubscribePage
89+
PhpList\Core\Domain\Subscription\Repository\SubscriberPageDataRepository:
90+
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
91+
arguments:
92+
- PhpList\Core\Domain\Subscription\Model\SubscribePageData
93+
6394

6495
PhpList\Core\Domain\Messaging\Repository\MessageRepository:
6596
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
6697
arguments:
6798
- PhpList\Core\Domain\Messaging\Model\Message
68-
6999
PhpList\Core\Domain\Messaging\Repository\TemplateRepository:
70100
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
71101
arguments:
72102
- PhpList\Core\Domain\Messaging\Model\Template
73-
74103
PhpList\Core\Domain\Messaging\Repository\TemplateImageRepository:
75104
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
76105
arguments:
77106
- PhpList\Core\Domain\Messaging\Model\TemplateImage
78-
79107
PhpList\Core\Domain\Messaging\Repository\UserMessageBounceRepository:
80108
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
81109
arguments:
82110
- PhpList\Core\Domain\Messaging\Model\UserMessageBounce
83-
84111
PhpList\Core\Domain\Messaging\Repository\UserMessageForwardRepository:
85112
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
86113
arguments:
87114
- PhpList\Core\Domain\Messaging\Model\UserMessageForward
88-
89-
PhpList\Core\Domain\Analytics\Repository\LinkTrackRepository:
90-
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
91-
arguments:
92-
- PhpList\Core\Domain\Analytics\Model\LinkTrack
93-
94-
PhpList\Core\Domain\Analytics\Repository\UserMessageViewRepository:
95-
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
96-
arguments:
97-
- PhpList\Core\Domain\Analytics\Model\UserMessageView
98-
99-
PhpList\Core\Domain\Analytics\Repository\LinkTrackUmlClickRepository:
100-
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
101-
arguments:
102-
- PhpList\Core\Domain\Analytics\Model\LinkTrackUmlClick
103-
104115
PhpList\Core\Domain\Messaging\Repository\UserMessageRepository:
105116
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
106117
arguments:
107118
- PhpList\Core\Domain\Messaging\Model\UserMessage
108-
109-
PhpList\Core\Domain\Subscription\Repository\SubscriberHistoryRepository:
110-
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
111-
arguments:
112-
- PhpList\Core\Domain\Subscription\Model\SubscriberHistory
113-
114119
PhpList\Core\Domain\Messaging\Repository\ListMessageRepository:
115120
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
116121
arguments:
117122
- PhpList\Core\Domain\Messaging\Model\ListMessage
118-
119-
PhpList\Core\Domain\Subscription\Repository\UserBlacklistRepository:
120-
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
121-
arguments:
122-
- PhpList\Core\Domain\Subscription\Model\UserBlacklist
123-
124-
PhpList\Core\Domain\Subscription\Repository\UserBlacklistDataRepository:
125-
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
126-
arguments:
127-
- PhpList\Core\Domain\Subscription\Model\UserBlacklistData
128-
129-
PhpList\Core\Domain\Subscription\Repository\SubscriberPageRepository:
130-
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
131-
arguments:
132-
- PhpList\Core\Domain\Subscription\Model\SubscribePage
133-
134-
PhpList\Core\Domain\Subscription\Repository\SubscriberPageDataRepository:
135-
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
136-
arguments:
137-
- PhpList\Core\Domain\Subscription\Model\SubscribePageData
138-
139123
PhpList\Core\Domain\Messaging\Repository\BounceRegexRepository:
140124
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
141125
arguments:
142126
- PhpList\Core\Domain\Messaging\Model\BounceRegex
143-
144127
PhpList\Core\Domain\Messaging\Repository\BounceRepository:
145128
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
146129
arguments:
147130
- PhpList\Core\Domain\Messaging\Model\Bounce
148-
149131
PhpList\Core\Domain\Messaging\Repository\BounceRegexBounceRepository:
150132
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
151133
arguments:
152134
- PhpList\Core\Domain\Messaging\Model\BounceRegex
153-
154135
PhpList\Core\Domain\Messaging\Repository\SendProcessRepository:
155136
parent: PhpList\Core\Domain\Common\Repository\AbstractRepository
156137
arguments:

config/services/resolvers.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
services:
2+
PhpList\Core\Domain\Subscription\Service\Resolver\AttributeValueResolver:
3+
arguments:
4+
$providers:
5+
- '@PhpList\Core\Domain\Subscription\Service\Provider\CheckboxGroupValueProvider'
6+
- '@PhpList\Core\Domain\Subscription\Service\Provider\SelectOrRadioValueProvider'
7+
- '@PhpList\Core\Domain\Subscription\Service\Provider\ScalarValueProvider'
8+
9+
PhpList\Core\Domain\Common\ClientIpResolver:
10+
autowire: true
11+
autoconfigure: true
12+
13+
PhpList\Core\Domain\Messaging\Service\BounceActionResolver:
14+
arguments:
15+
- !tagged_iterator { tag: 'phplist.bounce_action_handler' }

config/services/services.yml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@ services:
4444
$mailqueueBatchPeriod: '%messaging.mail_queue_period%'
4545
$mailqueueThrottle: '%messaging.mail_queue_throttle%'
4646

47-
PhpList\Core\Domain\Common\ClientIpResolver:
48-
autowire: true
49-
autoconfigure: true
50-
5147
PhpList\Core\Domain\Common\SystemInfoCollector:
5248
autowire: true
5349
autoconfigure: true
@@ -118,10 +114,6 @@ services:
118114
autoconfigure: true
119115
resource: '../../src/Domain/Messaging/Service/Handler/*Handler.php'
120116

121-
PhpList\Core\Domain\Messaging\Service\BounceActionResolver:
122-
arguments:
123-
- !tagged_iterator { tag: 'phplist.bounce_action_handler' }
124-
125117
PhpList\Core\Domain\Messaging\Service\MaxProcessTimeLimiter:
126118
autowire: true
127119
autoconfigure: true
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Subscription\Repository;
6+
7+
use Doctrine\DBAL\ArrayParameterType;
8+
use Doctrine\DBAL\Connection;
9+
use Doctrine\DBAL\Exception;
10+
use InvalidArgumentException;
11+
12+
class DynamicListAttrRepository
13+
{
14+
public function __construct(
15+
private readonly Connection $connection,
16+
private readonly string $prefix = 'phplist_'
17+
) {}
18+
19+
/**
20+
* @return list<string>
21+
* @throws Exception
22+
*/
23+
public function fetchOptionNames(string $listTable, array $ids): array
24+
{
25+
if (empty($ids)) return [];
26+
27+
if (!preg_match('/^[A-Za-z0-9_]+$/', $listTable)) {
28+
throw new InvalidArgumentException('Invalid list table');
29+
}
30+
31+
$table = $this->prefix . 'listattr_' . $listTable;
32+
33+
$qb = $this->connection->createQueryBuilder();
34+
$qb->select('name')
35+
->from($table)
36+
->where('id IN (:ids)')
37+
->setParameter('ids', array_map('intval', $ids), ArrayParameterType::INTEGER);
38+
39+
return $qb->executeQuery()->fetchFirstColumn();
40+
}
41+
42+
public function fetchSingleOptionName(string $listTable, int $id): ?string
43+
{
44+
if (!preg_match('/^[A-Za-z0-9_]+$/', $listTable)) {
45+
throw new InvalidArgumentException('Invalid list table');
46+
}
47+
48+
$table = $this->prefix . 'listattr_' . $listTable;
49+
50+
$qb = $this->connection->createQueryBuilder();
51+
$qb->select('name')
52+
->from($table)
53+
->where('id = :id')
54+
->setParameter('id', $id);
55+
56+
$val = $qb->executeQuery()->fetchOne();
57+
58+
return $val === false ? null : (string) $val;
59+
}
60+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Subscription\Service\Provider;
6+
7+
use PhpList\Core\Domain\Subscription\Model\SubscriberAttributeDefinition;
8+
use PhpList\Core\Domain\Subscription\Model\SubscriberAttributeValue;
9+
10+
interface AttributeValueProvider
11+
{
12+
public function supports(SubscriberAttributeDefinition $attribute): bool;
13+
14+
/** Return normalized, human-readable value (string) */
15+
public function getValue(SubscriberAttributeDefinition $attribute, SubscriberAttributeValue $userValue): string;
16+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Subscription\Service\Provider;
6+
7+
use PhpList\Core\Domain\Subscription\Model\SubscriberAttributeDefinition;
8+
use PhpList\Core\Domain\Subscription\Model\SubscriberAttributeValue;
9+
use PhpList\Core\Domain\Subscription\Repository\DynamicListAttrRepository;
10+
11+
class CheckboxGroupValueProvider implements AttributeValueProvider
12+
{
13+
public function __construct(private DynamicListAttrRepository $repo) {}
14+
15+
public function supports(SubscriberAttributeDefinition $attribute): bool
16+
{
17+
// todo: check what real types exist in the database
18+
return $attribute->getType() === 'checkboxgroup';
19+
}
20+
21+
public function getValue(SubscriberAttributeDefinition $attribute, SubscriberAttributeValue $userValue): string
22+
{
23+
$csv = $userValue->getValue() ?? '';
24+
if ($csv === '') {
25+
return '';
26+
}
27+
28+
$ids = array_values(array_filter(array_map(
29+
fn($v) => ($i = (int)trim($v)) > 0 ? $i : null,
30+
explode(',', $csv)
31+
)));
32+
33+
if (empty($ids) || !$attribute->getTableName()) return '';
34+
35+
$names = $this->repo->fetchOptionNames($attribute->getTableName(), $ids);
36+
37+
return implode('; ', $names);
38+
}
39+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Subscription\Service\Provider;
6+
7+
use PhpList\Core\Domain\Subscription\Model\SubscriberAttributeDefinition;
8+
use PhpList\Core\Domain\Subscription\Model\SubscriberAttributeValue;
9+
10+
class ScalarValueProvider implements AttributeValueProvider
11+
{
12+
public function supports(SubscriberAttributeDefinition $attribute): bool
13+
{
14+
return $attribute->getType() === null;
15+
}
16+
17+
public function getValue(SubscriberAttributeDefinition $attribute, SubscriberAttributeValue $userValue): string
18+
{
19+
return $userValue->getValue() ?? '';
20+
}
21+
}

0 commit comments

Comments
 (0)