mirror of
https://github.com/torrentpier/torrentpier
synced 2025-08-22 06:13:58 -07:00
Merge branch 'master' into Added-Docker-support
This commit is contained in:
commit
dfb7e529a6
457 changed files with 27877 additions and 13403 deletions
7
.cliffignore
Normal file
7
.cliffignore
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
9766c534bddad8e82e6d19f9bad5cf70b9887f9a
|
||||||
|
92ce77ec0ec703c08a659419087a373f76e711f7
|
||||||
|
2d53efc945c7747be1755d0b66557a86bdc12cbd
|
||||||
|
602137b65129b817811b80975a369ebde3270c6d
|
||||||
|
4eb26ae37e1f4c82a45961517ffeb54c20200408
|
||||||
|
e59adce848a9e10ee5775254045cbbd915236b8b
|
||||||
|
9e0a64108d62236ab07b3f8d10e8c78269b8e1d1
|
|
@ -1,12 +1,13 @@
|
||||||
# Common params
|
# Common params
|
||||||
APP_ENV=local
|
TP_HOST=example.com
|
||||||
|
TP_PORT=80
|
||||||
|
APP_ENV=production
|
||||||
APP_CRON_ENABLED=true
|
APP_CRON_ENABLED=true
|
||||||
APP_DEMO_MODE=false
|
APP_DEMO_MODE=false
|
||||||
|
|
||||||
# Database credentials
|
# Database credentials
|
||||||
DB_CONNECTION=mysql
|
|
||||||
DB_HOST=localhost
|
DB_HOST=localhost
|
||||||
DB_PORT=3306
|
DB_PORT=3306
|
||||||
DB_DATABASE=torrentpier
|
DB_DATABASE=torrentpier
|
||||||
DB_USERNAME=root
|
DB_USERNAME=root
|
||||||
DB_PASSWORD=
|
DB_PASSWORD=secret
|
||||||
|
|
35
.github/ISSUE_TEMPLATE/bug_report.md
vendored
35
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -1,35 +0,0 @@
|
||||||
---
|
|
||||||
name: Bug report
|
|
||||||
about: Create a report to help us improve
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Describe the bug**
|
|
||||||
A clear and concise description of what the bug is.
|
|
||||||
|
|
||||||
**To Reproduce**
|
|
||||||
Steps to reproduce the behavior:
|
|
||||||
1. Go to '...'
|
|
||||||
2. Click on '....'
|
|
||||||
3. Scroll down to '....'
|
|
||||||
4. See error
|
|
||||||
|
|
||||||
**Expected behavior**
|
|
||||||
A clear and concise description of what you expected to happen.
|
|
||||||
|
|
||||||
**Screenshots**
|
|
||||||
If applicable, add screenshots to help explain your problem.
|
|
||||||
|
|
||||||
**Desktop (please complete the following information):**
|
|
||||||
- OS: [e.g. iOS]
|
|
||||||
- Browser [e.g. chrome, safari]
|
|
||||||
- Version [e.g. 22]
|
|
||||||
|
|
||||||
**Smartphone (please complete the following information):**
|
|
||||||
- Device: [e.g. iPhone6]
|
|
||||||
- OS: [e.g. iOS8.1]
|
|
||||||
- Browser [e.g. stock browser, safari]
|
|
||||||
- Version [e.g. 22]
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context about the problem here.
|
|
62
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
62
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
name: Bug Report
|
||||||
|
description: File a bug report
|
||||||
|
title: "[Bug]"
|
||||||
|
labels: [Bug]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out this bug report!
|
||||||
|
The more detailed this bug report is, the faster it can be reviewed and fixed.
|
||||||
|
- type: input
|
||||||
|
id: version-torrentpier
|
||||||
|
attributes:
|
||||||
|
label: TorrentPier Version
|
||||||
|
description: TorrentPier version your using?
|
||||||
|
placeholder: 2.4.0
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: version-php-os
|
||||||
|
attributes:
|
||||||
|
label: PHP & Platform
|
||||||
|
description: Exact PHP and Platform (OS) versions your using.
|
||||||
|
placeholder: 8.2.2 - Ubuntu 22.04 x64
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: checkboxes
|
||||||
|
id: requirements
|
||||||
|
attributes:
|
||||||
|
label: Have you done this?
|
||||||
|
options:
|
||||||
|
- label: I am willing to share my stack trace and logs
|
||||||
|
required: true
|
||||||
|
- label: I can suggest a fix as a Pull Request
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: expectation
|
||||||
|
attributes:
|
||||||
|
label: Expectation
|
||||||
|
description: Write what you expect to (correctly) happen.
|
||||||
|
placeholder: When I do this, I expect to this to happen.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: description
|
||||||
|
attributes:
|
||||||
|
label: Description
|
||||||
|
description: Write what (incorrectly) happens instead.
|
||||||
|
placeholder: Instead, when I do this, I receive that.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: logs
|
||||||
|
attributes:
|
||||||
|
label: Stack trace & logs
|
||||||
|
description: |
|
||||||
|
If you have a stack trace, you can copy it here. You may hide sensitive information.
|
||||||
|
Including a stack trace when reporting an error 500 is required.
|
||||||
|
placeholder: This is automatically formatted into code, no need for backticks.
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: false
|
7
.github/ISSUE_TEMPLATE/feature---enhancement-request.md
vendored
Normal file
7
.github/ISSUE_TEMPLATE/feature---enhancement-request.md
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
name: Feature / Enhancement request
|
||||||
|
about: Suggest an idea for TorrentPier
|
||||||
|
title: "[Feature]"
|
||||||
|
labels: [Feature, Enhancement]
|
||||||
|
assignees: ''
|
||||||
|
---
|
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
|
@ -1,17 +0,0 @@
|
||||||
---
|
|
||||||
name: Feature request
|
|
||||||
about: Suggest an idea for this project
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Is your feature request related to a problem? Please describe.**
|
|
||||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
|
||||||
|
|
||||||
**Describe the solution you'd like**
|
|
||||||
A clear and concise description of what you want to happen.
|
|
||||||
|
|
||||||
**Describe alternatives you've considered**
|
|
||||||
A clear and concise description of any alternative solutions or features you've considered.
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context or screenshots about the feature request here.
|
|
80
.github/workflows/cd.yml
vendored
Normal file
80
.github/workflows/cd.yml
vendored
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
name: Continuous Deployment
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "v*.*.*"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
generate-changelog:
|
||||||
|
name: Generate changelog
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
outputs:
|
||||||
|
release_body: ${{ steps.git-cliff.outputs.content }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Generate a changelog
|
||||||
|
uses: orhun/git-cliff-action@v4
|
||||||
|
id: git-cliff
|
||||||
|
with:
|
||||||
|
config: cliff.toml
|
||||||
|
args: -vv --latest --no-exec --github-repo ${{ github.repository }}
|
||||||
|
|
||||||
|
- name: Print the changelog
|
||||||
|
run: cat "${{ steps.git-cliff.outputs.changelog }}"
|
||||||
|
|
||||||
|
release:
|
||||||
|
name: Create release
|
||||||
|
needs: [ generate-changelog ]
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Set the release version
|
||||||
|
shell: bash
|
||||||
|
run: echo "RELEASE_VERSION=${GITHUB_REF:11}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: '8.2'
|
||||||
|
|
||||||
|
- name: Install Composer dependencies
|
||||||
|
run: composer install --no-dev --no-progress --prefer-dist --optimize-autoloader
|
||||||
|
|
||||||
|
- name: Cleanup
|
||||||
|
run: php _cleanup.php && rm _cleanup.php
|
||||||
|
|
||||||
|
- name: Create archive
|
||||||
|
id: create-zip
|
||||||
|
run: |
|
||||||
|
ZIP_NAME="torrentpier-v${{ env.RELEASE_VERSION }}.zip"
|
||||||
|
zip -r "$ZIP_NAME" . -x ".git/*"
|
||||||
|
echo "ZIP_NAME=$ZIP_NAME" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Publish to GitHub
|
||||||
|
if: ${{ !contains(github.ref, '-') }}
|
||||||
|
uses: svenstaro/upload-release-action@v2
|
||||||
|
with:
|
||||||
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
file: ${{ steps.create-zip.outputs.ZIP_NAME }}
|
||||||
|
overwrite: true
|
||||||
|
tag: ${{ github.ref }}
|
||||||
|
release_name: "v${{ env.RELEASE_VERSION }}"
|
||||||
|
body: "${{ needs.generate-changelog.outputs.release_body }}"
|
||||||
|
|
||||||
|
- name: Publish to GitHub (pre-release)
|
||||||
|
if: ${{ contains(github.ref, '-') }}
|
||||||
|
uses: svenstaro/upload-release-action@v2
|
||||||
|
with:
|
||||||
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
file: ${{ steps.create-zip.outputs.ZIP_NAME }}
|
||||||
|
overwrite: true
|
||||||
|
tag: ${{ github.ref }}
|
||||||
|
release_name: "v${{ env.RELEASE_VERSION }}"
|
||||||
|
body: "${{ needs.generate-changelog.outputs.release_body }}"
|
||||||
|
prerelease: true
|
45
.github/workflows/ci.yml
vendored
Normal file
45
.github/workflows/ci.yml
vendored
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
name: Continuous Integration
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
nightly:
|
||||||
|
name: Nightly builds 📦
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code 🗳
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup PHP 🔩
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: '8.2'
|
||||||
|
|
||||||
|
- name: Install Composer dependencies 🪚
|
||||||
|
run: composer install --no-dev --no-progress --prefer-dist --optimize-autoloader
|
||||||
|
|
||||||
|
- name: Get commit hash 🔗
|
||||||
|
id: get-commit-hash
|
||||||
|
run: |
|
||||||
|
COMMIT_HASH=$(git rev-parse --short HEAD)
|
||||||
|
echo "COMMIT_HASH=$COMMIT_HASH" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Cleanup
|
||||||
|
run: php _cleanup.php && rm _cleanup.php
|
||||||
|
|
||||||
|
- name: Create archive 🗞
|
||||||
|
id: create-zip
|
||||||
|
run: |
|
||||||
|
ZIP_NAME="torrentpier-${{ steps.get-commit-hash.outputs.COMMIT_HASH }}.zip"
|
||||||
|
zip -r "$ZIP_NAME" . -x ".git/*"
|
||||||
|
echo "ZIP_NAME=$ZIP_NAME" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Upload Archive 📤
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: TorrentPier-master
|
||||||
|
path: ${{ steps.create-zip.outputs.ZIP_NAME }}
|
41
.github/workflows/schedule.yml
vendored
Normal file
41
.github/workflows/schedule.yml
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
name: Changelog generation
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
changelog:
|
||||||
|
name: Changelog generation
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
ref: master
|
||||||
|
token: ${{ secrets.REPO_TOKEN }}
|
||||||
|
|
||||||
|
- name: Generate a changelog
|
||||||
|
uses: orhun/git-cliff-action@v4
|
||||||
|
id: git-cliff
|
||||||
|
with:
|
||||||
|
config: cliff.toml
|
||||||
|
args: v2.4.6-alpha.4.. --verbose
|
||||||
|
env:
|
||||||
|
OUTPUT: CHANGELOG.md
|
||||||
|
GITHUB_REPO: ${{ github.repository }}
|
||||||
|
|
||||||
|
- name: Print the changelog
|
||||||
|
run: cat "${{ steps.git-cliff.outputs.changelog }}"
|
||||||
|
|
||||||
|
- name: Commit changelog
|
||||||
|
run: |
|
||||||
|
git checkout master
|
||||||
|
git config --local user.name 'belomaxorka'
|
||||||
|
git config --local user.email 'roman25052006.kelesh@gmail.com'
|
||||||
|
set +e
|
||||||
|
git add CHANGELOG.md
|
||||||
|
git commit -m "changelog: Update CHANGELOG.md 📖"
|
||||||
|
git push https://${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git master
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,9 +1,11 @@
|
||||||
### IDE ###
|
### IDE ###
|
||||||
.idea
|
.idea
|
||||||
|
.vscode
|
||||||
|
|
||||||
### TorrentPier ###
|
### TorrentPier ###
|
||||||
*.log
|
*.log
|
||||||
*.integrity
|
install.php_*
|
||||||
|
composer-setup.php
|
||||||
.env
|
.env
|
||||||
.php_cs.cache
|
.php_cs.cache
|
||||||
data/avatars
|
data/avatars
|
||||||
|
|
1088
CHANGELOG.md
1088
CHANGELOG.md
File diff suppressed because it is too large
Load diff
144
CLAUDE.md
Normal file
144
CLAUDE.md
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
TorrentPier is a BitTorrent tracker engine written in PHP, designed for hosting BitTorrent communities with forum functionality. The project is in active modernization, transitioning from legacy code to modern PHP practices while maintaining backward compatibility.
|
||||||
|
|
||||||
|
## Technology Stack & Architecture
|
||||||
|
|
||||||
|
- **PHP 8.2+** with modern features
|
||||||
|
- **MySQL/MariaDB/Percona** database
|
||||||
|
- **Nette Database** with backward-compatible wrapper
|
||||||
|
- **Composer** for dependency management
|
||||||
|
- **Custom BitTorrent tracker** implementation
|
||||||
|
|
||||||
|
## Key Directory Structure
|
||||||
|
|
||||||
|
- `/src/` - Modern PHP classes (PSR-4 autoloaded as `TorrentPier\`)
|
||||||
|
- `/library/` - Core application logic and legacy code
|
||||||
|
- `/admin/` - Administrative interface
|
||||||
|
- `/bt/` - BitTorrent tracker functionality (announce.php, scrape.php)
|
||||||
|
- `/styles/` - Templates, CSS, JS, images
|
||||||
|
- `/internal_data/` - Cache, logs, compiled templates
|
||||||
|
- `/install/` - Installation scripts and configuration examples
|
||||||
|
- `/migrations/` - Database migration files (Phinx)
|
||||||
|
|
||||||
|
## Entry Points & Key Files
|
||||||
|
|
||||||
|
- `index.php` - Main forum homepage
|
||||||
|
- `tracker.php` - Torrent search/browse interface
|
||||||
|
- `bt/announce.php` - BitTorrent announce endpoint
|
||||||
|
- `bt/scrape.php` - BitTorrent scrape endpoint
|
||||||
|
- `admin/index.php` - Administrative panel
|
||||||
|
- `cron.php` - Background task runner (CLI only)
|
||||||
|
- `install.php` - Installation script (CLI only)
|
||||||
|
|
||||||
|
## Development Commands
|
||||||
|
|
||||||
|
### Installation & Setup
|
||||||
|
```bash
|
||||||
|
# Automated installation (CLI)
|
||||||
|
php install.php
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
composer install
|
||||||
|
|
||||||
|
# Update dependencies
|
||||||
|
composer update
|
||||||
|
```
|
||||||
|
|
||||||
|
### Maintenance & Operations
|
||||||
|
```bash
|
||||||
|
# Run background maintenance tasks
|
||||||
|
php cron.php
|
||||||
|
```
|
||||||
|
|
||||||
|
### Code Quality
|
||||||
|
The project uses **StyleCI** with PSR-2 preset for code style enforcement. StyleCI configuration is in `.styleci.yml` targeting `src/` directory.
|
||||||
|
|
||||||
|
## Modern Architecture Components
|
||||||
|
|
||||||
|
### Database Layer (`/src/Database/`)
|
||||||
|
- **Nette Database** with full old SqlDb backward compatibility
|
||||||
|
- Singleton pattern accessible via `DB()` function
|
||||||
|
- Support for multiple database connections and debug functionality
|
||||||
|
- Migration path to ORM-style Explorer queries
|
||||||
|
|
||||||
|
### Cache System (`/src/Cache/`)
|
||||||
|
- **Unified caching** using Nette Caching internally
|
||||||
|
- 100% backward compatibility with existing `CACHE()` and $datastore calls
|
||||||
|
- Supports file, SQLite, memory, and Memcached storage
|
||||||
|
- Advanced features: memoization, cache dependencies
|
||||||
|
|
||||||
|
### Configuration Management
|
||||||
|
- Environment-based config with `.env` files
|
||||||
|
- Singleton `Config` class accessible via `config()` function
|
||||||
|
- Local overrides supported via `library/config.local.php`
|
||||||
|
|
||||||
|
## Configuration Files
|
||||||
|
- `.env` - Environment variables (copy from `.env.example`)
|
||||||
|
- `library/config.php` - Main application configuration
|
||||||
|
- `library/config.local.php` - Local configuration overrides
|
||||||
|
- `composer.json` - Dependencies and PSR-4 autoloading
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
### CI/CD Pipeline
|
||||||
|
- **GitHub Actions** for automated testing and deployment
|
||||||
|
- **StyleCI** for code style enforcement
|
||||||
|
- **Dependabot** for dependency updates
|
||||||
|
- **FTP deployment** to demo environment
|
||||||
|
|
||||||
|
### Installation Methods
|
||||||
|
1. **Automated**: `php install.php` (recommended)
|
||||||
|
2. **Composer**: `composer create-project torrentpier/torrentpier`
|
||||||
|
3. **Manual**: Git clone + `composer install` + database setup
|
||||||
|
|
||||||
|
## Database & Schema
|
||||||
|
|
||||||
|
- **Database migrations** managed via Phinx in `/migrations/` directory
|
||||||
|
- Initial schema: `20250619000001_initial_schema.php`
|
||||||
|
- Initial seed data: `20250619000002_seed_initial_data.php`
|
||||||
|
- UTF-8 (utf8mb4) character set required
|
||||||
|
- Multiple database alias support for different components
|
||||||
|
|
||||||
|
### Migration Commands
|
||||||
|
```bash
|
||||||
|
# Run all pending migrations
|
||||||
|
php vendor/bin/phinx migrate --configuration=phinx.php
|
||||||
|
|
||||||
|
# Check migration status
|
||||||
|
php vendor/bin/phinx status --configuration=phinx.php
|
||||||
|
|
||||||
|
# Mark migrations as applied (for existing installations)
|
||||||
|
php vendor/bin/phinx migrate --fake --configuration=phinx.php
|
||||||
|
```
|
||||||
|
|
||||||
|
## Legacy Compatibility Strategy
|
||||||
|
|
||||||
|
The codebase maintains 100% backward compatibility while introducing modern alternatives:
|
||||||
|
|
||||||
|
- **Database layer**: Existing old SqlDb calls work while new code can use Nette Database
|
||||||
|
- **Cache system**: All existing `CACHE()` and $datastore calls preserved while adding modern features
|
||||||
|
- **Configuration**: Legacy config access maintained alongside new singleton pattern
|
||||||
|
|
||||||
|
This approach allows gradual modernization without breaking existing functionality - critical for a mature application with existing deployments.
|
||||||
|
|
||||||
|
## Security & Performance
|
||||||
|
|
||||||
|
- **Environment-based secrets** management via `.env`
|
||||||
|
- **CDN/proxy support** (Cloudflare, Fastly)
|
||||||
|
- **Input sanitization** and CSRF protection
|
||||||
|
- **Advanced caching** with multiple storage backends
|
||||||
|
- **Rate limiting** and IP-based restrictions
|
||||||
|
|
||||||
|
## BitTorrent Tracker Features
|
||||||
|
|
||||||
|
- **BitTorrent v1 & v2** support
|
||||||
|
- **TorrServer integration** capability
|
||||||
|
- **Client ban system** for problematic torrent clients
|
||||||
|
- **Scrape support** for tracker statistics
|
||||||
|
|
||||||
|
When working with this codebase, prioritize understanding the legacy compatibility approach and modern architecture patterns. Always test both legacy and modern code paths when making changes to core systems.
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2005-2024 TorrentPier
|
Copyright (c) 2005-2025 TorrentPier
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
135
README.md
135
README.md
|
@ -2,45 +2,47 @@
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
Bull-powered BitTorrent tracker engine
|
Bull-powered BitTorrent tracker engine
|
||||||
<br>
|
<br/>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/torrentpier/torrentpier/blob/master/LICENSE"><img src="https://img.shields.io/github/license/torrentpier/torrentpier" alt="License"></a>
|
<a href="https://github.com/torrentpier/torrentpier/blob/master/LICENSE"><img src="https://img.shields.io/github/license/torrentpier/torrentpier" alt="License"></a>
|
||||||
<a href="https://packagist.org/packages/torrentpier/torrentpier"><img src="https://img.shields.io/packagist/stars/torrentpier/torrentpier" alt="Stars Packagist"></a>
|
<a href="https://packagist.org/packages/torrentpier/torrentpier"><img src="https://img.shields.io/packagist/stars/torrentpier/torrentpier" alt="Stars Packagist"></a>
|
||||||
<a href="https://github.com/torrentpier/torrentpier/actions"><img src="https://img.shields.io/github/actions/workflow/status/torrentpier/torrentpier/phpmd.yml" alt="Build status"></a>
|
|
||||||
<a href="https://crowdin.com/project/torrentpier"><img src="https://badges.crowdin.net/torrentpier/localized.svg" alt="Crowdin"></a>
|
<a href="https://crowdin.com/project/torrentpier"><img src="https://badges.crowdin.net/torrentpier/localized.svg" alt="Crowdin"></a>
|
||||||
|
<a href="https://nightly.link/torrentpier/torrentpier/workflows/ci/master/TorrentPier-master"><img src="https://img.shields.io/badge/Nightly%20release-gray?logo=hackthebox&logoColor=fff" alt="TorrentPier nightly"></a>
|
||||||
<a href="https://packagist.org/packages/torrentpier/torrentpier"><img src="https://img.shields.io/packagist/dt/torrentpier/torrentpier" alt="Downloads"></a>
|
<a href="https://packagist.org/packages/torrentpier/torrentpier"><img src="https://img.shields.io/packagist/dt/torrentpier/torrentpier" alt="Downloads"></a>
|
||||||
<a href="https://packagist.org/packages/torrentpier/torrentpier"><img src="https://img.shields.io/packagist/v/torrentpier/torrentpier" alt="Version"></a>
|
<a href="https://packagist.org/packages/torrentpier/torrentpier"><img src="https://img.shields.io/packagist/v/torrentpier/torrentpier" alt="Version"></a>
|
||||||
<a href="https://github.com/torrentpier/torrentpier/releases"><img src="https://img.shields.io/github/release-date/torrentpier/torrentpier" alt="Last release"></a>
|
<a href="https://github.com/torrentpier/torrentpier/releases"><img src="https://img.shields.io/github/release-date/torrentpier/torrentpier" alt="Last release"></a>
|
||||||
<img src="https://img.shields.io/github/repo-size/torrentpier/torrentpier" alt="Size">
|
<img src="https://img.shields.io/github/repo-size/torrentpier/torrentpier" alt="Size">
|
||||||
|
<a href="https://github.com/SamKirkland/FTP-Deploy-Action"><img src="https://img.shields.io/badge/Deployed to TorrentPier Demo with-FTP DEPLOY ACTION-%3CCOLOR%3E?color=2b9348" alt="Deployed to TorrentPier Demo with FTP Deploy Action"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## 🐂 About TorrentPier
|
## 🐂 About TorrentPier
|
||||||
|
|
||||||
TorrentPier — bull-powered BitTorrent Public/Private tracker engine, written in php. High speed, simple modification, high load
|
TorrentPier — bull-powered BitTorrent Public/Private tracker engine, written in PHP. High speed, simple modifications, load-balanced
|
||||||
architecture. In addition, we have very helpful
|
architecture. In addition, we have a very helpful
|
||||||
[official support forum](https://torrentpier.com), where it's possible to get any support and download modifications for engine.
|
[official support forum](https://torrentpier.com), where it's possible to get support and download modifications for the engine.
|
||||||
|
|
||||||
## 🌈 Current status
|
## 🌈 Current status
|
||||||
|
|
||||||
TorrentPier is currently in active development. The goal is to remove all legacy code and rewrite existing to
|
TorrentPier is currently in active development. The goal is to remove all legacy code and rewrite the existing code to
|
||||||
modern standards. If you want to go deep on the code, check our [issues](https://github.com/torrentpier/torrentpier/issues)
|
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 into english in the near future, currently russian is the main language of it.
|
and go from there. The documentation will be translated to English in the near future, currently Russian is the main language.
|
||||||
|
|
||||||
## ✨ Features
|
## ✨ Features
|
||||||
* Rich forum browsing/moderation tools
|
* Rich forum with browsing/moderation tools
|
||||||
* High-load capable, heavily configurable announcer
|
* High-load capable, heavily configurable announcer
|
||||||
* Scrape support
|
* Scrape support
|
||||||
* FreeLeech
|
* FreeLeech
|
||||||
|
* [TorrServer integration](https://github.com/YouROK/TorrServer) support
|
||||||
* BitTorrent v2 support
|
* BitTorrent v2 support
|
||||||
* Event-based invite system
|
* Event-based invite system
|
||||||
* Bonus points
|
* Bonus points
|
||||||
* Polls system
|
* Polling system
|
||||||
* PM system
|
* PM/DM system
|
||||||
* Multilingual support
|
* Multilingual support (Russian and English are currently fully supported, with others in the future)
|
||||||
* Atom feeds
|
* Atom/RSS feeds
|
||||||
* and MUCH MORE!
|
* ... and so MUCH MORE!
|
||||||
|
|
||||||
## 🖥️ Demo
|
## 🖥️ Demo
|
||||||
|
|
||||||
|
@ -49,66 +51,106 @@ and go from there. The documentation will be translated into english in the near
|
||||||
* Password: `admin`
|
* Password: `admin`
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> Demo is resetting every 24 hours!
|
> Demo resets every 24 hours!
|
||||||
|
|
||||||
## 🔧 Requirements
|
## 🔧 Requirements
|
||||||
|
|
||||||
* Apache / nginx
|
* 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
|
* PHP: 8.2 / 8.3 / 8.4
|
||||||
* PHP Extensions: mbstring, bcmath, intl, tidy (optional), xml, xmlwriter
|
* PHP Extensions: mbstring, gd, bcmath, intl, tidy (optional), xml, xmlwriter
|
||||||
* Crontab (Recommended)
|
* Crontab (Recommended)
|
||||||
|
|
||||||
## 💾 Installation
|
## 💾 Installation
|
||||||
|
|
||||||
For installation, you need to follow a few simple steps.
|
For the installation, select one of the installation variants below:
|
||||||
|
|
||||||
### Quick ☕️
|
### Quick (Clean install) 🚀
|
||||||
|
|
||||||
1. [Download latest](https://github.com/torrentpier/torrentpier/archive/refs/heads/master.zip) version of TorrentPier
|
Check out our [autoinstall](https://github.com/torrentpier/autoinstall) repository with detailed instructions.
|
||||||
2. Open directory with TorrentPier and run in CLI mode `php install.php`
|
|
||||||
3. Voila! ✨
|
> [!NOTE]
|
||||||
|
> Thanks to [Sergei Solovev](https://github.com/SeAnSolovev) for this installation script ❤️
|
||||||
|
|
||||||
|
### Quick (For web-panels) ☕️
|
||||||
|
|
||||||
|
1. Select the folder where you want TorrentPier installed
|
||||||
|
```shell
|
||||||
|
cd /path/to/public_html
|
||||||
|
```
|
||||||
|
2. Download the latest version of TorrentPier
|
||||||
|
```shell
|
||||||
|
sudo git clone https://github.com/torrentpier/torrentpier.git .
|
||||||
|
```
|
||||||
|
3. After completing, execute the command below and follow the instructions
|
||||||
|
```shell
|
||||||
|
php install.php
|
||||||
|
```
|
||||||
|
4. Voila! ✨
|
||||||
|
|
||||||
### Manual 🔩
|
### Manual 🔩
|
||||||
|
|
||||||
1. Install [Composer](https://getcomposer.org/)
|
1. Install [Composer](https://getcomposer.org/)
|
||||||
2. Run `composer create-project torrentpier/torrentpier`
|
2. Run the following command to create the TorrentPier project
|
||||||
|
```shell
|
||||||
|
composer create-project torrentpier/torrentpier
|
||||||
|
```
|
||||||
3. [Check our system requirements](#-requirements)
|
3. [Check our system requirements](#-requirements)
|
||||||
4. After run `composer install` on the project directory
|
4. After, run this command in the project directory to install Composer dependencies
|
||||||
5. Create database and import dump located at `install/sql/mysql.sql`
|
```shell
|
||||||
6. Edit database configuration settings in the environment (`.env.example`), after rename to `.env`
|
composer install
|
||||||
|
```
|
||||||
|
5. Edit database configuration settings in the environment (`.env.example`), after, rename to `.env`
|
||||||
|
6. Create a database and run migrations to set up the schema
|
||||||
|
```shell
|
||||||
|
php vendor/bin/phinx migrate --configuration=phinx.php
|
||||||
|
```
|
||||||
7. Provide write permissions to the specified folders:
|
7. Provide write permissions to the specified folders:
|
||||||
* `data/avatars`, `data/uploads`, `data/uploads/thumbs`
|
* `data/avatars`, `data/uploads`, `data/uploads/thumbs`
|
||||||
* `internal_data/atom`, `internal_data/cache`, `internal_data/log`, `internal_data/triggers`
|
* `internal_data/atom`, `internal_data/cache`, `internal_data/log`, `internal_data/triggers`
|
||||||
* `sitemap`
|
* `sitemap`
|
||||||
8. Voila! ✨
|
8. Voila! ✨
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> You can automate steps 4-7 by running `php install.php` instead, which will guide you through the setup process interactively.
|
||||||
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> The specific settings depend on the server you are using, but in general case we recommend chmod **0755** for folders, and chmod **0644** for files in them.
|
> The specific settings depend on the server you are using, but in general we recommend chmod **0755** for folders, and chmod **0644** for the files in them.
|
||||||
|
|
||||||
### Additional steps 👣
|
### Additional steps 👣
|
||||||
|
|
||||||
1. Edit domain name and domain port in the configuration file or a local copy (`$reserved_name` and `$reserved_port`)
|
1. Edit these files:
|
||||||
2. Edit this files:
|
* `favicon.png` (change to your own)
|
||||||
* `favicon.png` (change on your own)
|
* `robots.txt` (change the addresses in lines `Host` and `Sitemap` to your own)
|
||||||
* `robots.txt` (change the addresses in lines `Host` and `Sitemap` on 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!
|
||||||
* `opensearch_desc.xml` (change the description and address on your own)
|
|
||||||
* `opensearch_desc_bt.xml` (change the description and address on your own)
|
|
||||||
3. Log in to the forum with **admin/admin** login/password and finish setting up via admin panel
|
|
||||||
|
|
||||||
## 🔐 Security vulnerabilities
|
## 🔐 Security vulnerabilities
|
||||||
|
|
||||||
If you discover a security vulnerability within TorrentPier, please follow our [security policy](https://github.com/torrentpier/torrentpier/security/policy), so we can address it promptly.
|
If you discover a security vulnerability within TorrentPier, please follow our [security policy](https://github.com/torrentpier/torrentpier/security/policy), so we can address it promptly.
|
||||||
|
|
||||||
|
## 🧪 Testing
|
||||||
|
|
||||||
|
TorrentPier includes a comprehensive testing suite built with **Pest PHP**. Run tests to ensure code quality and system reliability:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Run all tests
|
||||||
|
./vendor/bin/pest
|
||||||
|
|
||||||
|
# Run with coverage
|
||||||
|
./vendor/bin/pest --coverage
|
||||||
|
```
|
||||||
|
|
||||||
|
For detailed testing documentation, see [tests/README.md](tests/README.md).
|
||||||
|
|
||||||
## 📌 Our recommendations
|
## 📌 Our recommendations
|
||||||
|
|
||||||
* *The recommended way to run `cron.php`.* - For significant tracker speed increase may be required to replace built-in cron.php by 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 local configuration file `library/config.local.php`.
|
* *Local configuration copy.* - You can override the settings using the local configuration file `library/config.local.php`.
|
||||||
|
|
||||||
## 💚 Contributing / Contributors
|
## 💚 Contributing / Contributors
|
||||||
|
|
||||||
Please read our [contributing policy](CONTRIBUTING.md) and [code of conduct](CODE_OF_CONDUCT.md) for details, and the process for
|
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
|
submitting pull requests to us. But we are always ready to review your pull-request for compliance with
|
||||||
these requirements. Just send it!
|
these requirements. Just send it!
|
||||||
|
|
||||||
<a href="https://github.com/torrentpier/torrentpier/graphs/contributors">
|
<a href="https://github.com/torrentpier/torrentpier/graphs/contributors">
|
||||||
|
@ -126,17 +168,18 @@ Support this project by becoming a sponsor or a backer.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Monero</summary>
|
<summary>Monero</summary>
|
||||||
42zJE3FDvN8foP9QYgDrBjgtd7h2FipGCGmAcmG5VFQuRkJBGMbCvoLSmivepmAMEgik2E8MPWUzKaoYsGCtmhvL7ZN73jh
|
|
||||||
|
```
|
||||||
|
42zJE3FDvN8foP9QYgDrBjgtd7h2FipGCGmAcmG5VFQuRkJBGMbCvoLSmivepmAMEgik2E8MPWUzKaoYsGCtmhvL7ZN73jh
|
||||||
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Bitcoin</summary>
|
<summary>YooMoney</summary>
|
||||||
bc1qselchy0nnh7xl99glfffedqp7p9gpvatdr9dz9
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
```
|
||||||
<summary>ЮMoney</summary>
|
4100118022415720
|
||||||
4100118022415720
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## 📦 Versioning
|
## 📦 Versioning
|
||||||
|
|
1261
UPGRADE_GUIDE.md
Normal file
1261
UPGRADE_GUIDE.md
Normal file
File diff suppressed because it is too large
Load diff
57
_cleanup.php
Normal file
57
_cleanup.php
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('BB_ROOT')) {
|
||||||
|
define('BB_ROOT', __DIR__ . DIRECTORY_SEPARATOR);
|
||||||
|
define('BB_PATH', BB_ROOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check CLI mode
|
||||||
|
if (PHP_SAPI != 'cli') {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists('removeFile')) {
|
||||||
|
// Get all constants
|
||||||
|
require_once BB_ROOT . 'library/defines.php';
|
||||||
|
|
||||||
|
// Include CLI functions
|
||||||
|
require INC_DIR . '/functions_cli.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
$items = [
|
||||||
|
'.github',
|
||||||
|
'.cliffignore',
|
||||||
|
'.editorconfig',
|
||||||
|
'.gitignore',
|
||||||
|
'.styleci.yml',
|
||||||
|
'_release.php',
|
||||||
|
'CHANGELOG.md',
|
||||||
|
'CLAUDE.md',
|
||||||
|
'cliff.toml',
|
||||||
|
'CODE_OF_CONDUCT.md',
|
||||||
|
'CONTRIBUTING.md',
|
||||||
|
'crowdin.yml',
|
||||||
|
'HISTORY.md',
|
||||||
|
'phpunit.xml',
|
||||||
|
'README.md',
|
||||||
|
'SECURITY.md',
|
||||||
|
'tests',
|
||||||
|
'UPGRADE_GUIDE.md'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$path = BB_ROOT . $item;
|
||||||
|
|
||||||
|
if (is_file($path)) {
|
||||||
|
removeFile($path);
|
||||||
|
} elseif (is_dir($path)) {
|
||||||
|
removeDir($path);
|
||||||
|
}
|
||||||
|
}
|
130
_release.php
Normal file
130
_release.php
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
define('BB_ROOT', __DIR__ . DIRECTORY_SEPARATOR);
|
||||||
|
define('BB_PATH', BB_ROOT);
|
||||||
|
|
||||||
|
// Check CLI mode
|
||||||
|
if (PHP_SAPI != 'cli') {
|
||||||
|
die('Please run <code style="background:#222;color:#00e01f;padding:2px 6px;border-radius:3px;">php ' . basename(__FILE__) . '</code> in CLI mode');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all constants
|
||||||
|
require_once BB_ROOT . 'library/defines.php';
|
||||||
|
|
||||||
|
// Include CLI functions
|
||||||
|
require INC_DIR . '/functions_cli.php';
|
||||||
|
|
||||||
|
// Welcoming message
|
||||||
|
out("--- Release creation tool ---\n", 'info');
|
||||||
|
|
||||||
|
$configFile = BB_PATH . '/library/config.php';
|
||||||
|
|
||||||
|
if (!is_file($configFile)) {
|
||||||
|
out('- Config file ' . basename($configFile) . ' not found', 'error');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
if (!is_readable($configFile)) {
|
||||||
|
out('- Config file ' . basename($configFile) . ' is not readable', 'error');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
if (!is_writable($configFile)) {
|
||||||
|
out('- Config file ' . basename($configFile) . ' is not writable', 'error');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ask for version
|
||||||
|
fwrite(STDOUT, 'Enter version number (e.g, v2.4.0): ');
|
||||||
|
$version = trim(fgets(STDIN));
|
||||||
|
|
||||||
|
if (empty($version)) {
|
||||||
|
out("- Version cannot be empty. Please enter a valid version number", 'error');
|
||||||
|
exit;
|
||||||
|
} else {
|
||||||
|
// Add 'v' prefix if missing
|
||||||
|
if (!str_starts_with($version, 'v')) {
|
||||||
|
$version = 'v' . $version;
|
||||||
|
}
|
||||||
|
|
||||||
|
out("- Using version: $version", 'info');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ask for version emoji
|
||||||
|
fwrite(STDOUT, 'Enter version emoji: ');
|
||||||
|
$versionEmoji = trim(fgets(STDIN));
|
||||||
|
|
||||||
|
if (!empty($versionEmoji)) {
|
||||||
|
out("- Using version emoji: $versionEmoji", 'info');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ask for release date or use today's date
|
||||||
|
fwrite(STDOUT, "Enter release date (e.g. 25-05-2025), leave empty to use today's date: ");
|
||||||
|
$date = trim(fgets(STDIN));
|
||||||
|
|
||||||
|
if (empty($date)) {
|
||||||
|
$date = date('d-m-Y');
|
||||||
|
out("- Using current date: $date", 'info');
|
||||||
|
} else {
|
||||||
|
// Validate date format (dd-mm-yyyy)
|
||||||
|
$dateObj = DateTime::createFromFormat('d-m-Y', $date);
|
||||||
|
if (!$dateObj || $dateObj->format('d-m-Y') !== $date) {
|
||||||
|
out("- Invalid date format. Expected format: DD-MM-YYYY", 'error');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
out("- Using date: $date", 'info');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read config file content
|
||||||
|
$content = file_get_contents($configFile);
|
||||||
|
|
||||||
|
// Update version
|
||||||
|
$content = preg_replace(
|
||||||
|
"/\\\$bb_cfg\['tp_version'\]\s*=\s*'[^']*';/",
|
||||||
|
"\$bb_cfg['tp_version'] = '$version';",
|
||||||
|
$content
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update release date
|
||||||
|
$content = preg_replace(
|
||||||
|
"/\\\$bb_cfg\['tp_release_date'\]\s*=\s*'[^']*';/",
|
||||||
|
"\$bb_cfg['tp_release_date'] = '$date';",
|
||||||
|
$content
|
||||||
|
);
|
||||||
|
|
||||||
|
// Save updated config
|
||||||
|
$bytesWritten = file_put_contents($configFile, $content);
|
||||||
|
|
||||||
|
if ($bytesWritten === false) {
|
||||||
|
out("- Failed to write to config file", 'error');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($bytesWritten === 0) {
|
||||||
|
out("- Config file was not updated (0 bytes written)", 'error');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
out("\n- Config file has been updated!", 'success');
|
||||||
|
|
||||||
|
// Update CHANGELOG.md
|
||||||
|
runProcess('npx git-cliff v2.4.6-alpha.4.. --config cliff.toml --tag "' . $version . '" > CHANGELOG.md');
|
||||||
|
|
||||||
|
// Git add & commit
|
||||||
|
runProcess('git add -A && git commit -m "release: ' . escapeshellarg($version) . (!empty($versionEmoji) ? (' ' . $versionEmoji) : '') . '"');
|
||||||
|
|
||||||
|
// Git tag
|
||||||
|
runProcess("git tag -a \"$version\" -m \"Release $version\"");
|
||||||
|
runProcess("git tag -v \"$version\"");
|
||||||
|
|
||||||
|
// Git push
|
||||||
|
runProcess("git push origin master");
|
||||||
|
runProcess("git push origin $version");
|
||||||
|
|
||||||
|
out("\n- Release $version has been successfully prepared, committed and pushed!", 'success');
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -69,44 +69,44 @@ $order_by = '';
|
||||||
if ($view === 'username') {
|
if ($view === 'username') {
|
||||||
switch ($mode) {
|
switch ($mode) {
|
||||||
case 'username':
|
case 'username':
|
||||||
$order_by = 'ORDER BY u.username ' . $sort_order . ' LIMIT ' . $start . ', ' . $bb_cfg['topics_per_page'];
|
$order_by = 'ORDER BY u.username ' . $sort_order . ' LIMIT ' . $start . ', ' . config()->get('topics_per_page');
|
||||||
break;
|
break;
|
||||||
case 'attachments':
|
case 'attachments':
|
||||||
$order_by = 'ORDER BY total_attachments ' . $sort_order . ' LIMIT ' . $start . ', ' . $bb_cfg['topics_per_page'];
|
$order_by = 'ORDER BY total_attachments ' . $sort_order . ' LIMIT ' . $start . ', ' . config()->get('topics_per_page');
|
||||||
break;
|
break;
|
||||||
case 'filesize':
|
case 'filesize':
|
||||||
$order_by = 'ORDER BY total_size ' . $sort_order . ' LIMIT ' . $start . ', ' . $bb_cfg['topics_per_page'];
|
$order_by = 'ORDER BY total_size ' . $sort_order . ' LIMIT ' . $start . ', ' . config()->get('topics_per_page');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$mode = 'attachments';
|
$mode = 'attachments';
|
||||||
$sort_order = 'DESC';
|
$sort_order = 'DESC';
|
||||||
$order_by = 'ORDER BY total_attachments ' . $sort_order . ' LIMIT ' . $start . ', ' . $bb_cfg['topics_per_page'];
|
$order_by = 'ORDER BY total_attachments ' . $sort_order . ' LIMIT ' . $start . ', ' . config()->get('topics_per_page');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} elseif ($view === 'attachments') {
|
} elseif ($view === 'attachments') {
|
||||||
switch ($mode) {
|
switch ($mode) {
|
||||||
case 'real_filename':
|
case 'real_filename':
|
||||||
$order_by = 'ORDER BY a.real_filename ' . $sort_order . ' LIMIT ' . $start . ', ' . $bb_cfg['topics_per_page'];
|
$order_by = 'ORDER BY a.real_filename ' . $sort_order . ' LIMIT ' . $start . ', ' . config()->get('topics_per_page');
|
||||||
break;
|
break;
|
||||||
case 'comment':
|
case 'comment':
|
||||||
$order_by = 'ORDER BY a.comment ' . $sort_order . ' LIMIT ' . $start . ', ' . $bb_cfg['topics_per_page'];
|
$order_by = 'ORDER BY a.comment ' . $sort_order . ' LIMIT ' . $start . ', ' . config()->get('topics_per_page');
|
||||||
break;
|
break;
|
||||||
case 'extension':
|
case 'extension':
|
||||||
$order_by = 'ORDER BY a.extension ' . $sort_order . ' LIMIT ' . $start . ', ' . $bb_cfg['topics_per_page'];
|
$order_by = 'ORDER BY a.extension ' . $sort_order . ' LIMIT ' . $start . ', ' . config()->get('topics_per_page');
|
||||||
break;
|
break;
|
||||||
case 'filesize':
|
case 'filesize':
|
||||||
$order_by = 'ORDER BY a.filesize ' . $sort_order . ' LIMIT ' . $start . ', ' . $bb_cfg['topics_per_page'];
|
$order_by = 'ORDER BY a.filesize ' . $sort_order . ' LIMIT ' . $start . ', ' . config()->get('topics_per_page');
|
||||||
break;
|
break;
|
||||||
case 'downloads':
|
case 'downloads':
|
||||||
$order_by = 'ORDER BY a.download_count ' . $sort_order . ' LIMIT ' . $start . ', ' . $bb_cfg['topics_per_page'];
|
$order_by = 'ORDER BY a.download_count ' . $sort_order . ' LIMIT ' . $start . ', ' . config()->get('topics_per_page');
|
||||||
break;
|
break;
|
||||||
case 'post_time':
|
case 'post_time':
|
||||||
$order_by = 'ORDER BY a.filetime ' . $sort_order . ' LIMIT ' . $start . ', ' . $bb_cfg['topics_per_page'];
|
$order_by = 'ORDER BY a.filetime ' . $sort_order . ' LIMIT ' . $start . ', ' . config()->get('topics_per_page');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$mode = 'a.real_filename';
|
$mode = 'a.real_filename';
|
||||||
$sort_order = 'ASC';
|
$sort_order = 'ASC';
|
||||||
$order_by = 'ORDER BY a.real_filename ' . $sort_order . ' LIMIT ' . $start . ', ' . $bb_cfg['topics_per_page'];
|
$order_by = 'ORDER BY a.real_filename ' . $sort_order . ' LIMIT ' . $start . ', ' . config()->get('topics_per_page');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -422,11 +422,7 @@ if ($view === 'attachments') {
|
||||||
|
|
||||||
$row = DB()->sql_fetchrow($result);
|
$row = DB()->sql_fetchrow($result);
|
||||||
DB()->sql_freeresult($result);
|
DB()->sql_freeresult($result);
|
||||||
$post_title = $row['topic_title'];
|
$post_title = str_short($row['topic_title'], 30);
|
||||||
|
|
||||||
if (strlen($post_title) > 32) {
|
|
||||||
$post_title = str_short($post_title, 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
$view_topic = BB_ROOT . POST_URL . $ids[$j]['post_id'] . '#' . $ids[$j]['post_id'];
|
$view_topic = BB_ROOT . POST_URL . $ids[$j]['post_id'] . '#' . $ids[$j]['post_id'];
|
||||||
|
|
||||||
|
@ -474,8 +470,8 @@ if ($view === 'attachments') {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate Pagination
|
// Generate Pagination
|
||||||
if ($do_pagination && $total_rows > $bb_cfg['topics_per_page']) {
|
if ($do_pagination && $total_rows > config()->get('topics_per_page')) {
|
||||||
generate_pagination('admin_attach_cp.php?view=' . $view . '&mode=' . $mode . '&order=' . $sort_order . '&uid=' . $uid, $total_rows, $bb_cfg['topics_per_page'], $start);
|
generate_pagination('admin_attach_cp.php?view=' . $view . '&mode=' . $mode . '&order=' . $sort_order . '&uid=' . $uid, $total_rows, config()->get('topics_per_page'), $start);
|
||||||
}
|
}
|
||||||
|
|
||||||
print_page('admin_attach_cp.tpl', 'admin');
|
print_page('admin_attach_cp.tpl', 'admin');
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -61,6 +61,7 @@ switch ($mode) {
|
||||||
'CONFIG_MODS' => true,
|
'CONFIG_MODS' => true,
|
||||||
|
|
||||||
'MAGNET_LINKS_ENABLED' => $new['magnet_links_enabled'],
|
'MAGNET_LINKS_ENABLED' => $new['magnet_links_enabled'],
|
||||||
|
'MAGNET_LINKS_FOR_GUESTS' => $new['magnet_links_for_guests'],
|
||||||
'GENDER' => $new['gender'],
|
'GENDER' => $new['gender'],
|
||||||
'CALLSEED' => $new['callseed'],
|
'CALLSEED' => $new['callseed'],
|
||||||
'TOR_STATS' => $new['tor_stats'],
|
'TOR_STATS' => $new['tor_stats'],
|
||||||
|
@ -135,8 +136,8 @@ switch ($mode) {
|
||||||
'POSTS_PER_PAGE' => $new['posts_per_page'],
|
'POSTS_PER_PAGE' => $new['posts_per_page'],
|
||||||
'HOT_TOPIC' => $new['hot_threshold'],
|
'HOT_TOPIC' => $new['hot_threshold'],
|
||||||
'DEFAULT_DATEFORMAT' => $new['default_dateformat'],
|
'DEFAULT_DATEFORMAT' => $new['default_dateformat'],
|
||||||
'LANG_SELECT' => \TorrentPier\Legacy\Select::language($new['default_lang'], 'default_lang'),
|
'LANG_SELECT' => \TorrentPier\Legacy\Common\Select::language($new['default_lang'], 'default_lang'),
|
||||||
'TIMEZONE_SELECT' => \TorrentPier\Legacy\Select::timezone($new['board_timezone'], 'board_timezone'),
|
'TIMEZONE_SELECT' => \TorrentPier\Legacy\Common\Select::timezone($new['board_timezone'], 'board_timezone'),
|
||||||
'MAX_LOGIN_ATTEMPTS' => $new['max_login_attempts'],
|
'MAX_LOGIN_ATTEMPTS' => $new['max_login_attempts'],
|
||||||
'LOGIN_RESET_TIME' => $new['login_reset_time'],
|
'LOGIN_RESET_TIME' => $new['login_reset_time'],
|
||||||
'PRUNE_ENABLE' => (bool)$new['prune_enable'],
|
'PRUNE_ENABLE' => (bool)$new['prune_enable'],
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -188,7 +188,8 @@ switch ($mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($submit) {
|
if ($submit) {
|
||||||
if ($_POST['mode'] == 'list') {
|
$mode2 = $_POST['mode'] ?? '';
|
||||||
|
if ($mode2 == 'list') {
|
||||||
if ($cron_action == 'run' && $jobs) {
|
if ($cron_action == 'run' && $jobs) {
|
||||||
\TorrentPier\Legacy\Admin\Cron::run_jobs($jobs);
|
\TorrentPier\Legacy\Admin\Cron::run_jobs($jobs);
|
||||||
} elseif ($cron_action == 'delete' && $jobs) {
|
} elseif ($cron_action == 'delete' && $jobs) {
|
||||||
|
@ -198,12 +199,12 @@ if ($submit) {
|
||||||
}
|
}
|
||||||
redirect('admin/' . basename(__FILE__) . '?mode=list');
|
redirect('admin/' . basename(__FILE__) . '?mode=list');
|
||||||
} elseif (\TorrentPier\Legacy\Admin\Cron::validate_cron_post($_POST) == 1) {
|
} elseif (\TorrentPier\Legacy\Admin\Cron::validate_cron_post($_POST) == 1) {
|
||||||
if ($_POST['mode'] == 'edit') {
|
if ($mode2 == 'edit') {
|
||||||
\TorrentPier\Legacy\Admin\Cron::update_cron_job($_POST);
|
\TorrentPier\Legacy\Admin\Cron::update_cron_job($_POST);
|
||||||
} elseif ($_POST['mode'] == 'add') {
|
} elseif ($mode2 == 'add') {
|
||||||
\TorrentPier\Legacy\Admin\Cron::insert_cron_job($_POST);
|
\TorrentPier\Legacy\Admin\Cron::insert_cron_job($_POST);
|
||||||
} else {
|
} else {
|
||||||
bb_die('Mode error');
|
bb_die("Invalid mode: $mode2");
|
||||||
}
|
}
|
||||||
|
|
||||||
redirect('admin/' . basename(__FILE__) . '?mode=list');
|
redirect('admin/' . basename(__FILE__) . '?mode=list');
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -123,6 +123,7 @@ if ($submit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$datastore->update('cat_forums');
|
$datastore->update('cat_forums');
|
||||||
|
CACHE('bb_cache')->rm();
|
||||||
bb_die($lang['FORUM_AUTH_UPDATED'] . '<br /><br />' . sprintf($lang['CLICK_RETURN_FORUMAUTH'], '<a href="' . 'admin_forumauth.php' . '">', '</a>'));
|
bb_die($lang['FORUM_AUTH_UPDATED'] . '<br /><br />' . sprintf($lang['CLICK_RETURN_FORUMAUTH'], '<a href="' . 'admin_forumauth.php' . '">', '</a>'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -153,6 +153,7 @@ if ($submit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$datastore->update('cat_forums');
|
$datastore->update('cat_forums');
|
||||||
|
CACHE('bb_cache')->rm();
|
||||||
bb_die($lang['FORUM_AUTH_UPDATED'] . '<br /><br />' . sprintf($lang['CLICK_RETURN_FORUMAUTH'], '<a href="admin_forumauth_list.php">', '</a>'));
|
bb_die($lang['FORUM_AUTH_UPDATED'] . '<br /><br />' . sprintf($lang['CLICK_RETURN_FORUMAUTH'], '<a href="admin_forumauth_list.php">', '</a>'));
|
||||||
} // End of submit
|
} // End of submit
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -865,7 +865,7 @@ function get_list($mode, $id, $select)
|
||||||
if ($row[$idfield] == $id) {
|
if ($row[$idfield] == $id) {
|
||||||
$s = ' selected';
|
$s = ' selected';
|
||||||
}
|
}
|
||||||
$catlist .= '<option value="' . $row[$idfield] . '"' . $s . '> ' . htmlCHR(str_short($row[$namefield], 60)) . '</option>\n';
|
$catlist .= '<option value="' . $row[$idfield] . '"' . $s . '> ' . str_short(htmlCHR($row[$namefield]), 60) . '</option>\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $catlist;
|
return $catlist;
|
||||||
|
@ -1102,7 +1102,7 @@ function sf_get_list($mode, $exclude = 0, $select = 0)
|
||||||
$selected = ($fid == $select) ? HTML_SELECTED : '';
|
$selected = ($fid == $select) ? HTML_SELECTED : '';
|
||||||
$disabled = ($fid == $exclude && !$forum_parent) ? HTML_DISABLED : '';
|
$disabled = ($fid == $exclude && !$forum_parent) ? HTML_DISABLED : '';
|
||||||
$style = $disabled ? ' style="color: gray" ' : (($fid == $exclude) ? ' style="color: darkred" ' : '');
|
$style = $disabled ? ' style="color: gray" ' : (($fid == $exclude) ? ' style="color: darkred" ' : '');
|
||||||
$opt .= '<option value="' . $fid . '" ' . $selected . $disabled . $style . '>' . ($f['forum_parent'] ? HTML_SF_SPACER : '') . htmlCHR(str_short($f['forum_name'], 60)) . " </option>\n";
|
$opt .= '<option value="' . $fid . '" ' . $selected . $disabled . $style . '>' . ($f['forum_parent'] ? HTML_SF_SPACER : '') . str_short(htmlCHR($f['forum_name']), 60) . " </option>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
$opt .= '</optgroup>';
|
$opt .= '</optgroup>';
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -59,7 +59,7 @@ $def_forums = $all_forums;
|
||||||
$def_sort = $sort_desc;
|
$def_sort = $sort_desc;
|
||||||
|
|
||||||
// Moderators data
|
// Moderators data
|
||||||
if (!$mod = $datastore->get('moderators') and !$datastore->has('moderators')) {
|
if (!$mod = $datastore->get('moderators')) {
|
||||||
$datastore->update('moderators');
|
$datastore->update('moderators');
|
||||||
$mod = $datastore->get('moderators');
|
$mod = $datastore->get('moderators');
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ $users = array($lang['ACTS_LOG_ALL_ACTIONS'] => $all_users) + array_flip($mod['m
|
||||||
unset($mod);
|
unset($mod);
|
||||||
|
|
||||||
// Forums data
|
// Forums data
|
||||||
if (!$forums = $datastore->get('cat_forums') and !$datastore->has('cat_forums')) {
|
if (!$forums = $datastore->get('cat_forums')) {
|
||||||
$datastore->update('cat_forums');
|
$datastore->update('cat_forums');
|
||||||
$forums = $datastore->get('cat_forums');
|
$forums = $datastore->get('cat_forums');
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ if ($var =& $_REQUEST[$daysback_key] && $var != $def_days) {
|
||||||
$url = url_arg($url, $daysback_key, $daysback_val);
|
$url = url_arg($url, $daysback_key, $daysback_val);
|
||||||
}
|
}
|
||||||
if ($var =& $_REQUEST[$datetime_key] && $var != $def_datetime) {
|
if ($var =& $_REQUEST[$datetime_key] && $var != $def_datetime) {
|
||||||
$tz = TIMENOW + (3600 * $bb_cfg['board_timezone']);
|
$tz = TIMENOW + (3600 * config()->get('board_timezone'));
|
||||||
if (($tmp_timestamp = strtotime($var, $tz)) > 0) {
|
if (($tmp_timestamp = strtotime($var, $tz)) > 0) {
|
||||||
$datetime_val = $tmp_timestamp;
|
$datetime_val = $tmp_timestamp;
|
||||||
$url = url_arg($url, $datetime_key, date($dt_format, $datetime_val));
|
$url = url_arg($url, $datetime_key, date($dt_format, $datetime_val));
|
||||||
|
@ -225,6 +225,9 @@ if ($log_rowset) {
|
||||||
case $log_type['mod_topic_unlock']:
|
case $log_type['mod_topic_unlock']:
|
||||||
case $log_type['mod_topic_set_downloaded']:
|
case $log_type['mod_topic_set_downloaded']:
|
||||||
case $log_type['mod_topic_unset_downloaded']:
|
case $log_type['mod_topic_unset_downloaded']:
|
||||||
|
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_renamed']:
|
case $log_type['mod_topic_renamed']:
|
||||||
case $log_type['mod_post_delete']:
|
case $log_type['mod_post_delete']:
|
||||||
case $log_type['mod_post_pin']:
|
case $log_type['mod_post_pin']:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -14,7 +14,7 @@ if (!empty($setmodules)) {
|
||||||
|
|
||||||
require __DIR__ . '/pagestart.php';
|
require __DIR__ . '/pagestart.php';
|
||||||
|
|
||||||
if (!$bb_cfg['emailer']['enabled']) {
|
if (!config()->get('emailer.enabled')) {
|
||||||
bb_die($lang['EMAILER_DISABLED']);
|
bb_die($lang['EMAILER_DISABLED']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ set_time_limit(1200);
|
||||||
$subject = trim(request_var('subject', ''));
|
$subject = trim(request_var('subject', ''));
|
||||||
$message = (string)request_var('message', '');
|
$message = (string)request_var('message', '');
|
||||||
$group_id = (int)request_var(POST_GROUPS_URL, 0);
|
$group_id = (int)request_var(POST_GROUPS_URL, 0);
|
||||||
$reply_to = (string)request_var('reply_to', $bb_cfg['board_email']);
|
$reply_to = (string)request_var('reply_to', config()->get('board_email'));
|
||||||
$message_type = (string)request_var('message_type', '');
|
$message_type = (string)request_var('message_type', '');
|
||||||
|
|
||||||
$errors = $user_id_sql = [];
|
$errors = $user_id_sql = [];
|
||||||
|
@ -40,12 +40,7 @@ if (isset($_POST['submit'])) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$errors) {
|
if (!$errors) {
|
||||||
$sql = DB()->fetch_rowset('SELECT ban_userid FROM ' . BB_BANLIST . ' WHERE ban_userid != 0');
|
$banned_users = ($get_banned_users = get_banned_users()) ? (', ' . implode(', ', $get_banned_users)) : '';
|
||||||
|
|
||||||
foreach ($sql as $row) {
|
|
||||||
$user_id_sql[] = ',' . $row['ban_userid'];
|
|
||||||
}
|
|
||||||
$user_id_sql = implode('', $user_id_sql);
|
|
||||||
|
|
||||||
if ($group_id != -1) {
|
if ($group_id != -1) {
|
||||||
$user_list = DB()->fetch_rowset('
|
$user_list = DB()->fetch_rowset('
|
||||||
|
@ -55,14 +50,14 @@ if (isset($_POST['submit'])) {
|
||||||
AND ug.user_pending = 0
|
AND ug.user_pending = 0
|
||||||
AND u.user_id = ug.user_id
|
AND u.user_id = ug.user_id
|
||||||
AND u.user_active = 1
|
AND u.user_active = 1
|
||||||
AND u.user_id NOT IN(" . EXCLUDED_USERS . $user_id_sql . ')
|
AND u.user_id NOT IN(" . EXCLUDED_USERS . $banned_users . ')
|
||||||
');
|
');
|
||||||
} else {
|
} else {
|
||||||
$user_list = DB()->fetch_rowset('
|
$user_list = DB()->fetch_rowset('
|
||||||
SELECT username, user_email, user_lang
|
SELECT username, user_email, user_lang
|
||||||
FROM ' . BB_USERS . '
|
FROM ' . BB_USERS . '
|
||||||
WHERE user_active = 1
|
WHERE user_active = 1
|
||||||
AND user_id NOT IN(' . EXCLUDED_USERS . $user_id_sql . ')
|
AND user_id NOT IN(' . EXCLUDED_USERS . $banned_users . ')
|
||||||
');
|
');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
79
admin/admin_migrations.php
Normal file
79
admin/admin_migrations.php
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!empty($setmodules)) {
|
||||||
|
if (IS_SUPER_ADMIN) {
|
||||||
|
$module['GENERAL']['MIGRATIONS_STATUS'] = basename(__FILE__);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
require __DIR__ . '/pagestart.php';
|
||||||
|
|
||||||
|
if (!IS_SUPER_ADMIN) {
|
||||||
|
bb_die(__('ONLY_FOR_SUPER_ADMIN'));
|
||||||
|
}
|
||||||
|
|
||||||
|
use TorrentPier\Database\MigrationStatus;
|
||||||
|
|
||||||
|
// Initialize migration status
|
||||||
|
$migrationStatus = new MigrationStatus();
|
||||||
|
$status = $migrationStatus->getMigrationStatus();
|
||||||
|
$schemaInfo = $migrationStatus->getSchemaInfo();
|
||||||
|
|
||||||
|
// Template variables
|
||||||
|
$template->assign_vars([
|
||||||
|
'PAGE_TITLE' => __('MIGRATIONS_STATUS'),
|
||||||
|
'CURRENT_TIME' => date('Y-m-d H:i:s'),
|
||||||
|
|
||||||
|
// Migration status individual fields
|
||||||
|
'MIGRATION_TABLE_EXISTS' => $status['table_exists'],
|
||||||
|
'MIGRATION_CURRENT_VERSION' => $status['current_version'],
|
||||||
|
'MIGRATION_APPLIED_COUNT' => count($status['applied_migrations']),
|
||||||
|
'MIGRATION_PENDING_COUNT' => count($status['pending_migrations']),
|
||||||
|
|
||||||
|
// Setup status fields
|
||||||
|
'SETUP_REQUIRES_SETUP' => $status['requires_setup'] ?? false,
|
||||||
|
'SETUP_TYPE' => $status['setup_status']['type'] ?? __('UNKNOWN'),
|
||||||
|
'SETUP_MESSAGE' => $status['setup_status']['message'] ?? '',
|
||||||
|
'SETUP_ACTION_REQUIRED' => $status['setup_status']['action_required'] ?? false,
|
||||||
|
'SETUP_INSTRUCTIONS' => $status['setup_status']['instructions'] ?? '',
|
||||||
|
|
||||||
|
// Schema info individual fields
|
||||||
|
'SCHEMA_DATABASE_NAME' => $schemaInfo['database_name'],
|
||||||
|
'SCHEMA_TABLE_COUNT' => $schemaInfo['table_count'],
|
||||||
|
'SCHEMA_SIZE_MB' => $schemaInfo['size_mb'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Assign migration data for template
|
||||||
|
if (!empty($status['applied_migrations'])) {
|
||||||
|
foreach ($status['applied_migrations'] as $i => $migration) {
|
||||||
|
$template->assign_block_vars('applied_migrations', [
|
||||||
|
'VERSION' => $migration['version'],
|
||||||
|
'NAME' => $migration['migration_name'] ?? __('UNKNOWN'),
|
||||||
|
'START_TIME' => $migration['start_time'] ?? __('UNKNOWN'),
|
||||||
|
'END_TIME' => $migration['end_time'] ?? __('UNKNOWN'),
|
||||||
|
'ROW_CLASS' => ($i % 2) ? 'row1' : 'row2'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($status['pending_migrations'])) {
|
||||||
|
foreach ($status['pending_migrations'] as $i => $migration) {
|
||||||
|
$template->assign_block_vars('pending_migrations', [
|
||||||
|
'VERSION' => $migration['version'],
|
||||||
|
'NAME' => $migration['name'],
|
||||||
|
'FILENAME' => $migration['filename'],
|
||||||
|
'ROW_CLASS' => ($i % 2) ? 'row1' : 'row2'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output template using standard admin pattern
|
||||||
|
print_page('admin_migrations.tpl', 'admin');
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -29,6 +29,10 @@ if (isset($_GET['mode']) || isset($_POST['mode'])) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($mode == 'delete' && isset($_POST['cancel'])) {
|
||||||
|
$mode = '';
|
||||||
|
}
|
||||||
|
|
||||||
if ($mode != '') {
|
if ($mode != '') {
|
||||||
if ($mode == 'edit' || $mode == 'add') {
|
if ($mode == 'edit' || $mode == 'add') {
|
||||||
//
|
//
|
||||||
|
@ -83,7 +87,7 @@ if ($mode != '') {
|
||||||
// The rank image has to be a jpg, gif or png
|
// The rank image has to be a jpg, gif or png
|
||||||
//
|
//
|
||||||
if ($rank_image != '') {
|
if ($rank_image != '') {
|
||||||
if (!preg_match('/(\.gif|\.png|\.jpg|\.jpeg|\.bmp|\.webp|\.ico)$/is', $rank_image)) {
|
if (!preg_match('/(\.gif|\.png|\.jpg|\.jpeg|\.bmp|\.webp|\.avif\.ico)$/is', $rank_image)) {
|
||||||
$rank_image = '';
|
$rank_image = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,29 +127,40 @@ if ($mode != '') {
|
||||||
// Ok, they want to delete their rank
|
// Ok, they want to delete their rank
|
||||||
//
|
//
|
||||||
|
|
||||||
|
$confirmed = isset($_POST['confirm']);
|
||||||
if (isset($_POST['id']) || isset($_GET['id'])) {
|
if (isset($_POST['id']) || isset($_GET['id'])) {
|
||||||
$rank_id = isset($_POST['id']) ? (int)$_POST['id'] : (int)$_GET['id'];
|
$rank_id = isset($_POST['id']) ? (int)$_POST['id'] : (int)$_GET['id'];
|
||||||
} else {
|
} else {
|
||||||
$rank_id = 0;
|
$rank_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($rank_id) {
|
if ($confirmed) {
|
||||||
$sql = 'DELETE FROM ' . BB_RANKS . " WHERE rank_id = $rank_id";
|
if ($rank_id) {
|
||||||
|
$sql = 'DELETE FROM ' . BB_RANKS . " WHERE rank_id = $rank_id";
|
||||||
|
|
||||||
if (!$result = DB()->sql_query($sql)) {
|
if (!$result = DB()->sql_query($sql)) {
|
||||||
bb_die('Could not delete rank data');
|
bb_die('Could not delete rank data');
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = 'UPDATE ' . BB_USERS . " SET user_rank = 0 WHERE user_rank = $rank_id";
|
||||||
|
if (!$result = DB()->sql_query($sql)) {
|
||||||
|
bb_die($lang['NO_UPDATE_RANKS']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$datastore->update('ranks');
|
||||||
|
|
||||||
|
bb_die($lang['RANK_REMOVED'] . '<br /><br />' . sprintf($lang['CLICK_RETURN_RANKADMIN'], '<a href="admin_ranks.php">', '</a>') . '<br /><br />' . sprintf($lang['CLICK_RETURN_ADMIN_INDEX'], '<a href="index.php?pane=right">', '</a>'));
|
||||||
|
} else {
|
||||||
|
bb_die($lang['MUST_SELECT_RANK']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = 'UPDATE ' . BB_USERS . " SET user_rank = 0 WHERE user_rank = $rank_id";
|
|
||||||
if (!$result = DB()->sql_query($sql)) {
|
|
||||||
bb_die($lang['NO_UPDATE_RANKS']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$datastore->update('ranks');
|
|
||||||
|
|
||||||
bb_die($lang['RANK_REMOVED'] . '<br /><br />' . sprintf($lang['CLICK_RETURN_RANKADMIN'], '<a href="admin_ranks.php">', '</a>') . '<br /><br />' . sprintf($lang['CLICK_RETURN_ADMIN_INDEX'], '<a href="index.php?pane=right">', '</a>'));
|
|
||||||
} else {
|
} else {
|
||||||
bb_die($lang['MUST_SELECT_RANK']);
|
$hidden_fields = '<input type="hidden" name="mode" value="' . $mode . '" />';
|
||||||
|
$hidden_fields .= '<input type="hidden" name="id" value="' . $rank_id . '" />';
|
||||||
|
|
||||||
|
print_confirmation([
|
||||||
|
'FORM_ACTION' => 'admin_ranks.php',
|
||||||
|
'HIDDEN_FIELDS' => $hidden_fields,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bb_die('Invalid mode');
|
bb_die('Invalid mode');
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
|
45
admin/admin_robots.php
Normal file
45
admin/admin_robots.php
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!empty($setmodules)) {
|
||||||
|
$module['MODS']['ROBOTS_TXT_EDITOR_TITLE'] = basename(__FILE__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
require __DIR__ . '/pagestart.php';
|
||||||
|
|
||||||
|
$robots_file = BB_ROOT . 'robots.txt';
|
||||||
|
|
||||||
|
// Обработка сохранения
|
||||||
|
if (isset($_POST['save'])) {
|
||||||
|
$robots_txt = $_POST['robots_txt'] ?? '';
|
||||||
|
|
||||||
|
if (!is_writable($robots_file) && is_file($robots_file)) {
|
||||||
|
bb_die('File robots.txt is not writable #1');
|
||||||
|
}
|
||||||
|
|
||||||
|
$bytes = file_put_contents($robots_file, $robots_txt);
|
||||||
|
if ($bytes === false) {
|
||||||
|
bb_die('Could not write robots.txt #2');
|
||||||
|
}
|
||||||
|
|
||||||
|
bb_die($lang['ROBOTS_TXT_UPDATED_SUCCESSFULLY'] . '<br /><br />' . sprintf($lang['CLICK_RETURN_ROBOTS_TXT_CONFIG'], '<a href="admin_robots.php">', '</a>') . '<br /><br />' . sprintf($lang['CLICK_RETURN_ADMIN_INDEX'], '<a href="index.php?pane=right">', '</a>'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$current_content = '';
|
||||||
|
if (is_file($robots_file)) {
|
||||||
|
$current_content = file_get_contents($robots_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
$template->assign_vars([
|
||||||
|
'S_ACTION' => 'admin_robots.php',
|
||||||
|
'ROBOTS_TXT' => htmlCHR($current_content),
|
||||||
|
]);
|
||||||
|
|
||||||
|
print_page('admin_robots.tpl', 'admin');
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -14,7 +14,7 @@ if (!empty($setmodules)) {
|
||||||
|
|
||||||
require __DIR__ . '/pagestart.php';
|
require __DIR__ . '/pagestart.php';
|
||||||
|
|
||||||
$sql = 'SELECT * FROM ' . BB_CONFIG;
|
$sql = "SELECT * FROM " . BB_CONFIG . " WHERE config_name IN('sitemap_time', 'static_sitemap')";
|
||||||
|
|
||||||
if (!$result = DB()->sql_query($sql)) {
|
if (!$result = DB()->sql_query($sql)) {
|
||||||
bb_die('Could not query config information in admin_sitemap');
|
bb_die('Could not query config information in admin_sitemap');
|
||||||
|
@ -39,7 +39,7 @@ if (!$result = DB()->sql_query($sql)) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$s_mess = $lang['SITEMAP_CREATED'] . ': <b>' . bb_date($new['sitemap_time'], $bb_cfg['post_date_format']) . '</b> ' . $lang['SITEMAP_AVAILABLE'] . ': <a href="' . make_url('sitemap/sitemap.xml') . '" target="_blank">' . make_url('sitemap/sitemap.xml') . '</a>';
|
$s_mess = $lang['SITEMAP_CREATED'] . ': <b>' . bb_date($new['sitemap_time'], config()->get('post_date_format')) . '</b> ' . $lang['SITEMAP_AVAILABLE'] . ': <a href="' . make_url('sitemap/sitemap.xml') . '" target="_blank">' . make_url('sitemap/sitemap.xml') . '</a>';
|
||||||
$message = is_file(SITEMAP_DIR . '/sitemap.xml') ? $s_mess : $lang['SITEMAP_NOT_CREATED'];
|
$message = is_file(SITEMAP_DIR . '/sitemap.xml') ? $s_mess : $lang['SITEMAP_NOT_CREATED'];
|
||||||
|
|
||||||
$template->assign_vars([
|
$template->assign_vars([
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -22,7 +22,11 @@ if (isset($_POST['mode']) || isset($_GET['mode'])) {
|
||||||
$mode = '';
|
$mode = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$pathToSmilesDir = BB_ROOT . $bb_cfg['smilies_path'];
|
if ($mode == 'delete' && isset($_POST['cancel'])) {
|
||||||
|
$mode = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$pathToSmilesDir = BB_ROOT . config()->get('smilies_path');
|
||||||
$delimeter = '=+:';
|
$delimeter = '=+:';
|
||||||
$s_hidden_fields = '';
|
$s_hidden_fields = '';
|
||||||
$smiley_paks = $smiley_images = [];
|
$smiley_paks = $smiley_images = [];
|
||||||
|
@ -174,17 +178,28 @@ if (isset($_GET['import_pack']) || isset($_POST['import_pack'])) {
|
||||||
} elseif ($mode != '') {
|
} elseif ($mode != '') {
|
||||||
switch ($mode) {
|
switch ($mode) {
|
||||||
case 'delete':
|
case 'delete':
|
||||||
|
$confirmed = isset($_POST['confirm']);
|
||||||
$smiley_id = (!empty($_POST['id'])) ? $_POST['id'] : $_GET['id'];
|
$smiley_id = (!empty($_POST['id'])) ? $_POST['id'] : $_GET['id'];
|
||||||
$smiley_id = (int)$smiley_id;
|
$smiley_id = (int)$smiley_id;
|
||||||
|
|
||||||
$sql = 'DELETE FROM ' . BB_SMILIES . ' WHERE smilies_id = ' . $smiley_id;
|
if ($confirmed) {
|
||||||
$result = DB()->sql_query($sql);
|
$sql = 'DELETE FROM ' . BB_SMILIES . ' WHERE smilies_id = ' . $smiley_id;
|
||||||
if (!$result) {
|
$result = DB()->sql_query($sql);
|
||||||
bb_die('Could not delete smiley');
|
if (!$result) {
|
||||||
}
|
bb_die('Could not delete smiley');
|
||||||
$datastore->update('smile_replacements');
|
}
|
||||||
|
|
||||||
bb_die($lang['SMILEY_DEL_SUCCESS'] . '<br /><br />' . sprintf($lang['CLICK_RETURN_SMILEADMIN'], '<a href="admin_smilies.php">', '</a>') . '<br /><br />' . sprintf($lang['CLICK_RETURN_ADMIN_INDEX'], '<a href="index.php?pane=right">', '</a>'));
|
$datastore->update('smile_replacements');
|
||||||
|
bb_die($lang['SMILEY_DEL_SUCCESS'] . '<br /><br />' . sprintf($lang['CLICK_RETURN_SMILEADMIN'], '<a href="admin_smilies.php">', '</a>') . '<br /><br />' . sprintf($lang['CLICK_RETURN_ADMIN_INDEX'], '<a href="index.php?pane=right">', '</a>'));
|
||||||
|
} else {
|
||||||
|
$hidden_fields = '<input type="hidden" name="mode" value="' . $mode . '" />';
|
||||||
|
$hidden_fields .= '<input type="hidden" name="id" value="' . $smiley_id . '" />';
|
||||||
|
|
||||||
|
print_confirmation([
|
||||||
|
'FORM_ACTION' => 'admin_smilies.php',
|
||||||
|
'HIDDEN_FIELDS' => $hidden_fields,
|
||||||
|
]);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'edit':
|
case 'edit':
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -17,15 +17,15 @@ require INC_DIR . '/bbcode.php';
|
||||||
|
|
||||||
$preview = isset($_POST['preview']);
|
$preview = isset($_POST['preview']);
|
||||||
|
|
||||||
if (isset($_POST['post']) && ($bb_cfg['terms'] !== $_POST['message'])) {
|
if (isset($_POST['post']) && (config()->get('terms') !== $_POST['message'])) {
|
||||||
bb_update_config(['terms' => $_POST['message']]);
|
bb_update_config(['terms' => $_POST['message']]);
|
||||||
bb_die($lang['CONFIG_UPDATED']);
|
bb_die($lang['TERMS_UPDATED_SUCCESSFULLY'] . '<br /><br />' . sprintf($lang['CLICK_RETURN_TERMS_CONFIG'], '<a href="admin_terms.php">', '</a>') . '<br /><br />' . sprintf($lang['CLICK_RETURN_ADMIN_INDEX'], '<a href="index.php?pane=right">', '</a>'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$template->assign_vars([
|
$template->assign_vars([
|
||||||
'S_ACTION' => 'admin_terms.php',
|
'S_ACTION' => 'admin_terms.php',
|
||||||
'EXT_LINK_NW' => $bb_cfg['ext_link_new_win'],
|
'EXT_LINK_NW' => config()->get('ext_link_new_win'),
|
||||||
'MESSAGE' => $preview ? $_POST['message'] : $bb_cfg['terms'],
|
'MESSAGE' => $preview ? $_POST['message'] : config()->get('terms'),
|
||||||
'PREVIEW_HTML' => $preview ? bbcode2html($_POST['message']) : '',
|
'PREVIEW_HTML' => $preview ? bbcode2html($_POST['message']) : '',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -20,9 +20,9 @@ $max_forum_name_length = 50;
|
||||||
$yes_sign = '√';
|
$yes_sign = '√';
|
||||||
$no_sign = 'x';
|
$no_sign = 'x';
|
||||||
|
|
||||||
$group_id = isset($_REQUEST['g']) ? (int)$_REQUEST['g'] : 0;
|
$group_id = isset($_REQUEST[POST_GROUPS_URL]) ? (int)$_REQUEST[POST_GROUPS_URL] : 0;
|
||||||
$user_id = isset($_REQUEST['u']) ? (int)$_REQUEST['u'] : 0;
|
$user_id = isset($_REQUEST[POST_USERS_URL]) ? (int)$_REQUEST[POST_USERS_URL] : 0;
|
||||||
$cat_id = isset($_REQUEST['c']) ? (int)$_REQUEST['c'] : 0;
|
$cat_id = isset($_REQUEST[POST_CAT_URL]) ? (int)$_REQUEST[POST_CAT_URL] : 0;
|
||||||
$mode = isset($_REQUEST['mode']) ? (string)$_REQUEST['mode'] : '';
|
$mode = isset($_REQUEST['mode']) ? (string)$_REQUEST['mode'] : '';
|
||||||
$submit = isset($_REQUEST['submit']);
|
$submit = isset($_REQUEST['submit']);
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ if ($mode == 'user' && (!empty($_POST['username']) || $user_id)) {
|
||||||
bb_die($lang['NO_SUCH_USER']);
|
bb_die($lang['NO_SUCH_USER']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$forums = $datastore->get('cat_forums') and !$datastore->has('cat_forums')) {
|
if (!$forums = $datastore->get('cat_forums')) {
|
||||||
$datastore->update('cat_forums');
|
$datastore->update('cat_forums');
|
||||||
$forums = $datastore->get('cat_forums');
|
$forums = $datastore->get('cat_forums');
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ if ($mode == 'user' && (!empty($_POST['username']) || $user_id)) {
|
||||||
'CAT_HREF' => "$base_url&" . POST_CAT_URL . "=$c_id",
|
'CAT_HREF' => "$base_url&" . POST_CAT_URL . "=$c_id",
|
||||||
));
|
));
|
||||||
|
|
||||||
if (!$c =& $_REQUEST['c'] or !in_array($c, array('all', $c_id)) or empty($c_data['forums'])) {
|
if (!$c =& $_REQUEST[POST_CAT_URL] or !in_array($c, array('all', $c_id)) or empty($c_data['forums'])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ if ($mode == 'user' && (!empty($_POST['username']) || $user_id)) {
|
||||||
bb_die($lang['GROUP_NOT_EXIST']);
|
bb_die($lang['GROUP_NOT_EXIST']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$forums = $datastore->get('cat_forums') and !$datastore->has('cat_forums')) {
|
if (!$forums = $datastore->get('cat_forums')) {
|
||||||
$datastore->update('cat_forums');
|
$datastore->update('cat_forums');
|
||||||
$forums = $datastore->get('cat_forums');
|
$forums = $datastore->get('cat_forums');
|
||||||
}
|
}
|
||||||
|
@ -316,7 +316,7 @@ if ($mode == 'user' && (!empty($_POST['username']) || $user_id)) {
|
||||||
'CAT_HREF' => "$base_url&" . POST_CAT_URL . "=$c_id",
|
'CAT_HREF' => "$base_url&" . POST_CAT_URL . "=$c_id",
|
||||||
));
|
));
|
||||||
|
|
||||||
if (!($c =& $_REQUEST['c']) || !in_array($c, array('all', $c_id)) || empty($c_data['forums'])) {
|
if (!($c =& $_REQUEST[POST_CAT_URL]) || !in_array($c, array('all', $c_id)) || empty($c_data['forums'])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -52,8 +52,8 @@ if (!isset($_REQUEST['dosearch'])) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$language_list = \TorrentPier\Legacy\Select::language('', 'language_type');
|
$language_list = \TorrentPier\Legacy\Common\Select::language('', 'language_type');
|
||||||
$timezone_list = \TorrentPier\Legacy\Select::timezone('', 'timezone_type');
|
$timezone_list = \TorrentPier\Legacy\Common\Select::timezone('', 'timezone_type');
|
||||||
|
|
||||||
$sql = 'SELECT f.forum_id, f.forum_name, f.forum_parent, c.cat_id, c.cat_title
|
$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 )
|
FROM ( ' . BB_FORUMS . ' AS f INNER JOIN ' . BB_CATEGORIES . ' AS c ON c.cat_id = f.cat_id )
|
||||||
|
@ -252,8 +252,7 @@ if (!isset($_REQUEST['dosearch'])) {
|
||||||
|
|
||||||
$text = sprintf($lang['SEARCH_FOR_USERNAME'], strip_tags(htmlspecialchars(stripslashes($username))));
|
$text = sprintf($lang['SEARCH_FOR_USERNAME'], strip_tags(htmlspecialchars(stripslashes($username))));
|
||||||
|
|
||||||
$username = str_replace("\*", '%', trim(strip_tags(strtolower($username))));
|
$username = str_replace('*', '%', trim(strip_tags(strtolower($username))));
|
||||||
|
|
||||||
if (str_contains($username, '%')) {
|
if (str_contains($username, '%')) {
|
||||||
$op = 'LIKE';
|
$op = 'LIKE';
|
||||||
} else {
|
} else {
|
||||||
|
@ -273,8 +272,7 @@ if (!isset($_REQUEST['dosearch'])) {
|
||||||
|
|
||||||
$text = sprintf($lang['SEARCH_FOR_EMAIL'], strip_tags(htmlspecialchars(stripslashes($email))));
|
$text = sprintf($lang['SEARCH_FOR_EMAIL'], strip_tags(htmlspecialchars(stripslashes($email))));
|
||||||
|
|
||||||
$email = str_replace("\*", '%', trim(strip_tags(strtolower($email))));
|
$email = str_replace('*', '%', trim(strip_tags(strtolower($email))));
|
||||||
|
|
||||||
if (str_contains($email, '%')) {
|
if (str_contains($email, '%')) {
|
||||||
$op = 'LIKE';
|
$op = 'LIKE';
|
||||||
} else {
|
} else {
|
||||||
|
@ -568,8 +566,7 @@ if (!isset($_REQUEST['dosearch'])) {
|
||||||
|
|
||||||
$text = strip_tags(htmlspecialchars(stripslashes($userfield_value)));
|
$text = strip_tags(htmlspecialchars(stripslashes($userfield_value)));
|
||||||
|
|
||||||
$userfield_value = str_replace("\*", '%', trim(strip_tags(strtolower($userfield_value))));
|
$userfield_value = str_replace('*', '%', trim(strip_tags(strtolower($userfield_value))));
|
||||||
|
|
||||||
if (str_contains($userfield_value, '%')) {
|
if (str_contains($userfield_value, '%')) {
|
||||||
$op = 'LIKE';
|
$op = 'LIKE';
|
||||||
} else {
|
} else {
|
||||||
|
@ -844,10 +841,10 @@ if (!isset($_REQUEST['dosearch'])) {
|
||||||
if ($page == 1) {
|
if ($page == 1) {
|
||||||
$offset = 0;
|
$offset = 0;
|
||||||
} else {
|
} else {
|
||||||
$offset = (($page - 1) * $bb_cfg['topics_per_page']);
|
$offset = (($page - 1) * config()->get('topics_per_page'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$limit = "LIMIT $offset, " . $bb_cfg['topics_per_page'];
|
$limit = "LIMIT $offset, " . config()->get('topics_per_page');
|
||||||
|
|
||||||
$select_sql .= " $limit";
|
$select_sql .= " $limit";
|
||||||
|
|
||||||
|
@ -862,7 +859,7 @@ if (!isset($_REQUEST['dosearch'])) {
|
||||||
bb_die($lang['SEARCH_NO_RESULTS']);
|
bb_die($lang['SEARCH_NO_RESULTS']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$num_pages = ceil($total_pages['total'] / $bb_cfg['topics_per_page']);
|
$num_pages = ceil($total_pages['total'] / config()->get('topics_per_page'));
|
||||||
|
|
||||||
$pagination = '';
|
$pagination = '';
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -14,8 +14,8 @@ if (!empty($setmodules)) {
|
||||||
|
|
||||||
require __DIR__ . '/pagestart.php';
|
require __DIR__ . '/pagestart.php';
|
||||||
|
|
||||||
if (!$bb_cfg['use_word_censor']) {
|
if (!config()->get('use_word_censor')) {
|
||||||
bb_die('Word censor disabled <br /><br /> ($bb_cfg[\'use_word_censor\'] in config.php)');
|
bb_die('Word censor disabled <br /><br /> (use_word_censor in config.php)');
|
||||||
}
|
}
|
||||||
|
|
||||||
$mode = request_var('mode', '');
|
$mode = request_var('mode', '');
|
||||||
|
@ -81,6 +81,7 @@ if ($mode != '') {
|
||||||
}
|
}
|
||||||
|
|
||||||
$datastore->update('censor');
|
$datastore->update('censor');
|
||||||
|
censor()->reload(); // Reload the singleton instance with updated words
|
||||||
$message .= '<br /><br />' . sprintf($lang['CLICK_RETURN_WORDADMIN'], '<a href="admin_words.php">', '</a>') . '<br /><br />' . sprintf($lang['CLICK_RETURN_ADMIN_INDEX'], '<a href="index.php?pane=right">', '</a>');
|
$message .= '<br /><br />' . sprintf($lang['CLICK_RETURN_WORDADMIN'], '<a href="admin_words.php">', '</a>') . '<br /><br />' . sprintf($lang['CLICK_RETURN_ADMIN_INDEX'], '<a href="index.php?pane=right">', '</a>');
|
||||||
|
|
||||||
bb_die($message);
|
bb_die($message);
|
||||||
|
@ -95,6 +96,7 @@ if ($mode != '') {
|
||||||
}
|
}
|
||||||
|
|
||||||
$datastore->update('censor');
|
$datastore->update('censor');
|
||||||
|
censor()->reload(); // Reload the singleton instance with updated words
|
||||||
|
|
||||||
bb_die($lang['WORD_REMOVED'] . '<br /><br />' . sprintf($lang['CLICK_RETURN_WORDADMIN'], '<a href="admin_words.php">', '</a>') . '<br /><br />' . sprintf($lang['CLICK_RETURN_ADMIN_INDEX'], '<a href="index.php?pane=right">', '</a>'));
|
bb_die($lang['WORD_REMOVED'] . '<br /><br />' . sprintf($lang['CLICK_RETURN_WORDADMIN'], '<a href="admin_words.php">', '</a>') . '<br /><br />' . sprintf($lang['CLICK_RETURN_ADMIN_INDEX'], '<a href="index.php?pane=right">', '</a>'));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -10,19 +10,13 @@
|
||||||
require __DIR__ . '/pagestart.php';
|
require __DIR__ . '/pagestart.php';
|
||||||
|
|
||||||
// Statistics
|
// Statistics
|
||||||
if (!$stats = $datastore->get('stats') and !$datastore->has('stats')) {
|
if (!$stats = $datastore->get('stats')) {
|
||||||
$datastore->update('stats');
|
$datastore->update('stats');
|
||||||
$stats = $datastore->get('stats');
|
$stats = $datastore->get('stats');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Files integrity check
|
|
||||||
if (!$files_integrity_data = $datastore->get('files_integrity') and !$datastore->has('files_integrity')) {
|
|
||||||
$datastore->update('files_integrity');
|
|
||||||
$files_integrity_data = $datastore->get('files_integrity');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for updates
|
// Check for updates
|
||||||
if (!$update_data = $datastore->get('check_updates') and !$datastore->has('check_updates')) {
|
if (!$update_data = $datastore->get('check_updates')) {
|
||||||
$datastore->update('check_updates');
|
$datastore->update('check_updates');
|
||||||
$update_data = $datastore->get('check_updates');
|
$update_data = $datastore->get('check_updates');
|
||||||
}
|
}
|
||||||
|
@ -84,20 +78,10 @@ if (isset($_GET['pane']) && $_GET['pane'] == 'left') {
|
||||||
} elseif (isset($_GET['pane']) && $_GET['pane'] == 'right') {
|
} elseif (isset($_GET['pane']) && $_GET['pane'] == 'right') {
|
||||||
$template->assign_vars([
|
$template->assign_vars([
|
||||||
'TPL_ADMIN_MAIN' => true,
|
'TPL_ADMIN_MAIN' => true,
|
||||||
'ADMIN_LOCK' => (bool)$bb_cfg['board_disable'],
|
'ADMIN_LOCK' => (bool)config()->get('board_disable'),
|
||||||
'ADMIN_LOCK_CRON' => is_file(BB_DISABLED),
|
'ADMIN_LOCK_CRON' => is_file(BB_DISABLED),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Files integrity check results
|
|
||||||
if (!empty($files_integrity_data)) {
|
|
||||||
$template->assign_block_vars('integrity_check', [
|
|
||||||
'INTEGRITY_SUCCESS' => (bool)$files_integrity_data['success'],
|
|
||||||
'INTEGRITY_WRONG_FILES_LIST' => implode("\n</li>\n<li>\n", $files_integrity_data['wrong_files']),
|
|
||||||
'INTEGRITY_LAST_CHECK_TIME' => sprintf($lang['INTEGRITY_LAST_CHECK'], bb_date($files_integrity_data['timestamp'])),
|
|
||||||
'INTEGRITY_CHECKED_FILES' => sprintf($lang['INTEGRITY_CHECKED'], $files_integrity_data['total_num'], ($files_integrity_data['total_num'] - $files_integrity_data['wrong_files_num'])),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for updates
|
// Check for updates
|
||||||
if (isset($update_data['available_update'])) {
|
if (isset($update_data['available_update'])) {
|
||||||
$template->assign_block_vars('updater', [
|
$template->assign_block_vars('updater', [
|
||||||
|
@ -106,7 +90,7 @@ if (isset($_GET['pane']) && $_GET['pane'] == 'left') {
|
||||||
'NEW_VERSION_SIZE' => $update_data['latest_version_size'],
|
'NEW_VERSION_SIZE' => $update_data['latest_version_size'],
|
||||||
'NEW_VERSION_DL_LINK' => $update_data['latest_version_dl_link'],
|
'NEW_VERSION_DL_LINK' => $update_data['latest_version_dl_link'],
|
||||||
'NEW_VERSION_LINK' => $update_data['latest_version_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']
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,8 +98,8 @@ if (isset($_GET['pane']) && $_GET['pane'] == 'left') {
|
||||||
$total_posts = $stats['postcount'];
|
$total_posts = $stats['postcount'];
|
||||||
$total_topics = $stats['topiccount'];
|
$total_topics = $stats['topiccount'];
|
||||||
$total_users = $stats['usercount'];
|
$total_users = $stats['usercount'];
|
||||||
$start_date = bb_date($bb_cfg['board_startdate']);
|
$start_date = bb_date(config()->get('board_startdate'));
|
||||||
$boarddays = (TIMENOW - $bb_cfg['board_startdate']) / 86400;
|
$boarddays = (TIMENOW - config()->get('board_startdate')) / 86400;
|
||||||
|
|
||||||
$posts_per_day = sprintf('%.2f', $total_posts / $boarddays);
|
$posts_per_day = sprintf('%.2f', $total_posts / $boarddays);
|
||||||
$topics_per_day = sprintf('%.2f', $total_topics / $boarddays);
|
$topics_per_day = sprintf('%.2f', $total_topics / $boarddays);
|
||||||
|
@ -123,10 +107,10 @@ if (isset($_GET['pane']) && $_GET['pane'] == 'left') {
|
||||||
|
|
||||||
$avatar_dir_size = 0;
|
$avatar_dir_size = 0;
|
||||||
|
|
||||||
if ($avatar_dir = opendir($bb_cfg['avatars']['upload_path'])) {
|
if ($avatar_dir = opendir(config()->get('avatars.upload_path'))) {
|
||||||
while ($file = readdir($avatar_dir)) {
|
while ($file = readdir($avatar_dir)) {
|
||||||
if ($file != '.' && $file != '..') {
|
if ($file != '.' && $file != '..') {
|
||||||
$avatar_dir_size += @filesize($bb_cfg['avatars']['upload_path'] . $file);
|
$avatar_dir_size += @filesize(config()->get('avatars.upload_path') . $file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir($avatar_dir);
|
closedir($avatar_dir);
|
||||||
|
@ -203,7 +187,7 @@ if (isset($_GET['pane']) && $_GET['pane'] == 'left') {
|
||||||
'STARTED' => bb_date($onlinerow_reg[$i]['session_start'], 'd-M-Y H:i', false),
|
'STARTED' => bb_date($onlinerow_reg[$i]['session_start'], 'd-M-Y H:i', false),
|
||||||
'LASTUPDATE' => bb_date($onlinerow_reg[$i]['user_session_time'], 'd-M-Y H:i', false),
|
'LASTUPDATE' => bb_date($onlinerow_reg[$i]['user_session_time'], 'd-M-Y H:i', false),
|
||||||
'IP_ADDRESS' => $reg_ip,
|
'IP_ADDRESS' => $reg_ip,
|
||||||
'U_WHOIS_IP' => $bb_cfg['whois_info'] . $reg_ip,
|
'U_WHOIS_IP' => config()->get('whois_info') . $reg_ip,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,7 +206,7 @@ if (isset($_GET['pane']) && $_GET['pane'] == 'left') {
|
||||||
'STARTED' => bb_date($onlinerow_guest[$i]['session_start'], 'd-M-Y H:i', false),
|
'STARTED' => bb_date($onlinerow_guest[$i]['session_start'], 'd-M-Y H:i', false),
|
||||||
'LASTUPDATE' => bb_date($onlinerow_guest[$i]['session_time'], 'd-M-Y H:i', false),
|
'LASTUPDATE' => bb_date($onlinerow_guest[$i]['session_time'], 'd-M-Y H:i', false),
|
||||||
'IP_ADDRESS' => $guest_ip,
|
'IP_ADDRESS' => $guest_ip,
|
||||||
'U_WHOIS_IP' => $bb_cfg['whois_info'] . $guest_ip,
|
'U_WHOIS_IP' => config()->get('whois_info') . $guest_ip,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,7 +218,7 @@ if (isset($_GET['pane']) && $_GET['pane'] == 'left') {
|
||||||
} else {
|
} else {
|
||||||
// Generate frameset
|
// Generate frameset
|
||||||
$template->assign_vars([
|
$template->assign_vars([
|
||||||
'CONTENT_ENCODING' => $bb_cfg['charset'],
|
'CONTENT_ENCODING' => DEFAULT_CHARSET,
|
||||||
'TPL_ADMIN_FRAMESET' => true,
|
'TPL_ADMIN_FRAMESET' => true,
|
||||||
]);
|
]);
|
||||||
send_no_cache_headers();
|
send_no_cache_headers();
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -31,7 +31,8 @@ echo '<html><body><head></head>';
|
||||||
echo '<br /><br /><table border="1" cellspacing="0" cellpadding="6" align="center">';
|
echo '<br /><br /><table border="1" cellspacing="0" cellpadding="6" align="center">';
|
||||||
|
|
||||||
foreach ($sql as $i => $query) {
|
foreach ($sql as $i => $query) {
|
||||||
$row = mysqli_fetch_row(DB()->query($query))[0];
|
$result = DB()->fetch_row($query);
|
||||||
|
$row = array_values($result)[0]; // Get first column value
|
||||||
$row = ($i == 2) ? humn_size($row) : $row;
|
$row = ($i == 2) ? humn_size($row) : $row;
|
||||||
echo "<tr><td>{$lang['TR_STATS'][$i]}</td><td><b>$row</b></td>";
|
echo "<tr><td>{$lang['TR_STATS'][$i]}</td><td><b>$row</b></td>";
|
||||||
}
|
}
|
||||||
|
@ -39,7 +40,7 @@ foreach ($sql as $i => $query) {
|
||||||
echo '</table>';
|
echo '</table>';
|
||||||
echo '<div align="center"><pre>';
|
echo '<div align="center"><pre>';
|
||||||
|
|
||||||
echo 'gen time: <b>' . sprintf('%.4f', array_sum(explode(' ', microtime())) - TIMESTART) . "</b> sec\n";
|
echo 'gen time: <b>' . sprintf('%.3f', array_sum(explode(' ', microtime())) - TIMESTART) . "</b> sec\n";
|
||||||
|
|
||||||
echo '</pre></div>';
|
echo '</pre></div>';
|
||||||
echo '</body></html>';
|
echo '</body></html>';
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -21,7 +21,7 @@ if (!IS_ADMIN) {
|
||||||
$peers_in_last_minutes = [30, 15, 5, 1];
|
$peers_in_last_minutes = [30, 15, 5, 1];
|
||||||
$peers_in_last_sec_limit = 300;
|
$peers_in_last_sec_limit = 300;
|
||||||
|
|
||||||
$announce_interval = (int)$bb_cfg['announce_interval'];
|
$announce_interval = (int)config()->get('announce_interval');
|
||||||
$stat = [];
|
$stat = [];
|
||||||
|
|
||||||
define('TMP_TRACKER_TABLE', 'tmp_tracker');
|
define('TMP_TRACKER_TABLE', 'tmp_tracker');
|
||||||
|
@ -116,7 +116,7 @@ if ($client_full || !$stats_cache = CACHE('tr_cache')->get('tracker_clients_stat
|
||||||
|
|
||||||
$n = 1;
|
$n = 1;
|
||||||
foreach (array_slice($clients_percentage, 0, $numwant) as $client => $value) {
|
foreach (array_slice($clients_percentage, 0, $numwant) as $client => $value) {
|
||||||
$client_list .= ($client_full) ? ("$client => $value<br>") : "$n. " . get_user_torrent_client($client) . " $value<br>";
|
$client_list .= ($client_full) ? ("$client => $value<br/>") : "$n. " . get_user_torrent_client($client) . " $value<br/>";
|
||||||
$n++;
|
$n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,16 +164,16 @@ echo "\n
|
||||||
<td align=center>
|
<td align=center>
|
||||||
|
|
||||||
$client_list
|
$client_list
|
||||||
<br>
|
<br/>
|
||||||
\n";
|
\n";
|
||||||
echo (count($clients_percentage) > $numwant) ? ('<a href="' . 'tracker.php?client_numwant=' . ($numwant + 100) . '">' . 'Show more' . '</a><br>') : '';
|
echo (count($clients_percentage) > $numwant) ? ('<a href="' . 'tracker.php?client_numwant=' . ($numwant + 100) . '">' . 'Show more' . '</a><br/>') : '';
|
||||||
echo $client_full ? '<br><b>Get more length and numbers via modifying the parameters in the url<b>' : (!empty($client_list) ? '<a href="tracker.php?client_length=6&client_numwant=10">Peer_ids with more length (version debugging)</a>' : '');
|
echo $client_full ? '<br/><b>Get more length and numbers via modifying the parameters in the url<b>' : (!empty($client_list) ? '<a href="tracker.php?client_length=6&client_numwant=10">Peer_ids with more length (version debugging)</a>' : '');
|
||||||
echo '</td></tr>';
|
echo '</td></tr>';
|
||||||
echo '</table>';
|
echo '</table>';
|
||||||
echo !$client_full ? '<p style = "text-align:right;">Simple stats for clients are being cached for one hour.</p>' : '';
|
echo !$client_full ? '<p style = "text-align:right;">Simple stats for clients are being cached for one hour.</p>' : '';
|
||||||
echo '<div align="center"><pre>';
|
echo '<div align="center"><pre>';
|
||||||
|
|
||||||
echo 'gen time: <b>' . sprintf('%.4f', array_sum(explode(' ', microtime())) - TIMESTART) . "</b> sec\n";
|
echo 'gen time: <b>' . sprintf('%.3f', array_sum(explode(' ', microtime())) - TIMESTART) . "</b> sec\n";
|
||||||
echo '</pre></div>';
|
echo '</pre></div>';
|
||||||
echo '</body></html>';
|
echo '</body></html>';
|
||||||
|
|
||||||
|
|
4
ajax.php
4
ajax.php
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -41,5 +41,5 @@ $ajax->exec();
|
||||||
/**
|
/**
|
||||||
* @deprecated ajax_common
|
* @deprecated ajax_common
|
||||||
* Dirty class removed from here since 2.2.0
|
* Dirty class removed from here since 2.2.0
|
||||||
* To add new actions see at src/Legacy/Ajax.php
|
* To add new actions see at src/Ajax.php
|
||||||
*/
|
*/
|
||||||
|
|
169
bt/announce.php
169
bt/announce.php
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -11,15 +11,15 @@ define('IN_TRACKER', true);
|
||||||
define('BB_ROOT', './../');
|
define('BB_ROOT', './../');
|
||||||
require dirname(__DIR__) . '/common.php';
|
require dirname(__DIR__) . '/common.php';
|
||||||
|
|
||||||
global $bb_cfg;
|
// Check User-Agent for existence
|
||||||
|
$userAgent = (string)$_SERVER['HTTP_USER_AGENT'];
|
||||||
if (empty($_SERVER['HTTP_USER_AGENT'])) {
|
if (empty($userAgent)) {
|
||||||
header('Location: http://127.0.0.1', true, 301);
|
header('Location: http://127.0.0.1', true, 301);
|
||||||
die;
|
die;
|
||||||
}
|
}
|
||||||
|
|
||||||
$announce_interval = $bb_cfg['announce_interval'];
|
$announce_interval = config()->get('announce_interval');
|
||||||
$passkey_key = $bb_cfg['passkey_key'];
|
$passkey_key = config()->get('passkey_key');
|
||||||
|
|
||||||
// Recover info_hash
|
// Recover info_hash
|
||||||
if (isset($_GET['?info_hash']) && !isset($_GET['info_hash'])) {
|
if (isset($_GET['?info_hash']) && !isset($_GET['info_hash'])) {
|
||||||
|
@ -65,10 +65,26 @@ if (strlen($peer_id) !== 20) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for client ban
|
// Check for client ban
|
||||||
if ($bb_cfg['client_ban']['enabled']) {
|
if (config()->get('client_ban.enabled')) {
|
||||||
foreach ($bb_cfg['client_ban']['clients'] as $clientId => $reason) {
|
$targetClient = [];
|
||||||
|
|
||||||
|
foreach (config()->get('client_ban.clients') as $clientId => $banReason) {
|
||||||
if (str_starts_with($peer_id, $clientId)) {
|
if (str_starts_with($peer_id, $clientId)) {
|
||||||
msg_die($reason);
|
$targetClient = [
|
||||||
|
'peer_id' => $clientId,
|
||||||
|
'ban_reason' => $banReason
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config()->get('client_ban.only_allow_mode')) {
|
||||||
|
if (empty($targetClient['peer_id'])) {
|
||||||
|
msg_die('Your BitTorrent client has been banned!');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!empty($targetClient['peer_id'])) {
|
||||||
|
msg_die(empty($targetClient['ban_reason']) ? 'Your BitTorrent client has been banned!' : $targetClient['ban_reason']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,44 +94,87 @@ if (!isset($info_hash)) {
|
||||||
msg_die('info_hash was not provided');
|
msg_die('info_hash was not provided');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify event
|
||||||
|
*
|
||||||
|
* @see https://github.com/HDInnovations/UNIT3D-Community-Edition/blob/c64275f0b5dcb3c4c845d5204871adfe24f359d6/app/Http/Controllers/AnnounceController.php#L275
|
||||||
|
*/
|
||||||
|
$event = strtolower((string)$event);
|
||||||
|
if (!in_array($event, ['started', 'completed', 'stopped', 'paused', ''])) {
|
||||||
|
msg_die('Invalid event: ' . $event);
|
||||||
|
}
|
||||||
|
|
||||||
// Store info hash in hex format
|
// Store info hash in hex format
|
||||||
$info_hash_hex = bin2hex($info_hash);
|
$info_hash_hex = bin2hex($info_hash);
|
||||||
|
|
||||||
// Store peer id
|
// Store peer id
|
||||||
$peer_id_sql = preg_replace('/[^a-zA-Z0-9\-\_]/', '', $peer_id);
|
$peer_id_sql = preg_replace('/[^a-zA-Z0-9\-\_]/', '', $peer_id);
|
||||||
|
|
||||||
|
// Stopped event
|
||||||
|
$stopped = ($event === 'stopped');
|
||||||
|
|
||||||
// Check info_hash length
|
// Check info_hash length
|
||||||
if (strlen($info_hash) !== 20) {
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($port) || $port < 0 || $port > 0xFFFF) {
|
/**
|
||||||
|
* Block system-reserved ports since 99.9% of the time they're fake and thus not connectable
|
||||||
|
* Some clients will send port of 0 on 'stopped' events. Let them through as they won't receive peers anyway.
|
||||||
|
*
|
||||||
|
* @see https://github.com/HDInnovations/UNIT3D-Community-Edition/blob/c64275f0b5dcb3c4c845d5204871adfe24f359d6/app/Http/Controllers/AnnounceController.php#L284
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
!isset($port)
|
||||||
|
|| !is_numeric($port)
|
||||||
|
|| ($port < 1024 && !$stopped)
|
||||||
|
|| $port > 0xFFFF
|
||||||
|
|| (!empty(config()->get('disallowed_ports')) && in_array($port, config()->get('disallowed_ports')))
|
||||||
|
) {
|
||||||
msg_die('Invalid port: ' . $port);
|
msg_die('Invalid port: ' . $port);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($uploaded) || $uploaded < 0) {
|
if (!isset($uploaded) || !is_numeric($uploaded) || $uploaded < 0) {
|
||||||
msg_die('Invalid uploaded value: ' . $uploaded);
|
msg_die('Invalid uploaded value: ' . $uploaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($downloaded) || $downloaded < 0) {
|
if (!isset($downloaded) || !is_numeric($downloaded) || $downloaded < 0) {
|
||||||
msg_die('Invalid downloaded value: ' . $downloaded);
|
msg_die('Invalid downloaded value: ' . $downloaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($left) || $left < 0) {
|
if (!isset($left) || !is_numeric($left) || $left < 0) {
|
||||||
msg_die('Invalid left value: ' . $left);
|
msg_die('Invalid left value: ' . $left);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check User-Agent length
|
||||||
|
*
|
||||||
|
* @see https://github.com/HDInnovations/UNIT3D-Community-Edition/blob/c64275f0b5dcb3c4c845d5204871adfe24f359d6/app/Http/Controllers/AnnounceController.php#L177
|
||||||
|
*/
|
||||||
|
if (strlen($userAgent) > 64) {
|
||||||
|
msg_die('User-Agent must be less than 64 characters long');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Block Browser by checking the User-Agent
|
||||||
|
*
|
||||||
|
* @see https://github.com/HDInnovations/UNIT3D-Community-Edition/blob/c64275f0b5dcb3c4c845d5204871adfe24f359d6/app/Http/Controllers/AnnounceController.php#L182
|
||||||
|
*/
|
||||||
|
if (preg_match('/(Mozilla|Browser|Chrome|Safari|AppleWebKit|Opera|Links|Lynx|Bot|Unknown)/i', $userAgent)) {
|
||||||
|
msg_die('Browser disallowed');
|
||||||
|
}
|
||||||
|
|
||||||
// IP
|
// IP
|
||||||
$ip = $_SERVER['REMOTE_ADDR'];
|
$ip = $_SERVER['REMOTE_ADDR'];
|
||||||
|
|
||||||
// 'ip' query handling
|
// 'ip' query handling
|
||||||
if (!$bb_cfg['ignore_reported_ip'] && isset($_GET['ip']) && $ip !== $_GET['ip']) {
|
if (!config()->get('ignore_reported_ip') && isset($_GET['ip']) && $ip !== $_GET['ip']) {
|
||||||
if (!$bb_cfg['verify_reported_ip'] && isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
if (!config()->get('verify_reported_ip') && isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
||||||
$x_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
$x_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
||||||
|
|
||||||
if ($x_ip === $_GET['ip']) {
|
if ($x_ip === $_GET['ip']) {
|
||||||
$filteredIp = filter_var($x_ip, FILTER_VALIDATE_IP);
|
$filteredIp = filter_var($x_ip, FILTER_VALIDATE_IP);
|
||||||
if ($filteredIp !== false && ($bb_cfg['allow_internal_ip'] || !filter_var($filteredIp, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE))) {
|
if ($filteredIp !== false && (config()->get('allow_internal_ip') || !filter_var($filteredIp, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE))) {
|
||||||
$ip = $filteredIp;
|
$ip = $filteredIp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,9 +201,6 @@ if ($ip_version === 'ipv6') {
|
||||||
// Peer unique id
|
// Peer unique id
|
||||||
$peer_hash = hash('xxh128', $passkey . $info_hash_hex . $port);
|
$peer_hash = hash('xxh128', $passkey . $info_hash_hex . $port);
|
||||||
|
|
||||||
// Events
|
|
||||||
$stopped = ($event === 'stopped');
|
|
||||||
|
|
||||||
// Set seeder & complete
|
// Set seeder & complete
|
||||||
$complete = $seeder = ($left == 0) ? 1 : 0;
|
$complete = $seeder = ($left == 0) ? 1 : 0;
|
||||||
|
|
||||||
|
@ -183,16 +239,17 @@ if ($lp_info) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Currently torrent clients send truncated v2 hashes (the design raises questions).
|
* Currently torrent clients send truncated v2 hashes (the design raises questions).
|
||||||
* https://github.com/bittorrent/bittorrent.org/issues/145#issuecomment-1720040343
|
* @see https://github.com/bittorrent/bittorrent.org/issues/145#issuecomment-1720040343
|
||||||
*/
|
*/
|
||||||
$info_hash_where = "WHERE tor.info_hash = '$info_hash_sql' OR SUBSTRING(tor.info_hash_v2, 1, 20) = '$info_hash_sql'";
|
$info_hash_where = "WHERE tor.info_hash = '$info_hash_sql' OR SUBSTRING(tor.info_hash_v2, 1, 20) = '$info_hash_sql'";
|
||||||
|
|
||||||
$passkey_sql = DB()->escape($passkey);
|
$passkey_sql = DB()->escape($passkey);
|
||||||
|
|
||||||
$sql = "
|
$sql = "
|
||||||
SELECT tor.topic_id, tor.poster_id, tor.tor_type, tor.info_hash, tor.info_hash_v2, u.*
|
SELECT tor.topic_id, tor.poster_id, tor.tor_type, tor.tor_status, tor.info_hash, tor.info_hash_v2, bt.*, u.user_level
|
||||||
FROM " . BB_BT_TORRENTS . " tor
|
FROM " . BB_BT_TORRENTS . " tor
|
||||||
LEFT JOIN " . BB_BT_USERS . " u ON u.auth_key = '$passkey_sql'
|
LEFT JOIN " . BB_BT_USERS . " bt ON bt.auth_key = '$passkey_sql'
|
||||||
|
LEFT JOIN " . BB_USERS . " u ON u.user_id = bt.user_id
|
||||||
$info_hash_where
|
$info_hash_where
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
";
|
";
|
||||||
|
@ -200,7 +257,7 @@ if ($lp_info) {
|
||||||
|
|
||||||
// Verify if torrent registered on tracker and user authorized
|
// Verify if torrent registered on tracker and user authorized
|
||||||
if (empty($row['topic_id'])) {
|
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'])) {
|
if (empty($row['user_id'])) {
|
||||||
msg_die('Please LOG IN and RE-DOWNLOAD this torrent (user not found)');
|
msg_die('Please LOG IN and RE-DOWNLOAD this torrent (user not found)');
|
||||||
|
@ -208,16 +265,28 @@ if ($lp_info) {
|
||||||
|
|
||||||
// Assign variables
|
// Assign variables
|
||||||
$user_id = $row['user_id'];
|
$user_id = $row['user_id'];
|
||||||
|
define('IS_GUEST', (int)$user_id === GUEST_UID);
|
||||||
|
define('IS_ADMIN', !IS_GUEST && (int)$row['user_level'] === ADMIN);
|
||||||
|
define('IS_MOD', !IS_GUEST && (int)$row['user_level'] === MOD);
|
||||||
|
define('IS_GROUP_MEMBER', !IS_GUEST && (int)$row['user_level'] === GROUP_MEMBER);
|
||||||
|
define('IS_USER', !IS_GUEST && (int)$row['user_level'] === USER);
|
||||||
|
define('IS_SUPER_ADMIN', IS_ADMIN && isset(config()->get('super_admins')[$user_id]));
|
||||||
|
define('IS_AM', IS_ADMIN || IS_MOD);
|
||||||
$topic_id = $row['topic_id'];
|
$topic_id = $row['topic_id'];
|
||||||
$releaser = (int)($user_id == $row['poster_id']);
|
$releaser = (int)($user_id == $row['poster_id']);
|
||||||
$tor_type = $row['tor_type'];
|
$tor_type = $row['tor_type'];
|
||||||
|
$tor_status = $row['tor_status'];
|
||||||
|
|
||||||
|
// Check tor status
|
||||||
|
if (!IS_AM && isset(config()->get('tor_frozen')[$tor_status]) && !(isset(config()->get('tor_frozen_author_download')[$tor_status]) && $releaser)) {
|
||||||
|
msg_die('Torrent frozen and cannot be downloaded');
|
||||||
|
}
|
||||||
|
|
||||||
// Check hybrid status
|
// Check hybrid status
|
||||||
if (!empty($row['info_hash']) && !empty($row['info_hash_v2'])) {
|
if (!empty($row['info_hash']) && !empty($row['info_hash_v2'])) {
|
||||||
$stat_protocol = match ($bb_cfg['tracker']['hybrid_stat_protocol']) {
|
$stat_protocol = match ((int)config()->get('tracker.hybrid_stat_protocol')) {
|
||||||
1 => $row['info_hash'],
|
|
||||||
2 => substr($row['info_hash_v2'], 0, 20),
|
2 => substr($row['info_hash_v2'], 0, 20),
|
||||||
default => $row['info_hash']
|
default => $row['info_hash'] // 1
|
||||||
};
|
};
|
||||||
if ($info_hash !== $stat_protocol) {
|
if ($info_hash !== $stat_protocol) {
|
||||||
$hybrid_unrecord = true; // This allows us to announce only for one info-hash
|
$hybrid_unrecord = true; // This allows us to announce only for one info-hash
|
||||||
|
@ -225,7 +294,7 @@ if ($lp_info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ratio limits
|
// Ratio limits
|
||||||
if ((RATIO_ENABLED || $bb_cfg['tracker']['limit_concurrent_ips']) && !$stopped) {
|
if ((RATIO_ENABLED || config()->get('tracker.limit_concurrent_ips')) && !$stopped) {
|
||||||
$user_ratio = get_bt_ratio($row);
|
$user_ratio = get_bt_ratio($row);
|
||||||
if ($user_ratio === null) {
|
if ($user_ratio === null) {
|
||||||
$user_ratio = 1;
|
$user_ratio = 1;
|
||||||
|
@ -233,10 +302,10 @@ if ($lp_info) {
|
||||||
$rating_msg = '';
|
$rating_msg = '';
|
||||||
|
|
||||||
if (!$seeder) {
|
if (!$seeder) {
|
||||||
foreach ($bb_cfg['rating'] as $ratio => $limit) {
|
foreach (config()->get('rating') as $ratio => $limit) {
|
||||||
if ($user_ratio < $ratio) {
|
if ($user_ratio < $ratio) {
|
||||||
$bb_cfg['tracker']['limit_active_tor'] = 1;
|
config()->set('tracker.limit_active_tor', 1);
|
||||||
$bb_cfg['tracker']['limit_leech_count'] = $limit;
|
config()->set('tracker.limit_leech_count', $limit);
|
||||||
$rating_msg = " (ratio < $ratio)";
|
$rating_msg = " (ratio < $ratio)";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -244,29 +313,29 @@ if ($lp_info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Limit active torrents
|
// Limit active torrents
|
||||||
if (!isset($bb_cfg['unlimited_users'][$user_id]) && $bb_cfg['tracker']['limit_active_tor'] && (($bb_cfg['tracker']['limit_seed_count'] && $seeder) || ($bb_cfg['tracker']['limit_leech_count'] && !$seeder))) {
|
if (!isset(config()->get('unlimited_users')[$user_id]) && config()->get('tracker.limit_active_tor') && ((config()->get('tracker.limit_seed_count') && $seeder) || (config()->get('tracker.limit_leech_count') && !$seeder))) {
|
||||||
$sql = "SELECT COUNT(DISTINCT topic_id) AS active_torrents
|
$sql = "SELECT COUNT(DISTINCT topic_id) AS active_torrents
|
||||||
FROM " . BB_BT_TRACKER . "
|
FROM " . BB_BT_TRACKER . "
|
||||||
WHERE user_id = $user_id
|
WHERE user_id = $user_id
|
||||||
AND seeder = $seeder
|
AND seeder = $seeder
|
||||||
AND topic_id != $topic_id";
|
AND topic_id != $topic_id";
|
||||||
|
|
||||||
if (!$seeder && $bb_cfg['tracker']['leech_expire_factor'] && $user_ratio < 0.5) {
|
if (!$seeder && config()->get('tracker.leech_expire_factor') && $user_ratio < 0.5) {
|
||||||
$sql .= " AND update_time > " . (TIMENOW - 60 * $bb_cfg['tracker']['leech_expire_factor']);
|
$sql .= " AND update_time > " . (TIMENOW - 60 * config()->get('tracker.leech_expire_factor'));
|
||||||
}
|
}
|
||||||
$sql .= " GROUP BY user_id";
|
$sql .= " GROUP BY user_id";
|
||||||
|
|
||||||
if ($row = DB()->fetch_row($sql)) {
|
if ($row = DB()->fetch_row($sql)) {
|
||||||
if ($seeder && $bb_cfg['tracker']['limit_seed_count'] && $row['active_torrents'] >= $bb_cfg['tracker']['limit_seed_count']) {
|
if ($seeder && config()->get('tracker.limit_seed_count') && $row['active_torrents'] >= config()->get('tracker.limit_seed_count')) {
|
||||||
msg_die('Only ' . $bb_cfg['tracker']['limit_seed_count'] . ' torrent(s) allowed for seeding');
|
msg_die('Only ' . config()->get('tracker.limit_seed_count') . ' torrent(s) allowed for seeding');
|
||||||
} elseif (!$seeder && $bb_cfg['tracker']['limit_leech_count'] && $row['active_torrents'] >= $bb_cfg['tracker']['limit_leech_count']) {
|
} elseif (!$seeder && config()->get('tracker.limit_leech_count') && $row['active_torrents'] >= config()->get('tracker.limit_leech_count')) {
|
||||||
msg_die('Only ' . $bb_cfg['tracker']['limit_leech_count'] . ' torrent(s) allowed for leeching' . $rating_msg);
|
msg_die('Only ' . config()->get('tracker.limit_leech_count') . ' torrent(s) allowed for leeching' . $rating_msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Limit concurrent IPs
|
// Limit concurrent IPs
|
||||||
if ($bb_cfg['tracker']['limit_concurrent_ips'] && (($bb_cfg['tracker']['limit_seed_ips'] && $seeder) || ($bb_cfg['tracker']['limit_leech_ips'] && !$seeder))) {
|
if (config()->get('tracker.limit_concurrent_ips') && ((config()->get('tracker.limit_seed_ips') && $seeder) || (config()->get('tracker.limit_leech_ips') && !$seeder))) {
|
||||||
$sql = "SELECT COUNT(DISTINCT ip) AS ips
|
$sql = "SELECT COUNT(DISTINCT ip) AS ips
|
||||||
FROM " . BB_BT_TRACKER . "
|
FROM " . BB_BT_TRACKER . "
|
||||||
WHERE topic_id = $topic_id
|
WHERE topic_id = $topic_id
|
||||||
|
@ -274,16 +343,16 @@ if ($lp_info) {
|
||||||
AND seeder = $seeder
|
AND seeder = $seeder
|
||||||
AND $ip_version != '$ip_sql'";
|
AND $ip_version != '$ip_sql'";
|
||||||
|
|
||||||
if (!$seeder && $bb_cfg['tracker']['leech_expire_factor']) {
|
if (!$seeder && config()->get('tracker.leech_expire_factor')) {
|
||||||
$sql .= " AND update_time > " . (TIMENOW - 60 * $bb_cfg['tracker']['leech_expire_factor']);
|
$sql .= " AND update_time > " . (TIMENOW - 60 * config()->get('tracker.leech_expire_factor'));
|
||||||
}
|
}
|
||||||
$sql .= " GROUP BY topic_id";
|
$sql .= " GROUP BY topic_id";
|
||||||
|
|
||||||
if ($row = DB()->fetch_row($sql)) {
|
if ($row = DB()->fetch_row($sql)) {
|
||||||
if ($seeder && $bb_cfg['tracker']['limit_seed_ips'] && $row['ips'] >= $bb_cfg['tracker']['limit_seed_ips']) {
|
if ($seeder && config()->get('tracker.limit_seed_ips') && $row['ips'] >= config()->get('tracker.limit_seed_ips')) {
|
||||||
msg_die('You can seed only from ' . $bb_cfg['tracker']['limit_seed_ips'] . " IP's");
|
msg_die('You can seed only from ' . config()->get('tracker.limit_seed_ips') . " IP's");
|
||||||
} elseif (!$seeder && $bb_cfg['tracker']['limit_leech_ips'] && $row['ips'] >= $bb_cfg['tracker']['limit_leech_ips']) {
|
} elseif (!$seeder && config()->get('tracker.limit_leech_ips') && $row['ips'] >= config()->get('tracker.limit_leech_ips')) {
|
||||||
msg_die('You can leech only from ' . $bb_cfg['tracker']['limit_leech_ips'] . " IP's");
|
msg_die('You can leech only from ' . config()->get('tracker.limit_leech_ips') . " IP's");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,7 +376,7 @@ $up_add = ($lp_info && $uploaded > $lp_info['uploaded']) ? $uploaded - $lp_info[
|
||||||
$down_add = ($lp_info && $downloaded > $lp_info['downloaded']) ? $downloaded - $lp_info['downloaded'] : 0;
|
$down_add = ($lp_info && $downloaded > $lp_info['downloaded']) ? $downloaded - $lp_info['downloaded'] : 0;
|
||||||
|
|
||||||
// Gold/Silver releases
|
// Gold/Silver releases
|
||||||
if ($bb_cfg['tracker']['gold_silver_enabled'] && $down_add) {
|
if (config()->get('tracker.gold_silver_enabled') && $down_add) {
|
||||||
if ($tor_type == TOR_TYPE_GOLD) {
|
if ($tor_type == TOR_TYPE_GOLD) {
|
||||||
$down_add = 0;
|
$down_add = 0;
|
||||||
} // Silver releases
|
} // Silver releases
|
||||||
|
@ -317,7 +386,7 @@ if ($bb_cfg['tracker']['gold_silver_enabled'] && $down_add) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Freeleech
|
// Freeleech
|
||||||
if ($bb_cfg['tracker']['freeleech'] && $down_add) {
|
if (config()->get('tracker.freeleech') && $down_add) {
|
||||||
$down_add = 0;
|
$down_add = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,8 +464,8 @@ $output = CACHE('tr_cache')->get(PEERS_LIST_PREFIX . $topic_id);
|
||||||
|
|
||||||
if (!$output) {
|
if (!$output) {
|
||||||
// Retrieve peers
|
// Retrieve peers
|
||||||
$numwant = (int)$bb_cfg['tracker']['numwant'];
|
$numwant = (int)config()->get('tracker.numwant');
|
||||||
$compact_mode = ($bb_cfg['tracker']['compact_mode'] || !empty($compact));
|
$compact_mode = (config()->get('tracker.compact_mode') || !empty($compact));
|
||||||
|
|
||||||
$rowset = DB()->fetch_rowset("
|
$rowset = DB()->fetch_rowset("
|
||||||
SELECT ip, ipv6, port
|
SELECT ip, ipv6, port
|
||||||
|
@ -441,7 +510,7 @@ if (!$output) {
|
||||||
|
|
||||||
$seeders = $leechers = $client_completed = 0;
|
$seeders = $leechers = $client_completed = 0;
|
||||||
|
|
||||||
if ($bb_cfg['tracker']['scrape']) {
|
if (config()->get('tracker.scrape')) {
|
||||||
$row = DB()->fetch_row("
|
$row = DB()->fetch_row("
|
||||||
SELECT seeders, leechers, completed
|
SELECT seeders, leechers, completed
|
||||||
FROM " . BB_BT_TRACKER_SNAP . "
|
FROM " . BB_BT_TRACKER_SNAP . "
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Require all denied
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -11,11 +11,9 @@ if (!defined('IN_TRACKER')) {
|
||||||
die(basename(__FILE__));
|
die(basename(__FILE__));
|
||||||
}
|
}
|
||||||
|
|
||||||
global $bb_cfg;
|
|
||||||
|
|
||||||
// Exit if tracker is disabled
|
// Exit if tracker is disabled
|
||||||
if ($bb_cfg['tracker']['bt_off']) {
|
if (config()->get('tracker.bt_off')) {
|
||||||
msg_die($bb_cfg['tracker']['bt_off_reason']);
|
msg_die(config()->get('tracker.bt_off_reason'));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -11,9 +11,7 @@ define('IN_TRACKER', true);
|
||||||
define('BB_ROOT', './../');
|
define('BB_ROOT', './../');
|
||||||
require dirname(__DIR__) . '/common.php';
|
require dirname(__DIR__) . '/common.php';
|
||||||
|
|
||||||
global $bb_cfg;
|
if (!config()->get('tracker.scrape')) {
|
||||||
|
|
||||||
if (!$bb_cfg['tracker']['scrape']) {
|
|
||||||
msg_die('Please disable SCRAPE!');
|
msg_die('Please disable SCRAPE!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +32,7 @@ $info_hash_hex = bin2hex($info_hash);
|
||||||
|
|
||||||
// Check info_hash length
|
// Check info_hash length
|
||||||
if (strlen($info_hash) !== 20) {
|
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
|
// Handle multiple hashes
|
||||||
|
@ -60,15 +58,15 @@ foreach ($info_hash_array[1] as $hash) {
|
||||||
$info_hash_count = count($info_hashes);
|
$info_hash_count = count($info_hashes);
|
||||||
|
|
||||||
if (!empty($info_hash_count)) {
|
if (!empty($info_hash_count)) {
|
||||||
if ($info_hash_count > $bb_cfg['max_scrapes']) {
|
if ($info_hash_count > config()->get('max_scrapes')) {
|
||||||
$info_hashes = array_slice($info_hashes, 0, $bb_cfg['max_scrapes']);
|
$info_hashes = array_slice($info_hashes, 0, config()->get('max_scrapes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$info_hashes_sql = implode('\', \'', $info_hashes);
|
$info_hashes_sql = implode('\', \'', $info_hashes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Currently torrent clients send truncated v2 hashes (the design raises questions).
|
* Currently torrent clients send truncated v2 hashes (the design raises questions).
|
||||||
* https://github.com/bittorrent/bittorrent.org/issues/145#issuecomment-1720040343
|
* @see https://github.com/bittorrent/bittorrent.org/issues/145#issuecomment-1720040343
|
||||||
*/
|
*/
|
||||||
$info_hash_where = "tor.info_hash IN ('$info_hashes_sql') OR SUBSTRING(tor.info_hash_v2, 1, 20) IN ('$info_hashes_sql')";
|
$info_hash_where = "tor.info_hash IN ('$info_hashes_sql') OR SUBSTRING(tor.info_hash_v2, 1, 20) IN ('$info_hashes_sql')";
|
||||||
|
|
||||||
|
@ -99,7 +97,7 @@ if (!empty($info_hash_count)) {
|
||||||
|
|
||||||
// Verify if torrent registered on tracker
|
// Verify if torrent registered on tracker
|
||||||
if (empty($torrents)) {
|
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));
|
die(\Arokettu\Bencode\Bencode::encode($torrents));
|
||||||
|
|
126
cliff.toml
Normal file
126
cliff.toml
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
# git-cliff ~ TorrentPier configuration file
|
||||||
|
# https://git-cliff.org/docs/configuration
|
||||||
|
#
|
||||||
|
# Lines starting with "#" are comments.
|
||||||
|
# Configuration options are organized into tables and keys.
|
||||||
|
# See documentation for more information on available options.
|
||||||
|
|
||||||
|
[remote.github]
|
||||||
|
owner = "torrentpier"
|
||||||
|
repo = "torrentpier"
|
||||||
|
|
||||||
|
[changelog]
|
||||||
|
# template for the changelog header
|
||||||
|
header = """
|
||||||
|
[](https://github.com/torrentpier)\n
|
||||||
|
# 📖 Change Log\n
|
||||||
|
"""
|
||||||
|
# template for the changelog body
|
||||||
|
# https://keats.github.io/tera/docs/#introduction
|
||||||
|
body = """
|
||||||
|
{%- macro remote_url() -%}
|
||||||
|
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
|
||||||
|
{%- endmacro -%}
|
||||||
|
|
||||||
|
{%- macro nightly_url() -%}
|
||||||
|
https://nightly.link/{{ remote.github.owner }}/{{ remote.github.repo }}/workflows/ci/master/TorrentPier-master
|
||||||
|
{%- endmacro -%}
|
||||||
|
|
||||||
|
{% macro print_commit(commit) -%}
|
||||||
|
- {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
|
||||||
|
{% if commit.breaking %}[**breaking**] {% endif %}\
|
||||||
|
{{ commit.message | upper_first }} - \
|
||||||
|
([{{ commit.id | truncate(length=7, end="") }}]({{ self::remote_url() }}/commit/{{ commit.id }}))\
|
||||||
|
{% endmacro -%}
|
||||||
|
|
||||||
|
{% if version %}\
|
||||||
|
{% if previous.version %}\
|
||||||
|
## [{{ version }}]\
|
||||||
|
({{ self::remote_url() }}/compare/{{ previous.version }}..{{ version }}) ({{ timestamp | date(format="%Y-%m-%d") }})
|
||||||
|
{% else %}\
|
||||||
|
## {{ version }} ({{ timestamp | date(format="%Y-%m-%d") }})
|
||||||
|
{% endif %}\
|
||||||
|
{% else %}\
|
||||||
|
## [nightly]({{ self::nightly_url() }})
|
||||||
|
{% endif %}\
|
||||||
|
|
||||||
|
{% for group, commits in commits | group_by(attribute="group") %}
|
||||||
|
### {{ group | striptags | trim | upper_first }}
|
||||||
|
{% for commit in commits
|
||||||
|
| filter(attribute="scope")
|
||||||
|
| sort(attribute="scope") %}
|
||||||
|
{{ self::print_commit(commit=commit) }}
|
||||||
|
{%- endfor %}
|
||||||
|
{% for commit in commits %}
|
||||||
|
{%- if not commit.scope -%}
|
||||||
|
{{ self::print_commit(commit=commit) }}
|
||||||
|
{% endif -%}
|
||||||
|
{% endfor -%}
|
||||||
|
{% endfor -%}
|
||||||
|
{%- if github -%}
|
||||||
|
{% if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}
|
||||||
|
## New Contributors ❤️
|
||||||
|
{% endif %}\
|
||||||
|
{% for contributor in github.contributors | filter(attribute="is_first_time", value=true) %}
|
||||||
|
* @{{ contributor.username }} made their first contribution
|
||||||
|
{%- if contributor.pr_number %} in \
|
||||||
|
[#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \
|
||||||
|
{%- endif %}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
# template for the changelog footer
|
||||||
|
footer = """
|
||||||
|
"""
|
||||||
|
# remove the leading and trailing whitespace from the templates
|
||||||
|
trim = true
|
||||||
|
# postprocessors
|
||||||
|
postprocessors = [
|
||||||
|
{ pattern = '<REPO>', replace = "https://github.com/torrentpier/torrentpier" }, # replace repository URL
|
||||||
|
]
|
||||||
|
|
||||||
|
[git]
|
||||||
|
# parse the commits based on https://www.conventionalcommits.org
|
||||||
|
conventional_commits = true
|
||||||
|
# filter out the commits that are not conventional
|
||||||
|
filter_unconventional = true
|
||||||
|
# process each line of a commit as an individual commit
|
||||||
|
split_commits = false
|
||||||
|
# regex for preprocessing the commit messages
|
||||||
|
commit_preprocessors = [
|
||||||
|
# Replace issue numbers
|
||||||
|
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/pull/${2}))" },
|
||||||
|
# Check spelling of the commit with https://github.com/crate-ci/typos
|
||||||
|
# If the spelling is incorrect, it will be automatically fixed.
|
||||||
|
# { pattern = '.*', replace_command = 'typos --write-changes -' },
|
||||||
|
]
|
||||||
|
# regex for parsing and grouping commits
|
||||||
|
commit_parsers = [
|
||||||
|
{ message = "^feat", group = "<!-- 0 -->🚀 Features" },
|
||||||
|
{ message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
|
||||||
|
{ message = "^doc", group = "<!-- 3 -->📚 Documentation" },
|
||||||
|
{ message = "^perf", group = "<!-- 4 -->⚡ Performance" },
|
||||||
|
{ message = "^refactor", group = "<!-- 2 -->🚜 Refactor" },
|
||||||
|
{ message = "^style", group = "<!-- 5 -->🎨 Styling" },
|
||||||
|
{ message = "^test", group = "<!-- 6 -->🧪 Testing" },
|
||||||
|
{ message = "^ignore|^release|^changelog", skip = true },
|
||||||
|
{ message = "^chore|^ci|^misc", group = "<!-- 7 -->⚙️ Miscellaneous" },
|
||||||
|
{ body = ".*security", group = "<!-- 8 -->🛡️ Security" },
|
||||||
|
{ message = "^revert", group = "<!-- 9 -->◀️ Revert" },
|
||||||
|
{ message = "^crowdin|^crodwin", group = "<!-- 10 -->🈳 New translations" }, # crowdin pulls supporting
|
||||||
|
{ message = "^Composer", group = "<!-- 11 -->📦 Dependencies" }, # dependabot pulls supporting
|
||||||
|
{ message = "^rem|^drop|^removed", group = "<!-- 12 -->🗑️ Removed" },
|
||||||
|
{ message = ".*", group = "<!-- 13 -->💼 Other" },
|
||||||
|
]
|
||||||
|
# protect breaking changes from being skipped due to matching a skipping commit_parser
|
||||||
|
protect_breaking_commits = false
|
||||||
|
# filter out the commits that are not matched by commit parsers
|
||||||
|
filter_commits = false
|
||||||
|
# regex for matching git tags
|
||||||
|
tag_pattern = "v[0-9].*"
|
||||||
|
# sort the tags topologically
|
||||||
|
topo_order = false
|
||||||
|
# sort the commits inside sections by oldest/newest order
|
||||||
|
sort_commits = "newest"
|
175
common.php
175
common.php
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -54,7 +54,7 @@ require_once BB_PATH . '/library/defines.php';
|
||||||
|
|
||||||
// Composer
|
// Composer
|
||||||
if (!is_file(BB_PATH . '/vendor/autoload.php')) {
|
if (!is_file(BB_PATH . '/vendor/autoload.php')) {
|
||||||
die('🔩 Manual install: <a href="https://getcomposer.org/download/" target="_blank" rel="noreferrer" style="color:#0a25bb;">Install composer</a> and run <code style="background:#222;color:#00e01f;padding:2px 6px;border-radius:3px;">composer install</code>.<br>☕️ Quick install: Run <code style="background:#222;color:#00e01f;padding:2px 6px;border-radius:3px;">php install.php</code> in CLI mode.');
|
die('🔩 Manual install: <a href="https://getcomposer.org/download/" target="_blank" rel="noreferrer" style="color:#0a25bb;">Install composer</a> and run <code style="background:#222;color:#00e01f;padding:2px 6px;border-radius:3px;">composer install</code>.<br/>☕️ Quick install: Run <code style="background:#222;color:#00e01f;padding:2px 6px;border-radius:3px;">php install.php</code> in CLI mode.');
|
||||||
}
|
}
|
||||||
require_once BB_PATH . '/vendor/autoload.php';
|
require_once BB_PATH . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ try {
|
||||||
$dotenv = Dotenv\Dotenv::createMutable(BB_PATH);
|
$dotenv = Dotenv\Dotenv::createMutable(BB_PATH);
|
||||||
$dotenv->load();
|
$dotenv->load();
|
||||||
} catch (\Dotenv\Exception\InvalidPathException $pathException) {
|
} catch (\Dotenv\Exception\InvalidPathException $pathException) {
|
||||||
die('🔩 Manual install: Rename from <code style="background:#222;color:#00e01f;padding:2px 6px;border-radius:3px;">.env.example</code> to <code style="background:#222;color:#00e01f;padding:2px 6px;border-radius:3px;">.env</code>, and configure it.<br>☕️ Quick install: Run <code style="background:#222;color:#00e01f;padding:2px 6px;border-radius:3px;">php install.php</code> in CLI mode.');
|
die('🔩 Manual install: Rename from <code style="background:#222;color:#00e01f;padding:2px 6px;border-radius:3px;">.env.example</code> to <code style="background:#222;color:#00e01f;padding:2px 6px;border-radius:3px;">.env</code>, and configure it.<br/>☕️ Quick install: Run <code style="background:#222;color:#00e01f;padding:2px 6px;border-radius:3px;">php install.php</code> in CLI mode.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load config
|
// Load config
|
||||||
|
@ -86,63 +86,138 @@ if (is_file(BB_PATH . '/library/config.local.php')) {
|
||||||
require_once BB_PATH . '/library/config.local.php';
|
require_once BB_PATH . '/library/config.local.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @noinspection PhpUndefinedVariableInspection */
|
||||||
|
// Initialize Config singleton, bb_cfg from global file config
|
||||||
|
$config = \TorrentPier\Config::init($bb_cfg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error reporting
|
* Get the Config instance
|
||||||
|
*
|
||||||
|
* @return \TorrentPier\Config
|
||||||
*/
|
*/
|
||||||
$debug = new \TorrentPier\Dev();
|
function config(): \TorrentPier\Config
|
||||||
|
{
|
||||||
|
return \TorrentPier\Config::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Censor instance
|
||||||
|
*
|
||||||
|
* @return \TorrentPier\Censor
|
||||||
|
*/
|
||||||
|
function censor(): \TorrentPier\Censor
|
||||||
|
{
|
||||||
|
return \TorrentPier\Censor::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Dev instance
|
||||||
|
*
|
||||||
|
* @return \TorrentPier\Dev
|
||||||
|
*/
|
||||||
|
function dev(): \TorrentPier\Dev
|
||||||
|
{
|
||||||
|
return \TorrentPier\Dev::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Language instance
|
||||||
|
*
|
||||||
|
* @return \TorrentPier\Language
|
||||||
|
*/
|
||||||
|
function lang(): \TorrentPier\Language
|
||||||
|
{
|
||||||
|
return \TorrentPier\Language::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a language string (shorthand for lang()->get())
|
||||||
|
*
|
||||||
|
* @param string $key Language key, supports dot notation (e.g., 'DATETIME.TODAY')
|
||||||
|
* @param mixed $default Default value if key doesn't exist
|
||||||
|
* @return mixed Language string or default value
|
||||||
|
*/
|
||||||
|
function __(string $key, mixed $default = null): mixed
|
||||||
|
{
|
||||||
|
return \TorrentPier\Language::getInstance()->get($key, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Echo a language string (shorthand for echo __())
|
||||||
|
*
|
||||||
|
* @param string $key Language key, supports dot notation
|
||||||
|
* @param mixed $default Default value if key doesn't exist
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function _e(string $key, mixed $default = null): void
|
||||||
|
{
|
||||||
|
echo \TorrentPier\Language::getInstance()->get($key, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize debug
|
||||||
|
*/
|
||||||
|
define('APP_ENV', env('APP_ENV', 'production'));
|
||||||
|
if (APP_ENV === 'development') {
|
||||||
|
define('DBG_USER', true); // forced debug
|
||||||
|
} else {
|
||||||
|
define('DBG_USER', isset($_COOKIE[COOKIE_DBG]));
|
||||||
|
}
|
||||||
|
(\TorrentPier\Dev::init());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server variables initialize
|
* Server variables initialize
|
||||||
*/
|
*/
|
||||||
$server_protocol = $bb_cfg['cookie_secure'] ? 'https://' : 'http://';
|
$server_protocol = config()->get('cookie_secure') ? 'https://' : 'http://';
|
||||||
$server_port = in_array((int)$bb_cfg['server_port'], [80, 443], true) ? '' : ':' . $bb_cfg['server_port'];
|
$server_port = in_array((int)config()->get('server_port'), [80, 443], true) ? '' : ':' . config()->get('server_port');
|
||||||
define('FORUM_PATH', $bb_cfg['script_path']);
|
define('FORUM_PATH', config()->get('script_path'));
|
||||||
define('FULL_URL', $server_protocol . $bb_cfg['server_name'] . $server_port . $bb_cfg['script_path']);
|
define('FULL_URL', $server_protocol . config()->get('server_name') . $server_port . config()->get('script_path'));
|
||||||
unset($server_protocol, $server_port);
|
unset($server_protocol, $server_port);
|
||||||
|
|
||||||
/**
|
// Initialize the new DB factory with database configuration
|
||||||
* Database
|
TorrentPier\Database\DatabaseFactory::init(config()->get('db'), config()->get('db_alias', []));
|
||||||
*/
|
|
||||||
$DBS = new TorrentPier\Legacy\Dbs($bb_cfg);
|
|
||||||
|
|
||||||
function DB(string $db_alias = 'db')
|
/**
|
||||||
|
* Get the Database instance
|
||||||
|
*
|
||||||
|
* @param string $db_alias
|
||||||
|
* @return \TorrentPier\Database\Database
|
||||||
|
*/
|
||||||
|
function DB(string $db_alias = 'db'): \TorrentPier\Database\Database
|
||||||
{
|
{
|
||||||
global $DBS;
|
return TorrentPier\Database\DatabaseFactory::getInstance($db_alias);
|
||||||
return $DBS->get_db_obj($db_alias);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Initialize Unified Cache System
|
||||||
* Cache
|
TorrentPier\Cache\UnifiedCacheSystem::getInstance(config()->all());
|
||||||
*/
|
|
||||||
$CACHES = new TorrentPier\Legacy\Caches($bb_cfg);
|
|
||||||
|
|
||||||
function CACHE(string $cache_name)
|
/**
|
||||||
|
* Get cache manager instance (replaces legacy cache system)
|
||||||
|
*
|
||||||
|
* @param string $cache_name
|
||||||
|
* @return \TorrentPier\Cache\CacheManager
|
||||||
|
*/
|
||||||
|
function CACHE(string $cache_name): \TorrentPier\Cache\CacheManager
|
||||||
{
|
{
|
||||||
global $CACHES;
|
return TorrentPier\Cache\UnifiedCacheSystem::getInstance()->get_cache_obj($cache_name);
|
||||||
return $CACHES->get_cache_obj($cache_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Datastore
|
* Get datastore manager instance (replaces legacy datastore system)
|
||||||
|
*
|
||||||
|
* @return \TorrentPier\Cache\DatastoreManager
|
||||||
*/
|
*/
|
||||||
switch ($bb_cfg['datastore_type']) {
|
function datastore(): \TorrentPier\Cache\DatastoreManager
|
||||||
case 'apcu':
|
{
|
||||||
$datastore = new TorrentPier\Legacy\Datastore\APCu($bb_cfg['cache']['prefix']);
|
return TorrentPier\Cache\UnifiedCacheSystem::getInstance()->getDatastore(config()->get('datastore_type', 'file'));
|
||||||
break;
|
|
||||||
case 'memcached':
|
|
||||||
$datastore = new TorrentPier\Legacy\Datastore\Memcached($bb_cfg['cache']['memcached'], $bb_cfg['cache']['prefix']);
|
|
||||||
break;
|
|
||||||
case 'sqlite':
|
|
||||||
$datastore = new TorrentPier\Legacy\Datastore\Sqlite($bb_cfg['cache']['db_dir'] . 'datastore', $bb_cfg['cache']['prefix']);
|
|
||||||
break;
|
|
||||||
case 'redis':
|
|
||||||
$datastore = new TorrentPier\Legacy\Datastore\Redis($bb_cfg['cache']['redis'], $bb_cfg['cache']['prefix']);
|
|
||||||
break;
|
|
||||||
case 'filecache':
|
|
||||||
default:
|
|
||||||
$datastore = new TorrentPier\Legacy\Datastore\File($bb_cfg['cache']['db_dir'] . 'datastore/', $bb_cfg['cache']['prefix']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backward compatibility: Global datastore variable
|
||||||
|
* This allows existing code to continue using global $datastore
|
||||||
|
*/
|
||||||
|
$datastore = datastore();
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
function utime()
|
function utime()
|
||||||
{
|
{
|
||||||
|
@ -233,7 +308,7 @@ function clean_filename($fname)
|
||||||
* @param ?string $charset
|
* @param ?string $charset
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function htmlCHR($txt, bool $double_encode = false, int $quote_style = ENT_QUOTES, ?string $charset = 'UTF-8'): string
|
function htmlCHR($txt, bool $double_encode = false, int $quote_style = ENT_QUOTES, ?string $charset = DEFAULT_CHARSET): string
|
||||||
{
|
{
|
||||||
return (string)htmlspecialchars($txt ?? '', $quote_style, $charset, $double_encode);
|
return (string)htmlspecialchars($txt ?? '', $quote_style, $charset, $double_encode);
|
||||||
}
|
}
|
||||||
|
@ -244,7 +319,7 @@ function htmlCHR($txt, bool $double_encode = false, int $quote_style = ENT_QUOTE
|
||||||
*/
|
*/
|
||||||
function str_compact($str)
|
function str_compact($str)
|
||||||
{
|
{
|
||||||
return preg_replace('#\s+#u', ' ', trim($str ?? ''));
|
return preg_replace('/\s\s+/', ' ', trim($str ?? ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -324,6 +399,12 @@ function hide_bb_path(string $path): string
|
||||||
return ltrim(str_replace(BB_PATH, '', $path), '/\\');
|
return ltrim(str_replace(BB_PATH, '', $path), '/\\');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns memory usage statistic
|
||||||
|
*
|
||||||
|
* @param string $param
|
||||||
|
* @return int|void
|
||||||
|
*/
|
||||||
function sys(string $param)
|
function sys(string $param)
|
||||||
{
|
{
|
||||||
switch ($param) {
|
switch ($param) {
|
||||||
|
@ -339,6 +420,10 @@ function sys(string $param)
|
||||||
/**
|
/**
|
||||||
* Some shared defines
|
* Some shared defines
|
||||||
*/
|
*/
|
||||||
|
// Initialize demo mode
|
||||||
|
define('IN_DEMO_MODE', env('APP_DEMO_MODE', false));
|
||||||
|
|
||||||
|
// Ratio status
|
||||||
define('RATIO_ENABLED', TR_RATING_LIMITS && MIN_DL_FOR_RATIO > 0);
|
define('RATIO_ENABLED', TR_RATING_LIMITS && MIN_DL_FOR_RATIO > 0);
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
|
@ -348,9 +433,9 @@ if (!defined('IN_TRACKER')) {
|
||||||
} else {
|
} else {
|
||||||
define('DUMMY_PEER', pack('Nn', \TorrentPier\Helpers\IPHelper::ip2long($_SERVER['REMOTE_ADDR']), !empty($_GET['port']) ? (int)$_GET['port'] : random_int(1000, 65000)));
|
define('DUMMY_PEER', pack('Nn', \TorrentPier\Helpers\IPHelper::ip2long($_SERVER['REMOTE_ADDR']), !empty($_GET['port']) ? (int)$_GET['port'] : random_int(1000, 65000)));
|
||||||
|
|
||||||
define('PEER_HASH_EXPIRE', round($bb_cfg['announce_interval'] * (0.85 * $bb_cfg['tracker']['expire_factor'])));
|
define('PEER_HASH_EXPIRE', round(config()->get('announce_interval') * (0.85 * config()->get('tracker.expire_factor'))));
|
||||||
define('PEERS_LIST_EXPIRE', round($bb_cfg['announce_interval'] * 0.7));
|
define('PEERS_LIST_EXPIRE', round(config()->get('announce_interval') * 0.7));
|
||||||
define('SCRAPE_LIST_EXPIRE', round($bb_cfg['scrape_interval'] * 0.7));
|
define('SCRAPE_LIST_EXPIRE', round(config()->get('scrape_interval') * 0.7));
|
||||||
|
|
||||||
define('PEER_HASH_PREFIX', 'peer_');
|
define('PEER_HASH_PREFIX', 'peer_');
|
||||||
define('PEERS_LIST_PREFIX', 'peers_list_');
|
define('PEERS_LIST_PREFIX', 'peers_list_');
|
||||||
|
|
|
@ -46,46 +46,57 @@
|
||||||
"forum": "https://torrentpier.com"
|
"forum": "https://torrentpier.com"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.1 | ^8.2 | ^8.3 | ^8.4",
|
"php": ">=8.2",
|
||||||
"arokettu/random-polyfill": "1.0.2",
|
|
||||||
"arokettu/bencode": "^4.1.0",
|
"arokettu/bencode": "^4.1.0",
|
||||||
"arokettu/monsterid": "dev-master",
|
"arokettu/monsterid": "^4.1.0",
|
||||||
|
"arokettu/random-polyfill": "1.0.2",
|
||||||
"arokettu/torrent-file": "^5.2.1",
|
"arokettu/torrent-file": "^5.2.1",
|
||||||
|
"belomaxorka/captcha": "1.*",
|
||||||
"bugsnag/bugsnag": "^v3.29.1",
|
"bugsnag/bugsnag": "^v3.29.1",
|
||||||
"claviska/simpleimage": "^4.0",
|
"claviska/simpleimage": "^4.0",
|
||||||
"egulias/email-validator": "^4.0.1",
|
"egulias/email-validator": "^4.0.1",
|
||||||
"filp/whoops": "^2.15",
|
"filp/whoops": "^2.15",
|
||||||
|
"gemorroj/m3u-parser": "^6.0.1",
|
||||||
"gigablah/sphinxphp": "2.0.8",
|
"gigablah/sphinxphp": "2.0.8",
|
||||||
"google/recaptcha": "^1.3",
|
"google/recaptcha": "^1.3",
|
||||||
"jacklul/monolog-telegram": "^3.1",
|
"jacklul/monolog-telegram": "^3.1",
|
||||||
"josantonius/cookie": "^2.0",
|
"josantonius/cookie": "^2.0",
|
||||||
"league/flysystem": "^3.28",
|
"league/flysystem": "^3.28",
|
||||||
"longman/ip-tools": "1.2.1",
|
"longman/ip-tools": "1.2.1",
|
||||||
"matthiasmullie/scrapbook": "^1.5",
|
|
||||||
"monolog/monolog": "^3.4",
|
"monolog/monolog": "^3.4",
|
||||||
|
"nette/caching": "^3.3",
|
||||||
|
"nette/database": "^3.2",
|
||||||
|
"php-curl-class/php-curl-class": "^12.0.0",
|
||||||
|
"robmorgan/phinx": "^0.16.9",
|
||||||
"samdark/sitemap": "2.4.1",
|
"samdark/sitemap": "2.4.1",
|
||||||
"symfony/finder": "^6.4",
|
"symfony/mailer": "^7.3",
|
||||||
"symfony/filesystem": "^6.4",
|
"symfony/polyfill": "v1.32.0",
|
||||||
"symfony/event-dispatcher": "^6.4",
|
"vlucas/phpdotenv": "^5.5",
|
||||||
"symfony/mime": "^6.4",
|
"z4kn4fein/php-semver": "^v3.0.0"
|
||||||
"symfony/mailer": "^6.4",
|
|
||||||
"vlucas/phpdotenv": "^5.5"
|
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/var-dumper": "^6.4"
|
"mockery/mockery": "^1.6",
|
||||||
|
"pestphp/pest": "^3.8",
|
||||||
|
"symfony/var-dumper": "^7.3"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"TorrentPier\\": "src/"
|
"TorrentPier\\": "src/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"Tests\\": "tests/"
|
||||||
|
}
|
||||||
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"sort-packages": true,
|
"sort-packages": true,
|
||||||
"optimize-autoloader": true,
|
"optimize-autoloader": true,
|
||||||
"allow-plugins": {
|
"allow-plugins": {
|
||||||
|
"pestphp/pest-plugin": true,
|
||||||
"php-http/discovery": true
|
"php-http/discovery": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "stable",
|
||||||
"prefer-stable": true
|
"prefer-stable": true
|
||||||
}
|
}
|
||||||
|
|
5571
composer.lock
generated
5571
composer.lock
generated
File diff suppressed because it is too large
Load diff
2
cron.php
2
cron.php
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
php_flag engine off
|
|
||||||
RemoveHandler .php .php5 .php4 .php3 .phtml .pl .asp
|
|
||||||
AddType text/plain .php .php .htm .html .phtml .pl .asp
|
|
26
dl.php
26
dl.php
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -20,11 +20,12 @@ $datastore->enqueue([
|
||||||
|
|
||||||
$download_id = request_var('id', 0);
|
$download_id = request_var('id', 0);
|
||||||
$thumbnail = request_var('thumb', 0);
|
$thumbnail = request_var('thumb', 0);
|
||||||
|
$m3u = isset($_GET['m3u']) && $_GET['m3u'];
|
||||||
|
|
||||||
// Send file to browser
|
// Send file to browser
|
||||||
function send_file_to_browser($attachment, $upload_dir)
|
function send_file_to_browser($attachment, $upload_dir)
|
||||||
{
|
{
|
||||||
global $bb_cfg, $lang;
|
global $lang;
|
||||||
|
|
||||||
$filename = $upload_dir . '/' . $attachment['physical_filename'];
|
$filename = $upload_dir . '/' . $attachment['physical_filename'];
|
||||||
$gotit = false;
|
$gotit = false;
|
||||||
|
@ -52,7 +53,7 @@ function send_file_to_browser($attachment, $upload_dir)
|
||||||
header('Pragma: public');
|
header('Pragma: public');
|
||||||
$real_filename = clean_filename(basename($attachment['real_filename']));
|
$real_filename = clean_filename(basename($attachment['real_filename']));
|
||||||
$mimetype = $attachment['mimetype'] . ';';
|
$mimetype = $attachment['mimetype'] . ';';
|
||||||
$charset = "charset={$bb_cfg['charset']};";
|
$charset = 'charset=' . DEFAULT_CHARSET . ';';
|
||||||
|
|
||||||
// Send out the Headers
|
// Send out the Headers
|
||||||
header("Content-Type: $mimetype $charset name=\"$real_filename\"");
|
header("Content-Type: $mimetype $charset name=\"$real_filename\"");
|
||||||
|
@ -100,9 +101,18 @@ if (!($attachment = DB()->sql_fetchrow($result))) {
|
||||||
|
|
||||||
$attachment['physical_filename'] = basename($attachment['physical_filename']);
|
$attachment['physical_filename'] = basename($attachment['physical_filename']);
|
||||||
|
|
||||||
// Re-define $attachment['physical_filename'] for thumbnails
|
|
||||||
if ($thumbnail) {
|
if ($thumbnail) {
|
||||||
|
// Re-define $attachment['physical_filename'] for thumbnails
|
||||||
$attachment['physical_filename'] = THUMB_DIR . '/t_' . $attachment['physical_filename'];
|
$attachment['physical_filename'] = THUMB_DIR . '/t_' . $attachment['physical_filename'];
|
||||||
|
} elseif ($m3u) {
|
||||||
|
// Check m3u file exist
|
||||||
|
if (!$m3uFile = (new \TorrentPier\TorrServerAPI())->getM3UPath($download_id)) {
|
||||||
|
bb_die($lang['ERROR_NO_ATTACHMENT']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$attachment['physical_filename'] = $attachment['real_filename'] = basename($m3uFile);
|
||||||
|
$attachment['mimetype'] = mime_content_type($m3uFile);
|
||||||
|
$attachment['extension'] = str_replace('.', '', \TorrentPier\TorrServerAPI::M3U['extension']);
|
||||||
}
|
}
|
||||||
|
|
||||||
DB()->sql_freeresult($result);
|
DB()->sql_freeresult($result);
|
||||||
|
@ -151,7 +161,7 @@ if (!$authorised) {
|
||||||
$datastore->rm('cat_forums');
|
$datastore->rm('cat_forums');
|
||||||
|
|
||||||
// Check tor status
|
// Check tor status
|
||||||
if (!IS_AM && str_contains($attachment['mimetype'], 'bittorrent')) {
|
if (!IS_AM && ($attachment['mimetype'] === TORRENT_MIMETYPE)) {
|
||||||
$sql = 'SELECT tor_status, poster_id FROM ' . BB_BT_TORRENTS . ' WHERE attach_id = ' . (int)$attachment['attach_id'];
|
$sql = 'SELECT tor_status, poster_id FROM ' . BB_BT_TORRENTS . ' WHERE attach_id = ' . (int)$attachment['attach_id'];
|
||||||
|
|
||||||
if (!($result = DB()->sql_query($sql))) {
|
if (!($result = DB()->sql_query($sql))) {
|
||||||
|
@ -160,7 +170,7 @@ if (!IS_AM && str_contains($attachment['mimetype'], 'bittorrent')) {
|
||||||
|
|
||||||
$row = DB()->sql_fetchrow($result);
|
$row = DB()->sql_fetchrow($result);
|
||||||
|
|
||||||
if (isset($bb_cfg['tor_frozen'][$row['tor_status']]) && !(isset($bb_cfg['tor_frozen_author_download'][$row['tor_status']]) && $userdata['user_id'] === $row['poster_id'])) {
|
if (isset(config()->get('tor_frozen')[$row['tor_status']]) && !(isset(config()->get('tor_frozen_author_download')[$row['tor_status']]) && $userdata['user_id'] === $row['poster_id'])) {
|
||||||
bb_die($lang['TOR_STATUS_FORBIDDEN'] . $lang['TOR_STATUS_NAME'][$row['tor_status']]);
|
bb_die($lang['TOR_STATUS_FORBIDDEN'] . $lang['TOR_STATUS_NAME'][$row['tor_status']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +204,7 @@ if (isset($download_mode[$attachment['extension']])) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update download count
|
// Update download count
|
||||||
if (!$thumbnail && is_file(realpath($upload_dir . '/' . $attachment['physical_filename']))) {
|
if (!$m3u && !$thumbnail && is_file(realpath($upload_dir . '/' . $attachment['physical_filename']))) {
|
||||||
$sql = 'UPDATE ' . BB_ATTACHMENTS_DESC . ' SET download_count = download_count + 1 WHERE attach_id = ' . (int)$attachment['attach_id'];
|
$sql = 'UPDATE ' . BB_ATTACHMENTS_DESC . ' SET download_count = download_count + 1 WHERE attach_id = ' . (int)$attachment['attach_id'];
|
||||||
|
|
||||||
if (!DB()->sql_query($sql)) {
|
if (!DB()->sql_query($sql)) {
|
||||||
|
@ -209,7 +219,7 @@ switch ($download_mode) {
|
||||||
header('Location: ' . $url);
|
header('Location: ' . $url);
|
||||||
exit;
|
exit;
|
||||||
case INLINE_LINK:
|
case INLINE_LINK:
|
||||||
if (IS_GUEST && !$bb_cfg['captcha']['disabled'] && !bb_captcha('check')) {
|
if (IS_GUEST && !config()->get('captcha.disabled') && !bb_captcha('check')) {
|
||||||
global $template;
|
global $template;
|
||||||
|
|
||||||
$redirect_url = $_POST['redirect_url'] ?? $_SERVER['HTTP_REFERER'] ?? '/';
|
$redirect_url = $_POST['redirect_url'] ?? $_SERVER['HTTP_REFERER'] ?? '/';
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
|
14
feed.php
14
feed.php
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -34,11 +34,11 @@ if ($mode === 'get_feed_url' && ($type === 'f' || $type === 'u') && $id >= 0) {
|
||||||
bb_simple_die($lang['ATOM_ERROR'] . ' #1');
|
bb_simple_die($lang['ATOM_ERROR'] . ' #1');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_file($bb_cfg['atom']['path'] . '/f/' . $id . '.atom') && filemtime($bb_cfg['atom']['path'] . '/f/' . $id . '.atom') > $timecheck) {
|
if (is_file(config()->get('atom.path') . '/f/' . $id . '.atom') && filemtime(config()->get('atom.path') . '/f/' . $id . '.atom') > $timecheck) {
|
||||||
redirect($bb_cfg['atom']['url'] . '/f/' . $id . '.atom');
|
redirect(config()->get('atom.url') . '/f/' . $id . '.atom');
|
||||||
} else {
|
} else {
|
||||||
if (\TorrentPier\Legacy\Atom::update_forum_feed($id, $forum_data)) {
|
if (\TorrentPier\Legacy\Atom::update_forum_feed($id, $forum_data)) {
|
||||||
redirect($bb_cfg['atom']['url'] . '/f/' . $id . '.atom');
|
redirect(config()->get('atom.url') . '/f/' . $id . '.atom');
|
||||||
} else {
|
} else {
|
||||||
bb_simple_die($lang['ATOM_NO_FORUM']);
|
bb_simple_die($lang['ATOM_NO_FORUM']);
|
||||||
}
|
}
|
||||||
|
@ -52,11 +52,11 @@ if ($mode === 'get_feed_url' && ($type === 'f' || $type === 'u') && $id >= 0) {
|
||||||
if (!$username = get_username($id)) {
|
if (!$username = get_username($id)) {
|
||||||
bb_simple_die($lang['ATOM_ERROR'] . ' #3');
|
bb_simple_die($lang['ATOM_ERROR'] . ' #3');
|
||||||
}
|
}
|
||||||
if (is_file($bb_cfg['atom']['path'] . '/u/' . floor($id / 5000) . '/' . ($id % 100) . '/' . $id . '.atom') && filemtime($bb_cfg['atom']['path'] . '/u/' . floor($id / 5000) . '/' . ($id % 100) . '/' . $id . '.atom') > $timecheck) {
|
if (is_file(config()->get('atom.path') . '/u/' . floor($id / 5000) . '/' . ($id % 100) . '/' . $id . '.atom') && filemtime(config()->get('atom.path') . '/u/' . floor($id / 5000) . '/' . ($id % 100) . '/' . $id . '.atom') > $timecheck) {
|
||||||
redirect($bb_cfg['atom']['url'] . '/u/' . floor($id / 5000) . '/' . ($id % 100) . '/' . $id . '.atom');
|
redirect(config()->get('atom.url') . '/u/' . floor($id / 5000) . '/' . ($id % 100) . '/' . $id . '.atom');
|
||||||
} else {
|
} else {
|
||||||
if (\TorrentPier\Legacy\Atom::update_user_feed($id, $username)) {
|
if (\TorrentPier\Legacy\Atom::update_user_feed($id, $username)) {
|
||||||
redirect($bb_cfg['atom']['url'] . '/u/' . floor($id / 5000) . '/' . ($id % 100) . '/' . $id . '.atom');
|
redirect(config()->get('atom.url') . '/u/' . floor($id / 5000) . '/' . ($id % 100) . '/' . $id . '.atom');
|
||||||
} else {
|
} else {
|
||||||
bb_simple_die($lang['ATOM_NO_USER']);
|
bb_simple_die($lang['ATOM_NO_USER']);
|
||||||
}
|
}
|
||||||
|
|
39
filelist.php
39
filelist.php
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -14,16 +14,16 @@ require __DIR__ . '/common.php';
|
||||||
// Start session management
|
// Start session management
|
||||||
$user->session_start();
|
$user->session_start();
|
||||||
|
|
||||||
if ($bb_cfg['bt_disable_dht'] && IS_GUEST) {
|
if (config()->get('bt_disable_dht') && IS_GUEST) {
|
||||||
bb_simple_die($lang['BT_PRIVATE_TRACKER'], 403);
|
bb_die($lang['BT_PRIVATE_TRACKER'], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
$topic_id = isset($_GET[POST_TOPIC_URL]) ? (int)$_GET[POST_TOPIC_URL] : 0;
|
$topic_id = isset($_GET[POST_TOPIC_URL]) ? (int)$_GET[POST_TOPIC_URL] : 0;
|
||||||
if (!$topic_id) {
|
if (!$topic_id) {
|
||||||
bb_simple_die($lang['INVALID_TOPIC_ID'], 404);
|
bb_die($lang['INVALID_TOPIC_ID'], 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = 'SELECT t.attach_id, t.info_hash, t.info_hash_v2, t.size, ad.physical_filename
|
$sql = 'SELECT t.forum_id, t.attach_id, t.info_hash, t.info_hash_v2, t.size, ad.physical_filename
|
||||||
FROM ' . BB_BT_TORRENTS . ' t
|
FROM ' . BB_BT_TORRENTS . ' t
|
||||||
LEFT JOIN ' . BB_ATTACHMENTS_DESC . ' ad
|
LEFT JOIN ' . BB_ATTACHMENTS_DESC . ' ad
|
||||||
ON t.attach_id = ad.attach_id
|
ON t.attach_id = ad.attach_id
|
||||||
|
@ -31,7 +31,13 @@ $sql = 'SELECT t.attach_id, t.info_hash, t.info_hash_v2, t.size, ad.physical_fil
|
||||||
LIMIT 1';
|
LIMIT 1';
|
||||||
|
|
||||||
if (!$row = DB()->fetch_row($sql)) {
|
if (!$row = DB()->fetch_row($sql)) {
|
||||||
bb_simple_die($lang['INVALID_TOPIC_ID_DB'], 404);
|
bb_die($lang['INVALID_TOPIC_ID_DB'], 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check rights
|
||||||
|
$is_auth = auth(AUTH_ALL, $row['forum_id'], $userdata);
|
||||||
|
if (!$is_auth['auth_view']) {
|
||||||
|
bb_die($lang['SORRY_AUTH_VIEW_ATTACH'], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Protocol meta
|
// Protocol meta
|
||||||
|
@ -45,11 +51,11 @@ $t_hash_field = $meta_v2 ? 'piecesRoot' : 'sha1';
|
||||||
|
|
||||||
$file_path = get_attachments_dir() . '/' . $row['physical_filename'];
|
$file_path = get_attachments_dir() . '/' . $row['physical_filename'];
|
||||||
if (!is_file($file_path)) {
|
if (!is_file($file_path)) {
|
||||||
bb_simple_die($lang['TOR_NOT_FOUND'], 410);
|
bb_die($lang['TOR_NOT_FOUND'], 410);
|
||||||
}
|
}
|
||||||
|
|
||||||
$file_contents = file_get_contents($file_path);
|
$file_contents = file_get_contents($file_path);
|
||||||
if ($bb_cfg['flist_max_files']) {
|
if (config()->get('flist_max_files')) {
|
||||||
$filetree_pos = $meta_v2 ? strpos($file_contents, '9:file tree') : false;
|
$filetree_pos = $meta_v2 ? strpos($file_contents, '9:file tree') : false;
|
||||||
$files_pos = $meta_v1 ? strpos($file_contents, '5:files', $filetree_pos) : false;
|
$files_pos = $meta_v1 ? strpos($file_contents, '5:files', $filetree_pos) : false;
|
||||||
|
|
||||||
|
@ -59,23 +65,24 @@ if ($bb_cfg['flist_max_files']) {
|
||||||
$file_count = substr_count($file_contents, '6:length', $files_pos);
|
$file_count = substr_count($file_contents, '6:length', $files_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($file_count > $bb_cfg['flist_max_files']) {
|
if ($file_count > config()->get('flist_max_files')) {
|
||||||
bb_simple_die(sprintf($lang['BT_FLIST_LIMIT'], $bb_cfg['flist_max_files'], $file_count), 410);
|
bb_die(sprintf($lang['BT_FLIST_LIMIT'], config()->get('flist_max_files'), $file_count), 410);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$torrent = \Arokettu\Torrent\TorrentFile::loadFromString($file_contents);
|
$torrent = \Arokettu\Torrent\TorrentFile::loadFromString($file_contents);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
bb_simple_die(htmlCHR("{$lang['TORFILE_INVALID']}: {$e->getMessage()}"), 410);
|
bb_die(htmlCHR("{$lang['TORFILE_INVALID']}: {$e->getMessage()}"), 410);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_GUEST && $torrent->isPrivate()) {
|
if (IS_GUEST && $torrent->isPrivate()) {
|
||||||
bb_simple_die($lang['BT_PRIVATE_TORRENT'], 403);
|
bb_die($lang['BT_PRIVATE_TORRENT'], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get torrent files
|
||||||
$files = $torrent->$t_version_field()->$t_files_field();
|
$files = $torrent->$t_version_field()->$t_files_field();
|
||||||
if ($meta_v1 && $meta_v2) {
|
if ($meta_v2) {
|
||||||
$files = new \RecursiveIteratorIterator($files); // Flatten the list
|
$files = new \RecursiveIteratorIterator($files); // Flatten the list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,14 +99,16 @@ foreach ($files as $file) {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$torrent_name = !empty($t_name = $torrent->getName()) ? htmlCHR(str_short($t_name, 200)) : $lang['UNKNOWN'];
|
$torrent_name = !empty($t_name = $torrent->getName()) ? str_short(htmlCHR($t_name), 200) : $lang['UNKNOWN'];
|
||||||
$torrent_size = humn_size($row['size'], 2);
|
$torrent_size = humn_size($row['size'], 2);
|
||||||
|
|
||||||
|
// Output page
|
||||||
$template->assign_vars([
|
$template->assign_vars([
|
||||||
'PAGE_TITLE' => "$torrent_name (" . $torrent_size . ")",
|
'PAGE_TITLE' => "$torrent_name (" . $torrent_size . ")",
|
||||||
'FILES_COUNT' => sprintf($lang['BT_FLIST_FILE_PATH'], declension(iterator_count($files), 'files')),
|
'FILES_COUNT' => sprintf($lang['BT_FLIST_FILE_PATH'], declension(iterator_count($files), 'files')),
|
||||||
'TORRENT_CREATION_DATE' => (!empty($dt = $torrent->getCreationDate()) && is_numeric($creation_date = $dt->getTimestamp())) ? date('d-M-Y H:i (e)', $creation_date) : $lang['UNKNOWN'],
|
'TORRENT_CREATION_DATE' => (!empty($dt = $torrent->getCreationDate()) && is_numeric($creation_date = $dt->getTimestamp())) ? date('d-M-Y H:i (e)', $creation_date) : $lang['UNKNOWN'],
|
||||||
'TORRENT_CLIENT' => !empty($creator = $torrent->getCreatedBy()) ? htmlCHR(str_short($creator, 20)) : $lang['UNKNOWN'],
|
'TORRENT_CLIENT' => !empty($creator = $torrent->getCreatedBy()) ? htmlCHR($creator) : $lang['UNKNOWN'],
|
||||||
|
'TORRENT_PRIVATE' => $torrent->isPrivate() ? $lang['YES'] : $lang['NO'],
|
||||||
|
|
||||||
'BTMR_NOTICE' => sprintf($lang['BT_FLIST_BTMR_NOTICE'], 'https://github.com/kovalensky/tmrr'),
|
'BTMR_NOTICE' => sprintf($lang['BT_FLIST_BTMR_NOTICE'], 'https://github.com/kovalensky/tmrr'),
|
||||||
'U_TOPIC' => TOPIC_URL . $topic_id,
|
'U_TOPIC' => TOPIC_URL . $topic_id,
|
||||||
|
|
18
group.php
18
group.php
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -24,7 +24,7 @@ set_die_append_msg();
|
||||||
|
|
||||||
$group_id = isset($_REQUEST[POST_GROUPS_URL]) ? (int)$_REQUEST[POST_GROUPS_URL] : null;
|
$group_id = isset($_REQUEST[POST_GROUPS_URL]) ? (int)$_REQUEST[POST_GROUPS_URL] : null;
|
||||||
$start = isset($_REQUEST['start']) ? abs((int)$_REQUEST['start']) : 0;
|
$start = isset($_REQUEST['start']) ? abs((int)$_REQUEST['start']) : 0;
|
||||||
$per_page = $bb_cfg['group_members_per_page'];
|
$per_page = config()->get('group_members_per_page');
|
||||||
$view_mode = isset($_REQUEST['view']) ? (string)$_REQUEST['view'] : null;
|
$view_mode = isset($_REQUEST['view']) ? (string)$_REQUEST['view'] : null;
|
||||||
$rel_limit = 50;
|
$rel_limit = 50;
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ if (!$group_id) {
|
||||||
|
|
||||||
$options = '';
|
$options = '';
|
||||||
foreach ($params as $name => $data) {
|
foreach ($params as $name => $data) {
|
||||||
$text = htmlCHR(str_short(rtrim($name), HTML_SELECT_MAX_LENGTH));
|
$text = str_short(rtrim(htmlCHR($name)), HTML_SELECT_MAX_LENGTH);
|
||||||
|
|
||||||
$members = ($data['m']) ? $lang['MEMBERS_IN_GROUP'] . ': ' . $data['m'] : $lang['NO_GROUP_MEMBERS'];
|
$members = ($data['m']) ? $lang['MEMBERS_IN_GROUP'] . ': ' . $data['m'] : $lang['NO_GROUP_MEMBERS'];
|
||||||
$candidates = ($data['c']) ? $lang['PENDING_MEMBERS'] . ': ' . $data['c'] : $lang['NO_PENDING_GROUP_MEMBERS'];
|
$candidates = ($data['c']) ? $lang['PENDING_MEMBERS'] . ': ' . $data['c'] : $lang['NO_PENDING_GROUP_MEMBERS'];
|
||||||
|
@ -168,7 +168,7 @@ if (!$group_id) {
|
||||||
|
|
||||||
\TorrentPier\Legacy\Group::add_user_into_group($group_id, $userdata['user_id'], 1, TIMENOW);
|
\TorrentPier\Legacy\Group::add_user_into_group($group_id, $userdata['user_id'], 1, TIMENOW);
|
||||||
|
|
||||||
if ($bb_cfg['group_send_email']) {
|
if (config()->get('group_send_email')) {
|
||||||
// Sending email
|
// Sending email
|
||||||
$emailer = new TorrentPier\Emailer();
|
$emailer = new TorrentPier\Emailer();
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ if (!$group_id) {
|
||||||
|
|
||||||
\TorrentPier\Legacy\Group::add_user_into_group($group_id, $row['user_id']);
|
\TorrentPier\Legacy\Group::add_user_into_group($group_id, $row['user_id']);
|
||||||
|
|
||||||
if ($bb_cfg['group_send_email']) {
|
if (config()->get('group_send_email')) {
|
||||||
// Sending email
|
// Sending email
|
||||||
$emailer = new TorrentPier\Emailer();
|
$emailer = new TorrentPier\Emailer();
|
||||||
|
|
||||||
|
@ -273,10 +273,10 @@ if (!$group_id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Email users when they are approved
|
// Email users when they are approved
|
||||||
if (!empty($_POST['approve']) && $bb_cfg['group_send_email']) {
|
if (!empty($_POST['approve']) && config()->get('group_send_email')) {
|
||||||
$sql_select = "SELECT username, user_email, user_lang
|
$sql_select = "SELECT username, user_email, user_lang
|
||||||
FROM " . BB_USERS . "
|
FROM " . BB_USERS . "
|
||||||
WHERE user_id IN($sql_in)";
|
WHERE user_id IN($sql_in)";
|
||||||
|
|
||||||
if (!$result = DB()->sql_query($sql_select)) {
|
if (!$result = DB()->sql_query($sql_select)) {
|
||||||
bb_die('Could not get user email information');
|
bb_die('Could not get user email information');
|
||||||
|
@ -573,7 +573,7 @@ if (!$group_id) {
|
||||||
$template->assign_block_vars('pending', [
|
$template->assign_block_vars('pending', [
|
||||||
'ROW_CLASS' => $row_class,
|
'ROW_CLASS' => $row_class,
|
||||||
'AVATAR_IMG' => $pending_info['avatar'],
|
'AVATAR_IMG' => $pending_info['avatar'],
|
||||||
'USER' => profile_url($pending_info),
|
'USER' => profile_url($member),
|
||||||
'FROM' => $pending_info['from'],
|
'FROM' => $pending_info['from'],
|
||||||
'JOINED' => $pending_info['joined'],
|
'JOINED' => $pending_info['joined'],
|
||||||
'JOINED_RAW' => $pending_info['joined_raw'],
|
'JOINED_RAW' => $pending_info['joined_raw'],
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -35,10 +35,10 @@ if ($group_id) {
|
||||||
if ($is_moderator) {
|
if ($is_moderator) {
|
||||||
// Avatar
|
// Avatar
|
||||||
if ($submit) {
|
if ($submit) {
|
||||||
if (!empty($_FILES['avatar']['name']) && $bb_cfg['group_avatars']['up_allowed']) {
|
if (!empty($_FILES['avatar']['name']) && config()->get('group_avatars.up_allowed')) {
|
||||||
$upload = new TorrentPier\Legacy\Common\Upload();
|
$upload = new TorrentPier\Legacy\Common\Upload();
|
||||||
|
|
||||||
if ($upload->init($bb_cfg['group_avatars'], $_FILES['avatar']) and $upload->store('avatar', ['user_id' => GROUP_AVATAR_MASK . $group_id, 'avatar_ext_id' => $group_info['avatar_ext_id']])) {
|
if ($upload->init(config()->get('group_avatars'), $_FILES['avatar']) and $upload->store('avatar', ['user_id' => GROUP_AVATAR_MASK . $group_id, 'avatar_ext_id' => $group_info['avatar_ext_id']])) {
|
||||||
$avatar_ext_id = (int)$upload->file_ext_id;
|
$avatar_ext_id = (int)$upload->file_ext_id;
|
||||||
DB()->query("UPDATE " . BB_GROUPS . " SET avatar_ext_id = $avatar_ext_id WHERE group_id = $group_id LIMIT 1");
|
DB()->query("UPDATE " . BB_GROUPS . " SET avatar_ext_id = $avatar_ext_id WHERE group_id = $group_id LIMIT 1");
|
||||||
} else {
|
} else {
|
||||||
|
@ -76,7 +76,7 @@ if ($is_moderator) {
|
||||||
'S_HIDDEN_FIELDS' => $s_hidden_fields,
|
'S_HIDDEN_FIELDS' => $s_hidden_fields,
|
||||||
'S_GROUP_CONFIG_ACTION' => "group_edit.php?" . POST_GROUPS_URL . "=$group_id",
|
'S_GROUP_CONFIG_ACTION' => "group_edit.php?" . POST_GROUPS_URL . "=$group_id",
|
||||||
|
|
||||||
'AVATAR_EXPLAIN' => sprintf($lang['AVATAR_EXPLAIN'], $bb_cfg['group_avatars']['max_width'], $bb_cfg['group_avatars']['max_height'], humn_size($bb_cfg['group_avatars']['max_size'])),
|
'AVATAR_EXPLAIN' => sprintf($lang['AVATAR_EXPLAIN'], config()->get('group_avatars.max_width'), config()->get('group_avatars.max_height'), humn_size(config()->get('group_avatars.max_size'))),
|
||||||
'AVATAR_IMG' => get_avatar(GROUP_AVATAR_MASK . $group_id, $group_info['avatar_ext_id']),
|
'AVATAR_IMG' => get_avatar(GROUP_AVATAR_MASK . $group_id, $group_info['avatar_ext_id']),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
69
index.php
69
index.php
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -31,12 +31,12 @@ $datastore->enqueue([
|
||||||
'cat_forums'
|
'cat_forums'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($bb_cfg['show_latest_news']) {
|
if (config()->get('show_latest_news')) {
|
||||||
$datastore->enqueue([
|
$datastore->enqueue([
|
||||||
'latest_news'
|
'latest_news'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
if ($bb_cfg['show_network_news']) {
|
if (config()->get('show_network_news')) {
|
||||||
$datastore->enqueue([
|
$datastore->enqueue([
|
||||||
'network_news'
|
'network_news'
|
||||||
]);
|
]);
|
||||||
|
@ -45,8 +45,11 @@ if ($bb_cfg['show_network_news']) {
|
||||||
// Init userdata
|
// Init userdata
|
||||||
$user->session_start();
|
$user->session_start();
|
||||||
|
|
||||||
|
// Set meta description
|
||||||
|
$page_cfg['meta_description'] = config()->get('site_desc');
|
||||||
|
|
||||||
// Init main vars
|
// Init main vars
|
||||||
$viewcat = isset($_GET['c']) ? (int)$_GET['c'] : 0;
|
$viewcat = isset($_GET[POST_CAT_URL]) ? (int)$_GET[POST_CAT_URL] : 0;
|
||||||
$lastvisit = IS_GUEST ? TIMENOW : $userdata['user_lastvisit'];
|
$lastvisit = IS_GUEST ? TIMENOW : $userdata['user_lastvisit'];
|
||||||
|
|
||||||
// Caching output
|
// Caching output
|
||||||
|
@ -54,7 +57,7 @@ $req_page = 'index_page';
|
||||||
$req_page .= $viewcat ? "_c{$viewcat}" : '';
|
$req_page .= $viewcat ? "_c{$viewcat}" : '';
|
||||||
|
|
||||||
define('REQUESTED_PAGE', $req_page);
|
define('REQUESTED_PAGE', $req_page);
|
||||||
caching_output(IS_GUEST, 'send', REQUESTED_PAGE . '_guest_' . $bb_cfg['default_lang']);
|
caching_output(IS_GUEST, 'send', REQUESTED_PAGE . '_guest_' . config()->get('default_lang'));
|
||||||
|
|
||||||
$hide_cat_opt = isset($user->opt_js['h_cat']) ? (string)$user->opt_js['h_cat'] : 0;
|
$hide_cat_opt = isset($user->opt_js['h_cat']) ? (string)$user->opt_js['h_cat'] : 0;
|
||||||
$hide_cat_user = array_flip(explode('-', $hide_cat_opt));
|
$hide_cat_user = array_flip(explode('-', $hide_cat_opt));
|
||||||
|
@ -65,13 +68,15 @@ $tracking_topics = get_tracks('topic');
|
||||||
$tracking_forums = get_tracks('forum');
|
$tracking_forums = get_tracks('forum');
|
||||||
|
|
||||||
// Statistics
|
// Statistics
|
||||||
if (!$stats = $datastore->get('stats') and !$datastore->has('stats')) {
|
$stats = $datastore->get('stats');
|
||||||
|
if ($stats === false) {
|
||||||
$datastore->update('stats');
|
$datastore->update('stats');
|
||||||
$stats = $datastore->get('stats');
|
$stats = $datastore->get('stats');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forums data
|
// Forums data
|
||||||
if (!$forums = $datastore->get('cat_forums') and !$datastore->has('cat_forums')) {
|
$forums = $datastore->get('cat_forums');
|
||||||
|
if ($forums === false) {
|
||||||
$datastore->update('cat_forums');
|
$datastore->update('cat_forums');
|
||||||
$forums = $datastore->get('cat_forums');
|
$forums = $datastore->get('cat_forums');
|
||||||
}
|
}
|
||||||
|
@ -80,6 +85,7 @@ $forum_name_html = $forums['forum_name_html'];
|
||||||
|
|
||||||
$anon = GUEST_UID;
|
$anon = GUEST_UID;
|
||||||
$excluded_forums_csv = $user->get_excluded_forums(AUTH_VIEW);
|
$excluded_forums_csv = $user->get_excluded_forums(AUTH_VIEW);
|
||||||
|
$excluded_forums_array = $excluded_forums_csv ? explode(',', $excluded_forums_csv) : [];
|
||||||
$only_new = $user->opt_js['only_new'];
|
$only_new = $user->opt_js['only_new'];
|
||||||
|
|
||||||
// Validate requested category id
|
// Validate requested category id
|
||||||
|
@ -173,7 +179,8 @@ if (!$cat_forums = CACHE('bb_cache')->get($cache_name)) {
|
||||||
|
|
||||||
// Obtain list of moderators
|
// Obtain list of moderators
|
||||||
$moderators = [];
|
$moderators = [];
|
||||||
if (!$mod = $datastore->get('moderators') and !$datastore->has('moderators')) {
|
$mod = $datastore->get('moderators');
|
||||||
|
if ($mod === false) {
|
||||||
$datastore->update('moderators');
|
$datastore->update('moderators');
|
||||||
$mod = $datastore->get('moderators');
|
$mod = $datastore->get('moderators');
|
||||||
}
|
}
|
||||||
|
@ -255,7 +262,7 @@ foreach ($cat_forums as $cid => $c) {
|
||||||
'LAST_TOPIC_ID' => $f['last_topic_id'],
|
'LAST_TOPIC_ID' => $f['last_topic_id'],
|
||||||
'LAST_TOPIC_TIP' => $f['last_topic_title'],
|
'LAST_TOPIC_TIP' => $f['last_topic_title'],
|
||||||
'LAST_TOPIC_TITLE' => str_short($f['last_topic_title'], $last_topic_max_len),
|
'LAST_TOPIC_TITLE' => str_short($f['last_topic_title'], $last_topic_max_len),
|
||||||
'LAST_POST_TIME' => bb_date($f['last_post_time'], $bb_cfg['last_post_date_format']),
|
'LAST_POST_TIME' => bb_date($f['last_post_time'], config()->get('last_post_date_format')),
|
||||||
'LAST_POST_USER' => profile_url(['username' => str_short($f['last_post_username'], 15), 'user_id' => $f['last_post_user_id'], 'user_rank' => $f['last_post_user_rank']]),
|
'LAST_POST_USER' => profile_url(['username' => str_short($f['last_post_username'], 15), 'user_id' => $f['last_post_user_id'], 'user_rank' => $f['last_post_user_rank']]),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -271,7 +278,7 @@ $template->assign_vars([
|
||||||
'TOTAL_TOPICS' => sprintf($lang['POSTED_TOPICS_TOTAL'], $stats['topiccount']),
|
'TOTAL_TOPICS' => sprintf($lang['POSTED_TOPICS_TOTAL'], $stats['topiccount']),
|
||||||
'TOTAL_POSTS' => sprintf($lang['POSTED_ARTICLES_TOTAL'], $stats['postcount']),
|
'TOTAL_POSTS' => sprintf($lang['POSTED_ARTICLES_TOTAL'], $stats['postcount']),
|
||||||
'TOTAL_USERS' => sprintf($lang['REGISTERED_USERS_TOTAL'], $stats['usercount']),
|
'TOTAL_USERS' => sprintf($lang['REGISTERED_USERS_TOTAL'], $stats['usercount']),
|
||||||
'TOTAL_GENDER' => $bb_cfg['gender'] ? sprintf(
|
'TOTAL_GENDER' => config()->get('gender') ? sprintf(
|
||||||
$lang['USERS_TOTAL_GENDER'],
|
$lang['USERS_TOTAL_GENDER'],
|
||||||
$stats['male'],
|
$stats['male'],
|
||||||
$stats['female'],
|
$stats['female'],
|
||||||
|
@ -280,22 +287,22 @@ $template->assign_vars([
|
||||||
'NEWEST_USER' => sprintf($lang['NEWEST_USER'], profile_url($stats['newestuser'])),
|
'NEWEST_USER' => sprintf($lang['NEWEST_USER'], profile_url($stats['newestuser'])),
|
||||||
|
|
||||||
// Tracker stats
|
// Tracker stats
|
||||||
'TORRENTS_STAT' => $bb_cfg['tor_stats'] ? sprintf(
|
'TORRENTS_STAT' => config()->get('tor_stats') ? sprintf(
|
||||||
$lang['TORRENTS_STAT'],
|
$lang['TORRENTS_STAT'],
|
||||||
$stats['torrentcount'],
|
$stats['torrentcount'],
|
||||||
humn_size($stats['size'])
|
humn_size($stats['size'])
|
||||||
) : '',
|
) : '',
|
||||||
'PEERS_STAT' => $bb_cfg['tor_stats'] ? sprintf(
|
'PEERS_STAT' => config()->get('tor_stats') ? sprintf(
|
||||||
$lang['PEERS_STAT'],
|
$lang['PEERS_STAT'],
|
||||||
$stats['peers'],
|
$stats['peers'],
|
||||||
$stats['seeders'],
|
$stats['seeders'],
|
||||||
$stats['leechers']
|
$stats['leechers']
|
||||||
) : '',
|
) : '',
|
||||||
'SPEED_STAT' => $bb_cfg['tor_stats'] ? sprintf(
|
'SPEED_STAT' => config()->get('tor_stats') ? sprintf(
|
||||||
$lang['SPEED_STAT'],
|
$lang['SPEED_STAT'],
|
||||||
humn_size($stats['speed']) . '/s'
|
humn_size($stats['speed']) . '/s'
|
||||||
) : '',
|
) : '',
|
||||||
'SHOW_MOD_INDEX' => $bb_cfg['show_mod_index'],
|
'SHOW_MOD_INDEX' => config()->get('show_mod_index'),
|
||||||
'FORUM_IMG' => $images['forum'],
|
'FORUM_IMG' => $images['forum'],
|
||||||
'FORUM_NEW_IMG' => $images['forum_new'],
|
'FORUM_NEW_IMG' => $images['forum_new'],
|
||||||
'FORUM_LOCKED_IMG' => $images['forum_locked'],
|
'FORUM_LOCKED_IMG' => $images['forum_locked'],
|
||||||
|
@ -308,20 +315,21 @@ $template->assign_vars([
|
||||||
'U_SEARCH_SELF_BY_MY' => "search.php?uid={$userdata['user_id']}&o=1",
|
'U_SEARCH_SELF_BY_MY' => "search.php?uid={$userdata['user_id']}&o=1",
|
||||||
'U_SEARCH_LATEST' => 'search.php?search_id=latest',
|
'U_SEARCH_LATEST' => 'search.php?search_id=latest',
|
||||||
'U_SEARCH_UNANSWERED' => 'search.php?search_id=unanswered',
|
'U_SEARCH_UNANSWERED' => 'search.php?search_id=unanswered',
|
||||||
'U_ATOM_FEED' => is_file($bb_cfg['atom']['path'] . '/f/0.atom') ? make_url($bb_cfg['atom']['url'] . '/f/0.atom') : false,
|
'U_ATOM_FEED' => is_file(config()->get('atom.path') . '/f/0.atom') ? make_url(config()->get('atom.url') . '/f/0.atom') : false,
|
||||||
|
|
||||||
'SHOW_LAST_TOPIC' => $show_last_topic,
|
'SHOW_LAST_TOPIC' => $show_last_topic,
|
||||||
'BOARD_START' => $bb_cfg['show_board_start_index'] ? ($lang['BOARD_STARTED'] . ': ' . '<b>' . bb_date($bb_cfg['board_startdate']) . '</b>') : false,
|
'BOARD_START' => config()->get('show_board_start_index') ? ($lang['BOARD_STARTED'] . ': ' . '<b>' . bb_date(config()->get('board_startdate')) . '</b>') : false,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Set tpl vars for bt_userdata
|
// Set tpl vars for bt_userdata
|
||||||
if ($bb_cfg['bt_show_dl_stat_on_index'] && !IS_GUEST) {
|
if (config()->get('bt_show_dl_stat_on_index') && !IS_GUEST) {
|
||||||
show_bt_userdata($userdata['user_id']);
|
show_bt_userdata($userdata['user_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Latest news
|
// Latest news
|
||||||
if ($bb_cfg['show_latest_news']) {
|
if (config()->get('show_latest_news')) {
|
||||||
if (!$latest_news = $datastore->get('latest_news') and !$datastore->has('latest_news')) {
|
$latest_news = $datastore->get('latest_news');
|
||||||
|
if ($latest_news === false) {
|
||||||
$datastore->update('latest_news');
|
$datastore->update('latest_news');
|
||||||
$latest_news = $datastore->get('latest_news');
|
$latest_news = $datastore->get('latest_news');
|
||||||
}
|
}
|
||||||
|
@ -329,9 +337,13 @@ if ($bb_cfg['show_latest_news']) {
|
||||||
$template->assign_vars(['SHOW_LATEST_NEWS' => true]);
|
$template->assign_vars(['SHOW_LATEST_NEWS' => true]);
|
||||||
|
|
||||||
foreach ($latest_news as $news) {
|
foreach ($latest_news as $news) {
|
||||||
|
if (in_array($news['forum_id'], $excluded_forums_array)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$template->assign_block_vars('news', [
|
$template->assign_block_vars('news', [
|
||||||
'NEWS_TOPIC_ID' => $news['topic_id'],
|
'NEWS_TOPIC_ID' => $news['topic_id'],
|
||||||
'NEWS_TITLE' => str_short($wordCensor->censorString($news['topic_title']), $bb_cfg['max_news_title']),
|
'NEWS_TITLE' => str_short(censor()->censorString($news['topic_title']), config()->get('max_news_title')),
|
||||||
'NEWS_TIME' => bb_date($news['topic_time'], 'd-M', false),
|
'NEWS_TIME' => bb_date($news['topic_time'], 'd-M', false),
|
||||||
'NEWS_IS_NEW' => is_unread($news['topic_time'], $news['topic_id'], $news['forum_id']),
|
'NEWS_IS_NEW' => is_unread($news['topic_time'], $news['topic_id'], $news['forum_id']),
|
||||||
]);
|
]);
|
||||||
|
@ -339,8 +351,9 @@ if ($bb_cfg['show_latest_news']) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Network news
|
// Network news
|
||||||
if ($bb_cfg['show_network_news']) {
|
if (config()->get('show_network_news')) {
|
||||||
if (!$network_news = $datastore->get('network_news') and !$datastore->has('network_news')) {
|
$network_news = $datastore->get('network_news');
|
||||||
|
if ($network_news === false) {
|
||||||
$datastore->update('network_news');
|
$datastore->update('network_news');
|
||||||
$network_news = $datastore->get('network_news');
|
$network_news = $datastore->get('network_news');
|
||||||
}
|
}
|
||||||
|
@ -348,16 +361,20 @@ if ($bb_cfg['show_network_news']) {
|
||||||
$template->assign_vars(['SHOW_NETWORK_NEWS' => true]);
|
$template->assign_vars(['SHOW_NETWORK_NEWS' => true]);
|
||||||
|
|
||||||
foreach ($network_news as $net) {
|
foreach ($network_news as $net) {
|
||||||
|
if (in_array($net['forum_id'], $excluded_forums_array)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$template->assign_block_vars('net', [
|
$template->assign_block_vars('net', [
|
||||||
'NEWS_TOPIC_ID' => $net['topic_id'],
|
'NEWS_TOPIC_ID' => $net['topic_id'],
|
||||||
'NEWS_TITLE' => str_short($wordCensor->censorString($net['topic_title']), $bb_cfg['max_net_title']),
|
'NEWS_TITLE' => str_short(censor()->censorString($net['topic_title']), config()->get('max_net_title')),
|
||||||
'NEWS_TIME' => bb_date($net['topic_time'], 'd-M', false),
|
'NEWS_TIME' => bb_date($net['topic_time'], 'd-M', false),
|
||||||
'NEWS_IS_NEW' => is_unread($net['topic_time'], $net['topic_id'], $net['forum_id']),
|
'NEWS_IS_NEW' => is_unread($net['topic_time'], $net['topic_id'], $net['forum_id']),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($bb_cfg['birthday_check_day'] && $bb_cfg['birthday_enabled']) {
|
if (config()->get('birthday_check_day') && config()->get('birthday_enabled')) {
|
||||||
$week_list = $today_list = [];
|
$week_list = $today_list = [];
|
||||||
$week_all = $today_all = false;
|
$week_all = $today_all = false;
|
||||||
|
|
||||||
|
@ -371,9 +388,9 @@ if ($bb_cfg['birthday_check_day'] && $bb_cfg['birthday_enabled']) {
|
||||||
$week_list[] = profile_url($week) . ' <span class="small">(' . birthday_age(date('Y-m-d', strtotime('-1 year', strtotime($week['user_birthday'])))) . ')</span>';
|
$week_list[] = profile_url($week) . ' <span class="small">(' . birthday_age(date('Y-m-d', strtotime('-1 year', strtotime($week['user_birthday'])))) . ')</span>';
|
||||||
}
|
}
|
||||||
$week_all = $week_all ? ' <a class="txtb" href="#" onclick="ajax.exec({action: \'index_data\', mode: \'birthday_week\'}); return false;" title="' . $lang['ALL'] . '">...</a>' : '';
|
$week_all = $week_all ? ' <a class="txtb" href="#" onclick="ajax.exec({action: \'index_data\', mode: \'birthday_week\'}); return false;" title="' . $lang['ALL'] . '">...</a>' : '';
|
||||||
$week_list = sprintf($lang['BIRTHDAY_WEEK'], $bb_cfg['birthday_check_day'], implode(', ', $week_list)) . $week_all;
|
$week_list = sprintf($lang['BIRTHDAY_WEEK'], config()->get('birthday_check_day'), implode(', ', $week_list)) . $week_all;
|
||||||
} else {
|
} else {
|
||||||
$week_list = sprintf($lang['NOBIRTHDAY_WEEK'], $bb_cfg['birthday_check_day']);
|
$week_list = sprintf($lang['NOBIRTHDAY_WEEK'], config()->get('birthday_check_day'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($stats['birthday_today_list'])) {
|
if (!empty($stats['birthday_today_list'])) {
|
||||||
|
|
7
info.php
7
info.php
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -16,8 +16,9 @@ $user->session_start();
|
||||||
|
|
||||||
$info = [];
|
$info = [];
|
||||||
$htmlDir = LANG_DIR . 'html/';
|
$htmlDir = LANG_DIR . 'html/';
|
||||||
|
$show = isset($_REQUEST['show']) ? (string)$_REQUEST['show'] : '';
|
||||||
|
|
||||||
switch ((string)$_REQUEST['show'] ?? 'not_found') {
|
switch ($show) {
|
||||||
case 'advert':
|
case 'advert':
|
||||||
$info['title'] = $lang['ADVERT'];
|
$info['title'] = $lang['ADVERT'];
|
||||||
$info['src'] = 'advert.html';
|
$info['src'] = 'advert.html';
|
||||||
|
@ -43,7 +44,7 @@ switch ((string)$_REQUEST['show'] ?? 'not_found') {
|
||||||
$require = is_file($htmlDir . $info['src']) ? ($htmlDir . $info['src']) : false;
|
$require = is_file($htmlDir . $info['src']) ? ($htmlDir . $info['src']) : false;
|
||||||
|
|
||||||
$template->assign_vars([
|
$template->assign_vars([
|
||||||
'PAGE_TITLE' => mb_strtoupper($info['title'], 'UTF-8'),
|
'PAGE_TITLE' => mb_strtoupper($info['title'], DEFAULT_CHARSET),
|
||||||
'REQUIRE' => $require ? file_get_contents($require) : $lang['NOT_FOUND'],
|
'REQUIRE' => $require ? file_get_contents($require) : $lang['NOT_FOUND'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
290
install.php
290
install.php
|
@ -2,23 +2,30 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
define('BB_ROOT', __DIR__ . '/');
|
define('BB_ROOT', __DIR__ . DIRECTORY_SEPARATOR);
|
||||||
|
define('BB_PATH', BB_ROOT);
|
||||||
|
|
||||||
// Check CLI mode
|
// Check CLI mode
|
||||||
if (php_sapi_name() !== 'cli') {
|
if (PHP_SAPI != 'cli') {
|
||||||
die('Please run <code style="background:#222;color:#00e01f;padding:2px 6px;border-radius:3px;">php ' . basename(__FILE__) . '</code> in CLI mode');
|
die('Please run <code style="background:#222;color:#00e01f;padding:2px 6px;border-radius:3px;">php ' . basename(__FILE__) . '</code> in CLI mode');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get all constants
|
||||||
|
require_once BB_ROOT . 'library/defines.php';
|
||||||
|
|
||||||
|
// Include CLI functions
|
||||||
|
require INC_DIR . '/functions_cli.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* System requirements
|
* System requirements
|
||||||
*/
|
*/
|
||||||
define('CHECK_REQUIREMENTS', [
|
const CHECK_REQUIREMENTS = [
|
||||||
'php_min_version' => '8.1.0',
|
'php_min_version' => '8.2.0',
|
||||||
'ext_list' => [
|
'ext_list' => [
|
||||||
'json',
|
'json',
|
||||||
'curl',
|
'curl',
|
||||||
|
@ -29,128 +36,10 @@ define('CHECK_REQUIREMENTS', [
|
||||||
'intl',
|
'intl',
|
||||||
'xml',
|
'xml',
|
||||||
'xmlwriter',
|
'xmlwriter',
|
||||||
'zip'
|
'zip',
|
||||||
|
'gd'
|
||||||
],
|
],
|
||||||
]);
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* Colored console output
|
|
||||||
*
|
|
||||||
* @param string $str
|
|
||||||
* @param string $type
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function out(string $str, string $type = ''): void
|
|
||||||
{
|
|
||||||
echo match ($type) {
|
|
||||||
'error' => "\033[31m$str \033[0m\n",
|
|
||||||
'success' => "\033[32m$str \033[0m\n",
|
|
||||||
'warning' => "\033[33m$str \033[0m\n",
|
|
||||||
'info' => "\033[36m$str \033[0m\n",
|
|
||||||
'debug' => "\033[90m$str \033[0m\n",
|
|
||||||
default => "$str\n",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run process with realtime output
|
|
||||||
*
|
|
||||||
* @param string $cmd
|
|
||||||
* @param string|null $input
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function runProcess(string $cmd, string $input = null): void
|
|
||||||
{
|
|
||||||
$descriptorSpec = [
|
|
||||||
0 => ['pipe', 'r'],
|
|
||||||
1 => ['pipe', 'w'],
|
|
||||||
2 => ['pipe', 'w'],
|
|
||||||
];
|
|
||||||
|
|
||||||
$process = proc_open($cmd, $descriptorSpec, $pipes);
|
|
||||||
|
|
||||||
if (!is_resource($process)) {
|
|
||||||
out('- Could not start subprocess', 'error');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write input if provided
|
|
||||||
if ($input !== null) {
|
|
||||||
fwrite($pipes[0], $input);
|
|
||||||
fclose($pipes[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read and print output in real-time
|
|
||||||
while (!feof($pipes[1])) {
|
|
||||||
echo stream_get_contents($pipes[1], 1);
|
|
||||||
flush(); // Flush output buffer for immediate display
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read and print error output
|
|
||||||
while (!feof($pipes[2])) {
|
|
||||||
echo stream_get_contents($pipes[2], 1);
|
|
||||||
flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose($pipes[1]);
|
|
||||||
fclose($pipes[2]);
|
|
||||||
|
|
||||||
proc_close($process);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove directory recursively
|
|
||||||
*
|
|
||||||
* @param string $dir
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function rmdir_rec(string $dir): void
|
|
||||||
{
|
|
||||||
$it = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
|
|
||||||
$files = new RecursiveIteratorIterator($it,
|
|
||||||
RecursiveIteratorIterator::CHILD_FIRST);
|
|
||||||
foreach ($files as $file) {
|
|
||||||
if ($file->isDir()) {
|
|
||||||
rmdir($file->getPathname());
|
|
||||||
} else {
|
|
||||||
unlink($file->getPathname());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rmdir($dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setting permissions recursively
|
|
||||||
*
|
|
||||||
* @param string $dir
|
|
||||||
* @param int $dirPermissions
|
|
||||||
* @param int $filePermissions
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function chmod_r(string $dir, int $dirPermissions, int $filePermissions): void
|
|
||||||
{
|
|
||||||
$dp = opendir($dir);
|
|
||||||
while ($file = readdir($dp)) {
|
|
||||||
if (($file == '.') || ($file == '..')) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$fullPath = realpath($dir . '/' . $file);
|
|
||||||
if (is_dir($fullPath)) {
|
|
||||||
// out("- Directory: $fullPath");
|
|
||||||
chmod($fullPath, $dirPermissions);
|
|
||||||
chmod_r($fullPath, $dirPermissions, $filePermissions);
|
|
||||||
} elseif (is_file($fullPath)) {
|
|
||||||
// out("- File: $fullPath");
|
|
||||||
chmod($fullPath, $filePermissions);
|
|
||||||
} else {
|
|
||||||
out("- Cannot find target path: $fullPath", 'error');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir($dp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Welcoming message
|
// Welcoming message
|
||||||
out("--- TorrentPier Installer ---\n", 'info');
|
out("--- TorrentPier Installer ---\n", 'info');
|
||||||
|
@ -160,25 +49,31 @@ out("- Checking installed extensions...", 'info');
|
||||||
|
|
||||||
// [1] Check PHP Version
|
// [1] Check PHP Version
|
||||||
if (!version_compare(PHP_VERSION, CHECK_REQUIREMENTS['php_min_version'], '>=')) {
|
if (!version_compare(PHP_VERSION, CHECK_REQUIREMENTS['php_min_version'], '>=')) {
|
||||||
out("- TorrentPier requires PHP version " . CHECK_REQUIREMENTS['php_min_version'] . "+ Your PHP version " . PHP_VERSION, 'error');
|
out("- TorrentPier requires PHP version " . CHECK_REQUIREMENTS['php_min_version'] . "+ Your PHP version " . PHP_VERSION, 'warning');
|
||||||
}
|
}
|
||||||
|
|
||||||
// [2] Check installed PHP Extensions on server
|
// [2] Check installed PHP Extensions on server
|
||||||
foreach (CHECK_REQUIREMENTS['ext_list'] as $ext) {
|
foreach (CHECK_REQUIREMENTS['ext_list'] as $ext) {
|
||||||
if (!extension_loaded($ext)) {
|
if (!extension_loaded($ext)) {
|
||||||
out("- ext-$ext not installed", 'error');
|
out("- ext-$ext not installed. Check out php.ini file", 'error');
|
||||||
exit;
|
if (!defined('EXTENSIONS_NOT_INSTALLED')) {
|
||||||
|
define('EXTENSIONS_NOT_INSTALLED', true);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
out("- ext-$ext installed!");
|
out("- ext-$ext installed!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out("- All extensions are installed!\n", 'success');
|
if (!defined('EXTENSIONS_NOT_INSTALLED')) {
|
||||||
|
out("- All extensions are installed!\n", 'success');
|
||||||
|
} else {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if already installed
|
// Check if already installed
|
||||||
if (is_file(BB_ROOT . '.env')) {
|
if (is_file(BB_ROOT . '.env')) {
|
||||||
out('- TorrentPier already installed', 'warning');
|
out('- TorrentPier already installed', 'warning');
|
||||||
echo 'Are you sure want to re-install TorrentPier? [y/N]: ';
|
echo 'Are you sure want to re-install TorrentPier? [y/N]: ';
|
||||||
if (readline() === 'y') {
|
if (str_starts_with(mb_strtolower(trim(readline())), 'y')) {
|
||||||
out("\n- Re-install process started...", 'info');
|
out("\n- Re-install process started...", 'info');
|
||||||
// environment
|
// environment
|
||||||
if (is_file(BB_ROOT . '.env')) {
|
if (is_file(BB_ROOT . '.env')) {
|
||||||
|
@ -200,7 +95,7 @@ if (is_file(BB_ROOT . '.env')) {
|
||||||
}
|
}
|
||||||
// composer dir
|
// composer dir
|
||||||
if (is_dir(BB_ROOT . 'vendor')) {
|
if (is_dir(BB_ROOT . 'vendor')) {
|
||||||
rmdir_rec(BB_ROOT . 'vendor');
|
removeDir(BB_ROOT . 'vendor', true);
|
||||||
if (!is_dir(BB_ROOT . 'vendor')) {
|
if (!is_dir(BB_ROOT . 'vendor')) {
|
||||||
out("- Composer directory successfully removed!");
|
out("- Composer directory successfully removed!");
|
||||||
} else {
|
} else {
|
||||||
|
@ -209,6 +104,7 @@ if (is_file(BB_ROOT . '.env')) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out("- Re-install process completed!\n", 'success');
|
out("- Re-install process completed!\n", 'success');
|
||||||
|
out('- Starting installation...', 'info');
|
||||||
} else {
|
} else {
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
@ -230,27 +126,42 @@ if (!is_file(BB_ROOT . 'vendor/autoload.php')) {
|
||||||
out('- Downloading Composer...', 'info');
|
out('- Downloading Composer...', 'info');
|
||||||
if (copy('https://getcomposer.org/installer', BB_ROOT . 'composer-setup.php')) {
|
if (copy('https://getcomposer.org/installer', BB_ROOT . 'composer-setup.php')) {
|
||||||
out("- Composer successfully downloaded!\n", 'success');
|
out("- Composer successfully downloaded!\n", 'success');
|
||||||
runProcess('php ' . BB_ROOT . 'composer-setup.php');
|
runProcess('php ' . BB_ROOT . 'composer-setup.php --install-dir=' . BB_ROOT);
|
||||||
} else {
|
} else {
|
||||||
out('- Cannot download Composer', 'error');
|
out('- Cannot download Composer. Please, download it (composer.phar) manually', 'error');
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
if (is_file(BB_ROOT . 'composer-setup.php')) {
|
if (is_file(BB_ROOT . 'composer-setup.php')) {
|
||||||
if (unlink(BB_ROOT . 'composer-setup.php')) {
|
if (unlink(BB_ROOT . 'composer-setup.php')) {
|
||||||
out("- Composer installation file successfully removed!\n", 'success');
|
out("- Composer installation file successfully removed!\n", 'success');
|
||||||
} else {
|
} else {
|
||||||
out('- Cannot remove Composer installation file. Delete it manually', 'warning');
|
out('- Cannot remove Composer installation file (composer-setup.php). Please, delete it manually', 'warning');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
out("- composer.phar file found!\n", 'success');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Installing dependencies
|
// Installing dependencies
|
||||||
if (is_file(BB_ROOT . 'composer.phar')) {
|
if (is_file(BB_ROOT . 'composer.phar')) {
|
||||||
out('- Installing dependencies...', 'info');
|
out('- Installing dependencies...', 'info');
|
||||||
|
|
||||||
runProcess('php ' . BB_ROOT . 'composer.phar install --no-interaction --no-ansi');
|
runProcess('php ' . BB_ROOT . 'composer.phar install --no-interaction --no-ansi');
|
||||||
|
define('COMPOSER_COMPLETED', true);
|
||||||
|
} else {
|
||||||
|
out('- composer.phar not found. Please, download it (composer.phar) manually', 'error');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out('- Composer dependencies are present!', 'success');
|
||||||
|
out("- Note: Remove 'vendor' folder if you want to re-install dependencies\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check composer dependencies
|
||||||
|
if (defined('COMPOSER_COMPLETED')) {
|
||||||
|
if (is_file(BB_ROOT . 'vendor/autoload.php')) {
|
||||||
out("- Completed! Composer dependencies are installed!\n", 'success');
|
out("- Completed! Composer dependencies are installed!\n", 'success');
|
||||||
} else {
|
} else {
|
||||||
out('- composer.phar not found', 'error');
|
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,7 +177,7 @@ if (is_file(BB_ROOT . '.env.example') && !is_file(BB_ROOT . '.env')) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Editing ENV file
|
// Editing ENV file
|
||||||
$DB_HOST = '';
|
$DB_HOST = 'localhost';
|
||||||
$DB_PORT = 3306;
|
$DB_PORT = 3306;
|
||||||
$DB_DATABASE = '';
|
$DB_DATABASE = '';
|
||||||
$DB_USERNAME = '';
|
$DB_USERNAME = '';
|
||||||
|
@ -287,23 +198,23 @@ if (is_file(BB_ROOT . '.env')) {
|
||||||
if (trim($line) !== '' && !str_starts_with($line, '#')) {
|
if (trim($line) !== '' && !str_starts_with($line, '#')) {
|
||||||
$parts = explode('=', $line, 2);
|
$parts = explode('=', $line, 2);
|
||||||
$key = trim($parts[0]);
|
$key = trim($parts[0]);
|
||||||
$value = isset($parts[1]) ? trim($parts[1]) : '';
|
$value = (!empty($parts[1]) && $key !== 'DB_PASSWORD') ? trim($parts[1]) : '';
|
||||||
|
|
||||||
// Database default values
|
|
||||||
if (in_array($key, ['DB_HOST', 'DB_PORT', 'DB_DATABASE', 'DB_USERNAME', 'DB_PASSWORD'])) {
|
|
||||||
$$key = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
out("\nCurrent value of $key: $value", 'debug');
|
out("\nCurrent value of $key: $value", 'debug');
|
||||||
echo "Enter a new value for $key (or leave empty to not change): ";
|
echo "Enter a new value for $key (or leave empty to not change): ";
|
||||||
$newValue = readline();
|
$newValue = trim(readline());
|
||||||
|
|
||||||
if (!empty($newValue)) {
|
if (!empty($newValue) || $key === 'DB_PASSWORD') {
|
||||||
$line = "$key=$newValue";
|
if ($key === 'TP_HOST') {
|
||||||
// Configuring database connection
|
if (!preg_match('/^https?:\/\//', $newValue)) {
|
||||||
if (in_array($key, ['DB_HOST', 'DB_PORT', 'DB_DATABASE', 'DB_USERNAME', 'DB_PASSWORD'])) {
|
$newValue = 'https://' . $newValue;
|
||||||
$$key = $newValue;
|
}
|
||||||
|
$newValue = parse_url($newValue, PHP_URL_HOST);
|
||||||
}
|
}
|
||||||
|
$line = "$key=$newValue";
|
||||||
|
$$key = $newValue;
|
||||||
|
} else {
|
||||||
|
$$key = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +256,7 @@ if (!empty($DB_HOST) && !empty($DB_DATABASE) && !empty($DB_USERNAME)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creating database if not exist
|
// Creating database if not exist
|
||||||
if ($conn->query("CREATE DATABASE IF NOT EXISTS $DB_DATABASE")) {
|
if ($conn->query("CREATE DATABASE IF NOT EXISTS $DB_DATABASE CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci")) {
|
||||||
out('- Database created successfully!', 'success');
|
out('- Database created successfully!', 'success');
|
||||||
} else {
|
} else {
|
||||||
out("- Cannot create database: $DB_DATABASE", 'error');
|
out("- Cannot create database: $DB_DATABASE", 'error');
|
||||||
|
@ -353,35 +264,68 @@ if (!empty($DB_HOST) && !empty($DB_DATABASE) && !empty($DB_USERNAME)) {
|
||||||
}
|
}
|
||||||
$conn->select_db($DB_DATABASE);
|
$conn->select_db($DB_DATABASE);
|
||||||
|
|
||||||
// Checking SQL dump
|
// Close database connection - migrations will handle their own connections
|
||||||
$dumpPath = BB_ROOT . 'install/sql/mysql.sql';
|
$conn->close();
|
||||||
if (is_file($dumpPath) && is_readable($dumpPath)) {
|
|
||||||
out('- SQL dump file found and readable!', 'success');
|
// Run database migrations
|
||||||
} else {
|
out('- Setting up database using migrations...', 'info');
|
||||||
out('- SQL dump file not found / not readable', 'error');
|
|
||||||
|
// Check if phinx.php exists
|
||||||
|
if (!is_file(BB_ROOT . 'phinx.php')) {
|
||||||
|
out('- Migration configuration (phinx.php) not found', 'error');
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inserting SQL dump
|
// Run migrations
|
||||||
out('- Start importing SQL dump...', 'info');
|
$migrationResult = runProcess('php vendor/bin/phinx migrate --configuration=' . BB_ROOT . 'phinx.php');
|
||||||
$tempLine = '';
|
if ($migrationResult !== 0) {
|
||||||
foreach (file($dumpPath) as $line) {
|
out('- Database migration failed', 'error');
|
||||||
if (str_starts_with($line, '--') || $line == '') {
|
exit;
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$tempLine .= $line;
|
out("- Database setup completed!\n", 'success');
|
||||||
if (str_ends_with(trim($line), ';')) {
|
|
||||||
if (!$conn->query($tempLine)) {
|
// Autofill host in robots.txt
|
||||||
out("- Error performing query: $tempLine", 'error');
|
$robots_txt_file = BB_ROOT . 'robots.txt';
|
||||||
exit;
|
if (isset($TP_HOST) && is_file($robots_txt_file)) {
|
||||||
|
$content = file_get_contents($robots_txt_file);
|
||||||
|
$content = str_replace('example.com', $TP_HOST, $content);
|
||||||
|
file_put_contents($robots_txt_file, $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($APP_ENV) && $APP_ENV === 'local') {
|
||||||
|
if (!is_file(BB_ROOT . 'library/config.local.php')) {
|
||||||
|
if (copy(BB_ROOT . 'library/config.php', BB_ROOT . 'library/config.local.php')) {
|
||||||
|
out('- Local configuration file created!', 'success');
|
||||||
|
} else {
|
||||||
|
out('- Cannot create library/config.local.php file. You can create it manually, just copy config.php and rename it to config.local.php', 'warning');
|
||||||
}
|
}
|
||||||
$tempLine = '';
|
}
|
||||||
|
} else {
|
||||||
|
if (rename(__FILE__, __FILE__ . '_' . hash('xxh128', time()))) {
|
||||||
|
out("- Installation file renamed!", 'success');
|
||||||
|
} else {
|
||||||
|
out('- Cannot rename installation file (' . __FILE__ . '). Please, rename it manually for security reasons', 'warning');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$conn->close();
|
// Cleanup...
|
||||||
out("- Importing SQL dump completed!\n", 'success');
|
if (is_file(BB_ROOT . '_cleanup.php')) {
|
||||||
out("- Voila! Good luck & have fun!", 'success');
|
out("\n--- Finishing installation (Cleanup) ---\n", 'info');
|
||||||
rename(__FILE__, hash('md5', time()));
|
out('The cleanup process will remove:');
|
||||||
|
out('- Development documentation (README, CHANGELOG)', 'debug');
|
||||||
|
out('- Git configuration files', 'debug');
|
||||||
|
out('- CI/CD pipelines and code analysis tools', 'debug');
|
||||||
|
out('- Translation and contribution guidelines', 'debug');
|
||||||
|
echo 'Do you want to delete these files permanently? [y/N]: ';
|
||||||
|
if (str_starts_with(mb_strtolower(trim(readline())), 'y')) {
|
||||||
|
out("\n- Cleanup...", 'info');
|
||||||
|
require_once BB_ROOT . '_cleanup.php';
|
||||||
|
unlink(BB_ROOT . '_cleanup.php');
|
||||||
|
} else {
|
||||||
|
out('- Skipping...', 'info');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out("\n- Voila! Good luck & have fun!", 'success');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Require all denied
|
|
27
install/Caddyfile
Normal file
27
install/Caddyfile
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# Example Caddy configuration for TorrentPier
|
||||||
|
|
||||||
|
example.com {
|
||||||
|
root * /path/to/root
|
||||||
|
encode gzip zstd
|
||||||
|
php_fastcgi unix//run/php/php-fpm.sock
|
||||||
|
try_files {path} {path}/ /index.php?{query}
|
||||||
|
file_server
|
||||||
|
|
||||||
|
@blocked {
|
||||||
|
path /install/* /internal_data/* /library/*
|
||||||
|
path /.ht* /.en*
|
||||||
|
path /.git/*
|
||||||
|
path *.sql *.tpl *.db *.inc *.log *.md
|
||||||
|
}
|
||||||
|
respond @blocked 404
|
||||||
|
|
||||||
|
redir /sitemap.xml /sitemap/sitemap.xml
|
||||||
|
|
||||||
|
@html_css_js {
|
||||||
|
path *.html *.css *.js *.json *.xml *.txt
|
||||||
|
}
|
||||||
|
header @html_css_js Content-Type "{mime}; charset=utf-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Refer to the Caddy docs for more information:
|
||||||
|
# https://caddyserver.com/docs/caddyfile
|
39
install/nginx.conf
Normal file
39
install/nginx.conf
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# Example nginx configuration for TorrentPier
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80; # port
|
||||||
|
server_name example.com; # your domain
|
||||||
|
root /path/to/root; # folder with TorrentPier installed
|
||||||
|
index index.php;
|
||||||
|
charset utf-8;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files \$uri \$uri/ /index.php?\$args;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ \/(install|internal_data|library)\/ {
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ /\.(ht|en) {
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ /\.git {
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ \.(.*sql|tpl|db|inc|log|md)$ {
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
|
||||||
|
rewrite ^/sitemap.xml$ /sitemap/sitemap.xml;
|
||||||
|
|
||||||
|
location ~ \.php$ {
|
||||||
|
include fastcgi_params;
|
||||||
|
fastcgi_pass unix:/run/php/php-fpm.sock;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
|
||||||
|
include fastcgi_params;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,57 +0,0 @@
|
||||||
SET SQL_MODE = "";
|
|
||||||
|
|
||||||
-- ----------------------------
|
|
||||||
-- Table structure for `bb_bt_tracker`
|
|
||||||
-- ----------------------------
|
|
||||||
DROP TABLE IF EXISTS `bb_bt_tracker`;
|
|
||||||
CREATE TABLE IF NOT EXISTS `bb_bt_tracker`
|
|
||||||
(
|
|
||||||
`peer_hash` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
|
||||||
`topic_id` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`peer_id` varchar(20) NOT NULL,
|
|
||||||
`user_id` mediumint(9) NOT NULL DEFAULT '0',
|
|
||||||
`ip` varchar(42) NOT NULL DEFAULT '0',
|
|
||||||
`ipv6` varchar(32) DEFAULT NULL,
|
|
||||||
`port` smallint(5) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`client` varchar(51) NOT NULL DEFAULT 'Unknown',
|
|
||||||
`seeder` tinyint(1) NOT NULL DEFAULT '0',
|
|
||||||
`releaser` tinyint(1) NOT NULL DEFAULT '0',
|
|
||||||
`tor_type` tinyint(1) NOT NULL DEFAULT '0',
|
|
||||||
`uploaded` bigint(20) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`downloaded` bigint(20) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`remain` bigint(20) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`speed_up` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`speed_down` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`up_add` bigint(20) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`down_add` bigint(20) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`update_time` int(11) NOT NULL DEFAULT '0',
|
|
||||||
`complete_percent` bigint(20) NOT NULL DEFAULT '0',
|
|
||||||
PRIMARY KEY (`peer_hash`),
|
|
||||||
KEY `topic_id` (`topic_id`),
|
|
||||||
KEY `user_id` (`user_id`)
|
|
||||||
) ENGINE = MyISAM
|
|
||||||
DEFAULT CHARSET = utf8;
|
|
||||||
|
|
||||||
-- ----------------------------
|
|
||||||
-- Records of bb_bt_tracker
|
|
||||||
-- ----------------------------
|
|
||||||
|
|
||||||
-- ----------------------------
|
|
||||||
-- Table structure for `bb_bt_tracker_snap`
|
|
||||||
-- ----------------------------
|
|
||||||
DROP TABLE IF EXISTS `bb_bt_tracker_snap`;
|
|
||||||
CREATE TABLE IF NOT EXISTS `bb_bt_tracker_snap`
|
|
||||||
(
|
|
||||||
`topic_id` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`seeders` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`leechers` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`speed_up` int(10) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`speed_down` int(10) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`complete` int(11) NOT NULL DEFAULT '0',
|
|
||||||
PRIMARY KEY (`topic_id`)
|
|
||||||
) ENGINE = MyISAM
|
|
||||||
DEFAULT CHARSET = utf8;
|
|
||||||
|
|
||||||
-- ----------------------------
|
|
||||||
-- Records of bb_bt_tracker_snap
|
|
||||||
-- ----------------------------
|
|
|
@ -1,96 +0,0 @@
|
||||||
Схема изменений начиная с версии 2.1.5:
|
|
||||||
|
|
||||||
Изменения в базе:
|
|
||||||
|
|
||||||
// 2.2.0
|
|
||||||
UPDATE `bb_config` SET `config_value` = 'http://whatismyipaddress.com/ip/' WHERE `config_name` = 'whois_info';
|
|
||||||
DELETE FROM `bb_smilies` WHERE `code` = ':ad:';
|
|
||||||
INSERT INTO `bb_smilies` (`code`, `smile_url`, `emoticon`) VALUES (':сd:', 'сd.gif', 'сd');
|
|
||||||
DROP TABLE IF EXISTS `bb_ads`;
|
|
||||||
DELETE FROM `bb_config` WHERE `config_name` = 'active_ads';
|
|
||||||
ALTER TABLE `bb_log` DROP COLUMN `log_username`;
|
|
||||||
DELETE FROM `bb_config` WHERE `config_name` = 'new_tpls';
|
|
||||||
UPDATE `bb_posts` SET `poster_ip` = '0';
|
|
||||||
ALTER TABLE `bb_posts` CHANGE `poster_ip` `poster_ip` varchar(42) NOT NULL DEFAULT '0';
|
|
||||||
UPDATE `bb_bt_tracker` SET `ip` = '0';
|
|
||||||
ALTER TABLE `bb_bt_tracker` CHANGE `ip` `ip` varchar(42) NOT NULL DEFAULT '0';
|
|
||||||
UPDATE `bb_users` SET `user_last_ip` = '0';
|
|
||||||
ALTER TABLE `bb_users` CHANGE `user_last_ip` `user_last_ip` varchar(42) NOT NULL DEFAULT '0';
|
|
||||||
UPDATE `bb_users` SET `user_reg_ip` = '0';
|
|
||||||
ALTER TABLE `bb_users` CHANGE `user_reg_ip` `user_reg_ip` varchar(42) NOT NULL DEFAULT '0';
|
|
||||||
UPDATE `bb_log` SET `log_user_ip` = '0';
|
|
||||||
ALTER TABLE `bb_log` CHANGE `log_user_ip` `log_user_ip` varchar(42) NOT NULL DEFAULT '0';
|
|
||||||
UPDATE `bb_poll_users` SET `vote_ip` = '0';
|
|
||||||
ALTER TABLE `bb_poll_users` CHANGE `vote_ip` `vote_ip` varchar(42) NOT NULL DEFAULT '0';
|
|
||||||
UPDATE `bb_privmsgs` SET `privmsgs_ip` = '0';
|
|
||||||
ALTER TABLE `bb_privmsgs` CHANGE `privmsgs_ip` `privmsgs_ip` varchar(42) NOT NULL DEFAULT '0';
|
|
||||||
UPDATE `bb_sessions` SET `session_ip` = '0';
|
|
||||||
ALTER TABLE `bb_sessions` CHANGE `session_ip` `session_ip` varchar(42) NOT NULL DEFAULT '0';
|
|
||||||
UPDATE `bb_banlist` SET `ban_ip` = '0';
|
|
||||||
ALTER TABLE `bb_banlist` CHANGE `ban_ip` `ban_ip` varchar(42) NOT NULL DEFAULT '0';
|
|
||||||
|
|
||||||
// 2.2.2
|
|
||||||
ALTER TABLE `bb_ranks` DROP `rank_min`;
|
|
||||||
ALTER TABLE `bb_ranks` DROP `rank_special`;
|
|
||||||
|
|
||||||
// 2.3.0
|
|
||||||
ALTER TABLE `bb_cron` CHANGE `last_run` `last_run` DATETIME NOT NULL DEFAULT '1900-01-01 00:00:00';
|
|
||||||
ALTER TABLE `bb_cron` CHANGE `next_run` `next_run` DATETIME NOT NULL DEFAULT '1900-01-01 00:00:00';
|
|
||||||
ALTER TABLE `bb_users` CHANGE `user_birthday` `user_birthday` DATE NOT NULL DEFAULT '1900-01-01';
|
|
||||||
ALTER TABLE `bb_posts` CHANGE `mc_comment` `mc_comment` TEXT NOT NULL DEFAULT '';
|
|
||||||
|
|
||||||
// 2.3.0.2
|
|
||||||
ALTER TABLE `bb_users` CHANGE `user_sig` `user_sig` TEXT NOT NULL DEFAULT '';
|
|
||||||
ALTER TABLE `bb_groups` CHANGE `group_signature` `group_signature` TEXT NOT NULL DEFAULT '';
|
|
||||||
ALTER TABLE `bb_groups` CHANGE `group_description` `group_description` TEXT NOT NULL DEFAULT '';
|
|
||||||
UPDATE `bb_smilies` SET `code` = ':cd:', `smile_url` = 'cd.gif', `emoticon` = 'cd' WHERE `code` = ':сd:' AND `smile_url` = 'сd.gif' AND `emoticon` = 'сd';
|
|
||||||
|
|
||||||
// 2.3.1
|
|
||||||
ALTER TABLE `bb_search_results` CHANGE `search_id` `search_id` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
|
|
||||||
ALTER TABLE `bb_users` CHANGE `autologin_id` `autologin_id` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
|
|
||||||
DELETE FROM `bb_config` WHERE `config_name` = 'cron_enabled';
|
|
||||||
|
|
||||||
// 2.4.0-alpha1
|
|
||||||
ALTER TABLE `bb_search_results` CHANGE `session_id` `session_id` CHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
|
|
||||||
ALTER TABLE `bb_sessions` CHANGE `session_id` `session_id` CHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
|
|
||||||
ALTER TABLE `bb_users` CHANGE `username` `username` VARCHAR(255) NOT NULL DEFAULT '';
|
|
||||||
ALTER TABLE `bb_users` CHANGE `user_password` `user_password` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
|
|
||||||
ALTER TABLE `bb_users` CHANGE `user_actkey` `user_actkey` VARCHAR(255) NOT NULL DEFAULT '';
|
|
||||||
ALTER TABLE `bb_users` CHANGE `user_newpasswd` `user_newpasswd` VARCHAR(255) NOT NULL DEFAULT '';
|
|
||||||
|
|
||||||
// 2.4.0-alpha3
|
|
||||||
INSERT INTO bb_config VALUES ('show_board_start_index', '1');
|
|
||||||
|
|
||||||
// 2.4.0-beta2
|
|
||||||
INSERT INTO `bb_cron` (`cron_active`, `cron_title`, `cron_script`, `schedule`, `run_day`, `run_time`, `run_order`,
|
|
||||||
`last_run`, `next_run`, `run_interval`, `log_enabled`, `log_file`, `log_sql_queries`,
|
|
||||||
`disable_board`, `run_counter`) VALUES ('1', 'PM cleanup', 'clean_pm.php', 'daily', '', '05:00:00', '70', '', '', '', '1', '', '0', '1', '0');
|
|
||||||
ALTER TABLE `bb_posts_text` CHANGE `post_text` `post_text` MEDIUMTEXT NOT NULL;
|
|
||||||
ALTER TABLE `bb_privmsgs_text` CHANGE `privmsgs_text` `privmsgs_text` MEDIUMTEXT NOT NULL;
|
|
||||||
ALTER TABLE `bb_bt_torrents` ADD COLUMN `info_hash_v2` VARBINARY(32) NOT NULL DEFAULT '';
|
|
||||||
ALTER TABLE `bb_bt_tracker_snap` ADD COLUMN `completed` INT(10) NOT NULL DEFAULT '0';
|
|
||||||
ALTER TABLE `bb_bt_tracker` CHANGE `complete` `complete` TINYINT(1) NOT NULL DEFAULT '0';
|
|
||||||
|
|
||||||
// 2.4.0-beta3
|
|
||||||
INSERT INTO `bb_extensions` VALUES ('994', '1', 'webp', '');
|
|
||||||
INSERT INTO `bb_extensions` VALUES ('995', '2', '7z', '');
|
|
||||||
INSERT INTO `bb_extensions` VALUES ('996', '1', 'bmp', '');
|
|
||||||
ALTER TABLE `bb_bt_tracker` CHANGE `speed_up` `speed_up` INT(11) UNSIGNED NOT NULL DEFAULT '0';
|
|
||||||
ALTER TABLE `bb_bt_tracker` CHANGE `speed_down` `speed_down` INT(11) UNSIGNED NOT NULL DEFAULT '0';
|
|
||||||
ALTER TABLE `bb_bt_tracker_snap` CHANGE `speed_up` `speed_up` INT(11) UNSIGNED NOT NULL DEFAULT '0';
|
|
||||||
ALTER TABLE `bb_bt_tracker_snap` CHANGE `speed_down` `speed_down` INT(11) UNSIGNED NOT NULL DEFAULT '0';
|
|
||||||
ALTER TABLE `bb_bt_torrents` ADD COLUMN `last_seeder_id` MEDIUMINT(8) NOT NULL DEFAULT '0';
|
|
||||||
ALTER TABLE `buf_last_seeder` ADD COLUMN `user_id` MEDIUMINT(8) NOT NULL DEFAULT '0';
|
|
||||||
ALTER TABLE `bb_bt_tracker` CHANGE `ip` `ip` VARCHAR(42) DEFAULT NULL;
|
|
||||||
ALTER TABLE `bb_bt_tracker` CHANGE `ipv6` `ipv6` VARCHAR(42) DEFAULT NULL;
|
|
||||||
ALTER TABLE `bb_bt_users` CHANGE `auth_key` `auth_key` CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
|
|
||||||
|
|
||||||
// 2.4.0-beta4
|
|
||||||
DELETE FROM `bb_extensions` WHERE `extension` = 'tif';
|
|
||||||
INSERT INTO `bb_extensions` VALUES ('997', '4', 'tif', '');
|
|
||||||
INSERT INTO `bb_extensions` VALUES ('998', '4', 'tiff', '');
|
|
||||||
DELETE FROM `bb_extensions` WHERE `extension` = 'tga';
|
|
||||||
INSERT INTO `bb_extensions` VALUES ('999', '4', 'tga', '');
|
|
||||||
|
|
||||||
// 2.4.0-rc1
|
|
||||||
ALTER TABLE `bb_bt_tracker` DROP COLUMN `client`;
|
|
1
internal_data/cache/.htaccess
vendored
1
internal_data/cache/.htaccess
vendored
|
@ -1 +0,0 @@
|
||||||
Require all denied
|
|
0
internal_data/cache/.keep
vendored
Normal file
0
internal_data/cache/.keep
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1 +0,0 @@
|
||||||
Require all denied
|
|
0
internal_data/log/.keep
Normal file
0
internal_data/log/.keep
Normal file
|
@ -1 +0,0 @@
|
||||||
Require all denied
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -11,7 +11,7 @@ if (!defined('IN_AJAX')) {
|
||||||
die(basename(__FILE__));
|
die(basename(__FILE__));
|
||||||
}
|
}
|
||||||
|
|
||||||
global $bb_cfg, $lang, $user;
|
global $lang, $user;
|
||||||
|
|
||||||
if (!$mode = (string)$this->request['mode']) {
|
if (!$mode = (string)$this->request['mode']) {
|
||||||
$this->ajax_die('invalid mode (empty)');
|
$this->ajax_die('invalid mode (empty)');
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -11,9 +11,9 @@ if (!defined('IN_AJAX')) {
|
||||||
die(basename(__FILE__));
|
die(basename(__FILE__));
|
||||||
}
|
}
|
||||||
|
|
||||||
global $bb_cfg, $userdata, $lang;
|
global $userdata, $lang;
|
||||||
|
|
||||||
if (!$bb_cfg['callseed']) {
|
if (!config()->get('callseed')) {
|
||||||
$this->ajax_die($lang['MODULE_OFF']);
|
$this->ajax_die($lang['MODULE_OFF']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,14 +27,16 @@ if (!$t_data = topic_info($topic_id)) {
|
||||||
|
|
||||||
$forum_id = $t_data['forum_id'];
|
$forum_id = $t_data['forum_id'];
|
||||||
|
|
||||||
if ($t_data['seeders'] > 2) {
|
if ($t_data['seeders'] >= 3) {
|
||||||
$this->ajax_die(sprintf($lang['CALLSEED_HAVE_SEED'], $t_data['seeders']));
|
$this->ajax_die(sprintf($lang['CALLSEED_HAVE_SEED'], $t_data['seeders']));
|
||||||
} elseif ($t_data['call_seed_time'] > (TIMENOW - 86400)) {
|
} elseif ($t_data['call_seed_time'] >= (TIMENOW - 86400)) {
|
||||||
$time_left = delta_time($t_data['call_seed_time'] + 86400, TIMENOW, 'days');
|
$time_left = delta_time($t_data['call_seed_time'] + 86400, TIMENOW, 'days');
|
||||||
$this->ajax_die(sprintf($lang['CALLSEED_MSG_SPAM'], $time_left));
|
$this->ajax_die(sprintf($lang['CALLSEED_MSG_SPAM'], $time_left));
|
||||||
|
} elseif (isset(config()->get('tor_no_tor_act')[$t_data['tor_status']])) {
|
||||||
|
$this->ajax_die($lang['NOT_AVAILABLE']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$get_banned_users = get_banned_users() ? (', ' . implode(', ', get_banned_users())) : '';
|
$banned_users = ($get_banned_users = get_banned_users()) ? (', ' . implode(', ', $get_banned_users)) : '';
|
||||||
|
|
||||||
$user_list = DB()->fetch_rowset("
|
$user_list = DB()->fetch_rowset("
|
||||||
SELECT DISTINCT dl.user_id, u.user_opt, tr.user_id as active_dl
|
SELECT DISTINCT dl.user_id, u.user_opt, tr.user_id as active_dl
|
||||||
|
@ -43,7 +45,7 @@ $user_list = DB()->fetch_rowset("
|
||||||
LEFT JOIN " . BB_BT_TRACKER . " tr ON(tr.user_id = dl.user_id)
|
LEFT JOIN " . BB_BT_TRACKER . " tr ON(tr.user_id = dl.user_id)
|
||||||
WHERE dl.topic_id = $topic_id
|
WHERE dl.topic_id = $topic_id
|
||||||
AND dl.user_status IN (" . DL_STATUS_COMPLETE . ", " . DL_STATUS_DOWN . ")
|
AND dl.user_status IN (" . DL_STATUS_COMPLETE . ", " . DL_STATUS_DOWN . ")
|
||||||
AND dl.user_id NOT IN ({$userdata['user_id']}, " . EXCLUDED_USERS . $get_banned_users . ")
|
AND dl.user_id NOT IN ({$userdata['user_id']}, " . EXCLUDED_USERS . $banned_users . ")
|
||||||
AND u.user_active = 1
|
AND u.user_active = 1
|
||||||
GROUP BY dl.user_id
|
GROUP BY dl.user_id
|
||||||
");
|
");
|
||||||
|
@ -73,7 +75,7 @@ function topic_info($topic_id)
|
||||||
|
|
||||||
$sql = "
|
$sql = "
|
||||||
SELECT
|
SELECT
|
||||||
tor.poster_id, tor.forum_id, tor.attach_id, tor.call_seed_time,
|
tor.poster_id, tor.forum_id, tor.attach_id, tor.call_seed_time, tor.tor_status,
|
||||||
t.topic_title, sn.seeders
|
t.topic_title, sn.seeders
|
||||||
FROM " . BB_BT_TORRENTS . " tor
|
FROM " . BB_BT_TORRENTS . " tor
|
||||||
LEFT JOIN " . BB_TOPICS . " t USING(topic_id)
|
LEFT JOIN " . BB_TOPICS . " t USING(topic_id)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -11,7 +11,7 @@ if (!defined('IN_AJAX')) {
|
||||||
die(basename(__FILE__));
|
die(basename(__FILE__));
|
||||||
}
|
}
|
||||||
|
|
||||||
global $userdata, $bb_cfg, $lang;
|
global $userdata, $lang, $log_action;
|
||||||
|
|
||||||
if (!$attach_id = (int)$this->request['attach_id']) {
|
if (!$attach_id = (int)$this->request['attach_id']) {
|
||||||
$this->ajax_die($lang['EMPTY_ATTACH_ID']);
|
$this->ajax_die($lang['EMPTY_ATTACH_ID']);
|
||||||
|
@ -22,7 +22,7 @@ if (!$mode = (string)$this->request['mode']) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$comment = false;
|
$comment = false;
|
||||||
if ($bb_cfg['tor_comment']) {
|
if (config()->get('tor_comment')) {
|
||||||
$comment = (string)$this->request['comment'];
|
$comment = (string)$this->request['comment'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ switch ($mode) {
|
||||||
case 'status':
|
case 'status':
|
||||||
$new_status = (int)$this->request['status'];
|
$new_status = (int)$this->request['status'];
|
||||||
|
|
||||||
// Валидность статуса
|
// Check status validity
|
||||||
if (!isset($lang['TOR_STATUS_NAME'][$new_status])) {
|
if (!isset($lang['TOR_STATUS_NAME'][$new_status])) {
|
||||||
$this->ajax_die($lang['TOR_STATUS_FAILED']);
|
$this->ajax_die($lang['TOR_STATUS_FAILED']);
|
||||||
}
|
}
|
||||||
|
@ -55,17 +55,17 @@ switch ($mode) {
|
||||||
$this->ajax_die($lang['NOT_MODERATOR']);
|
$this->ajax_die($lang['NOT_MODERATOR']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Тот же статус
|
// Error if same status
|
||||||
if ($tor['tor_status'] == $new_status) {
|
if ($tor['tor_status'] == $new_status) {
|
||||||
$this->ajax_die($lang['TOR_STATUS_DUB']);
|
$this->ajax_die($lang['TOR_STATUS_DUB']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Запрет на изменение/присвоение CH-статуса модератором
|
// Prohibition on changing/assigning CH-status by moderator
|
||||||
if ($new_status == TOR_CLOSED_CPHOLD && !IS_ADMIN) {
|
if ($new_status == TOR_CLOSED_CPHOLD && !IS_ADMIN) {
|
||||||
$this->ajax_die($lang['TOR_DONT_CHANGE']);
|
$this->ajax_die($lang['TOR_DONT_CHANGE']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Права на изменение статуса
|
// Check rights to change status
|
||||||
if ($tor['tor_status'] == TOR_CLOSED_CPHOLD) {
|
if ($tor['tor_status'] == TOR_CLOSED_CPHOLD) {
|
||||||
if (!IS_ADMIN) {
|
if (!IS_ADMIN) {
|
||||||
$this->verify_mod_rights($tor['forum_id']);
|
$this->verify_mod_rights($tor['forum_id']);
|
||||||
|
@ -75,7 +75,7 @@ switch ($mode) {
|
||||||
$this->verify_mod_rights($tor['forum_id']);
|
$this->verify_mod_rights($tor['forum_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Подтверждение изменения статуса, выставленного другим модератором
|
// Confirmation of status change set by another moderator
|
||||||
if ($tor['tor_status'] != TOR_NOT_APPROVED && $tor['checked_user_id'] != $userdata['user_id'] && $tor['checked_time'] + 2 * 3600 > TIMENOW) {
|
if ($tor['tor_status'] != TOR_NOT_APPROVED && $tor['checked_user_id'] != $userdata['user_id'] && $tor['checked_time'] + 2 * 3600 > TIMENOW) {
|
||||||
if (empty($this->request['confirmed'])) {
|
if (empty($this->request['confirmed'])) {
|
||||||
$msg = $lang['TOR_STATUS_OF'] . " {$lang['TOR_STATUS_NAME'][$tor['tor_status']]}\n\n";
|
$msg = $lang['TOR_STATUS_OF'] . " {$lang['TOR_STATUS_NAME'][$tor['tor_status']]}\n\n";
|
||||||
|
@ -87,12 +87,24 @@ switch ($mode) {
|
||||||
|
|
||||||
\TorrentPier\Legacy\Torrent::change_tor_status($attach_id, $new_status);
|
\TorrentPier\Legacy\Torrent::change_tor_status($attach_id, $new_status);
|
||||||
|
|
||||||
$this->response['status'] = $bb_cfg['tor_icons'][$new_status] . ' <b> ' . $lang['TOR_STATUS_NAME'][$new_status] . '</b> · ' . profile_url($userdata) . ' · <i>' . delta_time(TIMENOW) . $lang['TOR_BACK'] . '</i>';
|
// Log action
|
||||||
|
$log_msg = sprintf($lang['TOR_STATUS_LOG_ACTION'], config()->get('tor_icons')[$new_status] . ' <b> ' . $lang['TOR_STATUS_NAME'][$new_status] . '</b>', config()->get('tor_icons')[$tor['tor_status']] . ' <b> ' . $lang['TOR_STATUS_NAME'][$tor['tor_status']] . '</b>');
|
||||||
|
if ($comment && $comment != $lang['COMMENT']) {
|
||||||
|
$log_msg .= "<br/>{$lang['COMMENT']}: <b>$comment</b>.";
|
||||||
|
}
|
||||||
|
$log_action->mod('mod_topic_change_tor_status', [
|
||||||
|
'forum_id' => $tor['forum_id'],
|
||||||
|
'topic_id' => $tor['topic_id'],
|
||||||
|
'topic_title' => $tor['topic_title'],
|
||||||
|
'log_msg' => $log_msg . '<br/>-------------',
|
||||||
|
]);
|
||||||
|
|
||||||
if ($bb_cfg['tor_comment'] && (($comment && $comment != $lang['COMMENT']) || in_array($new_status, $bb_cfg['tor_reply']))) {
|
$this->response['status'] = config()->get('tor_icons')[$new_status] . ' <b> ' . $lang['TOR_STATUS_NAME'][$new_status] . '</b> · ' . profile_url($userdata) . ' · <i>' . delta_time(TIMENOW) . $lang['TOR_BACK'] . '</i>';
|
||||||
|
|
||||||
|
if (config()->get('tor_comment') && (($comment && $comment != $lang['COMMENT']) || in_array($new_status, config()->get('tor_reply')))) {
|
||||||
if ($tor['poster_id'] > 0) {
|
if ($tor['poster_id'] > 0) {
|
||||||
$subject = sprintf($lang['TOR_MOD_TITLE'], $tor['topic_title']);
|
$subject = sprintf($lang['TOR_MOD_TITLE'], $tor['topic_title']);
|
||||||
$message = sprintf($lang['TOR_MOD_MSG'], get_username($tor['poster_id']), make_url(TOPIC_URL . $tor['topic_id']), $bb_cfg['tor_icons'][$new_status] . ' ' . $lang['TOR_STATUS_NAME'][$new_status]);
|
$message = sprintf($lang['TOR_MOD_MSG'], get_username($tor['poster_id']), make_url(TOPIC_URL . $tor['topic_id']), config()->get('tor_icons')[$new_status] . ' ' . $lang['TOR_STATUS_NAME'][$new_status]);
|
||||||
|
|
||||||
if ($comment && $comment != $lang['COMMENT']) {
|
if ($comment && $comment != $lang['COMMENT']) {
|
||||||
$message .= "\n\n[b]" . $lang['COMMENT'] . '[/b]: ' . $comment;
|
$message .= "\n\n[b]" . $lang['COMMENT'] . '[/b]: ' . $comment;
|
||||||
|
@ -105,7 +117,7 @@ switch ($mode) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'status_reply':
|
case 'status_reply':
|
||||||
if (!$bb_cfg['tor_comment']) {
|
if (!config()->get('tor_comment')) {
|
||||||
$this->ajax_die($lang['MODULE_OFF']);
|
$this->ajax_die($lang['MODULE_OFF']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -11,7 +11,7 @@ if (!defined('IN_AJAX')) {
|
||||||
die(basename(__FILE__));
|
die(basename(__FILE__));
|
||||||
}
|
}
|
||||||
|
|
||||||
global $userdata, $bb_cfg, $lang;
|
global $userdata, $lang, $log_action;
|
||||||
|
|
||||||
if (!isset($this->request['attach_id'])) {
|
if (!isset($this->request['attach_id'])) {
|
||||||
$this->ajax_die($lang['EMPTY_ATTACH_ID']);
|
$this->ajax_die($lang['EMPTY_ATTACH_ID']);
|
||||||
|
@ -19,31 +19,11 @@ if (!isset($this->request['attach_id'])) {
|
||||||
if (!isset($this->request['type'])) {
|
if (!isset($this->request['type'])) {
|
||||||
$this->ajax_die('empty type');
|
$this->ajax_die('empty type');
|
||||||
}
|
}
|
||||||
|
|
||||||
$attach_id = (int)$this->request['attach_id'];
|
$attach_id = (int)$this->request['attach_id'];
|
||||||
$type = (string)$this->request['type'];
|
$type = (string)$this->request['type'];
|
||||||
|
|
||||||
$torrent = DB()->fetch_row("
|
if (!$torrent = \TorrentPier\Legacy\Torrent::get_torrent_info($attach_id)) {
|
||||||
SELECT
|
|
||||||
a.post_id, d.physical_filename, d.extension, d.tracker_status,
|
|
||||||
t.topic_first_post_id,
|
|
||||||
p.poster_id, p.topic_id, p.forum_id,
|
|
||||||
f.allow_reg_tracker
|
|
||||||
FROM
|
|
||||||
" . BB_ATTACHMENTS . " a,
|
|
||||||
" . BB_ATTACHMENTS_DESC . " d,
|
|
||||||
" . BB_POSTS . " p,
|
|
||||||
" . BB_TOPICS . " t,
|
|
||||||
" . BB_FORUMS . " f
|
|
||||||
WHERE
|
|
||||||
a.attach_id = $attach_id
|
|
||||||
AND d.attach_id = $attach_id
|
|
||||||
AND p.post_id = a.post_id
|
|
||||||
AND t.topic_id = p.topic_id
|
|
||||||
AND f.forum_id = p.forum_id
|
|
||||||
LIMIT 1
|
|
||||||
");
|
|
||||||
|
|
||||||
if (!$torrent) {
|
|
||||||
$this->ajax_die($lang['INVALID_ATTACH_ID']);
|
$this->ajax_die($lang['INVALID_ATTACH_ID']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,12 +43,25 @@ switch ($type) {
|
||||||
case 'unset_silver_gold':
|
case 'unset_silver_gold':
|
||||||
if ($type == 'set_silver') {
|
if ($type == 'set_silver') {
|
||||||
$tor_type = TOR_TYPE_SILVER;
|
$tor_type = TOR_TYPE_SILVER;
|
||||||
|
$tor_type_lang = $lang['SILVER'];
|
||||||
} elseif ($type == 'set_gold') {
|
} elseif ($type == 'set_gold') {
|
||||||
$tor_type = TOR_TYPE_GOLD;
|
$tor_type = TOR_TYPE_GOLD;
|
||||||
|
$tor_type_lang = $lang['GOLD'];
|
||||||
} else {
|
} else {
|
||||||
$tor_type = 0;
|
$tor_type = TOR_TYPE_DEFAULT;
|
||||||
|
$tor_type_lang = "{$lang['UNSET_GOLD_TORRENT']} / {$lang['UNSET_SILVER_TORRENT']}";
|
||||||
}
|
}
|
||||||
|
|
||||||
\TorrentPier\Legacy\Torrent::change_tor_type($attach_id, $tor_type);
|
\TorrentPier\Legacy\Torrent::change_tor_type($attach_id, $tor_type);
|
||||||
|
|
||||||
|
// Log action
|
||||||
|
$log_action->mod('mod_topic_change_tor_type', [
|
||||||
|
'forum_id' => $torrent['forum_id'],
|
||||||
|
'topic_id' => $torrent['topic_id'],
|
||||||
|
'topic_title' => $torrent['topic_title'],
|
||||||
|
'log_msg' => sprintf($lang['TOR_TYPE_LOG_ACTION'], $tor_type_lang),
|
||||||
|
]);
|
||||||
|
|
||||||
$title = $lang['CHANGE_TOR_TYPE'];
|
$title = $lang['CHANGE_TOR_TYPE'];
|
||||||
$url = make_url(TOPIC_URL . $torrent['topic_id']);
|
$url = make_url(TOPIC_URL . $torrent['topic_id']);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -32,7 +32,7 @@ foreach ($bf['user_opt'] as $opt_name => $opt_bit) {
|
||||||
|
|
||||||
DB()->query("UPDATE " . BB_USERS . " SET user_opt = {$u_data['user_opt']} WHERE user_id = $user_id LIMIT 1");
|
DB()->query("UPDATE " . BB_USERS . " SET user_opt = {$u_data['user_opt']} WHERE user_id = $user_id LIMIT 1");
|
||||||
|
|
||||||
// Удаляем данные из кеша
|
// Remove data from cache
|
||||||
\TorrentPier\Sessions::cache_rm_user_sessions($user_id);
|
\TorrentPier\Sessions::cache_rm_user_sessions($user_id);
|
||||||
|
|
||||||
$this->response['resp_html'] = $lang['SAVED'];
|
$this->response['resp_html'] = $lang['SAVED'];
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -13,7 +13,7 @@ if (!defined('IN_AJAX')) {
|
||||||
|
|
||||||
global $datastore, $lang;
|
global $datastore, $lang;
|
||||||
|
|
||||||
if (!$ranks = $datastore->get('ranks') and !$datastore->has('ranks')) {
|
if (!$ranks = $datastore->get('ranks')) {
|
||||||
$datastore->update('ranks');
|
$datastore->update('ranks');
|
||||||
$ranks = $datastore->get('ranks');
|
$ranks = $datastore->get('ranks');
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ if ($rank_id != 0 && !isset($ranks[$rank_id])) {
|
||||||
$this->ajax_die("invalid rank_id: $rank_id");
|
$this->ajax_die("invalid rank_id: $rank_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
DB()->query("UPDATE " . BB_USERS . " SET user_rank = $rank_id WHERE user_id = $user_id");
|
DB()->query("UPDATE " . BB_USERS . " SET user_rank = $rank_id WHERE user_id = $user_id LIMIT 1");
|
||||||
|
|
||||||
\TorrentPier\Sessions::cache_rm_user_sessions($user_id);
|
\TorrentPier\Sessions::cache_rm_user_sessions($user_id);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -11,7 +11,7 @@ if (!defined('IN_AJAX')) {
|
||||||
die(basename(__FILE__));
|
die(basename(__FILE__));
|
||||||
}
|
}
|
||||||
|
|
||||||
global $bb_cfg, $userdata, $lang;
|
global $userdata, $lang;
|
||||||
|
|
||||||
if (!$group_id = (int)$this->request['group_id'] or !$group_info = \TorrentPier\Legacy\Group::get_group_data($group_id)) {
|
if (!$group_id = (int)$this->request['group_id'] or !$group_info = \TorrentPier\Legacy\Group::get_group_data($group_id)) {
|
||||||
$this->ajax_die($lang['NO_GROUP_ID_SPECIFIED']);
|
$this->ajax_die($lang['NO_GROUP_ID_SPECIFIED']);
|
||||||
|
@ -51,4 +51,4 @@ switch ($mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$value_sql = DB()->escape($value, true);
|
$value_sql = DB()->escape($value, true);
|
||||||
DB()->query("UPDATE " . BB_GROUPS . " SET $mode = $value_sql WHERE group_id = $group_id");
|
DB()->query("UPDATE " . BB_GROUPS . " SET $mode = $value_sql WHERE group_id = $group_id LIMIT 1");
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -11,7 +11,7 @@ if (!defined('IN_AJAX')) {
|
||||||
die(basename(__FILE__));
|
die(basename(__FILE__));
|
||||||
}
|
}
|
||||||
|
|
||||||
global $bb_cfg, $lang;
|
global $lang;
|
||||||
|
|
||||||
if (!$user_id = (int)$this->request['user_id'] or !$profiledata = get_userdata($user_id)) {
|
if (!$user_id = (int)$this->request['user_id'] or !$profiledata = get_userdata($user_id)) {
|
||||||
$this->ajax_die($lang['NO_USER_ID_SPECIFIED']);
|
$this->ajax_die($lang['NO_USER_ID_SPECIFIED']);
|
||||||
|
@ -55,7 +55,7 @@ switch ($field) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'user_gender':
|
case 'user_gender':
|
||||||
if (!$bb_cfg['gender']) {
|
if (!config()->get('gender')) {
|
||||||
$this->ajax_die($lang['MODULE_OFF']);
|
$this->ajax_die($lang['MODULE_OFF']);
|
||||||
}
|
}
|
||||||
if (!isset($lang['GENDER_SELECT'][$value])) {
|
if (!isset($lang['GENDER_SELECT'][$value])) {
|
||||||
|
@ -65,7 +65,7 @@ switch ($field) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'user_birthday':
|
case 'user_birthday':
|
||||||
if (!$bb_cfg['birthday_enabled']) {
|
if (!config()->get('birthday_enabled')) {
|
||||||
$this->ajax_die($lang['MODULE_OFF']);
|
$this->ajax_die($lang['MODULE_OFF']);
|
||||||
}
|
}
|
||||||
$birthday_date = date_parse($value);
|
$birthday_date = date_parse($value);
|
||||||
|
@ -73,10 +73,10 @@ switch ($field) {
|
||||||
if (!empty($birthday_date['year'])) {
|
if (!empty($birthday_date['year'])) {
|
||||||
if (strtotime($value) >= TIMENOW) {
|
if (strtotime($value) >= TIMENOW) {
|
||||||
$this->ajax_die($lang['WRONG_BIRTHDAY_FORMAT']);
|
$this->ajax_die($lang['WRONG_BIRTHDAY_FORMAT']);
|
||||||
} elseif (bb_date(TIMENOW, 'Y', false) - $birthday_date['year'] > $bb_cfg['birthday_max_age']) {
|
} elseif (bb_date(TIMENOW, 'Y', false) - $birthday_date['year'] > config()->get('birthday_max_age')) {
|
||||||
$this->ajax_die(sprintf($lang['BIRTHDAY_TO_HIGH'], $bb_cfg['birthday_max_age']));
|
$this->ajax_die(sprintf($lang['BIRTHDAY_TO_HIGH'], config()->get('birthday_max_age')));
|
||||||
} elseif (bb_date(TIMENOW, 'Y', false) - $birthday_date['year'] < $bb_cfg['birthday_min_age']) {
|
} elseif (bb_date(TIMENOW, 'Y', false) - $birthday_date['year'] < config()->get('birthday_min_age')) {
|
||||||
$this->ajax_die(sprintf($lang['BIRTHDAY_TO_LOW'], $bb_cfg['birthday_min_age']));
|
$this->ajax_die(sprintf($lang['BIRTHDAY_TO_LOW'], config()->get('birthday_min_age')));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ switch ($field) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$value_sql = DB()->escape($value, true);
|
$value_sql = DB()->escape($value, true);
|
||||||
DB()->query("UPDATE $table SET $field = $value_sql WHERE user_id = $user_id");
|
DB()->query("UPDATE $table SET $field = $value_sql WHERE user_id = $user_id LIMIT 1");
|
||||||
|
|
||||||
\TorrentPier\Sessions::cache_rm_user_sessions($user_id);
|
\TorrentPier\Sessions::cache_rm_user_sessions($user_id);
|
||||||
|
|
||||||
|
|
154
library/ajax/ffprobe_info.php
Normal file
154
library/ajax/ffprobe_info.php
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('IN_AJAX')) {
|
||||||
|
die(basename(__FILE__));
|
||||||
|
}
|
||||||
|
|
||||||
|
global $lang;
|
||||||
|
|
||||||
|
if (!config()->get('torr_server.enabled')) {
|
||||||
|
$this->ajax_die($lang['MODULE_OFF']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config()->get('torr_server.disable_for_guest') && IS_GUEST) {
|
||||||
|
$this->ajax_die($lang['NEED_TO_LOGIN_FIRST']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$attach_id = $this->request['attach_id'] ?? '';
|
||||||
|
if (empty($attach_id) || !is_numeric($attach_id)) {
|
||||||
|
$this->ajax_die($lang['INVALID_ATTACH_ID']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$file_index = $this->request['file_index'] ?? '';
|
||||||
|
if (empty($file_index) || !is_numeric($file_index)) {
|
||||||
|
$this->ajax_die("Invalid file index: $file_index");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$info_hash = (string)$this->request['info_hash'] or !ctype_xdigit($info_hash)) {
|
||||||
|
$this->ajax_die("Invalid info_hash: $info_hash");
|
||||||
|
}
|
||||||
|
|
||||||
|
$isAudio = isset($this->request['is_audio']) && $this->request['is_audio'];
|
||||||
|
|
||||||
|
// Get ffprobe info from TorrServer
|
||||||
|
$ffpInfo = (new \TorrentPier\TorrServerAPI())->getFfpInfo($info_hash, $file_index, $attach_id);
|
||||||
|
$ffpInfo = $ffpInfo->{$file_index};
|
||||||
|
if (isset($ffpInfo->streams)) {
|
||||||
|
// Video codec information
|
||||||
|
$videoCodecIndex = array_search('video', array_column($ffpInfo->streams, 'codec_type'));
|
||||||
|
if (is_int($videoCodecIndex)) {
|
||||||
|
$videoCodecInfo = $ffpInfo->streams[$videoCodecIndex];
|
||||||
|
}
|
||||||
|
// Audio codec information
|
||||||
|
$audioTracks = array_filter($ffpInfo->streams, function ($e) {
|
||||||
|
return $e->codec_type === 'audio';
|
||||||
|
});
|
||||||
|
// Audio tracks information
|
||||||
|
$audioDub = array_map(function ($stream) {
|
||||||
|
global $lang;
|
||||||
|
|
||||||
|
$result = '<span class="warnColor2">' . sprintf($lang['AUDIO_TRACK'], (!isset($stream->index) || $stream->index === 0) ? 1 : $stream->index) . '</span><br/>';
|
||||||
|
if (isset($stream->tags->language)) {
|
||||||
|
if (isset($stream->tags->title)) {
|
||||||
|
$result .= '<b>' . mb_strtoupper($stream->tags->language, DEFAULT_CHARSET) . ' (' . $stream->tags->title . ')' . '</b>';
|
||||||
|
} else {
|
||||||
|
$result .= '<b>' . mb_strtoupper($stream->tags->language, DEFAULT_CHARSET) . '</b>';
|
||||||
|
}
|
||||||
|
$result .= '<br/>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($stream->codec_name)) {
|
||||||
|
$result .= sprintf($lang['AUDIO_CODEC'], $stream->codec_long_name, mb_strtoupper($stream->codec_name, DEFAULT_CHARSET)) . '<br/>';
|
||||||
|
}
|
||||||
|
if (!empty($stream->bit_rate)) {
|
||||||
|
$result .= sprintf($lang['BITRATE'], humn_bitrate((int)$stream->bit_rate)) . '<br/>';
|
||||||
|
}
|
||||||
|
if (!empty($stream->sample_rate)) {
|
||||||
|
$result .= sprintf($lang['SAMPLE_RATE'], humn_sample_rate((int)$stream->sample_rate)) . '<br/>';
|
||||||
|
}
|
||||||
|
if (!empty($stream->channels)) {
|
||||||
|
$result .= sprintf($lang['CHANNELS'], $stream->channels) . '<br/>';
|
||||||
|
}
|
||||||
|
if (!empty($stream->channel_layout)) {
|
||||||
|
$result .= sprintf($lang['CHANNELS_LAYOUT'], $stream->channel_layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}, $audioTracks);
|
||||||
|
|
||||||
|
// Generate output data
|
||||||
|
$data = [
|
||||||
|
'filesize' => sprintf($lang['FILESIZE'] . ': <b>%s</b>', humn_size($ffpInfo->format->size)),
|
||||||
|
'resolution' => (!$isAudio && isset($videoCodecInfo)) ? sprintf($lang['RESOLUTION'], $videoCodecInfo->width . 'x' . $videoCodecInfo->height) : '',
|
||||||
|
'video_codec' => (!$isAudio && isset($videoCodecInfo->codec_name)) ? sprintf($lang['VIDEO_CODEC'], $videoCodecInfo->codec_long_name, mb_strtoupper($videoCodecInfo->codec_name, DEFAULT_CHARSET)) : '',
|
||||||
|
'audio_dub' => implode('<hr/>', $audioDub)
|
||||||
|
];
|
||||||
|
|
||||||
|
// Validate output data
|
||||||
|
$result = '<hr/>';
|
||||||
|
if (!empty($data['resolution'])) {
|
||||||
|
$result .= $data['resolution'] . '<br/>';
|
||||||
|
}
|
||||||
|
if (!empty($data['filesize'])) {
|
||||||
|
$result .= $data['filesize'] . '<br/>';
|
||||||
|
}
|
||||||
|
if (!empty($data['video_codec'])) {
|
||||||
|
$result .= $data['video_codec'];
|
||||||
|
}
|
||||||
|
if (!empty($data['audio_dub'])) {
|
||||||
|
$result .= '<hr/>' . $data['audio_dub'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->response['ffprobe_data'] = $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bitrate to human-readable format
|
||||||
|
*
|
||||||
|
* @param int $bitrate
|
||||||
|
* @param string $space
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function humn_bitrate(int $bitrate, string $space = ' '): string
|
||||||
|
{
|
||||||
|
if ($bitrate >= 1000000) {
|
||||||
|
$unit = 'Mbps';
|
||||||
|
$bitrate /= 1000000;
|
||||||
|
} elseif ($bitrate >= 1000) {
|
||||||
|
$unit = 'kbps';
|
||||||
|
$bitrate /= 1000;
|
||||||
|
} else {
|
||||||
|
$unit = 'bps';
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf('%d', commify($bitrate)) . $space . $unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sample rate to human-readable format
|
||||||
|
*
|
||||||
|
* @param int $sample_rate
|
||||||
|
* @param string $space
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function humn_sample_rate(int $sample_rate, string $space = ' '): string
|
||||||
|
{
|
||||||
|
if ($sample_rate >= 1000000) {
|
||||||
|
$unit = 'Mhz';
|
||||||
|
} elseif ($sample_rate >= 1000) {
|
||||||
|
$unit = 'kHz';
|
||||||
|
} else {
|
||||||
|
$unit = 'Hz';
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf('%.1f', commify($sample_rate)) . $space . $unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->response['file_index'] = $file_index;
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -42,13 +42,14 @@ switch ($mode) {
|
||||||
$link = '<a href="' . $href . '" class="' . $class . '" target="_blank">' . htmlCHR($row['group_name']) . '</a>';
|
$link = '<a href="' . $href . '" class="' . $class . '" target="_blank">' . htmlCHR($row['group_name']) . '</a>';
|
||||||
$html[] = $link;
|
$html[] = $link;
|
||||||
} else {
|
} else {
|
||||||
// скрытая группа и сам юзер не является ее членом
|
// hidden group and the user himself is not a member of it
|
||||||
if ($row['group_type'] == GROUP_HIDDEN && !$row['can_view']) {
|
if ($row['group_type'] == GROUP_HIDDEN && !$row['can_view']) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($row['group_moderator'] == $user->id) {
|
if ($row['group_moderator'] == $user->id) {
|
||||||
|
// the user himself is the moderator of this group
|
||||||
$class .= ' selfMod';
|
$class .= ' selfMod';
|
||||||
$href .= "&" . POST_USERS_URL . "=$user_id"; // сам юзер модератор этой группы
|
$href .= "&" . POST_USERS_URL . "=$user_id";
|
||||||
}
|
}
|
||||||
$link = '<a href="' . $href . '" class="' . $class . '" target="_blank">' . htmlCHR($row['group_name']) . '</a>';
|
$link = '<a href="' . $href . '" class="' . $class . '" target="_blank">' . htmlCHR($row['group_name']) . '</a>';
|
||||||
$html[] = $link;
|
$html[] = $link;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -11,25 +11,19 @@ if (!defined('IN_AJAX')) {
|
||||||
die(basename(__FILE__));
|
die(basename(__FILE__));
|
||||||
}
|
}
|
||||||
|
|
||||||
global $bb_cfg, $lang, $userdata, $datastore;
|
global $lang, $userdata, $datastore;
|
||||||
|
|
||||||
if (!$mode = (string)$this->request['mode']) {
|
if (!$mode = (string)$this->request['mode']) {
|
||||||
$this->ajax_die('invalid mode (empty)');
|
$this->ajax_die('invalid mode (empty)');
|
||||||
}
|
}
|
||||||
|
|
||||||
$datastore->enqueue([
|
|
||||||
'stats',
|
|
||||||
'moderators',
|
|
||||||
'cat_forums'
|
|
||||||
]);
|
|
||||||
|
|
||||||
$html = '';
|
$html = '';
|
||||||
switch ($mode) {
|
switch ($mode) {
|
||||||
case 'birthday_week':
|
case 'birthday_week':
|
||||||
if (!$stats = $datastore->get('stats') and !$datastore->has('stats')) {
|
$datastore->enqueue([
|
||||||
$datastore->update('stats');
|
'stats'
|
||||||
$stats = $datastore->get('stats');
|
]);
|
||||||
}
|
$stats = $datastore->get('stats');
|
||||||
|
|
||||||
$users = [];
|
$users = [];
|
||||||
|
|
||||||
|
@ -37,17 +31,17 @@ switch ($mode) {
|
||||||
foreach ($stats['birthday_week_list'] as $week) {
|
foreach ($stats['birthday_week_list'] as $week) {
|
||||||
$users[] = profile_url($week) . ' <span class="small">(' . birthday_age(date('Y-m-d', strtotime('-1 year', strtotime($week['user_birthday'])))) . ')</span>';
|
$users[] = profile_url($week) . ' <span class="small">(' . birthday_age(date('Y-m-d', strtotime('-1 year', strtotime($week['user_birthday'])))) . ')</span>';
|
||||||
}
|
}
|
||||||
$html = sprintf($lang['BIRTHDAY_WEEK'], $bb_cfg['birthday_check_day'], implode(', ', $users));
|
$html = sprintf($lang['BIRTHDAY_WEEK'], config()->get('birthday_check_day'), implode(', ', $users));
|
||||||
} else {
|
} else {
|
||||||
$html = sprintf($lang['NOBIRTHDAY_WEEK'], $bb_cfg['birthday_check_day']);
|
$html = sprintf($lang['NOBIRTHDAY_WEEK'], config()->get('birthday_check_day'));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'birthday_today':
|
case 'birthday_today':
|
||||||
if (!$stats = $datastore->get('stats') and !$datastore->has('stats')) {
|
$datastore->enqueue([
|
||||||
$datastore->update('stats');
|
'stats'
|
||||||
$stats = $datastore->get('stats');
|
]);
|
||||||
}
|
$stats = $datastore->get('stats');
|
||||||
|
|
||||||
$users = [];
|
$users = [];
|
||||||
|
|
||||||
|
@ -64,12 +58,12 @@ switch ($mode) {
|
||||||
case 'get_forum_mods':
|
case 'get_forum_mods':
|
||||||
$forum_id = (int)$this->request['forum_id'];
|
$forum_id = (int)$this->request['forum_id'];
|
||||||
|
|
||||||
if (!$mod = $datastore->get('moderators') and !$datastore->has('moderators')) {
|
$datastore->enqueue([
|
||||||
$datastore->update('moderators');
|
'moderators'
|
||||||
$mod = $datastore->get('moderators');
|
]);
|
||||||
}
|
|
||||||
|
|
||||||
$moderators = [];
|
$moderators = [];
|
||||||
|
$mod = $datastore->get('moderators');
|
||||||
|
|
||||||
if (isset($mod['mod_users'][$forum_id])) {
|
if (isset($mod['mod_users'][$forum_id])) {
|
||||||
foreach ($mod['mod_users'][$forum_id] as $user_id) {
|
foreach ($mod['mod_users'][$forum_id] as $user_id) {
|
||||||
|
@ -90,7 +84,7 @@ switch ($mode) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'null_ratio':
|
case 'null_ratio':
|
||||||
if (!$bb_cfg['ratio_null_enabled'] || !RATIO_ENABLED) {
|
if (!config()->get('ratio_null_enabled') || !RATIO_ENABLED) {
|
||||||
$this->ajax_die($lang['MODULE_OFF']);
|
$this->ajax_die($lang['MODULE_OFF']);
|
||||||
}
|
}
|
||||||
if (empty($this->request['confirmed'])) {
|
if (empty($this->request['confirmed'])) {
|
||||||
|
@ -112,8 +106,8 @@ switch ($mode) {
|
||||||
if ($ratio_nulled && !IS_ADMIN) {
|
if ($ratio_nulled && !IS_ADMIN) {
|
||||||
$this->ajax_die($lang['BT_NULL_RATIO_AGAIN']);
|
$this->ajax_die($lang['BT_NULL_RATIO_AGAIN']);
|
||||||
}
|
}
|
||||||
if (($user_ratio >= $bb_cfg['ratio_to_null']) && !IS_ADMIN) {
|
if (($user_ratio >= config()->get('ratio_to_null')) && !IS_ADMIN) {
|
||||||
$this->ajax_die(sprintf($lang['BT_NULL_RATIO_NOT_NEEDED'], $bb_cfg['ratio_to_null']));
|
$this->ajax_die(sprintf($lang['BT_NULL_RATIO_NOT_NEEDED'], config()->get('ratio_to_null')));
|
||||||
}
|
}
|
||||||
|
|
||||||
$ratio_nulled_sql = !IS_ADMIN ? ', ratio_nulled = 1' : '';
|
$ratio_nulled_sql = !IS_ADMIN ? ', ratio_nulled = 1' : '';
|
||||||
|
@ -123,6 +117,10 @@ switch ($mode) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'releaser_stats':
|
case 'releaser_stats':
|
||||||
|
if (IS_GUEST) {
|
||||||
|
$this->ajax_die($lang['NEED_TO_LOGIN_FIRST']);
|
||||||
|
}
|
||||||
|
|
||||||
$user_id = (int)$this->request['user_id'];
|
$user_id = (int)$this->request['user_id'];
|
||||||
|
|
||||||
$sql = "
|
$sql = "
|
||||||
|
@ -155,6 +153,10 @@ switch ($mode) {
|
||||||
$this->ajax_die($lang['MODULE_OFF']);
|
$this->ajax_die($lang['MODULE_OFF']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_GUEST) {
|
||||||
|
$this->ajax_die($lang['NEED_TO_LOGIN_FIRST']);
|
||||||
|
}
|
||||||
|
|
||||||
$user_id = (int)$this->request['user_id'];
|
$user_id = (int)$this->request['user_id'];
|
||||||
$btu = get_bt_userdata($user_id);
|
$btu = get_bt_userdata($user_id);
|
||||||
$profiledata = get_userdata($user_id);
|
$profiledata = get_userdata($user_id);
|
||||||
|
@ -170,7 +172,7 @@ switch ($mode) {
|
||||||
<th>' . $lang['UPLOADED'] . '</th>
|
<th>' . $lang['UPLOADED'] . '</th>
|
||||||
<th>' . $lang['RELEASED'] . '</th>
|
<th>' . $lang['RELEASED'] . '</th>
|
||||||
<th>' . $lang['BONUS'] . '</th>';
|
<th>' . $lang['BONUS'] . '</th>';
|
||||||
$html .= ($bb_cfg['seed_bonus_enabled']) ? '<th>' . $lang['SEED_BONUS'] . '</th>' : '';
|
$html .= config()->get('seed_bonus_enabled') ? '<th>' . $lang['SEED_BONUS'] . '</th>' : '';
|
||||||
$html .= '</tr>
|
$html .= '</tr>
|
||||||
<tr class="row1">
|
<tr class="row1">
|
||||||
<td>' . $lang['TOTAL_TRAF'] . '</td>
|
<td>' . $lang['TOTAL_TRAF'] . '</td>
|
||||||
|
@ -178,17 +180,17 @@ switch ($mode) {
|
||||||
<td id="u_up_total"><span class="editable bold seedmed">' . humn_size($btu['u_up_total']) . '</span></td>
|
<td id="u_up_total"><span class="editable bold seedmed">' . humn_size($btu['u_up_total']) . '</span></td>
|
||||||
<td id="u_up_release"><span class="editable bold seedmed">' . humn_size($btu['u_up_release']) . '</span></td>
|
<td id="u_up_release"><span class="editable bold seedmed">' . humn_size($btu['u_up_release']) . '</span></td>
|
||||||
<td id="u_up_bonus"><span class="editable bold seedmed">' . humn_size($btu['u_up_bonus']) . '</span></td>';
|
<td id="u_up_bonus"><span class="editable bold seedmed">' . humn_size($btu['u_up_bonus']) . '</span></td>';
|
||||||
$html .= ($bb_cfg['seed_bonus_enabled']) ? '<td id="user_points"><span class="editable bold points">' . $profiledata['user_points'] . '</b></td>' : '';
|
$html .= config()->get('seed_bonus_enabled') ? '<td id="user_points"><span class="editable bold points">' . $profiledata['user_points'] . '</b></td>' : '';
|
||||||
$html .= '</tr>
|
$html .= '</tr>
|
||||||
<tr class="row5">
|
<tr class="row5">
|
||||||
<td colspan="1">' . $lang['MAX_SPEED'] . '</td>
|
<td colspan="1">' . $lang['MAX_SPEED'] . '</td>
|
||||||
<td colspan="2">' . $lang['DL_DL_SPEED'] . ': ' . $speed_down . '</span></td>
|
<td colspan="2">' . $lang['DL_DL_SPEED'] . ': ' . $speed_down . '</span></td>
|
||||||
<td colspan="2">' . $lang['DL_UL_SPEED'] . ': ' . $speed_up . '</span></td>';
|
<td colspan="2">' . $lang['DL_UL_SPEED'] . ': ' . $speed_up . '</span></td>';
|
||||||
$html .= ($bb_cfg['seed_bonus_enabled']) ? '<td colspan="1"></td>' : '';
|
$html .= config()->get('seed_bonus_enabled') ? '<td colspan="1"></td>' : '';
|
||||||
$html .= '</tr>';
|
$html .= '</tr>';
|
||||||
|
|
||||||
$this->response['user_ratio'] = '
|
$this->response['user_ratio'] = '
|
||||||
<th><a href="' . $bb_cfg['ratio_url_help'] . '" class="bold">' . $lang['USER_RATIO'] . '</a>:</th>
|
<th><a href="' . config()->get('ratio_url_help') . '" class="bold">' . $lang['USER_RATIO'] . '</a>:</th>
|
||||||
<td>' . $user_ratio . '</td>
|
<td>' . $user_ratio . '</td>
|
||||||
';
|
';
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -11,7 +11,7 @@ if (!defined('IN_AJAX')) {
|
||||||
die(basename(__FILE__));
|
die(basename(__FILE__));
|
||||||
}
|
}
|
||||||
|
|
||||||
global $userdata, $lang, $bb_cfg;
|
global $userdata, $lang;
|
||||||
|
|
||||||
if (!$mode = (string)$this->request['mode']) {
|
if (!$mode = (string)$this->request['mode']) {
|
||||||
$this->ajax_die('invalid mode (empty)');
|
$this->ajax_die('invalid mode (empty)');
|
||||||
|
@ -19,7 +19,7 @@ if (!$mode = (string)$this->request['mode']) {
|
||||||
|
|
||||||
switch ($mode) {
|
switch ($mode) {
|
||||||
case 'clear_cache':
|
case 'clear_cache':
|
||||||
foreach ($bb_cfg['cache']['engines'] as $cache_name => $cache_val) {
|
foreach (config()->get('cache.engines') as $cache_name => $cache_val) {
|
||||||
CACHE($cache_name)->rm();
|
CACHE($cache_name)->rm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,20 +48,20 @@ switch ($mode) {
|
||||||
$this->response['template_cache_html'] = '<span class="seed bold">' . $lang['ALL_TEMPLATE_CLEARED'] . '</span>';
|
$this->response['template_cache_html'] = '<span class="seed bold">' . $lang['ALL_TEMPLATE_CLEARED'] . '</span>';
|
||||||
break;
|
break;
|
||||||
case 'indexer':
|
case 'indexer':
|
||||||
exec("indexer --config {$bb_cfg['sphinx_config_path']} --all --rotate", $result);
|
exec("indexer --config " . config()->get('sphinx_config_path') . " --all --rotate", $result);
|
||||||
|
|
||||||
if (!is_file($bb_cfg['sphinx_config_path'] . ".log")) {
|
if (!is_file(config()->get('sphinx_config_path') . ".log")) {
|
||||||
file_put_contents($bb_cfg['sphinx_config_path'] . ".log", "##############################" . date("H:i:s", TIMENOW) . "##############################\r\n\r\n\r\n\r\n", FILE_APPEND);
|
file_put_contents(config()->get('sphinx_config_path') . ".log", "##############################" . date("H:i:s", TIMENOW) . "##############################\r\n\r\n\r\n\r\n", FILE_APPEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
file_put_contents($bb_cfg['sphinx_config_path'] . ".log", "##############################" . date("H:i:s", TIMENOW) . "##############################\r\n", FILE_APPEND);
|
file_put_contents(config()->get('sphinx_config_path') . ".log", "##############################" . date("H:i:s", TIMENOW) . "##############################\r\n", FILE_APPEND);
|
||||||
|
|
||||||
foreach ($result as $row) {
|
foreach ($result as $row) {
|
||||||
file_put_contents($bb_cfg['sphinx_config_path'] . ".log", $row . "\r\n", FILE_APPEND);
|
file_put_contents(config()->get('sphinx_config_path') . ".log", $row . "\r\n", FILE_APPEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
file_put_contents($bb_cfg['sphinx_config_path'] . ".log", "\r\n", FILE_APPEND);
|
file_put_contents(config()->get('sphinx_config_path') . ".log", "\r\n", FILE_APPEND);
|
||||||
file_put_contents($bb_cfg['sphinx_config_path'] . ".log", "\r\n", FILE_APPEND);
|
file_put_contents(config()->get('sphinx_config_path') . ".log", "\r\n", FILE_APPEND);
|
||||||
|
|
||||||
$this->response['indexer_html'] = '<span class="seed bold">' . $lang['INDEXER'] . '</span>';
|
$this->response['indexer_html'] = '<span class="seed bold">' . $lang['INDEXER'] . '</span>';
|
||||||
break;
|
break;
|
||||||
|
@ -82,10 +82,6 @@ switch ($mode) {
|
||||||
\TorrentPier\Helpers\CronHelper::enableBoard();
|
\TorrentPier\Helpers\CronHelper::enableBoard();
|
||||||
$this->response['unlock_cron_html'] = '<span class="seed bold">' . $lang['ADMIN_UNLOCKED'] . '</span>';
|
$this->response['unlock_cron_html'] = '<span class="seed bold">' . $lang['ADMIN_UNLOCKED'] . '</span>';
|
||||||
break;
|
break;
|
||||||
case 'restore_corrupt_files':
|
|
||||||
file_write('', RESTORE_CORRUPT_CONFIRM_FILE, replace_content: true);
|
|
||||||
$this->response['restore_corrupt_files_html'] = '<span class="seed bold">' . $lang['INTEGRITY_RESTORE_CONFIRM_OK'] . '</span>';
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
$this->ajax_die('Invalid mode: ' . $mode);
|
$this->ajax_die('Invalid mode: ' . $mode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -11,7 +11,7 @@ if (!defined('IN_AJAX')) {
|
||||||
die(basename(__FILE__));
|
die(basename(__FILE__));
|
||||||
}
|
}
|
||||||
|
|
||||||
global $userdata, $lang, $bb_cfg;
|
global $userdata, $lang;
|
||||||
|
|
||||||
if (!$mode = (string)$this->request['mode']) {
|
if (!$mode = (string)$this->request['mode']) {
|
||||||
$this->ajax_die('invalid mode (empty)');
|
$this->ajax_die('invalid mode (empty)');
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -11,7 +11,7 @@ if (!defined('IN_AJAX')) {
|
||||||
die(basename(__FILE__));
|
die(basename(__FILE__));
|
||||||
}
|
}
|
||||||
|
|
||||||
global $userdata, $bb_cfg, $lang, $datastore, $log_action;
|
global $userdata, $lang, $datastore, $log_action;
|
||||||
|
|
||||||
if (!$mode = (string)$this->request['mode']) {
|
if (!$mode = (string)$this->request['mode']) {
|
||||||
$this->ajax_die('invalid mode (empty)');
|
$this->ajax_die('invalid mode (empty)');
|
||||||
|
@ -22,7 +22,7 @@ switch ($mode) {
|
||||||
$topics = (string)$this->request['topic_ids'];
|
$topics = (string)$this->request['topic_ids'];
|
||||||
$status = (int)$this->request['status'];
|
$status = (int)$this->request['status'];
|
||||||
|
|
||||||
// Валидность статуса
|
// Check status validity
|
||||||
if (!isset($lang['TOR_STATUS_NAME'][$status])) {
|
if (!isset($lang['TOR_STATUS_NAME'][$status])) {
|
||||||
$this->ajax_die($lang['TOR_STATUS_FAILED']);
|
$this->ajax_die($lang['TOR_STATUS_FAILED']);
|
||||||
}
|
}
|
||||||
|
@ -30,9 +30,29 @@ switch ($mode) {
|
||||||
$topic_ids = DB()->fetch_rowset("SELECT attach_id FROM " . BB_BT_TORRENTS . " WHERE topic_id IN($topics)", 'attach_id');
|
$topic_ids = DB()->fetch_rowset("SELECT attach_id FROM " . BB_BT_TORRENTS . " WHERE topic_id IN($topics)", 'attach_id');
|
||||||
|
|
||||||
foreach ($topic_ids as $attach_id) {
|
foreach ($topic_ids as $attach_id) {
|
||||||
|
$tor = DB()->fetch_row("
|
||||||
|
SELECT
|
||||||
|
tor.forum_id, tor.topic_id, t.topic_title, tor.tor_status
|
||||||
|
FROM " . BB_BT_TORRENTS . " tor
|
||||||
|
INNER JOIN " . BB_TOPICS . " t ON(t.topic_id = tor.topic_id)
|
||||||
|
WHERE tor.attach_id = $attach_id LIMIT 1");
|
||||||
|
|
||||||
|
if (!$tor) {
|
||||||
|
$this->ajax_die($lang['TORRENT_FAILED']);
|
||||||
|
}
|
||||||
|
|
||||||
\TorrentPier\Legacy\Torrent::change_tor_status($attach_id, $status);
|
\TorrentPier\Legacy\Torrent::change_tor_status($attach_id, $status);
|
||||||
|
|
||||||
|
// Log action
|
||||||
|
$log_msg = sprintf($lang['TOR_STATUS_LOG_ACTION'], config()->get('tor_icons')[$status] . ' <b> ' . $lang['TOR_STATUS_NAME'][$status] . '</b>', config()->get('tor_icons')[$tor['tor_status']] . ' <b> ' . $lang['TOR_STATUS_NAME'][$tor['tor_status']] . '</b>');
|
||||||
|
$log_action->mod('mod_topic_change_tor_status', [
|
||||||
|
'forum_id' => $tor['forum_id'],
|
||||||
|
'topic_id' => $tor['topic_id'],
|
||||||
|
'topic_title' => $tor['topic_title'],
|
||||||
|
'log_msg' => $log_msg . '<br/>-------------',
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
$this->response['status'] = $bb_cfg['tor_icons'][$status];
|
$this->response['status'] = config()->get('tor_icons')[$status];
|
||||||
$this->response['topics'] = explode(',', $topics);
|
$this->response['topics'] = explode(',', $topics);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -57,17 +77,17 @@ switch ($mode) {
|
||||||
|
|
||||||
DB()->query("UPDATE " . BB_TOPICS . " SET topic_title = '$topic_title_sql' WHERE topic_id = $topic_id LIMIT 1");
|
DB()->query("UPDATE " . BB_TOPICS . " SET topic_title = '$topic_title_sql' WHERE topic_id = $topic_id LIMIT 1");
|
||||||
|
|
||||||
// Обновление кеша новостей на главной
|
// Update the news cache on the index page
|
||||||
$news_forums = array_flip(explode(',', $bb_cfg['latest_news_forum_id']));
|
$news_forums = array_flip(explode(',', config()->get('latest_news_forum_id')));
|
||||||
if (isset($news_forums[$t_data['forum_id']]) && $bb_cfg['show_latest_news']) {
|
if (isset($news_forums[$t_data['forum_id']]) && config()->get('show_latest_news')) {
|
||||||
$datastore->enqueue([
|
$datastore->enqueue([
|
||||||
'latest_news'
|
'latest_news'
|
||||||
]);
|
]);
|
||||||
$datastore->update('latest_news');
|
$datastore->update('latest_news');
|
||||||
}
|
}
|
||||||
|
|
||||||
$net_forums = array_flip(explode(',', $bb_cfg['network_news_forum_id']));
|
$net_forums = array_flip(explode(',', config()->get('network_news_forum_id')));
|
||||||
if (isset($net_forums[$t_data['forum_id']]) && $bb_cfg['show_network_news']) {
|
if (isset($net_forums[$t_data['forum_id']]) && config()->get('show_network_news')) {
|
||||||
$datastore->enqueue([
|
$datastore->enqueue([
|
||||||
'network_news'
|
'network_news'
|
||||||
]);
|
]);
|
||||||
|
@ -78,6 +98,7 @@ switch ($mode) {
|
||||||
$log_action->mod('mod_topic_renamed', [
|
$log_action->mod('mod_topic_renamed', [
|
||||||
'forum_id' => $t_data['forum_id'],
|
'forum_id' => $t_data['forum_id'],
|
||||||
'topic_id' => $topic_id,
|
'topic_id' => $topic_id,
|
||||||
|
'topic_id_new' => $topic_id,
|
||||||
'topic_title' => $old_title,
|
'topic_title' => $old_title,
|
||||||
'topic_title_new' => $new_title
|
'topic_title_new' => $new_title
|
||||||
]);
|
]);
|
||||||
|
@ -130,8 +151,8 @@ switch ($mode) {
|
||||||
} else {
|
} else {
|
||||||
$user_reg_ip = \TorrentPier\Helpers\IPHelper::long2ip_extended($profiledata['user_reg_ip']);
|
$user_reg_ip = \TorrentPier\Helpers\IPHelper::long2ip_extended($profiledata['user_reg_ip']);
|
||||||
$user_last_ip = \TorrentPier\Helpers\IPHelper::long2ip_extended($profiledata['user_last_ip']);
|
$user_last_ip = \TorrentPier\Helpers\IPHelper::long2ip_extended($profiledata['user_last_ip']);
|
||||||
$reg_ip = '<a href="' . $bb_cfg['whois_info'] . $user_reg_ip . '" class="gen" target="_blank">' . $user_reg_ip . '</a>';
|
$reg_ip = '<a href="' . config()->get('whois_info') . $user_reg_ip . '" class="gen" target="_blank">' . $user_reg_ip . '</a>';
|
||||||
$last_ip = '<a href="' . $bb_cfg['whois_info'] . $user_last_ip . '" class="gen" target="_blank">' . $user_last_ip . '</a>';
|
$last_ip = '<a href="' . config()->get('whois_info') . $user_last_ip . '" class="gen" target="_blank">' . $user_last_ip . '</a>';
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response['ip_list_html'] = '
|
$this->response['ip_list_html'] = '
|
||||||
|
@ -151,5 +172,5 @@ switch ($mode) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$this->ajax_die('Invalid mode');
|
$this->ajax_die('Invalid mode: ' . $mode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -11,7 +11,7 @@ if (!defined('IN_AJAX')) {
|
||||||
die(basename(__FILE__));
|
die(basename(__FILE__));
|
||||||
}
|
}
|
||||||
|
|
||||||
global $lang, $bb_cfg, $userdata, $wordCensor;
|
global $lang, $userdata;
|
||||||
|
|
||||||
if (!isset($this->request['type'])) {
|
if (!isset($this->request['type'])) {
|
||||||
$this->ajax_die('empty type');
|
$this->ajax_die('empty type');
|
||||||
|
@ -76,16 +76,16 @@ switch ($this->request['type']) {
|
||||||
$message = "[quote=\"" . $quote_username . "\"][qpost=" . $post['post_id'] . "]" . $post['post_text'] . "[/quote]\r";
|
$message = "[quote=\"" . $quote_username . "\"][qpost=" . $post['post_id'] . "]" . $post['post_text'] . "[/quote]\r";
|
||||||
|
|
||||||
// hide user passkey
|
// hide user passkey
|
||||||
$message = preg_replace('#(?<=[\?&;]' . $bb_cfg['passkey_key'] . '=)[a-zA-Z0-9]#', 'passkey', $message);
|
$message = preg_replace('#(?<=[\?&;]' . config()->get('passkey_key') . '=)[a-zA-Z0-9]#', 'passkey', $message);
|
||||||
// hide sid
|
// hide sid
|
||||||
$message = preg_replace('#(?<=[\?&;]sid=)[a-zA-Z0-9]#', 'sid', $message);
|
$message = preg_replace('#(?<=[\?&;]sid=)[a-zA-Z0-9]#', 'sid', $message);
|
||||||
|
|
||||||
$message = $wordCensor->censorString($message);
|
$message = censor()->censorString($message);
|
||||||
|
|
||||||
if ($post['post_id'] == $post['topic_first_post_id']) {
|
if ($post['post_id'] == $post['topic_first_post_id']) {
|
||||||
$message = "[quote]" . $post['topic_title'] . "[/quote]\r";
|
$message = "[quote]" . $post['topic_title'] . "[/quote]\r";
|
||||||
}
|
}
|
||||||
if (mb_strlen($message, 'UTF-8') > 1000) {
|
if (mb_strlen($message, DEFAULT_CHARSET) > 1000) {
|
||||||
$this->response['redirect'] = make_url(POSTING_URL . '?mode=quote&' . POST_POST_URL . '=' . $post_id);
|
$this->response['redirect'] = make_url(POSTING_URL . '?mode=quote&' . POST_POST_URL . '=' . $post_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ switch ($this->request['type']) {
|
||||||
if ($post['poster_id'] != $userdata['user_id'] && !$is_auth['auth_mod']) {
|
if ($post['poster_id'] != $userdata['user_id'] && !$is_auth['auth_mod']) {
|
||||||
$this->ajax_die($lang['EDIT_OWN_POSTS']);
|
$this->ajax_die($lang['EDIT_OWN_POSTS']);
|
||||||
}
|
}
|
||||||
if ((mb_strlen($post['post_text'], 'UTF-8') > 1000) || $post['post_attachment'] || ($post['topic_first_post_id'] == $post_id)) {
|
if ((mb_strlen($post['post_text'], DEFAULT_CHARSET) > 1000) || $post['post_attachment'] || ($post['topic_first_post_id'] == $post_id)) {
|
||||||
$this->response['redirect'] = make_url(POSTING_URL . '?mode=editpost&' . POST_POST_URL . '=' . $post_id);
|
$this->response['redirect'] = make_url(POSTING_URL . '?mode=editpost&' . POST_POST_URL . '=' . $post_id);
|
||||||
} elseif ($this->request['type'] == 'editor') {
|
} elseif ($this->request['type'] == 'editor') {
|
||||||
$text = (string)$this->request['text'];
|
$text = (string)$this->request['text'];
|
||||||
|
@ -120,10 +120,10 @@ switch ($this->request['type']) {
|
||||||
|
|
||||||
if (mb_strlen($text) > 2) {
|
if (mb_strlen($text) > 2) {
|
||||||
if ($text != $post['post_text']) {
|
if ($text != $post['post_text']) {
|
||||||
if ($bb_cfg['max_smilies']) {
|
if (config()->get('max_smilies')) {
|
||||||
$count_smilies = substr_count(bbcode2html($text), '<img class="smile" src="' . $bb_cfg['smilies_path']);
|
$count_smilies = substr_count(bbcode2html($text), '<img class="smile" src="' . config()->get('smilies_path'));
|
||||||
if ($count_smilies > $bb_cfg['max_smilies']) {
|
if ($count_smilies > config()->get('max_smilies')) {
|
||||||
$this->ajax_die(sprintf($lang['MAX_SMILIES_PER_POST'], $bb_cfg['max_smilies']));
|
$this->ajax_die(sprintf($lang['MAX_SMILIES_PER_POST'], config()->get('max_smilies')));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DB()->query("UPDATE " . BB_POSTS_TEXT . " SET post_text = '" . DB()->escape($text) . "' WHERE post_id = $post_id LIMIT 1");
|
DB()->query("UPDATE " . BB_POSTS_TEXT . " SET post_text = '" . DB()->escape($text) . "' WHERE post_id = $post_id LIMIT 1");
|
||||||
|
@ -179,7 +179,7 @@ switch ($this->request['type']) {
|
||||||
<input title="Alt+Enter" name="preview" type="submit" value="' . $lang['PREVIEW'] . '">
|
<input title="Alt+Enter" name="preview" type="submit" value="' . $lang['PREVIEW'] . '">
|
||||||
<input type="button" onclick="edit_post(' . $post_id . ');" value="' . $lang['CANCEL'] . '">
|
<input type="button" onclick="edit_post(' . $post_id . ');" value="' . $lang['CANCEL'] . '">
|
||||||
<input type="button" onclick="edit_post(' . $post_id . ', \'editor\', $(\'#message-' . $post_id . '\').val()); return false;" class="bold" value="' . $lang['SUBMIT'] . '">
|
<input type="button" onclick="edit_post(' . $post_id . ', \'editor\', $(\'#message-' . $post_id . '\').val()); return false;" class="bold" value="' . $lang['SUBMIT'] . '">
|
||||||
</div><hr>
|
</div><hr/>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var bbcode = new BBCode("message-' . $post_id . '");
|
var bbcode = new BBCode("message-' . $post_id . '");
|
||||||
var ctrl = "ctrl";
|
var ctrl = "ctrl";
|
||||||
|
@ -225,7 +225,7 @@ switch ($this->request['type']) {
|
||||||
$sql = "SELECT MAX(p.post_time) AS last_post_time FROM " . BB_POSTS . " p WHERE $where_sql";
|
$sql = "SELECT MAX(p.post_time) AS last_post_time FROM " . BB_POSTS . " p WHERE $where_sql";
|
||||||
if ($row = DB()->fetch_row($sql) and $row['last_post_time']) {
|
if ($row = DB()->fetch_row($sql) and $row['last_post_time']) {
|
||||||
if ($userdata['user_level'] == USER) {
|
if ($userdata['user_level'] == USER) {
|
||||||
if ((TIMENOW - $row['last_post_time']) < $bb_cfg['flood_interval']) {
|
if ((TIMENOW - $row['last_post_time']) < config()->get('flood_interval')) {
|
||||||
$this->ajax_die($lang['FLOOD_ERROR']);
|
$this->ajax_die($lang['FLOOD_ERROR']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,10 +251,10 @@ switch ($this->request['type']) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($bb_cfg['max_smilies']) {
|
if (config()->get('max_smilies')) {
|
||||||
$count_smilies = substr_count(bbcode2html($message), '<img class="smile" src="' . $bb_cfg['smilies_path']);
|
$count_smilies = substr_count(bbcode2html($message), '<img class="smile" src="' . config()->get('smilies_path'));
|
||||||
if ($count_smilies > $bb_cfg['max_smilies']) {
|
if ($count_smilies > config()->get('max_smilies')) {
|
||||||
$this->ajax_die(sprintf($lang['MAX_SMILIES_PER_POST'], $bb_cfg['max_smilies']));
|
$this->ajax_die(sprintf($lang['MAX_SMILIES_PER_POST'], config()->get('max_smilies')));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +272,7 @@ switch ($this->request['type']) {
|
||||||
'post_text' => $message
|
'post_text' => $message
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($bb_cfg['topic_notify_enabled']) {
|
if (config()->get('topic_notify_enabled')) {
|
||||||
$notify = !empty($this->request['notify']);
|
$notify = !empty($this->request['notify']);
|
||||||
\TorrentPier\Legacy\Post::user_notification('reply', $post, $post['topic_title'], $post['forum_id'], $topic_id, $notify);
|
\TorrentPier\Legacy\Post::user_notification('reply', $post, $post['topic_title'], $post['forum_id'], $topic_id, $notify);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -11,7 +11,7 @@ if (!defined('IN_AJAX')) {
|
||||||
die(basename(__FILE__));
|
die(basename(__FILE__));
|
||||||
}
|
}
|
||||||
|
|
||||||
global $bb_cfg, $lang;
|
global $lang;
|
||||||
|
|
||||||
if (!$mode = (string)$this->request['mode']) {
|
if (!$mode = (string)$this->request['mode']) {
|
||||||
$this->ajax_die('invalid mode (empty)');
|
$this->ajax_die('invalid mode (empty)');
|
||||||
|
@ -24,28 +24,12 @@ switch ($mode) {
|
||||||
case 'create':
|
case 'create':
|
||||||
$map->createSitemap();
|
$map->createSitemap();
|
||||||
if (is_file(SITEMAP_DIR . '/sitemap.xml')) {
|
if (is_file(SITEMAP_DIR . '/sitemap.xml')) {
|
||||||
$html .= $lang['SITEMAP_CREATED'] . ': <b>' . bb_date(TIMENOW, $bb_cfg['post_date_format']) . '</b> ' . $lang['SITEMAP_AVAILABLE'] . ': <a href="' . make_url('sitemap/sitemap.xml') . '" target="_blank">' . make_url('sitemap/sitemap.xml') . '</a>';
|
$html .= $lang['SITEMAP_CREATED'] . ': <b>' . bb_date(TIMENOW, config()->get('post_date_format')) . '</b> ' . $lang['SITEMAP_AVAILABLE'] . ': <a href="' . make_url('sitemap/sitemap.xml') . '" target="_blank">' . make_url('sitemap/sitemap.xml') . '</a>';
|
||||||
} else {
|
} else {
|
||||||
$html .= $lang['SITEMAP_NOT_CREATED'];
|
$html .= $lang['SITEMAP_NOT_CREATED'];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'search_update':
|
|
||||||
if (!is_file(SITEMAP_DIR . '/sitemap.xml')) {
|
|
||||||
$map->createSitemap();
|
|
||||||
}
|
|
||||||
|
|
||||||
$map_link = make_url(hide_bb_path(SITEMAP_DIR . '/sitemap.xml'));
|
|
||||||
|
|
||||||
foreach ($bb_cfg['sitemap_sending'] as $source_name => $source_link) {
|
|
||||||
if ($map->sendSitemap($source_link, $map_link)) {
|
|
||||||
$html .= '<br />' . $lang['SITEMAP_NOTIFY_SEARCH'] . ' ' . $source_name . ' : <span style="color: green;">' . $lang['SITEMAP_SENT'] . '</span>';
|
|
||||||
} else {
|
|
||||||
$html .= '<br />' . $lang['SITEMAP_NOTIFY_SEARCH'] . ' ' . $source_name . ' : <span style="color: red;">' . $lang['SITEMAP_ERROR'] . '</span> URL: <a href="' . $source_link . urlencode($map_link) . '" target="_blank">' . $source_link . $map_link . '</a>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$this->ajax_die("Invalid mode: $mode");
|
$this->ajax_die("Invalid mode: $mode");
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -11,9 +11,9 @@ if (!defined('IN_AJAX')) {
|
||||||
die(basename(__FILE__));
|
die(basename(__FILE__));
|
||||||
}
|
}
|
||||||
|
|
||||||
global $bb_cfg, $lang, $userdata;
|
global $lang, $userdata;
|
||||||
|
|
||||||
if (!$bb_cfg['tor_thank']) {
|
if (!config()->get('tor_thank')) {
|
||||||
$this->ajax_die($lang['MODULE_OFF']);
|
$this->ajax_die($lang['MODULE_OFF']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,12 +49,12 @@ switch ($mode) {
|
||||||
|
|
||||||
// Limit voters per topic
|
// Limit voters per topic
|
||||||
$thanks_count = DB()->fetch_row('SELECT COUNT(*) as thx FROM ' . BB_THX . " WHERE topic_id = $topic_id")['thx'];
|
$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']) {
|
if ($thanks_count > (int)config()->get('tor_thank_limit_per_topic')) {
|
||||||
DB()->query('DELETE FROM ' . BB_THX . " WHERE topic_id = $topic_id ORDER BY time ASC LIMIT 1");
|
DB()->query('DELETE FROM ' . BB_THX . " WHERE topic_id = $topic_id ORDER BY time ASC LIMIT 1");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'get':
|
case 'get':
|
||||||
if (IS_GUEST && !$bb_cfg['tor_thanks_list_guests']) {
|
if (IS_GUEST && !config()->get('tor_thanks_list_guests')) {
|
||||||
$this->ajax_die($lang['NEED_TO_LOGIN_FIRST']);
|
$this->ajax_die($lang['NEED_TO_LOGIN_FIRST']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||||
*
|
*
|
||||||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -116,7 +116,7 @@ switch ($mode) {
|
||||||
$new_tpl_id = $tpl_id;
|
$new_tpl_id = $tpl_id;
|
||||||
$this->response['msg'] = "Включен шаблон $tpl_name";
|
$this->response['msg'] = "Включен шаблон $tpl_name";
|
||||||
}
|
}
|
||||||
DB()->query("UPDATE " . BB_FORUMS . " SET forum_tpl_id = $new_tpl_id WHERE forum_id = $forum_id");
|
DB()->query("UPDATE " . BB_FORUMS . " SET forum_tpl_id = $new_tpl_id WHERE forum_id = $forum_id LIMIT 1");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// сохранение изменений
|
// сохранение изменений
|
||||||
|
@ -127,7 +127,7 @@ switch ($mode) {
|
||||||
$msg .= 'Шаблон был отредактирован: ' . html_ent_decode($last_edit_by_username) . ', ' . bb_date($tpl_data['tpl_last_edit_tm'], 'd-M-y H:i');
|
$msg .= 'Шаблон был отредактирован: ' . html_ent_decode($last_edit_by_username) . ', ' . bb_date($tpl_data['tpl_last_edit_tm'], 'd-M-y H:i');
|
||||||
$this->ajax_die($msg);
|
$this->ajax_die($msg);
|
||||||
}
|
}
|
||||||
$sql = "UPDATE " . BB_TOPIC_TPL . " SET " . DB()->build_array('UPDATE', $sql_args) . " WHERE tpl_id = $tpl_id";
|
$sql = "UPDATE " . BB_TOPIC_TPL . " SET " . DB()->build_array('UPDATE', $sql_args) . " WHERE tpl_id = $tpl_id LIMIT 1";
|
||||||
if (!DB()->query($sql)) {
|
if (!DB()->query($sql)) {
|
||||||
$sql_error = DB()->sql_error();
|
$sql_error = DB()->sql_error();
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue