Skip to content

Dev - #386

Open
TatevikGr wants to merge 1 commit into
mainfrom
dev
Open

Dev#386
TatevikGr wants to merge 1 commit into
mainfrom
dev

Conversation

@TatevikGr

@TatevikGr TatevikGr commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added .env-based configuration for database, mail, security, messaging, uploads, and other application settings.
    • Application startup now loads settings from .env files.
    • Installation and update processes can generate a local .env configuration with a secure secret.
  • Documentation

    • Updated setup instructions to configure database credentials through .env.
    • Documented the new environment configuration approach in the changelog.

Thanks for contributing to phpList!

* Refactor: env

* feat: add support for .env configuration files and dotenv integration

* feat: add parameters configuration file creation to ScriptHandler

* remove legacy public app files

* fix: correct environment variable naming for parallel usage with phplist3

---------

Co-authored-by: Tatevik <tatevikg1@gmail.com>
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR moves deployment configuration defaults into .env.dist, generates .env during Composer configuration updates, loads dotenv variables during bootstrap, and updates the parameters template, ignore rules, changelog, and setup instructions.

Changes

Environment configuration migration

Layer / File(s) Summary
Dotenv template and generation
.env.dist, composer.json, src/Composer/ScriptHandler.php, .gitignore
Adds environment defaults, the Symfony Dotenv dependency, .env generation with a random secret, and environment-file ignore rules.
Bootstrap dotenv loading
src/Core/Bootstrap.php
Loads .env and environment-specific dotenv files before debugging and application-kernel configuration.
Configuration template and documentation migration
config/parameters.yml, CHANGELOG.md, README.md
Adds an environment-backed parameters template and updates release notes and setup instructions for .env configuration.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Composer
  participant ScriptHandler
  participant DotenvFile
  participant Bootstrap
  participant ApplicationKernel
  Composer->>ScriptHandler: run update-configuration
  ScriptHandler->>DotenvFile: create /.env from /.env.dist
  Bootstrap->>DotenvFile: load environment variables
  Bootstrap->>ApplicationKernel: configure application
Loading

Possibly related PRs

  • phpList/core#385: Related dotenv dependency, bootstrap loading, and .env generation changes.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is too vague to convey the main change in this PR. Rename it to a specific summary, e.g. 'Add dotenv-based environment configuration'.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/Composer/ScriptHandler.php (1)

283-285: 🗄️ Data Integrity & Integration | 🔵 Trivial | 🏗️ Heavy lift

Handle existing .env files during upgrades.

Preserving an existing file avoids overwriting deployment secrets, but it also prevents newly required keys from .env.dist from being added. Since config/parameters.yml now references those keys without inline fallbacks, older or partial .env files can leave required parameters unresolved. Add a merge/validation step or document an explicit upgrade procedure.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Composer/ScriptHandler.php` around lines 283 - 285, Update the existing
`.env` handling in the upgrade flow so an early return from the file-exists
check no longer skips required-key validation and incorporation of newly
introduced values from `.env.dist`. Preserve existing deployment secrets while
merging only missing required keys, or invoke the project’s established
validation/upgrade mechanism to ensure parameters referenced by
`config/parameters.yml` are resolved.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.env.dist:
- Around line 55-57: Update the environment-loading flow around
loadEnvironmentVariables so .env.dist remains template-only and PHPLIST_SECRET
never accepts the literal “%s” placeholder. Require a non-placeholder generated
or explicitly supplied secret, and fail fast when it is missing before security
tokens are used.

In `@CHANGELOG.md`:
- Line 13: Update the changelog entry to reference the current parameters
template path, config/parameters.yml, or explicitly state that
config/parameters.yml.dist was renamed to config/parameters.yml; keep the
description of defaults moving to .env.dist unchanged.

---

Nitpick comments:
In `@src/Composer/ScriptHandler.php`:
- Around line 283-285: Update the existing `.env` handling in the upgrade flow
so an early return from the file-exists check no longer skips required-key
validation and incorporation of newly introduced values from `.env.dist`.
Preserve existing deployment secrets while merging only missing required keys,
or invoke the project’s established validation/upgrade mechanism to ensure
parameters referenced by `config/parameters.yml` are resolved.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c64df25-bce9-461d-83d0-2f202a1f882d

📥 Commits

Reviewing files that changed from the base of the PR and between c5efbd8 and 8d28d3b.

📒 Files selected for processing (12)
  • .env.dist
  • .gitignore
  • CHANGELOG.md
  • README.md
  • composer.json
  • config/parameters.yml
  • config/parameters.yml.dist
  • public/app.php
  • public/app_dev.php
  • public/app_test.php
  • src/Composer/ScriptHandler.php
  • src/Core/Bootstrap.php
💤 Files with no reviewable changes (4)
  • public/app_test.php
  • config/parameters.yml.dist
  • public/app_dev.php
  • public/app.php

Comment thread .env.dist
Comment on lines +55 to +57
# A secret key that's used to generate certain security-related tokens
PHPLIST_SECRET=%s
VERIFY_SSL=1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)(\.env\.dist|Bootstrap\.php|composer\.json)$|Dotenv' || true

echo
echo "== .env.dist relevant lines =="
if [ -f .env.dist ]; then
  nl -ba .env.dist | sed -n '45,65p'
fi

echo
echo "== composer scripts and dotenv package version =="
if [ -f composer.json ]; then
  sed -n '1,220p' composer.json | rg -n '"scripts"|"symfony/dotenv"|"require-dev":|"dotenv"' -C 4 || true
fi

echo
echo "== search for env.dist or Dotenv usage =="
rg -n 'env\.dist|Dotenv|loadEnv|PHPLIST_SECRET' -S . --glob '!vendor/**' --glob '!node_modules/**' || true

Repository: phpList/core

Length of output: 282


🌐 Web query:

Symfony Dotenv 6.4 loadEnv .env.dist fallback behavior source Dotenv.php

💡 Result:

In Symfony 6.4, the loadEnv method in the Dotenv component implements a specific fallback mechanism for the.env file. According to the source code (Dotenv.php), if the primary.env file is missing, the component will automatically attempt to load the.env.dist file if it exists [1][2][3]. The specific logic within loadEnv is implemented as follows: if (is_file($path) ||!is_file($p = "$path.dist")) { $this->doLoad($overrideExistingVars, [$path]); } else { $this->doLoad($overrideExistingVars, [$p]); } This means that if the provided path (usually.env) is not found (is_file($path) is false) AND a file with a.dist extension exists at that location (.env.dist), the Dotenv component will load the.env.dist file instead [1][2][4]. Key points regarding this behavior: - Fallback Priority: The primary.env file always takes precedence. The.env.dist file is only used as a fallback when the primary.env file is absent [1][3]. - Modern Usage: While this fallback exists for compatibility, modern Symfony best practices emphasize that.env should be committed to the repository containing non-sensitive default values, effectively replacing the historical role of.env.dist [5]. - Overriding: This loading process respects the overrideExistingVars parameter, which determines whether values from these files can override environment variables already set by the system [6][1]. System environment variables generally always have the highest precedence and cannot be overridden by Dotenv files unless explicitly configured [5][7].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== .env.dist relevant lines =="
if [ -f .env.dist ]; then
  awk '{printf "%6d  %s\n", NR, $0}' .env.dist | sed -n '45,65p'
fi

echo
echo "== composer relevant snippets =="
if [ -f composer.json ]; then
  python3 - <<'PY'
import json, re, sys
from pathlib import Path
p=Path('composer.json')
text=p.read_text()
try: data=json.loads(text)
except Exception as e:
    print("json_parse_error", repr(e))
    for line in text.splitlines()[:240]:
        if any(s in line for s in ['scripts', 'symfony/dotenv', '"dotenv"', 'require-dev', 'require']):
            print(line)
    sys.exit(0)
print("scripts:", data.get("scripts"))
print("symfony/dotenv:", data.get("require", {}).get("symfony/dotenv"), data.get("require-dev", {}).get("symfony/dotenv"))
for key in ("require","require-dev"):
    for pk,ve in data.get(key,{}).items():
        if "dot" in pk.lower() or "symfony" in pk.lower():
            print(key, pk, ve)
PY
fi

echo
echo "== Bootstrap.php outlines/snippets =="
if [ -f src/Core/Bootstrap.php ]; then
  wc -l src/Core/Bootstrap.php
  rg -n 'Dotenv|loadEnv|env\.dist|load\\(|PHPLIST_SECRET|try|catch' src/Core/Bootstrap.php -C 8
fi

echo
echo "== repository-wide env.dist/env.load/fallback =="
rg -n 'env\.dist|loadEnv\\(|new Dotenv|Dotenv::|PHPLIST_SECRET|secret' -S src composer.json .env.dist --glob '!vendor/**' --glob '!node_modules/**' || true

Repository: phpList/core

Length of output: 2686


🌐 Web query:

Symfony Dotenv load .env.dist if .env missing loadEnv $projectRoot/.env

💡 Result:

In Symfony, the Dotenv component's loadEnv method is designed to handle environment file loading automatically, including a fallback mechanism for the.env.dist file [1][2][3]. When calling $dotenv->loadEnv($projectRoot. '/.env'), the component follows these behaviors: 1. Fallback to.env.dist: If a.env file does not exist, the component will load.env.dist if it is present [1][3]. This was implemented to allow projects to define environment variables in.env.dist when a local.env file is intentionally omitted [1]. 2. Loading Order: The loadEnv method loads files in a specific order, where subsequent files can override variables defined in previously loaded files [2][4][3]. The standard sequence (subject to file existence) is: -.env (or.env.dist if.env is missing) [2][3] -.env.local (skipped for the "test" environment) [2][4][3] -.env.$env (based on the APP_ENV variable) [2][3] -.env.$env.local [2][3] This logic is typically invoked in the project's bootstrap file (e.g., config/bootstrap.php) to ensure environment variables are populated before the application kernel or other components are initialized [5][3]. Note that actual system environment variables always take precedence over values defined in these.env files [6].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== .env.dist relevant lines =="
if [ -f .env.dist ]; then
  awk '{printf "%6d  %s\n", NR, $0}' .env.dist | sed -n '45,65p'
fi

echo
echo "== composer relevant snippets =="
if [ - f composer.json ]; then
  python3 - <<'PY'
import json, re, sys
from pathlib import Path
p=Path('composer.json')
text=p.read_text()
try: data=json.loads(text)
except Exception as e:
    print("json_parse_error", repr(e))
    for line in text.splitlines()[:240]:
        if any(s in line for s in ['scripts', 'symfony/dotenv', '"dotenv"', 'require-dev', 'require']):
            print(line)
    sys.exit(0)
print("scripts:", data.get("scripts"))
print("symfony/dotenv:", data.get("require", {}).get("symfony/dotenv"), data.get("require-dev", {}).get("symfony/dotenv"))
for key in ("require","require-dev"):
    for pk,ve in data.get(key,{}).items():
        if "dot" in pk.lower() or "symfony" in pk.lower():
            print(key, pk, ve)
PY
fi

echo
echo "== Bootstrap.php outlines/snippets =="
if [ -f src/Core/Bootstrap.php ]; then
  wc -l src/Core/Bootstrap.php
  rg -n 'Dotenv|loadEnv|env\.dist|load\\(|PHPLIST_SECRET|try|catch' src/Core/Bootstrap.php -C 8
fi

echo
echo "== repository-wide env.dist/env.load/fallback =="
rg -n 'env\.dist|loadEnv\\(|new Dotenv|Dotenv::|PHPLIST_SECRET|secret' -S src composer.json .env.dist --glob '!vendor/**' --glob '!node_modules/**' || true

Repository: phpList/core

Length of output: 1181


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Bootstrap.php Bootstrap.php matches =="
rg -n 'Dotenv|loadEnv|PHPLIST_SECRET|throw new|secret' src/Core/Bootstrap.php composer.json --glob '!vendor/**' --glob '!node_modules/**' || true

echo
echo "== src/Core/Bootstrap.php line 1-180 =="
awk '{printf "%6d  %s\n", NR, $0}' src/Core/Bootstrap.php | sed -n '1,180p'

echo
echo "== src/Core/Bootstrap.php exact Dotenv/loadEnv snippets =="
awk '{printf "%6d  %s\n", NR, $0}' src/Core/Bootstrap.php | sed -n '/Dotenv/,+8p;/loadEnv/,+12p;/PHPLIST_SECRET/,+12p'

Repository: phpList/core

Length of output: 10010


🌐 Web query:

raw github symfony dotenv 6.4 src Symfony Component Dotenv Dotenv.php is_file projectRoot .env.dist

💡 Result:

In Symfony's Dotenv component (including version 6.4), the logic regarding .env.dist is implemented within the loadEnv() method of the Dotenv.php class [1][2][3]. The relevant code snippet typically appears as follows: if (is_file($path) ||!is_file($p = "$path.dist")) { $this->doLoad($overrideExistingVars, [$path]); } else { $this->doLoad($overrideExistingVars, [$p]); } This logic performs the following behavior: 1. It checks if the primary environment file (defined by $path, usually .env) exists using is_file($path) [1][2]. 2. If the primary file exists, it loads that file. 3. If the primary file does not exist, it checks if a corresponding .dist file exists (e.g., .env.dist) using is_file($p = "$path.dist") [1][2]. 4. If the .dist file exists (and the primary file does not), it loads the .dist file instead [1][2]. This mechanism is designed to support projects that provide a template file (like .env.dist or .env.example) for developers to copy and populate while ensuring the application can still load configuration if the main file is missing [1][2].

Citations:


Don’t let .env.dist become the signed secret.

loadEnvironmentVariables() also triggers Dotenv when .env.dist exists, and Symfony Dotenv will load .env.dist if .env is absent. Since PHPLIST_SECRET=%s, anyone missing Composer script output can run with the literal template value as the signing secret. Keep .env.dist strictly template-only and fail fast unless a real generated/supplied secret exists.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.env.dist around lines 55 - 57, Update the environment-loading flow around
loadEnvironmentVariables so .env.dist remains template-only and PHPLIST_SECRET
never accepts the literal “%s” placeholder. Require a non-placeholder generated
or explicitly supplied secret, and fail fast when it is missing before security
tokens are used.

Source: MCP tools

Comment thread CHANGELOG.md
- `symfony/dotenv` support: configuration values are now read from a `.env` file (generated from `.env.dist` on install/update), in addition to real environment variables (#TBD)

### Changed
- `config/parameters.yml.dist` no longer contains inline `env(VAR): default` fallbacks; defaults now live in `.env.dist` (#TBD)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use the current parameters template path.

This entry names config/parameters.yml.dist, while the migrated template and ScriptHandler now use config/parameters.yml. Use the current path or explicitly describe the rename.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CHANGELOG.md` at line 13, Update the changelog entry to reference the current
parameters template path, config/parameters.yml, or explicitly state that
config/parameters.yml.dist was renamed to config/parameters.yml; keep the
description of defaults moving to .env.dist unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant