chore: Update minimum PHP requirement to 8.2 (#1987)

* chore: Update minimum PHP requirement to 8.2

* chore: Update PHP version references to 8.2 in documentation and templates

* chore: Update issue template labels to array format for consistency

* refactor: Changed `local` environment name to `development`

* chore(composer.json): Changed version of `gemorroj/m3u-parser` package

* chore(composer): Removed `matthiasmullie/scrapbook` package

* fix(template): Update variable fallback behavior to return empty string for missing variables

---------

Co-authored-by: Yury Pikhtarev <exileum@icloud.com>
This commit is contained in:
Roman Kelesidis 2025-06-21 10:45:56 +03:00 committed by GitHub
parent 423424e947
commit 9b322c7093
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 138 additions and 319 deletions

View file

@ -1,7 +1,7 @@
name: Bug Report
description: File a bug report
title: "[Bug]"
labels: Bug
labels: [Bug]
body:
- type: markdown
attributes:
@ -21,7 +21,7 @@ body:
attributes:
label: PHP & Platform
description: Exact PHP and Platform (OS) versions your using.
placeholder: 8.1.2 - Ubuntu 22.04 x64
placeholder: 8.2.2 - Ubuntu 22.04 x64
validations:
required: true
- type: checkboxes

View file

@ -2,6 +2,6 @@
name: Feature / Enhancement request
about: Suggest an idea for TorrentPier
title: "[Feature]"
labels: Feature, Enhancement
labels: [Feature, Enhancement]
assignees: ''
---

View file

@ -41,7 +41,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
php-version: '8.2'
- name: Install Composer dependencies
run: composer install --no-dev --no-progress --prefer-dist --optimize-autoloader

View file

@ -17,7 +17,7 @@ jobs:
- name: Setup PHP 🔩
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
php-version: '8.2'
- name: Install Composer dependencies 🪚
run: composer install --no-dev --no-progress --prefer-dist --optimize-autoloader
@ -54,7 +54,7 @@ jobs:
- name: 🔩 Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
php-version: '8.2'
- name: 🖇 Install Composer dependencies
run: composer install --no-dev --no-progress --prefer-dist --optimize-autoloader

View file

@ -8,7 +8,7 @@ TorrentPier is a BitTorrent tracker engine written in PHP, designed for hosting
## Technology Stack & Architecture
- **PHP 8.1+** with modern features
- **PHP 8.2+** with modern features
- **MySQL/MariaDB/Percona** database
- **Nette Database** with backward-compatible wrapper
- **Composer** for dependency management

View file

@ -57,7 +57,7 @@ and go from there. The documentation will be translated to English in the near f
* Apache / nginx ([example config](install/nginx.conf)) / caddy ([example config](install/Caddyfile))
* MySQL 5.5.3 or above (including MySQL 8.0+) / MariaDB 10.0 or above / Percona
* PHP: 8.1 / 8.2 / 8.3 / 8.4 (8.2+ required for development dependencies)
* PHP: 8.2 / 8.3 / 8.4
* PHP Extensions: mbstring, gd, bcmath, intl, tidy (optional), xml, xmlwriter
* Crontab (Recommended)
@ -69,7 +69,7 @@ For the installation, select one of the installation variants below:
Check out our [autoinstall](https://github.com/torrentpier/autoinstall) repository with detailed instructions.
> [!IMPORTANT]
> [!NOTE]
> Thanks to [Sergei Solovev](https://github.com/SeAnSolovev) for this installation script ❤️
### Quick (For web-panels) ☕️
@ -98,10 +98,6 @@ Check out our [autoinstall](https://github.com/torrentpier/autoinstall) reposito
3. [Check our system requirements](#-requirements)
4. After, run this command in the project directory to install Composer dependencies
```shell
# For production (PHP 8.1+)
composer install --no-dev
# For development (PHP 8.2+ required)
composer install
```
5. Edit database configuration settings in the environment (`.env.example`), after, rename to `.env`
@ -136,9 +132,6 @@ If you discover a security vulnerability within TorrentPier, please follow our [
TorrentPier includes a comprehensive testing suite built with **Pest PHP**. Run tests to ensure code quality and system reliability:
> [!NOTE]
> Testing requires **PHP 8.2+** and development dependencies. Install with `composer install` (without `--no-dev` flag).
```shell
# Run all tests
./vendor/bin/pest

View file

@ -158,7 +158,7 @@ function _e(string $key, mixed $default = null): void
* Initialize debug
*/
define('APP_ENV', env('APP_ENV', 'production'));
if (APP_ENV === 'local') {
if (APP_ENV === 'development') {
define('DBG_USER', true); // forced debug
} else {
define('DBG_USER', isset($_COOKIE[COOKIE_DBG]));

View file

@ -46,9 +46,9 @@
"forum": "https://torrentpier.com"
},
"require": {
"php": ">=8.1",
"php": ">=8.2",
"arokettu/bencode": "^4.1.0",
"arokettu/monsterid": "dev-master",
"arokettu/monsterid": "^4.1.0",
"arokettu/random-polyfill": "1.0.2",
"arokettu/torrent-file": "^5.2.1",
"belomaxorka/captcha": "1.*",
@ -56,25 +56,20 @@
"claviska/simpleimage": "^4.0",
"egulias/email-validator": "^4.0.1",
"filp/whoops": "^2.15",
"gemorroj/m3u-parser": "dev-master",
"gemorroj/m3u-parser": "^6.0.1",
"gigablah/sphinxphp": "2.0.8",
"google/recaptcha": "^1.3",
"jacklul/monolog-telegram": "^3.1",
"josantonius/cookie": "^2.0",
"league/flysystem": "^3.28",
"longman/ip-tools": "1.2.1",
"matthiasmullie/scrapbook": "^1.5.4",
"monolog/monolog": "^3.4",
"nette/caching": "^3.3",
"nette/database": "^3.2",
"php-curl-class/php-curl-class": "^12.0.0",
"robmorgan/phinx": "^0.16.9",
"samdark/sitemap": "2.4.1",
"symfony/event-dispatcher": "^6.4",
"symfony/filesystem": "^6.4",
"symfony/finder": "^6.4",
"symfony/mailer": "^6.4",
"symfony/mime": "^6.4",
"symfony/mailer": "^7.3",
"symfony/polyfill": "v1.32.0",
"vlucas/phpdotenv": "^5.5",
"z4kn4fein/php-semver": "^v3.0.0"
@ -82,7 +77,7 @@
"require-dev": {
"mockery/mockery": "^1.6",
"pestphp/pest": "^3.8",
"symfony/var-dumper": "^6.4"
"symfony/var-dumper": "^7.3"
},
"autoload": {
"psr-4": {
@ -102,6 +97,6 @@
"php-http/discovery": true
}
},
"minimum-stability": "dev",
"minimum-stability": "stable",
"prefer-stable": true
}

359
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "22ce2e2cd48a2460b740ef920c114be6",
"content-hash": "7c0b87c0c30183dc306f763c724beafc",
"packages": [
{
"name": "arokettu/bencode",
@ -141,7 +141,7 @@
},
{
"name": "arokettu/monsterid",
"version": "dev-master",
"version": "4.1.0",
"source": {
"type": "git",
"url": "https://github.com/arokettu/monsterid.git",
@ -171,7 +171,6 @@
"squizlabs/php_codesniffer": "*",
"vimeo/psalm": "^5.4 || ^6.0"
},
"default-branch": true,
"type": "library",
"extra": {
"discovery": {
@ -605,7 +604,7 @@
},
{
"name": "cakephp/core",
"version": "5.2.4",
"version": "5.2.5",
"source": {
"type": "git",
"url": "https://github.com/cakephp/core.git",
@ -672,16 +671,16 @@
},
{
"name": "cakephp/database",
"version": "5.2.4",
"version": "5.2.5",
"source": {
"type": "git",
"url": "https://github.com/cakephp/database.git",
"reference": "8c4eaecf6612274b445172b680dc47a2dad681a9"
"reference": "a6bf606b1bab532d04ea504fef8a272a1aeba287"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/cakephp/database/zipball/8c4eaecf6612274b445172b680dc47a2dad681a9",
"reference": "8c4eaecf6612274b445172b680dc47a2dad681a9",
"url": "https://api.github.com/repos/cakephp/database/zipball/a6bf606b1bab532d04ea504fef8a272a1aeba287",
"reference": "a6bf606b1bab532d04ea504fef8a272a1aeba287",
"shasum": ""
},
"require": {
@ -735,11 +734,11 @@
"issues": "https://github.com/cakephp/cakephp/issues",
"source": "https://github.com/cakephp/database"
},
"time": "2025-05-09T15:08:51+00:00"
"time": "2025-06-18T02:55:13+00:00"
},
{
"name": "cakephp/datasource",
"version": "5.2.4",
"version": "5.2.5",
"source": {
"type": "git",
"url": "https://github.com/cakephp/datasource.git",
@ -806,16 +805,16 @@
},
{
"name": "cakephp/utility",
"version": "5.2.4",
"version": "5.2.5",
"source": {
"type": "git",
"url": "https://github.com/cakephp/utility.git",
"reference": "76dcd5c20e46aaf5bfdf9ad51e9f5313abffe104"
"reference": "7eaef40766bf671332adfacdc2d6fb9ea8aea5de"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/cakephp/utility/zipball/76dcd5c20e46aaf5bfdf9ad51e9f5313abffe104",
"reference": "76dcd5c20e46aaf5bfdf9ad51e9f5313abffe104",
"url": "https://api.github.com/repos/cakephp/utility/zipball/7eaef40766bf671332adfacdc2d6fb9ea8aea5de",
"reference": "7eaef40766bf671332adfacdc2d6fb9ea8aea5de",
"shasum": ""
},
"require": {
@ -866,7 +865,7 @@
"issues": "https://github.com/cakephp/cakephp/issues",
"source": "https://github.com/cakephp/utility"
},
"time": "2025-04-19T12:34:03+00:00"
"time": "2025-05-21T14:35:19+00:00"
},
{
"name": "claviska/simpleimage",
@ -1214,16 +1213,16 @@
},
{
"name": "gemorroj/m3u-parser",
"version": "dev-master",
"version": "6.0.1",
"source": {
"type": "git",
"url": "https://github.com/Gemorroj/M3uParser.git",
"reference": "95c62fd837e7adad1694d86dd8f6b31b603ab819"
"reference": "92fc0fe236d77e1b5a26c735ffcb6fc637eb298a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Gemorroj/M3uParser/zipball/95c62fd837e7adad1694d86dd8f6b31b603ab819",
"reference": "95c62fd837e7adad1694d86dd8f6b31b603ab819",
"url": "https://api.github.com/repos/Gemorroj/M3uParser/zipball/92fc0fe236d77e1b5a26c735ffcb6fc637eb298a",
"reference": "92fc0fe236d77e1b5a26c735ffcb6fc637eb298a",
"shasum": ""
},
"require": {
@ -1234,7 +1233,6 @@
"phpstan/phpstan": "^2.1",
"phpunit/phpunit": "^9.6.22"
},
"default-branch": true,
"type": "library",
"autoload": {
"psr-4": {
@ -1258,9 +1256,9 @@
],
"support": {
"issues": "https://github.com/Gemorroj/M3uParser/issues",
"source": "https://github.com/Gemorroj/M3uParser/tree/master"
"source": "https://github.com/Gemorroj/M3uParser/tree/6.0.1"
},
"time": "2025-05-04T19:36:03+00:00"
"time": "2025-03-25T19:21:43+00:00"
},
{
"name": "gigablah/sphinxphp",
@ -2272,105 +2270,6 @@
},
"time": "2016-10-23T20:08:46+00:00"
},
{
"name": "matthiasmullie/scrapbook",
"version": "1.5.4",
"source": {
"type": "git",
"url": "https://github.com/matthiasmullie/scrapbook.git",
"reference": "6ca64d54d7106deffbb98cb9c6a6f5fdb13ce1f1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/matthiasmullie/scrapbook/zipball/6ca64d54d7106deffbb98cb9c6a6f5fdb13ce1f1",
"reference": "6ca64d54d7106deffbb98cb9c6a6f5fdb13ce1f1",
"shasum": ""
},
"require": {
"php": ">=8.0.0",
"psr/cache": "^2.0||^3.0",
"psr/simple-cache": "^2.0||^3.0"
},
"provide": {
"psr/cache-implementation": "^1.0||^2.0||^3.0",
"psr/simple-cache-implementation": "^1.0||^2.0||^3.0"
},
"require-dev": {
"ext-pcntl": "*",
"friendsofphp/php-cs-fixer": ">=3.0",
"phpunit/phpunit": ">=10.0"
},
"suggest": {
"couchbase/couchbase": ">=3.0",
"ext-apcu": ">=4.0.0",
"ext-couchbase": ">=3.0.0",
"ext-memcached": ">=2.0.0",
"ext-pdo": ">=0.1.0",
"ext-redis": ">=2.2.0||0.0.0.0",
"league/flysystem": ">=1.0"
},
"type": "library",
"autoload": {
"psr-4": {
"MatthiasMullie\\Scrapbook\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Matthias Mullie",
"email": "scrapbook@mullie.eu",
"homepage": "https://www.mullie.eu",
"role": "Developer"
}
],
"description": "Scrapbook is a PHP cache library, with adapters for e.g. Memcached, Redis, Couchbase, APCu, SQL and additional capabilities (e.g. transactions, stampede protection) built on top.",
"homepage": "https://scrapbook.cash",
"keywords": [
"Buffer",
"Flysystem",
"apc",
"buffered",
"cache",
"caching",
"commit",
"couchbase",
"filesystem",
"key",
"memcached",
"mitigation",
"mysql",
"postgresql",
"protection",
"psr-16",
"psr-6",
"psr-cache",
"psr-simple-cache",
"redis",
"rollback",
"sql",
"sqlite",
"stampede",
"store",
"transaction",
"transactional",
"value"
],
"support": {
"issues": "https://github.com/matthiasmullie/scrapbook/issues",
"source": "https://github.com/matthiasmullie/scrapbook/tree/1.5.4"
},
"funding": [
{
"url": "https://github.com/matthiasmullie",
"type": "github"
}
],
"time": "2024-12-20T11:47:12+00:00"
},
{
"name": "monolog/monolog",
"version": "3.9.0",
@ -2916,55 +2815,6 @@
],
"time": "2024-07-20T21:41:07+00:00"
},
{
"name": "psr/cache",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/cache.git",
"reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
"reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
"shasum": ""
},
"require": {
"php": ">=8.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Cache\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for caching libraries",
"keywords": [
"cache",
"psr",
"psr-6"
],
"support": {
"source": "https://github.com/php-fig/cache/tree/3.0.0"
},
"time": "2021-02-03T23:26:27+00:00"
},
{
"name": "psr/clock",
"version": "1.0.0",
@ -3569,22 +3419,22 @@
},
{
"name": "symfony/config",
"version": "v7.0.8",
"version": "v7.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
"reference": "f8a8fb0c2d0a188a00a2dd5af8a4eb070641ec60"
"reference": "ba62ae565f1327c2f6366726312ed828c85853bc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/config/zipball/f8a8fb0c2d0a188a00a2dd5af8a4eb070641ec60",
"reference": "f8a8fb0c2d0a188a00a2dd5af8a4eb070641ec60",
"url": "https://api.github.com/repos/symfony/config/zipball/ba62ae565f1327c2f6366726312ed828c85853bc",
"reference": "ba62ae565f1327c2f6366726312ed828c85853bc",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/filesystem": "^6.4|^7.0",
"symfony/filesystem": "^7.1",
"symfony/polyfill-ctype": "~1.8"
},
"conflict": {
@ -3624,7 +3474,7 @@
"description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/config/tree/v7.0.8"
"source": "https://github.com/symfony/config/tree/v7.3.0"
},
"funding": [
{
@ -3640,7 +3490,7 @@
"type": "tidelift"
}
],
"time": "2024-05-31T14:55:39+00:00"
"time": "2025-05-15T09:04:05+00:00"
},
{
"name": "symfony/console",
@ -3805,24 +3655,24 @@
},
{
"name": "symfony/event-dispatcher",
"version": "v6.4.13",
"version": "v7.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e"
"reference": "497f73ac996a598c92409b44ac43b6690c4f666d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e",
"reference": "0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/497f73ac996a598c92409b44ac43b6690c4f666d",
"reference": "497f73ac996a598c92409b44ac43b6690c4f666d",
"shasum": ""
},
"require": {
"php": ">=8.1",
"php": ">=8.2",
"symfony/event-dispatcher-contracts": "^2.5|^3"
},
"conflict": {
"symfony/dependency-injection": "<5.4",
"symfony/dependency-injection": "<6.4",
"symfony/service-contracts": "<2.5"
},
"provide": {
@ -3831,13 +3681,13 @@
},
"require-dev": {
"psr/log": "^1|^2|^3",
"symfony/config": "^5.4|^6.0|^7.0",
"symfony/dependency-injection": "^5.4|^6.0|^7.0",
"symfony/error-handler": "^5.4|^6.0|^7.0",
"symfony/expression-language": "^5.4|^6.0|^7.0",
"symfony/http-foundation": "^5.4|^6.0|^7.0",
"symfony/config": "^6.4|^7.0",
"symfony/dependency-injection": "^6.4|^7.0",
"symfony/error-handler": "^6.4|^7.0",
"symfony/expression-language": "^6.4|^7.0",
"symfony/http-foundation": "^6.4|^7.0",
"symfony/service-contracts": "^2.5|^3",
"symfony/stopwatch": "^5.4|^6.0|^7.0"
"symfony/stopwatch": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@ -3865,7 +3715,7 @@
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/event-dispatcher/tree/v6.4.13"
"source": "https://github.com/symfony/event-dispatcher/tree/v7.3.0"
},
"funding": [
{
@ -3881,7 +3731,7 @@
"type": "tidelift"
}
],
"time": "2024-09-25T14:18:03+00:00"
"time": "2025-04-22T09:11:45+00:00"
},
{
"name": "symfony/event-dispatcher-contracts",
@ -3961,25 +3811,25 @@
},
{
"name": "symfony/filesystem",
"version": "v6.4.13",
"version": "v7.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
"reference": "4856c9cf585d5a0313d8d35afd681a526f038dd3"
"reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/4856c9cf585d5a0313d8d35afd681a526f038dd3",
"reference": "4856c9cf585d5a0313d8d35afd681a526f038dd3",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb",
"reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb",
"shasum": ""
},
"require": {
"php": ">=8.1",
"php": ">=8.2",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.8"
},
"require-dev": {
"symfony/process": "^5.4|^6.4|^7.0"
"symfony/process": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@ -4007,7 +3857,7 @@
"description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/filesystem/tree/v6.4.13"
"source": "https://github.com/symfony/filesystem/tree/v7.3.0"
},
"funding": [
{
@ -4023,27 +3873,27 @@
"type": "tidelift"
}
],
"time": "2024-10-25T15:07:50+00:00"
"time": "2024-10-25T15:15:23+00:00"
},
{
"name": "symfony/finder",
"version": "v6.4.17",
"version": "v7.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "1d0e8266248c5d9ab6a87e3789e6dc482af3c9c7"
"reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/1d0e8266248c5d9ab6a87e3789e6dc482af3c9c7",
"reference": "1d0e8266248c5d9ab6a87e3789e6dc482af3c9c7",
"url": "https://api.github.com/repos/symfony/finder/zipball/ec2344cf77a48253bbca6939aa3d2477773ea63d",
"reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d",
"shasum": ""
},
"require": {
"php": ">=8.1"
"php": ">=8.2"
},
"require-dev": {
"symfony/filesystem": "^6.0|^7.0"
"symfony/filesystem": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@ -4071,7 +3921,7 @@
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/finder/tree/v6.4.17"
"source": "https://github.com/symfony/finder/tree/v7.3.0"
},
"funding": [
{
@ -4087,43 +3937,43 @@
"type": "tidelift"
}
],
"time": "2024-12-29T13:51:37+00:00"
"time": "2024-12-30T19:00:26+00:00"
},
{
"name": "symfony/mailer",
"version": "v6.4.21",
"version": "v7.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/mailer.git",
"reference": "ada2809ccd4ec27aba9fc344e3efdaec624c6438"
"reference": "0f375bbbde96ae8c78e4aa3e63aabd486e33364c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/mailer/zipball/ada2809ccd4ec27aba9fc344e3efdaec624c6438",
"reference": "ada2809ccd4ec27aba9fc344e3efdaec624c6438",
"url": "https://api.github.com/repos/symfony/mailer/zipball/0f375bbbde96ae8c78e4aa3e63aabd486e33364c",
"reference": "0f375bbbde96ae8c78e4aa3e63aabd486e33364c",
"shasum": ""
},
"require": {
"egulias/email-validator": "^2.1.10|^3|^4",
"php": ">=8.1",
"php": ">=8.2",
"psr/event-dispatcher": "^1",
"psr/log": "^1|^2|^3",
"symfony/event-dispatcher": "^5.4|^6.0|^7.0",
"symfony/mime": "^6.2|^7.0",
"symfony/event-dispatcher": "^6.4|^7.0",
"symfony/mime": "^7.2",
"symfony/service-contracts": "^2.5|^3"
},
"conflict": {
"symfony/http-client-contracts": "<2.5",
"symfony/http-kernel": "<5.4",
"symfony/messenger": "<6.2",
"symfony/mime": "<6.2",
"symfony/twig-bridge": "<6.2.1"
"symfony/http-kernel": "<6.4",
"symfony/messenger": "<6.4",
"symfony/mime": "<6.4",
"symfony/twig-bridge": "<6.4"
},
"require-dev": {
"symfony/console": "^5.4|^6.0|^7.0",
"symfony/http-client": "^5.4|^6.0|^7.0",
"symfony/messenger": "^6.2|^7.0",
"symfony/twig-bridge": "^6.2|^7.0"
"symfony/console": "^6.4|^7.0",
"symfony/http-client": "^6.4|^7.0",
"symfony/messenger": "^6.4|^7.0",
"symfony/twig-bridge": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@ -4151,7 +4001,7 @@
"description": "Helps sending emails",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/mailer/tree/v6.4.21"
"source": "https://github.com/symfony/mailer/tree/v7.3.0"
},
"funding": [
{
@ -4167,25 +4017,24 @@
"type": "tidelift"
}
],
"time": "2025-04-26T23:47:35+00:00"
"time": "2025-04-04T09:51:09+00:00"
},
{
"name": "symfony/mime",
"version": "v6.4.21",
"version": "v7.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/mime.git",
"reference": "fec8aa5231f3904754955fad33c2db50594d22d1"
"reference": "0e7b19b2f399c31df0cdbe5d8cbf53f02f6cfcd9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/mime/zipball/fec8aa5231f3904754955fad33c2db50594d22d1",
"reference": "fec8aa5231f3904754955fad33c2db50594d22d1",
"url": "https://api.github.com/repos/symfony/mime/zipball/0e7b19b2f399c31df0cdbe5d8cbf53f02f6cfcd9",
"reference": "0e7b19b2f399c31df0cdbe5d8cbf53f02f6cfcd9",
"shasum": ""
},
"require": {
"php": ">=8.1",
"symfony/deprecation-contracts": "^2.5|^3",
"php": ">=8.2",
"symfony/polyfill-intl-idn": "^1.10",
"symfony/polyfill-mbstring": "^1.0"
},
@ -4193,17 +4042,17 @@
"egulias/email-validator": "~3.0.0",
"phpdocumentor/reflection-docblock": "<3.2.2",
"phpdocumentor/type-resolver": "<1.4.0",
"symfony/mailer": "<5.4",
"symfony/mailer": "<6.4",
"symfony/serializer": "<6.4.3|>7.0,<7.0.3"
},
"require-dev": {
"egulias/email-validator": "^2.1.10|^3.1|^4",
"league/html-to-markdown": "^5.0",
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
"symfony/dependency-injection": "^5.4|^6.0|^7.0",
"symfony/process": "^5.4|^6.4|^7.0",
"symfony/property-access": "^5.4|^6.0|^7.0",
"symfony/property-info": "^5.4|^6.0|^7.0",
"symfony/dependency-injection": "^6.4|^7.0",
"symfony/process": "^6.4|^7.0",
"symfony/property-access": "^6.4|^7.0",
"symfony/property-info": "^6.4|^7.0",
"symfony/serializer": "^6.4.3|^7.0.3"
},
"type": "library",
@ -4236,7 +4085,7 @@
"mime-type"
],
"support": {
"source": "https://github.com/symfony/mime/tree/v6.4.21"
"source": "https://github.com/symfony/mime/tree/v7.3.0"
},
"funding": [
{
@ -4252,7 +4101,7 @@
"type": "tidelift"
}
],
"time": "2025-04-27T13:27:38+00:00"
"time": "2025-02-19T08:51:26+00:00"
},
{
"name": "symfony/polyfill",
@ -7534,34 +7383,33 @@
},
{
"name": "symfony/var-dumper",
"version": "v6.4.21",
"version": "v7.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "22560f80c0c5cd58cc0bcaf73455ffd81eb380d5"
"reference": "548f6760c54197b1084e1e5c71f6d9d523f2f78e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/22560f80c0c5cd58cc0bcaf73455ffd81eb380d5",
"reference": "22560f80c0c5cd58cc0bcaf73455ffd81eb380d5",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/548f6760c54197b1084e1e5c71f6d9d523f2f78e",
"reference": "548f6760c54197b1084e1e5c71f6d9d523f2f78e",
"shasum": ""
},
"require": {
"php": ">=8.1",
"php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-mbstring": "~1.0"
},
"conflict": {
"symfony/console": "<5.4"
"symfony/console": "<6.4"
},
"require-dev": {
"ext-iconv": "*",
"symfony/console": "^5.4|^6.0|^7.0",
"symfony/error-handler": "^6.3|^7.0",
"symfony/http-kernel": "^5.4|^6.0|^7.0",
"symfony/process": "^5.4|^6.0|^7.0",
"symfony/uid": "^5.4|^6.0|^7.0",
"twig/twig": "^2.13|^3.0.4"
"symfony/console": "^6.4|^7.0",
"symfony/http-kernel": "^6.4|^7.0",
"symfony/process": "^6.4|^7.0",
"symfony/uid": "^6.4|^7.0",
"twig/twig": "^3.12"
},
"bin": [
"Resources/bin/var-dump-server"
@ -7599,7 +7447,7 @@
"dump"
],
"support": {
"source": "https://github.com/symfony/var-dumper/tree/v6.4.21"
"source": "https://github.com/symfony/var-dumper/tree/v7.3.0"
},
"funding": [
{
@ -7615,7 +7463,7 @@
"type": "tidelift"
}
],
"time": "2025-04-09T07:34:50+00:00"
"time": "2025-04-27T18:39:23+00:00"
},
{
"name": "ta-tikoma/phpunit-architecture-test",
@ -7786,15 +7634,12 @@
}
],
"aliases": [],
"minimum-stability": "dev",
"stability-flags": {
"arokettu/monsterid": 20,
"gemorroj/m3u-parser": 20
},
"minimum-stability": "stable",
"stability-flags": {},
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
"php": ">=8.1"
"php": ">=8.2"
},
"platform-dev": {},
"plugin-api-version": "2.6.0"

View file

@ -25,7 +25,7 @@ require INC_DIR . '/functions_cli.php';
* System requirements
*/
const CHECK_REQUIREMENTS = [
'php_min_version' => '8.1.0',
'php_min_version' => '8.2.0',
'ext_list' => [
'json',
'curl',
@ -146,26 +146,7 @@ if (!is_file(BB_ROOT . 'vendor/autoload.php')) {
if (is_file(BB_ROOT . 'composer.phar')) {
out('- Installing dependencies...', 'info');
// Ask if user is a developer before installing dependencies
$isDeveloper = false;
echo "\nAre you a developer who needs testing tools and dev dependencies? [y/N]: ";
if (str_starts_with(mb_strtolower(trim(readline())), 'y')) {
$isDeveloper = true;
if (!version_compare(PHP_VERSION, '8.2.0', '>=')) {
out("- Warning: Development dependencies require PHP 8.2+, your version is " . PHP_VERSION, 'warning');
out("- Some testing tools may not work properly", 'warning');
}
out("- Installing all dependencies including dev tools...\n", 'info');
} else {
out("- Installing production dependencies only...\n", 'info');
}
$composerFlags = '--no-interaction --no-ansi';
if (!$isDeveloper) {
$composerFlags .= ' --no-dev';
}
runProcess('php ' . BB_ROOT . 'composer.phar install ' . $composerFlags);
runProcess('php ' . BB_ROOT . 'composer.phar install --no-interaction --no-ansi');
define('COMPOSER_COMPLETED', true);
} else {
out('- composer.phar not found. Please, download it (composer.phar) manually', 'error');

View file

@ -49,14 +49,14 @@ class Dev
{
$this->whoops = new Run;
if (DBG_USER) {
if ($this->isDebugEnabled()) {
$this->getWhoopsOnPage();
} else {
$this->getWhoopsPlaceholder();
}
$this->getWhoopsLogger();
if (APP_ENV !== 'local') {
if (!$this->isDevelopmentEnvironment()) {
$this->getTelegramSender();
$this->getBugsnag();
}
@ -416,13 +416,13 @@ class Dev
}
/**
* Check if application is in local environment
* Check if application is in development environment
*
* @return bool
*/
public function isLocalEnvironment(): bool
public function isDevelopmentEnvironment(): bool
{
return APP_ENV === 'local';
return APP_ENV === 'development';
}
/**

View file

@ -421,7 +421,7 @@ class Template
// Append the variable reference.
$varref .= "['$varname']";
$varref = "<?php echo isset($varref) ? $varref : '" . $namespace . ".$varname'; ?>";
$varref = '<?php echo isset(' . $varref . ') ? ' . $varref . ' : \'\'; ?>';
return $varref;
}
@ -766,10 +766,15 @@ class Template
$code = str_replace($search, $replace, $code);
}
// This will handle the remaining root-level varrefs
$code = preg_replace('#\{(L_([a-z0-9\-_]+?))\}#i', '<?php echo isset($L[\'$2\']) ? $L[\'$2\'] : (isset($V[\'$1\']) ? $V[\'$1\'] : \'$1\'); ?>', $code);
// Handle L_ language variables specifically - show plain text when not found
$code = preg_replace('#\{(L_([a-z0-9\-_]+?))\}#i', '<?php echo isset($L[\'$2\']) ? $L[\'$2\'] : \'$1\'; ?>', $code);
// Handle PHP variables
$code = preg_replace('#\{(\$[a-z_][a-z0-9_$\->\'\"\.\[\]]*?)\}#i', '<?php echo isset($1) ? $1 : \'\'; ?>', $code);
// Handle constants
$code = preg_replace('#\{(\#([a-z_][a-z0-9_]*?)\#)\}#i', '<?php echo defined(\'$2\') ? $2 : \'\'; ?>', $code);
$code = preg_replace('#\{([a-z0-9\-_]+?)\}#i', '<?php echo isset($V[\'$1\']) ? $V[\'$1\'] : \'\'; ?>', $code);
// Handle simple variables (but NOT variables with dots - those should be handled by block processing)
// Only match variables that don't contain dots
$code = preg_replace('#\{([a-z0-9\-_]+)\}#i', '<?php echo isset($V[\'$1\']) ? $V[\'$1\'] : \'\'; ?>', $code);
return $code;
}

View file

@ -217,14 +217,14 @@ describe('Template Text Compilation - Graceful Fallback', function () {
describe('Template Block Variable Fallback', function () {
it('shows missing block variables as original syntax', function () {
it('shows missing block variables as empty string', function () {
$namespace = 'testblock';
$varname = 'MISSING_VAR';
$result = $this->template->generate_block_varref($namespace . '.', $varname);
// Verify the exact expected fallback output format string
$expectedFormat = "<?php echo isset(\$testblock_item['MISSING_VAR']) ? \$testblock_item['MISSING_VAR'] : 'testblock.MISSING_VAR'; ?>";
// Block variables should show empty string when missing, not the variable name
$expectedFormat = "<?php echo isset(\$testblock_item['MISSING_VAR']) ? \$testblock_item['MISSING_VAR'] : ''; ?>";
expect($result)->toBe($expectedFormat);
});
@ -234,8 +234,8 @@ describe('Template Block Variable Fallback', function () {
$result = $this->template->generate_block_varref($namespace . '.', $varname);
// Verify the exact expected fallback output format string
$expectedFormat = "<?php echo isset(\$news_item['TITLE']) ? \$news_item['TITLE'] : 'news.TITLE'; ?>";
// Block variables should show empty string when missing, not the variable name
$expectedFormat = "<?php echo isset(\$news_item['TITLE']) ? \$news_item['TITLE'] : ''; ?>";
expect($result)->toBe($expectedFormat);
});