diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e92dfe326..e38c0ad2a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -3,7 +3,7 @@ name: Continuous Integration
on:
push:
branches:
- - master
+ - v2.4
jobs:
nightly:
@@ -44,37 +44,5 @@ jobs:
- name: Upload Archive ๐ค
uses: actions/upload-artifact@v4
with:
- name: TorrentPier-master
+ name: TorrentPier-v2.4
path: ${{ steps.create-zip.outputs.ZIP_NAME }}
-
- deploy:
- name: ๐ Deploy
- runs-on: ubuntu-22.04
- steps:
- - name: ๐ Get latest code
- uses: actions/checkout@v4
-
- - name: ๐ฉ Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- php-version: '8.1'
-
- - name: Update composer.lock file
- run: composer update --no-install
-
- - name: ๐ Install Composer dependencies
- run: composer install --no-progress --prefer-dist --optimize-autoloader
-
- - name: ๐ Sync files
- uses: SamKirkland/FTP-Deploy-Action@v4.3.5
- with:
- server: ${{ secrets.FTP_SERVER }}
- username: ${{ secrets.FTP_USERNAME }}
- password: ${{ secrets.FTP_PASSWORD }}
- server-dir: ${{ secrets.FTP_DIR }}
- protocol: ${{ secrets.FTP_PROTOCOL }}
- port: ${{ secrets.FTP_PORT }}
- exclude: |
- **/.git*
- **/.git*/**
- .env
diff --git a/.github/workflows/phpmd.yml b/.github/workflows/phpmd.yml
index 3e06d7538..0bc28da28 100644
--- a/.github/workflows/phpmd.yml
+++ b/.github/workflows/phpmd.yml
@@ -17,10 +17,10 @@ name: PHPMD
on:
push:
- branches: [ "master" ]
+ branches: [ "v2.4" ]
pull_request:
# The branches below must be a subset of the branches above
- branches: [ "master" ]
+ branches: [ "v2.4" ]
schedule:
- cron: '40 0 * * 3'
diff --git a/.github/workflows/schedule.yml b/.github/workflows/schedule.yml
index 209512552..d0ab3b5a9 100644
--- a/.github/workflows/schedule.yml
+++ b/.github/workflows/schedule.yml
@@ -14,7 +14,7 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
- ref: master
+ ref: v2.4
token: ${{ secrets.REPO_TOKEN }}
- name: Generate a changelog
@@ -32,10 +32,10 @@ jobs:
- name: Commit changelog
run: |
- git checkout master
+ git checkout v2.4
git config --local user.name 'belomaxorka'
git config --local user.email 'roman25052006.kelesh@gmail.com'
set +e
git add CHANGELOG.md
- git commit -m "Update CHANGELOG.md ๐"
- git push https://${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git master
+ git commit -m "changelog: Update CHANGELOG.md ๐"
+ git push https://${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git v2.4
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 19f1dc9f6..1abfb528f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,63 @@
# ๐ Change Log
-## [nightly](https://nightly.link/torrentpier/torrentpier/workflows/ci/master/TorrentPier-master)
+## [v2.4.10](https://github.com/torrentpier/torrentpier/compare/v2.4.9..v2.4.10) (2025-07-03)
+
+### ๐ Features
+
+- *(lang)* Added `RTL` languages support ([#2031](https://github.com/torrentpier/torrentpier/pull/2031)) - ([9024640](https://github.com/torrentpier/torrentpier/commit/9024640d59428cc164fc6b10246ee40e333ec8e9))
+- Restore some deprecated code for backward compatibility ([#2028](https://github.com/torrentpier/torrentpier/pull/2028)) - ([695864e](https://github.com/torrentpier/torrentpier/commit/695864ef6995a3c7b16ade822036c23908fc3aaf))
+
+### โ๏ธ Revert
+
+- "refactor: Moved `Select` class into `Legacy\Common` ([#1846](https://github.com/torrentpier/torrentpier/pull/1846))" - ([e697672](https://github.com/torrentpier/torrentpier/commit/e6976721dc2f6cde6a09b6a55e2f37e5f43f5932))
+
+
+## [v2.4.9](https://github.com/torrentpier/torrentpier/compare/v2.4.8..v2.4.9) (2025-07-02)
+
+### ๐ Features
+
+- *(updater)* Added exceptions logging ([#2026](https://github.com/torrentpier/torrentpier/pull/2026)) - ([57d0d59](https://github.com/torrentpier/torrentpier/commit/57d0d59b5379600f63cf7d5f774e3ec000e39473))
+
+### ๐ Refactor
+
+- *(TorrentFileList)* Reduce duplication in root directory unset logic ([#2027](https://github.com/torrentpier/torrentpier/pull/2027)) - ([6840376](https://github.com/torrentpier/torrentpier/commit/68403760c1e9e01133536bb5021b08d9101d323e))
+
+
+## [v2.4.8](https://github.com/torrentpier/torrentpier/compare/v2.4.7..v2.4.8) (2025-06-30)
+
+### ๐ Bug Fixes
+
+- *(TorrentFileList)* Avoid `array_merge` reindexing for numeric folder names ([#2014](https://github.com/torrentpier/torrentpier/pull/2014)) - ([a5fbc2f](https://github.com/torrentpier/torrentpier/commit/a5fbc2ffc7389c30ffbb98d253ff8e936528fec1))
+- *(redirect)* Add no-cache headers to prevent browser caching of redirects ([#2010](https://github.com/torrentpier/torrentpier/pull/2010)) - ([134b3df](https://github.com/torrentpier/torrentpier/commit/134b3dfa5cd8e8e5ce3f10912b58afecc4f118e0))
+
+### ๐ Refactor
+
+- Use `DEFAULT_CHARSET` constant instead of hardcoded string ([#2011](https://github.com/torrentpier/torrentpier/pull/2011)) - ([c2cbc77](https://github.com/torrentpier/torrentpier/commit/c2cbc77b144057d3d37cd58b635eabc6280fe137))
+
+
+## [v2.4.7](https://github.com/torrentpier/torrentpier/compare/v2.4.6..v2.4.7) (2025-06-24)
+
+### ๐ Bug Fixes
+
+- *(filelist)* `Undefined property: FileTree::$length` when v2 torrent only ([#2004](https://github.com/torrentpier/torrentpier/pull/2004)) - ([8c161ce](https://github.com/torrentpier/torrentpier/commit/8c161ceae0f80a3ffe57da06dbadd1f9a53272f3))
+- *(ip-api)* Add error handling and logging for freeipapi.com requests ([#2006](https://github.com/torrentpier/torrentpier/pull/2006)) - ([12ce6e7](https://github.com/torrentpier/torrentpier/commit/12ce6e783ec97a6c3df0e11273944a3e6cfe466d))
+
+### ๐ Documentation
+
+- Changed nightly.link url in `README.md` ([#1977](https://github.com/torrentpier/torrentpier/pull/1977)) - ([dc64426](https://github.com/torrentpier/torrentpier/commit/dc64426574087e69bc7e056a89ff367438e37344))
+- Updated `Requirements` sections in README.md ([#1975](https://github.com/torrentpier/torrentpier/pull/1975)) - ([b7bc7f9](https://github.com/torrentpier/torrentpier/commit/b7bc7f91662b050082843d18b03376dc67efa3e0))
+- Fixed some typos in `README.md` ([#1974](https://github.com/torrentpier/torrentpier/pull/1974)) - ([403fcf2](https://github.com/torrentpier/torrentpier/commit/403fcf2aca4b2d70bfca194107f4b4f5c5ba7f03))
+
+
+## [v2.4.6](https://github.com/torrentpier/torrentpier/compare/v2.4.6-alpha.4..v2.4.6) (2025-06-19)
+
+### ๐ Bug Fixes
+
+- *(installer)* Strip protocol from TP_HOST to keep only hostname ([#1969](https://github.com/torrentpier/torrentpier/pull/1969)) - ([15f9948](https://github.com/torrentpier/torrentpier/commit/15f994840331b135cd64c0cd61de95fecfc29db8))
+- *(sql)* Resolve `only_full_group_by` compatibility issues in tracker cleanup - ([faf3d79](https://github.com/torrentpier/torrentpier/commit/faf3d7919249d869d8ca8d41617dd4356dc0ac48))
+- Duplicate column SQL query issues in `viewtopic.php` ([#1973](https://github.com/torrentpier/torrentpier/pull/1973)) - ([6a1d682](https://github.com/torrentpier/torrentpier/commit/6a1d6823856dd7c3cef45bea2681828526d1b9f8))
+- SQL queries in online_userlist.php to use MAX() for session data and adjusted GROUP BY clause for better accuracy ([#1971](https://github.com/torrentpier/torrentpier/pull/1971)) - ([2a8b6da](https://github.com/torrentpier/torrentpier/commit/2a8b6daecf63752b8a852c950e9a7fd08e17f57c))
### ๐ฆ Dependencies
@@ -11,7 +67,14 @@
### โ๏ธ Miscellaneous
- *(_release.php)* Finally! Removed some useless params ([#1947](https://github.com/torrentpier/torrentpier/pull/1947)) - ([9c7d270](https://github.com/torrentpier/torrentpier/commit/9c7d270598c0153fb82f4b7ad96f5b59399b2159))
+- *(cliff)* Add conventional commit prefix to changelog message ([#1970](https://github.com/torrentpier/torrentpier/pull/1970)) - ([7d9594e](https://github.com/torrentpier/torrentpier/commit/7d9594eedab1b2c81d888dfba68ded1b8a142282))
+- Changed active branch name in `_release.php` ([#1972](https://github.com/torrentpier/torrentpier/pull/1972)) - ([7dc69ba](https://github.com/torrentpier/torrentpier/commit/7dc69ba699c75d87c709a799291c4b544b3e92aa))
+- Changed branch name from `master` to `v2.4` ([#1968](https://github.com/torrentpier/torrentpier/pull/1968)) - ([a8e252f](https://github.com/torrentpier/torrentpier/commit/a8e252f64f7205b7bb24739ab637144c6fb022d6))
+## New Contributors โค๏ธ
+
+* @belomaxorka made their first contribution
+* @dependabot[bot] made their first contribution in [#1948](https://github.com/torrentpier/torrentpier/pull/1948)
## [v2.4.6-alpha.4](https://github.com/torrentpier/torrentpier/compare/v2.4.6-alpha.3..v2.4.6-alpha.4) (2025-06-13)
diff --git a/README.md b/README.md
index 8397b363b..3a699f78a 100644
--- a/README.md
+++ b/README.md
@@ -9,25 +9,25 @@
-
+
-
+
## ๐ About TorrentPier
-TorrentPier โ bull-powered BitTorrent Public/Private tracker engine, written in PHP. High speed, simple modifications, load-balanced
-architecture. In addition, we have a very helpful
+TorrentPier โ bull-powered BitTorrent Public/Private tracker engine, written in PHP. High speed, simple modifications, load-balanced
+architecture. In addition, we have a very helpful
[official support forum](https://torrentpier.com), where it's possible to get support and download modifications for the engine.
## ๐ Current status
-TorrentPier is currently in active development. The goal is to remove all legacy code and rewrite the existing code to
-modern specifications. If you want delve deep into the code, check our [issues](https://github.com/torrentpier/torrentpier/issues)
-and go from there. The documentation will be translated to english in the near future, currently russian is the main language of it.
+TorrentPier is currently in active development. The goal is to remove all legacy code and rewrite the existing code to
+modern specifications. If you want to delve deep into the code, check our [issues](https://github.com/torrentpier/torrentpier/issues)
+and go from there. The documentation will be translated to English in the near future; currently Russian is the main language.
## โจ Features
* Rich forum with browsing/moderation tools
@@ -40,7 +40,7 @@ and go from there. The documentation will be translated to english in the near f
* Bonus points
* Polling system
* PM/DM system
-* Multilingual support (Russian and English is currently fully supported, with others in the future)
+* Multilingual support (Russian and English are currently fully supported, with others in the future)
* Atom/RSS feeds
* ... and so MUCH MORE!
@@ -56,7 +56,7 @@ and go from there. The documentation will be translated to english in the near f
## ๐ง Requirements
* Apache / nginx ([example config](install/nginx.conf)) / caddy ([example config](install/Caddyfile))
-* MySQL 5.5.3 or above / MariaDB 10.0 or above / Percona
+* 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
* PHP Extensions: mbstring, gd, bcmath, intl, tidy (optional), xml, xmlwriter
* Crontab (Recommended)
@@ -103,9 +103,9 @@ Check out our [autoinstall](https://github.com/torrentpier/autoinstall) reposito
5. Create a database and import the dump located at `install/sql/mysql.sql`
6. Edit database configuration settings in the environment (`.env.example`), after, rename to `.env`
7. Provide write permissions to the specified folders:
- * `data/avatars`, `data/uploads`, `data/uploads/thumbs`
- * `internal_data/atom`, `internal_data/cache`, `internal_data/log`, `internal_data/triggers`
- * `sitemap`
+ * `data/avatars`, `data/uploads`, `data/uploads/thumbs`
+ * `internal_data/atom`, `internal_data/cache`, `internal_data/log`, `internal_data/triggers`
+ * `sitemap`
8. Voila! โจ
> [!IMPORTANT]
@@ -114,8 +114,8 @@ Check out our [autoinstall](https://github.com/torrentpier/autoinstall) reposito
### Additional steps ๐ฃ
1. Edit these files:
- * `favicon.png` (change to your own)
- * `robots.txt` (change the addresses in lines `Host` and `Sitemap` to your own)
+ * `favicon.png` (change to your own)
+ * `robots.txt` (change the addresses in lines `Host` and `Sitemap` to your own)
2. Log in to the forum using the **admin/admin** login/password, and finish setting up via admin panel. Don't forget to change your password!
## ๐ Security vulnerabilities
@@ -124,13 +124,13 @@ If you discover a security vulnerability within TorrentPier, please follow our [
## ๐ Our recommendations
-* *It's recommended to run `cron.php`.* - For significant tracker speed increase it ay be required to replace the built-in cron.php in operating system daemon.
+* *It's recommended to run `cron.php`.* - For significant tracker speed increase it may be required to replace the built-in cron.php with an operating system daemon.
* *Local configuration copy.* - You can override the settings using the local configuration file `library/config.local.php`.
## ๐ Contributing / Contributors
-Please read our [contributing policy](CONTRIBUTING.md) and [code of conduct](CODE_OF_CONDUCT.md) for details, and the process for
-submitting pull requests to us. But we are always ready to renew your pull-request for compliance with
+Please read our [contributing policy](CONTRIBUTING.md) and [code of conduct](CODE_OF_CONDUCT.md) for details, and the process for
+submitting pull requests to us. But we are always ready to review your pull-request for compliance with
these requirements. Just send it!
@@ -141,7 +141,7 @@ Made with [contrib.rocks](https://contrib.rocks).
## ๐ Sponsoring
-Support this project by becoming a sponsor or a backer.
+Support this project by becoming a sponsor or a backer.
[](https://opencollective.com/torrentpier)
[](https://opencollective.com/torrentpier)
@@ -164,7 +164,7 @@ Support this project by becoming a sponsor or a backer.
## ๐ฆ Versioning
-We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/torrentpier/torrentpier/tags).
+We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/torrentpier/torrentpier/tags).
## ๐ License
diff --git a/_release.php b/_release.php
index a09f3c718..bb3364439 100644
--- a/_release.php
+++ b/_release.php
@@ -124,7 +124,8 @@ runProcess("git tag -a \"$version\" -m \"Release $version\"");
runProcess("git tag -v \"$version\"");
// Git push
-runProcess("git push origin master");
+runProcess("git checkout v2.4");
+runProcess("git push origin v2.4");
runProcess("git push origin $version");
out("\n- Release $version has been successfully prepared, committed and pushed!", 'success');
diff --git a/admin/admin_board.php b/admin/admin_board.php
index 191666675..b836ff29f 100644
--- a/admin/admin_board.php
+++ b/admin/admin_board.php
@@ -136,8 +136,8 @@ switch ($mode) {
'POSTS_PER_PAGE' => $new['posts_per_page'],
'HOT_TOPIC' => $new['hot_threshold'],
'DEFAULT_DATEFORMAT' => $new['default_dateformat'],
- 'LANG_SELECT' => \TorrentPier\Legacy\Common\Select::language($new['default_lang'], 'default_lang'),
- 'TIMEZONE_SELECT' => \TorrentPier\Legacy\Common\Select::timezone($new['board_timezone'], 'board_timezone'),
+ 'LANG_SELECT' => \TorrentPier\Legacy\Select::language($new['default_lang'], 'default_lang'),
+ 'TIMEZONE_SELECT' => \TorrentPier\Legacy\Select::timezone($new['board_timezone'], 'board_timezone'),
'MAX_LOGIN_ATTEMPTS' => $new['max_login_attempts'],
'LOGIN_RESET_TIME' => $new['login_reset_time'],
'PRUNE_ENABLE' => (bool)$new['prune_enable'],
diff --git a/admin/admin_user_search.php b/admin/admin_user_search.php
index f89f3f669..4a29d0e06 100644
--- a/admin/admin_user_search.php
+++ b/admin/admin_user_search.php
@@ -52,8 +52,8 @@ if (!isset($_REQUEST['dosearch'])) {
}
}
- $language_list = \TorrentPier\Legacy\Common\Select::language('', 'language_type');
- $timezone_list = \TorrentPier\Legacy\Common\Select::timezone('', 'timezone_type');
+ $language_list = \TorrentPier\Legacy\Select::language('', 'language_type');
+ $timezone_list = \TorrentPier\Legacy\Select::timezone('', 'timezone_type');
$sql = 'SELECT f.forum_id, f.forum_name, f.forum_parent, c.cat_id, c.cat_title
FROM ( ' . BB_FORUMS . ' AS f INNER JOIN ' . BB_CATEGORIES . ' AS c ON c.cat_id = f.cat_id )
diff --git a/admin/index.php b/admin/index.php
index ea3d0a2aa..1b42b53fa 100644
--- a/admin/index.php
+++ b/admin/index.php
@@ -90,7 +90,7 @@ if (isset($_GET['pane']) && $_GET['pane'] == 'left') {
'NEW_VERSION_SIZE' => $update_data['latest_version_size'],
'NEW_VERSION_DL_LINK' => $update_data['latest_version_dl_link'],
'NEW_VERSION_LINK' => $update_data['latest_version_link'],
- 'NEW_VERSION_MD5' => $update_data['latest_version_checksum']
+ 'NEW_VERSION_HASH' => $update_data['latest_version_checksum']
]);
}
diff --git a/bt/announce.php b/bt/announce.php
index 91d9d1e23..245b7c0dd 100644
--- a/bt/announce.php
+++ b/bt/announce.php
@@ -117,7 +117,7 @@ $stopped = ($event === 'stopped');
// Check info_hash length
if (strlen($info_hash) !== 20) {
- msg_die('Invalid info_hash: ' . (mb_check_encoding($info_hash, 'UTF8') ? $info_hash : $info_hash_hex));
+ msg_die('Invalid info_hash: ' . (mb_check_encoding($info_hash, DEFAULT_CHARSET) ? $info_hash : $info_hash_hex));
}
/**
@@ -259,7 +259,7 @@ if ($lp_info) {
// Verify if torrent registered on tracker and user authorized
if (empty($row['topic_id'])) {
- msg_die('Torrent not registered, info_hash = ' . (mb_check_encoding($info_hash, 'UTF8') ? $info_hash : $info_hash_hex));
+ msg_die('Torrent not registered, info_hash = ' . (mb_check_encoding($info_hash, DEFAULT_CHARSET) ? $info_hash : $info_hash_hex));
}
if (empty($row['user_id'])) {
msg_die('Please LOG IN and RE-DOWNLOAD this torrent (user not found)');
diff --git a/bt/scrape.php b/bt/scrape.php
index 534cd57fd..e2c2676ec 100644
--- a/bt/scrape.php
+++ b/bt/scrape.php
@@ -34,7 +34,7 @@ $info_hash_hex = bin2hex($info_hash);
// Check info_hash length
if (strlen($info_hash) !== 20) {
- msg_die('Invalid info_hash: ' . (mb_check_encoding($info_hash, 'UTF8') ? $info_hash : $info_hash_hex));
+ msg_die('Invalid info_hash: ' . (mb_check_encoding($info_hash, DEFAULT_CHARSET) ? $info_hash : $info_hash_hex));
}
// Handle multiple hashes
@@ -99,7 +99,7 @@ if (!empty($info_hash_count)) {
// Verify if torrent registered on tracker
if (empty($torrents)) {
- msg_die('Torrent not registered, info_hash = ' . (mb_check_encoding($info_hash, 'UTF8') ? $info_hash : $info_hash_hex));
+ msg_die('Torrent not registered, info_hash = ' . (mb_check_encoding($info_hash, DEFAULT_CHARSET) ? $info_hash : $info_hash_hex));
}
die(\Arokettu\Bencode\Bencode::encode($torrents));
diff --git a/cliff.toml b/cliff.toml
index 1753dd8a4..858d0a4db 100644
--- a/cliff.toml
+++ b/cliff.toml
@@ -23,7 +23,7 @@ body = """
{%- endmacro -%}
{%- macro nightly_url() -%}
- https://nightly.link/{{ remote.github.owner }}/{{ remote.github.repo }}/workflows/ci/master/TorrentPier-master
+ https://nightly.link/{{ remote.github.owner }}/{{ remote.github.repo }}/workflows/ci/v2.4/TorrentPier-v2.4
{%- endmacro -%}
{% macro print_commit(commit) -%}
@@ -105,7 +105,7 @@ commit_parsers = [
{ message = "^refactor", group = "๐ Refactor" },
{ message = "^style", group = "๐จ Styling" },
{ message = "^test", group = "๐งช Testing" },
- { message = "^ignore|^release", skip = true },
+ { message = "^ignore|^release|^changelog", skip = true },
{ message = "^chore|^ci|^misc", group = "โ๏ธ Miscellaneous" },
{ body = ".*security", group = "๐ก๏ธ Security" },
{ message = "^revert", group = "โ๏ธ Revert" },
diff --git a/composer.lock b/composer.lock
index a3fa490ba..9bf9af62c 100644
--- a/composer.lock
+++ b/composer.lock
@@ -286,16 +286,16 @@
},
{
"name": "arokettu/torrent-file",
- "version": "5.3.1",
+ "version": "5.3.2",
"source": {
"type": "git",
"url": "https://github.com/arokettu/torrent-file.git",
- "reference": "650ed7109bcd01dd6c4f47d129f120eb1f82ca07"
+ "reference": "0fba9ed15b8f60beb33a590a36db9b97d28ce171"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/arokettu/torrent-file/zipball/650ed7109bcd01dd6c4f47d129f120eb1f82ca07",
- "reference": "650ed7109bcd01dd6c4f47d129f120eb1f82ca07",
+ "url": "https://api.github.com/repos/arokettu/torrent-file/zipball/0fba9ed15b8f60beb33a590a36db9b97d28ce171",
+ "reference": "0fba9ed15b8f60beb33a590a36db9b97d28ce171",
"shasum": ""
},
"require": {
@@ -313,9 +313,9 @@
"league/event": "^3.0",
"phpunit/phpunit": "^10.5.3",
"psy/psysh": "*",
- "sandfox.dev/code-standard": "^1.2024.07.05",
+ "sandfox.dev/code-standard": "^1.2025.05.07",
"squizlabs/php_codesniffer": "*",
- "vimeo/psalm": "^5.2"
+ "vimeo/psalm": "^5.2 | ^6"
},
"suggest": {
"ext-openssl": "for signature logic"
@@ -351,7 +351,7 @@
"issues": "https://gitlab.com/sandfox/torrent-file/-/issues",
"source": "https://gitlab.com/sandfox/torrent-file"
},
- "time": "2024-07-28T21:43:34+00:00"
+ "time": "2025-06-28T21:41:10+00:00"
},
{
"name": "arokettu/unsigned",
@@ -995,16 +995,16 @@
},
{
"name": "google/recaptcha",
- "version": "1.3.0",
+ "version": "1.3.1",
"source": {
"type": "git",
"url": "https://github.com/google/recaptcha.git",
- "reference": "d59a801e98a4e9174814a6d71bbc268dff1202df"
+ "reference": "56522c261d2e8c58ba416c90f81a4cd9f2ed89b9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/google/recaptcha/zipball/d59a801e98a4e9174814a6d71bbc268dff1202df",
- "reference": "d59a801e98a4e9174814a6d71bbc268dff1202df",
+ "url": "https://api.github.com/repos/google/recaptcha/zipball/56522c261d2e8c58ba416c90f81a4cd9f2ed89b9",
+ "reference": "56522c261d2e8c58ba416c90f81a4cd9f2ed89b9",
"shasum": ""
},
"require": {
@@ -1043,7 +1043,7 @@
"issues": "https://github.com/google/recaptcha/issues",
"source": "https://github.com/google/recaptcha"
},
- "time": "2023-02-18T17:41:46+00:00"
+ "time": "2025-06-26T22:21:57+00:00"
},
{
"name": "graham-campbell/result-type",
@@ -1620,16 +1620,16 @@
},
{
"name": "league/flysystem",
- "version": "3.29.1",
+ "version": "3.30.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
- "reference": "edc1bb7c86fab0776c3287dbd19b5fa278347319"
+ "reference": "2203e3151755d874bb2943649dae1eb8533ac93e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/edc1bb7c86fab0776c3287dbd19b5fa278347319",
- "reference": "edc1bb7c86fab0776c3287dbd19b5fa278347319",
+ "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/2203e3151755d874bb2943649dae1eb8533ac93e",
+ "reference": "2203e3151755d874bb2943649dae1eb8533ac93e",
"shasum": ""
},
"require": {
@@ -1653,13 +1653,13 @@
"composer/semver": "^3.0",
"ext-fileinfo": "*",
"ext-ftp": "*",
- "ext-mongodb": "^1.3",
+ "ext-mongodb": "^1.3|^2",
"ext-zip": "*",
"friendsofphp/php-cs-fixer": "^3.5",
"google/cloud-storage": "^1.23",
"guzzlehttp/psr7": "^2.6",
"microsoft/azure-storage-blob": "^1.1",
- "mongodb/mongodb": "^1.2",
+ "mongodb/mongodb": "^1.2|^2",
"phpseclib/phpseclib": "^3.0.36",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^9.5.11|^10.0",
@@ -1697,22 +1697,22 @@
],
"support": {
"issues": "https://github.com/thephpleague/flysystem/issues",
- "source": "https://github.com/thephpleague/flysystem/tree/3.29.1"
+ "source": "https://github.com/thephpleague/flysystem/tree/3.30.0"
},
- "time": "2024-10-08T08:58:34+00:00"
+ "time": "2025-06-25T13:29:59+00:00"
},
{
"name": "league/flysystem-local",
- "version": "3.29.0",
+ "version": "3.30.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem-local.git",
- "reference": "e0e8d52ce4b2ed154148453d321e97c8e931bd27"
+ "reference": "6691915f77c7fb69adfb87dcd550052dc184ee10"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/e0e8d52ce4b2ed154148453d321e97c8e931bd27",
- "reference": "e0e8d52ce4b2ed154148453d321e97c8e931bd27",
+ "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/6691915f77c7fb69adfb87dcd550052dc184ee10",
+ "reference": "6691915f77c7fb69adfb87dcd550052dc184ee10",
"shasum": ""
},
"require": {
@@ -1746,9 +1746,9 @@
"local"
],
"support": {
- "source": "https://github.com/thephpleague/flysystem-local/tree/3.29.0"
+ "source": "https://github.com/thephpleague/flysystem-local/tree/3.30.0"
},
- "time": "2024-08-09T21:24:39+00:00"
+ "time": "2025-05-21T10:34:19+00:00"
},
{
"name": "league/mime-type-detection",
@@ -3146,16 +3146,16 @@
},
{
"name": "symfony/mailer",
- "version": "v6.4.21",
+ "version": "v6.4.23",
"source": {
"type": "git",
"url": "https://github.com/symfony/mailer.git",
- "reference": "ada2809ccd4ec27aba9fc344e3efdaec624c6438"
+ "reference": "a480322ddf8e54de262c9bca31fdcbe26b553de5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/mailer/zipball/ada2809ccd4ec27aba9fc344e3efdaec624c6438",
- "reference": "ada2809ccd4ec27aba9fc344e3efdaec624c6438",
+ "url": "https://api.github.com/repos/symfony/mailer/zipball/a480322ddf8e54de262c9bca31fdcbe26b553de5",
+ "reference": "a480322ddf8e54de262c9bca31fdcbe26b553de5",
"shasum": ""
},
"require": {
@@ -3206,7 +3206,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/v6.4.23"
},
"funding": [
{
@@ -3222,7 +3222,7 @@
"type": "tidelift"
}
],
- "time": "2025-04-26T23:47:35+00:00"
+ "time": "2025-06-26T21:24:02+00:00"
},
{
"name": "symfony/mime",
@@ -3651,16 +3651,16 @@
"packages-dev": [
{
"name": "symfony/var-dumper",
- "version": "v6.4.21",
+ "version": "v6.4.23",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "22560f80c0c5cd58cc0bcaf73455ffd81eb380d5"
+ "reference": "d55b1834cdbfcc31bc2cd7e095ba5ed9a88f6600"
},
"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/d55b1834cdbfcc31bc2cd7e095ba5ed9a88f6600",
+ "reference": "d55b1834cdbfcc31bc2cd7e095ba5ed9a88f6600",
"shasum": ""
},
"require": {
@@ -3716,7 +3716,7 @@
"dump"
],
"support": {
- "source": "https://github.com/symfony/var-dumper/tree/v6.4.21"
+ "source": "https://github.com/symfony/var-dumper/tree/v6.4.23"
},
"funding": [
{
@@ -3732,7 +3732,7 @@
"type": "tidelift"
}
],
- "time": "2025-04-09T07:34:50+00:00"
+ "time": "2025-06-27T15:05:27+00:00"
}
],
"aliases": [],
@@ -3746,6 +3746,6 @@
"platform": {
"php": ">=8.1"
},
- "platform-dev": [],
- "plugin-api-version": "2.3.0"
+ "platform-dev": {},
+ "plugin-api-version": "2.6.0"
}
diff --git a/filelist.php b/filelist.php
index 8e256dc67..2cfd9d418 100644
--- a/filelist.php
+++ b/filelist.php
@@ -82,7 +82,7 @@ if (IS_GUEST && $torrent->isPrivate()) {
// Get torrent files
$files = $torrent->$t_version_field()->$t_files_field();
-if ($meta_v1 && $meta_v2) {
+if ($meta_v2) {
$files = new \RecursiveIteratorIterator($files); // Flatten the list
}
@@ -102,19 +102,6 @@ foreach ($files as $file) {
$torrent_name = !empty($t_name = $torrent->getName()) ? str_short(htmlCHR($t_name), 200) : $lang['UNKNOWN'];
$torrent_size = humn_size($row['size'], 2);
-// Get announcers list
-$announcers_list = $torrent->getAnnounceList()->toArray();
-$announcers_count = 0;
-foreach ($announcers_list as $announcer) {
- $announcers_count++;
- $row_class = ($announcers_count % 2) ? 'row1' : 'row2';
- $template->assign_block_vars('announcers', [
- 'ROW_NUMBER' => $announcers_count,
- 'ROW_CLASS' => $row_class,
- 'ANNOUNCER' => $announcer[0]
- ]);
-}
-
// Output page
$template->assign_vars([
'PAGE_TITLE' => "$torrent_name (" . $torrent_size . ")",
diff --git a/install.php b/install.php
index 009098420..327c0fb5d 100644
--- a/install.php
+++ b/install.php
@@ -206,6 +206,12 @@ if (is_file(BB_ROOT . '.env')) {
$newValue = trim(readline());
if (!empty($newValue) || $key === 'DB_PASSWORD') {
+ if ($key === 'TP_HOST') {
+ if (!preg_match('/^https?:\/\//', $newValue)) {
+ $newValue = 'https://' . $newValue;
+ }
+ $newValue = parse_url($newValue, PHP_URL_HOST);
+ }
$line = "$key=$newValue";
$$key = $newValue;
} else {
diff --git a/library/attach_mod/displaying_torrent.php b/library/attach_mod/displaying_torrent.php
index 06a670266..ce6bf669a 100644
--- a/library/attach_mod/displaying_torrent.php
+++ b/library/attach_mod/displaying_torrent.php
@@ -475,6 +475,8 @@ if ($tor_reged && $tor_info) {
if ($infoByIP = infoByIP((!empty($peer['ipv6']) ? $peer['ipv6'] : $peer['ip']), $peer['port'])) {
if (!empty($infoByIP['countryCode'])) {
$peerCountry = render_flag($infoByIP['countryCode'], false);
+ } else {
+ $peerCountry = $lang['NOT_AVAILABLE'];
}
}
}
diff --git a/library/config.php b/library/config.php
index 866c8ed75..847562369 100644
--- a/library/config.php
+++ b/library/config.php
@@ -18,8 +18,8 @@ $reserved_port = env('TP_PORT', 80);
$bb_cfg = [];
// Version info
-$bb_cfg['tp_version'] = 'v2.4.6-alpha.4';
-$bb_cfg['tp_release_date'] = '13-06-2025';
+$bb_cfg['tp_version'] = 'v2.4.10';
+$bb_cfg['tp_release_date'] = '03-07-2025';
$bb_cfg['tp_release_codename'] = 'Cattle';
// Increase version number after changing JS or CSS
@@ -209,6 +209,7 @@ $bb_cfg['lang'] = [
'ar' => [
'name' => 'Arabic',
'locale' => 'ar_SA.UTF-8',
+ 'rtl' => true,
],
'hy' => [
'name' => 'Armenian',
@@ -285,6 +286,7 @@ $bb_cfg['lang'] = [
'he' => [
'name' => 'Hebrew',
'locale' => 'he_IL.UTF-8',
+ 'rtl' => true,
],
'hi' => [
'name' => 'Hindi',
@@ -724,6 +726,8 @@ $bb_cfg['tracker'] = [
'update_dlstat' => true,
'expire_factor' => 2.5,
'compact_mode' => true,
+ 'upd_user_up_down_stat' => true, // unused
+ 'browser_redirect_url' => '', // unused
'scrape' => true,
'limit_active_tor' => true,
'limit_seed_count' => 0,
diff --git a/library/defines.php b/library/defines.php
index df8813a64..0f50090d7 100644
--- a/library/defines.php
+++ b/library/defines.php
@@ -15,11 +15,13 @@ if (!defined('BB_ROOT')) {
define('ADMIN_DIR', BB_PATH . '/admin');
define('DATA_DIR', BB_PATH . '/data');
define('INT_DATA_DIR', BB_PATH . '/internal_data');
+define('AJAX_HTML_DIR', BB_ROOT . '/internal_data/ajax_html/');
define('CACHE_DIR', BB_PATH . '/internal_data/cache');
define('LOG_DIR', BB_PATH . '/internal_data/log');
define('TRIGGERS_DIR', BB_PATH . '/internal_data/triggers');
define('AJAX_DIR', BB_PATH . '/library/ajax');
define('ATTACH_DIR', BB_PATH . '/library/attach_mod');
+define('CFG_DIR', BB_PATH . '/library/config');
define('INC_DIR', BB_PATH . '/library/includes');
define('UCP_DIR', BB_PATH . '/library/includes/ucp');
define('LANG_ROOT_DIR', BB_PATH . '/library/language');
diff --git a/library/includes/cron/jobs/attach_maintenance.php b/library/includes/cron/jobs/attach_maintenance.php
index 99e9a7168..d778cb38c 100644
--- a/library/includes/cron/jobs/attach_maintenance.php
+++ b/library/includes/cron/jobs/attach_maintenance.php
@@ -26,9 +26,9 @@ $posts_without_attach = $topics_without_attach = [];
DB()->query("
CREATE TEMPORARY TABLE $tmp_attach_tbl (
- physical_filename VARCHAR(255) NOT NULL default '',
+ physical_filename VARCHAR(255) NOT NULL default '' COLLATE utf8mb4_unicode_ci,
KEY physical_filename (physical_filename(20))
- ) ENGINE = MyISAM DEFAULT CHARSET = utf8
+ ) ENGINE = MyISAM DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci
");
DB()->add_shutdown_query("DROP TEMPORARY TABLE IF EXISTS $tmp_attach_tbl");
diff --git a/library/includes/cron/jobs/tr_cleanup_and_dlstat.php b/library/includes/cron/jobs/tr_cleanup_and_dlstat.php
index a0d7efd25..a0a64251f 100644
--- a/library/includes/cron/jobs/tr_cleanup_and_dlstat.php
+++ b/library/includes/cron/jobs/tr_cleanup_and_dlstat.php
@@ -39,7 +39,7 @@ if ($bb_cfg['tracker']['update_dlstat']) {
INSERT INTO " . NEW_BB_BT_LAST_TORSTAT . "
(topic_id, user_id, dl_status, up_add, down_add, release_add, speed_up, speed_down)
SELECT
- topic_id, user_id, IF(releaser, $releaser, seeder), SUM(up_add), SUM(down_add), IF(releaser, SUM(up_add), 0), SUM(speed_up), SUM(speed_down)
+ topic_id, user_id, IF(MAX(releaser), $releaser, MAX(seeder)), SUM(up_add), SUM(down_add), IF(MAX(releaser), SUM(up_add), 0), SUM(speed_up), SUM(speed_down)
FROM " . BB_BT_TRACKER . "
WHERE (up_add != 0 OR down_add != 0)
GROUP BY topic_id, user_id
@@ -61,7 +61,6 @@ DB()->query("
FROM " . BB_BT_TRACKER . "
WHERE seeder = 1
GROUP BY topic_id, user_id
- ORDER BY update_time DESC
");
// Clean peers table
diff --git a/library/includes/datastore/build_check_updates.php b/library/includes/datastore/build_check_updates.php
index a990d4364..aae8ededd 100644
--- a/library/includes/datastore/build_check_updates.php
+++ b/library/includes/datastore/build_check_updates.php
@@ -18,9 +18,16 @@ if (!$bb_cfg['tp_updater_settings']['enabled']) {
}
$data = [];
+$data[] = ['latest_check_timestamp' => TIMENOW];
-$updaterDownloader = new \TorrentPier\Updater();
-$updaterDownloader = $updaterDownloader->getLastVersion($bb_cfg['tp_updater_settings']['allow_pre_releases']);
+try {
+ $updaterDownloader = new \TorrentPier\Updater();
+ $updaterDownloader = $updaterDownloader->getLastVersion($bb_cfg['tp_updater_settings']['allow_pre_releases']);
+} catch (Exception $exception) {
+ bb_log('[Updater] Exception: ' . $exception->getMessage() . LOG_LF);
+ $this->store('check_updates', $data);
+ return;
+}
$getVersion = \TorrentPier\Helpers\VersionHelper::removerPrefix($updaterDownloader['tag_name']);
$currentVersion = \TorrentPier\Helpers\VersionHelper::removerPrefix($bb_cfg['tp_version']);
@@ -28,6 +35,7 @@ $currentVersion = \TorrentPier\Helpers\VersionHelper::removerPrefix($bb_cfg['tp_
// Has update!
if (\z4kn4fein\SemVer\Version::greaterThan($getVersion, $currentVersion)) {
$latestBuildFileLink = $updaterDownloader['assets'][0]['browser_download_url'];
+ $SHAFileHash = $updaterDownloader['assets'][0]['digest'] ?? '';
// Check updater file
$updaterFile = readUpdaterFile();
@@ -41,10 +49,12 @@ if (\z4kn4fein\SemVer\Version::greaterThan($getVersion, $currentVersion)) {
]), UPDATER_FILE, replace_content: true);
}
- // Get MD5 checksum
+ // Get MD5 / sha256 checksum
$buildFileChecksum = '';
- if (isset($latestBuildFileLink)) {
- $buildFileChecksum = strtoupper(md5_file($latestBuildFileLink));
+ if (!empty($SHAFileHash)) {
+ $buildFileChecksum = $SHAFileHash;
+ } else {
+ $buildFileChecksum = 'MD5: ' . strtoupper(md5_file($latestBuildFileLink));
}
// Build data array
@@ -58,5 +68,4 @@ if (\z4kn4fein\SemVer\Version::greaterThan($getVersion, $currentVersion)) {
];
}
-$data[] = ['latest_check_timestamp' => TIMENOW];
$this->store('check_updates', $data);
diff --git a/library/includes/functions.php b/library/includes/functions.php
index 67256eb1f..38db141cd 100644
--- a/library/includes/functions.php
+++ b/library/includes/functions.php
@@ -800,6 +800,11 @@ function str_short($text, $max_length, $space = ' ')
return $text ?? '';
}
+function wbr($text, $max_word_length = HTML_WBR_LENGTH)
+{
+ return preg_replace("/([\w\->;:.,~!?(){}@#$%^*\/\\\\]{" . $max_word_length . "})/ui", '$1', $text);
+}
+
function generate_user_info($row, bool $have_auth = IS_ADMIN): array
{
global $userdata, $lang, $images, $bb_cfg;
@@ -940,6 +945,47 @@ function bb_update_config($params, $table = BB_CONFIG)
bb_get_config($table, true, true);
}
+function get_db_stat($mode)
+{
+ switch ($mode) {
+ case 'usercount':
+ $sql = "SELECT COUNT(user_id) AS total FROM " . BB_USERS;
+ break;
+
+ case 'newestuser':
+ $sql = "SELECT user_id, username FROM " . BB_USERS . " WHERE user_id <> " . GUEST_UID . " ORDER BY user_id DESC LIMIT 1";
+ break;
+
+ case 'postcount':
+ case 'topiccount':
+ $sql = "SELECT SUM(forum_topics) AS topic_total, SUM(forum_posts) AS post_total FROM " . BB_FORUMS;
+ break;
+ }
+
+ if (!($result = DB()->sql_query($sql))) {
+ return false;
+ }
+
+ $row = DB()->sql_fetchrow($result);
+
+ switch ($mode) {
+ case 'usercount':
+ return $row['total'];
+ break;
+ case 'newestuser':
+ return $row;
+ break;
+ case 'postcount':
+ return $row['post_total'];
+ break;
+ case 'topiccount':
+ return $row['topic_total'];
+ break;
+ }
+
+ return false;
+}
+
function clean_username($username)
{
$username = mb_substr(htmlspecialchars(str_replace("\'", "'", trim($username))), 0, 25, DEFAULT_CHARSET);
@@ -949,6 +995,28 @@ function clean_username($username)
return $username;
}
+function bb_ltrim($str, $charlist = false)
+{
+ if ($charlist === false) {
+ return ltrim($str);
+ }
+
+ $str = ltrim($str, $charlist);
+
+ return $str;
+}
+
+function bb_rtrim($str, $charlist = false)
+{
+ if ($charlist === false) {
+ return rtrim($str);
+ }
+
+ $str = rtrim($str, $charlist);
+
+ return $str;
+}
+
/**
* Get Userdata
*
@@ -1094,6 +1162,7 @@ function setup_style()
$css_dir = 'styles/' . basename(TEMPLATES_DIR) . '/' . $tpl_dir_name . '/css/';
$template->assign_vars([
+ 'BB_ROOT' => BB_ROOT,
'SPACER' => make_url('styles/images/spacer.gif'),
'STYLESHEET' => make_url($css_dir . $stylesheet),
'EXT_LINK_NEW_WIN' => $bb_cfg['ext_link_new_win'],
@@ -1412,6 +1481,11 @@ function bb_simple_die($txt, $status_code = null)
die($txt);
}
+function bb_realpath($path)
+{
+ return realpath($path);
+}
+
function login_redirect($url = '')
{
redirect(LOGIN_URL . '?redirect=' . (($url) ?: ($_SERVER['REQUEST_URI'] ?? '/')));
@@ -1450,6 +1524,9 @@ function redirect($url)
$redirect_url = $server_protocol . $server_name . $server_port . $script_name . preg_replace('#^\/?(.*?)\/?$#', '/\1', $url);
+ // Send no-cache headers to prevent browsers from caching redirects
+ send_no_cache_headers();
+
// Behave as per HTTP/1.1 spec for others
header('Location: ' . $redirect_url, response_code: 301);
exit;
@@ -2210,19 +2287,26 @@ function infoByIP(string $ipAddress, int $port = 0): array
}
$context = stream_context_create($contextOptions);
- $response = file_get_contents($bb_cfg['ip2country_settings']['endpoint'] . $ipAddress, context: $context);
- if ($response !== false) {
- $json = json_decode($response, true);
+ try {
+ $response = file_get_contents($bb_cfg['ip2country_settings']['endpoint'] . $ipAddress, context: $context);
- if (is_array($json) && !empty($json)) {
- $data = [
- 'ipVersion' => $json['ipVersion'],
- 'countryCode' => $json['countryCode'],
- 'continent' => $json['continent'],
- 'continentCode' => $json['continentCode']
- ];
+ if ($response !== false) {
+ $json = json_decode($response, true);
+
+ if (is_array($json) && !empty($json)) {
+ $data = [
+ 'ipVersion' => $json['ipVersion'],
+ 'countryCode' => $json['countryCode'],
+ 'continent' => $json['continent'],
+ 'continentCode' => $json['continentCode']
+ ];
+ }
+ } else {
+ bb_log("[FreeIPAPI] Failed to get IP info for: $ipAddress" . LOG_LF);
}
+ } catch (Exception $e) {
+ bb_log("[FreeIPAPI] " . $e->getMessage() . LOG_LF);
}
if (empty($data)) {
diff --git a/library/includes/init_bb.php b/library/includes/init_bb.php
index 932dba5a1..1cb8a6c6f 100644
--- a/library/includes/init_bb.php
+++ b/library/includes/init_bb.php
@@ -293,6 +293,7 @@ define('USER_AGENT', strtolower($_SERVER['HTTP_USER_AGENT']));
define('HTML_SELECT_MAX_LENGTH', 60);
define('HTML_SF_SPACER', ' |- ');
+define('HTML_WBR_LENGTH', 12);
define('HTML_CHECKED', ' checked ');
define('HTML_DISABLED', ' disabled ');
diff --git a/library/includes/online_userlist.php b/library/includes/online_userlist.php
index ffa0cd2e4..7434f79ea 100644
--- a/library/includes/online_userlist.php
+++ b/library/includes/online_userlist.php
@@ -36,11 +36,11 @@ $online = $online_short = ['userlist' => ''];
$sql = "
SELECT
u.username, u.user_id, u.user_opt, u.user_rank, u.user_level,
- s.session_logged_in, s.session_ip, (s.session_time - s.session_start) AS ses_len, COUNT(s.session_id) AS sessions, COUNT(DISTINCT s.session_ip) AS ips
+ MAX(s.session_logged_in) AS session_logged_in, MAX(s.session_ip) AS session_ip, MAX(s.session_time - s.session_start) AS ses_len, COUNT(s.session_id) AS sessions, COUNT(DISTINCT s.session_ip) AS ips
FROM " . BB_SESSIONS . " s, " . BB_USERS . " u
WHERE s.session_time > $time_online
AND u.user_id = s.session_user_id
- GROUP BY s.session_user_id
+ GROUP BY s.session_user_id, u.username, u.user_id, u.user_opt, u.user_rank, u.user_level
ORDER BY u.username
";
diff --git a/library/includes/page_header.php b/library/includes/page_header.php
index 195bcec10..0c72d56d2 100644
--- a/library/includes/page_header.php
+++ b/library/includes/page_header.php
@@ -117,6 +117,7 @@ $template->assign_vars([
'USER_HIDE_CAT' => (BB_SCRIPT == 'index'),
'USER_LANG' => $userdata['user_lang'],
+ 'USER_LANG_DIRECTION' => (isset($bb_cfg['lang'][$userdata['user_lang']]['rtl']) && $bb_cfg['lang'][$userdata['user_lang']]['rtl'] === true) ? 'rtl' : 'ltr',
'INCLUDE_BBCODE_JS' => !empty($page_cfg['include_bbcode_js']),
'USER_OPTIONS_JS' => IS_GUEST ? '{}' : json_encode($user->opt_js, JSON_THROW_ON_ERROR),
@@ -194,8 +195,14 @@ $template->assign_vars([
'BONUS_URL' => BB_ROOT . BONUS_URL,
'TOPIC_URL' => BB_ROOT . TOPIC_URL,
+ 'AJAX_HTML_DIR' => AJAX_HTML_DIR,
+
+ 'ONLY_NEW_POSTS' => ONLY_NEW_POSTS,
+ 'ONLY_NEW_TOPICS' => ONLY_NEW_TOPICS,
+
// Misc
'BOT_UID' => BOT_UID,
+ 'COOKIE_MARK' => COOKIE_MARK,
'SID' => $userdata['session_id'],
'SID_HIDDEN' => '',
diff --git a/library/includes/ucp/register.php b/library/includes/ucp/register.php
index 5e101a310..f70aa11a8 100644
--- a/library/includes/ucp/register.php
+++ b/library/includes/ucp/register.php
@@ -568,7 +568,7 @@ foreach ($profile_fields as $field => $can_edit) {
}
}
}
- $tp_data['TEMPLATES_SELECT'] = \TorrentPier\Legacy\Common\Select::template($pr_data['tpl_name'], 'tpl_name');
+ $tp_data['TEMPLATES_SELECT'] = \TorrentPier\Legacy\Select::template($pr_data['tpl_name'], 'tpl_name');
break;
/**
@@ -725,8 +725,8 @@ $template->assign_vars([
'INVITE_CODE' => !empty($_GET['invite']) ? htmlCHR($_GET['invite']) : '',
'CAPTCHA_HTML' => ($need_captcha) ? bb_captcha('get') : '',
- 'LANGUAGE_SELECT' => \TorrentPier\Legacy\Common\Select::language($pr_data['user_lang'], 'user_lang'),
- 'TIMEZONE_SELECT' => \TorrentPier\Legacy\Common\Select::timezone($pr_data['user_timezone'], 'user_timezone'),
+ 'LANGUAGE_SELECT' => \TorrentPier\Legacy\Select::language($pr_data['user_lang'], 'user_lang'),
+ 'TIMEZONE_SELECT' => \TorrentPier\Legacy\Select::timezone($pr_data['user_timezone'], 'user_timezone'),
'AVATAR_EXPLAIN' => sprintf($lang['AVATAR_EXPLAIN'], $bb_cfg['avatars']['max_width'], $bb_cfg['avatars']['max_height'], humn_size($bb_cfg['avatars']['max_size'])),
'AVATAR_DISALLOWED' => bf($pr_data['user_opt'], 'user_opt', 'dis_avatar'),
diff --git a/posting.php b/posting.php
index 39d44c373..b75e17091 100644
--- a/posting.php
+++ b/posting.php
@@ -625,6 +625,8 @@ $template->assign_vars([
'POSTER_RGROUPS' => !empty($poster_rgroups) ? $poster_rgroups : '',
'ATTACH_RG_SIG' => $switch_rg_sig ?: false,
+ 'U_VIEWTOPIC' => ($mode == 'reply') ? TOPIC_URL . "$topic_id&postorder=desc" : '',
+
'S_NOTIFY_CHECKED' => $notify_user ? 'checked' : '',
'S_ROBOTS_CHECKED' => $robots_indexing ? 'checked' : '',
'S_TYPE_TOGGLE' => $topic_type_toggle,
diff --git a/src/Legacy/Common/Select.php b/src/Legacy/Select.php
similarity index 97%
rename from src/Legacy/Common/Select.php
rename to src/Legacy/Select.php
index 424c99869..6dc3de2e0 100644
--- a/src/Legacy/Common/Select.php
+++ b/src/Legacy/Select.php
@@ -7,11 +7,11 @@
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
*/
-namespace TorrentPier\Legacy\Common;
+namespace TorrentPier\Legacy;
/**
* Class Select
- * @package TorrentPier\Legacy\Common
+ * @package TorrentPier\Legacy
*/
class Select
{
diff --git a/src/Legacy/TorrentFileList.php b/src/Legacy/TorrentFileList.php
index fd600d015..960603acc 100644
--- a/src/Legacy/TorrentFileList.php
+++ b/src/Legacy/TorrentFileList.php
@@ -53,8 +53,10 @@ class TorrentFileList
$this->build_filelist_array();
if ($this->multiple) {
- if (!empty($this->files_ary['/'])) {
- $this->files_ary = array_merge($this->files_ary, $this->files_ary['/']);
+ if (isset($this->files_ary['/'])) {
+ if (!empty($this->files_ary['/'])) {
+ $this->files_ary = $this->files_ary + $this->files_ary['/'];
+ }
unset($this->files_ary['/']);
}
$filelist = $html->array2html($this->files_ary);
diff --git a/src/Updater.php b/src/Updater.php
index 5ccba7843..2f90d2f1b 100644
--- a/src/Updater.php
+++ b/src/Updater.php
@@ -38,6 +38,13 @@ class Updater
*/
public string $savePath;
+ /**
+ * LTS version pattern (v2.4.*)
+ *
+ * @var string
+ */
+ private const LTS_VERSION_PATTERN = '/^v2\.4\.\d+$/';
+
/**
* Stream context
*
@@ -130,23 +137,67 @@ class Updater
}
/**
- * Returns information of latest TorrentPier version available
+ * Returns information of latest TorrentPier LTS version (v2.4.*) available
+ *
+ * @param bool $allowPreReleases
+ * @return array
+ * @throws Exception
+ */
+ public function getLastVersion(bool $allowPreReleases = true): array
+ {
+ // Filter releases to get only LTS versions (v2.4.*)
+ $ltsVersions = array_filter($this->jsonResponse, function ($release) {
+ return preg_match(self::LTS_VERSION_PATTERN, $release['tag_name']);
+ });
+
+ if (empty($ltsVersions)) {
+ throw new Exception('No LTS versions (v2.4.*) found');
+ }
+
+ // Sort LTS versions by version number (descending)
+ usort($ltsVersions, function ($a, $b) {
+ return version_compare($b['tag_name'], $a['tag_name']);
+ });
+
+ if (!$allowPreReleases) {
+ foreach ($ltsVersions as $release) {
+ if (isset($release['prerelease']) && $release['prerelease']) {
+ continue;
+ }
+ return $release;
+ }
+
+ // If no stable LTS versions found
+ throw new Exception('No stable LTS versions (v2.4.*) found');
+ }
+
+ return $ltsVersions[0];
+ }
+
+ /**
+ * Get all available LTS versions (v2.4.*)
*
* @param bool $allowPreReleases
* @return array
*/
- public function getLastVersion(bool $allowPreReleases = true): array
+ public function getAllLTSVersions(bool $allowPreReleases = true): array
{
- if (!$allowPreReleases) {
- foreach ($this->jsonResponse as $index) {
- if (isset($index['prerelease']) && $index['prerelease']) {
- continue;
- }
+ // Filter releases to get only LTS versions (v2.4.*)
+ $ltsVersions = array_filter($this->jsonResponse, function ($release) use ($allowPreReleases) {
+ $isLTSVersion = preg_match(self::LTS_VERSION_PATTERN, $release['tag_name']);
- return $index;
+ if (!$allowPreReleases && isset($release['prerelease']) && $release['prerelease']) {
+ return false;
}
- }
- return $this->jsonResponse[0];
+ return $isLTSVersion;
+ });
+
+ // Sort LTS versions by version number (descending)
+ usort($ltsVersions, function ($a, $b) {
+ return version_compare($b['tag_name'], $a['tag_name']);
+ });
+
+ return array_values($ltsVersions);
}
}
diff --git a/styles/templates/admin/index.tpl b/styles/templates/admin/index.tpl
index 3c8f30941..f29030591 100644
--- a/styles/templates/admin/index.tpl
+++ b/styles/templates/admin/index.tpl
@@ -1,7 +1,7 @@
-
+
@@ -160,7 +160,7 @@
{L_UPDATE_AVAILABLE}: |
- {updater.NEW_VERSION_NUMBER} ({L_SIZE}: {updater.NEW_VERSION_SIZE}) · {L_DOWNLOAD} · {L_CHANGELOG} · MD5: {updater.NEW_VERSION_MD5} |
+ {updater.NEW_VERSION_NUMBER} ({L_SIZE}: {updater.NEW_VERSION_SIZE}) · {L_DOWNLOAD} · {L_CHANGELOG} · {updater.NEW_VERSION_HASH} |
diff --git a/styles/templates/default/filelist.tpl b/styles/templates/default/filelist.tpl
index 9e6bc4eb4..149a98acc 100644
--- a/styles/templates/default/filelist.tpl
+++ b/styles/templates/default/filelist.tpl
@@ -6,30 +6,6 @@
-{L_BT_FLIST_ANNOUNCERS_LIST}
-
-
-
- # |
- {L_BT_FLIST_ANNOUNCERS} |
-
-
-
-
-
- {announcers.ROW_NUMBER} |
- {announcers.ANNOUNCER} |
-
-
-
-
-
- {L_BT_FLIST_ANNOUNCERS_NOTICE} |
-
-
-
-
-
{L_BT_FLIST}
diff --git a/styles/templates/default/images/icons_sources/icon_large.gif b/styles/templates/default/images/icons_sources/icon_large.gif
new file mode 100644
index 000000000..e3d072db6
Binary files /dev/null and b/styles/templates/default/images/icons_sources/icon_large.gif differ
diff --git a/styles/templates/default/images/icons_sources/icon_medium.gif b/styles/templates/default/images/icons_sources/icon_medium.gif
new file mode 100644
index 000000000..fed70f75e
Binary files /dev/null and b/styles/templates/default/images/icons_sources/icon_medium.gif differ
diff --git a/styles/templates/default/images/icons_sources/icon_small.gif b/styles/templates/default/images/icons_sources/icon_small.gif
new file mode 100644
index 000000000..85b723015
Binary files /dev/null and b/styles/templates/default/images/icons_sources/icon_small.gif differ
diff --git a/styles/templates/default/images/icons_sources/info.txt b/styles/templates/default/images/icons_sources/info.txt
new file mode 100644
index 000000000..5a3a6608e
--- /dev/null
+++ b/styles/templates/default/images/icons_sources/info.txt
@@ -0,0 +1,2 @@
+Color: #3c618b
+Font: Arial (Regular) 11pt
diff --git a/styles/templates/default/page_header.tpl b/styles/templates/default/page_header.tpl
index 0ec5fb8f5..a4b2db8bf 100644
--- a/styles/templates/default/page_header.tpl
+++ b/styles/templates/default/page_header.tpl
@@ -1,5 +1,5 @@
-
+
diff --git a/viewtopic.php b/viewtopic.php
index 82d39e685..7a0aec0bf 100644
--- a/viewtopic.php
+++ b/viewtopic.php
@@ -85,17 +85,17 @@ if ($topic_id && isset($_GET['view']) && ($_GET['view'] == 'next' || $_GET['view
// Get forum/topic data
if ($topic_id) {
- $sql = "SELECT t.*, f.*, tw.notify_status
+ $sql = "SELECT t.*, f.cat_id, f.forum_name, f.forum_desc, f.forum_status, f.forum_order, f.forum_posts, f.forum_topics, f.forum_last_post_id, f.forum_tpl_id, f.prune_days, f.auth_view, f.auth_read, f.auth_post, f.auth_reply, f.auth_edit, f.auth_delete, f.auth_sticky, f.auth_announce, f.auth_vote, f.auth_pollcreate, f.auth_attachments, f.auth_download, f.allow_reg_tracker, f.allow_porno_topic, f.self_moderated, f.forum_parent, f.show_on_index, f.forum_display_sort, f.forum_display_order, tw.notify_status
FROM " . BB_TOPICS . " t
- LEFT JOIN " . BB_FORUMS . " f USING(forum_id)
+ LEFT JOIN " . BB_FORUMS . " f ON t.forum_id = f.forum_id
LEFT JOIN " . BB_TOPICS_WATCH . " tw ON(tw.topic_id = t.topic_id AND tw.user_id = {$userdata['user_id']})
WHERE t.topic_id = $topic_id
";
} elseif ($post_id) {
- $sql = "SELECT t.*, f.*, p.post_time, tw.notify_status
+ $sql = "SELECT t.*, f.cat_id, f.forum_name, f.forum_desc, f.forum_status, f.forum_order, f.forum_posts, f.forum_topics, f.forum_last_post_id, f.forum_tpl_id, f.prune_days, f.auth_view, f.auth_read, f.auth_post, f.auth_reply, f.auth_edit, f.auth_delete, f.auth_sticky, f.auth_announce, f.auth_vote, f.auth_pollcreate, f.auth_attachments, f.auth_download, f.allow_reg_tracker, f.allow_porno_topic, f.self_moderated, f.forum_parent, f.show_on_index, f.forum_display_sort, f.forum_display_order, p.post_time, tw.notify_status
FROM " . BB_TOPICS . " t
- LEFT JOIN " . BB_FORUMS . " f USING(forum_id)
- LEFT JOIN " . BB_POSTS . " p USING(topic_id)
+ LEFT JOIN " . BB_FORUMS . " f ON t.forum_id = f.forum_id
+ LEFT JOIN " . BB_POSTS . " p ON t.topic_id = p.topic_id
LEFT JOIN " . BB_TOPICS_WATCH . " tw ON(tw.topic_id = t.topic_id AND tw.user_id = {$userdata['user_id']})
WHERE p.post_id = $post_id
";
@@ -759,7 +759,9 @@ if (defined('SPLIT_FORM_START')) {
$template->assign_vars([
'SPLIT_FORM' => true,
'START' => $start,
- 'S_SPLIT_ACTION' => 'modcp.php'
+ 'S_SPLIT_ACTION' => 'modcp.php',
+ 'POST_FORUM_URL' => POST_FORUM_URL,
+ 'POST_TOPIC_URL' => POST_TOPIC_URL,
]);
}