Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 5 additions & 5 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ reviews:
instructions: |
You are reviewing PHP domain-layer code. Enforce domain purity, with a relaxed policy for DynamicListAttr:

- ❌ Do not allow persistence or transaction side effects here for *normal* domain models.
- Flag ANY usage of Doctrine persistence APIs on regular domain entities, especially:
- ❌ Do not allow, flag ANY DB write / finalization:
- `$entityManager->flush(...)`, `$this->entityManager->flush(...)`
- `$em->persist(...)`, `$em->remove(...)`
- `$em->beginTransaction()`, `$em->commit()`, `$em->rollback()`
- `$em->beginTransaction()`, `$em->commit()`, `$em->rollback()`, `$em->transactional(...)`
- `$em->getConnection()->executeStatement(...)` for DML/DDL (INSERT/UPDATE/DELETE/ALTER/...)
- ✅ Accessing Doctrine *metadata*, *schema manager*, or *read-only schema info* is acceptable
as long as it does not modify state or perform writes.
as long as it does not modify state or perform writes. Accessing Doctrine *persistence APIs*
persist, remove, etc.) is acceptable, allow scheduling changes in the UnitOfWork (no DB writes)

- ✅ **Relaxed rule for DynamicListAttr-related code**:
- DynamicListAttr is a special case dealing with dynamic tables/attrs.
Expand Down
16 changes: 11 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "phplist/core",
"description": "The core module of phpList, the world's most popular open source newsletter manager",
"type": "phplist-module",
"type": "symfony-bundle",
"keywords": [
"phplist",
"email",
Expand Down Expand Up @@ -46,6 +46,7 @@
},
"require": {
"php": "^8.1",
"symfony/framework-bundle": "^6.4",
"symfony/dependency-injection": "^6.4",
"symfony/config": "^6.4",
"symfony/yaml": "^6.4",
Expand Down Expand Up @@ -79,7 +80,13 @@
"ext-imap": "*",
"tatevikgr/rss-feed": "dev-main",
"ext-pdo": "*",
"ezyang/htmlpurifier": "^4.19"
"ezyang/htmlpurifier": "^4.19",
"ext-libxml": "*",
"ext-gd": "*",
"ext-curl": "*",
"ext-fileinfo": "*",
"setasign/fpdf": "^1.8",
"phpdocumentor/reflection-docblock": "^5.2"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
Expand All @@ -92,7 +99,6 @@
"symfony/test-pack": "^1.1",
"symfony/process": "^6.4",
"composer/composer": "^2.7",
"symfony/framework-bundle": "^6.4",
"symfony/http-kernel": "^6.4",
"symfony/http-foundation": "^6.4",
"symfony/routing": "^6.4",
Expand Down Expand Up @@ -152,8 +158,8 @@
"Doctrine\\Bundle\\DoctrineBundle\\DoctrineBundle",
"Doctrine\\Bundle\\MigrationsBundle\\DoctrineMigrationsBundle",
"PhpList\\Core\\EmptyStartPageBundle\\EmptyStartPageBundle",
"FOS\\RestBundle\\FOSRestBundle",
"TatevikGr\\RssFeedBundle\\RssFeedBundle"
"PhpList\\Core\\EmptyStartPageBundle\\PhpListCoreBundle",
"FOS\\RestBundle\\FOSRestBundle"
],
"routes": {
"homepage": {
Expand Down
8 changes: 4 additions & 4 deletions config/PHPMD/rules.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<exclude-pattern>*/Migrations/*</exclude-pattern>

<!-- rules from the "clean code" rule set -->
<rule ref="rulesets/cleancode.xml/BooleanArgumentFlag"/>
<!-- <rule ref="rulesets/cleancode.xml/BooleanArgumentFlag"/>-->
<rule ref="rulesets/codesize.xml/CyclomaticComplexity"/>
<rule ref="rulesets/codesize.xml/NPathComplexity"/>
<rule ref="rulesets/codesize.xml/ExcessiveMethodLength"/>
Expand All @@ -33,20 +33,20 @@
<rule ref="rulesets/design.xml/DepthOfInheritance"/>
<rule ref="rulesets/design.xml/CouplingBetweenObjects">
<properties>
<property name="maximum" value="15"/>
<property name="maximum" value="17"/>
</properties>
</rule>
<rule ref="rulesets/design.xml/DevelopmentCodeFragment"/>

<!-- rules from the "naming" rule set -->
<rule ref="rulesets/naming.xml/ShortVariable">
<properties>
<property name="exceptions" value="id,ip,cc,io"/>
<property name="exceptions" value="id,ip,cc,io,to"/>
</properties>
</rule>
<rule ref="rulesets/naming.xml/LongVariable">
<properties>
<property name="maximum" value="25"/>
<property name="maximum" value="30"/>
</properties>
</rule>
<rule ref="rulesets/naming.xml/ShortMethodName"/>
Expand Down
6 changes: 5 additions & 1 deletion config/PhpCodeSniffer/ruleset.xml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@
<rule ref="PEAR.WhiteSpace.ScopeClosingBrace"/>
<rule ref="Squiz.WhiteSpace.CastSpacing"/>
<rule ref="Squiz.WhiteSpace.LogicalOperatorSpacing"/>
<rule ref="Squiz.WhiteSpace.OperatorSpacing"/>
<rule ref="Squiz.WhiteSpace.OperatorSpacing">
<properties>
<property name="ignoreNewlines" value="true"/>
</properties>
</rule>
<rule ref="Squiz.WhiteSpace.SemicolonSpacing"/>
</ruleset>
68 changes: 67 additions & 1 deletion config/parameters.yml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,22 @@ parameters:
env(DATABASE_PREFIX): 'phplist_'
list_table_prefix: '%%env(LIST_TABLE_PREFIX)%%'
env(LIST_TABLE_PREFIX): 'listattr_'
app.dev_version: '%%env(APP_DEV_VERSION)%%'
env(APP_DEV_VERSION): '0'
app.dev_email: '%%env(APP_DEV_EMAIL)%%'
env(APP_DEV_EMAIL): 'dev@dev.com'
app.powered_by_phplist: '%%env(APP_POWERED_BY_PHPLIST)%%'
env(APP_POWERED_BY_PHPLIST): '0'
app.preference_page_show_private_lists: '%%env(PREFERENCEPAGE_SHOW_PRIVATE_LISTS)%%'
env(PREFERENCEPAGE_SHOW_PRIVATE_LISTS): '0'
app.rest_api_domain: '%%env(REST_API_DOMAIN)%%'
env(REST_API_DOMAIN): 'example.com'

# Email configuration
app.mailer_from: '%%env(MAILER_FROM)%%'
env(MAILER_FROM): 'noreply@phplist.com'
app.mailer_dsn: '%%env(MAILER_DSN)%%'
env(MAILER_DSN): 'null://null'
env(MAILER_DSN): 'null://null' # set local_domain on transport
app.confirmation_url: '%%env(CONFIRMATION_URL)%%'
env(CONFIRMATION_URL): 'https://example.com/subscriber/confirm/'
app.subscription_confirmation_url: '%%env(SUBSCRIPTION_CONFIRMATION_URL)%%'
Expand Down Expand Up @@ -71,6 +81,8 @@ parameters:
# A secret key that's used to generate certain security-related tokens
secret: '%%env(PHPLIST_SECRET)%%'
env(PHPLIST_SECRET): %1$s
phplist.verify_ssl: '%%env(VERIFY_SSL)%%'
env(VERIFY_SSL): '1'

graylog_host: 'graylog.example.com'
graylog_port: 12201
Expand All @@ -89,3 +101,57 @@ parameters:
env(MESSAGING_MAX_PROCESS_TIME): '600'
messaging.max_mail_size: '%%env(MAX_MAILSIZE)%%'
env(MAX_MAILSIZE): '209715200'
messaging.default_message_age: '%%env(DEFAULT_MESSAGEAGE)%%'
env(DEFAULT_MESSAGEAGE): '691200'
messaging.use_manual_text_part: '%%env(USE_MANUAL_TEXT_PART)%%'
env(USE_MANUAL_TEXT_PART): '0'
messaging.blacklist_grace_time: '%%env(MESSAGING_BLACKLIST_GRACE_TIME)%%'
env(MESSAGING_BLACKLIST_GRACE_TIME): '600'
messaging.google_sender_id: '%%env(GOOGLE_SENDERID)%%'
env(GOOGLE_SENDERID): ''
messaging.use_amazon_ses: '%%env(USE_AMAZONSES)%%'
env(USE_AMAZONSES): '0'
messaging.use_precedence_header: '%%env(USE_PRECEDENCE_HEADER)%%'
env(USE_PRECEDENCE_HEADER): '0'
messaging.embed_external_images: '%%env(EMBEDEXTERNALIMAGES)%%'
env(EMBEDEXTERNALIMAGES): '0'
messaging.embed_uploaded_images: '%%env(EMBEDUPLOADIMAGES)%%'
env(EMBEDUPLOADIMAGES): '0'
messaging.external_image_max_age: '%%env(EXTERNALIMAGE_MAXAGE)%%'
env(EXTERNALIMAGE_MAXAGE): '0'
messaging.external_image_timeout: '%%env(EXTERNALIMAGE_TIMEOUT)%%'
env(EXTERNALIMAGE_TIMEOUT): '30'
messaging.external_image_max_size: '%%env(EXTERNALIMAGE_MAXSIZE)%%'
env(EXTERNALIMAGE_MAXSIZE): '204800'
messaging.forward_alternative_content: '%%env(FORWARD_ALTERNATIVE_CONTENT)%%'
env(FORWARD_ALTERNATIVE_CONTENT): '0'
messaging.email_text_credits: '%%env(EMAILTEXTCREDITS)%%'
env(EMAILTEXTCREDITS): '0'
messaging.always_add_user_track: '%%env(ALWAYS_ADD_USERTRACK)%%'
env(ALWAYS_ADD_USERTRACK): '1'
messaging.send_list_admin_copy: '%%env(SEND_LISTADMIN_COPY)%%'
env(SEND_LISTADMIN_COPY): '0'

phplist.forward_email_period: '%%env(FORWARD_EMAIL_PERIOD)%%'
env(FORWARD_EMAIL_PERIOD): '1 minute'
phplist.forward_email_count: '%%env(FORWARD_EMAIL_COUNT)%%'
env(FORWARD_EMAIL_COUNT): '1'
phplist.forward_personal_note_size: '%%env(FORWARD_PERSONAL_NOTE_SIZE)%%'
env(FORWARD_PERSONAL_NOTE_SIZE): '0'
phplist.forward_friend_count_attribute: '%%env(FORWARD_FRIEND_COUNT_ATTRIBUTE)%%'
env(FORWARD_FRIEND_COUNT_ATTRIBUTE): ''
phplist.keep_forwarded_attributes: '%%env(KEEPFORWARDERATTRIBUTES)%%'
env(KEEPFORWARDERATTRIBUTES): '0'

phplist.upload_images_dir: '%%env(PHPLIST_UPLOADIMAGES_DIR)%%'
env(PHPLIST_UPLOADIMAGES_DIR): 'images'
phplist.editor_images_dir: '%%env(FCKIMAGES_DIR)%%'
env(FCKIMAGES_DIR): 'uploadimages'
phplist.public_schema: '%%env(PUBLIC_SCHEMA)%%'
env(PUBLIC_SCHEMA): 'https'
phplist.attachment_download_url: '%%env(PHPLIST_ATTACHMENT_DOWNLOAD_URL)%%'
env(PHPLIST_ATTACHMENT_DOWNLOAD_URL): 'https://example.com/download/'
phplist.attachment_repository_path: '%%env(PHPLIST_ATTACHMENT_REPOSITORY_PATH)%%'
env(PHPLIST_ATTACHMENT_REPOSITORY_PATH): '/tmp'
phplist.max_avatar_size: '%%env(MAX_AVATAR_SIZE)%%'
env(MAX_AVATAR_SIZE): '100000'
7 changes: 3 additions & 4 deletions config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,9 @@ services:
calls:
- [ set, [ 'Cache.SerializerPath', '%kernel.cache_dir%/htmlpurifier' ] ]
- [ set, [ 'HTML.ForbiddenElements', [ 'script', 'style' ] ] ]
- [ set, [ 'CSS.Disable', true ] ]
- [ set, [ 'URI.DisableJavaScript', true ] ]
- [ set, [ 'URI.DisableDataURI', true ] ]
- [ set, [ 'HTML.Doctype', 'HTML5' ] ]
- [ set, [ 'CSS.AllowedProperties', [] ] ]
- [ set, [ 'URI.AllowedSchemes', { http: true, https: true, mailto: true } ] ]
- [ set, [ 'HTML.Doctype', 'XHTML 1.0 Transitional' ] ]
- [ set, [ 'HTML.Allowed', 'p,br,b,strong,i,em,u,a[href|title],ul,ol,li,blockquote,img[src|alt|title],span,div'] ]

HTMLPurifier:
Expand Down
42 changes: 27 additions & 15 deletions config/services/builders.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,34 @@ services:
autoconfigure: true
public: false

PhpList\Core\Domain\Messaging\Service\Builder\MessageBuilder:
autowire: true
autoconfigure: true
PhpList\Core\Domain\:
resource: '../../src/Domain/*/Service/Builder/*'

PhpList\Core\Domain\Messaging\Service\Builder\MessageFormatBuilder:
autowire: true
autoconfigure: true
# Concrete mail constructors
PhpList\Core\Domain\Messaging\Service\Constructor\SystemMailContentBuilder: ~
PhpList\Core\Domain\Messaging\Service\Constructor\CampaignMailContentBuilder: ~

PhpList\Core\Domain\Messaging\Service\Builder\MessageScheduleBuilder:
autowire: true
autoconfigure: true
# Two EmailBuilder services with different constructors injected
PhpList\Core\Domain\Messaging\Service\Builder\SystemEmailBuilder:
arguments:
$googleSenderId: '%messaging.google_sender_id%'
$useAmazonSes: '%messaging.use_amazon_ses%'
$usePrecedenceHeader: '%messaging.use_precedence_header%'
$devVersion: '%app.dev_version%'
$devEmail: '%app.dev_email%'

PhpList\Core\Domain\Messaging\Service\Builder\MessageContentBuilder:
autowire: true
autoconfigure: true
PhpList\Core\Domain\Messaging\Service\Builder\EmailBuilder:
arguments:
$googleSenderId: '%messaging.google_sender_id%'
$useAmazonSes: '%messaging.use_amazon_ses%'
$usePrecedenceHeader: '%messaging.use_precedence_header%'
$devVersion: '%app.dev_version%'
$devEmail: '%app.dev_email%'

PhpList\Core\Domain\Messaging\Service\Builder\MessageOptionsBuilder:
autowire: true
autoconfigure: true
PhpList\Core\Domain\Messaging\Service\Builder\ForwardEmailBuilder:
arguments:
$googleSenderId: '%messaging.google_sender_id%'
$useAmazonSes: '%messaging.use_amazon_ses%'
$usePrecedenceHeader: '%messaging.use_precedence_header%'
$devVersion: '%app.dev_version%'
$devEmail: '%app.dev_email%'
102 changes: 4 additions & 98 deletions config/services/managers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,11 @@ services:
autoconfigure: true
public: false

PhpList\Core\Domain\Configuration\Service\Manager\ConfigManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Configuration\Service\Manager\EventLogManager:
autowire: true
autoconfigure: true
PhpList\Core\Domain\:
resource: '../../src/Domain/*/Service/Manager/*'
exclude: '../../src/Domain/*/Service/Manager/Builder/*'

PhpList\Core\Domain\Identity\Service\SessionManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Identity\Service\AdministratorManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Identity\Service\AdminAttributeDefinitionManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Identity\Service\AdminAttributeManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Identity\Service\PasswordManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Subscription\Service\Manager\SubscriberManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Subscription\Service\Manager\SubscriberListManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Subscription\Service\Manager\SubscriptionManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Subscription\Service\Manager\AttributeDefinitionManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Subscription\Service\Manager\DynamicListAttrManager:
autowire: true
autoconfigure: true
PhpList\Core\Bounce\Service\Manager\BounceManager: ~

Doctrine\DBAL\Schema\AbstractSchemaManager:
factory: ['@doctrine.dbal.default_connection', 'createSchemaManager']
Expand All @@ -62,55 +20,3 @@ services:
arguments:
$dbPrefix: '%database_prefix%'
$dynamicListTablePrefix: '%list_table_prefix%'

PhpList\Core\Domain\Subscription\Service\Manager\SubscriberHistoryManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Subscription\Service\Manager\SubscriberAttributeManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Subscription\Service\Manager\SubscriberBlacklistManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Subscription\Service\Manager\SubscribePageManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Messaging\Service\Manager\MessageManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Messaging\Service\Manager\TemplateManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Messaging\Service\Manager\TemplateImageManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Messaging\Service\Manager\BounceRegexManager:
autowire: true
autoconfigure: true

PhpList\Core\Bounce\Service\Manager\BounceManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Messaging\Service\Manager\ListMessageManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Messaging\Service\Manager\BounceRuleManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Messaging\Service\Manager\SendProcessManager:
autowire: true
autoconfigure: true

PhpList\Core\Domain\Messaging\Service\Manager\MessageDataManager:
autowire: true
autoconfigure: true
Loading
Loading