diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e92dfe326..e38c0ad2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,7 +3,7 @@ name: Continuous Integration on: push: branches: - - master + - v2.4 jobs: nightly: @@ -44,37 +44,5 @@ jobs: - name: Upload Archive ๐Ÿ“ค uses: actions/upload-artifact@v4 with: - name: TorrentPier-master + name: TorrentPier-v2.4 path: ${{ steps.create-zip.outputs.ZIP_NAME }} - - deploy: - name: ๐ŸŽ‰ Deploy - runs-on: ubuntu-22.04 - steps: - - name: ๐Ÿšš Get latest code - uses: actions/checkout@v4 - - - name: ๐Ÿ”ฉ Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.1' - - - name: Update composer.lock file - run: composer update --no-install - - - name: ๐Ÿ–‡ Install Composer dependencies - run: composer install --no-progress --prefer-dist --optimize-autoloader - - - name: ๐Ÿ“‚ Sync files - uses: SamKirkland/FTP-Deploy-Action@v4.3.5 - with: - server: ${{ secrets.FTP_SERVER }} - username: ${{ secrets.FTP_USERNAME }} - password: ${{ secrets.FTP_PASSWORD }} - server-dir: ${{ secrets.FTP_DIR }} - protocol: ${{ secrets.FTP_PROTOCOL }} - port: ${{ secrets.FTP_PORT }} - exclude: | - **/.git* - **/.git*/** - .env diff --git a/.github/workflows/phpmd.yml b/.github/workflows/phpmd.yml index 3e06d7538..0bc28da28 100644 --- a/.github/workflows/phpmd.yml +++ b/.github/workflows/phpmd.yml @@ -17,10 +17,10 @@ name: PHPMD on: push: - branches: [ "master" ] + branches: [ "v2.4" ] pull_request: # The branches below must be a subset of the branches above - branches: [ "master" ] + branches: [ "v2.4" ] schedule: - cron: '40 0 * * 3' diff --git a/.github/workflows/schedule.yml b/.github/workflows/schedule.yml index 209512552..d0ab3b5a9 100644 --- a/.github/workflows/schedule.yml +++ b/.github/workflows/schedule.yml @@ -14,7 +14,7 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - ref: master + ref: v2.4 token: ${{ secrets.REPO_TOKEN }} - name: Generate a changelog @@ -32,10 +32,10 @@ jobs: - name: Commit changelog run: | - git checkout master + git checkout v2.4 git config --local user.name 'belomaxorka' git config --local user.email 'roman25052006.kelesh@gmail.com' set +e git add CHANGELOG.md - git commit -m "Update CHANGELOG.md ๐Ÿ“–" - git push https://${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git master + git commit -m "changelog: Update CHANGELOG.md ๐Ÿ“–" + git push https://${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git v2.4 diff --git a/CHANGELOG.md b/CHANGELOG.md index 19f1dc9f6..1abfb528f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,63 @@ # ๐Ÿ“– Change Log -## [nightly](https://nightly.link/torrentpier/torrentpier/workflows/ci/master/TorrentPier-master) +## [v2.4.10](https://github.com/torrentpier/torrentpier/compare/v2.4.9..v2.4.10) (2025-07-03) + +### ๐Ÿš€ Features + +- *(lang)* Added `RTL` languages support ([#2031](https://github.com/torrentpier/torrentpier/pull/2031)) - ([9024640](https://github.com/torrentpier/torrentpier/commit/9024640d59428cc164fc6b10246ee40e333ec8e9)) +- Restore some deprecated code for backward compatibility ([#2028](https://github.com/torrentpier/torrentpier/pull/2028)) - ([695864e](https://github.com/torrentpier/torrentpier/commit/695864ef6995a3c7b16ade822036c23908fc3aaf)) + +### โ—€๏ธ Revert + +- "refactor: Moved `Select` class into `Legacy\Common` ([#1846](https://github.com/torrentpier/torrentpier/pull/1846))" - ([e697672](https://github.com/torrentpier/torrentpier/commit/e6976721dc2f6cde6a09b6a55e2f37e5f43f5932)) + + +## [v2.4.9](https://github.com/torrentpier/torrentpier/compare/v2.4.8..v2.4.9) (2025-07-02) + +### ๐Ÿš€ Features + +- *(updater)* Added exceptions logging ([#2026](https://github.com/torrentpier/torrentpier/pull/2026)) - ([57d0d59](https://github.com/torrentpier/torrentpier/commit/57d0d59b5379600f63cf7d5f774e3ec000e39473)) + +### ๐Ÿšœ Refactor + +- *(TorrentFileList)* Reduce duplication in root directory unset logic ([#2027](https://github.com/torrentpier/torrentpier/pull/2027)) - ([6840376](https://github.com/torrentpier/torrentpier/commit/68403760c1e9e01133536bb5021b08d9101d323e)) + + +## [v2.4.8](https://github.com/torrentpier/torrentpier/compare/v2.4.7..v2.4.8) (2025-06-30) + +### ๐Ÿ› Bug Fixes + +- *(TorrentFileList)* Avoid `array_merge` reindexing for numeric folder names ([#2014](https://github.com/torrentpier/torrentpier/pull/2014)) - ([a5fbc2f](https://github.com/torrentpier/torrentpier/commit/a5fbc2ffc7389c30ffbb98d253ff8e936528fec1)) +- *(redirect)* Add no-cache headers to prevent browser caching of redirects ([#2010](https://github.com/torrentpier/torrentpier/pull/2010)) - ([134b3df](https://github.com/torrentpier/torrentpier/commit/134b3dfa5cd8e8e5ce3f10912b58afecc4f118e0)) + +### ๐Ÿšœ Refactor + +- Use `DEFAULT_CHARSET` constant instead of hardcoded string ([#2011](https://github.com/torrentpier/torrentpier/pull/2011)) - ([c2cbc77](https://github.com/torrentpier/torrentpier/commit/c2cbc77b144057d3d37cd58b635eabc6280fe137)) + + +## [v2.4.7](https://github.com/torrentpier/torrentpier/compare/v2.4.6..v2.4.7) (2025-06-24) + +### ๐Ÿ› Bug Fixes + +- *(filelist)* `Undefined property: FileTree::$length` when v2 torrent only ([#2004](https://github.com/torrentpier/torrentpier/pull/2004)) - ([8c161ce](https://github.com/torrentpier/torrentpier/commit/8c161ceae0f80a3ffe57da06dbadd1f9a53272f3)) +- *(ip-api)* Add error handling and logging for freeipapi.com requests ([#2006](https://github.com/torrentpier/torrentpier/pull/2006)) - ([12ce6e7](https://github.com/torrentpier/torrentpier/commit/12ce6e783ec97a6c3df0e11273944a3e6cfe466d)) + +### ๐Ÿ“š Documentation + +- Changed nightly.link url in `README.md` ([#1977](https://github.com/torrentpier/torrentpier/pull/1977)) - ([dc64426](https://github.com/torrentpier/torrentpier/commit/dc64426574087e69bc7e056a89ff367438e37344)) +- Updated `Requirements` sections in README.md ([#1975](https://github.com/torrentpier/torrentpier/pull/1975)) - ([b7bc7f9](https://github.com/torrentpier/torrentpier/commit/b7bc7f91662b050082843d18b03376dc67efa3e0)) +- Fixed some typos in `README.md` ([#1974](https://github.com/torrentpier/torrentpier/pull/1974)) - ([403fcf2](https://github.com/torrentpier/torrentpier/commit/403fcf2aca4b2d70bfca194107f4b4f5c5ba7f03)) + + +## [v2.4.6](https://github.com/torrentpier/torrentpier/compare/v2.4.6-alpha.4..v2.4.6) (2025-06-19) + +### ๐Ÿ› Bug Fixes + +- *(installer)* Strip protocol from TP_HOST to keep only hostname ([#1969](https://github.com/torrentpier/torrentpier/pull/1969)) - ([15f9948](https://github.com/torrentpier/torrentpier/commit/15f994840331b135cd64c0cd61de95fecfc29db8)) +- *(sql)* Resolve `only_full_group_by` compatibility issues in tracker cleanup - ([faf3d79](https://github.com/torrentpier/torrentpier/commit/faf3d7919249d869d8ca8d41617dd4356dc0ac48)) +- Duplicate column SQL query issues in `viewtopic.php` ([#1973](https://github.com/torrentpier/torrentpier/pull/1973)) - ([6a1d682](https://github.com/torrentpier/torrentpier/commit/6a1d6823856dd7c3cef45bea2681828526d1b9f8)) +- SQL queries in online_userlist.php to use MAX() for session data and adjusted GROUP BY clause for better accuracy ([#1971](https://github.com/torrentpier/torrentpier/pull/1971)) - ([2a8b6da](https://github.com/torrentpier/torrentpier/commit/2a8b6daecf63752b8a852c950e9a7fd08e17f57c)) ### ๐Ÿ“ฆ Dependencies @@ -11,7 +67,14 @@ ### โš™๏ธ Miscellaneous - *(_release.php)* Finally! Removed some useless params ([#1947](https://github.com/torrentpier/torrentpier/pull/1947)) - ([9c7d270](https://github.com/torrentpier/torrentpier/commit/9c7d270598c0153fb82f4b7ad96f5b59399b2159)) +- *(cliff)* Add conventional commit prefix to changelog message ([#1970](https://github.com/torrentpier/torrentpier/pull/1970)) - ([7d9594e](https://github.com/torrentpier/torrentpier/commit/7d9594eedab1b2c81d888dfba68ded1b8a142282)) +- Changed active branch name in `_release.php` ([#1972](https://github.com/torrentpier/torrentpier/pull/1972)) - ([7dc69ba](https://github.com/torrentpier/torrentpier/commit/7dc69ba699c75d87c709a799291c4b544b3e92aa)) +- Changed branch name from `master` to `v2.4` ([#1968](https://github.com/torrentpier/torrentpier/pull/1968)) - ([a8e252f](https://github.com/torrentpier/torrentpier/commit/a8e252f64f7205b7bb24739ab637144c6fb022d6)) +## New Contributors โค๏ธ + +* @belomaxorka made their first contribution +* @dependabot[bot] made their first contribution in [#1948](https://github.com/torrentpier/torrentpier/pull/1948) ## [v2.4.6-alpha.4](https://github.com/torrentpier/torrentpier/compare/v2.4.6-alpha.3..v2.4.6-alpha.4) (2025-06-13) diff --git a/README.md b/README.md index 8397b363b..3a699f78a 100644 --- a/README.md +++ b/README.md @@ -9,25 +9,25 @@ 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_user_search.php b/admin/admin_user_search.php index f89f3f669..4a29d0e06 100644 --- a/admin/admin_user_search.php +++ b/admin/admin_user_search.php @@ -52,8 +52,8 @@ if (!isset($_REQUEST['dosearch'])) { } } - $language_list = \TorrentPier\Legacy\Common\Select::language('', 'language_type'); - $timezone_list = \TorrentPier\Legacy\Common\Select::timezone('', 'timezone_type'); + $language_list = \TorrentPier\Legacy\Select::language('', 'language_type'); + $timezone_list = \TorrentPier\Legacy\Select::timezone('', 'timezone_type'); $sql = 'SELECT f.forum_id, f.forum_name, f.forum_parent, c.cat_id, c.cat_title FROM ( ' . BB_FORUMS . ' AS f INNER JOIN ' . BB_CATEGORIES . ' AS c ON c.cat_id = f.cat_id ) diff --git a/admin/index.php b/admin/index.php index ea3d0a2aa..1b42b53fa 100644 --- a/admin/index.php +++ b/admin/index.php @@ -90,7 +90,7 @@ if (isset($_GET['pane']) && $_GET['pane'] == 'left') { 'NEW_VERSION_SIZE' => $update_data['latest_version_size'], 'NEW_VERSION_DL_LINK' => $update_data['latest_version_dl_link'], 'NEW_VERSION_LINK' => $update_data['latest_version_link'], - 'NEW_VERSION_MD5' => $update_data['latest_version_checksum'] + 'NEW_VERSION_HASH' => $update_data['latest_version_checksum'] ]); } diff --git a/bt/announce.php b/bt/announce.php index 91d9d1e23..245b7c0dd 100644 --- a/bt/announce.php +++ b/bt/announce.php @@ -117,7 +117,7 @@ $stopped = ($event === 'stopped'); // Check info_hash length if (strlen($info_hash) !== 20) { - msg_die('Invalid info_hash: ' . (mb_check_encoding($info_hash, 'UTF8') ? $info_hash : $info_hash_hex)); + msg_die('Invalid info_hash: ' . (mb_check_encoding($info_hash, DEFAULT_CHARSET) ? $info_hash : $info_hash_hex)); } /** @@ -259,7 +259,7 @@ if ($lp_info) { // Verify if torrent registered on tracker and user authorized if (empty($row['topic_id'])) { - msg_die('Torrent not registered, info_hash = ' . (mb_check_encoding($info_hash, 'UTF8') ? $info_hash : $info_hash_hex)); + msg_die('Torrent not registered, info_hash = ' . (mb_check_encoding($info_hash, DEFAULT_CHARSET) ? $info_hash : $info_hash_hex)); } if (empty($row['user_id'])) { msg_die('Please LOG IN and RE-DOWNLOAD this torrent (user not found)'); diff --git a/bt/scrape.php b/bt/scrape.php index 534cd57fd..e2c2676ec 100644 --- a/bt/scrape.php +++ b/bt/scrape.php @@ -34,7 +34,7 @@ $info_hash_hex = bin2hex($info_hash); // Check info_hash length if (strlen($info_hash) !== 20) { - msg_die('Invalid info_hash: ' . (mb_check_encoding($info_hash, 'UTF8') ? $info_hash : $info_hash_hex)); + msg_die('Invalid info_hash: ' . (mb_check_encoding($info_hash, DEFAULT_CHARSET) ? $info_hash : $info_hash_hex)); } // Handle multiple hashes @@ -99,7 +99,7 @@ if (!empty($info_hash_count)) { // Verify if torrent registered on tracker if (empty($torrents)) { - msg_die('Torrent not registered, info_hash = ' . (mb_check_encoding($info_hash, 'UTF8') ? $info_hash : $info_hash_hex)); + msg_die('Torrent not registered, info_hash = ' . (mb_check_encoding($info_hash, DEFAULT_CHARSET) ? $info_hash : $info_hash_hex)); } die(\Arokettu\Bencode\Bencode::encode($torrents)); diff --git a/cliff.toml b/cliff.toml index 1753dd8a4..858d0a4db 100644 --- a/cliff.toml +++ b/cliff.toml @@ -23,7 +23,7 @@ body = """ {%- endmacro -%} {%- macro nightly_url() -%} - https://nightly.link/{{ remote.github.owner }}/{{ remote.github.repo }}/workflows/ci/master/TorrentPier-master + https://nightly.link/{{ remote.github.owner }}/{{ remote.github.repo }}/workflows/ci/v2.4/TorrentPier-v2.4 {%- endmacro -%} {% macro print_commit(commit) -%} @@ -105,7 +105,7 @@ commit_parsers = [ { message = "^refactor", group = "๐Ÿšœ Refactor" }, { message = "^style", group = "๐ŸŽจ Styling" }, { message = "^test", group = "๐Ÿงช Testing" }, - { message = "^ignore|^release", skip = true }, + { message = "^ignore|^release|^changelog", skip = true }, { message = "^chore|^ci|^misc", group = "โš™๏ธ Miscellaneous" }, { body = ".*security", group = "๐Ÿ›ก๏ธ Security" }, { message = "^revert", group = "โ—€๏ธ Revert" }, diff --git a/composer.lock b/composer.lock index a3fa490ba..9bf9af62c 100644 --- a/composer.lock +++ b/composer.lock @@ -286,16 +286,16 @@ }, { "name": "arokettu/torrent-file", - "version": "5.3.1", + "version": "5.3.2", "source": { "type": "git", "url": "https://github.com/arokettu/torrent-file.git", - "reference": "650ed7109bcd01dd6c4f47d129f120eb1f82ca07" + "reference": "0fba9ed15b8f60beb33a590a36db9b97d28ce171" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/arokettu/torrent-file/zipball/650ed7109bcd01dd6c4f47d129f120eb1f82ca07", - "reference": "650ed7109bcd01dd6c4f47d129f120eb1f82ca07", + "url": "https://api.github.com/repos/arokettu/torrent-file/zipball/0fba9ed15b8f60beb33a590a36db9b97d28ce171", + "reference": "0fba9ed15b8f60beb33a590a36db9b97d28ce171", "shasum": "" }, "require": { @@ -313,9 +313,9 @@ "league/event": "^3.0", "phpunit/phpunit": "^10.5.3", "psy/psysh": "*", - "sandfox.dev/code-standard": "^1.2024.07.05", + "sandfox.dev/code-standard": "^1.2025.05.07", "squizlabs/php_codesniffer": "*", - "vimeo/psalm": "^5.2" + "vimeo/psalm": "^5.2 | ^6" }, "suggest": { "ext-openssl": "for signature logic" @@ -351,7 +351,7 @@ "issues": "https://gitlab.com/sandfox/torrent-file/-/issues", "source": "https://gitlab.com/sandfox/torrent-file" }, - "time": "2024-07-28T21:43:34+00:00" + "time": "2025-06-28T21:41:10+00:00" }, { "name": "arokettu/unsigned", @@ -995,16 +995,16 @@ }, { "name": "google/recaptcha", - "version": "1.3.0", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/google/recaptcha.git", - "reference": "d59a801e98a4e9174814a6d71bbc268dff1202df" + "reference": "56522c261d2e8c58ba416c90f81a4cd9f2ed89b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/google/recaptcha/zipball/d59a801e98a4e9174814a6d71bbc268dff1202df", - "reference": "d59a801e98a4e9174814a6d71bbc268dff1202df", + "url": "https://api.github.com/repos/google/recaptcha/zipball/56522c261d2e8c58ba416c90f81a4cd9f2ed89b9", + "reference": "56522c261d2e8c58ba416c90f81a4cd9f2ed89b9", "shasum": "" }, "require": { @@ -1043,7 +1043,7 @@ "issues": "https://github.com/google/recaptcha/issues", "source": "https://github.com/google/recaptcha" }, - "time": "2023-02-18T17:41:46+00:00" + "time": "2025-06-26T22:21:57+00:00" }, { "name": "graham-campbell/result-type", @@ -1620,16 +1620,16 @@ }, { "name": "league/flysystem", - "version": "3.29.1", + "version": "3.30.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "edc1bb7c86fab0776c3287dbd19b5fa278347319" + "reference": "2203e3151755d874bb2943649dae1eb8533ac93e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/edc1bb7c86fab0776c3287dbd19b5fa278347319", - "reference": "edc1bb7c86fab0776c3287dbd19b5fa278347319", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/2203e3151755d874bb2943649dae1eb8533ac93e", + "reference": "2203e3151755d874bb2943649dae1eb8533ac93e", "shasum": "" }, "require": { @@ -1653,13 +1653,13 @@ "composer/semver": "^3.0", "ext-fileinfo": "*", "ext-ftp": "*", - "ext-mongodb": "^1.3", + "ext-mongodb": "^1.3|^2", "ext-zip": "*", "friendsofphp/php-cs-fixer": "^3.5", "google/cloud-storage": "^1.23", "guzzlehttp/psr7": "^2.6", "microsoft/azure-storage-blob": "^1.1", - "mongodb/mongodb": "^1.2", + "mongodb/mongodb": "^1.2|^2", "phpseclib/phpseclib": "^3.0.36", "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^9.5.11|^10.0", @@ -1697,22 +1697,22 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.29.1" + "source": "https://github.com/thephpleague/flysystem/tree/3.30.0" }, - "time": "2024-10-08T08:58:34+00:00" + "time": "2025-06-25T13:29:59+00:00" }, { "name": "league/flysystem-local", - "version": "3.29.0", + "version": "3.30.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-local.git", - "reference": "e0e8d52ce4b2ed154148453d321e97c8e931bd27" + "reference": "6691915f77c7fb69adfb87dcd550052dc184ee10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/e0e8d52ce4b2ed154148453d321e97c8e931bd27", - "reference": "e0e8d52ce4b2ed154148453d321e97c8e931bd27", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/6691915f77c7fb69adfb87dcd550052dc184ee10", + "reference": "6691915f77c7fb69adfb87dcd550052dc184ee10", "shasum": "" }, "require": { @@ -1746,9 +1746,9 @@ "local" ], "support": { - "source": "https://github.com/thephpleague/flysystem-local/tree/3.29.0" + "source": "https://github.com/thephpleague/flysystem-local/tree/3.30.0" }, - "time": "2024-08-09T21:24:39+00:00" + "time": "2025-05-21T10:34:19+00:00" }, { "name": "league/mime-type-detection", @@ -3146,16 +3146,16 @@ }, { "name": "symfony/mailer", - "version": "v6.4.21", + "version": "v6.4.23", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "ada2809ccd4ec27aba9fc344e3efdaec624c6438" + "reference": "a480322ddf8e54de262c9bca31fdcbe26b553de5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/ada2809ccd4ec27aba9fc344e3efdaec624c6438", - "reference": "ada2809ccd4ec27aba9fc344e3efdaec624c6438", + "url": "https://api.github.com/repos/symfony/mailer/zipball/a480322ddf8e54de262c9bca31fdcbe26b553de5", + "reference": "a480322ddf8e54de262c9bca31fdcbe26b553de5", "shasum": "" }, "require": { @@ -3206,7 +3206,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v6.4.21" + "source": "https://github.com/symfony/mailer/tree/v6.4.23" }, "funding": [ { @@ -3222,7 +3222,7 @@ "type": "tidelift" } ], - "time": "2025-04-26T23:47:35+00:00" + "time": "2025-06-26T21:24:02+00:00" }, { "name": "symfony/mime", @@ -3651,16 +3651,16 @@ "packages-dev": [ { "name": "symfony/var-dumper", - "version": "v6.4.21", + "version": "v6.4.23", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "22560f80c0c5cd58cc0bcaf73455ffd81eb380d5" + "reference": "d55b1834cdbfcc31bc2cd7e095ba5ed9a88f6600" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/22560f80c0c5cd58cc0bcaf73455ffd81eb380d5", - "reference": "22560f80c0c5cd58cc0bcaf73455ffd81eb380d5", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/d55b1834cdbfcc31bc2cd7e095ba5ed9a88f6600", + "reference": "d55b1834cdbfcc31bc2cd7e095ba5ed9a88f6600", "shasum": "" }, "require": { @@ -3716,7 +3716,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.21" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.23" }, "funding": [ { @@ -3732,7 +3732,7 @@ "type": "tidelift" } ], - "time": "2025-04-09T07:34:50+00:00" + "time": "2025-06-27T15:05:27+00:00" } ], "aliases": [], @@ -3746,6 +3746,6 @@ "platform": { "php": ">=8.1" }, - "platform-dev": [], - "plugin-api-version": "2.3.0" + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/filelist.php b/filelist.php index 8e256dc67..2cfd9d418 100644 --- a/filelist.php +++ b/filelist.php @@ -82,7 +82,7 @@ if (IS_GUEST && $torrent->isPrivate()) { // Get torrent files $files = $torrent->$t_version_field()->$t_files_field(); -if ($meta_v1 && $meta_v2) { +if ($meta_v2) { $files = new \RecursiveIteratorIterator($files); // Flatten the list } @@ -102,19 +102,6 @@ foreach ($files as $file) { $torrent_name = !empty($t_name = $torrent->getName()) ? str_short(htmlCHR($t_name), 200) : $lang['UNKNOWN']; $torrent_size = humn_size($row['size'], 2); -// Get announcers list -$announcers_list = $torrent->getAnnounceList()->toArray(); -$announcers_count = 0; -foreach ($announcers_list as $announcer) { - $announcers_count++; - $row_class = ($announcers_count % 2) ? 'row1' : 'row2'; - $template->assign_block_vars('announcers', [ - 'ROW_NUMBER' => $announcers_count, - 'ROW_CLASS' => $row_class, - 'ANNOUNCER' => $announcer[0] - ]); -} - // Output page $template->assign_vars([ 'PAGE_TITLE' => "$torrent_name (" . $torrent_size . ")", diff --git a/install.php b/install.php index 009098420..327c0fb5d 100644 --- a/install.php +++ b/install.php @@ -206,6 +206,12 @@ if (is_file(BB_ROOT . '.env')) { $newValue = trim(readline()); if (!empty($newValue) || $key === 'DB_PASSWORD') { + if ($key === 'TP_HOST') { + if (!preg_match('/^https?:\/\//', $newValue)) { + $newValue = 'https://' . $newValue; + } + $newValue = parse_url($newValue, PHP_URL_HOST); + } $line = "$key=$newValue"; $$key = $newValue; } else { diff --git a/library/attach_mod/displaying_torrent.php b/library/attach_mod/displaying_torrent.php index 06a670266..ce6bf669a 100644 --- a/library/attach_mod/displaying_torrent.php +++ b/library/attach_mod/displaying_torrent.php @@ -475,6 +475,8 @@ if ($tor_reged && $tor_info) { if ($infoByIP = infoByIP((!empty($peer['ipv6']) ? $peer['ipv6'] : $peer['ip']), $peer['port'])) { if (!empty($infoByIP['countryCode'])) { $peerCountry = render_flag($infoByIP['countryCode'], false); + } else { + $peerCountry = $lang['NOT_AVAILABLE']; } } } diff --git a/library/config.php b/library/config.php index 866c8ed75..847562369 100644 --- a/library/config.php +++ b/library/config.php @@ -18,8 +18,8 @@ $reserved_port = env('TP_PORT', 80); $bb_cfg = []; // Version info -$bb_cfg['tp_version'] = 'v2.4.6-alpha.4'; -$bb_cfg['tp_release_date'] = '13-06-2025'; +$bb_cfg['tp_version'] = 'v2.4.10'; +$bb_cfg['tp_release_date'] = '03-07-2025'; $bb_cfg['tp_release_codename'] = 'Cattle'; // Increase version number after changing JS or CSS @@ -209,6 +209,7 @@ $bb_cfg['lang'] = [ 'ar' => [ 'name' => 'Arabic', 'locale' => 'ar_SA.UTF-8', + 'rtl' => true, ], 'hy' => [ 'name' => 'Armenian', @@ -285,6 +286,7 @@ $bb_cfg['lang'] = [ 'he' => [ 'name' => 'Hebrew', 'locale' => 'he_IL.UTF-8', + 'rtl' => true, ], 'hi' => [ 'name' => 'Hindi', @@ -724,6 +726,8 @@ $bb_cfg['tracker'] = [ 'update_dlstat' => true, 'expire_factor' => 2.5, 'compact_mode' => true, + 'upd_user_up_down_stat' => true, // unused + 'browser_redirect_url' => '', // unused 'scrape' => true, 'limit_active_tor' => true, 'limit_seed_count' => 0, diff --git a/library/defines.php b/library/defines.php index df8813a64..0f50090d7 100644 --- a/library/defines.php +++ b/library/defines.php @@ -15,11 +15,13 @@ if (!defined('BB_ROOT')) { define('ADMIN_DIR', BB_PATH . '/admin'); define('DATA_DIR', BB_PATH . '/data'); define('INT_DATA_DIR', BB_PATH . '/internal_data'); +define('AJAX_HTML_DIR', BB_ROOT . '/internal_data/ajax_html/'); define('CACHE_DIR', BB_PATH . '/internal_data/cache'); define('LOG_DIR', BB_PATH . '/internal_data/log'); define('TRIGGERS_DIR', BB_PATH . '/internal_data/triggers'); define('AJAX_DIR', BB_PATH . '/library/ajax'); define('ATTACH_DIR', BB_PATH . '/library/attach_mod'); +define('CFG_DIR', BB_PATH . '/library/config'); define('INC_DIR', BB_PATH . '/library/includes'); define('UCP_DIR', BB_PATH . '/library/includes/ucp'); define('LANG_ROOT_DIR', BB_PATH . '/library/language'); diff --git a/library/includes/cron/jobs/attach_maintenance.php b/library/includes/cron/jobs/attach_maintenance.php index 99e9a7168..d778cb38c 100644 --- a/library/includes/cron/jobs/attach_maintenance.php +++ b/library/includes/cron/jobs/attach_maintenance.php @@ -26,9 +26,9 @@ $posts_without_attach = $topics_without_attach = []; DB()->query(" CREATE TEMPORARY TABLE $tmp_attach_tbl ( - physical_filename VARCHAR(255) NOT NULL default '', + physical_filename VARCHAR(255) NOT NULL default '' COLLATE utf8mb4_unicode_ci, KEY physical_filename (physical_filename(20)) - ) ENGINE = MyISAM DEFAULT CHARSET = utf8 + ) ENGINE = MyISAM DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci "); DB()->add_shutdown_query("DROP TEMPORARY TABLE IF EXISTS $tmp_attach_tbl"); diff --git a/library/includes/cron/jobs/tr_cleanup_and_dlstat.php b/library/includes/cron/jobs/tr_cleanup_and_dlstat.php index a0d7efd25..a0a64251f 100644 --- a/library/includes/cron/jobs/tr_cleanup_and_dlstat.php +++ b/library/includes/cron/jobs/tr_cleanup_and_dlstat.php @@ -39,7 +39,7 @@ if ($bb_cfg['tracker']['update_dlstat']) { INSERT INTO " . NEW_BB_BT_LAST_TORSTAT . " (topic_id, user_id, dl_status, up_add, down_add, release_add, speed_up, speed_down) SELECT - topic_id, user_id, IF(releaser, $releaser, seeder), SUM(up_add), SUM(down_add), IF(releaser, SUM(up_add), 0), SUM(speed_up), SUM(speed_down) + topic_id, user_id, IF(MAX(releaser), $releaser, MAX(seeder)), SUM(up_add), SUM(down_add), IF(MAX(releaser), SUM(up_add), 0), SUM(speed_up), SUM(speed_down) FROM " . BB_BT_TRACKER . " WHERE (up_add != 0 OR down_add != 0) GROUP BY topic_id, user_id @@ -61,7 +61,6 @@ DB()->query(" FROM " . BB_BT_TRACKER . " WHERE seeder = 1 GROUP BY topic_id, user_id - ORDER BY update_time DESC "); // Clean peers table diff --git a/library/includes/datastore/build_check_updates.php b/library/includes/datastore/build_check_updates.php index a990d4364..aae8ededd 100644 --- a/library/includes/datastore/build_check_updates.php +++ b/library/includes/datastore/build_check_updates.php @@ -18,9 +18,16 @@ if (!$bb_cfg['tp_updater_settings']['enabled']) { } $data = []; +$data[] = ['latest_check_timestamp' => TIMENOW]; -$updaterDownloader = new \TorrentPier\Updater(); -$updaterDownloader = $updaterDownloader->getLastVersion($bb_cfg['tp_updater_settings']['allow_pre_releases']); +try { + $updaterDownloader = new \TorrentPier\Updater(); + $updaterDownloader = $updaterDownloader->getLastVersion($bb_cfg['tp_updater_settings']['allow_pre_releases']); +} catch (Exception $exception) { + bb_log('[Updater] Exception: ' . $exception->getMessage() . LOG_LF); + $this->store('check_updates', $data); + return; +} $getVersion = \TorrentPier\Helpers\VersionHelper::removerPrefix($updaterDownloader['tag_name']); $currentVersion = \TorrentPier\Helpers\VersionHelper::removerPrefix($bb_cfg['tp_version']); @@ -28,6 +35,7 @@ $currentVersion = \TorrentPier\Helpers\VersionHelper::removerPrefix($bb_cfg['tp_ // Has update! if (\z4kn4fein\SemVer\Version::greaterThan($getVersion, $currentVersion)) { $latestBuildFileLink = $updaterDownloader['assets'][0]['browser_download_url']; + $SHAFileHash = $updaterDownloader['assets'][0]['digest'] ?? ''; // Check updater file $updaterFile = readUpdaterFile(); @@ -41,10 +49,12 @@ if (\z4kn4fein\SemVer\Version::greaterThan($getVersion, $currentVersion)) { ]), UPDATER_FILE, replace_content: true); } - // Get MD5 checksum + // Get MD5 / sha256 checksum $buildFileChecksum = ''; - if (isset($latestBuildFileLink)) { - $buildFileChecksum = strtoupper(md5_file($latestBuildFileLink)); + if (!empty($SHAFileHash)) { + $buildFileChecksum = $SHAFileHash; + } else { + $buildFileChecksum = 'MD5: ' . strtoupper(md5_file($latestBuildFileLink)); } // Build data array @@ -58,5 +68,4 @@ if (\z4kn4fein\SemVer\Version::greaterThan($getVersion, $currentVersion)) { ]; } -$data[] = ['latest_check_timestamp' => TIMENOW]; $this->store('check_updates', $data); diff --git a/library/includes/functions.php b/library/includes/functions.php index 67256eb1f..38db141cd 100644 --- a/library/includes/functions.php +++ b/library/includes/functions.php @@ -800,6 +800,11 @@ function str_short($text, $max_length, $space = ' ') return $text ?? ''; } +function wbr($text, $max_word_length = HTML_WBR_LENGTH) +{ + return preg_replace("/([\w\->;:.,~!?(){}@#$%^*\/\\\\]{" . $max_word_length . "})/ui", '$1', $text); +} + function generate_user_info($row, bool $have_auth = IS_ADMIN): array { global $userdata, $lang, $images, $bb_cfg; @@ -940,6 +945,47 @@ function bb_update_config($params, $table = BB_CONFIG) bb_get_config($table, true, true); } +function get_db_stat($mode) +{ + switch ($mode) { + case 'usercount': + $sql = "SELECT COUNT(user_id) AS total FROM " . BB_USERS; + break; + + case 'newestuser': + $sql = "SELECT user_id, username FROM " . BB_USERS . " WHERE user_id <> " . GUEST_UID . " ORDER BY user_id DESC LIMIT 1"; + break; + + case 'postcount': + case 'topiccount': + $sql = "SELECT SUM(forum_topics) AS topic_total, SUM(forum_posts) AS post_total FROM " . BB_FORUMS; + break; + } + + if (!($result = DB()->sql_query($sql))) { + return false; + } + + $row = DB()->sql_fetchrow($result); + + switch ($mode) { + case 'usercount': + return $row['total']; + break; + case 'newestuser': + return $row; + break; + case 'postcount': + return $row['post_total']; + break; + case 'topiccount': + return $row['topic_total']; + break; + } + + return false; +} + function clean_username($username) { $username = mb_substr(htmlspecialchars(str_replace("\'", "'", trim($username))), 0, 25, DEFAULT_CHARSET); @@ -949,6 +995,28 @@ function clean_username($username) return $username; } +function bb_ltrim($str, $charlist = false) +{ + if ($charlist === false) { + return ltrim($str); + } + + $str = ltrim($str, $charlist); + + return $str; +} + +function bb_rtrim($str, $charlist = false) +{ + if ($charlist === false) { + return rtrim($str); + } + + $str = rtrim($str, $charlist); + + return $str; +} + /** * Get Userdata * @@ -1094,6 +1162,7 @@ function setup_style() $css_dir = 'styles/' . basename(TEMPLATES_DIR) . '/' . $tpl_dir_name . '/css/'; $template->assign_vars([ + 'BB_ROOT' => BB_ROOT, 'SPACER' => make_url('styles/images/spacer.gif'), 'STYLESHEET' => make_url($css_dir . $stylesheet), 'EXT_LINK_NEW_WIN' => $bb_cfg['ext_link_new_win'], @@ -1412,6 +1481,11 @@ function bb_simple_die($txt, $status_code = null) die($txt); } +function bb_realpath($path) +{ + return realpath($path); +} + function login_redirect($url = '') { redirect(LOGIN_URL . '?redirect=' . (($url) ?: ($_SERVER['REQUEST_URI'] ?? '/'))); @@ -1450,6 +1524,9 @@ function redirect($url) $redirect_url = $server_protocol . $server_name . $server_port . $script_name . preg_replace('#^\/?(.*?)\/?$#', '/\1', $url); + // Send no-cache headers to prevent browsers from caching redirects + send_no_cache_headers(); + // Behave as per HTTP/1.1 spec for others header('Location: ' . $redirect_url, response_code: 301); exit; @@ -2210,19 +2287,26 @@ function infoByIP(string $ipAddress, int $port = 0): array } $context = stream_context_create($contextOptions); - $response = file_get_contents($bb_cfg['ip2country_settings']['endpoint'] . $ipAddress, context: $context); - if ($response !== false) { - $json = json_decode($response, true); + try { + $response = file_get_contents($bb_cfg['ip2country_settings']['endpoint'] . $ipAddress, context: $context); - if (is_array($json) && !empty($json)) { - $data = [ - 'ipVersion' => $json['ipVersion'], - 'countryCode' => $json['countryCode'], - 'continent' => $json['continent'], - 'continentCode' => $json['continentCode'] - ]; + if ($response !== false) { + $json = json_decode($response, true); + + if (is_array($json) && !empty($json)) { + $data = [ + 'ipVersion' => $json['ipVersion'], + 'countryCode' => $json['countryCode'], + 'continent' => $json['continent'], + 'continentCode' => $json['continentCode'] + ]; + } + } else { + bb_log("[FreeIPAPI] Failed to get IP info for: $ipAddress" . LOG_LF); } + } catch (Exception $e) { + bb_log("[FreeIPAPI] " . $e->getMessage() . LOG_LF); } if (empty($data)) { diff --git a/library/includes/init_bb.php b/library/includes/init_bb.php index 932dba5a1..1cb8a6c6f 100644 --- a/library/includes/init_bb.php +++ b/library/includes/init_bb.php @@ -293,6 +293,7 @@ define('USER_AGENT', strtolower($_SERVER['HTTP_USER_AGENT'])); define('HTML_SELECT_MAX_LENGTH', 60); define('HTML_SF_SPACER', ' |- '); +define('HTML_WBR_LENGTH', 12); define('HTML_CHECKED', ' checked '); define('HTML_DISABLED', ' disabled '); diff --git a/library/includes/online_userlist.php b/library/includes/online_userlist.php index ffa0cd2e4..7434f79ea 100644 --- a/library/includes/online_userlist.php +++ b/library/includes/online_userlist.php @@ -36,11 +36,11 @@ $online = $online_short = ['userlist' => '']; $sql = " SELECT u.username, u.user_id, u.user_opt, u.user_rank, u.user_level, - s.session_logged_in, s.session_ip, (s.session_time - s.session_start) AS ses_len, COUNT(s.session_id) AS sessions, COUNT(DISTINCT s.session_ip) AS ips + MAX(s.session_logged_in) AS session_logged_in, MAX(s.session_ip) AS session_ip, MAX(s.session_time - s.session_start) AS ses_len, COUNT(s.session_id) AS sessions, COUNT(DISTINCT s.session_ip) AS ips FROM " . BB_SESSIONS . " s, " . BB_USERS . " u WHERE s.session_time > $time_online AND u.user_id = s.session_user_id - GROUP BY s.session_user_id + GROUP BY s.session_user_id, u.username, u.user_id, u.user_opt, u.user_rank, u.user_level ORDER BY u.username "; diff --git a/library/includes/page_header.php b/library/includes/page_header.php index 195bcec10..0c72d56d2 100644 --- a/library/includes/page_header.php +++ b/library/includes/page_header.php @@ -117,6 +117,7 @@ $template->assign_vars([ 'USER_HIDE_CAT' => (BB_SCRIPT == 'index'), 'USER_LANG' => $userdata['user_lang'], + 'USER_LANG_DIRECTION' => (isset($bb_cfg['lang'][$userdata['user_lang']]['rtl']) && $bb_cfg['lang'][$userdata['user_lang']]['rtl'] === true) ? 'rtl' : 'ltr', 'INCLUDE_BBCODE_JS' => !empty($page_cfg['include_bbcode_js']), 'USER_OPTIONS_JS' => IS_GUEST ? '{}' : json_encode($user->opt_js, JSON_THROW_ON_ERROR), @@ -194,8 +195,14 @@ $template->assign_vars([ 'BONUS_URL' => BB_ROOT . BONUS_URL, 'TOPIC_URL' => BB_ROOT . TOPIC_URL, + 'AJAX_HTML_DIR' => AJAX_HTML_DIR, + + 'ONLY_NEW_POSTS' => ONLY_NEW_POSTS, + 'ONLY_NEW_TOPICS' => ONLY_NEW_TOPICS, + // Misc 'BOT_UID' => BOT_UID, + 'COOKIE_MARK' => COOKIE_MARK, 'SID' => $userdata['session_id'], 'SID_HIDDEN' => '', diff --git a/library/includes/ucp/register.php b/library/includes/ucp/register.php index 5e101a310..f70aa11a8 100644 --- a/library/includes/ucp/register.php +++ b/library/includes/ucp/register.php @@ -568,7 +568,7 @@ foreach ($profile_fields as $field => $can_edit) { } } } - $tp_data['TEMPLATES_SELECT'] = \TorrentPier\Legacy\Common\Select::template($pr_data['tpl_name'], 'tpl_name'); + $tp_data['TEMPLATES_SELECT'] = \TorrentPier\Legacy\Select::template($pr_data['tpl_name'], 'tpl_name'); break; /** @@ -725,8 +725,8 @@ $template->assign_vars([ 'INVITE_CODE' => !empty($_GET['invite']) ? htmlCHR($_GET['invite']) : '', 'CAPTCHA_HTML' => ($need_captcha) ? bb_captcha('get') : '', - 'LANGUAGE_SELECT' => \TorrentPier\Legacy\Common\Select::language($pr_data['user_lang'], 'user_lang'), - 'TIMEZONE_SELECT' => \TorrentPier\Legacy\Common\Select::timezone($pr_data['user_timezone'], 'user_timezone'), + 'LANGUAGE_SELECT' => \TorrentPier\Legacy\Select::language($pr_data['user_lang'], 'user_lang'), + 'TIMEZONE_SELECT' => \TorrentPier\Legacy\Select::timezone($pr_data['user_timezone'], 'user_timezone'), 'AVATAR_EXPLAIN' => sprintf($lang['AVATAR_EXPLAIN'], $bb_cfg['avatars']['max_width'], $bb_cfg['avatars']['max_height'], humn_size($bb_cfg['avatars']['max_size'])), 'AVATAR_DISALLOWED' => bf($pr_data['user_opt'], 'user_opt', 'dis_avatar'), diff --git a/posting.php b/posting.php index 39d44c373..b75e17091 100644 --- a/posting.php +++ b/posting.php @@ -625,6 +625,8 @@ $template->assign_vars([ 'POSTER_RGROUPS' => !empty($poster_rgroups) ? $poster_rgroups : '', 'ATTACH_RG_SIG' => $switch_rg_sig ?: false, + 'U_VIEWTOPIC' => ($mode == 'reply') ? TOPIC_URL . "$topic_id&postorder=desc" : '', + 'S_NOTIFY_CHECKED' => $notify_user ? 'checked' : '', 'S_ROBOTS_CHECKED' => $robots_indexing ? 'checked' : '', 'S_TYPE_TOGGLE' => $topic_type_toggle, diff --git a/src/Legacy/Common/Select.php b/src/Legacy/Select.php similarity index 97% rename from src/Legacy/Common/Select.php rename to src/Legacy/Select.php index 424c99869..6dc3de2e0 100644 --- a/src/Legacy/Common/Select.php +++ b/src/Legacy/Select.php @@ -7,11 +7,11 @@ * @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License */ -namespace TorrentPier\Legacy\Common; +namespace TorrentPier\Legacy; /** * Class Select - * @package TorrentPier\Legacy\Common + * @package TorrentPier\Legacy */ class Select { diff --git a/src/Legacy/TorrentFileList.php b/src/Legacy/TorrentFileList.php index fd600d015..960603acc 100644 --- a/src/Legacy/TorrentFileList.php +++ b/src/Legacy/TorrentFileList.php @@ -53,8 +53,10 @@ class TorrentFileList $this->build_filelist_array(); if ($this->multiple) { - if (!empty($this->files_ary['/'])) { - $this->files_ary = array_merge($this->files_ary, $this->files_ary['/']); + if (isset($this->files_ary['/'])) { + if (!empty($this->files_ary['/'])) { + $this->files_ary = $this->files_ary + $this->files_ary['/']; + } unset($this->files_ary['/']); } $filelist = $html->array2html($this->files_ary); diff --git a/src/Updater.php b/src/Updater.php index 5ccba7843..2f90d2f1b 100644 --- a/src/Updater.php +++ b/src/Updater.php @@ -38,6 +38,13 @@ class Updater */ public string $savePath; + /** + * LTS version pattern (v2.4.*) + * + * @var string + */ + private const LTS_VERSION_PATTERN = '/^v2\.4\.\d+$/'; + /** * Stream context * @@ -130,23 +137,67 @@ class Updater } /** - * Returns information of latest TorrentPier version available + * Returns information of latest TorrentPier LTS version (v2.4.*) available + * + * @param bool $allowPreReleases + * @return array + * @throws Exception + */ + public function getLastVersion(bool $allowPreReleases = true): array + { + // Filter releases to get only LTS versions (v2.4.*) + $ltsVersions = array_filter($this->jsonResponse, function ($release) { + return preg_match(self::LTS_VERSION_PATTERN, $release['tag_name']); + }); + + if (empty($ltsVersions)) { + throw new Exception('No LTS versions (v2.4.*) found'); + } + + // Sort LTS versions by version number (descending) + usort($ltsVersions, function ($a, $b) { + return version_compare($b['tag_name'], $a['tag_name']); + }); + + if (!$allowPreReleases) { + foreach ($ltsVersions as $release) { + if (isset($release['prerelease']) && $release['prerelease']) { + continue; + } + return $release; + } + + // If no stable LTS versions found + throw new Exception('No stable LTS versions (v2.4.*) found'); + } + + return $ltsVersions[0]; + } + + /** + * Get all available LTS versions (v2.4.*) * * @param bool $allowPreReleases * @return array */ - public function getLastVersion(bool $allowPreReleases = true): array + public function getAllLTSVersions(bool $allowPreReleases = true): array { - if (!$allowPreReleases) { - foreach ($this->jsonResponse as $index) { - if (isset($index['prerelease']) && $index['prerelease']) { - continue; - } + // Filter releases to get only LTS versions (v2.4.*) + $ltsVersions = array_filter($this->jsonResponse, function ($release) use ($allowPreReleases) { + $isLTSVersion = preg_match(self::LTS_VERSION_PATTERN, $release['tag_name']); - return $index; + if (!$allowPreReleases && isset($release['prerelease']) && $release['prerelease']) { + return false; } - } - return $this->jsonResponse[0]; + return $isLTSVersion; + }); + + // Sort LTS versions by version number (descending) + usort($ltsVersions, function ($a, $b) { + return version_compare($b['tag_name'], $a['tag_name']); + }); + + return array_values($ltsVersions); } } diff --git a/styles/templates/admin/index.tpl b/styles/templates/admin/index.tpl index 3c8f30941..f29030591 100644 --- a/styles/templates/admin/index.tpl +++ b/styles/templates/admin/index.tpl @@ -1,7 +1,7 @@ - + @@ -160,7 +160,7 @@ {L_UPDATE_AVAILABLE}: - {updater.NEW_VERSION_NUMBER} ({L_SIZE}: {updater.NEW_VERSION_SIZE}) · {L_DOWNLOAD} · {L_CHANGELOG} · MD5: {updater.NEW_VERSION_MD5} + {updater.NEW_VERSION_NUMBER} ({L_SIZE}: {updater.NEW_VERSION_SIZE}) · {L_DOWNLOAD} · {L_CHANGELOG} · {updater.NEW_VERSION_HASH} diff --git a/styles/templates/default/filelist.tpl b/styles/templates/default/filelist.tpl index 9e6bc4eb4..149a98acc 100644 --- a/styles/templates/default/filelist.tpl +++ b/styles/templates/default/filelist.tpl @@ -6,30 +6,6 @@
-

{L_BT_FLIST_ANNOUNCERS_LIST}

- - - - - - - - - - - - - - - - - - - - -
#{L_BT_FLIST_ANNOUNCERS}
{announcers.ROW_NUMBER}{announcers.ANNOUNCER}
{L_BT_FLIST_ANNOUNCERS_NOTICE}
-
-

{L_BT_FLIST}

diff --git a/styles/templates/default/images/icons_sources/icon_large.gif b/styles/templates/default/images/icons_sources/icon_large.gif new file mode 100644 index 000000000..e3d072db6 Binary files /dev/null and b/styles/templates/default/images/icons_sources/icon_large.gif differ diff --git a/styles/templates/default/images/icons_sources/icon_medium.gif b/styles/templates/default/images/icons_sources/icon_medium.gif new file mode 100644 index 000000000..fed70f75e Binary files /dev/null and b/styles/templates/default/images/icons_sources/icon_medium.gif differ diff --git a/styles/templates/default/images/icons_sources/icon_small.gif b/styles/templates/default/images/icons_sources/icon_small.gif new file mode 100644 index 000000000..85b723015 Binary files /dev/null and b/styles/templates/default/images/icons_sources/icon_small.gif differ diff --git a/styles/templates/default/images/icons_sources/info.txt b/styles/templates/default/images/icons_sources/info.txt new file mode 100644 index 000000000..5a3a6608e --- /dev/null +++ b/styles/templates/default/images/icons_sources/info.txt @@ -0,0 +1,2 @@ +Color: #3c618b +Font: Arial (Regular) 11pt diff --git a/styles/templates/default/page_header.tpl b/styles/templates/default/page_header.tpl index 0ec5fb8f5..a4b2db8bf 100644 --- a/styles/templates/default/page_header.tpl +++ b/styles/templates/default/page_header.tpl @@ -1,5 +1,5 @@ - + diff --git a/viewtopic.php b/viewtopic.php index 82d39e685..7a0aec0bf 100644 --- a/viewtopic.php +++ b/viewtopic.php @@ -85,17 +85,17 @@ if ($topic_id && isset($_GET['view']) && ($_GET['view'] == 'next' || $_GET['view // Get forum/topic data if ($topic_id) { - $sql = "SELECT t.*, f.*, tw.notify_status + $sql = "SELECT t.*, f.cat_id, f.forum_name, f.forum_desc, f.forum_status, f.forum_order, f.forum_posts, f.forum_topics, f.forum_last_post_id, f.forum_tpl_id, f.prune_days, f.auth_view, f.auth_read, f.auth_post, f.auth_reply, f.auth_edit, f.auth_delete, f.auth_sticky, f.auth_announce, f.auth_vote, f.auth_pollcreate, f.auth_attachments, f.auth_download, f.allow_reg_tracker, f.allow_porno_topic, f.self_moderated, f.forum_parent, f.show_on_index, f.forum_display_sort, f.forum_display_order, tw.notify_status FROM " . BB_TOPICS . " t - LEFT JOIN " . BB_FORUMS . " f USING(forum_id) + LEFT JOIN " . BB_FORUMS . " f ON t.forum_id = f.forum_id LEFT JOIN " . BB_TOPICS_WATCH . " tw ON(tw.topic_id = t.topic_id AND tw.user_id = {$userdata['user_id']}) WHERE t.topic_id = $topic_id "; } elseif ($post_id) { - $sql = "SELECT t.*, f.*, p.post_time, tw.notify_status + $sql = "SELECT t.*, f.cat_id, f.forum_name, f.forum_desc, f.forum_status, f.forum_order, f.forum_posts, f.forum_topics, f.forum_last_post_id, f.forum_tpl_id, f.prune_days, f.auth_view, f.auth_read, f.auth_post, f.auth_reply, f.auth_edit, f.auth_delete, f.auth_sticky, f.auth_announce, f.auth_vote, f.auth_pollcreate, f.auth_attachments, f.auth_download, f.allow_reg_tracker, f.allow_porno_topic, f.self_moderated, f.forum_parent, f.show_on_index, f.forum_display_sort, f.forum_display_order, p.post_time, tw.notify_status FROM " . BB_TOPICS . " t - LEFT JOIN " . BB_FORUMS . " f USING(forum_id) - LEFT JOIN " . BB_POSTS . " p USING(topic_id) + LEFT JOIN " . BB_FORUMS . " f ON t.forum_id = f.forum_id + LEFT JOIN " . BB_POSTS . " p ON t.topic_id = p.topic_id LEFT JOIN " . BB_TOPICS_WATCH . " tw ON(tw.topic_id = t.topic_id AND tw.user_id = {$userdata['user_id']}) WHERE p.post_id = $post_id "; @@ -759,7 +759,9 @@ if (defined('SPLIT_FORM_START')) { $template->assign_vars([ 'SPLIT_FORM' => true, 'START' => $start, - 'S_SPLIT_ACTION' => 'modcp.php' + 'S_SPLIT_ACTION' => 'modcp.php', + 'POST_FORUM_URL' => POST_FORUM_URL, + 'POST_TOPIC_URL' => POST_TOPIC_URL, ]); }