mirror of
https://github.com/torrentpier/torrentpier
synced 2025-08-21 13:54:02 -07:00
feat!: Laravel migration preparations (#2000)
* feat!: sunset legacy system - good night sweet prince Preparations for the full rewrite of TorrentPier application using Laravel framework. BREAKING CHANGE: Complete architectural overhaul. All legacy code will be replaced with Laravel implementation.
This commit is contained in:
parent
5b5bf49f4e
commit
b8e47d569e
1710 changed files with 423 additions and 5596 deletions
|
@ -1,7 +0,0 @@
|
||||||
9766c534bddad8e82e6d19f9bad5cf70b9887f9a
|
|
||||||
92ce77ec0ec703c08a659419087a373f76e711f7
|
|
||||||
2d53efc945c7747be1755d0b66557a86bdc12cbd
|
|
||||||
602137b65129b817811b80975a369ebde3270c6d
|
|
||||||
4eb26ae37e1f4c82a45961517ffeb54c20200408
|
|
||||||
e59adce848a9e10ee5775254045cbbd915236b8b
|
|
||||||
9e0a64108d62236ab07b3f8d10e8c78269b8e1d1
|
|
|
@ -1,19 +1,18 @@
|
||||||
# EditorConfig helps developers define and maintain consistent
|
|
||||||
# coding styles between different editors and IDEs
|
|
||||||
# editorconfig.org
|
|
||||||
|
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
end_of_line = lf
|
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
trim_trailing_whitespace = true
|
end_of_line = lf
|
||||||
insert_final_newline = true
|
indent_size = 4
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
[*.{diff,md}]
|
[*.md]
|
||||||
trim_trailing_whitespace = false
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
[*.{php,tpl}]
|
[*.{yml,yaml}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[docker-compose.yml]
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
---
|
|
||||||
name: Feature / Enhancement request
|
|
||||||
about: Suggest an idea for TorrentPier
|
|
||||||
title: "[Feature]"
|
|
||||||
labels: [Feature, Enhancement]
|
|
||||||
assignees: ''
|
|
||||||
---
|
|
80
.github/workflows/cd.yml
vendored
80
.github/workflows/cd.yml
vendored
|
@ -1,80 +0,0 @@
|
||||||
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.3'
|
|
||||||
|
|
||||||
- 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
|
|
74
.github/workflows/ci.yml
vendored
74
.github/workflows/ci.yml
vendored
|
@ -1,74 +0,0 @@
|
||||||
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.3'
|
|
||||||
|
|
||||||
- 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 }}
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
name: 🎉 Deploy
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- name: 🚚 Get latest code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: 🔩 Setup PHP
|
|
||||||
uses: shivammathur/setup-php@v2
|
|
||||||
with:
|
|
||||||
php-version: '8.3'
|
|
||||||
|
|
||||||
- name: 🖇 Install Composer dependencies
|
|
||||||
run: composer install --no-dev --no-progress --prefer-dist --optimize-autoloader
|
|
||||||
|
|
||||||
- name: 📂 Sync files
|
|
||||||
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
|
|
||||||
with:
|
|
||||||
server: ${{ secrets.FTP_SERVER }}
|
|
||||||
username: ${{ secrets.FTP_USERNAME }}
|
|
||||||
password: ${{ secrets.FTP_PASSWORD }}
|
|
||||||
server-dir: ${{ secrets.FTP_DIR }}
|
|
||||||
protocol: ${{ secrets.FTP_PROTOCOL }}
|
|
||||||
port: ${{ secrets.FTP_PORT }}
|
|
||||||
exclude: |
|
|
||||||
**/.git*
|
|
||||||
**/.git*/**
|
|
||||||
.env
|
|
57
.github/workflows/phpmd.yml
vendored
57
.github/workflows/phpmd.yml
vendored
|
@ -1,57 +0,0 @@
|
||||||
# This workflow uses actions that are not certified by GitHub.
|
|
||||||
# They are provided by a third-party and are governed by
|
|
||||||
# separate terms of service, privacy policy, and support
|
|
||||||
# documentation.
|
|
||||||
# PHPMD is a spin-off project of PHP Depend and
|
|
||||||
# aims to be a PHP equivalent of the well known Java tool PMD.
|
|
||||||
# What PHPMD does is: It takes a given PHP source code base
|
|
||||||
# and look for several potential problems within that source.
|
|
||||||
# These problems can be things like:
|
|
||||||
# Possible bugs
|
|
||||||
# Suboptimal code
|
|
||||||
# Overcomplicated expressions
|
|
||||||
# Unused parameters, methods, properties
|
|
||||||
# More details at https://phpmd.org/
|
|
||||||
|
|
||||||
name: PHPMD
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "master" ]
|
|
||||||
pull_request:
|
|
||||||
# The branches below must be a subset of the branches above
|
|
||||||
branches: [ "master" ]
|
|
||||||
schedule:
|
|
||||||
- cron: '40 0 * * 3'
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
PHPMD:
|
|
||||||
name: Run PHPMD scanning
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read # for checkout to fetch code
|
|
||||||
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
|
|
||||||
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Setup PHP
|
|
||||||
uses: shivammathur/setup-php@aa1fe473f9c687b6fb896056d771232c0bc41161
|
|
||||||
with:
|
|
||||||
coverage: none
|
|
||||||
tools: phpmd
|
|
||||||
|
|
||||||
- name: Run PHPMD
|
|
||||||
run: phpmd . sarif codesize --reportfile phpmd-results.sarif
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Upload analysis results to GitHub
|
|
||||||
uses: github/codeql-action/upload-sarif@v2
|
|
||||||
with:
|
|
||||||
sarif_file: phpmd-results.sarif
|
|
||||||
wait-for-processing: true
|
|
41
.github/workflows/schedule.yml
vendored
41
.github/workflows/schedule.yml
vendored
|
@ -1,41 +0,0 @@
|
||||||
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
|
|
205
.gitignore
vendored
205
.gitignore
vendored
|
@ -1,47 +1,176 @@
|
||||||
### IDE ###
|
# Created by https://www.toptal.com/developers/gitignore/api/macos,windows,laravel,phpstorm+all
|
||||||
.idea
|
# Edit at https://www.toptal.com/developers/gitignore?templates=macos,windows,laravel,phpstorm+all
|
||||||
.vscode
|
|
||||||
|
|
||||||
### TorrentPier ###
|
### Laravel ###
|
||||||
*.log
|
/vendor/
|
||||||
install.php_*
|
node_modules/
|
||||||
composer-setup.php
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
|
||||||
|
# Laravel 4 specific
|
||||||
|
bootstrap/compiled.php
|
||||||
|
app/storage/
|
||||||
|
|
||||||
|
# Laravel 5 & Lumen specific
|
||||||
|
public/storage
|
||||||
|
public/hot
|
||||||
|
|
||||||
|
# Laravel 5 & Lumen specific with changed public path
|
||||||
|
public_html/storage
|
||||||
|
public_html/hot
|
||||||
|
|
||||||
|
storage/*.key
|
||||||
.env
|
.env
|
||||||
.php_cs.cache
|
Homestead.yaml
|
||||||
data/avatars
|
Homestead.json
|
||||||
data/uploads
|
/.vagrant
|
||||||
internal_data/atom
|
.phpunit.result.cache
|
||||||
internal_data/cache
|
|
||||||
internal_data/log
|
|
||||||
internal_data/updater.json
|
|
||||||
sitemap
|
|
||||||
internal_data/triggers
|
|
||||||
library/config.local.php
|
|
||||||
vendor
|
|
||||||
|
|
||||||
### Archives ###
|
### macOS ###
|
||||||
*.phar
|
# General
|
||||||
*.rar
|
|
||||||
*.tar
|
|
||||||
*.gz
|
|
||||||
*.zip
|
|
||||||
*.7z
|
|
||||||
*.torrent
|
|
||||||
*.pak
|
|
||||||
|
|
||||||
### Windows ###
|
|
||||||
Thumbs.db
|
|
||||||
Desktop.ini
|
|
||||||
$RECYCLE.BIN/
|
|
||||||
*.lnk
|
|
||||||
*.bat
|
|
||||||
|
|
||||||
### OSX ###
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.AppleDouble
|
.AppleDouble
|
||||||
.LSOverride
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
._*
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
.Spotlight-V100
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
.Trashes
|
.Trashes
|
||||||
*.orig
|
.VolumeIcon.icns
|
||||||
*.rej
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
### macOS Patch ###
|
||||||
|
# iCloud generated files
|
||||||
|
*.icloud
|
||||||
|
|
||||||
|
### PhpStorm+all ###
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# AWS User-specific
|
||||||
|
.idea/**/aws.xml
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
# .idea/artifacts
|
||||||
|
# .idea/compiler.xml
|
||||||
|
# .idea/jarRepositories.xml
|
||||||
|
# .idea/modules.xml
|
||||||
|
# .idea/*.iml
|
||||||
|
# .idea/modules
|
||||||
|
# *.iml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-*/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# SonarLint plugin
|
||||||
|
.idea/sonarlint/
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based Rest Client
|
||||||
|
.idea/httpRequests
|
||||||
|
|
||||||
|
# Android studio 3.1+ serialized cache file
|
||||||
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
|
### PhpStorm+all Patch ###
|
||||||
|
# Ignore everything but code style settings and run configurations
|
||||||
|
# that are supposed to be shared within teams.
|
||||||
|
|
||||||
|
.idea/*
|
||||||
|
|
||||||
|
!.idea/codeStyles
|
||||||
|
!.idea/runConfigurations
|
||||||
|
|
||||||
|
### Windows ###
|
||||||
|
# Windows thumbnail cache files
|
||||||
|
Thumbs.db
|
||||||
|
Thumbs.db:encryptable
|
||||||
|
ehthumbs.db
|
||||||
|
ehthumbs_vista.db
|
||||||
|
|
||||||
|
# Dump file
|
||||||
|
*.stackdump
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
[Dd]esktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/macos,windows,laravel,phpstorm+all
|
||||||
|
|
18
.htaccess
18
.htaccess
|
@ -1,18 +0,0 @@
|
||||||
## set default server charset
|
|
||||||
AddDefaultCharset UTF-8
|
|
||||||
|
|
||||||
## folder listing access control
|
|
||||||
Options All -Indexes
|
|
||||||
|
|
||||||
## sitemap and atom rewrite
|
|
||||||
RewriteEngine On
|
|
||||||
RewriteRule ^sitemap.xml$ sitemap/sitemap.xml [L]
|
|
||||||
RewriteRule ^/internal_data/atom/(.*) /atom$1 [L]
|
|
||||||
|
|
||||||
## deny access to git folder
|
|
||||||
RedirectMatch 404 /\\.git(/|$)
|
|
||||||
|
|
||||||
## deny access to system files
|
|
||||||
<FilesMatch "\.(.*sql|tpl|db|inc|log|md|env)|(config|common).php$">
|
|
||||||
Require all denied
|
|
||||||
</FilesMatch>
|
|
168
README.md
168
README.md
|
@ -1,188 +1,36 @@
|
||||||
<p align="center"><a href="https://torrentpier.com"><img src="https://torrentpier.com/styles/default/xenforo/bull-logo.svg" width="400px" alt="TorrentPier" /></a></p>
|
<p align="center"><a href="https://torrentpier.com"><img src="https://torrentpier.com/styles/default/xenforo/bull-logo.svg" width="400px" alt="TorrentPier" /></a></p>
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
Bull-powered BitTorrent tracker engine
|
|
||||||
<br/>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<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://packagist.org/packages/torrentpier/torrentpier"><img src="https://img.shields.io/packagist/stars/torrentpier/torrentpier" alt="Stars Packagist"></a>
|
|
||||||
<a href="https://crowdin.com/project/torrentpier"><img src="https://badges.crowdin.net/torrentpier/localized.svg" alt="Crowdin"></a>
|
|
||||||
<a href="https://nightly.link/torrentpier/torrentpier/workflows/ci/master/TorrentPier-master"><img src="https://img.shields.io/badge/Nightly%20release-gray?logo=hackthebox&logoColor=fff" alt="TorrentPier nightly"></a>
|
|
||||||
<a href="https://packagist.org/packages/torrentpier/torrentpier"><img src="https://img.shields.io/packagist/dt/torrentpier/torrentpier" alt="Downloads"></a>
|
|
||||||
<a href="https://packagist.org/packages/torrentpier/torrentpier"><img src="https://img.shields.io/packagist/v/torrentpier/torrentpier" alt="Version"></a>
|
|
||||||
<a href="https://github.com/torrentpier/torrentpier/releases"><img src="https://img.shields.io/github/release-date/torrentpier/torrentpier" alt="Last release"></a>
|
|
||||||
<img src="https://img.shields.io/github/repo-size/torrentpier/torrentpier" alt="Size">
|
|
||||||
<a href="https://github.com/SamKirkland/FTP-Deploy-Action"><img src="https://img.shields.io/badge/Deployed to TorrentPier Demo with-FTP DEPLOY ACTION-%3CCOLOR%3E?color=2b9348" alt="Deployed to TorrentPier Demo with FTP Deploy Action"></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
## 🐂 About TorrentPier
|
## 🐂 About TorrentPier
|
||||||
|
|
||||||
TorrentPier — bull-powered BitTorrent Public/Private tracker engine, written in PHP. High speed, simple modifications, load-balanced
|
TorrentPier — bull-powered BitTorrent public/private tracker engine, written in PHP. High speed, simple modifications, load-balanced
|
||||||
architecture. In addition, we have a very helpful
|
architecture. In addition, we have a very helpful
|
||||||
[official support forum](https://torrentpier.com), where it's possible to get support and download modifications for the engine.
|
[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 undergoing a **major 3.0 rewrite** to remove all legacy code and modernize the codebase to current PHP standards. **Backward compatibility is not a priority** - this release focuses on moving forward with clean, modern architecture. If you want to delve deep into the code, check our [issues](https://github.com/torrentpier/torrentpier/issues) and go from there.
|
TorrentPier is currently being **completely rewritten from scratch on Laravel**. The current codebase may not reflect the final product, and code downloaded from the `dexter` branch may not include promised features.
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> This branch contains **development code** that is not ready for production use. For stable releases, please download from the [GitHub releases](https://github.com/torrentpier/torrentpier/releases) or use the [download center](https://nightly.link/torrentpier/torrentpier/workflows/ci/master/TorrentPier-master).
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> TorrentPier 3.0 will introduce breaking changes. Existing installations should remain on 2.x versions until ready to migrate to the new architecture.
|
> The legacy codebase (v2.x) can be found on the **master branch**. This Laravel rewrite (v3.0) will introduce breaking changes and is not backward compatible.
|
||||||
|
|
||||||
## ✨ Features
|
## ✨ Features
|
||||||
* Rich forum with 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
|
* TorrServer integration support
|
||||||
* BitTorrent v2 support
|
* BitTorrent v2 support
|
||||||
* Event-based invite system
|
* Event-based invite system
|
||||||
* Bonus points
|
* Bonus points
|
||||||
* Polling system
|
* Polling system
|
||||||
* PM/DM system
|
* PM/DM system
|
||||||
* Multilingual support (Russian and English are currently fully supported, with others in the future)
|
* Multilingual support
|
||||||
* Atom/RSS feeds
|
* Atom/RSS feeds
|
||||||
* ... and so MUCH MORE!
|
* ... and so MUCH MORE!
|
||||||
|
|
||||||
## 🖥️ Demo
|
|
||||||
|
|
||||||
* URL: https://torrentpier.duckdns.org
|
|
||||||
* Username: `admin`
|
|
||||||
* Password: `admin`
|
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> Demo resets every 24 hours!
|
|
||||||
|
|
||||||
## 🔧 Requirements
|
|
||||||
|
|
||||||
* Apache / nginx ([example config](install/nginx.conf)) / caddy ([example config](install/Caddyfile))
|
|
||||||
* MySQL 5.5.3 or above (including MySQL 8.0+) / MariaDB 10.0 or above / Percona
|
|
||||||
* PHP: 8.3 / 8.4
|
|
||||||
* PHP Extensions: mbstring, gd, bcmath, intl, tidy (optional), xml, xmlwriter
|
|
||||||
* Crontab (Recommended)
|
|
||||||
|
|
||||||
## 💾 Installation
|
|
||||||
|
|
||||||
For the installation, select one of the installation variants below:
|
|
||||||
|
|
||||||
### Quick (Clean install) 🚀
|
|
||||||
|
|
||||||
Check out our [autoinstall](https://github.com/torrentpier/autoinstall) repository with detailed instructions.
|
|
||||||
|
|
||||||
> [!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 🔩
|
|
||||||
|
|
||||||
1. Install [Composer](https://getcomposer.org/)
|
|
||||||
2. Run the following command to create the TorrentPier project
|
|
||||||
```shell
|
|
||||||
composer create-project torrentpier/torrentpier
|
|
||||||
```
|
|
||||||
3. [Check our system requirements](#-requirements)
|
|
||||||
4. After, run this command in the project directory to install Composer dependencies
|
|
||||||
```shell
|
|
||||||
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:
|
|
||||||
* `data/avatars`, `data/uploads`, `data/uploads/thumbs`
|
|
||||||
* `internal_data/atom`, `internal_data/cache`, `internal_data/log`, `internal_data/triggers`
|
|
||||||
* `sitemap`
|
|
||||||
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]
|
|
||||||
> 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 👣
|
|
||||||
|
|
||||||
1. Edit these files:
|
|
||||||
* `favicon.png` (change to your own)
|
|
||||||
* `robots.txt` (change the addresses in lines `Host` and `Sitemap` to your own)
|
|
||||||
2. Log in to the forum using the **admin/admin** login/password, and finish setting up via admin panel. Don't forget to change your password!
|
|
||||||
|
|
||||||
## 🔐 Security vulnerabilities
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
* *It's recommended to run `cron.php`.* - For significant tracker speed increase it may be required to replace the built-in cron.php with an operating system daemon.
|
|
||||||
* *Local configuration copy.* - You can override the settings using the local configuration file `library/config.local.php`.
|
|
||||||
|
|
||||||
## 💚 Contributing / Contributors
|
|
||||||
|
|
||||||
Please read our [contributing policy](CONTRIBUTING.md) and [code of conduct](CODE_OF_CONDUCT.md) for details, and the process for
|
|
||||||
submitting pull requests to us. But we are always ready to review your pull-request for compliance with
|
|
||||||
these requirements. Just send it!
|
|
||||||
|
|
||||||
<a href="https://github.com/torrentpier/torrentpier/graphs/contributors">
|
|
||||||
<img src="https://contrib.rocks/image?repo=torrentpier/torrentpier" alt="Contributors"/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
Made with [contrib.rocks](https://contrib.rocks).
|
|
||||||
|
|
||||||
## 💞 Sponsoring
|
|
||||||
|
|
||||||
Support this project by becoming a sponsor or a backer.
|
|
||||||
|
|
||||||
[](https://opencollective.com/torrentpier)
|
|
||||||
[](https://opencollective.com/torrentpier)
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Monero</summary>
|
|
||||||
|
|
||||||
```
|
|
||||||
42zJE3FDvN8foP9QYgDrBjgtd7h2FipGCGmAcmG5VFQuRkJBGMbCvoLSmivepmAMEgik2E8MPWUzKaoYsGCtmhvL7ZN73jh
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>YooMoney</summary>
|
|
||||||
|
|
||||||
```
|
|
||||||
4100118022415720
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## 📦 Versioning
|
## 📦 Versioning
|
||||||
|
|
||||||
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/torrentpier/torrentpier/tags).
|
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/torrentpier/torrentpier/tags).
|
||||||
|
|
57
_cleanup.php
57
_cleanup.php
|
@ -1,57 +0,0 @@
|
||||||
<?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
130
_release.php
|
@ -1,130 +0,0 @@
|
||||||
<?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');
|
|
126
cliff.toml
126
cliff.toml
|
@ -1,126 +0,0 @@
|
||||||
# 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"
|
|
|
@ -1,53 +0,0 @@
|
||||||
# Application Configuration
|
|
||||||
|
|
||||||
System configuration files using PHP arrays for type safety and IDE support:
|
|
||||||
|
|
||||||
- **app.php**: Core application settings
|
|
||||||
- Site name, URL, timezone
|
|
||||||
- Debug mode, environment
|
|
||||||
- Feature flags and toggles
|
|
||||||
|
|
||||||
- **database.php**: Database connection settings
|
|
||||||
- Multiple connection definitions
|
|
||||||
- Read/write splitting configuration
|
|
||||||
- Connection pooling settings
|
|
||||||
|
|
||||||
- **cache.php**: Cache driver configurations
|
|
||||||
- Redis, Memcached, file-based settings
|
|
||||||
- TTL defaults per cache type
|
|
||||||
- Cache key prefixes
|
|
||||||
|
|
||||||
- **tracker.php**: BitTorrent tracker settings
|
|
||||||
- Announce intervals
|
|
||||||
- Peer limits
|
|
||||||
- Ratio requirements
|
|
||||||
|
|
||||||
- **environments/**: Environment-specific overrides
|
|
||||||
- Development, staging, production settings
|
|
||||||
- Local developer configurations
|
|
||||||
|
|
||||||
Example database configuration:
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
return [
|
|
||||||
'default' => env('DB_CONNECTION', 'mysql'),
|
|
||||||
|
|
||||||
'connections' => [
|
|
||||||
'mysql' => [
|
|
||||||
'driver' => 'mysql',
|
|
||||||
'host' => env('DB_HOST', '127.0.0.1'),
|
|
||||||
'port' => env('DB_PORT', 3306),
|
|
||||||
'database' => env('DB_DATABASE', 'tp'),
|
|
||||||
'username' => env('DB_USERNAME', 'root'),
|
|
||||||
'password' => env('DB_PASSWORD', ''),
|
|
||||||
'charset' => 'utf8mb4',
|
|
||||||
'collation' => 'utf8mb4_unicode_ci',
|
|
||||||
'options' => [
|
|
||||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
||||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
|
||||||
PDO::ATTR_EMULATE_PREPARES => false,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
```
|
|
|
@ -1,26 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
return [
|
|
||||||
// Container configuration
|
|
||||||
'environment' => env('APP_ENV', 'development'),
|
|
||||||
'debug' => env('APP_DEBUG', false),
|
|
||||||
|
|
||||||
// Enable/disable features
|
|
||||||
'autowiring' => true,
|
|
||||||
'annotations' => false,
|
|
||||||
|
|
||||||
// Compilation settings for production
|
|
||||||
'compilation_dir' => __DIR__ . '/../internal_data/cache/container',
|
|
||||||
'proxies_dir' => __DIR__ . '/../internal_data/cache/proxies',
|
|
||||||
|
|
||||||
// Additional definition files to load
|
|
||||||
'definition_files' => [
|
|
||||||
// Add custom definition files here
|
|
||||||
// __DIR__ . '/services/custom.php',
|
|
||||||
],
|
|
||||||
|
|
||||||
// Container-specific settings
|
|
||||||
'container' => [
|
|
||||||
// Add any PHP-DI specific settings here
|
|
||||||
],
|
|
||||||
];
|
|
|
@ -1,30 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use function DI\factory;
|
|
||||||
use function DI\get;
|
|
||||||
use function DI\autowire;
|
|
||||||
|
|
||||||
return [
|
|
||||||
// Add custom service definitions here as they are implemented
|
|
||||||
|
|
||||||
// Examples (uncomment and modify when implementing):
|
|
||||||
|
|
||||||
// Logger service example
|
|
||||||
// 'logger' => factory(function () {
|
|
||||||
// $logger = new \Monolog\Logger('torrentpier');
|
|
||||||
// $logger->pushHandler(new \Monolog\Handler\StreamHandler(__DIR__ . '/../internal_data/logs/app.log'));
|
|
||||||
// return $logger;
|
|
||||||
// }),
|
|
||||||
|
|
||||||
// Configuration service example
|
|
||||||
// 'config' => factory(function () {
|
|
||||||
// return [
|
|
||||||
// 'app' => require __DIR__ . '/app.php',
|
|
||||||
// 'database' => require __DIR__ . '/database.php',
|
|
||||||
// 'cache' => require __DIR__ . '/cache.php',
|
|
||||||
// ];
|
|
||||||
// }),
|
|
||||||
|
|
||||||
// Interface to implementation binding example
|
|
||||||
// 'ServiceInterface' => autowire('ConcreteService'),
|
|
||||||
];
|
|
|
@ -1,99 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Example: How to use the DI Container in TorrentPier 3.0
|
|
||||||
*
|
|
||||||
* NOTE: These are examples for future implementation following the hexagonal architecture spec.
|
|
||||||
* Most services referenced here don't exist yet and will be implemented in phases.
|
|
||||||
*/
|
|
||||||
|
|
||||||
use TorrentPier\Infrastructure\DependencyInjection\Bootstrap;
|
|
||||||
use TorrentPier\Infrastructure\DependencyInjection\ContainerFactory;
|
|
||||||
|
|
||||||
// ===== PHASE 1: Foundation (CURRENT) =====
|
|
||||||
|
|
||||||
// 1. Bootstrap the container (typically done once in index.php or bootstrap file)
|
|
||||||
$rootPath = __DIR__ . '/../..';
|
|
||||||
$container = Bootstrap::init($rootPath);
|
|
||||||
|
|
||||||
// 2. Basic container usage (works now)
|
|
||||||
$containerInstance = app(); // Get container itself
|
|
||||||
$hasService = $container->has('some.service'); // Check if service exists
|
|
||||||
|
|
||||||
// ===== PHASE 2: Domain Modeling (FUTURE) =====
|
|
||||||
|
|
||||||
// 3. Repository interfaces (when implemented in Domain layer)
|
|
||||||
// $userRepository = app('TorrentPier\Domain\User\Repository\UserRepositoryInterface');
|
|
||||||
// $torrentRepository = app('TorrentPier\Domain\Tracker\Repository\TorrentRepositoryInterface');
|
|
||||||
// $forumRepository = app('TorrentPier\Domain\Forum\Repository\ForumRepositoryInterface');
|
|
||||||
|
|
||||||
// ===== PHASE 3: Application Services (FUTURE) =====
|
|
||||||
|
|
||||||
// 4. Command/Query handlers (when implemented)
|
|
||||||
// $registerUserHandler = app('TorrentPier\Application\User\Handler\RegisterUserHandler');
|
|
||||||
// $announceHandler = app('TorrentPier\Application\Tracker\Handler\ProcessAnnounceHandler');
|
|
||||||
// $createPostHandler = app('TorrentPier\Application\Forum\Handler\CreatePostHandler');
|
|
||||||
|
|
||||||
// 5. Making command instances with parameters
|
|
||||||
// $command = $container->make('TorrentPier\Application\User\Command\RegisterUserCommand', [
|
|
||||||
// 'username' => 'john_doe',
|
|
||||||
// 'email' => 'john@example.com',
|
|
||||||
// 'password' => 'secure_password'
|
|
||||||
// ]);
|
|
||||||
|
|
||||||
// ===== PHASE 4: Infrastructure (FUTURE) =====
|
|
||||||
|
|
||||||
// 6. Database and cache (when infrastructure is implemented)
|
|
||||||
// $database = app('database.connection.default');
|
|
||||||
// $cache = app('cache.factory')('forum'); // Get cache instance for 'forum' namespace
|
|
||||||
|
|
||||||
// ===== PHASE 5: Presentation (FUTURE) =====
|
|
||||||
|
|
||||||
// 7. Controllers (when implemented)
|
|
||||||
// $userController = app('TorrentPier\Presentation\Http\Controllers\Api\UserController');
|
|
||||||
// $trackerController = app('TorrentPier\Presentation\Http\Controllers\Web\TrackerController');
|
|
||||||
|
|
||||||
// ===== TESTING EXAMPLES =====
|
|
||||||
|
|
||||||
// 8. Testing with custom container (works now)
|
|
||||||
$testContainer = ContainerFactory::create([
|
|
||||||
'definitions' => [
|
|
||||||
'test.service' => \DI\factory(function () {
|
|
||||||
return new class {
|
|
||||||
public function test() { return 'test'; }
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
'environment' => 'testing',
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 9. Safe service resolution (works now)
|
|
||||||
try {
|
|
||||||
$service = app('optional.service');
|
|
||||||
} catch (RuntimeException $e) {
|
|
||||||
// Service not found, handle gracefully
|
|
||||||
$service = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== LEGACY INTEGRATION (CURRENT) =====
|
|
||||||
|
|
||||||
// 10. Integration with legacy code
|
|
||||||
// In legacy files, after including common.php or similar:
|
|
||||||
if (!Bootstrap::getContainer()) {
|
|
||||||
Bootstrap::init(BB_ROOT ?? __DIR__ . '/../..');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 11. Method injection (works now if service exists)
|
|
||||||
class ExampleService
|
|
||||||
{
|
|
||||||
public function processData(string $data)
|
|
||||||
{
|
|
||||||
// Container can inject dependencies when calling this method
|
|
||||||
return "Processed: $data";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$exampleService = new ExampleService();
|
|
||||||
$result = $container->call([$exampleService, 'processData'], [
|
|
||||||
'data' => 'test data'
|
|
||||||
]);
|
|
|
@ -1,436 +0,0 @@
|
||||||
# Hexagonal Architecture Directory Structure Specification
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This document specifies the new hexagonal architecture directory structure for TorrentPier 3.0. The structure follows Domain-Driven Design (DDD) principles and implements a clean separation of concerns through hexagonal architecture (ports and adapters pattern).
|
|
||||||
|
|
||||||
## Directory Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
/src/
|
|
||||||
├── Domain/ # Core business logic - no framework dependencies
|
|
||||||
│ ├── Forum/ # Forum bounded context
|
|
||||||
│ │ ├── Model/ # Aggregates and entities
|
|
||||||
│ │ ├── ValueObject/ # Value objects (PostId, ThreadTitle, etc.)
|
|
||||||
│ │ ├── Repository/ # Repository interfaces
|
|
||||||
│ │ └── Exception/ # Domain-specific exceptions
|
|
||||||
│ ├── Tracker/ # BitTorrent tracker bounded context
|
|
||||||
│ │ ├── Model/ # Torrent, Peer aggregates
|
|
||||||
│ │ ├── ValueObject/ # InfoHash, PeerId, etc.
|
|
||||||
│ │ ├── Repository/ # Repository interfaces
|
|
||||||
│ │ └── Exception/ # Tracker-specific exceptions
|
|
||||||
│ ├── User/ # User management bounded context
|
|
||||||
│ │ ├── Model/ # User aggregate
|
|
||||||
│ │ ├── ValueObject/ # UserId, Email, Username
|
|
||||||
│ │ ├── Repository/ # User repository interface
|
|
||||||
│ │ └── Exception/ # Authentication/authorization exceptions
|
|
||||||
│ └── Shared/ # Shared kernel - minimal shared concepts
|
|
||||||
│ ├── Model/ # Base classes (AggregateRoot, Entity)
|
|
||||||
│ ├── ValueObject/ # Common value objects (Id, DateTime)
|
|
||||||
│ └── Event/ # Domain events base classes
|
|
||||||
│
|
|
||||||
├── Application/ # Application services - orchestration layer
|
|
||||||
│ ├── Forum/
|
|
||||||
│ │ ├── Command/ # Commands (CreatePost, LockThread)
|
|
||||||
│ │ ├── Query/ # Queries (GetThreadList, SearchPosts)
|
|
||||||
│ │ └── Handler/ # Command and query handlers
|
|
||||||
│ ├── Tracker/
|
|
||||||
│ │ ├── Command/ # Commands (RegisterTorrent, ProcessAnnounce)
|
|
||||||
│ │ ├── Query/ # Queries (GetPeerList, GetTorrentStats)
|
|
||||||
│ │ └── Handler/ # Command and query handlers
|
|
||||||
│ └── User/
|
|
||||||
│ ├── Command/ # Commands (RegisterUser, ChangePassword)
|
|
||||||
│ ├── Query/ # Queries (GetUserProfile, SearchUsers)
|
|
||||||
│ └── Handler/ # Command and query handlers
|
|
||||||
│
|
|
||||||
├── Infrastructure/ # External concerns and implementations
|
|
||||||
│ ├── Persistence/ # Data persistence layer
|
|
||||||
│ │ ├── Database/ # Database adapter and connection management
|
|
||||||
│ │ ├── Migration/ # Database migrations
|
|
||||||
│ │ └── Repository/ # Repository implementations
|
|
||||||
│ ├── Cache/ # Caching implementations
|
|
||||||
│ │ ├── Redis/ # Redis adapter
|
|
||||||
│ │ ├── Memcached/ # Memcached adapter
|
|
||||||
│ │ └── File/ # File-based cache adapter
|
|
||||||
│ ├── Email/ # Email service implementations
|
|
||||||
│ │ ├── Template/ # Email templates
|
|
||||||
│ │ └── Transport/ # SMTP, API transports
|
|
||||||
│ └── FileStorage/ # File storage abstractions
|
|
||||||
│ ├── Local/ # Local filesystem storage
|
|
||||||
│ └── S3/ # AWS S3 storage adapter
|
|
||||||
│
|
|
||||||
└── Presentation/ # User interface layer
|
|
||||||
├── Http/ # Web interface
|
|
||||||
│ ├── Controllers/ # HTTP controllers
|
|
||||||
│ │ ├── Admin/ # Admin panel controllers
|
|
||||||
│ │ ├── Api/ # REST API controllers
|
|
||||||
│ │ └── Web/ # Web UI controllers
|
|
||||||
│ ├── Middleware/ # HTTP middleware (auth, CORS, etc.)
|
|
||||||
│ ├── Requests/ # Request DTOs and validation
|
|
||||||
│ └── Responses/ # Response transformers
|
|
||||||
└── Cli/ # Command line interface
|
|
||||||
└── Commands/ # Console commands
|
|
||||||
|
|
||||||
# Additional directories (outside /src/)
|
|
||||||
/config/ # Application configuration
|
|
||||||
├── app.php # Main application settings
|
|
||||||
├── database.php # Database connections
|
|
||||||
├── cache.php # Cache drivers configuration
|
|
||||||
├── tracker.php # BitTorrent tracker settings
|
|
||||||
└── environments/ # Environment-specific overrides
|
|
||||||
|
|
||||||
/tests/ # Test suites (Pest)
|
|
||||||
├── Unit/ # Unit tests (mirrors src/ structure)
|
|
||||||
├── Feature/ # Feature/Integration tests
|
|
||||||
├── Pest.php # Pest configuration
|
|
||||||
└── TestCase.php # Base test case
|
|
||||||
```
|
|
||||||
|
|
||||||
## Directory README.md Templates
|
|
||||||
|
|
||||||
### Domain Layer READMEs
|
|
||||||
|
|
||||||
#### `/src/Domain/README.md`
|
|
||||||
```markdown
|
|
||||||
# Domain Layer
|
|
||||||
|
|
||||||
This directory contains the core business logic of TorrentPier. Code here should:
|
|
||||||
- Have no dependencies on frameworks or infrastructure
|
|
||||||
- Represent pure business rules and domain models
|
|
||||||
- Be testable in isolation
|
|
||||||
- Use only PHP language features and domain concepts
|
|
||||||
|
|
||||||
## Bounded Contexts
|
|
||||||
- **Forum**: Discussion forums, posts, threads
|
|
||||||
- **Tracker**: BitTorrent tracking, peers, torrents
|
|
||||||
- **User**: User management, authentication, profiles
|
|
||||||
- **Shared**: Minimal shared concepts between contexts
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `/src/Domain/Tracker/Model/README.md`
|
|
||||||
```markdown
|
|
||||||
# Tracker Domain Models
|
|
||||||
|
|
||||||
Contains aggregate roots and entities for the BitTorrent tracker:
|
|
||||||
- `Torrent`: Aggregate root for torrent management
|
|
||||||
- `Peer`: Entity representing a BitTorrent peer
|
|
||||||
- `TorrentStatistics`: Value object for torrent stats
|
|
||||||
|
|
||||||
Example:
|
|
||||||
```php
|
|
||||||
class Torrent extends AggregateRoot
|
|
||||||
{
|
|
||||||
public function announce(Peer $peer, AnnounceEvent $event): void
|
|
||||||
{
|
|
||||||
// Business logic for handling announces
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `/src/Domain/Tracker/ValueObject/README.md`
|
|
||||||
```markdown
|
|
||||||
# Tracker Value Objects
|
|
||||||
|
|
||||||
Immutable objects representing domain concepts:
|
|
||||||
- `InfoHash`: 20-byte torrent identifier
|
|
||||||
- `PeerId`: Peer client identifier
|
|
||||||
- `Port`: Network port (1-65535)
|
|
||||||
- `BytesTransferred`: Upload/download bytes
|
|
||||||
|
|
||||||
Example:
|
|
||||||
```php
|
|
||||||
final class InfoHash
|
|
||||||
{
|
|
||||||
private string $hash;
|
|
||||||
|
|
||||||
public function __construct(string $hash)
|
|
||||||
{
|
|
||||||
$this->guardAgainstInvalidHash($hash);
|
|
||||||
$this->hash = $hash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Application Layer READMEs
|
|
||||||
|
|
||||||
#### `/src/Application/README.md`
|
|
||||||
```markdown
|
|
||||||
# Application Layer
|
|
||||||
|
|
||||||
Contains application services that orchestrate domain objects to fulfill use cases.
|
|
||||||
- Commands: Write operations that change state
|
|
||||||
- Queries: Read operations for data retrieval
|
|
||||||
- Handlers: Process commands and queries
|
|
||||||
|
|
||||||
This layer should:
|
|
||||||
- Coordinate domain objects
|
|
||||||
- Handle transactions
|
|
||||||
- Dispatch domain events
|
|
||||||
- Not contain business logic
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `/src/Application/Tracker/Command/README.md`
|
|
||||||
```markdown
|
|
||||||
# Tracker Commands
|
|
||||||
|
|
||||||
Commands representing write operations:
|
|
||||||
- `RegisterTorrentCommand`: Register new torrent
|
|
||||||
- `UpdateTorrentCommand`: Modify torrent details
|
|
||||||
- `DeleteTorrentCommand`: Remove torrent from tracker
|
|
||||||
|
|
||||||
Example:
|
|
||||||
```php
|
|
||||||
final class RegisterTorrentCommand
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
public readonly string $infoHash,
|
|
||||||
public readonly int $uploaderId,
|
|
||||||
public readonly string $name,
|
|
||||||
public readonly int $size
|
|
||||||
) {}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Infrastructure Layer READMEs
|
|
||||||
|
|
||||||
#### `/src/Infrastructure/README.md`
|
|
||||||
```markdown
|
|
||||||
# Infrastructure Layer
|
|
||||||
|
|
||||||
Technical implementations and external service adapters:
|
|
||||||
- Database persistence
|
|
||||||
- Caching mechanisms
|
|
||||||
- Email services
|
|
||||||
- File storage
|
|
||||||
- Third-party integrations
|
|
||||||
|
|
||||||
Infrastructure depends on domain, not vice versa.
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `/src/Infrastructure/Persistence/Repository/README.md`
|
|
||||||
```markdown
|
|
||||||
# Repository Implementations
|
|
||||||
|
|
||||||
Concrete implementations of domain repository interfaces:
|
|
||||||
- Uses database adapter for persistence
|
|
||||||
- Implements caching strategies
|
|
||||||
- Handles query optimization
|
|
||||||
- Supports multiple database backends
|
|
||||||
|
|
||||||
Example:
|
|
||||||
```php
|
|
||||||
class TorrentRepository implements TorrentRepositoryInterface
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private DatabaseAdapterInterface $db
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function findByInfoHash(InfoHash $infoHash): ?Torrent
|
|
||||||
{
|
|
||||||
// Database adapter implementation
|
|
||||||
$row = $this->db->select('torrents')
|
|
||||||
->where('info_hash', $infoHash->toString())
|
|
||||||
->first();
|
|
||||||
|
|
||||||
return $row ? $this->hydrateFromRow($row) : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Presentation Layer READMEs
|
|
||||||
|
|
||||||
#### `/src/Presentation/README.md`
|
|
||||||
```markdown
|
|
||||||
# Presentation Layer
|
|
||||||
|
|
||||||
User interface implementations:
|
|
||||||
- HTTP controllers for web and API
|
|
||||||
- CLI commands for console operations
|
|
||||||
- Request/response handling
|
|
||||||
- Input validation
|
|
||||||
- Output formatting
|
|
||||||
|
|
||||||
This layer translates between external format and application format.
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `/src/Presentation/Http/Controllers/Api/README.md`
|
|
||||||
```markdown
|
|
||||||
# API Controllers
|
|
||||||
|
|
||||||
RESTful API endpoints following OpenAPI specification:
|
|
||||||
- JSON request/response format
|
|
||||||
- Proper HTTP status codes
|
|
||||||
- HATEOAS where applicable
|
|
||||||
- Rate limiting aware
|
|
||||||
|
|
||||||
Example:
|
|
||||||
```php
|
|
||||||
class UserController
|
|
||||||
{
|
|
||||||
public function register(RegisterRequest $request): JsonResponse
|
|
||||||
{
|
|
||||||
$command = new RegisterUserCommand(
|
|
||||||
$request->getUsername(),
|
|
||||||
$request->getEmail(),
|
|
||||||
$request->getPassword()
|
|
||||||
);
|
|
||||||
|
|
||||||
$userId = $this->commandBus->handle($command);
|
|
||||||
|
|
||||||
return new JsonResponse([
|
|
||||||
'id' => $userId,
|
|
||||||
'username' => $request->getUsername()
|
|
||||||
], Response::HTTP_CREATED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `/src/Presentation/Http/Controllers/Admin/README.md`
|
|
||||||
```markdown
|
|
||||||
# Admin Panel Controllers
|
|
||||||
|
|
||||||
Administrative interface controllers with enhanced security:
|
|
||||||
- Role-based access control (RBAC)
|
|
||||||
- Audit logging for all actions
|
|
||||||
- Additional authentication checks
|
|
||||||
- Administrative dashboards and reports
|
|
||||||
|
|
||||||
Example:
|
|
||||||
```php
|
|
||||||
class AdminUserController
|
|
||||||
{
|
|
||||||
public function index(Request $request): Response
|
|
||||||
{
|
|
||||||
$query = new GetUsersQuery(
|
|
||||||
page: $request->getPage(),
|
|
||||||
filters: $request->getFilters()
|
|
||||||
);
|
|
||||||
|
|
||||||
$users = $this->queryBus->handle($query);
|
|
||||||
|
|
||||||
return $this->render('admin/users/index', [
|
|
||||||
'users' => $users,
|
|
||||||
'filters' => $request->getFilters()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `/config/README.md`
|
|
||||||
```markdown
|
|
||||||
# Application Configuration
|
|
||||||
|
|
||||||
System configuration files using PHP arrays for type safety and IDE support:
|
|
||||||
|
|
||||||
- **app.php**: Core application settings
|
|
||||||
- Site name, URL, timezone
|
|
||||||
- Debug mode, environment
|
|
||||||
- Feature flags and toggles
|
|
||||||
|
|
||||||
- **database.php**: Database connection settings
|
|
||||||
- Multiple connection definitions
|
|
||||||
- Read/write splitting configuration
|
|
||||||
- Connection pooling settings
|
|
||||||
|
|
||||||
- **cache.php**: Cache driver configurations
|
|
||||||
- Redis, Memcached, file-based settings
|
|
||||||
- TTL defaults per cache type
|
|
||||||
- Cache key prefixes
|
|
||||||
|
|
||||||
- **tracker.php**: BitTorrent tracker settings
|
|
||||||
- Announce intervals
|
|
||||||
- Peer limits
|
|
||||||
- Ratio requirements
|
|
||||||
|
|
||||||
- **environments/**: Environment-specific overrides
|
|
||||||
- Development, staging, production settings
|
|
||||||
- Local developer configurations
|
|
||||||
|
|
||||||
Example database configuration:
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
return [
|
|
||||||
'default' => env('DB_CONNECTION', 'mysql'),
|
|
||||||
|
|
||||||
'connections' => [
|
|
||||||
'mysql' => [
|
|
||||||
'driver' => 'mysql',
|
|
||||||
'host' => env('DB_HOST', '127.0.0.1'),
|
|
||||||
'port' => env('DB_PORT', 3306),
|
|
||||||
'database' => env('DB_DATABASE', 'tp'),
|
|
||||||
'username' => env('DB_USERNAME', 'root'),
|
|
||||||
'password' => env('DB_PASSWORD', ''),
|
|
||||||
'charset' => 'utf8mb4',
|
|
||||||
'collation' => 'utf8mb4_unicode_ci',
|
|
||||||
'options' => [
|
|
||||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
||||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
|
||||||
PDO::ATTR_EMULATE_PREPARES => false,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
```
|
|
||||||
|
|
||||||
## Implementation Order
|
|
||||||
|
|
||||||
1. **Phase 1: Foundation**
|
|
||||||
|
|
||||||
- Create directory structure
|
|
||||||
- Set up base classes in Domain/Shared
|
|
||||||
- Configure dependency injection
|
|
||||||
|
|
||||||
2. **Phase 2: Domain Modeling**
|
|
||||||
|
|
||||||
- Implement core aggregates
|
|
||||||
- Create value objects
|
|
||||||
- Define repository interfaces
|
|
||||||
|
|
||||||
3. **Phase 3: Application Services**
|
|
||||||
|
|
||||||
- Create commands and queries
|
|
||||||
- Implement handlers
|
|
||||||
- Set up event dispatching
|
|
||||||
|
|
||||||
4. **Phase 4: Infrastructure**
|
|
||||||
|
|
||||||
- Implement repositories
|
|
||||||
- Configure database adapter
|
|
||||||
- Set up caching
|
|
||||||
|
|
||||||
5. **Phase 5: Presentation**
|
|
||||||
|
|
||||||
- Create controllers
|
|
||||||
- Implement middleware
|
|
||||||
- Build CLI commands
|
|
||||||
|
|
||||||
## Migration Strategy
|
|
||||||
|
|
||||||
- Existing code remains in current locations
|
|
||||||
- New features built in hexagonal architecture
|
|
||||||
- Gradual migration using strangler fig pattern
|
|
||||||
- Legacy adapters bridge old and new code
|
|
||||||
- Feature flags control rollout
|
|
||||||
|
|
||||||
## Key Principles
|
|
||||||
|
|
||||||
1. **Dependency Rule**: Dependencies point inward (Presentation → Application → Domain)
|
|
||||||
2. **Domain Isolation**: Business logic has no framework dependencies
|
|
||||||
3. **Interface Segregation**: Small, focused interfaces
|
|
||||||
4. **CQRS**: Separate read and write models
|
|
||||||
5. **Event-Driven**: Domain events for cross-context communication
|
|
||||||
|
|
||||||
## Testing Strategy
|
|
||||||
|
|
||||||
- **Domain**: Pure unit tests, no mocks needed
|
|
||||||
- **Application**: Unit tests with mocked repositories
|
|
||||||
- **Infrastructure**: Integration tests with real services
|
|
||||||
- **Presentation**: E2E tests for user journeys
|
|
||||||
|
|
||||||
## Notes for Developers
|
|
||||||
|
|
||||||
- Start reading code from the Domain layer
|
|
||||||
- Business rules live in aggregates, not services
|
|
||||||
- Use value objects for type safety
|
|
||||||
- Prefer composition over inheritance
|
|
||||||
- Keep bounded contexts loosely coupled
|
|
331
install.php
331
install.php
|
@ -1,331 +0,0 @@
|
||||||
<?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';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* System requirements
|
|
||||||
*/
|
|
||||||
const CHECK_REQUIREMENTS = [
|
|
||||||
'php_min_version' => '8.3.0',
|
|
||||||
'ext_list' => [
|
|
||||||
'json',
|
|
||||||
'curl',
|
|
||||||
'readline',
|
|
||||||
'mysqli',
|
|
||||||
'bcmath',
|
|
||||||
'mbstring',
|
|
||||||
'intl',
|
|
||||||
'xml',
|
|
||||||
'xmlwriter',
|
|
||||||
'zip',
|
|
||||||
'gd'
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
// Welcoming message
|
|
||||||
out("--- TorrentPier Installer ---\n", 'info');
|
|
||||||
|
|
||||||
// Checking extensions
|
|
||||||
out("- Checking installed extensions...", 'info');
|
|
||||||
|
|
||||||
// [1] Check PHP 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, 'warning');
|
|
||||||
}
|
|
||||||
|
|
||||||
// [2] Check installed PHP Extensions on server
|
|
||||||
foreach (CHECK_REQUIREMENTS['ext_list'] as $ext) {
|
|
||||||
if (!extension_loaded($ext)) {
|
|
||||||
out("- ext-$ext not installed. Check out php.ini file", 'error');
|
|
||||||
if (!defined('EXTENSIONS_NOT_INSTALLED')) {
|
|
||||||
define('EXTENSIONS_NOT_INSTALLED', true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
out("- ext-$ext installed!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!defined('EXTENSIONS_NOT_INSTALLED')) {
|
|
||||||
out("- All extensions are installed!\n", 'success');
|
|
||||||
} else {
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if already installed
|
|
||||||
if (is_file(BB_ROOT . '.env')) {
|
|
||||||
out('- TorrentPier already installed', 'warning');
|
|
||||||
echo 'Are you sure want to re-install TorrentPier? [y/N]: ';
|
|
||||||
if (str_starts_with(mb_strtolower(trim(readline())), 'y')) {
|
|
||||||
out("\n- Re-install process started...", 'info');
|
|
||||||
// environment
|
|
||||||
if (is_file(BB_ROOT . '.env')) {
|
|
||||||
if (unlink(BB_ROOT . '.env')) {
|
|
||||||
out('- Environment file successfully removed!');
|
|
||||||
} else {
|
|
||||||
out('- Cannot remove environment (.env) file. Delete it manually', 'error');
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// composer.phar
|
|
||||||
if (is_file(BB_ROOT . 'composer.phar')) {
|
|
||||||
if (unlink(BB_ROOT . 'composer.phar')) {
|
|
||||||
out("- composer.phar file successfully removed!");
|
|
||||||
} else {
|
|
||||||
out('- Cannot remove composer.phar file. Delete it manually', 'error');
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// composer dir
|
|
||||||
if (is_dir(BB_ROOT . 'vendor')) {
|
|
||||||
removeDir(BB_ROOT . 'vendor', true);
|
|
||||||
if (!is_dir(BB_ROOT . 'vendor')) {
|
|
||||||
out("- Composer directory successfully removed!");
|
|
||||||
} else {
|
|
||||||
out('- Cannot remove Composer directory. Delete it manually', 'error');
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out("- Re-install process completed!\n", 'success');
|
|
||||||
out('- Starting installation...', 'info');
|
|
||||||
} else {
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Applying permissions
|
|
||||||
out("- Applying permissions for folders...", 'info');
|
|
||||||
chmod_r(BB_ROOT . 'data', 0755, 0644);
|
|
||||||
chmod_r(BB_ROOT . 'internal_data', 0755, 0644);
|
|
||||||
chmod_r(BB_ROOT . 'sitemap', 0755, 0644);
|
|
||||||
out("- Permissions successfully applied!\n", 'success');
|
|
||||||
|
|
||||||
// Check composer installation
|
|
||||||
if (!is_file(BB_ROOT . 'vendor/autoload.php')) {
|
|
||||||
out('- Hmm, it seems there are no Composer dependencies', 'info');
|
|
||||||
|
|
||||||
// Downloading composer
|
|
||||||
if (!is_file(BB_ROOT . 'composer.phar')) {
|
|
||||||
out('- Downloading Composer...', 'info');
|
|
||||||
if (copy('https://getcomposer.org/installer', BB_ROOT . 'composer-setup.php')) {
|
|
||||||
out("- Composer successfully downloaded!\n", 'success');
|
|
||||||
runProcess('php ' . BB_ROOT . 'composer-setup.php --install-dir=' . BB_ROOT);
|
|
||||||
} else {
|
|
||||||
out('- Cannot download Composer. Please, download it (composer.phar) manually', 'error');
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
if (is_file(BB_ROOT . 'composer-setup.php')) {
|
|
||||||
if (unlink(BB_ROOT . 'composer-setup.php')) {
|
|
||||||
out("- Composer installation file successfully removed!\n", 'success');
|
|
||||||
} else {
|
|
||||||
out('- Cannot remove Composer installation file (composer-setup.php). Please, delete it manually', 'warning');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
out("- composer.phar file found!\n", 'success');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Installing dependencies
|
|
||||||
if (is_file(BB_ROOT . 'composer.phar')) {
|
|
||||||
out('- Installing dependencies...', 'info');
|
|
||||||
|
|
||||||
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');
|
|
||||||
} else {
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Preparing ENV
|
|
||||||
if (is_file(BB_ROOT . '.env.example') && !is_file(BB_ROOT . '.env')) {
|
|
||||||
if (copy(BB_ROOT . '.env.example', BB_ROOT . '.env')) {
|
|
||||||
out("- Environment file created!\n", 'success');
|
|
||||||
} else {
|
|
||||||
out('- Cannot create environment file', 'error');
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Editing ENV file
|
|
||||||
$DB_HOST = 'localhost';
|
|
||||||
$DB_PORT = 3306;
|
|
||||||
$DB_DATABASE = '';
|
|
||||||
$DB_USERNAME = '';
|
|
||||||
$DB_PASSWORD = '';
|
|
||||||
|
|
||||||
if (is_file(BB_ROOT . '.env')) {
|
|
||||||
out("--- Configuring TorrentPier ---", 'info');
|
|
||||||
|
|
||||||
$envContent = file_get_contents(BB_ROOT . '.env');
|
|
||||||
if ($envContent === false) {
|
|
||||||
out('- Cannot open environment file', 'error');
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
$envLines = explode("\n", $envContent);
|
|
||||||
|
|
||||||
$editedLines = [];
|
|
||||||
foreach ($envLines as $line) {
|
|
||||||
if (trim($line) !== '' && !str_starts_with($line, '#')) {
|
|
||||||
$parts = explode('=', $line, 2);
|
|
||||||
$key = trim($parts[0]);
|
|
||||||
$value = (!empty($parts[1]) && $key !== 'DB_PASSWORD') ? trim($parts[1]) : '';
|
|
||||||
|
|
||||||
out("\nCurrent value of $key: $value", 'debug');
|
|
||||||
echo "Enter a new value for $key (or leave empty to not change): ";
|
|
||||||
$newValue = trim(readline());
|
|
||||||
|
|
||||||
if (!empty($newValue) || $key === 'DB_PASSWORD') {
|
|
||||||
if ($key === 'TP_HOST') {
|
|
||||||
if (!preg_match('/^https?:\/\//', $newValue)) {
|
|
||||||
$newValue = 'https://' . $newValue;
|
|
||||||
}
|
|
||||||
$newValue = parse_url($newValue, PHP_URL_HOST);
|
|
||||||
}
|
|
||||||
$line = "$key=$newValue";
|
|
||||||
$$key = $newValue;
|
|
||||||
} else {
|
|
||||||
$$key = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$editedLines[] = $line;
|
|
||||||
}
|
|
||||||
|
|
||||||
$newEnvContent = implode("\n", $editedLines);
|
|
||||||
if (file_put_contents(BB_ROOT . '.env', $newEnvContent)) {
|
|
||||||
out("- TorrentPier successfully configured!\n", 'success');
|
|
||||||
} else {
|
|
||||||
out('- Cannot save environment file', 'error');
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
out('- Environment file not found', 'error');
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($DB_HOST) && !empty($DB_DATABASE) && !empty($DB_USERNAME)) {
|
|
||||||
out("--- Checking environment settings ---\n", 'info');
|
|
||||||
// Connecting to database
|
|
||||||
out("- Trying connect to MySQL...", 'info');
|
|
||||||
|
|
||||||
// Checking mysqli extension installed
|
|
||||||
if (!extension_loaded('mysqli')) {
|
|
||||||
out('- ext-mysqli not found. Check out php.ini file', 'error');
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect to MySQL server
|
|
||||||
try {
|
|
||||||
$conn = new mysqli($DB_HOST, $DB_USERNAME, $DB_PASSWORD, port: $DB_PORT);
|
|
||||||
} catch (mysqli_sql_exception $exception) {
|
|
||||||
out("- Connection failed: {$exception->getMessage()}", 'error');
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
if (!$conn->connect_error) {
|
|
||||||
out('- Connected successfully!', 'success');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creating database if not exist
|
|
||||||
if ($conn->query("CREATE DATABASE IF NOT EXISTS $DB_DATABASE CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci")) {
|
|
||||||
out('- Database created successfully!', 'success');
|
|
||||||
} else {
|
|
||||||
out("- Cannot create database: $DB_DATABASE", 'error');
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
$conn->select_db($DB_DATABASE);
|
|
||||||
|
|
||||||
// Close database connection - migrations will handle their own connections
|
|
||||||
$conn->close();
|
|
||||||
|
|
||||||
// Run database migrations
|
|
||||||
out('- Setting up database using migrations...', 'info');
|
|
||||||
|
|
||||||
// Check if phinx.php exists
|
|
||||||
if (!is_file(BB_ROOT . 'phinx.php')) {
|
|
||||||
out('- Migration configuration (phinx.php) not found', 'error');
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run migrations
|
|
||||||
$migrationResult = runProcess('php vendor/bin/phinx migrate --configuration=' . BB_ROOT . 'phinx.php');
|
|
||||||
if ($migrationResult !== 0) {
|
|
||||||
out('- Database migration failed', 'error');
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
out("- Database setup completed!\n", 'success');
|
|
||||||
|
|
||||||
// Autofill host in robots.txt
|
|
||||||
$robots_txt_file = BB_ROOT . 'robots.txt';
|
|
||||||
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');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} 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');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup...
|
|
||||||
if (is_file(BB_ROOT . '_cleanup.php')) {
|
|
||||||
out("\n--- Finishing installation (Cleanup) ---\n", 'info');
|
|
||||||
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,27 +0,0 @@
|
||||||
# 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
|
|
|
@ -1,39 +0,0 @@
|
||||||
# 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;
|
|
||||||
}
|
|
||||||
}
|
|
47
legacy/.gitignore
vendored
Normal file
47
legacy/.gitignore
vendored
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
### IDE ###
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
### TorrentPier ###
|
||||||
|
*.log
|
||||||
|
install.php_*
|
||||||
|
composer-setup.php
|
||||||
|
.env
|
||||||
|
.php_cs.cache
|
||||||
|
data/avatars
|
||||||
|
data/uploads
|
||||||
|
internal_data/atom
|
||||||
|
internal_data/cache
|
||||||
|
internal_data/log
|
||||||
|
internal_data/updater.json
|
||||||
|
sitemap
|
||||||
|
internal_data/triggers
|
||||||
|
library/config.local.php
|
||||||
|
vendor
|
||||||
|
|
||||||
|
### Archives ###
|
||||||
|
*.phar
|
||||||
|
*.rar
|
||||||
|
*.tar
|
||||||
|
*.gz
|
||||||
|
*.zip
|
||||||
|
*.7z
|
||||||
|
*.torrent
|
||||||
|
*.pak
|
||||||
|
|
||||||
|
### Windows ###
|
||||||
|
Thumbs.db
|
||||||
|
Desktop.ini
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
*.lnk
|
||||||
|
*.bat
|
||||||
|
|
||||||
|
### OSX ###
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
._*
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
*.orig
|
||||||
|
*.rej
|
192
legacy/README.md
Normal file
192
legacy/README.md
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
<p align="center"><a href="https://torrentpier.com"><img src="https://torrentpier.com/styles/default/xenforo/bull-logo.svg" width="400px" alt="TorrentPier" /></a></p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
Bull-powered BitTorrent tracker engine
|
||||||
|
<br/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<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://packagist.org/packages/torrentpier/torrentpier"><img src="https://img.shields.io/packagist/stars/torrentpier/torrentpier" alt="Stars Packagist"></a>
|
||||||
|
<a href="https://crowdin.com/project/torrentpier"><img src="https://badges.crowdin.net/torrentpier/localized.svg" alt="Crowdin"></a>
|
||||||
|
<a href="https://nightly.link/torrentpier/torrentpier/workflows/ci/master/TorrentPier-master"><img src="https://img.shields.io/badge/Nightly%20release-gray?logo=hackthebox&logoColor=fff" alt="TorrentPier nightly"></a>
|
||||||
|
<a href="https://packagist.org/packages/torrentpier/torrentpier"><img src="https://img.shields.io/packagist/dt/torrentpier/torrentpier" alt="Downloads"></a>
|
||||||
|
<a href="https://packagist.org/packages/torrentpier/torrentpier"><img src="https://img.shields.io/packagist/v/torrentpier/torrentpier" alt="Version"></a>
|
||||||
|
<a href="https://github.com/torrentpier/torrentpier/releases"><img src="https://img.shields.io/github/release-date/torrentpier/torrentpier" alt="Last release"></a>
|
||||||
|
<img src="https://img.shields.io/github/repo-size/torrentpier/torrentpier" alt="Size">
|
||||||
|
<a href="https://github.com/SamKirkland/FTP-Deploy-Action"><img src="https://img.shields.io/badge/Deployed to TorrentPier Demo with-FTP DEPLOY ACTION-%3CCOLOR%3E?color=2b9348" alt="Deployed to TorrentPier Demo with FTP Deploy Action"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## 🐂 About TorrentPier
|
||||||
|
|
||||||
|
TorrentPier — bull-powered BitTorrent Public/Private tracker engine, written in PHP. High speed, simple modifications, load-balanced
|
||||||
|
architecture. In addition, we have a very helpful
|
||||||
|
[official support forum](https://torrentpier.com), where it's possible to get support and download modifications for the engine.
|
||||||
|
|
||||||
|
## 🌈 Current status
|
||||||
|
|
||||||
|
TorrentPier is currently undergoing a **major 3.0 rewrite** to remove all legacy code and modernize the codebase to current PHP standards. **Backward compatibility is not a priority** - this release focuses on moving forward with clean, modern architecture. If you want to delve deep into the code, check our [issues](https://github.com/torrentpier/torrentpier/issues) and go from there.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> TorrentPier 3.0 will introduce breaking changes. Existing installations should remain on 2.x versions until ready to migrate to the new architecture.
|
||||||
|
|
||||||
|
## ✨ Features
|
||||||
|
* Rich forum with browsing/moderation tools
|
||||||
|
* High-load capable, heavily configurable announcer
|
||||||
|
* Scrape support
|
||||||
|
* FreeLeech
|
||||||
|
* [TorrServer integration](https://github.com/YouROK/TorrServer) support
|
||||||
|
* BitTorrent v2 support
|
||||||
|
* Event-based invite system
|
||||||
|
* Bonus points
|
||||||
|
* Polling system
|
||||||
|
* PM/DM system
|
||||||
|
* Multilingual support (Russian and English are currently fully supported, with others in the future)
|
||||||
|
* Atom/RSS feeds
|
||||||
|
* ... and so MUCH MORE!
|
||||||
|
|
||||||
|
## 🖥️ Demo
|
||||||
|
|
||||||
|
* URL: https://torrentpier.duckdns.org
|
||||||
|
* Username: `admin`
|
||||||
|
* Password: `admin`
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Demo resets every 24 hours!
|
||||||
|
|
||||||
|
## 🔧 Requirements
|
||||||
|
|
||||||
|
* Apache / nginx ([example config](install/nginx.conf)) / caddy ([example config](install/Caddyfile))
|
||||||
|
* MySQL 5.5.3 or above (including MySQL 8.0+) / MariaDB 10.0 or above / Percona
|
||||||
|
* PHP: 8.3 / 8.4
|
||||||
|
* PHP Extensions: mbstring, gd, bcmath, intl, tidy (optional), xml, xmlwriter
|
||||||
|
* Crontab (Recommended)
|
||||||
|
|
||||||
|
## 💾 Installation
|
||||||
|
|
||||||
|
For the installation, select one of the installation variants below:
|
||||||
|
|
||||||
|
### Quick (Clean install) 🚀
|
||||||
|
|
||||||
|
Check out our [autoinstall](https://github.com/torrentpier/autoinstall) repository with detailed instructions.
|
||||||
|
|
||||||
|
> [!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 🔩
|
||||||
|
|
||||||
|
1. Install [Composer](https://getcomposer.org/)
|
||||||
|
2. Run the following command to create the TorrentPier project
|
||||||
|
```shell
|
||||||
|
composer create-project torrentpier/torrentpier
|
||||||
|
```
|
||||||
|
3. [Check our system requirements](#-requirements)
|
||||||
|
4. After, run this command in the project directory to install Composer dependencies
|
||||||
|
```shell
|
||||||
|
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:
|
||||||
|
* `data/avatars`, `data/uploads`, `data/uploads/thumbs`
|
||||||
|
* `internal_data/atom`, `internal_data/cache`, `internal_data/log`, `internal_data/triggers`
|
||||||
|
* `sitemap`
|
||||||
|
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]
|
||||||
|
> 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 👣
|
||||||
|
|
||||||
|
1. Edit these files:
|
||||||
|
* `favicon.png` (change to your own)
|
||||||
|
* `robots.txt` (change the addresses in lines `Host` and `Sitemap` to your own)
|
||||||
|
2. Log in to the forum using the **admin/admin** login/password, and finish setting up via admin panel. Don't forget to change your password!
|
||||||
|
|
||||||
|
## 🔐 Security vulnerabilities
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
* *It's recommended to run `cron.php`.* - For significant tracker speed increase it may be required to replace the built-in cron.php with an operating system daemon.
|
||||||
|
* *Local configuration copy.* - You can override the settings using the local configuration file `library/config.local.php`.
|
||||||
|
|
||||||
|
## 💚 Contributing / Contributors
|
||||||
|
|
||||||
|
Please read our [contributing policy](CONTRIBUTING.md) and [code of conduct](CODE_OF_CONDUCT.md) for details, and the process for
|
||||||
|
submitting pull requests to us. But we are always ready to review your pull-request for compliance with
|
||||||
|
these requirements. Just send it!
|
||||||
|
|
||||||
|
<a href="https://github.com/torrentpier/torrentpier/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=torrentpier/torrentpier" alt="Contributors"/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
Made with [contrib.rocks](https://contrib.rocks).
|
||||||
|
|
||||||
|
## 💞 Sponsoring
|
||||||
|
|
||||||
|
Support this project by becoming a sponsor or a backer.
|
||||||
|
|
||||||
|
[](https://opencollective.com/torrentpier)
|
||||||
|
[](https://opencollective.com/torrentpier)
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Monero</summary>
|
||||||
|
|
||||||
|
```
|
||||||
|
42zJE3FDvN8foP9QYgDrBjgtd7h2FipGCGmAcmG5VFQuRkJBGMbCvoLSmivepmAMEgik2E8MPWUzKaoYsGCtmhvL7ZN73jh
|
||||||
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>YooMoney</summary>
|
||||||
|
|
||||||
|
```
|
||||||
|
4100118022415720
|
||||||
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
|
## 📦 Versioning
|
||||||
|
|
||||||
|
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/torrentpier/torrentpier/tags).
|
||||||
|
|
||||||
|
## 📖 License
|
||||||
|
|
||||||
|
This project is licensed under the MIT License - see the [LICENSE](https://github.com/torrentpier/torrentpier/blob/master/LICENSE) file for details.
|
0
composer.lock → legacy/composer.lock
generated
0
composer.lock → legacy/composer.lock
generated
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
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