Compare commits

...

27 commits

Author SHA1 Message Date
Roman Kelesidis
c27d4373d6
release: v2.4.10
Some checks failed
Continuous Integration / Nightly builds 📦 (push) Has been cancelled
PHPMD / Run PHPMD scanning (push) Has been cancelled
2025-07-03 10:53:59 +03:00
Roman Kelesidis
9024640d59
feat(lang): Added RTL languages support (#2031) 2025-07-03 10:35:30 +03:00
Roman Kelesidis
e6976721dc
revert: "refactor: Moved Select class into Legacy\Common (#1846)"
This reverts commit bd0ef063fa.
2025-07-03 10:10:48 +03:00
Roman Kelesidis
695864ef69
feat: Restore some deprecated code for backward compatibility (#2028)
Some checks are pending
Continuous Integration / Nightly builds 📦 (push) Waiting to run
PHPMD / Run PHPMD scanning (push) Waiting to run
* feat: Restore some deprecated code for backward compatibility

* feat: Restore some constants

* feat: Restore `commify()` function

* feat: Restored functions: `bb_ltrim`, `bb_rtrim`, `get_db_stat`

* feat: Restore `bb_realpath`

* Update functions.php

* feat: Restore `AJAX_HTML_DIR` constant

* Update defines.php

* Update attach_maintenance.php

* Update viewtopic.php
2025-07-02 12:46:27 +03:00
Roman Kelesidis
90121aa21d
release: v2.4.9 2025-07-02 10:34:18 +03:00
Roman Kelesidis
68403760c1
refactor(TorrentFileList): Reduce duplication in root directory unset logic (#2027) 2025-07-02 10:31:07 +03:00
Roman Kelesidis
57d0d59b53
feat(updater): Added exceptions logging (#2026)
* feat(updater): Added exceptions logging

* refactor(updater): Use `sha256` hash if available
2025-07-02 10:16:54 +03:00
Roman Kelesidis
76b191ff41
release: v2.4.8
Some checks failed
Continuous Integration / Nightly builds 📦 (push) Has been cancelled
PHPMD / Run PHPMD scanning (push) Has been cancelled
2025-06-30 10:48:29 +03:00
Roman Kelesidis
a5fbc2ffc7
fix(TorrentFileList): Avoid array_merge reindexing for numeric folder names (#2014)
Some checks are pending
Continuous Integration / Nightly builds 📦 (push) Waiting to run
PHPMD / Run PHPMD scanning (push) Waiting to run
Co-authored-by: zxc <17812947+metalwarrior88@users.noreply.github.com>
2025-06-29 15:01:20 +03:00
Roman Kelesidis
c2cbc77b14
refactor: Use DEFAULT_CHARSET constant instead of hardcoded string (#2011)
Some checks failed
Continuous Integration / Nightly builds 📦 (push) Has been cancelled
PHPMD / Run PHPMD scanning (push) Has been cancelled
2025-06-26 13:31:41 +03:00
Roman Kelesidis
134b3dfa5c
fix(redirect): add no-cache headers to prevent browser caching of redirects (#2010) 2025-06-26 13:07:42 +03:00
Roman Kelesidis
986d198aaf
release: v2.4.7 2025-06-24 13:23:52 +03:00
Roman Kelesidis
12ce6e783e
fix(ip-api): Add error handling and logging for freeipapi.com requests (#2006) 2025-06-24 13:18:35 +03:00
Roman Kelesidis
8c161ceae0
fix(filelist): Undefined property: FileTree::$length when v2 torrent only (#2004) 2025-06-24 13:16:04 +03:00
belomaxorka
896cf6c3d6 changelog: Update CHANGELOG.md 📖
Some checks failed
Continuous Integration / Nightly builds 📦 (push) Has been cancelled
PHPMD / Run PHPMD scanning (push) Has been cancelled
2025-06-20 06:12:19 +00:00
Roman Kelesidis
dc64426574
docs: Changed nightly.link url in README.md (#1977)
Some checks are pending
Continuous Integration / Nightly builds 📦 (push) Waiting to run
PHPMD / Run PHPMD scanning (push) Waiting to run
2025-06-19 18:34:15 +03:00
Roman Kelesidis
b7bc7f9166
docs: Updated Requirements sections in README.md (#1975) 2025-06-19 14:52:07 +03:00
Roman Kelesidis
403fcf2aca
docs: Fixed some typos in README.md (#1974) 2025-06-19 14:47:06 +03:00
Roman Kelesidis
de9f5e2cb1
release: v2.4.6 🦜 2025-06-19 11:19:30 +03:00
Roman Kelesidis
6a1d682385
fix: Duplicate column SQL query issues in viewtopic.php (#1973)
Co-authored-by: Yury Pikhtarev <exileum@icloud.com>
2025-06-19 11:16:17 +03:00
Roman Kelesidis
faf3d79192
fix(sql): Resolve only_full_group_by compatibility issues in tracker cleanup
- Replace non-aggregated 'seeder' column with MAX(seeder) in GROUP BY query
- Remove ORDER BY clause incompatible with GROUP BY in seeder update query

Fixes MySQL 5.7+ strict SQL mode errors in tr_cleanup_and_dlstat cron job.

Co-Authored-By: Yury Pikhtarev <exileum@icloud.com>
2025-06-19 11:11:35 +03:00
Roman Kelesidis
7dc69ba699
chore: Changed active branch name in _release.php (#1972)
* chore: Changed active branch name in `_release.php`

* Update _release.php
2025-06-19 11:08:58 +03:00
Roman Kelesidis
2a8b6daecf
fix: SQL queries in online_userlist.php to use MAX() for session data and adjusted GROUP BY clause for better accuracy (#1971)
Co-authored-by: Yury Pikhtarev <exileum@icloud.com>
2025-06-19 11:05:23 +03:00
Roman Kelesidis
7d9594eeda
chore(cliff): Add conventional commit prefix to changelog message (#1970) 2025-06-19 11:01:52 +03:00
Roman Kelesidis
15f9948403
fix(installer): Strip protocol from TP_HOST to keep only hostname (#1969) 2025-06-19 10:59:18 +03:00
belomaxorka
ce1f35c2b5 Update CHANGELOG.md 📖 2025-06-19 07:52:50 +00:00
Roman Kelesidis
a8e252f64f
chore: Changed branch name from master to v2.4 (#1968) 2025-06-19 10:50:26 +03:00
38 changed files with 368 additions and 200 deletions

View file

@ -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

View file

@ -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'

View file

@ -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

View file

@ -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)

View file

@ -9,25 +9,25 @@
<a href="https://github.com/torrentpier/torrentpier/blob/master/LICENSE"><img src="https://img.shields.io/github/license/torrentpier/torrentpier" alt="License"></a>
<a href="https://packagist.org/packages/torrentpier/torrentpier"><img src="https://img.shields.io/packagist/stars/torrentpier/torrentpier" alt="Stars Packagist"></a>
<a href="https://crowdin.com/project/torrentpier"><img src="https://badges.crowdin.net/torrentpier/localized.svg" alt="Crowdin"></a>
<a href="https://nightly.link/torrentpier/torrentpier/workflows/ci/master/TorrentPier-master"><img src="https://img.shields.io/badge/Nightly%20release-gray?logo=hackthebox&logoColor=fff" alt="TorrentPier nightly"></a>
<a href="https://nightly.link/torrentpier/torrentpier/workflows/ci/v2.4/TorrentPier-v2.4"><img src="https://img.shields.io/badge/Nightly%20release-gray?logo=hackthebox&logoColor=fff" alt="TorrentPier nightly"></a>
<a href="https://packagist.org/packages/torrentpier/torrentpier"><img src="https://img.shields.io/packagist/dt/torrentpier/torrentpier" alt="Downloads"></a>
<a href="https://packagist.org/packages/torrentpier/torrentpier"><img src="https://img.shields.io/packagist/v/torrentpier/torrentpier" alt="Version"></a>
<a href="https://github.com/torrentpier/torrentpier/releases"><img src="https://img.shields.io/github/release-date/torrentpier/torrentpier" alt="Last release"></a>
<img src="https://img.shields.io/github/repo-size/torrentpier/torrentpier" alt="Size">
<a href="https://github.com/SamKirkland/FTP-Deploy-Action"><img src="https://img.shields.io/badge/Deployed to TorrentPier Demo with-FTP DEPLOY ACTION-%3CCOLOR%3E?color=2b9348" alt="Deployed to TorrentPier Demo with FTP Deploy Action"></a>
<a href="https://github.com/SamKirkland/FTP-Deploy-Action"><img src="https://img.shields.io/badge/Deployed%20with-FTP%20DEPLOY%20ACTION-2b9348" alt="Deployed with FTP Deploy Action"></a>
</p>
## 🐂 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!
<a href="https://github.com/torrentpier/torrentpier/graphs/contributors">
@ -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.
[![OpenCollective sponsors](https://opencollective.com/torrentpier/sponsors/badge.svg)](https://opencollective.com/torrentpier)
[![OpenCollective backers](https://opencollective.com/torrentpier/backers/badge.svg)](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

View file

@ -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');

View file

@ -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'],

View file

@ -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 )

View file

@ -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']
]);
}

View file

@ -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)');

View file

@ -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));

View file

@ -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 = "<!-- 2 -->🚜 Refactor" },
{ message = "^style", group = "<!-- 5 -->🎨 Styling" },
{ message = "^test", group = "<!-- 6 -->🧪 Testing" },
{ message = "^ignore|^release", skip = true },
{ message = "^ignore|^release|^changelog", skip = true },
{ message = "^chore|^ci|^misc", group = "<!-- 7 -->⚙️ Miscellaneous" },
{ body = ".*security", group = "<!-- 8 -->🛡️ Security" },
{ message = "^revert", group = "<!-- 9 -->◀️ Revert" },

80
composer.lock generated
View file

@ -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"
}

View file

@ -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 . ")",

View file

@ -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 {

View file

@ -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'];
}
}
}

View file

@ -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,

View file

@ -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');

View file

@ -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");

View file

@ -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

View file

@ -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);

View file

@ -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<wbr>', $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)) {

View file

@ -293,6 +293,7 @@ define('USER_AGENT', strtolower($_SERVER['HTTP_USER_AGENT']));
define('HTML_SELECT_MAX_LENGTH', 60);
define('HTML_SF_SPACER', '&nbsp;|-&nbsp;');
define('HTML_WBR_LENGTH', 12);
define('HTML_CHECKED', ' checked ');
define('HTML_DISABLED', ' disabled ');

View file

@ -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
";

View file

@ -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' => '<input type="hidden" name="sid" value="' . $userdata['session_id'] . '" />',

View file

@ -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'),

View file

@ -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&amp;postorder=desc" : '',
'S_NOTIFY_CHECKED' => $notify_user ? 'checked' : '',
'S_ROBOTS_CHECKED' => $robots_indexing ? 'checked' : '',
'S_TYPE_TOGGLE' => $topic_type_toggle,

View file

@ -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
{

View file

@ -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);

View file

@ -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);
}
}

View file

@ -1,7 +1,7 @@
<!-- IF TPL_ADMIN_FRAMESET -->
<!--========================================================================-->
<!DOCTYPE html>
<html lang="{$bb_cfg['default_lang']}">
<html dir="{USER_LANG_DIRECTION}" lang="{USER_LANG}">
<head>
<meta charset="{CONTENT_ENCODING}">
<link rel="shortcut icon" href="{SITE_URL}favicon.png" type="image/x-icon">
@ -160,7 +160,7 @@
<!-- IF updater.UPDATE_AVAILABLE -->
<tr>
<td class="row1" nowrap="nowrap" width="25%"><b>{L_UPDATE_AVAILABLE}:</b></td>
<td class="row2"><b>{updater.NEW_VERSION_NUMBER}</b><!-- IF updater.NEW_VERSION_SIZE -->&nbsp;({L_SIZE}:&nbsp;{updater.NEW_VERSION_SIZE})<!-- ENDIF -->&nbsp;&middot;&nbsp;<a target="_blank" href="{updater.NEW_VERSION_DL_LINK}">{L_DOWNLOAD}</a>&nbsp;&middot;&nbsp;<a target="_blank" href="{updater.NEW_VERSION_LINK}">{L_CHANGELOG}</a><!-- IF updater.NEW_VERSION_MD5 -->&nbsp;&middot;&nbsp;<span class="copyElement" data-clipboard-text="{updater.NEW_VERSION_MD5}" title="{L_COPY_TO_CLIPBOARD}">MD5:&nbsp;{updater.NEW_VERSION_MD5}</span><!-- ENDIF --></td>
<td class="row2"><b>{updater.NEW_VERSION_NUMBER}</b><!-- IF updater.NEW_VERSION_SIZE -->&nbsp;({L_SIZE}:&nbsp;{updater.NEW_VERSION_SIZE})<!-- ENDIF -->&nbsp;&middot;&nbsp;<a target="_blank" href="{updater.NEW_VERSION_DL_LINK}">{L_DOWNLOAD}</a>&nbsp;&middot;&nbsp;<a target="_blank" href="{updater.NEW_VERSION_LINK}">{L_CHANGELOG}</a><!-- IF updater.NEW_VERSION_HASH -->&nbsp;&middot;&nbsp;<span class="copyElement" data-clipboard-text="{updater.NEW_VERSION_HASH}" title="{L_COPY_TO_CLIPBOARD}">{updater.NEW_VERSION_HASH}</span><!-- ENDIF --></td>
</tr>
<!-- ENDIF -->
<!-- END updater -->

View file

@ -6,30 +6,6 @@
</ul>
<br/>
<h1 class="pagetitle">{L_BT_FLIST_ANNOUNCERS_LIST}</h1>
<table class="forumline">
<thead>
<tr>
<th>#</th>
<th>{L_BT_FLIST_ANNOUNCERS}</th>
</tr>
</thead>
<!-- BEGIN announcers -->
<tbody>
<tr class="{announcers.ROW_CLASS} tCenter">
<td>{announcers.ROW_NUMBER}</td>
<td>{announcers.ANNOUNCER}</td>
</tr>
</tbody>
<!-- END announcers -->
<tfoot>
<tr>
<td class="catBottom warnColor1" colspan="2">{L_BT_FLIST_ANNOUNCERS_NOTICE}</td>
</tr>
</tfoot>
</table>
<br/>
<h1 class="pagetitle">{L_BT_FLIST}</h1>
<table class="forumline">
<thead>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,2 @@
Color: #3c618b
Font: Arial (Regular) 11pt

View file

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="{$bb_cfg['default_lang']}">
<html dir="{USER_LANG_DIRECTION}" lang="{USER_LANG}">
<head>
<meta charset="{CONTENT_ENCODING}">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">

View file

@ -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,
]);
}