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 @@ License Stars Packagist Crowdin - TorrentPier nightly + TorrentPier nightly Downloads Version Last release Size - Deployed to TorrentPier Demo with FTP Deploy Action + Deployed with FTP Deploy Action

## πŸ‚ 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. [![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 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 @@ + + @@ -10,6 +12,7 @@
{L_ADD_ATTACHMENT_TITLE}
@@ -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}

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

{L_ADD_ATTACHMENT_EXPLAIN}