diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..c9f61d6d4
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,49 @@
+## π Whatβs this Pull Request?
+
+Please describe the purpose and context of this PR. Is it a bugfix, a feature, a refactor, or maintenance?
+
+- Type:
+ - [ ] Bugfix
+ - [ ] Feature
+ - [ ] Refactor
+ - [ ] Chore
+ - [ ] Other
+- Related Issue(s): Closes #XXXX, Implements #XXXX
+
+## β
Whatβs Changed?
+
+Briefly summarize the changes youβve made.
+
+- ...
+- ...
+- ...
+
+## π¬ How to Test
+
+Describe how a maintainer or reviewer can manually verify your changes.
+
+1. ...
+2. ...
+3. ...
+
+## π§ͺ Tests
+
+- [ ] Unit tests added or updated
+- [ ] No tests needed
+- [ ] Not applicable
+
+## π Documentation
+
+- [ ] Updated relevant docs
+- [ ] No docs needed
+- [ ] Not applicable
+
+## π‘ Additional Notes
+
+- Compatibility concerns? (e.g., PHP version, tracker behavior, database migrations)
+- Any known limitations?
+- Anything reviewers should pay special attention to?
+
+## πΈ UI / Frontend Changes (if applicable)
+
+_Add screenshots, videos, or gif demos if you made UI changes._
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e92dfe326..aec956ad7 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,17 +44,17 @@ 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
+ - name: Checkout code π³
uses: actions/checkout@v4
- - name: π© Setup PHP
+ - name: Setup PHP π©
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
@@ -62,10 +62,10 @@ jobs:
- name: Update composer.lock file
run: composer update --no-install
- - name: π Install Composer dependencies
+ - name: Install Composer dependencies πͺ
run: composer install --no-progress --prefer-dist --optimize-autoloader
- - name: π Sync files
+ - name: Sync files π
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
with:
server: ${{ secrets.FTP_SERVER }}
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..05139d7a4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,99 @@
# π Change Log
-## [nightly](https://nightly.link/torrentpier/torrentpier/workflows/ci/master/TorrentPier-master)
+## [v2.4.11](https://github.com/torrentpier/torrentpier/compare/v2.4.10..v2.4.11) (2025-08-06)
+
+### π Features
+
+- *(log action)* Show `torrent delete` action ([#2061](https://github.com/torrentpier/torrentpier/pull/2061)) - ([f80cad0](https://github.com/torrentpier/torrentpier/commit/f80cad0c6f8606ae3314e6dc4962f027f12798a3))
+- *(log action)* Show torrent register action ([#2060](https://github.com/torrentpier/torrentpier/pull/2060)) - ([66c01a5](https://github.com/torrentpier/torrentpier/commit/66c01a591f8618e911fd042cc23bf36902de8a38))
+- *(view_torrent.php)* Added checking auth to download ([#2067](https://github.com/torrentpier/torrentpier/pull/2067)) - ([7e38c5b](https://github.com/torrentpier/torrentpier/commit/7e38c5b63cacaec4c974a423fd1a6c0352529fd6))
+- *(vote topic)* Improved functionality & implemented caching ([#2063](https://github.com/torrentpier/torrentpier/pull/2063)) - ([e1337ef](https://github.com/torrentpier/torrentpier/commit/e1337ef5bc9cd7741d40cd645059019b5b5b576a))
+- Add clear button for file upload input in `posting_attach.tpl` ([#2072](https://github.com/torrentpier/torrentpier/pull/2072)) - ([7c6ab0e](https://github.com/torrentpier/torrentpier/commit/7c6ab0eed4691fa0f1bd29f9e19f956fdb16b43e))
+- Prevent robots indexing for private topics ([#2071](https://github.com/torrentpier/torrentpier/pull/2071)) - ([eecfe1a](https://github.com/torrentpier/torrentpier/commit/eecfe1a9515034d263a49f84210d3d32430253be))
+- Added check for frozen torrent in `playback_m3u.php` ([#2065](https://github.com/torrentpier/torrentpier/pull/2065)) - ([57a9f3f](https://github.com/torrentpier/torrentpier/commit/57a9f3f7c67ca5c8db2218269a465bfc2d4644b4))
+- Add option to use original torrent filenames for downloads ([#2064](https://github.com/torrentpier/torrentpier/pull/2064)) - ([07399fc](https://github.com/torrentpier/torrentpier/commit/07399fc00df214d1ad863e8a893495ace26ff7fa))
+- Added check for demo-mode in `admin_robots.php` and `admin_sitemap.php` ([#2046](https://github.com/torrentpier/torrentpier/pull/2046)) - ([dd64236](https://github.com/torrentpier/torrentpier/commit/dd64236da12f7d76e0b548601c86f38164a71725))
+
+### π Bug Fixes
+
+- *(ACP)* A non-numeric value encountered for stats ([#2073](https://github.com/torrentpier/torrentpier/pull/2073)) - ([d690447](https://github.com/torrentpier/torrentpier/commit/d690447cdbdf7f07de9a539ef752dab69a205390))
+- *(Attach.php)* Trying to access array offset on value of type null ([#2075](https://github.com/torrentpier/torrentpier/pull/2075)) - ([abb2b24](https://github.com/torrentpier/torrentpier/commit/abb2b242b75d1acc41e2d901f8b558e90a3b35d7))
+- Prevent showing meta description if defined `HAS_DIED` ([#2070](https://github.com/torrentpier/torrentpier/pull/2070)) - ([3eba11f](https://github.com/torrentpier/torrentpier/commit/3eba11f26b3432ef7446de5bc938cbcbfa4932f5))
+- Make `Ajax::$action` property nullable to handle missing POST parameter ([#2066](https://github.com/torrentpier/torrentpier/pull/2066)) - ([efd85ee](https://github.com/torrentpier/torrentpier/commit/efd85eef4ad69e5b53be3f3d0ea75d267d0b664c))
+
+### π¦ Dependencies
+
+- Replace `belomaxorka/captcha` with `gregwar/captcha` ([#2069](https://github.com/torrentpier/torrentpier/pull/2069)) - ([d12e6ba](https://github.com/torrentpier/torrentpier/commit/d12e6ba922d38c5c24380c58c037d405af5c38c9))
+
+### π Refactor
+
+- *(admin)* Remove redundant `dir` and `lang` attributes from html tag ([#2051](https://github.com/torrentpier/torrentpier/pull/2051)) - ([bb992fd](https://github.com/torrentpier/torrentpier/commit/bb992fd81b0fede511ab566fdc7bf4d25b924ae2))
+
+### βοΈ Miscellaneous
+
+- Some minor improvements ([#2076](https://github.com/torrentpier/torrentpier/pull/2076)) - ([5ff296f](https://github.com/torrentpier/torrentpier/commit/5ff296f83be87a0cc5607fd352d62321819b0e03))
+- Some minor improvements ([#2068](https://github.com/torrentpier/torrentpier/pull/2068)) - ([e3eb22e](https://github.com/torrentpier/torrentpier/commit/e3eb22e2d8d7b3bd2413cfcb1badfbd81ee9dc54))
+- Added pull request template & updated workflow ([#2052](https://github.com/torrentpier/torrentpier/pull/2052)) - ([a863a61](https://github.com/torrentpier/torrentpier/commit/a863a619419881e831a6556fa5e77dae746ff031))
+
+
+## [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 +103,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_log.php b/admin/admin_log.php
index 517a4b9bb..01dbba373 100644
--- a/admin/admin_log.php
+++ b/admin/admin_log.php
@@ -228,6 +228,8 @@ if ($log_rowset) {
case $log_type['mod_topic_change_tor_status']:
case $log_type['mod_topic_change_tor_type']:
case $log_type['mod_topic_tor_unregister']:
+ case $log_type['mod_topic_tor_register']:
+ case $log_type['mod_topic_tor_delete']:
case $log_type['mod_topic_renamed']:
case $log_type['mod_post_delete']:
case $log_type['mod_post_pin']:
diff --git a/admin/admin_robots.php b/admin/admin_robots.php
index 44d73d52b..36fd92a1f 100644
--- a/admin/admin_robots.php
+++ b/admin/admin_robots.php
@@ -16,8 +16,12 @@ require __DIR__ . '/pagestart.php';
$robots_file = BB_ROOT . 'robots.txt';
-// ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΡ
if (isset($_POST['save'])) {
+ // Check for demo mode
+ if (IN_DEMO_MODE) {
+ bb_die($lang['CANT_EDIT_IN_DEMO_MODE']);
+ }
+
$robots_txt = $_POST['robots_txt'] ?? '';
if (!is_writable($robots_file) && is_file($robots_file)) {
diff --git a/admin/admin_sitemap.php b/admin/admin_sitemap.php
index 3e3fd1fb6..15c605803 100644
--- a/admin/admin_sitemap.php
+++ b/admin/admin_sitemap.php
@@ -33,6 +33,10 @@ if (!$result = DB()->sql_query($sql)) {
}
if (isset($_POST['submit'])) {
+ // Check for demo mode
+ if (IN_DEMO_MODE) {
+ bb_die($lang['CANT_EDIT_IN_DEMO_MODE']);
+ }
if (!empty($new_params)) {
bb_update_config($new_params);
}
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..1f7bbd491 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']
]);
}
@@ -128,14 +128,14 @@ if (isset($_GET['pane']) && $_GET['pane'] == 'left') {
$topics_per_day = $total_topics;
}
- if ($users_per_day > $total_users) {
+ if ((int)$users_per_day > $total_users) {
$users_per_day = $total_users;
}
$template->assign_vars([
- 'NUMBER_OF_POSTS' => $total_posts,
- 'NUMBER_OF_TOPICS' => $total_topics,
- 'NUMBER_OF_USERS' => $total_users,
+ 'NUMBER_OF_POSTS' => commify($total_posts),
+ 'NUMBER_OF_TOPICS' => commify($total_topics),
+ 'NUMBER_OF_USERS' => commify($total_users),
'START_DATE' => $start_date,
'POSTS_PER_DAY' => $posts_per_day,
'TOPICS_PER_DAY' => $topics_per_day,
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..105f9ee7c 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,12 +105,12 @@ 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" },
{ message = "^crowdin|^crodwin", group = "π³ New translations" }, # crowdin pulls supporting
- { message = "^Composer", group = "π¦ Dependencies" }, # dependabot pulls supporting
+ { message = "^Composer|^deps", group = "π¦ Dependencies" }, # dependabot pulls supporting
{ message = "^rem|^drop|^removed", group = "ποΈ Removed" },
{ message = ".*", group = "πΌ Other" },
]
diff --git a/composer.json b/composer.json
index a15ef15cc..c5aaa06ff 100644
--- a/composer.json
+++ b/composer.json
@@ -53,7 +53,7 @@
"arokettu/torrent-file": "^5.2.1",
"bugsnag/bugsnag": "^v3.29.1",
"claviska/simpleimage": "^4.0",
- "belomaxorka/captcha": "1.*",
+ "gregwar/captcha": "1.*",
"egulias/email-validator": "^4.0.1",
"filp/whoops": "^2.15",
"z4kn4fein/php-semver": "^v3.0.0",
diff --git a/composer.lock b/composer.lock
index a3fa490ba..5ce29ce7c 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "2acad3dafd9fd57bc8c26303df22dd15",
+ "content-hash": "4a8e483526e6241286bf04937e1f4913",
"packages": [
{
"name": "arokettu/bencode",
@@ -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",
@@ -411,88 +411,18 @@
},
"time": "2025-03-31T23:49:37+00:00"
},
- {
- "name": "belomaxorka/captcha",
- "version": "v1.2.4",
- "source": {
- "type": "git",
- "url": "https://github.com/belomaxorka/Captcha.git",
- "reference": "db51723a9539b57ac3faff0211c117b4c55dbe23"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/belomaxorka/Captcha/zipball/db51723a9539b57ac3faff0211c117b4c55dbe23",
- "reference": "db51723a9539b57ac3faff0211c117b4c55dbe23",
- "shasum": ""
- },
- "require": {
- "ext-fileinfo": "*",
- "ext-gd": "*",
- "ext-mbstring": "*",
- "php": ">=5.3.0",
- "symfony/finder": "*"
- },
- "require-dev": {
- "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6.4 || ^7.0 || ^8.0 || ^9.0"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Gregwar\\": "src/Gregwar"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "GrΓ©goire Passault",
- "email": "g.passault@gmail.com",
- "homepage": "https://www.gregwar.com/",
- "role": "Developer"
- },
- {
- "name": "Jeremy Livingston",
- "email": "jeremy.j.livingston@gmail.com"
- },
- {
- "name": "belomaxorka",
- "email": "roman25052006.kelesh@gmail.com",
- "homepage": "https://belomaxorka.github.io/",
- "role": "Developer"
- }
- ],
- "description": "Captcha generator",
- "homepage": "https://github.com/belomaxorka/Captcha",
- "keywords": [
- "anti-bot",
- "anti-spam",
- "bot-protection",
- "captcha",
- "no-bot",
- "obfuscation",
- "security",
- "spam",
- "spam-protection"
- ],
- "support": {
- "source": "https://github.com/belomaxorka/Captcha/tree/v1.2.4"
- },
- "time": "2025-03-10T13:15:53+00:00"
- },
{
"name": "bugsnag/bugsnag",
- "version": "v3.29.3",
+ "version": "v3.30.0",
"source": {
"type": "git",
"url": "https://github.com/bugsnag/bugsnag-php.git",
- "reference": "9d9aa665f5e9d24f45aad5114dbd2d861119febb"
+ "reference": "ea174966d8a09424d7963e1e0fe9d570b63ff98c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/bugsnag/bugsnag-php/zipball/9d9aa665f5e9d24f45aad5114dbd2d861119febb",
- "reference": "9d9aa665f5e9d24f45aad5114dbd2d861119febb",
+ "url": "https://api.github.com/repos/bugsnag/bugsnag-php/zipball/ea174966d8a09424d7963e1e0fe9d570b63ff98c",
+ "reference": "ea174966d8a09424d7963e1e0fe9d570b63ff98c",
"shasum": ""
},
"require": {
@@ -540,9 +470,9 @@
],
"support": {
"issues": "https://github.com/bugsnag/bugsnag-php/issues",
- "source": "https://github.com/bugsnag/bugsnag-php/tree/v3.29.3"
+ "source": "https://github.com/bugsnag/bugsnag-php/tree/v3.30.0"
},
- "time": "2025-03-06T12:03:07+00:00"
+ "time": "2025-07-08T15:15:58+00:00"
},
{
"name": "claviska/simpleimage",
@@ -995,16 +925,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 +973,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",
@@ -1107,6 +1037,64 @@
],
"time": "2024-07-20T21:45:45+00:00"
},
+ {
+ "name": "gregwar/captcha",
+ "version": "v1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Gregwar/Captcha.git",
+ "reference": "4edbcd09fde4353b94ce550f43460eba73baf2cc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Gregwar/Captcha/zipball/4edbcd09fde4353b94ce550f43460eba73baf2cc",
+ "reference": "4edbcd09fde4353b94ce550f43460eba73baf2cc",
+ "shasum": ""
+ },
+ "require": {
+ "ext-fileinfo": "*",
+ "ext-gd": "*",
+ "ext-mbstring": "*",
+ "php": ">=5.3.0",
+ "symfony/finder": "*"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6.4 || ^7.0 || ^8.0 || ^9.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Gregwar\\": "src/Gregwar"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "GrΓ©goire Passault",
+ "email": "g.passault@gmail.com",
+ "homepage": "http://www.gregwar.com/"
+ },
+ {
+ "name": "Jeremy Livingston",
+ "email": "jeremy.j.livingston@gmail.com"
+ }
+ ],
+ "description": "Captcha generator",
+ "homepage": "https://github.com/Gregwar/Captcha",
+ "keywords": [
+ "bot",
+ "captcha",
+ "spam"
+ ],
+ "support": {
+ "issues": "https://github.com/Gregwar/Captcha/issues",
+ "source": "https://github.com/Gregwar/Captcha/tree/v1.3.0"
+ },
+ "time": "2025-06-23T12:25:54+00:00"
+ },
{
"name": "guzzlehttp/guzzle",
"version": "7.9.3",
@@ -1620,16 +1608,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 +1641,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 +1685,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 +1734,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 +3134,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 +3194,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 +3210,7 @@
"type": "tidelift"
}
],
- "time": "2025-04-26T23:47:35+00:00"
+ "time": "2025-06-26T21:24:02+00:00"
},
{
"name": "symfony/mime",
@@ -3651,16 +3639,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 +3704,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 +3720,7 @@
"type": "tidelift"
}
],
- "time": "2025-04-09T07:34:50+00:00"
+ "time": "2025-06-27T15:05:27+00:00"
}
],
"aliases": [],
@@ -3746,6 +3734,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/index.php b/index.php
index 2c752341c..589b061ae 100644
--- a/index.php
+++ b/index.php
@@ -272,9 +272,9 @@ $template->assign_vars([
'PAGE_TITLE' => $viewcat ? $cat_title_html[$viewcat] : $lang['HOME'],
'NO_FORUMS_MSG' => $only_new ? $lang['NO_NEW_POSTS'] : $lang['NO_FORUMS'],
- 'TOTAL_TOPICS' => sprintf($lang['POSTED_TOPICS_TOTAL'], $stats['topiccount']),
- 'TOTAL_POSTS' => sprintf($lang['POSTED_ARTICLES_TOTAL'], $stats['postcount']),
- 'TOTAL_USERS' => sprintf($lang['REGISTERED_USERS_TOTAL'], $stats['usercount']),
+ 'TOTAL_TOPICS' => sprintf($lang['POSTED_TOPICS_TOTAL'], commify($stats['topiccount'])),
+ 'TOTAL_POSTS' => sprintf($lang['POSTED_ARTICLES_TOTAL'], commify($stats['postcount'])),
+ 'TOTAL_USERS' => sprintf($lang['REGISTERED_USERS_TOTAL'], commify($stats['usercount'])),
'TOTAL_GENDER' => $bb_cfg['gender'] ? sprintf(
$lang['USERS_TOTAL_GENDER'],
$stats['male'],
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/ajax/change_torrent.php b/library/ajax/change_torrent.php
index ca26b7c24..fd6de3bff 100644
--- a/library/ajax/change_torrent.php
+++ b/library/ajax/change_torrent.php
@@ -68,11 +68,23 @@ switch ($type) {
case 'reg':
\TorrentPier\Legacy\Torrent::tracker_register($attach_id);
+ // Log action
+ $log_action->mod('mod_topic_tor_register', [
+ 'forum_id' => $torrent['forum_id'],
+ 'topic_id' => $torrent['topic_id'],
+ 'topic_title' => $torrent['topic_title'],
+ ]);
$url = (TOPIC_URL . $torrent['topic_id']);
break;
case 'unreg':
\TorrentPier\Legacy\Torrent::tracker_unregister($attach_id);
+ // Log action
+ $log_action->mod('mod_topic_tor_unregister', [
+ 'forum_id' => $torrent['forum_id'],
+ 'topic_id' => $torrent['topic_id'],
+ 'topic_title' => $torrent['topic_title'],
+ ]);
$url = (TOPIC_URL . $torrent['topic_id']);
break;
diff --git a/library/ajax/post_mod_comment.php b/library/ajax/post_mod_comment.php
index cca1c8e30..959f66ec6 100644
--- a/library/ajax/post_mod_comment.php
+++ b/library/ajax/post_mod_comment.php
@@ -27,7 +27,7 @@ $post = DB()->fetch_row("
WHERE p.post_id = $post_id
");
if (!$post) {
- $this->ajax_die('not post');
+ $this->ajax_die($lang['TOPIC_POST_NOT_EXIST']);
}
$data = [
diff --git a/library/ajax/posts.php b/library/ajax/posts.php
index e34b8b2c1..694177522 100644
--- a/library/ajax/posts.php
+++ b/library/ajax/posts.php
@@ -26,7 +26,7 @@ if (isset($this->request['post_id'])) {
AND p.post_id = pt.post_id
LIMIT 1");
if (!$post) {
- $this->ajax_die('not post');
+ $this->ajax_die($lang['TOPIC_POST_NOT_EXIST']);
}
$is_auth = auth(AUTH_ALL, $post['forum_id'], $userdata, $post);
diff --git a/library/ajax/thanks.php b/library/ajax/thanks.php
index cbe29ac01..bf536cdd7 100644
--- a/library/ajax/thanks.php
+++ b/library/ajax/thanks.php
@@ -29,6 +29,40 @@ if (!$poster_id = (int)$this->request['poster_id']) {
$this->ajax_die($lang['NO_USER_ID_SPECIFIED']);
}
+$cache_lifetime = 3600;
+$thanks_cache_key = 'topic_thanks_' . $topic_id;
+
+/**
+ * Get thanks by topic id
+ *
+ * @param $topic_id
+ * @param string $thanks_cache_key
+ * @param int $cache_lifetime
+ * @return array
+ */
+function get_thanks_list($topic_id, string $thanks_cache_key, int $cache_lifetime)
+{
+ if (!$cached_thanks = CACHE('bb_cache')->get($thanks_cache_key)) {
+ $cached_thanks = [];
+ $sql = DB()->fetch_rowset('SELECT u.username, u.user_rank, u.user_id, thx.* FROM ' . BB_THX . ' thx, ' . BB_USERS . " u WHERE thx.topic_id = $topic_id AND thx.user_id = u.user_id");
+
+ foreach ($sql as $row) {
+ $cached_thanks[$row['user_id']] = [
+ 'user_id' => $row['user_id'],
+ 'username' => $row['username'],
+ 'user_rank' => $row['user_rank'],
+ 'time' => $row['time']
+ ];
+ }
+
+ if (!empty($cached_thanks)) {
+ CACHE('bb_cache')->set($thanks_cache_key, $cached_thanks, $cache_lifetime);
+ }
+ }
+
+ return $cached_thanks;
+}
+
switch ($mode) {
case 'add':
if (IS_GUEST) {
@@ -39,7 +73,8 @@ switch ($mode) {
$this->ajax_die($lang['LIKE_OWN_POST']);
}
- if (DB()->fetch_row('SELECT topic_id FROM ' . BB_THX . " WHERE topic_id = $topic_id AND user_id = " . $userdata['user_id'])) {
+ $cached_thanks = get_thanks_list($topic_id, $thanks_cache_key, $cache_lifetime);
+ if (isset($cached_thanks[$userdata['user_id']])) {
$this->ajax_die($lang['LIKE_ALREADY']);
}
@@ -47,10 +82,34 @@ switch ($mode) {
$values = "$topic_id, {$userdata['user_id']}, " . TIMENOW;
DB()->query('INSERT IGNORE INTO ' . BB_THX . " ($columns) VALUES ($values)");
+ $cached_thanks[$userdata['user_id']] = [
+ 'user_id' => $userdata['user_id'],
+ 'username' => $userdata['username'],
+ 'user_rank' => $userdata['user_rank'],
+ 'time' => TIMENOW
+ ];
+
// Limit voters per topic
- $thanks_count = DB()->fetch_row('SELECT COUNT(*) as thx FROM ' . BB_THX . " WHERE topic_id = $topic_id")['thx'];
- if ($thanks_count > (int)$bb_cfg['tor_thank_limit_per_topic']) {
- DB()->query('DELETE FROM ' . BB_THX . " WHERE topic_id = $topic_id ORDER BY time ASC LIMIT 1");
+ $tor_thank_limit_per_topic = (int)$bb_cfg['tor_thank_limit_per_topic'];
+ if ($tor_thank_limit_per_topic > 0) {
+ $thanks_count = count($cached_thanks);
+ if ($thanks_count > $tor_thank_limit_per_topic) {
+ $oldest_user_id = null;
+ foreach ($cached_thanks as $user_id => $thanks_data) {
+ // First value
+ $oldest_user_id = $thanks_data['user_id'];
+ break;
+ }
+
+ if ($oldest_user_id) {
+ DB()->query('DELETE FROM ' . BB_THX . " WHERE topic_id = $topic_id AND user_id = $oldest_user_id LIMIT 1");
+ unset($cached_thanks[$oldest_user_id]);
+ }
+ }
+ }
+
+ if (!empty($cached_thanks)) {
+ CACHE('bb_cache')->set($thanks_cache_key, $cached_thanks, $cache_lifetime);
}
break;
case 'get':
@@ -58,9 +117,9 @@ switch ($mode) {
$this->ajax_die($lang['NEED_TO_LOGIN_FIRST']);
}
+ $cached_thanks = get_thanks_list($topic_id, $thanks_cache_key, $cache_lifetime);
$user_list = [];
- $sql = DB()->fetch_rowset('SELECT u.username, u.user_rank, u.user_id, t.* FROM ' . BB_THX . ' t, ' . BB_USERS . " u WHERE t.topic_id = $topic_id AND t.user_id = u.user_id");
- foreach ($sql as $row) {
+ foreach ($cached_thanks as $row) {
$user_list[] = '' . profile_url($row) . ' (' . bb_date($row['time']) . ')';
}
diff --git a/library/ajax/view_torrent.php b/library/ajax/view_torrent.php
index 942a32b11..6d342781a 100644
--- a/library/ajax/view_torrent.php
+++ b/library/ajax/view_torrent.php
@@ -11,18 +11,30 @@ if (!defined('IN_AJAX')) {
die(basename(__FILE__));
}
-global $lang;
+global $lang, $userdata;
if (!isset($this->request['attach_id'])) {
$this->ajax_die($lang['EMPTY_ATTACH_ID']);
}
$attach_id = (int)$this->request['attach_id'];
-$torrent = DB()->fetch_row("SELECT attach_id, physical_filename FROM " . BB_ATTACHMENTS_DESC . " WHERE attach_id = $attach_id LIMIT 1");
+$torrent = DB()->fetch_row("
+ SELECT
+ ad.attach_id, ad.physical_filename,
+ tor.forum_id
+ FROM " . BB_ATTACHMENTS_DESC . " ad
+ INNER JOIN " . BB_BT_TORRENTS . " tor ON (ad.attach_id = tor.attach_id)
+ WHERE ad.attach_id = $attach_id LIMIT 1");
if (!$torrent) {
$this->ajax_die($lang['ERROR_BUILD']);
}
+// Check rights
+$is_auth = auth(AUTH_ALL, $torrent['forum_id'], $userdata);
+if (!$is_auth['auth_view']) {
+ $this->ajax_die($lang['SORRY_AUTH_VIEW_ATTACH']);
+}
+
$file_contents = null;
$filename = get_attachments_dir() . '/' . $torrent['physical_filename'];
if (!is_file($filename) || !$file_contents = file_get_contents($filename)) {
@@ -37,7 +49,6 @@ try {
}
$torrent = new TorrentPier\Legacy\TorrentFileList($tor);
-
$tor_filelist = $torrent->get_filelist();
$this->response['html'] = $tor_filelist;
diff --git a/library/attach_mod/displaying_torrent.php b/library/attach_mod/displaying_torrent.php
index 06a670266..10dab59af 100644
--- a/library/attach_mod/displaying_torrent.php
+++ b/library/attach_mod/displaying_torrent.php
@@ -66,6 +66,7 @@ $tracker_status = $attachments['_' . $post_id][$i]['tracker_status'];
$download_count = declension((int)$attachments['_' . $post_id][$i]['download_count'], 'times');
$tor_file_size = humn_size($attachments['_' . $post_id][$i]['filesize']);
$tor_file_time = bb_date($attachments['_' . $post_id][$i]['filetime']);
+$real_filename = clean_filename(basename($attachments['_' . $post_id][$i]['real_filename']));
$tor_reged = (bool)$tracker_status;
$show_peers = (bool)$bb_cfg['bt_show_peers'];
@@ -88,10 +89,14 @@ if ($tor_auth_reg || $tor_auth_del) {
$tracker_link = ($tor_reged) ? $unreg_tor_url : $reg_tor_url;
}
-if ($bb_cfg['tracker']['use_old_torrent_name_format']) {
- $display_name = '[' . $bb_cfg['server_name'] . '].t' . $bt_topic_id . '.' . TORRENT_EXT;
+if ($bb_cfg['tracker']['use_real_filename']) {
+ $display_name = $real_filename;
} else {
- $display_name = $t_data['topic_title'] . ' [' . $bb_cfg['server_name'] . '-' . $bt_topic_id . ']' . '.' . TORRENT_EXT;
+ if ($bb_cfg['tracker']['use_old_torrent_name_format']) {
+ $display_name = '[' . $bb_cfg['server_name'] . '].t' . $bt_topic_id . '.' . TORRENT_EXT;
+ } else {
+ $display_name = $t_data['topic_title'] . ' [' . $bb_cfg['server_name'] . '-' . $bt_topic_id . ']' . '.' . TORRENT_EXT;
+ }
}
if (!$tor_reged) {
@@ -475,6 +480,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..bb8ea9cbe 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.11';
+$bb_cfg['tp_release_date'] = '06-08-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',
@@ -567,7 +569,7 @@ $bb_cfg['limit_max_search_results'] = false; // Limit for number of search resul
// Posting
$bb_cfg['prevent_multiposting'] = true; // TODO: replace "reply" with "edit last msg" if user (not admin or mod) is last topic poster
-$bb_cfg['max_smilies'] = 25; //Max number of smilies in a post (0 - unlimited)
+$bb_cfg['max_smilies'] = 25; // Max number of smilies in a post (0 - unlimited)
$bb_cfg['max_symbols_post'] = 5000; // TODO: Max number of symbols in a post (0 - unlimited)
// PM
@@ -591,7 +593,7 @@ $bb_cfg['user_not_active_days_keep'] = 180; // After how many days should I dele
// Vote for torrents
$bb_cfg['tor_thank'] = true;
$bb_cfg['tor_thanks_list_guests'] = true; // Show voters to guests
-$bb_cfg['tor_thank_limit_per_topic'] = 50;
+$bb_cfg['tor_thank_limit_per_topic'] = 50; // Set "0" to disable limit
// Groups
$bb_cfg['group_members_per_page'] = 50; // How many groups will be displayed in a page
@@ -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,
@@ -743,7 +747,8 @@ $bb_cfg['tracker'] = [
'hybrid_stat_protocol' => 1, // For hybrid torrents there are two identical requests sent by clients, for counting stats we gotta choose one, you can change this to '2' in future, when v1 protocol is outdated
'disabled_v1_torrents' => false, // disallow registration of v1-only torrents, for future implementations where client will use v2 only and there won't be need for v1, thus relieving tracker
'disabled_v2_torrents' => false, // disallow registration of v2-only torrents
- 'use_old_torrent_name_format' => false, // when enabled, the names of torrent files will have the classic format: [yoursite.com].txxx.torrent
+ 'use_real_filename' => false, // Use original torrent filename for downloads. If disabled, filename will be generated automatically
+ 'use_old_torrent_name_format' => false, // Use classic filename format '[yoursite.com].txxx.torrent'. Only works when use_real_filename is disabled
];
// Ratio settings
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/datastore/build_stats.php b/library/includes/datastore/build_stats.php
index e25d8e085..1b4ffbe98 100644
--- a/library/includes/datastore/build_stats.php
+++ b/library/includes/datastore/build_stats.php
@@ -17,7 +17,7 @@ $data = [];
// usercount
$row = DB()->fetch_row("SELECT COUNT(*) AS usercount FROM " . BB_USERS . " WHERE user_id NOT IN(" . EXCLUDED_USERS . ")");
-$data['usercount'] = commify($row['usercount']);
+$data['usercount'] = (int)$row['usercount'];
// newestuser
$row = DB()->fetch_row("SELECT user_id, username, user_rank FROM " . BB_USERS . " WHERE user_active = 1 AND user_id NOT IN(" . EXCLUDED_USERS . ") ORDER BY user_id DESC LIMIT 1");
@@ -25,8 +25,8 @@ $data['newestuser'] = $row;
// post/topic count
$row = DB()->fetch_row("SELECT SUM(forum_topics) AS topiccount, SUM(forum_posts) AS postcount FROM " . BB_FORUMS);
-$data['postcount'] = commify($row['postcount']);
-$data['topiccount'] = commify($row['topiccount']);
+$data['postcount'] = (int)$row['postcount'];
+$data['topiccount'] = (int)$row['topiccount'];
// Tracker stats
if ($bb_cfg['tor_stats']) {
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..5a2f24a99 100644
--- a/library/includes/page_header.php
+++ b/library/includes/page_header.php
@@ -117,13 +117,14 @@ $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),
'USE_TABLESORTER' => !empty($page_cfg['use_tablesorter']),
'ALLOW_ROBOTS' => !$bb_cfg['board_disable'] && (!isset($page_cfg['allow_robots']) || $page_cfg['allow_robots'] === true),
- 'META_DESCRIPTION' => !empty($page_cfg['meta_description']) ? trim(htmlCHR($page_cfg['meta_description'])) : '',
+ 'META_DESCRIPTION' => (!defined('HAS_DIED') && !empty($page_cfg['meta_description'])) ? trim(htmlCHR($page_cfg['meta_description'])) : '',
'SITENAME' => $bb_cfg['sitename'],
'U_INDEX' => BB_ROOT . 'index.php',
@@ -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/library/language/source/main.php b/library/language/source/main.php
index 80059d74b..ffc0e2091 100644
--- a/library/language/source/main.php
+++ b/library/language/source/main.php
@@ -2823,6 +2823,8 @@ $lang['LOG_ACTION']['LOG_TYPE'] = [
'mod_topic_change_tor_status' => 'Topic:
changed torrent status',
'mod_topic_change_tor_type' => 'Topic:
changed torrent type',
'mod_topic_tor_unregister' => 'Topic:
torrent unregistered',
+ 'mod_topic_tor_register' => 'Topic:
torrent registered',
+ 'mod_topic_tor_delete' => 'Topic:
torrent deleted',
'mod_topic_renamed' => 'Topic:
renamed',
'mod_post_delete' => 'Post:
deleted',
'mod_post_pin' => 'Post:
pinned',
diff --git a/playback_m3u.php b/playback_m3u.php
index 3bf98fbd6..6714745af 100644
--- a/playback_m3u.php
+++ b/playback_m3u.php
@@ -34,7 +34,7 @@ if (!$topic_id) {
}
// Getting torrent info from database
-$sql = 'SELECT attach_id, forum_id, info_hash, info_hash_v2
+$sql = 'SELECT attach_id, forum_id, info_hash, info_hash_v2, tor_status, poster_id
FROM ' . BB_BT_TORRENTS . '
WHERE topic_id = ' . $topic_id . '
LIMIT 1';
@@ -58,6 +58,13 @@ if (!$is_auth['auth_download']) {
bb_die($lang['SORRY_AUTH_VIEW_ATTACH']);
}
+// Check for frozen torrent
+$releaser = $userdata['user_id'] == $row['poster_id'];
+$tor_status = $row['tor_status'];
+if (!IS_AM && isset($bb_cfg['tor_frozen'][$tor_status]) && !(isset($bb_cfg['tor_frozen_author_download'][$tor_status]) && $releaser)) {
+ bb_die($lang['TOR_STATUS_FORBIDDEN'] . $lang['TOR_STATUS_NAME'][$tor_status]);
+}
+
// Parse M3U file
$m3uParser = new M3uParser\M3uParser();
$m3uParser->addDefaultTags();
diff --git a/posting.php b/posting.php
index 39d44c373..f823d5a66 100644
--- a/posting.php
+++ b/posting.php
@@ -253,7 +253,11 @@ if (!empty($bb_cfg['tor_cannot_edit']) && $post_info['allow_reg_tracker'] && $po
$robots_indexing = $post_info['topic_allow_robots'] ?? true;
if ($submit || $refresh) {
if (IS_AM) {
- $robots_indexing = !empty($_POST['robots']);
+ if ($post_info['auth_read'] == AUTH_ALL) {
+ $robots_indexing = !empty($_POST['robots']);
+ } else {
+ $robots_indexing = true;
+ }
}
$notify_user = (int)!empty($_POST['notify']);
} else {
@@ -504,7 +508,7 @@ if (!IS_GUEST) {
$topic_type_toggle = '';
if ($mode == 'newtopic' || ($mode == 'editpost' && $post_data['first_post'])) {
// Allow robots indexing
- if (IS_AM) {
+ if (IS_AM && $post_info['auth_read'] == AUTH_ALL) {
$template->assign_var('SHOW_ROBOTS_CHECKBOX');
}
@@ -625,6 +629,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/Ajax.php b/src/Ajax.php
index a2f3e6090..c123ea4fe 100644
--- a/src/Ajax.php
+++ b/src/Ajax.php
@@ -50,7 +50,7 @@ class Ajax
'index_data' => ['guest'],
];
- public string $action;
+ public ?string $action;
/**
* Constructor
diff --git a/src/Legacy/Attach.php b/src/Legacy/Attach.php
index 3123a2aa5..ae0eefedc 100644
--- a/src/Legacy/Attach.php
+++ b/src/Legacy/Attach.php
@@ -479,6 +479,8 @@ class Attach
unlink_attach($row['physical_filename'], MODE_THUMBNAIL);
}
+ // todo: log action - torrent updated
+
//bt
if ($this->attachment_extension_list[$actual_element] === TORRENT_EXT && $attachments[$actual_element]['tracker_status']) {
Torrent::tracker_unregister($attachment_id);
@@ -786,9 +788,10 @@ class Attach
}
DB()->sql_freeresult($result);
- $allowed_filesize = $row['max_filesize'] ?: $attach_config['max_filesize'];
- $cat_id = (int)$row['cat_id'];
- $auth_cache = trim($row['forum_permissions']);
+ $allowed_filesize = $row['max_filesize'] ?? $attach_config['max_filesize'];
+ $cat_id = isset($row['cat_id']) ? (int)$row['cat_id'] : 0;
+ $auth_cache = isset($row['forum_permissions']) ? trim($row['forum_permissions']) : '';
+ $row['allow_group'] = $row['allow_group'] ?? 0;
// check Filename
if (preg_match("#[\\/:*?\"<>|]#i", $this->filename)) {
diff --git a/src/Legacy/LogAction.php b/src/Legacy/LogAction.php
index b1d7b2dfb..e4af99bb7 100644
--- a/src/Legacy/LogAction.php
+++ b/src/Legacy/LogAction.php
@@ -33,6 +33,8 @@ class LogAction
'mod_topic_change_tor_status' => 15,
'mod_topic_change_tor_type' => 16,
'mod_topic_tor_unregister' => 17,
+ 'mod_topic_tor_register' => 18,
+ 'mod_topic_tor_delete' => 19,
];
public $log_type_select = [];
public $log_disabled = false;
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/Torrent.php b/src/Legacy/Torrent.php
index 791ff30bd..e1c00bb0e 100644
--- a/src/Legacy/Torrent.php
+++ b/src/Legacy/Torrent.php
@@ -97,7 +97,7 @@ class Torrent
*/
public static function tracker_unregister($attach_id, $mode = '')
{
- global $lang, $bb_cfg, $log_action;
+ global $lang, $bb_cfg;
$attach_id = (int)$attach_id;
$post_id = $topic_id = $topic_title = $forum_id = null;
@@ -153,13 +153,6 @@ class Torrent
$torrServer->removeM3U($attach_id);
}
- // Log action
- $log_action->mod('mod_topic_tor_unregister', [
- 'forum_id' => $forum_id,
- 'topic_id' => $topic_id,
- 'topic_title' => $topic_title,
- ]);
-
// Delete torrent
$sql = "DELETE FROM " . BB_BT_TORRENTS . " WHERE attach_id = $attach_id";
@@ -188,7 +181,7 @@ class Torrent
*/
public static function delete_torrent($attach_id, $mode = '')
{
- global $lang, $reg_mode, $topic_id;
+ global $lang, $reg_mode, $topic_id, $log_action;
$attach_id = (int)$attach_id;
$reg_mode = $mode;
@@ -208,6 +201,13 @@ class Torrent
self::torrent_auth_check($forum_id, $poster_id);
self::tracker_unregister($attach_id);
delete_attachment(0, $attach_id);
+
+ // Log action
+ $log_action->mod('mod_topic_tor_delete', [
+ 'forum_id' => $torrent['forum_id'],
+ 'topic_id' => $torrent['topic_id'],
+ 'topic_title' => $torrent['topic_title'],
+ ]);
}
/**
@@ -644,10 +644,15 @@ class Torrent
// Send torrent
$output = Bencode::encode($tor);
- if ($bb_cfg['tracker']['use_old_torrent_name_format']) {
- $dl_fname = '[' . $bb_cfg['server_name'] . '].t' . $topic_id . '.' . TORRENT_EXT;
+ $real_filename = clean_filename(basename($attachment['real_filename']));
+ if ($bb_cfg['tracker']['use_real_filename']) {
+ $dl_fname = $real_filename;
} else {
- $dl_fname = html_ent_decode($topic_title) . ' [' . $bb_cfg['server_name'] . '-' . $topic_id . ']' . '.' . TORRENT_EXT;
+ if ($bb_cfg['tracker']['use_old_torrent_name_format']) {
+ $dl_fname = '[' . $bb_cfg['server_name'] . '].t' . $topic_id . '.' . TORRENT_EXT;
+ } else {
+ $dl_fname = html_ent_decode($topic_title) . ' [' . $bb_cfg['server_name'] . '-' . $topic_id . ']' . '.' . TORRENT_EXT;
+ }
}
if (!empty($_COOKIE['explain'])) {
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/TorrServerAPI.php b/src/TorrServerAPI.php
index 3764c56e6..190f2343c 100644
--- a/src/TorrServerAPI.php
+++ b/src/TorrServerAPI.php
@@ -54,7 +54,7 @@ class TorrServerAPI
{
global $bb_cfg;
- $this->url = $bb_cfg['torr_server']['url'] . '/';
+ $this->url = rtrim(trim($bb_cfg['torr_server']['url']), '/') . '/';
}
/**
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..ccef53861 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/styles/templates/default/posting_attach.tpl b/styles/templates/default/posting_attach.tpl
index b9af32484..18b4799ad 100644
--- a/styles/templates/default/posting_attach.tpl
+++ b/styles/templates/default/posting_attach.tpl
@@ -1,6 +1,8 @@
+
+
{L_ADD_ATTACHMENT_TITLE} |
@@ -10,6 +12,7 @@
+
{L_ADD_ATTACHMENT_EXPLAIN}
|
@@ -26,6 +29,24 @@
+
+
diff --git a/styles/templates/default/viewtopic_attach.tpl b/styles/templates/default/viewtopic_attach.tpl
index 14c28862f..81df0305b 100644
--- a/styles/templates/default/viewtopic_attach.tpl
+++ b/styles/templates/default/viewtopic_attach.tpl
@@ -173,12 +173,14 @@
{postrow.attach.tor_reged.FILESIZE}
+

{L_PLAYBACK_M3U}
+
diff --git a/viewtopic.php b/viewtopic.php
index 82d39e685..0ed14fd11 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
";
@@ -113,9 +113,6 @@ $topic_id = $t_data['topic_id'];
$forum_id = $t_data['forum_id'];
$topic_attachment = isset($t_data['topic_attachment']) ? (int)$t_data['topic_attachment'] : null;
-// Allow robots indexing
-$page_cfg['allow_robots'] = (bool)$t_data['topic_allow_robots'];
-
if ($t_data['allow_porno_topic'] && bf($userdata['user_opt'], 'user_opt', 'user_porn_forums')) {
bb_die($lang['ERROR_PORNO_FORUM']);
}
@@ -229,6 +226,13 @@ $datastore->rm('cat_forums');
// Make jumpbox
make_jumpbox();
+// Allow robots indexing
+if ($is_auth['auth_read']) {
+ $page_cfg['allow_robots'] = (bool)$t_data['topic_allow_robots'];
+} else {
+ $page_cfg['allow_robots'] = false;
+}
+
if ($post_id && !empty($t_data['prev_posts'])) {
$start = floor(($t_data['prev_posts'] - 1) / $posts_per_page) * $posts_per_page;
}
@@ -759,7 +763,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,
]);
}