mirror of
https://github.com/torrentpier/torrentpier
synced 2025-07-05 20:41:41 -07:00
feat(migrations): implement Phinx database migration system (#1976)
* feat(migrations): implement Phinx database migration system and update installation process - Introduced a modern database migration system using Phinx, replacing the legacy SQL import method. - Updated `install.php` to run migrations instead of importing SQL dumps. - Added migration configuration file `phinx.php` and initial migration files for schema and data seeding. - Created a new admin panel for migration status management. - Updated UPGRADE_GUIDE.md to include migration setup instructions and benefits. - Ensured backward compatibility for existing installations while facilitating a smoother transition to the new system. * update runProcess to return process exit code * refactor(migrations): clean up whitespace and formatting in migration files - Removed unnecessary whitespace and adjusted formatting for consistency across migration files. * fix(migrations): enforce NOT NULL constraints on migration columns - Updated various migration columns to enforce NOT NULL constraints, ensuring data integrity across the schema. - Adjusted default values and nullability for multiple fields in the initial schema migration files. * refactor(database): standardize table engines to InnoDB for reliability - Updated UPGRADE_GUIDE.md to reflect the use of InnoDB for all tables, emphasizing data integrity and reliability. - Modified migration files to change table engines from MyISAM to InnoDB for various tracker and temporary tables. - Optimized session variable settings in cron jobs for InnoDB compatibility. - Ensured consistency across the schema by enforcing InnoDB usage in all relevant areas. * fix(migrations): correct MySQL integer field types to match original schema - Fix bb_forums table: forum_status (INT→TINYINT), forum_tpl_id (INT→SMALLINT) - Fix bb_users table: avatar_ext_id remains TINYINT as per original schema - Fix bb_groups table: avatar_ext_id (SMALLINT→INT) to match original INT(15) - Fix bb_topics table: topic_show_first_post, topic_allow_robots (TINYINT(1)→TINYINT UNSIGNED) - Remove incorrect 'limit' => 11 from standard INT fields, use default Phinx behavior - Fix search_size field to use proper INT type instead of maximum value hack - Correct poll table field types: vote_id (TINYINT), user_id (MEDIUMINT), vote_result (MEDIUMINT UNSIGNED) - Standardize all timestamp and ID fields to use appropriate MySQL integer types Ensures migration creates database schema identical to install/sql/mysql.sql while maintaining InnoDB engine for all tables instead of MyISAM. * fix(cache): auto-create cache directories when using FileStorage The UnifiedCacheSystem was constructing directory paths for Nette FileStorage but not creating them, causing "Directory not found" errors when accessing caches like 'bb_login_err'. FileStorage expects directories to already exist. Changes: - Add automatic directory creation using bb_mkdir() before FileStorage init - Handle both regular cache directories and SQLite parent directories - Apply to both _buildStorage() and _buildDatastoreStorage() methods - Add proper error handling with RuntimeException for failed creation - Maintain consistency with TorrentPier's directory creation patterns This ensures cache directories are created automatically when first accessed, eliminating the need for manual directory creation during deployment. Fixes: Cache initialization failures with missing directories * refactor(docs): update README for clarity and remove legacy SQL file - Improved formatting and clarity in the README, ensuring consistent line breaks and spacing. - Updated installation instructions to reflect the new migration process, emphasizing the use of `phinx` for database setup. - Removed the legacy SQL dump file `mysql.sql` and the `legacy-changes.txt` file, streamlining the installation process and reducing confusion for new users. - Enhanced the documentation to guide users through the setup process more effectively. * docs: enhance CLAUDE.md with migration details and directory updates - Updated the `/library/` section to clarify its purpose. - Added a new `/migrations/` directory section detailing database migration files managed by Phinx. - Included migration commands for running and checking migration status. - Revised the initial schema and seed data references for clarity. - Improved formatting for consistency throughout the document. * refactor(cron): remove demo_mode.php cron job and related functionality - Deleted the demo_mode.php cron job file, which was responsible for managing demo mode operations. - Added a migration to remove the demo_mode.php entry from the bb_cron table, ensuring a clean database state. - Updated the initial schema migration comment to reflect the creation of essential database schema for fresh installations. * refactor(docs): Fixed some typos * chore: update changelog generation starting from v2.4.6-alpha.4 * refactor: Changed some `php_sapi_name()` to `PHP_SAPI` constants * refactor: Extract hardcoded migrations to class property * refactor: Use `count()` to count $initialMigrations elements * feat(migrations): enhance migration management UI with new language variables - Added new language variables for migration status, instructions, and applied/pending migrations to improve user interface clarity. - Updated admin migration template to utilize these new language variables for better localization and maintainability. - Introduced a new file 'CLAUDE.md' to the cleanup process for documentation purposes. --------- Co-authored-by: Roman Kelesidis <roman25052006.kelesh@gmail.com>
This commit is contained in:
parent
0d4c869f30
commit
fbde8cd421
26 changed files with 4084 additions and 2942 deletions
2
.github/workflows/schedule.yml
vendored
2
.github/workflows/schedule.yml
vendored
|
@ -22,7 +22,7 @@ jobs:
|
|||
id: git-cliff
|
||||
with:
|
||||
config: cliff.toml
|
||||
args: v2.4.5-rc.2.. --verbose
|
||||
args: v2.4.6-alpha.4.. --verbose
|
||||
env:
|
||||
OUTPUT: CHANGELOG.md
|
||||
GITHUB_REPO: ${{ github.repository }}
|
||||
|
|
144
CLAUDE.md
Normal file
144
CLAUDE.md
Normal file
|
@ -0,0 +1,144 @@
|
|||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
TorrentPier is a BitTorrent tracker engine written in PHP, designed for hosting BitTorrent communities with forum functionality. The project is in active modernization, transitioning from legacy code to modern PHP practices while maintaining backward compatibility.
|
||||
|
||||
## Technology Stack & Architecture
|
||||
|
||||
- **PHP 8.1+** with modern features
|
||||
- **MySQL/MariaDB/Percona** database
|
||||
- **Nette Database** with backward-compatible wrapper
|
||||
- **Composer** for dependency management
|
||||
- **Custom BitTorrent tracker** implementation
|
||||
|
||||
## Key Directory Structure
|
||||
|
||||
- `/src/` - Modern PHP classes (PSR-4 autoloaded as `TorrentPier\`)
|
||||
- `/library/` - Core application logic and legacy code
|
||||
- `/admin/` - Administrative interface
|
||||
- `/bt/` - BitTorrent tracker functionality (announce.php, scrape.php)
|
||||
- `/styles/` - Templates, CSS, JS, images
|
||||
- `/internal_data/` - Cache, logs, compiled templates
|
||||
- `/install/` - Installation scripts and configuration examples
|
||||
- `/migrations/` - Database migration files (Phinx)
|
||||
|
||||
## Entry Points & Key Files
|
||||
|
||||
- `index.php` - Main forum homepage
|
||||
- `tracker.php` - Torrent search/browse interface
|
||||
- `bt/announce.php` - BitTorrent announce endpoint
|
||||
- `bt/scrape.php` - BitTorrent scrape endpoint
|
||||
- `admin/index.php` - Administrative panel
|
||||
- `cron.php` - Background task runner (CLI only)
|
||||
- `install.php` - Installation script (CLI only)
|
||||
|
||||
## Development Commands
|
||||
|
||||
### Installation & Setup
|
||||
```bash
|
||||
# Automated installation (CLI)
|
||||
php install.php
|
||||
|
||||
# Install dependencies
|
||||
composer install
|
||||
|
||||
# Update dependencies
|
||||
composer update
|
||||
```
|
||||
|
||||
### Maintenance & Operations
|
||||
```bash
|
||||
# Run background maintenance tasks
|
||||
php cron.php
|
||||
```
|
||||
|
||||
### Code Quality
|
||||
The project uses **StyleCI** with PSR-2 preset for code style enforcement. StyleCI configuration is in `.styleci.yml` targeting `src/` directory.
|
||||
|
||||
## Modern Architecture Components
|
||||
|
||||
### Database Layer (`/src/Database/`)
|
||||
- **Nette Database** with full old SqlDb backward compatibility
|
||||
- Singleton pattern accessible via `DB()` function
|
||||
- Support for multiple database connections and debug functionality
|
||||
- Migration path to ORM-style Explorer queries
|
||||
|
||||
### Cache System (`/src/Cache/`)
|
||||
- **Unified caching** using Nette Caching internally
|
||||
- 100% backward compatibility with existing `CACHE()` and $datastore calls
|
||||
- Supports file, SQLite, memory, and Memcached storage
|
||||
- Advanced features: memoization, cache dependencies
|
||||
|
||||
### Configuration Management
|
||||
- Environment-based config with `.env` files
|
||||
- Singleton `Config` class accessible via `config()` function
|
||||
- Local overrides supported via `library/config.local.php`
|
||||
|
||||
## Configuration Files
|
||||
- `.env` - Environment variables (copy from `.env.example`)
|
||||
- `library/config.php` - Main application configuration
|
||||
- `library/config.local.php` - Local configuration overrides
|
||||
- `composer.json` - Dependencies and PSR-4 autoloading
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### CI/CD Pipeline
|
||||
- **GitHub Actions** for automated testing and deployment
|
||||
- **StyleCI** for code style enforcement
|
||||
- **Dependabot** for dependency updates
|
||||
- **FTP deployment** to demo environment
|
||||
|
||||
### Installation Methods
|
||||
1. **Automated**: `php install.php` (recommended)
|
||||
2. **Composer**: `composer create-project torrentpier/torrentpier`
|
||||
3. **Manual**: Git clone + `composer install` + database setup
|
||||
|
||||
## Database & Schema
|
||||
|
||||
- **Database migrations** managed via Phinx in `/migrations/` directory
|
||||
- Initial schema: `20250619000001_initial_schema.php`
|
||||
- Initial seed data: `20250619000002_seed_initial_data.php`
|
||||
- UTF-8 (utf8mb4) character set required
|
||||
- Multiple database alias support for different components
|
||||
|
||||
### Migration Commands
|
||||
```bash
|
||||
# Run all pending migrations
|
||||
php vendor/bin/phinx migrate --configuration=phinx.php
|
||||
|
||||
# Check migration status
|
||||
php vendor/bin/phinx status --configuration=phinx.php
|
||||
|
||||
# Mark migrations as applied (for existing installations)
|
||||
php vendor/bin/phinx migrate --fake --configuration=phinx.php
|
||||
```
|
||||
|
||||
## Legacy Compatibility Strategy
|
||||
|
||||
The codebase maintains 100% backward compatibility while introducing modern alternatives:
|
||||
|
||||
- **Database layer**: Existing old SqlDb calls work while new code can use Nette Database
|
||||
- **Cache system**: All existing `CACHE()` and $datastore calls preserved while adding modern features
|
||||
- **Configuration**: Legacy config access maintained alongside new singleton pattern
|
||||
|
||||
This approach allows gradual modernization without breaking existing functionality - critical for a mature application with existing deployments.
|
||||
|
||||
## Security & Performance
|
||||
|
||||
- **Environment-based secrets** management via `.env`
|
||||
- **CDN/proxy support** (Cloudflare, Fastly)
|
||||
- **Input sanitization** and CSRF protection
|
||||
- **Advanced caching** with multiple storage backends
|
||||
- **Rate limiting** and IP-based restrictions
|
||||
|
||||
## BitTorrent Tracker Features
|
||||
|
||||
- **BitTorrent v1 & v2** support
|
||||
- **TorrServer integration** capability
|
||||
- **Client ban system** for problematic torrent clients
|
||||
- **Scrape support** for tracker statistics
|
||||
|
||||
When working with this codebase, prioritize understanding the legacy compatibility approach and modern architecture patterns. Always test both legacy and modern code paths when making changes to core systems.
|
1131
HISTORY.md
1131
HISTORY.md
File diff suppressed because it is too large
Load diff
34
README.md
34
README.md
|
@ -19,15 +19,15 @@
|
|||
|
||||
## 🐂 About TorrentPier
|
||||
|
||||
TorrentPier — bull-powered BitTorrent Public/Private tracker engine, written in PHP. High speed, simple modifications, load-balanced
|
||||
architecture. In addition, we have a very helpful
|
||||
TorrentPier — bull-powered BitTorrent Public/Private tracker engine, written in PHP. High speed, simple modifications, load-balanced
|
||||
architecture. In addition, we have a very helpful
|
||||
[official support forum](https://torrentpier.com), where it's possible to get support and download modifications for the engine.
|
||||
|
||||
## 🌈 Current status
|
||||
|
||||
TorrentPier is currently in active development. The goal is to remove all legacy code and rewrite the existing code to
|
||||
modern specifications. If you want delve deep into the code, check our [issues](https://github.com/torrentpier/torrentpier/issues)
|
||||
and go from there. The documentation will be translated to english in the near future, currently russian is the main language of it.
|
||||
TorrentPier is currently in active development. The goal is to remove all legacy code and rewrite the existing code to
|
||||
modern specifications. If you want to delve deep into the code, check our [issues](https://github.com/torrentpier/torrentpier/issues)
|
||||
and go from there. The documentation will be translated to English in the near future, currently Russian is the main language.
|
||||
|
||||
## ✨ Features
|
||||
* Rich forum with browsing/moderation tools
|
||||
|
@ -40,7 +40,7 @@ and go from there. The documentation will be translated to english in the near f
|
|||
* Bonus points
|
||||
* Polling system
|
||||
* PM/DM system
|
||||
* Multilingual support (Russian and English is currently fully supported, with others in the future)
|
||||
* Multilingual support (Russian and English are currently fully supported, with others in the future)
|
||||
* Atom/RSS feeds
|
||||
* ... and so MUCH MORE!
|
||||
|
||||
|
@ -56,7 +56,7 @@ and go from there. The documentation will be translated to english in the near f
|
|||
## 🔧 Requirements
|
||||
|
||||
* Apache / nginx ([example config](install/nginx.conf)) / caddy ([example config](install/Caddyfile))
|
||||
* MySQL 5.5.3 or above / MariaDB 10.0 or above / Percona
|
||||
* MySQL 5.5.3 or above (including MySQL 8.0+) / MariaDB 10.0 or above / Percona
|
||||
* PHP: 8.1 / 8.2 / 8.3 / 8.4
|
||||
* PHP Extensions: mbstring, gd, bcmath, intl, tidy (optional), xml, xmlwriter
|
||||
* Crontab (Recommended)
|
||||
|
@ -100,14 +100,20 @@ Check out our [autoinstall](https://github.com/torrentpier/autoinstall) reposito
|
|||
```shell
|
||||
composer install
|
||||
```
|
||||
5. Create a database and import the dump located at `install/sql/mysql.sql`
|
||||
6. Edit database configuration settings in the environment (`.env.example`), after, rename to `.env`
|
||||
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.
|
||||
|
||||
|
@ -124,13 +130,13 @@ If you discover a security vulnerability within TorrentPier, please follow our [
|
|||
|
||||
## 📌 Our recommendations
|
||||
|
||||
* *It's recommended to run `cron.php`.* - For significant tracker speed increase it ay be required to replace the built-in cron.php in operating system daemon.
|
||||
* *It's recommended to run `cron.php`.* - For significant tracker speed increase it may be required to replace the built-in cron.php with an operating system daemon.
|
||||
* *Local configuration copy.* - You can override the settings using the local configuration file `library/config.local.php`.
|
||||
|
||||
## 💚 Contributing / Contributors
|
||||
|
||||
Please read our [contributing policy](CONTRIBUTING.md) and [code of conduct](CODE_OF_CONDUCT.md) for details, and the process for
|
||||
submitting pull requests to us. But we are always ready to renew your pull-request for compliance with
|
||||
Please read our [contributing policy](CONTRIBUTING.md) and [code of conduct](CODE_OF_CONDUCT.md) for details, and the process for
|
||||
submitting pull requests to us. But we are always ready to review your pull-request for compliance with
|
||||
these requirements. Just send it!
|
||||
|
||||
<a href="https://github.com/torrentpier/torrentpier/graphs/contributors">
|
||||
|
@ -141,7 +147,7 @@ Made with [contrib.rocks](https://contrib.rocks).
|
|||
|
||||
## 💞 Sponsoring
|
||||
|
||||
Support this project by becoming a sponsor or a backer.
|
||||
Support this project by becoming a sponsor or a backer.
|
||||
|
||||
[](https://opencollective.com/torrentpier)
|
||||
[](https://opencollective.com/torrentpier)
|
||||
|
@ -164,7 +170,7 @@ Support this project by becoming a sponsor or a backer.
|
|||
|
||||
## 📦 Versioning
|
||||
|
||||
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/torrentpier/torrentpier/tags).
|
||||
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/torrentpier/torrentpier/tags).
|
||||
|
||||
## 📖 License
|
||||
|
||||
|
|
352
UPGRADE_GUIDE.md
352
UPGRADE_GUIDE.md
|
@ -4,6 +4,7 @@ This guide helps you upgrade your TorrentPier installation to the latest version
|
|||
|
||||
## 📖 Table of Contents
|
||||
|
||||
- [Database Migration System](#database-migration-system)
|
||||
- [Database Layer Migration](#database-layer-migration)
|
||||
- [Unified Cache System Migration](#unified-cache-system-migration)
|
||||
- [Configuration System Migration](#configuration-system-migration)
|
||||
|
@ -14,6 +15,357 @@ This guide helps you upgrade your TorrentPier installation to the latest version
|
|||
- [Breaking Changes](#breaking-changes)
|
||||
- [Best Practices](#best-practices)
|
||||
|
||||
## 🗄️ Database Migration System
|
||||
|
||||
TorrentPier now includes a modern database migration system using **Phinx** (from CakePHP), replacing the legacy direct SQL import approach. This provides version-controlled database schema management with rollback capabilities.
|
||||
|
||||
### Key Benefits
|
||||
|
||||
- **Version Control**: Database schema changes are tracked in code
|
||||
- **Environment Consistency**: Same database structure across development, staging, and production
|
||||
- **Safe Rollbacks**: Ability to safely revert schema changes
|
||||
- **Team Collaboration**: No more merge conflicts on database changes
|
||||
- **Automated Deployments**: Database updates as part of deployment process
|
||||
|
||||
### Migration Architecture
|
||||
|
||||
#### Engine Strategy
|
||||
- **InnoDB**: Used for all tables for maximum data integrity and reliability
|
||||
- **ACID Compliance**: Full transaction support and crash recovery for all data
|
||||
- **Row-Level Locking**: Better concurrency for high-traffic operations
|
||||
|
||||
#### Directory Structure
|
||||
```
|
||||
/migrations/
|
||||
├── 20250619000001_initial_schema.php # Complete database schema
|
||||
├── 20250619000002_seed_initial_data.php # Essential data seeding
|
||||
└── future_migrations... # Your custom migrations
|
||||
/phinx.php # Migration configuration
|
||||
```
|
||||
|
||||
### For New Installations
|
||||
|
||||
New installations automatically use migrations instead of the legacy SQL dump:
|
||||
|
||||
```bash
|
||||
# Fresh installation now uses migrations
|
||||
php install.php
|
||||
```
|
||||
|
||||
The installer will:
|
||||
1. Set up environment configuration
|
||||
2. Create the database
|
||||
3. Run all migrations automatically
|
||||
4. Seed initial data (admin user, configuration, etc.)
|
||||
|
||||
### For Existing Installations
|
||||
|
||||
Existing installations continue to work without changes. The migration system is designed for new installations and development workflows.
|
||||
|
||||
**Important**: Existing installations should **not** attempt to migrate to the new system without proper backup and testing procedures.
|
||||
|
||||
### Developer Workflow
|
||||
|
||||
#### Creating Migrations
|
||||
```bash
|
||||
# Create a new migration
|
||||
php vendor/bin/phinx create AddNewFeatureTable
|
||||
|
||||
# Edit the generated migration file
|
||||
# /migrations/YYYYMMDDHHMMSS_add_new_feature_table.php
|
||||
```
|
||||
|
||||
#### Running Migrations
|
||||
```bash
|
||||
# Run all pending migrations
|
||||
php vendor/bin/phinx migrate
|
||||
|
||||
# Check migration status
|
||||
php vendor/bin/phinx status
|
||||
|
||||
# Rollback last migration
|
||||
php vendor/bin/phinx rollback
|
||||
```
|
||||
|
||||
#### Migration Template
|
||||
```php
|
||||
<?php
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
class AddNewFeatureTable extends AbstractMigration
|
||||
{
|
||||
public function change()
|
||||
{
|
||||
// InnoDB for data integrity
|
||||
$table = $this->table('bb_new_feature', [
|
||||
'engine' => 'InnoDB',
|
||||
'collation' => 'utf8mb4_unicode_ci'
|
||||
]);
|
||||
|
||||
$table->addColumn('name', 'string', ['limit' => 100])
|
||||
->addColumn('created_at', 'timestamp', ['default' => 'CURRENT_TIMESTAMP'])
|
||||
->addIndex('name')
|
||||
->create();
|
||||
}
|
||||
|
||||
// Optional: explicit up/down methods for complex operations
|
||||
public function up()
|
||||
{
|
||||
// Complex data migration logic
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
// Rollback logic
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Engine Guidelines
|
||||
```php
|
||||
// Use InnoDB for all tables for maximum reliability
|
||||
$table = $this->table('bb_user_posts', [
|
||||
'engine' => 'InnoDB',
|
||||
'collation' => 'utf8mb4_unicode_ci'
|
||||
]);
|
||||
|
||||
// All tracker tables also use InnoDB for data integrity
|
||||
$table = $this->table('bb_bt_peer_stats', [
|
||||
'engine' => 'InnoDB',
|
||||
'collation' => 'utf8mb4_unicode_ci'
|
||||
]);
|
||||
|
||||
// Buffer tables use InnoDB for consistency and reliability
|
||||
public function up() {
|
||||
$this->execute('DROP TABLE IF EXISTS buf_temp_data');
|
||||
// Recreate with new structure using InnoDB
|
||||
}
|
||||
```
|
||||
|
||||
### Admin Panel Integration
|
||||
|
||||
The admin panel includes a read-only migration status page at `/admin/admin_migrations.php`:
|
||||
|
||||
- **Current migration version**
|
||||
- **Applied migrations history**
|
||||
- **Pending migrations list**
|
||||
- **Database statistics**
|
||||
- **Clear instructions for CLI operations**
|
||||
|
||||
**Important**: The admin panel is **read-only** for security. All migration operations must be performed via CLI.
|
||||
|
||||
### Complex Migration Handling
|
||||
|
||||
For complex data transformations, create external scripts:
|
||||
|
||||
```php
|
||||
// migrations/YYYYMMDDHHMMSS_complex_data_migration.php
|
||||
class ComplexDataMigration extends AbstractMigration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$this->output->writeln('Running complex data migration...');
|
||||
|
||||
// Call external script for complex operations
|
||||
$result = shell_exec('php ' . __DIR__ . '/../scripts/migrate_torrent_data.php');
|
||||
$this->output->writeln($result);
|
||||
|
||||
if (strpos($result, 'ERROR') !== false) {
|
||||
throw new Exception('Complex migration failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Best Practices
|
||||
|
||||
#### Migration Development
|
||||
```bash
|
||||
# 1. Create migration
|
||||
php vendor/bin/phinx create MyFeature
|
||||
|
||||
# 2. Edit migration file
|
||||
# 3. Test locally
|
||||
php vendor/bin/phinx migrate -e development
|
||||
|
||||
# 4. Test rollback
|
||||
php vendor/bin/phinx rollback -e development
|
||||
|
||||
# 5. Commit to version control
|
||||
git add migrations/
|
||||
git commit -m "Add MyFeature migration"
|
||||
```
|
||||
|
||||
#### Production Deployment
|
||||
```bash
|
||||
# Always backup database first
|
||||
mysqldump tracker_db > backup_$(date +%Y%m%d_%H%M%S).sql
|
||||
|
||||
# Run migrations
|
||||
php vendor/bin/phinx migrate -e production
|
||||
|
||||
# Verify application functionality
|
||||
# Monitor error logs
|
||||
```
|
||||
|
||||
#### Team Collaboration
|
||||
- **Never modify existing migrations** that have been deployed
|
||||
- **Always create new migrations** for schema changes
|
||||
- **Test migrations on production-like data** before deployment
|
||||
- **Coordinate with team** before major schema changes
|
||||
|
||||
### Configuration
|
||||
|
||||
The migration system uses your existing `.env` configuration:
|
||||
|
||||
```php
|
||||
// phinx.php automatically reads from .env
|
||||
'production' => [
|
||||
'adapter' => 'mysql',
|
||||
'host' => env('DB_HOST', 'localhost'),
|
||||
'port' => (int) env('DB_PORT', 3306),
|
||||
'name' => env('DB_DATABASE'),
|
||||
'user' => env('DB_USERNAME'),
|
||||
'pass' => env('DB_PASSWORD', ''),
|
||||
'charset' => 'utf8mb4',
|
||||
'collation' => 'utf8mb4_unicode_ci'
|
||||
]
|
||||
```
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
#### Common Issues
|
||||
```bash
|
||||
# Migration table doesn't exist
|
||||
php vendor/bin/phinx init # Re-run if needed
|
||||
|
||||
# Migration fails mid-way
|
||||
php vendor/bin/phinx rollback # Rollback to previous state
|
||||
|
||||
# Check what would be applied
|
||||
php vendor/bin/phinx status # See pending migrations
|
||||
```
|
||||
|
||||
#### Migration Recovery
|
||||
```bash
|
||||
# If migration fails, check status first
|
||||
php vendor/bin/phinx status
|
||||
|
||||
# Rollback to known good state
|
||||
php vendor/bin/phinx rollback -t 20250619000002
|
||||
|
||||
# Fix the migration code and re-run
|
||||
php vendor/bin/phinx migrate
|
||||
```
|
||||
|
||||
### Legacy SQL Import Removal
|
||||
|
||||
The legacy `install/sql/mysql.sql` approach has been replaced by migrations:
|
||||
|
||||
- ✅ **New installations**: Use migrations automatically
|
||||
- ✅ **Development workflow**: Create migrations for all schema changes
|
||||
- ✅ **Version control**: All schema changes tracked in Git
|
||||
- ❌ **Direct SQL imports**: No longer used for new installations
|
||||
|
||||
### Security Considerations
|
||||
|
||||
- **CLI-only execution**: Migrations run via command line only
|
||||
- **Read-only admin interface**: Web interface shows status only
|
||||
- **Backup requirements**: Always backup before production migrations
|
||||
- **Access control**: Restrict migration command access to authorized personnel
|
||||
|
||||
### Migration Setup for Existing Installations
|
||||
|
||||
If you have an **existing TorrentPier installation** and want to adopt the migration system, you need to mark the initial migrations as already applied to avoid recreating your existing database schema.
|
||||
|
||||
#### Detection: Do You Need This?
|
||||
|
||||
You need migration setup if:
|
||||
- ✅ You have an existing TorrentPier installation with data
|
||||
- ✅ Your database already has tables like `bb_users`, `bb_forums`, etc.
|
||||
- ✅ The admin migration panel shows "Migration System: ✗ Not Initialized"
|
||||
|
||||
#### Step-by-Step Setup Process
|
||||
|
||||
**1. Backup Your Database**
|
||||
```bash
|
||||
mysqldump -u username -p database_name > backup_$(date +%Y%m%d_%H%M%S).sql
|
||||
```
|
||||
|
||||
**2. Initialize Migration Table**
|
||||
```bash
|
||||
# This creates the bb_migrations table without running any migrations
|
||||
php vendor/bin/phinx init
|
||||
```
|
||||
|
||||
**3. Mark Initial Migrations as Applied (Fake Run)**
|
||||
```bash
|
||||
# Mark the schema migration as applied without running it
|
||||
php vendor/bin/phinx migrate --fake --target=20250619000001
|
||||
|
||||
# Mark the data seeding migration as applied without running it
|
||||
php vendor/bin/phinx migrate --fake --target=20250619000002
|
||||
```
|
||||
|
||||
**4. Verify Setup**
|
||||
```bash
|
||||
# Check migration status
|
||||
php vendor/bin/phinx status
|
||||
```
|
||||
|
||||
You should see both initial migrations marked as "up" (applied).
|
||||
|
||||
#### Alternative: Manual SQL Method
|
||||
|
||||
If you prefer manual control, you can directly insert migration records:
|
||||
|
||||
```sql
|
||||
-- Create migration table (if phinx init didn't work)
|
||||
CREATE TABLE IF NOT EXISTS bb_migrations (
|
||||
version bigint(20) NOT NULL,
|
||||
migration_name varchar(100) DEFAULT NULL,
|
||||
start_time timestamp NULL DEFAULT NULL,
|
||||
end_time timestamp NULL DEFAULT NULL,
|
||||
breakpoint tinyint(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (version)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Mark initial migrations as applied
|
||||
INSERT INTO bb_migrations (version, migration_name, start_time, end_time, breakpoint)
|
||||
VALUES
|
||||
('20250619000001', 'InitialSchema', NOW(), NOW(), 0),
|
||||
('20250619000002', 'SeedInitialData', NOW(), NOW(), 0);
|
||||
```
|
||||
|
||||
#### Post-Setup Workflow
|
||||
|
||||
After setup, your existing installation will work exactly like a fresh installation:
|
||||
|
||||
```bash
|
||||
# Create new migrations
|
||||
php vendor/bin/phinx create AddNewFeature
|
||||
|
||||
# Run new migrations
|
||||
php vendor/bin/phinx migrate
|
||||
|
||||
# Check status
|
||||
php vendor/bin/phinx status
|
||||
```
|
||||
|
||||
#### Troubleshooting
|
||||
|
||||
**Migration table already exists:**
|
||||
- Check if you've already set up migrations: `php vendor/bin/phinx status`
|
||||
- If it shows errors, you may need to recreate: `DROP TABLE bb_migrations;` then restart
|
||||
|
||||
**"Nothing to migrate" message:**
|
||||
- This is normal after fake runs - it means setup was successful
|
||||
- New migrations will appear when you create them
|
||||
|
||||
**Admin panel shows "Needs Setup":**
|
||||
- Follow the setup process above
|
||||
- Refresh the admin panel after completion
|
||||
|
||||
## 🗄️ Database Layer Migration
|
||||
|
||||
TorrentPier has completely replaced its legacy database layer (SqlDb/Dbs) with a modern implementation using Nette Database while maintaining 100% backward compatibility.
|
||||
|
|
|
@ -13,7 +13,7 @@ if (!defined('BB_ROOT')) {
|
|||
}
|
||||
|
||||
// Check CLI mode
|
||||
if (php_sapi_name() !== 'cli') {
|
||||
if (PHP_SAPI != 'cli') {
|
||||
exit;
|
||||
}
|
||||
|
||||
|
@ -34,12 +34,14 @@ $items = [
|
|||
'_release.php',
|
||||
'CHANGELOG.md',
|
||||
'cliff.toml',
|
||||
'CLAUDE.md',
|
||||
'CODE_OF_CONDUCT.md',
|
||||
'CONTRIBUTING.md',
|
||||
'crowdin.yml',
|
||||
'HISTORY.md',
|
||||
'README.md',
|
||||
'SECURITY.md'
|
||||
'SECURITY.md',
|
||||
'UPGRADE_GUIDE.md'
|
||||
];
|
||||
|
||||
foreach ($items as $item) {
|
||||
|
|
|
@ -11,7 +11,7 @@ define('BB_ROOT', __DIR__ . DIRECTORY_SEPARATOR);
|
|||
define('BB_PATH', BB_ROOT);
|
||||
|
||||
// Check CLI mode
|
||||
if (php_sapi_name() !== 'cli') {
|
||||
if (PHP_SAPI != 'cli') {
|
||||
die('Please run <code style="background:#222;color:#00e01f;padding:2px 6px;border-radius:3px;">php ' . basename(__FILE__) . '</code> in CLI mode');
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ if ($bytesWritten === 0) {
|
|||
out("\n- Config file has been updated!", 'success');
|
||||
|
||||
// Update CHANGELOG.md
|
||||
runProcess('npx git-cliff v2.4.5-rc.2.. --config cliff.toml --tag "' . $version . '" > 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) : '') . '"');
|
||||
|
|
79
admin/admin_migrations.php
Normal file
79
admin/admin_migrations.php
Normal file
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
/**
|
||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||
*
|
||||
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||
*/
|
||||
|
||||
if (!empty($setmodules)) {
|
||||
if (IS_SUPER_ADMIN) {
|
||||
$module['GENERAL']['MIGRATIONS_STATUS'] = basename(__FILE__);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
require __DIR__ . '/pagestart.php';
|
||||
|
||||
if (!IS_SUPER_ADMIN) {
|
||||
bb_die(__('ONLY_FOR_SUPER_ADMIN'));
|
||||
}
|
||||
|
||||
use TorrentPier\Database\MigrationStatus;
|
||||
|
||||
// Initialize migration status
|
||||
$migrationStatus = new MigrationStatus();
|
||||
$status = $migrationStatus->getMigrationStatus();
|
||||
$schemaInfo = $migrationStatus->getSchemaInfo();
|
||||
|
||||
// Template variables
|
||||
$template->assign_vars([
|
||||
'PAGE_TITLE' => __('MIGRATIONS_STATUS'),
|
||||
'CURRENT_TIME' => date('Y-m-d H:i:s'),
|
||||
|
||||
// Migration status individual fields
|
||||
'MIGRATION_TABLE_EXISTS' => $status['table_exists'],
|
||||
'MIGRATION_CURRENT_VERSION' => $status['current_version'],
|
||||
'MIGRATION_APPLIED_COUNT' => count($status['applied_migrations']),
|
||||
'MIGRATION_PENDING_COUNT' => count($status['pending_migrations']),
|
||||
|
||||
// Setup status fields
|
||||
'SETUP_REQUIRES_SETUP' => $status['requires_setup'] ?? false,
|
||||
'SETUP_TYPE' => $status['setup_status']['type'] ?? __('UNKNOWN'),
|
||||
'SETUP_MESSAGE' => $status['setup_status']['message'] ?? '',
|
||||
'SETUP_ACTION_REQUIRED' => $status['setup_status']['action_required'] ?? false,
|
||||
'SETUP_INSTRUCTIONS' => $status['setup_status']['instructions'] ?? '',
|
||||
|
||||
// Schema info individual fields
|
||||
'SCHEMA_DATABASE_NAME' => $schemaInfo['database_name'],
|
||||
'SCHEMA_TABLE_COUNT' => $schemaInfo['table_count'],
|
||||
'SCHEMA_SIZE_MB' => $schemaInfo['size_mb'],
|
||||
]);
|
||||
|
||||
// Assign migration data for template
|
||||
if (!empty($status['applied_migrations'])) {
|
||||
foreach ($status['applied_migrations'] as $i => $migration) {
|
||||
$template->assign_block_vars('applied_migrations', [
|
||||
'VERSION' => $migration['version'],
|
||||
'NAME' => $migration['migration_name'] ?? __('UNKNOWN'),
|
||||
'START_TIME' => $migration['start_time'] ?? __('UNKNOWN'),
|
||||
'END_TIME' => $migration['end_time'] ?? __('UNKNOWN'),
|
||||
'ROW_CLASS' => ($i % 2) ? 'row1' : 'row2'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($status['pending_migrations'])) {
|
||||
foreach ($status['pending_migrations'] as $i => $migration) {
|
||||
$template->assign_block_vars('pending_migrations', [
|
||||
'VERSION' => $migration['version'],
|
||||
'NAME' => $migration['name'],
|
||||
'FILENAME' => $migration['filename'],
|
||||
'ROW_CLASS' => ($i % 2) ? 'row1' : 'row2'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Output template using standard admin pattern
|
||||
print_page('admin_migrations.tpl', 'admin');
|
|
@ -68,6 +68,7 @@
|
|||
"nette/caching": "^3.3",
|
||||
"nette/database": "^3.2",
|
||||
"php-curl-class/php-curl-class": "^12.0.0",
|
||||
"robmorgan/phinx": "^0.16.9",
|
||||
"samdark/sitemap": "2.4.1",
|
||||
"symfony/event-dispatcher": "^6.4",
|
||||
"symfony/filesystem": "^6.4",
|
||||
|
|
799
composer.lock
generated
799
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "61d990417a4943d9986cef7fc3c0f382",
|
||||
"content-hash": "1c6ed0e1507a53ce5784c929c38e84cf",
|
||||
"packages": [
|
||||
{
|
||||
"name": "arokettu/bencode",
|
||||
|
@ -544,6 +544,330 @@
|
|||
},
|
||||
"time": "2025-03-06T12:03:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "cakephp/chronos",
|
||||
"version": "3.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cakephp/chronos.git",
|
||||
"reference": "786d69e1ee4b735765cbdb5521b9603e9b98d650"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/cakephp/chronos/zipball/786d69e1ee4b735765cbdb5521b9603e9b98d650",
|
||||
"reference": "786d69e1ee4b735765cbdb5521b9603e9b98d650",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"psr/clock": "^1.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/clock-implementation": "1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"cakephp/cakephp-codesniffer": "^5.0",
|
||||
"phpunit/phpunit": "^10.1.0 || ^11.1.3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Cake\\Chronos\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Brian Nesbitt",
|
||||
"email": "brian@nesbot.com",
|
||||
"homepage": "http://nesbot.com"
|
||||
},
|
||||
{
|
||||
"name": "The CakePHP Team",
|
||||
"homepage": "https://cakephp.org"
|
||||
}
|
||||
],
|
||||
"description": "A simple API extension for DateTime.",
|
||||
"homepage": "https://cakephp.org",
|
||||
"keywords": [
|
||||
"date",
|
||||
"datetime",
|
||||
"time"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/cakephp/chronos/issues",
|
||||
"source": "https://github.com/cakephp/chronos"
|
||||
},
|
||||
"time": "2024-07-18T03:18:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "cakephp/core",
|
||||
"version": "5.2.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cakephp/core.git",
|
||||
"reference": "a0a92ee7fbb7b7555dbf4ea7ff3fd4e779693da6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/cakephp/core/zipball/a0a92ee7fbb7b7555dbf4ea7ff3fd4e779693da6",
|
||||
"reference": "a0a92ee7fbb7b7555dbf4ea7ff3fd4e779693da6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"cakephp/utility": "5.2.*@dev",
|
||||
"league/container": "^4.2",
|
||||
"php": ">=8.1",
|
||||
"psr/container": "^1.1 || ^2.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/container-implementation": "^2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"cakephp/cache": "To use Configure::store() and restore().",
|
||||
"cakephp/event": "To use PluginApplicationInterface or plugin applications.",
|
||||
"league/container": "To use Container and ServiceProvider classes"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-5.x": "5.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Cake\\Core\\": "."
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "CakePHP Community",
|
||||
"homepage": "https://github.com/cakephp/core/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "CakePHP Framework Core classes",
|
||||
"homepage": "https://cakephp.org",
|
||||
"keywords": [
|
||||
"cakephp",
|
||||
"core",
|
||||
"framework"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://stackoverflow.com/tags/cakephp",
|
||||
"irc": "irc://irc.freenode.org/cakephp",
|
||||
"issues": "https://github.com/cakephp/cakephp/issues",
|
||||
"source": "https://github.com/cakephp/core"
|
||||
},
|
||||
"time": "2025-04-19T12:34:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "cakephp/database",
|
||||
"version": "5.2.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cakephp/database.git",
|
||||
"reference": "8c4eaecf6612274b445172b680dc47a2dad681a9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/cakephp/database/zipball/8c4eaecf6612274b445172b680dc47a2dad681a9",
|
||||
"reference": "8c4eaecf6612274b445172b680dc47a2dad681a9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"cakephp/chronos": "^3.1",
|
||||
"cakephp/core": "5.2.*@dev",
|
||||
"cakephp/datasource": "5.2.*@dev",
|
||||
"php": ">=8.1",
|
||||
"psr/log": "^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"cakephp/i18n": "5.2.*@dev",
|
||||
"cakephp/log": "5.2.*@dev"
|
||||
},
|
||||
"suggest": {
|
||||
"cakephp/i18n": "If you are using locale-aware datetime formats.",
|
||||
"cakephp/log": "If you want to use query logging without providing a logger yourself."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-5.x": "5.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Cake\\Database\\": "."
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "CakePHP Community",
|
||||
"homepage": "https://github.com/cakephp/database/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Flexible and powerful Database abstraction library with a familiar PDO-like API",
|
||||
"homepage": "https://cakephp.org",
|
||||
"keywords": [
|
||||
"abstraction",
|
||||
"cakephp",
|
||||
"database",
|
||||
"database abstraction",
|
||||
"pdo"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://stackoverflow.com/tags/cakephp",
|
||||
"irc": "irc://irc.freenode.org/cakephp",
|
||||
"issues": "https://github.com/cakephp/cakephp/issues",
|
||||
"source": "https://github.com/cakephp/database"
|
||||
},
|
||||
"time": "2025-05-09T15:08:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "cakephp/datasource",
|
||||
"version": "5.2.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cakephp/datasource.git",
|
||||
"reference": "f7dc4292bec0ec746db3200a5b18bb371d50dab3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/cakephp/datasource/zipball/f7dc4292bec0ec746db3200a5b18bb371d50dab3",
|
||||
"reference": "f7dc4292bec0ec746db3200a5b18bb371d50dab3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"cakephp/core": "5.2.*@dev",
|
||||
"php": ">=8.1",
|
||||
"psr/simple-cache": "^2.0 || ^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"cakephp/cache": "5.2.*@dev",
|
||||
"cakephp/collection": "5.2.*@dev",
|
||||
"cakephp/utility": "5.2.*@dev"
|
||||
},
|
||||
"suggest": {
|
||||
"cakephp/cache": "If you decide to use Query caching.",
|
||||
"cakephp/collection": "If you decide to use ResultSetInterface.",
|
||||
"cakephp/utility": "If you decide to use EntityTrait."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-5.x": "5.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Cake\\Datasource\\": "."
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "CakePHP Community",
|
||||
"homepage": "https://github.com/cakephp/datasource/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Provides connection managing and traits for Entities and Queries that can be reused for different datastores",
|
||||
"homepage": "https://cakephp.org",
|
||||
"keywords": [
|
||||
"cakephp",
|
||||
"connection management",
|
||||
"datasource",
|
||||
"entity",
|
||||
"query"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://stackoverflow.com/tags/cakephp",
|
||||
"irc": "irc://irc.freenode.org/cakephp",
|
||||
"issues": "https://github.com/cakephp/cakephp/issues",
|
||||
"source": "https://github.com/cakephp/datasource"
|
||||
},
|
||||
"time": "2025-04-26T23:00:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "cakephp/utility",
|
||||
"version": "5.2.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cakephp/utility.git",
|
||||
"reference": "76dcd5c20e46aaf5bfdf9ad51e9f5313abffe104"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/cakephp/utility/zipball/76dcd5c20e46aaf5bfdf9ad51e9f5313abffe104",
|
||||
"reference": "76dcd5c20e46aaf5bfdf9ad51e9f5313abffe104",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"cakephp/core": "5.2.*@dev",
|
||||
"php": ">=8.1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "To use Text::transliterate() or Text::slug()",
|
||||
"lib-ICU": "To use Text::transliterate() or Text::slug()"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-5.x": "5.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Cake\\Utility\\": "."
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "CakePHP Community",
|
||||
"homepage": "https://github.com/cakephp/utility/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "CakePHP Utility classes such as Inflector, String, Hash, and Security",
|
||||
"homepage": "https://cakephp.org",
|
||||
"keywords": [
|
||||
"cakephp",
|
||||
"hash",
|
||||
"inflector",
|
||||
"security",
|
||||
"string",
|
||||
"utility"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://stackoverflow.com/tags/cakephp",
|
||||
"irc": "irc://irc.freenode.org/cakephp",
|
||||
"issues": "https://github.com/cakephp/cakephp/issues",
|
||||
"source": "https://github.com/cakephp/utility"
|
||||
},
|
||||
"time": "2025-04-19T12:34:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "claviska/simpleimage",
|
||||
"version": "4.2.1",
|
||||
|
@ -1618,6 +1942,88 @@
|
|||
},
|
||||
"time": "2022-09-24T15:57:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/container",
|
||||
"version": "4.2.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/container.git",
|
||||
"reference": "d3cebb0ff4685ff61c749e54b27db49319e2ec00"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/container/zipball/d3cebb0ff4685ff61c749e54b27db49319e2ec00",
|
||||
"reference": "d3cebb0ff4685ff61c749e54b27db49319e2ec00",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"psr/container": "^1.1 || ^2.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/container-implementation": "^1.0"
|
||||
},
|
||||
"replace": {
|
||||
"orno/di": "~2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"nette/php-generator": "^3.4",
|
||||
"nikic/php-parser": "^4.10",
|
||||
"phpstan/phpstan": "^0.12.47",
|
||||
"phpunit/phpunit": "^8.5.17",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"scrutinizer/ocular": "^1.8",
|
||||
"squizlabs/php_codesniffer": "^3.6"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-1.x": "1.x-dev",
|
||||
"dev-2.x": "2.x-dev",
|
||||
"dev-3.x": "3.x-dev",
|
||||
"dev-4.x": "4.x-dev",
|
||||
"dev-master": "4.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Container\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Phil Bennett",
|
||||
"email": "mail@philbennett.co.uk",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "A fast and intuitive dependency injection container.",
|
||||
"homepage": "https://github.com/thephpleague/container",
|
||||
"keywords": [
|
||||
"container",
|
||||
"dependency",
|
||||
"di",
|
||||
"injection",
|
||||
"league",
|
||||
"provider",
|
||||
"service"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/container/issues",
|
||||
"source": "https://github.com/thephpleague/container/tree/4.2.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/philipobenito",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-05-20T12:55:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
"version": "3.29.1",
|
||||
|
@ -2559,6 +2965,54 @@
|
|||
},
|
||||
"time": "2021-02-03T23:26:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/clock",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/clock.git",
|
||||
"reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d",
|
||||
"reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.0 || ^8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Clock\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for reading the clock.",
|
||||
"homepage": "https://github.com/php-fig/clock",
|
||||
"keywords": [
|
||||
"clock",
|
||||
"now",
|
||||
"psr",
|
||||
"psr-20",
|
||||
"time"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-fig/clock/issues",
|
||||
"source": "https://github.com/php-fig/clock/tree/1.0.0"
|
||||
},
|
||||
"time": "2022-11-25T14:36:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
"version": "2.0.2",
|
||||
|
@ -2967,6 +3421,93 @@
|
|||
},
|
||||
"time": "2019-03-08T08:55:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "robmorgan/phinx",
|
||||
"version": "0.16.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cakephp/phinx.git",
|
||||
"reference": "524ebdeb0e1838a845d752a3418726b38cd1e654"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/cakephp/phinx/zipball/524ebdeb0e1838a845d752a3418726b38cd1e654",
|
||||
"reference": "524ebdeb0e1838a845d752a3418726b38cd1e654",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"cakephp/database": "^5.0.2",
|
||||
"composer-runtime-api": "^2.0",
|
||||
"php-64bit": ">=8.1",
|
||||
"psr/container": "^1.1|^2.0",
|
||||
"symfony/config": "^4.0|^5.0|^6.0|^7.0",
|
||||
"symfony/console": "^6.0|^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"cakephp/cakephp-codesniffer": "^5.0",
|
||||
"cakephp/i18n": "^5.0",
|
||||
"ext-json": "*",
|
||||
"ext-pdo": "*",
|
||||
"phpunit/phpunit": "^9.5.19",
|
||||
"symfony/yaml": "^4.0|^5.0|^6.0|^7.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-json": "Install if using JSON configuration format",
|
||||
"ext-pdo": "PDO extension is needed",
|
||||
"symfony/yaml": "Install if using YAML configuration format"
|
||||
},
|
||||
"bin": [
|
||||
"bin/phinx"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Phinx\\": "src/Phinx/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Rob Morgan",
|
||||
"email": "robbym@gmail.com",
|
||||
"homepage": "https://robmorgan.id.au",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Woody Gilk",
|
||||
"email": "woody.gilk@gmail.com",
|
||||
"homepage": "https://shadowhand.me",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Richard Quadling",
|
||||
"email": "rquadling@gmail.com",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "CakePHP Community",
|
||||
"homepage": "https://github.com/cakephp/phinx/graphs/contributors",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Phinx makes it ridiculously easy to manage the database migrations for your PHP app.",
|
||||
"homepage": "https://phinx.org",
|
||||
"keywords": [
|
||||
"database",
|
||||
"database migrations",
|
||||
"db",
|
||||
"migrations",
|
||||
"phinx"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/cakephp/phinx/issues",
|
||||
"source": "https://github.com/cakephp/phinx/tree/0.16.9"
|
||||
},
|
||||
"time": "2025-05-25T16:07:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "samdark/sitemap",
|
||||
"version": "2.4.1",
|
||||
|
@ -3026,6 +3567,175 @@
|
|||
],
|
||||
"time": "2023-11-01T08:41:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/config",
|
||||
"version": "v7.0.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/config.git",
|
||||
"reference": "f8a8fb0c2d0a188a00a2dd5af8a4eb070641ec60"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/config/zipball/f8a8fb0c2d0a188a00a2dd5af8a4eb070641ec60",
|
||||
"reference": "f8a8fb0c2d0a188a00a2dd5af8a4eb070641ec60",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/filesystem": "^6.4|^7.0",
|
||||
"symfony/polyfill-ctype": "~1.8"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/finder": "<6.4",
|
||||
"symfony/service-contracts": "<2.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/event-dispatcher": "^6.4|^7.0",
|
||||
"symfony/finder": "^6.4|^7.0",
|
||||
"symfony/messenger": "^6.4|^7.0",
|
||||
"symfony/service-contracts": "^2.5|^3",
|
||||
"symfony/yaml": "^6.4|^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Config\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/config/tree/v7.0.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-05-31T14:55:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v7.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "66c1440edf6f339fd82ed6c7caa76cb006211b44"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/66c1440edf6f339fd82ed6c7caa76cb006211b44",
|
||||
"reference": "66c1440edf6f339fd82ed6c7caa76cb006211b44",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/polyfill-mbstring": "~1.0",
|
||||
"symfony/service-contracts": "^2.5|^3",
|
||||
"symfony/string": "^7.2"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/dependency-injection": "<6.4",
|
||||
"symfony/dotenv": "<6.4",
|
||||
"symfony/event-dispatcher": "<6.4",
|
||||
"symfony/lock": "<6.4",
|
||||
"symfony/process": "<6.4"
|
||||
},
|
||||
"provide": {
|
||||
"psr/log-implementation": "1.0|2.0|3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/log": "^1|^2|^3",
|
||||
"symfony/config": "^6.4|^7.0",
|
||||
"symfony/dependency-injection": "^6.4|^7.0",
|
||||
"symfony/event-dispatcher": "^6.4|^7.0",
|
||||
"symfony/http-foundation": "^6.4|^7.0",
|
||||
"symfony/http-kernel": "^6.4|^7.0",
|
||||
"symfony/lock": "^6.4|^7.0",
|
||||
"symfony/messenger": "^6.4|^7.0",
|
||||
"symfony/process": "^6.4|^7.0",
|
||||
"symfony/stopwatch": "^6.4|^7.0",
|
||||
"symfony/var-dumper": "^6.4|^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Console\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Eases the creation of beautiful and testable command line interfaces",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"cli",
|
||||
"command-line",
|
||||
"console",
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v7.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-05-24T10:34:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
"version": "v3.6.0",
|
||||
|
@ -3744,6 +4454,93 @@
|
|||
],
|
||||
"time": "2025-04-25T09:37:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v7.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/f3570b8c61ca887a9e2938e85cb6458515d2b125",
|
||||
"reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/polyfill-ctype": "~1.8",
|
||||
"symfony/polyfill-intl-grapheme": "~1.0",
|
||||
"symfony/polyfill-intl-normalizer": "~1.0",
|
||||
"symfony/polyfill-mbstring": "~1.0"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/translation-contracts": "<2.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/emoji": "^7.1",
|
||||
"symfony/error-handler": "^6.4|^7.0",
|
||||
"symfony/http-client": "^6.4|^7.0",
|
||||
"symfony/intl": "^6.4|^7.0",
|
||||
"symfony/translation-contracts": "^2.5|^3.0",
|
||||
"symfony/var-exporter": "^6.4|^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"Resources/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\String\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"grapheme",
|
||||
"i18n",
|
||||
"string",
|
||||
"unicode",
|
||||
"utf-8",
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v7.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-20T20:19:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "vlucas/phpdotenv",
|
||||
"version": "v5.6.2",
|
||||
|
|
45
install.php
45
install.php
|
@ -11,7 +11,7 @@ define('BB_ROOT', __DIR__ . DIRECTORY_SEPARATOR);
|
|||
define('BB_PATH', BB_ROOT);
|
||||
|
||||
// Check CLI mode
|
||||
if (php_sapi_name() !== 'cli') {
|
||||
if (PHP_SAPI != 'cli') {
|
||||
die('Please run <code style="background:#222;color:#00e01f;padding:2px 6px;border-radius:3px;">php ' . basename(__FILE__) . '</code> in CLI mode');
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ require INC_DIR . '/functions_cli.php';
|
|||
/**
|
||||
* System requirements
|
||||
*/
|
||||
define('CHECK_REQUIREMENTS', [
|
||||
const CHECK_REQUIREMENTS = [
|
||||
'php_min_version' => '8.1.0',
|
||||
'ext_list' => [
|
||||
'json',
|
||||
|
@ -39,7 +39,7 @@ define('CHECK_REQUIREMENTS', [
|
|||
'zip',
|
||||
'gd'
|
||||
],
|
||||
]);
|
||||
];
|
||||
|
||||
// Welcoming message
|
||||
out("--- TorrentPier Installer ---\n", 'info');
|
||||
|
@ -265,35 +265,26 @@ if (!empty($DB_HOST) && !empty($DB_DATABASE) && !empty($DB_USERNAME)) {
|
|||
}
|
||||
$conn->select_db($DB_DATABASE);
|
||||
|
||||
// Checking SQL dump
|
||||
$dumpPath = BB_ROOT . 'install/sql/mysql.sql';
|
||||
if (is_file($dumpPath) && is_readable($dumpPath)) {
|
||||
out('- SQL dump file found and readable!', 'success');
|
||||
} else {
|
||||
out('- SQL dump file not found / not readable', 'error');
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Inserting SQL dump
|
||||
out('- Start importing SQL dump...', 'info');
|
||||
$tempLine = '';
|
||||
foreach (file($dumpPath) as $line) {
|
||||
if (str_starts_with($line, '--') || $line == '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tempLine .= $line;
|
||||
if (str_ends_with(trim($line), ';')) {
|
||||
if (!$conn->query($tempLine)) {
|
||||
out("- Error performing query: $tempLine", 'error');
|
||||
exit;
|
||||
}
|
||||
$tempLine = '';
|
||||
}
|
||||
// Run migrations
|
||||
$migrationResult = runProcess('php vendor/bin/phinx migrate --configuration=' . BB_ROOT . 'phinx.php');
|
||||
if ($migrationResult !== 0) {
|
||||
out('- Database migration failed', 'error');
|
||||
exit;
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
out("- Importing SQL dump completed!\n", 'success');
|
||||
out("- Database setup completed!\n", 'success');
|
||||
|
||||
// Autofill host in robots.txt
|
||||
$robots_txt_file = BB_ROOT . 'robots.txt';
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,157 +0,0 @@
|
|||
// Changes from v2.2.0 to 2.4.5
|
||||
|
||||
// 2.2.0
|
||||
UPDATE `bb_config` SET `config_value` = 'http://whatismyipaddress.com/ip/' WHERE `config_name` = 'whois_info';
|
||||
DELETE FROM `bb_smilies` WHERE `code` = ':ad:';
|
||||
INSERT INTO `bb_smilies` (`code`, `smile_url`, `emoticon`) VALUES (':сd:', 'сd.gif', 'сd');
|
||||
DROP TABLE IF EXISTS `bb_ads`;
|
||||
DELETE FROM `bb_config` WHERE `config_name` = 'active_ads';
|
||||
ALTER TABLE `bb_log` DROP COLUMN `log_username`;
|
||||
DELETE FROM `bb_config` WHERE `config_name` = 'new_tpls';
|
||||
UPDATE `bb_posts` SET `poster_ip` = '0';
|
||||
ALTER TABLE `bb_posts` CHANGE `poster_ip` `poster_ip` varchar(42) NOT NULL DEFAULT '0';
|
||||
UPDATE `bb_bt_tracker` SET `ip` = '0';
|
||||
ALTER TABLE `bb_bt_tracker` CHANGE `ip` `ip` varchar(42) NOT NULL DEFAULT '0';
|
||||
UPDATE `bb_users` SET `user_last_ip` = '0';
|
||||
ALTER TABLE `bb_users` CHANGE `user_last_ip` `user_last_ip` varchar(42) NOT NULL DEFAULT '0';
|
||||
UPDATE `bb_users` SET `user_reg_ip` = '0';
|
||||
ALTER TABLE `bb_users` CHANGE `user_reg_ip` `user_reg_ip` varchar(42) NOT NULL DEFAULT '0';
|
||||
UPDATE `bb_log` SET `log_user_ip` = '0';
|
||||
ALTER TABLE `bb_log` CHANGE `log_user_ip` `log_user_ip` varchar(42) NOT NULL DEFAULT '0';
|
||||
UPDATE `bb_poll_users` SET `vote_ip` = '0';
|
||||
ALTER TABLE `bb_poll_users` CHANGE `vote_ip` `vote_ip` varchar(42) NOT NULL DEFAULT '0';
|
||||
UPDATE `bb_privmsgs` SET `privmsgs_ip` = '0';
|
||||
ALTER TABLE `bb_privmsgs` CHANGE `privmsgs_ip` `privmsgs_ip` varchar(42) NOT NULL DEFAULT '0';
|
||||
UPDATE `bb_sessions` SET `session_ip` = '0';
|
||||
ALTER TABLE `bb_sessions` CHANGE `session_ip` `session_ip` varchar(42) NOT NULL DEFAULT '0';
|
||||
UPDATE `bb_banlist` SET `ban_ip` = '0';
|
||||
ALTER TABLE `bb_banlist` CHANGE `ban_ip` `ban_ip` varchar(42) NOT NULL DEFAULT '0';
|
||||
|
||||
// 2.2.2
|
||||
ALTER TABLE `bb_ranks` DROP `rank_min`;
|
||||
ALTER TABLE `bb_ranks` DROP `rank_special`;
|
||||
|
||||
// 2.3.0
|
||||
ALTER TABLE `bb_cron` CHANGE `last_run` `last_run` DATETIME NOT NULL DEFAULT '1900-01-01 00:00:00';
|
||||
ALTER TABLE `bb_cron` CHANGE `next_run` `next_run` DATETIME NOT NULL DEFAULT '1900-01-01 00:00:00';
|
||||
ALTER TABLE `bb_users` CHANGE `user_birthday` `user_birthday` DATE NOT NULL DEFAULT '1900-01-01';
|
||||
ALTER TABLE `bb_posts` CHANGE `mc_comment` `mc_comment` TEXT NOT NULL DEFAULT '';
|
||||
|
||||
// 2.3.0.2
|
||||
ALTER TABLE `bb_users` CHANGE `user_sig` `user_sig` TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE `bb_groups` CHANGE `group_signature` `group_signature` TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE `bb_groups` CHANGE `group_description` `group_description` TEXT NOT NULL DEFAULT '';
|
||||
UPDATE `bb_smilies` SET `code` = ':cd:', `smile_url` = 'cd.gif', `emoticon` = 'cd' WHERE `code` = ':сd:' AND `smile_url` = 'сd.gif' AND `emoticon` = 'сd';
|
||||
|
||||
// 2.3.1
|
||||
ALTER TABLE `bb_search_results` CHANGE `search_id` `search_id` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
|
||||
ALTER TABLE `bb_users` CHANGE `autologin_id` `autologin_id` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
|
||||
DELETE FROM `bb_config` WHERE `config_name` = 'cron_enabled';
|
||||
|
||||
// 2.4.0-alpha1
|
||||
ALTER TABLE `bb_search_results` CHANGE `session_id` `session_id` CHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
|
||||
ALTER TABLE `bb_sessions` CHANGE `session_id` `session_id` CHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
|
||||
ALTER TABLE `bb_users` CHANGE `username` `username` VARCHAR(255) NOT NULL DEFAULT '';
|
||||
ALTER TABLE `bb_users` CHANGE `user_password` `user_password` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
|
||||
ALTER TABLE `bb_users` CHANGE `user_actkey` `user_actkey` VARCHAR(255) NOT NULL DEFAULT '';
|
||||
ALTER TABLE `bb_users` CHANGE `user_newpasswd` `user_newpasswd` VARCHAR(255) NOT NULL DEFAULT '';
|
||||
|
||||
// 2.4.0-alpha3
|
||||
INSERT INTO bb_config VALUES ('show_board_start_index', '1');
|
||||
|
||||
// 2.4.0-beta2
|
||||
INSERT INTO `bb_cron` (`cron_active`, `cron_title`, `cron_script`, `schedule`, `run_day`, `run_time`, `run_order`,
|
||||
`last_run`, `next_run`, `run_interval`, `log_enabled`, `log_file`, `log_sql_queries`,
|
||||
`disable_board`, `run_counter`) VALUES ('1', 'PM cleanup', 'clean_pm.php', 'daily', '', '05:00:00', '70', '', '', '', '1', '', '0', '1', '0');
|
||||
ALTER TABLE `bb_posts_text` CHANGE `post_text` `post_text` MEDIUMTEXT NOT NULL;
|
||||
ALTER TABLE `bb_privmsgs_text` CHANGE `privmsgs_text` `privmsgs_text` MEDIUMTEXT NOT NULL;
|
||||
ALTER TABLE `bb_bt_torrents` ADD COLUMN `info_hash_v2` VARBINARY(32) NOT NULL DEFAULT '';
|
||||
ALTER TABLE `bb_bt_tracker_snap` ADD COLUMN `completed` INT(10) NOT NULL DEFAULT '0';
|
||||
ALTER TABLE `bb_bt_tracker` CHANGE `complete` `complete` TINYINT(1) NOT NULL DEFAULT '0';
|
||||
|
||||
// 2.4.0-beta3
|
||||
INSERT INTO `bb_extensions` (`group_id`, `extension`, `comment`) VALUES ('1', 'webp', '');
|
||||
INSERT INTO `bb_extensions` (`group_id`, `extension`, `comment`) VALUES ('2', '7z', '');
|
||||
INSERT INTO `bb_extensions` (`group_id`, `extension`, `comment`) VALUES ('1', 'bmp', '');
|
||||
ALTER TABLE `bb_bt_tracker` CHANGE `speed_up` `speed_up` INT(11) UNSIGNED NOT NULL DEFAULT '0';
|
||||
ALTER TABLE `bb_bt_tracker` CHANGE `speed_down` `speed_down` INT(11) UNSIGNED NOT NULL DEFAULT '0';
|
||||
ALTER TABLE `bb_bt_tracker_snap` CHANGE `speed_up` `speed_up` INT(11) UNSIGNED NOT NULL DEFAULT '0';
|
||||
ALTER TABLE `bb_bt_tracker_snap` CHANGE `speed_down` `speed_down` INT(11) UNSIGNED NOT NULL DEFAULT '0';
|
||||
ALTER TABLE `bb_bt_torrents` ADD COLUMN `last_seeder_id` MEDIUMINT(8) NOT NULL DEFAULT '0';
|
||||
ALTER TABLE `buf_last_seeder` ADD COLUMN `user_id` MEDIUMINT(8) NOT NULL DEFAULT '0';
|
||||
ALTER TABLE `bb_bt_tracker` CHANGE `ip` `ip` VARCHAR(42) DEFAULT NULL;
|
||||
ALTER TABLE `bb_bt_tracker` CHANGE `ipv6` `ipv6` VARCHAR(42) DEFAULT NULL;
|
||||
ALTER TABLE `bb_bt_users` CHANGE `auth_key` `auth_key` CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
|
||||
|
||||
// 2.4.0-beta4
|
||||
DELETE FROM `bb_extensions` WHERE `extension` = 'tif';
|
||||
INSERT INTO `bb_extensions` (`group_id`, `extension`, `comment`) VALUES ('4', 'tif', '');
|
||||
INSERT INTO `bb_extensions` (`group_id`, `extension`, `comment`) VALUES ('4', 'tiff', '');
|
||||
DELETE FROM `bb_extensions` WHERE `extension` = 'tga';
|
||||
INSERT INTO `bb_extensions` (`group_id`, `extension`, `comment`) VALUES ('4', 'tga', '');
|
||||
|
||||
// 2.4.0-rc1
|
||||
ALTER TABLE `bb_bt_tracker` DROP COLUMN `client`;
|
||||
DROP TABLE IF EXISTS `bb_thx`;
|
||||
CREATE TABLE IF NOT EXISTS `bb_thx`
|
||||
(
|
||||
`topic_id` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`user_id` MEDIUMINT(8) NOT NULL DEFAULT '0',
|
||||
`time` INT(11) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`topic_id`, `user_id`)
|
||||
)
|
||||
ENGINE = MyISAM
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
// 2.4.0
|
||||
UPDATE `bb_attachments_config` SET `config_value` = 'data/uploads' WHERE `config_name` = 'upload_dir';
|
||||
UPDATE `bb_attachments_config` SET `config_value` = '12000' WHERE `config_name` = 'img_min_thumb_filesize';
|
||||
DELETE FROM `bb_attachments_config` WHERE config_name = 'attach_version';
|
||||
DELETE FROM `bb_attachments_config` WHERE config_name = 'img_min_thumb_filesize';
|
||||
DELETE FROM `bb_attachments_config` WHERE config_name = 'img_imagick';
|
||||
DELETE FROM `bb_attachments_config` WHERE config_name = 'use_gd2';
|
||||
DELETE FROM `bb_attachments_config` WHERE config_name = 'wma_autoplay';
|
||||
DELETE FROM `bb_attachments_config` WHERE config_name = 'flash_autoplay';
|
||||
DELETE FROM `bb_extensions` WHERE extension = 'tif';
|
||||
DELETE FROM `bb_extensions` WHERE extension = 'tiff';
|
||||
DELETE FROM `bb_extensions` WHERE extension = 'tga';
|
||||
DROP TABLE IF EXISTS `bb_banlist`;
|
||||
CREATE TABLE IF NOT EXISTS `bb_banlist`
|
||||
(
|
||||
`ban_id` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`ban_userid` MEDIUMINT(8) NOT NULL DEFAULT '0',
|
||||
`ban_reason` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (`ban_id`, `ban_userid`)
|
||||
)
|
||||
ENGINE = MyISAM
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
// 2.4.1
|
||||
UPDATE `bb_config` SET `config_value` = '' WHERE `config_name` = 'bt_announce_url';
|
||||
|
||||
// 2.4.2
|
||||
INSERT INTO `bb_cron` (`cron_active`, `cron_title`, `cron_script`, `schedule`, `run_day`, `run_time`, `run_order`,
|
||||
`last_run`, `next_run`, `run_interval`, `log_enabled`, `log_file`, `log_sql_queries`,
|
||||
`disable_board`, `run_counter`) VALUES ('1', 'Demo mode', 'demo_mode.php', 'daily', '', '05:00:00', '255', '', '', '', '1', 'demo_mode_cron', '1', '1', '0');
|
||||
|
||||
// 2.4.3
|
||||
UPDATE `bb_config` SET `config_value` = 'https://localhost/bt/announce.php' WHERE `config_name` = 'bt_announce_url';
|
||||
|
||||
// 2.4.4
|
||||
ALTER TABLE `bb_poll_users` CHANGE `user_id` `user_id` MEDIUMINT(8) NOT NULL;
|
||||
ALTER TABLE `bb_bt_users` ADD COLUMN `ratio_nulled` TINYINT(1) NOT NULL DEFAULT '0';
|
||||
DELETE FROM `bb_cron` WHERE `cron_script` = 'cache_gc.php';
|
||||
UPDATE `bb_cron` SET `run_interval` = '00:10:00' WHERE `cron_script` = 'tr_seed_bonus.php';
|
||||
|
||||
// 2.4.5-rc.1
|
||||
INSERT INTO `bb_extensions` (`group_id`, `extension`, `comment`) VALUES ('1', 'avif', ''), ('3', 'm3u', '');
|
||||
ALTER TABLE `bb_topics` ADD COLUMN `topic_allow_robots` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0';
|
||||
|
||||
// 2.4.5-rc.2
|
||||
INSERT INTO `bb_config` VALUES ('magnet_links_for_guests', '0');
|
||||
INSERT INTO `bb_config` VALUES ('tp_instance_hash', '');
|
||||
|
||||
// 2.4.5-rc.5
|
||||
DELETE FROM `bb_config` WHERE `config_name` = 'tp_instance_hash';
|
|
@ -83,6 +83,9 @@ define('CRON_RUNNING', TRIGGERS_DIR . '/cron_running');
|
|||
define('GZIP_OUTPUT_ALLOWED', extension_loaded('zlib') && !ini_get('zlib.output_compression'));
|
||||
define('UA_GZIP_SUPPORTED', isset($_SERVER['HTTP_ACCEPT_ENCODING']) && str_contains($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip'));
|
||||
|
||||
// Migrations table
|
||||
define('BB_MIGRATIONS', 'bb_migrations');
|
||||
|
||||
// Tracker shared constants
|
||||
define('BB_BT_TORRENTS', 'bb_bt_torrents');
|
||||
define('BB_BT_TRACKER', 'bb_bt_tracker');
|
||||
|
|
|
@ -13,11 +13,10 @@ if (!defined('BB_ROOT')) {
|
|||
|
||||
define('IN_CRON', true);
|
||||
|
||||
// Set SESSION vars
|
||||
// Set SESSION vars (optimized for InnoDB)
|
||||
DB()->query("
|
||||
SET SESSION
|
||||
myisam_sort_buffer_size = 16*1024*1024
|
||||
, bulk_insert_buffer_size = 8*1024*1024
|
||||
bulk_insert_buffer_size = 8*1024*1024
|
||||
, join_buffer_size = 4*1024*1024
|
||||
, read_buffer_size = 4*1024*1024
|
||||
, read_rnd_buffer_size = 8*1024*1024
|
||||
|
@ -29,8 +28,7 @@ DB()->query("
|
|||
// Restore vars at shutdown
|
||||
DB()->add_shutdown_query("
|
||||
SET SESSION
|
||||
myisam_sort_buffer_size = DEFAULT
|
||||
, bulk_insert_buffer_size = DEFAULT
|
||||
bulk_insert_buffer_size = DEFAULT
|
||||
, join_buffer_size = DEFAULT
|
||||
, read_buffer_size = DEFAULT
|
||||
, read_rnd_buffer_size = DEFAULT
|
||||
|
|
|
@ -28,7 +28,7 @@ DB()->query("
|
|||
CREATE TEMPORARY TABLE $tmp_attach_tbl (
|
||||
physical_filename VARCHAR(255) NOT NULL default '',
|
||||
KEY physical_filename (physical_filename(20))
|
||||
) ENGINE = MyISAM DEFAULT CHARSET = utf8
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
|
||||
");
|
||||
DB()->add_shutdown_query("DROP TEMPORARY TABLE IF EXISTS $tmp_attach_tbl");
|
||||
|
||||
|
|
|
@ -1,44 +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')) {
|
||||
die(basename(__FILE__));
|
||||
}
|
||||
|
||||
set_time_limit(600);
|
||||
|
||||
global $cron_runtime_log;
|
||||
|
||||
$dump_path = BB_ROOT . 'install/sql/mysql.sql';
|
||||
|
||||
if (!IN_DEMO_MODE || !is_file($dump_path) || !is_readable($dump_path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clean cache & datastore
|
||||
$datastore->clean();
|
||||
foreach (config()->get('cache.engines') as $cache_name => $cache_val) {
|
||||
CACHE($cache_name)->rm();
|
||||
}
|
||||
|
||||
// Drop tables & Insert sql dump
|
||||
$temp_line = '';
|
||||
foreach (file($dump_path) as $line) {
|
||||
if (str_starts_with($line, '--') || $line == '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$temp_line .= $line;
|
||||
if (str_ends_with(trim($line), ';')) {
|
||||
if (!DB()->query($temp_line)) {
|
||||
$cron_runtime_log[] = date('Y-m-d H:i:s') . " -- Error performing query: " . $temp_line . " | " . DB()->sql_error()['message'];
|
||||
}
|
||||
$temp_line = '';
|
||||
}
|
||||
}
|
|
@ -86,9 +86,9 @@ function out(string $str, string $type = ''): void
|
|||
*
|
||||
* @param string $cmd
|
||||
* @param string|null $input
|
||||
* @return void
|
||||
* @return int
|
||||
*/
|
||||
function runProcess(string $cmd, ?string $input = null): void
|
||||
function runProcess(string $cmd, ?string $input = null): int
|
||||
{
|
||||
$descriptorSpec = [
|
||||
0 => ['pipe', 'r'],
|
||||
|
@ -100,7 +100,7 @@ function runProcess(string $cmd, ?string $input = null): void
|
|||
|
||||
if (!is_resource($process)) {
|
||||
out('- Could not start subprocess', 'error');
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Write input if provided
|
||||
|
@ -124,7 +124,7 @@ function runProcess(string $cmd, ?string $input = null): void
|
|||
fclose($pipes[1]);
|
||||
fclose($pipes[2]);
|
||||
|
||||
proc_close($process);
|
||||
return proc_close($process);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1946,6 +1946,31 @@ $lang['TRACKER_CONFIG'] = 'Tracker settings';
|
|||
$lang['RELEASE_TEMPLATES'] = 'Release Templates';
|
||||
$lang['ACTIONS_LOG'] = 'Report on action';
|
||||
|
||||
// Migrations
|
||||
$lang['MIGRATIONS_STATUS'] = 'Database Migration Status';
|
||||
$lang['MIGRATIONS_DATABASE_NAME'] = 'Database Name';
|
||||
$lang['MIGRATIONS_DATABASE_TOTAL'] = 'Total Tables';
|
||||
$lang['MIGRATIONS_DATABASE_SIZE'] = 'Database Size';
|
||||
$lang['MIGRATIONS_DATABASE_INFO'] = 'Database Information';
|
||||
$lang['MIGRATIONS_SYSTEM'] = 'Migration System';
|
||||
$lang['MIGRATIONS_NEEDS_SETUP'] = 'Needs Setup';
|
||||
$lang['MIGRATIONS_ACTIVE'] = 'Active';
|
||||
$lang['MIGRATIONS_NOT_INITIALIZED'] = 'Not Initialized';
|
||||
$lang['MIGRATIONS_UP_TO_DATE'] = 'All up to date';
|
||||
$lang['MIGRATIONS_PENDING_COUNT'] = 'pending';
|
||||
$lang['MIGRATIONS_APPLIED'] = 'Applied Migrations';
|
||||
$lang['MIGRATIONS_PENDING'] = 'Pending Migrations';
|
||||
$lang['MIGRATIONS_VERSION'] = 'Version';
|
||||
$lang['MIGRATIONS_NAME'] = 'Migration Name';
|
||||
$lang['MIGRATIONS_APPLIED_AT'] = 'Applied At';
|
||||
$lang['MIGRATIONS_COMPLETED_AT'] = 'Completed At';
|
||||
$lang['MIGRATIONS_CURRENT_VERSION'] = 'Current Version';
|
||||
$lang['MIGRATIONS_NOT_APPLIED'] = 'No migrations applied';
|
||||
$lang['MIGRATIONS_INSTRUCTIONS'] = 'Instructions';
|
||||
$lang['MIGRATIONS_SETUP_STATUS'] = 'Setup Status';
|
||||
$lang['MIGRATIONS_SETUP_GUIDE'] = 'See setup guide below';
|
||||
$lang['MIGRATIONS_ACTION_REQUIRED'] = 'Action Required';
|
||||
|
||||
// Index
|
||||
$lang['MAIN_INDEX'] = 'Forum Index';
|
||||
$lang['FORUM_STATS'] = 'Forum Statistics';
|
||||
|
|
1017
migrations/20250619000001_initial_schema.php
Normal file
1017
migrations/20250619000001_initial_schema.php
Normal file
File diff suppressed because it is too large
Load diff
968
migrations/20250619000002_seed_initial_data.php
Normal file
968
migrations/20250619000002_seed_initial_data.php
Normal file
|
@ -0,0 +1,968 @@
|
|||
<?php
|
||||
/**
|
||||
* TorrentPier Initial Data Seeding Migration
|
||||
* Seeds essential data for fresh installations
|
||||
*/
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
class SeedInitialData extends AbstractMigration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
// Seed all essential data
|
||||
$this->seedCategories();
|
||||
$this->seedForums();
|
||||
$this->seedUsers();
|
||||
$this->seedBtUsers();
|
||||
$this->seedConfiguration();
|
||||
$this->seedCronJobs();
|
||||
$this->seedExtensions();
|
||||
$this->seedSmilies();
|
||||
$this->seedRanks();
|
||||
$this->seedQuotaLimits();
|
||||
$this->seedDisallowedUsernames();
|
||||
$this->seedAttachmentConfig();
|
||||
$this->seedTopicsAndPosts();
|
||||
$this->seedTopicWatch();
|
||||
}
|
||||
|
||||
private function seedCategories()
|
||||
{
|
||||
$this->table('bb_categories')->insert([
|
||||
[
|
||||
'cat_id' => 1,
|
||||
'cat_title' => 'Your first category',
|
||||
'cat_order' => 10
|
||||
]
|
||||
])->saveData();
|
||||
}
|
||||
|
||||
private function seedForums()
|
||||
{
|
||||
$this->table('bb_forums')->insert([
|
||||
[
|
||||
'forum_id' => 1,
|
||||
'cat_id' => 1,
|
||||
'forum_name' => 'Your first forum',
|
||||
'forum_desc' => 'Description of the forum.',
|
||||
'forum_status' => 0,
|
||||
'forum_order' => 10,
|
||||
'forum_posts' => 1,
|
||||
'forum_topics' => 1,
|
||||
'forum_last_post_id' => 1,
|
||||
'forum_tpl_id' => 0,
|
||||
'prune_days' => 0,
|
||||
'auth_view' => 0,
|
||||
'auth_read' => 0,
|
||||
'auth_post' => 1,
|
||||
'auth_reply' => 1,
|
||||
'auth_edit' => 1,
|
||||
'auth_delete' => 1,
|
||||
'auth_sticky' => 3,
|
||||
'auth_announce' => 3,
|
||||
'auth_vote' => 1,
|
||||
'auth_pollcreate' => 1,
|
||||
'auth_attachments' => 1,
|
||||
'auth_download' => 1,
|
||||
'allow_reg_tracker' => 0,
|
||||
'allow_porno_topic' => 0,
|
||||
'self_moderated' => 0,
|
||||
'forum_parent' => 0,
|
||||
'show_on_index' => 1,
|
||||
'forum_display_sort' => 0,
|
||||
'forum_display_order' => 0
|
||||
]
|
||||
])->saveData();
|
||||
}
|
||||
|
||||
private function seedUsers()
|
||||
{
|
||||
$this->table('bb_users')->insert([
|
||||
[
|
||||
'user_id' => -1,
|
||||
'user_active' => 0,
|
||||
'username' => 'Guest',
|
||||
'user_password' => '$2y$10$sfZSmqPio8mxxFQLRRXaFuVMkFKZARRz/RzqddfYByN3M53.CEe.O',
|
||||
'user_session_time' => 0,
|
||||
'user_lastvisit' => 0,
|
||||
'user_last_ip' => '0',
|
||||
'user_regdate' => time(),
|
||||
'user_reg_ip' => '0',
|
||||
'user_level' => 0,
|
||||
'user_posts' => 0,
|
||||
'user_timezone' => 0.00,
|
||||
'user_lang' => 'en',
|
||||
'user_new_privmsg' => 0,
|
||||
'user_unread_privmsg' => 0,
|
||||
'user_last_privmsg' => 0,
|
||||
'user_opt' => 0,
|
||||
'user_rank' => 0,
|
||||
'avatar_ext_id' => 0,
|
||||
'user_gender' => 0,
|
||||
'user_birthday' => '1900-01-01',
|
||||
'user_email' => '',
|
||||
'user_skype' => '',
|
||||
'user_twitter' => '',
|
||||
'user_icq' => '',
|
||||
'user_website' => '',
|
||||
'user_from' => '',
|
||||
'user_sig' => '',
|
||||
'user_occ' => '',
|
||||
'user_interests' => '',
|
||||
'user_actkey' => '',
|
||||
'user_newpasswd' => '',
|
||||
'autologin_id' => '',
|
||||
'user_newest_pm_id' => 0,
|
||||
'user_points' => 0.00,
|
||||
'tpl_name' => 'default'
|
||||
],
|
||||
[
|
||||
'user_id' => -746,
|
||||
'user_active' => 0,
|
||||
'username' => 'bot',
|
||||
'user_password' => '$2y$10$sfZSmqPio8mxxFQLRRXaFuVMkFKZARRz/RzqddfYByN3M53.CEe.O',
|
||||
'user_session_time' => 0,
|
||||
'user_lastvisit' => 0,
|
||||
'user_last_ip' => '0',
|
||||
'user_regdate' => time(),
|
||||
'user_reg_ip' => '0',
|
||||
'user_level' => 0,
|
||||
'user_posts' => 0,
|
||||
'user_timezone' => 0.00,
|
||||
'user_lang' => 'en',
|
||||
'user_new_privmsg' => 0,
|
||||
'user_unread_privmsg' => 0,
|
||||
'user_last_privmsg' => 0,
|
||||
'user_opt' => 144,
|
||||
'user_rank' => 0,
|
||||
'avatar_ext_id' => 0,
|
||||
'user_gender' => 0,
|
||||
'user_birthday' => '1900-01-01',
|
||||
'user_email' => 'bot@torrentpier.com',
|
||||
'user_skype' => '',
|
||||
'user_twitter' => '',
|
||||
'user_icq' => '',
|
||||
'user_website' => '',
|
||||
'user_from' => '',
|
||||
'user_sig' => '',
|
||||
'user_occ' => '',
|
||||
'user_interests' => '',
|
||||
'user_actkey' => '',
|
||||
'user_newpasswd' => '',
|
||||
'autologin_id' => '',
|
||||
'user_newest_pm_id' => 0,
|
||||
'user_points' => 0.00,
|
||||
'tpl_name' => 'default'
|
||||
],
|
||||
[
|
||||
'user_id' => 2,
|
||||
'user_active' => 1,
|
||||
'username' => 'admin',
|
||||
'user_password' => '$2y$10$QeekUGqdfMO0yp7AT7la8OhgbiNBoJ627BO38MdS1h5kY7oX6UUKu',
|
||||
'user_session_time' => 0,
|
||||
'user_lastvisit' => 0,
|
||||
'user_last_ip' => '0',
|
||||
'user_regdate' => time(),
|
||||
'user_reg_ip' => '0',
|
||||
'user_level' => 1,
|
||||
'user_posts' => 1,
|
||||
'user_timezone' => 0.00,
|
||||
'user_lang' => 'en',
|
||||
'user_new_privmsg' => 0,
|
||||
'user_unread_privmsg' => 0,
|
||||
'user_last_privmsg' => 0,
|
||||
'user_opt' => 304,
|
||||
'user_rank' => 1,
|
||||
'avatar_ext_id' => 0,
|
||||
'user_gender' => 0,
|
||||
'user_birthday' => '1900-01-01',
|
||||
'user_email' => 'admin@torrentpier.com',
|
||||
'user_skype' => '',
|
||||
'user_twitter' => '',
|
||||
'user_icq' => '',
|
||||
'user_website' => '',
|
||||
'user_from' => '',
|
||||
'user_sig' => '',
|
||||
'user_occ' => '',
|
||||
'user_interests' => '',
|
||||
'user_actkey' => '',
|
||||
'user_newpasswd' => '',
|
||||
'autologin_id' => '',
|
||||
'user_newest_pm_id' => 0,
|
||||
'user_points' => 0.00,
|
||||
'tpl_name' => 'default'
|
||||
]
|
||||
])->saveData();
|
||||
}
|
||||
|
||||
private function seedBtUsers()
|
||||
{
|
||||
$this->table('bb_bt_users')->insert([
|
||||
[
|
||||
'user_id' => -1,
|
||||
'auth_key' => substr(md5(rand()), 0, 20)
|
||||
],
|
||||
[
|
||||
'user_id' => -746,
|
||||
'auth_key' => substr(md5(rand()), 0, 20)
|
||||
],
|
||||
[
|
||||
'user_id' => 2,
|
||||
'auth_key' => substr(md5(rand()), 0, 20)
|
||||
]
|
||||
])->saveData();
|
||||
}
|
||||
|
||||
private function seedConfiguration()
|
||||
{
|
||||
$currentTime = time();
|
||||
|
||||
$configs = [
|
||||
['config_name' => 'allow_autologin', 'config_value' => '1'],
|
||||
['config_name' => 'allow_bbcode', 'config_value' => '1'],
|
||||
['config_name' => 'allow_namechange', 'config_value' => '0'],
|
||||
['config_name' => 'allow_sig', 'config_value' => '1'],
|
||||
['config_name' => 'allow_smilies', 'config_value' => '1'],
|
||||
['config_name' => 'board_disable', 'config_value' => '0'],
|
||||
['config_name' => 'board_startdate', 'config_value' => (string)$currentTime],
|
||||
['config_name' => 'board_timezone', 'config_value' => '0'],
|
||||
['config_name' => 'bonus_upload', 'config_value' => ''],
|
||||
['config_name' => 'bonus_upload_price', 'config_value' => ''],
|
||||
['config_name' => 'birthday_enabled', 'config_value' => '1'],
|
||||
['config_name' => 'birthday_max_age', 'config_value' => '99'],
|
||||
['config_name' => 'birthday_min_age', 'config_value' => '10'],
|
||||
['config_name' => 'birthday_check_day', 'config_value' => '7'],
|
||||
['config_name' => 'bt_add_auth_key', 'config_value' => '1'],
|
||||
['config_name' => 'bt_allow_spmode_change', 'config_value' => '1'],
|
||||
['config_name' => 'bt_announce_url', 'config_value' => 'https://localhost/bt/announce.php'],
|
||||
['config_name' => 'bt_disable_dht', 'config_value' => '0'],
|
||||
['config_name' => 'bt_check_announce_url', 'config_value' => '0'],
|
||||
['config_name' => 'bt_del_addit_ann_urls', 'config_value' => '1'],
|
||||
['config_name' => 'bt_dl_list_only_1st_page', 'config_value' => '1'],
|
||||
['config_name' => 'bt_dl_list_only_count', 'config_value' => '1'],
|
||||
['config_name' => 'bt_newtopic_auto_reg', 'config_value' => '1'],
|
||||
['config_name' => 'bt_replace_ann_url', 'config_value' => '1'],
|
||||
['config_name' => 'bt_search_bool_mode', 'config_value' => '1'],
|
||||
['config_name' => 'bt_set_dltype_on_tor_reg', 'config_value' => '1'],
|
||||
['config_name' => 'bt_show_dl_but_cancel', 'config_value' => '1'],
|
||||
['config_name' => 'bt_show_dl_but_compl', 'config_value' => '1'],
|
||||
['config_name' => 'bt_show_dl_but_down', 'config_value' => '0'],
|
||||
['config_name' => 'bt_show_dl_but_will', 'config_value' => '1'],
|
||||
['config_name' => 'bt_show_dl_list', 'config_value' => '0'],
|
||||
['config_name' => 'bt_show_dl_list_buttons', 'config_value' => '1'],
|
||||
['config_name' => 'bt_show_dl_stat_on_index', 'config_value' => '1'],
|
||||
['config_name' => 'bt_show_ip_only_moder', 'config_value' => '1'],
|
||||
['config_name' => 'bt_show_peers', 'config_value' => '1'],
|
||||
['config_name' => 'bt_show_peers_mode', 'config_value' => '1'],
|
||||
['config_name' => 'bt_show_port_only_moder', 'config_value' => '1'],
|
||||
['config_name' => 'bt_tor_browse_only_reg', 'config_value' => '0'],
|
||||
['config_name' => 'bt_unset_dltype_on_tor_unreg', 'config_value' => '1'],
|
||||
['config_name' => 'cron_last_check', 'config_value' => '0'],
|
||||
['config_name' => 'default_dateformat', 'config_value' => 'Y-m-d H:i'],
|
||||
['config_name' => 'default_lang', 'config_value' => 'en'],
|
||||
['config_name' => 'flood_interval', 'config_value' => '15'],
|
||||
['config_name' => 'hot_threshold', 'config_value' => '300'],
|
||||
['config_name' => 'login_reset_time', 'config_value' => '30'],
|
||||
['config_name' => 'max_autologin_time', 'config_value' => '10'],
|
||||
['config_name' => 'max_login_attempts', 'config_value' => '5'],
|
||||
['config_name' => 'max_poll_options', 'config_value' => '6'],
|
||||
['config_name' => 'max_sig_chars', 'config_value' => '255'],
|
||||
['config_name' => 'posts_per_page', 'config_value' => '15'],
|
||||
['config_name' => 'prune_enable', 'config_value' => '1'],
|
||||
['config_name' => 'record_online_date', 'config_value' => (string)$currentTime],
|
||||
['config_name' => 'record_online_users', 'config_value' => '0'],
|
||||
['config_name' => 'seed_bonus_enabled', 'config_value' => '1'],
|
||||
['config_name' => 'seed_bonus_release', 'config_value' => ''],
|
||||
['config_name' => 'seed_bonus_points', 'config_value' => ''],
|
||||
['config_name' => 'seed_bonus_tor_size', 'config_value' => '0'],
|
||||
['config_name' => 'seed_bonus_user_regdate', 'config_value' => '0'],
|
||||
['config_name' => 'site_desc', 'config_value' => 'Bull-powered BitTorrent tracker engine'],
|
||||
['config_name' => 'sitemap_time', 'config_value' => ''],
|
||||
['config_name' => 'sitename', 'config_value' => 'TorrentPier'],
|
||||
['config_name' => 'smilies_path', 'config_value' => 'styles/images/smiles'],
|
||||
['config_name' => 'static_sitemap', 'config_value' => ''],
|
||||
['config_name' => 'topics_per_page', 'config_value' => '50'],
|
||||
['config_name' => 'xs_use_cache', 'config_value' => '1'],
|
||||
['config_name' => 'cron_check_interval', 'config_value' => '180'],
|
||||
['config_name' => 'magnet_links_enabled', 'config_value' => '1'],
|
||||
['config_name' => 'magnet_links_for_guests', 'config_value' => '0'],
|
||||
['config_name' => 'gender', 'config_value' => '1'],
|
||||
['config_name' => 'callseed', 'config_value' => '0'],
|
||||
['config_name' => 'tor_stats', 'config_value' => '1'],
|
||||
['config_name' => 'show_latest_news', 'config_value' => '1'],
|
||||
['config_name' => 'max_news_title', 'config_value' => '50'],
|
||||
['config_name' => 'latest_news_count', 'config_value' => '5'],
|
||||
['config_name' => 'latest_news_forum_id', 'config_value' => '1'],
|
||||
['config_name' => 'show_network_news', 'config_value' => '1'],
|
||||
['config_name' => 'max_net_title', 'config_value' => '50'],
|
||||
['config_name' => 'network_news_count', 'config_value' => '5'],
|
||||
['config_name' => 'network_news_forum_id', 'config_value' => '2'],
|
||||
['config_name' => 'whois_info', 'config_value' => 'https://whatismyipaddress.com/ip/'],
|
||||
['config_name' => 'show_mod_index', 'config_value' => '0'],
|
||||
['config_name' => 'premod', 'config_value' => '0'],
|
||||
['config_name' => 'tor_comment', 'config_value' => '1'],
|
||||
['config_name' => 'terms', 'config_value' => ''],
|
||||
['config_name' => 'show_board_start_index', 'config_value' => '1']
|
||||
];
|
||||
|
||||
$this->table('bb_config')->insert($configs)->saveData();
|
||||
}
|
||||
|
||||
private function seedCronJobs()
|
||||
{
|
||||
$cronJobs = [
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Attach maintenance',
|
||||
'cron_script' => 'attach_maintenance.php',
|
||||
'schedule' => 'daily',
|
||||
'run_day' => null,
|
||||
'run_time' => '05:00:00',
|
||||
'run_order' => 40,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => null,
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 1,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Board maintenance',
|
||||
'cron_script' => 'board_maintenance.php',
|
||||
'schedule' => 'daily',
|
||||
'run_day' => null,
|
||||
'run_time' => '05:00:00',
|
||||
'run_order' => 40,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => null,
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 1,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Prune forums',
|
||||
'cron_script' => 'prune_forums.php',
|
||||
'schedule' => 'daily',
|
||||
'run_day' => null,
|
||||
'run_time' => '05:00:00',
|
||||
'run_order' => 50,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => null,
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 1,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Prune topic moved stubs',
|
||||
'cron_script' => 'prune_topic_moved.php',
|
||||
'schedule' => 'daily',
|
||||
'run_day' => null,
|
||||
'run_time' => '05:00:00',
|
||||
'run_order' => 60,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => null,
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 1,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Logs cleanup',
|
||||
'cron_script' => 'clean_log.php',
|
||||
'schedule' => 'daily',
|
||||
'run_day' => null,
|
||||
'run_time' => '05:00:00',
|
||||
'run_order' => 70,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => null,
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 1,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'PM cleanup',
|
||||
'cron_script' => 'clean_pm.php',
|
||||
'schedule' => 'daily',
|
||||
'run_day' => null,
|
||||
'run_time' => '05:00:00',
|
||||
'run_order' => 70,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => null,
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 1,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Tracker maintenance',
|
||||
'cron_script' => 'tr_maintenance.php',
|
||||
'schedule' => 'daily',
|
||||
'run_day' => null,
|
||||
'run_time' => '05:00:00',
|
||||
'run_order' => 90,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => null,
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 1,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Clean dlstat',
|
||||
'cron_script' => 'clean_dlstat.php',
|
||||
'schedule' => 'daily',
|
||||
'run_day' => null,
|
||||
'run_time' => '05:00:00',
|
||||
'run_order' => 100,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => null,
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 1,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Prune inactive users',
|
||||
'cron_script' => 'prune_inactive_users.php',
|
||||
'schedule' => 'daily',
|
||||
'run_day' => null,
|
||||
'run_time' => '05:00:00',
|
||||
'run_order' => 110,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => null,
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 1,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Sessions cleanup',
|
||||
'cron_script' => 'sessions_cleanup.php',
|
||||
'schedule' => 'interval',
|
||||
'run_day' => null,
|
||||
'run_time' => '04:00:00',
|
||||
'run_order' => 255,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => '00:03:00',
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 0,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'DS update cat_forums',
|
||||
'cron_script' => 'ds_update_cat_forums.php',
|
||||
'schedule' => 'interval',
|
||||
'run_day' => null,
|
||||
'run_time' => '04:00:00',
|
||||
'run_order' => 255,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => '00:05:00',
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 0,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'DS update stats',
|
||||
'cron_script' => 'ds_update_stats.php',
|
||||
'schedule' => 'interval',
|
||||
'run_day' => null,
|
||||
'run_time' => '04:00:00',
|
||||
'run_order' => 255,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => '00:10:00',
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 0,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Flash topic view',
|
||||
'cron_script' => 'flash_topic_view.php',
|
||||
'schedule' => 'interval',
|
||||
'run_day' => null,
|
||||
'run_time' => '04:00:00',
|
||||
'run_order' => 255,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => '00:10:00',
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 0,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Clean search results',
|
||||
'cron_script' => 'clean_search_results.php',
|
||||
'schedule' => 'interval',
|
||||
'run_day' => null,
|
||||
'run_time' => '04:00:00',
|
||||
'run_order' => 255,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => '00:10:00',
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 0,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Tracker cleanup and dlstat',
|
||||
'cron_script' => 'tr_cleanup_and_dlstat.php',
|
||||
'schedule' => 'interval',
|
||||
'run_day' => null,
|
||||
'run_time' => '04:00:00',
|
||||
'run_order' => 20,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => '00:15:00',
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 0,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Accrual seedbonus',
|
||||
'cron_script' => 'tr_seed_bonus.php',
|
||||
'schedule' => 'interval',
|
||||
'run_day' => null,
|
||||
'run_time' => '04:00:00',
|
||||
'run_order' => 25,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => '00:10:00',
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 0,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Make tracker snapshot',
|
||||
'cron_script' => 'tr_make_snapshot.php',
|
||||
'schedule' => 'interval',
|
||||
'run_day' => null,
|
||||
'run_time' => '04:00:00',
|
||||
'run_order' => 10,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => '00:10:00',
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 0,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Seeder last seen',
|
||||
'cron_script' => 'tr_update_seeder_last_seen.php',
|
||||
'schedule' => 'interval',
|
||||
'run_day' => null,
|
||||
'run_time' => '04:00:00',
|
||||
'run_order' => 255,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => '01:00:00',
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 0,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Tracker dl-complete count',
|
||||
'cron_script' => 'tr_complete_count.php',
|
||||
'schedule' => 'interval',
|
||||
'run_day' => null,
|
||||
'run_time' => '04:00:00',
|
||||
'run_order' => 255,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => '06:00:00',
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 0,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Sitemap update',
|
||||
'cron_script' => 'sitemap.php',
|
||||
'schedule' => 'daily',
|
||||
'run_day' => null,
|
||||
'run_time' => '06:00:00',
|
||||
'run_order' => 30,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => null,
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 0,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Update forums atom',
|
||||
'cron_script' => 'update_forums_atom.php',
|
||||
'schedule' => 'interval',
|
||||
'run_day' => null,
|
||||
'run_time' => '04:00:00',
|
||||
'run_order' => 255,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => '00:15:00',
|
||||
'log_enabled' => 0,
|
||||
'log_file' => '',
|
||||
'log_sql_queries' => 0,
|
||||
'disable_board' => 0,
|
||||
'run_counter' => 0
|
||||
],
|
||||
[
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Demo mode',
|
||||
'cron_script' => 'demo_mode.php',
|
||||
'schedule' => 'daily',
|
||||
'run_day' => null,
|
||||
'run_time' => '05:00:00',
|
||||
'run_order' => 255,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => null,
|
||||
'log_enabled' => 1,
|
||||
'log_file' => 'demo_mode_cron',
|
||||
'log_sql_queries' => 1,
|
||||
'disable_board' => 1,
|
||||
'run_counter' => 0
|
||||
]
|
||||
];
|
||||
|
||||
$this->table('bb_cron')->insert($cronJobs)->saveData();
|
||||
}
|
||||
|
||||
private function seedExtensions()
|
||||
{
|
||||
// Extension groups
|
||||
$groups = [
|
||||
['group_name' => 'Images', 'cat_id' => 1, 'allow_group' => 1, 'download_mode' => 1, 'upload_icon' => '', 'max_filesize' => 262144, 'forum_permissions' => ''],
|
||||
['group_name' => 'Archives', 'cat_id' => 0, 'allow_group' => 1, 'download_mode' => 1, 'upload_icon' => '', 'max_filesize' => 262144, 'forum_permissions' => ''],
|
||||
['group_name' => 'Plain text', 'cat_id' => 0, 'allow_group' => 1, 'download_mode' => 1, 'upload_icon' => '', 'max_filesize' => 262144, 'forum_permissions' => ''],
|
||||
['group_name' => 'Documents', 'cat_id' => 0, 'allow_group' => 1, 'download_mode' => 1, 'upload_icon' => '', 'max_filesize' => 262144, 'forum_permissions' => ''],
|
||||
['group_name' => 'Real media', 'cat_id' => 0, 'allow_group' => 0, 'download_mode' => 2, 'upload_icon' => '', 'max_filesize' => 262144, 'forum_permissions' => ''],
|
||||
['group_name' => 'Torrent', 'cat_id' => 0, 'allow_group' => 1, 'download_mode' => 1, 'upload_icon' => '', 'max_filesize' => 262144, 'forum_permissions' => '']
|
||||
];
|
||||
|
||||
$this->table('bb_extension_groups')->insert($groups)->saveData();
|
||||
|
||||
// Extensions
|
||||
$extensions = [
|
||||
['group_id' => 1, 'extension' => 'gif', 'comment' => ''],
|
||||
['group_id' => 1, 'extension' => 'png', 'comment' => ''],
|
||||
['group_id' => 1, 'extension' => 'jpeg', 'comment' => ''],
|
||||
['group_id' => 1, 'extension' => 'jpg', 'comment' => ''],
|
||||
['group_id' => 1, 'extension' => 'webp', 'comment' => ''],
|
||||
['group_id' => 1, 'extension' => 'avif', 'comment' => ''],
|
||||
['group_id' => 1, 'extension' => 'bmp', 'comment' => ''],
|
||||
['group_id' => 2, 'extension' => 'gtar', 'comment' => ''],
|
||||
['group_id' => 2, 'extension' => 'gz', 'comment' => ''],
|
||||
['group_id' => 2, 'extension' => 'tar', 'comment' => ''],
|
||||
['group_id' => 2, 'extension' => 'zip', 'comment' => ''],
|
||||
['group_id' => 2, 'extension' => 'rar', 'comment' => ''],
|
||||
['group_id' => 2, 'extension' => 'ace', 'comment' => ''],
|
||||
['group_id' => 2, 'extension' => '7z', 'comment' => ''],
|
||||
['group_id' => 3, 'extension' => 'txt', 'comment' => ''],
|
||||
['group_id' => 3, 'extension' => 'c', 'comment' => ''],
|
||||
['group_id' => 3, 'extension' => 'h', 'comment' => ''],
|
||||
['group_id' => 3, 'extension' => 'cpp', 'comment' => ''],
|
||||
['group_id' => 3, 'extension' => 'hpp', 'comment' => ''],
|
||||
['group_id' => 3, 'extension' => 'diz', 'comment' => ''],
|
||||
['group_id' => 3, 'extension' => 'm3u', 'comment' => ''],
|
||||
['group_id' => 4, 'extension' => 'xls', 'comment' => ''],
|
||||
['group_id' => 4, 'extension' => 'doc', 'comment' => ''],
|
||||
['group_id' => 4, 'extension' => 'dot', 'comment' => ''],
|
||||
['group_id' => 4, 'extension' => 'pdf', 'comment' => ''],
|
||||
['group_id' => 4, 'extension' => 'ai', 'comment' => ''],
|
||||
['group_id' => 4, 'extension' => 'ps', 'comment' => ''],
|
||||
['group_id' => 4, 'extension' => 'ppt', 'comment' => ''],
|
||||
['group_id' => 5, 'extension' => 'rm', 'comment' => ''],
|
||||
['group_id' => 6, 'extension' => 'torrent', 'comment' => '']
|
||||
];
|
||||
|
||||
$this->table('bb_extensions')->insert($extensions)->saveData();
|
||||
}
|
||||
|
||||
private function seedSmilies()
|
||||
{
|
||||
$smilies = [
|
||||
['code' => ':aa:', 'smile_url' => 'aa.gif', 'emoticon' => 'aa'],
|
||||
['code' => ':ab:', 'smile_url' => 'ab.gif', 'emoticon' => 'ab'],
|
||||
['code' => ':ac:', 'smile_url' => 'ac.gif', 'emoticon' => 'ac'],
|
||||
['code' => ':ae:', 'smile_url' => 'ae.gif', 'emoticon' => 'ae'],
|
||||
['code' => ':af:', 'smile_url' => 'af.gif', 'emoticon' => 'af'],
|
||||
['code' => ':ag:', 'smile_url' => 'ag.gif', 'emoticon' => 'ag'],
|
||||
['code' => ':ah:', 'smile_url' => 'ah.gif', 'emoticon' => 'ah'],
|
||||
['code' => ':ai:', 'smile_url' => 'ai.gif', 'emoticon' => 'ai'],
|
||||
['code' => ':aj:', 'smile_url' => 'aj.gif', 'emoticon' => 'aj'],
|
||||
['code' => ':ak:', 'smile_url' => 'ak.gif', 'emoticon' => 'ak'],
|
||||
['code' => ':al:', 'smile_url' => 'al.gif', 'emoticon' => 'al'],
|
||||
['code' => ':am:', 'smile_url' => 'am.gif', 'emoticon' => 'am'],
|
||||
['code' => ':an:', 'smile_url' => 'an.gif', 'emoticon' => 'an'],
|
||||
['code' => ':ao:', 'smile_url' => 'ao.gif', 'emoticon' => 'ao'],
|
||||
['code' => ':ap:', 'smile_url' => 'ap.gif', 'emoticon' => 'ap'],
|
||||
['code' => ':aq:', 'smile_url' => 'aq.gif', 'emoticon' => 'aq'],
|
||||
['code' => ':ar:', 'smile_url' => 'ar.gif', 'emoticon' => 'ar'],
|
||||
['code' => ':as:', 'smile_url' => 'as.gif', 'emoticon' => 'as'],
|
||||
['code' => ':at:', 'smile_url' => 'at.gif', 'emoticon' => 'at'],
|
||||
['code' => ':au:', 'smile_url' => 'au.gif', 'emoticon' => 'au'],
|
||||
['code' => ':av:', 'smile_url' => 'av.gif', 'emoticon' => 'av'],
|
||||
['code' => ':aw:', 'smile_url' => 'aw.gif', 'emoticon' => 'aw'],
|
||||
['code' => ':ax:', 'smile_url' => 'ax.gif', 'emoticon' => 'ax'],
|
||||
['code' => ':ay:', 'smile_url' => 'ay.gif', 'emoticon' => 'ay'],
|
||||
['code' => ':az:', 'smile_url' => 'az.gif', 'emoticon' => 'az'],
|
||||
['code' => ':ba:', 'smile_url' => 'ba.gif', 'emoticon' => 'ba'],
|
||||
['code' => ':bb:', 'smile_url' => 'bb.gif', 'emoticon' => 'bb'],
|
||||
['code' => ':bc:', 'smile_url' => 'bc.gif', 'emoticon' => 'bc'],
|
||||
['code' => ':bd:', 'smile_url' => 'bd.gif', 'emoticon' => 'bd'],
|
||||
['code' => ':be:', 'smile_url' => 'be.gif', 'emoticon' => 'be'],
|
||||
['code' => ':bf:', 'smile_url' => 'bf.gif', 'emoticon' => 'bf'],
|
||||
['code' => ':bg:', 'smile_url' => 'bg.gif', 'emoticon' => 'bg'],
|
||||
['code' => ':bh:', 'smile_url' => 'bh.gif', 'emoticon' => 'bh'],
|
||||
['code' => ':bi:', 'smile_url' => 'bi.gif', 'emoticon' => 'bi'],
|
||||
['code' => ':bj:', 'smile_url' => 'bj.gif', 'emoticon' => 'bj'],
|
||||
['code' => ':bk:', 'smile_url' => 'bk.gif', 'emoticon' => 'bk'],
|
||||
['code' => ':bl:', 'smile_url' => 'bl.gif', 'emoticon' => 'bl'],
|
||||
['code' => ':bm:', 'smile_url' => 'bm.gif', 'emoticon' => 'bm'],
|
||||
['code' => ':bn:', 'smile_url' => 'bn.gif', 'emoticon' => 'bn'],
|
||||
['code' => ':bo:', 'smile_url' => 'bo.gif', 'emoticon' => 'bo'],
|
||||
['code' => ':bp:', 'smile_url' => 'bp.gif', 'emoticon' => 'bp'],
|
||||
['code' => ':bq:', 'smile_url' => 'bq.gif', 'emoticon' => 'bq'],
|
||||
['code' => ':br:', 'smile_url' => 'br.gif', 'emoticon' => 'br'],
|
||||
['code' => ':bs:', 'smile_url' => 'bs.gif', 'emoticon' => 'bs'],
|
||||
['code' => ':bt:', 'smile_url' => 'bt.gif', 'emoticon' => 'bt'],
|
||||
['code' => ':bu:', 'smile_url' => 'bu.gif', 'emoticon' => 'bu'],
|
||||
['code' => ':bv:', 'smile_url' => 'bv.gif', 'emoticon' => 'bv'],
|
||||
['code' => ':bw:', 'smile_url' => 'bw.gif', 'emoticon' => 'bw'],
|
||||
['code' => ':bx:', 'smile_url' => 'bx.gif', 'emoticon' => 'bx'],
|
||||
['code' => ':by:', 'smile_url' => 'by.gif', 'emoticon' => 'by'],
|
||||
['code' => ':bz:', 'smile_url' => 'bz.gif', 'emoticon' => 'bz'],
|
||||
['code' => ':ca:', 'smile_url' => 'ca.gif', 'emoticon' => 'ca'],
|
||||
['code' => ':cb:', 'smile_url' => 'cb.gif', 'emoticon' => 'cb'],
|
||||
['code' => ':cc:', 'smile_url' => 'cc.gif', 'emoticon' => 'cc'],
|
||||
['code' => ':cd:', 'smile_url' => 'cd.gif', 'emoticon' => 'cd']
|
||||
];
|
||||
|
||||
$this->table('bb_smilies')->insert($smilies)->saveData();
|
||||
}
|
||||
|
||||
private function seedRanks()
|
||||
{
|
||||
$this->table('bb_ranks')->insert([
|
||||
[
|
||||
'rank_title' => 'Administrator',
|
||||
'rank_image' => 'styles/images/ranks/admin.png',
|
||||
'rank_style' => 'colorAdmin'
|
||||
]
|
||||
])->saveData();
|
||||
}
|
||||
|
||||
private function seedQuotaLimits()
|
||||
{
|
||||
$quotas = [
|
||||
['quota_desc' => 'Low', 'quota_limit' => 262144],
|
||||
['quota_desc' => 'Medium', 'quota_limit' => 10485760],
|
||||
['quota_desc' => 'High', 'quota_limit' => 15728640]
|
||||
];
|
||||
|
||||
$this->table('bb_quota_limits')->insert($quotas)->saveData();
|
||||
}
|
||||
|
||||
private function seedDisallowedUsernames()
|
||||
{
|
||||
$disallowed = [
|
||||
['disallow_id' => 1, 'disallow_username' => 'torrentpier*'],
|
||||
['disallow_id' => 2, 'disallow_username' => 'tracker*'],
|
||||
['disallow_id' => 3, 'disallow_username' => 'forum*'],
|
||||
['disallow_id' => 4, 'disallow_username' => 'torrent*'],
|
||||
['disallow_id' => 5, 'disallow_username' => 'admin*']
|
||||
];
|
||||
|
||||
$this->table('bb_disallow')->insert($disallowed)->saveData();
|
||||
}
|
||||
|
||||
private function seedAttachmentConfig()
|
||||
{
|
||||
$attachConfig = [
|
||||
['config_name' => 'upload_dir', 'config_value' => 'data/uploads'],
|
||||
['config_name' => 'upload_img', 'config_value' => 'styles/images/icon_clip.gif'],
|
||||
['config_name' => 'topic_icon', 'config_value' => 'styles/images/icon_clip.gif'],
|
||||
['config_name' => 'display_order', 'config_value' => '0'],
|
||||
['config_name' => 'max_filesize', 'config_value' => '262144'],
|
||||
['config_name' => 'attachment_quota', 'config_value' => '52428800'],
|
||||
['config_name' => 'max_filesize_pm', 'config_value' => '262144'],
|
||||
['config_name' => 'max_attachments', 'config_value' => '1'],
|
||||
['config_name' => 'max_attachments_pm', 'config_value' => '1'],
|
||||
['config_name' => 'disable_mod', 'config_value' => '0'],
|
||||
['config_name' => 'allow_pm_attach', 'config_value' => '1'],
|
||||
['config_name' => 'default_upload_quota', 'config_value' => '0'],
|
||||
['config_name' => 'default_pm_quota', 'config_value' => '0'],
|
||||
['config_name' => 'img_display_inlined', 'config_value' => '1'],
|
||||
['config_name' => 'img_max_width', 'config_value' => '2000'],
|
||||
['config_name' => 'img_max_height', 'config_value' => '2000'],
|
||||
['config_name' => 'img_link_width', 'config_value' => '600'],
|
||||
['config_name' => 'img_link_height', 'config_value' => '400'],
|
||||
['config_name' => 'img_create_thumbnail', 'config_value' => '1'],
|
||||
['config_name' => 'img_min_thumb_filesize', 'config_value' => '12000']
|
||||
];
|
||||
|
||||
$this->table('bb_attachments_config')->insert($attachConfig)->saveData();
|
||||
}
|
||||
|
||||
private function seedTopicsAndPosts()
|
||||
{
|
||||
$currentTime = time();
|
||||
|
||||
// Create welcome topic
|
||||
$this->table('bb_topics')->insert([
|
||||
[
|
||||
'topic_id' => 1,
|
||||
'forum_id' => 1,
|
||||
'topic_title' => 'Welcome to TorrentPier Cattle',
|
||||
'topic_poster' => 2,
|
||||
'topic_time' => $currentTime,
|
||||
'topic_views' => 0,
|
||||
'topic_replies' => 0,
|
||||
'topic_status' => 0,
|
||||
'topic_vote' => 0,
|
||||
'topic_type' => 0,
|
||||
'topic_first_post_id' => 1,
|
||||
'topic_last_post_id' => 1,
|
||||
'topic_moved_id' => 0,
|
||||
'topic_attachment' => 0,
|
||||
'topic_dl_type' => 0,
|
||||
'topic_last_post_time' => $currentTime,
|
||||
'topic_show_first_post' => 0,
|
||||
'topic_allow_robots' => 1
|
||||
]
|
||||
])->saveData();
|
||||
|
||||
// Create welcome post
|
||||
$this->table('bb_posts')->insert([
|
||||
[
|
||||
'post_id' => 1,
|
||||
'topic_id' => 1,
|
||||
'forum_id' => 1,
|
||||
'poster_id' => 2,
|
||||
'post_time' => $currentTime,
|
||||
'poster_ip' => '0',
|
||||
'poster_rg_id' => 0,
|
||||
'attach_rg_sig' => 0,
|
||||
'post_username' => '',
|
||||
'post_edit_time' => 0,
|
||||
'post_edit_count' => 0,
|
||||
'post_attachment' => 0,
|
||||
'user_post' => 1,
|
||||
'mc_comment' => '',
|
||||
'mc_type' => 0,
|
||||
'mc_user_id' => 0
|
||||
]
|
||||
])->saveData();
|
||||
|
||||
// Create welcome post text
|
||||
$welcomeText = "Thank you for installing the new — TorrentPier Cattle!\n\n" .
|
||||
"What to do next? First of all configure your site in the administration panel (link in the bottom).\n\n" .
|
||||
"Change main options: site description, number of messages per topic, time zone, language by default, seed-bonus options, birthdays etc... " .
|
||||
"Create a couple of forums, delete or change this one. Change settings of categories to allow registration of torrents, change announcer url. " .
|
||||
"If you will have questions or want additional modifications of the engine, [url=https://torrentpier.com/]visit our forum[/url] " .
|
||||
"(you can use english, we will try to help in any case).\n\n" .
|
||||
"If you want to help with the translations: [url=https://crowdin.com/project/torrentpier]Crowdin[/url].\n\n" .
|
||||
"Our GitHub organization: [url=https://github.com/torrentpier]https://github.com/torrentpier[/url].\n" .
|
||||
"Our SourceForge repository: [url=https://sourceforge.net/projects/torrentpier-engine]https://sourceforge.net/projects/torrentpier-engine[/url].\n" .
|
||||
"Our demo website: [url=https://torrentpier.duckdns.org]https://torrentpier.duckdns.org[/url].\n\n" .
|
||||
"We are sure that you will be able to create the best tracker available!\n" .
|
||||
"Good luck! 😉";
|
||||
|
||||
$this->table('bb_posts_text')->insert([
|
||||
[
|
||||
'post_id' => 1,
|
||||
'post_text' => $welcomeText
|
||||
]
|
||||
])->saveData();
|
||||
}
|
||||
|
||||
private function seedTopicWatch()
|
||||
{
|
||||
$this->table('bb_topics_watch')->insert([
|
||||
[
|
||||
'topic_id' => 1,
|
||||
'user_id' => 2,
|
||||
'notify_status' => 1
|
||||
]
|
||||
])->saveData();
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
// Clean all seeded data
|
||||
$tables = [
|
||||
'bb_topics_watch', 'bb_posts_text', 'bb_posts', 'bb_topics',
|
||||
'bb_attachments_config', 'bb_disallow', 'bb_quota_limits',
|
||||
'bb_ranks', 'bb_smilies', 'bb_extensions', 'bb_extension_groups',
|
||||
'bb_cron', 'bb_config', 'bb_bt_users', 'bb_users', 'bb_forums', 'bb_categories'
|
||||
];
|
||||
|
||||
foreach ($tables as $table) {
|
||||
$this->execute("DELETE FROM {$table}");
|
||||
}
|
||||
}
|
||||
}
|
44
migrations/20250620001449_remove_demo_mode.php
Normal file
44
migrations/20250620001449_remove_demo_mode.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
final class RemoveDemoMode extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* Migrate Up.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
// Delete the demo_mode.php cron job from bb_cron table
|
||||
$this->table('bb_cron')
|
||||
->getAdapter()
|
||||
->execute("DELETE FROM bb_cron WHERE cron_script = 'demo_mode.php'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate Down.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
// Restore the demo_mode.php cron job to bb_cron table
|
||||
$this->table('bb_cron')->insert([
|
||||
'cron_active' => 1,
|
||||
'cron_title' => 'Demo mode',
|
||||
'cron_script' => 'demo_mode.php',
|
||||
'schedule' => 'daily',
|
||||
'run_day' => null,
|
||||
'run_time' => '05:00:00',
|
||||
'run_order' => 255,
|
||||
'last_run' => '1900-01-01 00:00:00',
|
||||
'next_run' => '1900-01-01 00:00:00',
|
||||
'run_interval' => null,
|
||||
'log_enabled' => 1,
|
||||
'log_file' => 'demo_mode_cron',
|
||||
'log_sql_queries' => 1,
|
||||
'disable_board' => 1,
|
||||
'run_counter' => 0
|
||||
])->save();
|
||||
}
|
||||
}
|
74
phinx.php
Normal file
74
phinx.php
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
/**
|
||||
* Phinx configuration for TorrentPier
|
||||
*/
|
||||
|
||||
if (PHP_SAPI != 'cli') {
|
||||
die(basename(__FILE__));
|
||||
}
|
||||
|
||||
// Only load what's needed for Phinx - don't bootstrap the entire application
|
||||
const BB_ROOT = __DIR__ . DIRECTORY_SEPARATOR;
|
||||
const BB_PATH = __DIR__;
|
||||
require_once BB_ROOT . 'library/defines.php';
|
||||
|
||||
// Load environment variables
|
||||
use Dotenv\Dotenv;
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
if (file_exists(__DIR__ . '/.env')) {
|
||||
$dotenv = Dotenv::createMutable(__DIR__);
|
||||
$dotenv->load();
|
||||
}
|
||||
|
||||
// Helper function for environment variables
|
||||
function env(string $key, mixed $default = null): mixed
|
||||
{
|
||||
$value = $_ENV[$key] ?? getenv($key);
|
||||
if ($value === false) {
|
||||
return $default;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
return [
|
||||
'paths' => [
|
||||
'migrations' => __DIR__ . '/migrations'
|
||||
],
|
||||
'environments' => [
|
||||
'default_migration_table' => BB_MIGRATIONS,
|
||||
'default_environment' => env('APP_ENV', 'production'),
|
||||
'production' => [
|
||||
'adapter' => 'mysql',
|
||||
'host' => env('DB_HOST', 'localhost'),
|
||||
'port' => (int)env('DB_PORT', 3306),
|
||||
'name' => env('DB_DATABASE'),
|
||||
'user' => env('DB_USERNAME'),
|
||||
'pass' => env('DB_PASSWORD', ''),
|
||||
'charset' => 'utf8mb4',
|
||||
'collation' => 'utf8mb4_unicode_ci',
|
||||
'table_options' => [
|
||||
'ENGINE' => 'InnoDB',
|
||||
'DEFAULT CHARSET' => 'utf8mb4',
|
||||
'COLLATE' => 'utf8mb4_unicode_ci'
|
||||
]
|
||||
],
|
||||
'development' => [
|
||||
'adapter' => 'mysql',
|
||||
'host' => env('DB_HOST', 'localhost'),
|
||||
'port' => (int)env('DB_PORT', 3306),
|
||||
'name' => env('DB_DATABASE'),
|
||||
'user' => env('DB_USERNAME'),
|
||||
'pass' => env('DB_PASSWORD', ''),
|
||||
'charset' => 'utf8mb4',
|
||||
'collation' => 'utf8mb4_unicode_ci',
|
||||
'table_options' => [
|
||||
'ENGINE' => 'InnoDB',
|
||||
'DEFAULT CHARSET' => 'utf8mb4',
|
||||
'COLLATE' => 'utf8mb4_unicode_ci'
|
||||
]
|
||||
]
|
||||
],
|
||||
'version_order' => 'creation',
|
||||
];
|
|
@ -165,10 +165,23 @@ class UnifiedCacheSystem
|
|||
case 'redis':
|
||||
// Some deprecated cache types will fall back to file storage
|
||||
$dir = rtrim($this->cfg['db_dir'] ?? sys_get_temp_dir() . '/cache/', '/') . '/' . $cache_name . '/';
|
||||
|
||||
// Create directory automatically using TorrentPier's bb_mkdir function
|
||||
if (!is_dir($dir) && !bb_mkdir($dir)) {
|
||||
throw new \RuntimeException("Failed to create cache directory: $dir");
|
||||
}
|
||||
|
||||
return new FileStorage($dir);
|
||||
|
||||
case 'sqlite':
|
||||
$dbFile = rtrim($this->cfg['db_dir'] ?? sys_get_temp_dir() . '/cache/', '/') . '/' . $cache_name . '.db';
|
||||
|
||||
// Create parent directory for SQLite file
|
||||
$dbDir = dirname($dbFile);
|
||||
if (!is_dir($dbDir) && !bb_mkdir($dbDir)) {
|
||||
throw new \RuntimeException("Failed to create cache directory for SQLite: $dbDir");
|
||||
}
|
||||
|
||||
return new SQLiteStorage($dbFile);
|
||||
|
||||
case 'memory':
|
||||
|
@ -183,6 +196,12 @@ class UnifiedCacheSystem
|
|||
default:
|
||||
// Fallback to file storage
|
||||
$dir = rtrim($this->cfg['db_dir'] ?? sys_get_temp_dir() . '/cache/', '/') . '/' . $cache_name . '/';
|
||||
|
||||
// Create directory automatically using TorrentPier's bb_mkdir function
|
||||
if (!is_dir($dir) && !bb_mkdir($dir)) {
|
||||
throw new \RuntimeException("Failed to create cache directory: $dir");
|
||||
}
|
||||
|
||||
return new FileStorage($dir);
|
||||
}
|
||||
}
|
||||
|
@ -218,10 +237,23 @@ class UnifiedCacheSystem
|
|||
case 'redis':
|
||||
// Some deprecated cache types will fall back to file storage
|
||||
$dir = rtrim($this->cfg['db_dir'] ?? sys_get_temp_dir() . '/cache/', '/') . '/datastore/';
|
||||
|
||||
// Create directory automatically using TorrentPier's bb_mkdir function
|
||||
if (!is_dir($dir) && !bb_mkdir($dir)) {
|
||||
throw new \RuntimeException("Failed to create datastore directory: $dir");
|
||||
}
|
||||
|
||||
return new FileStorage($dir);
|
||||
|
||||
case 'sqlite':
|
||||
$dbFile = rtrim($this->cfg['db_dir'] ?? sys_get_temp_dir() . '/cache/', '/') . '/datastore.db';
|
||||
|
||||
// Create parent directory for SQLite file
|
||||
$dbDir = dirname($dbFile);
|
||||
if (!is_dir($dbDir) && !bb_mkdir($dbDir)) {
|
||||
throw new \RuntimeException("Failed to create datastore directory for SQLite: $dbDir");
|
||||
}
|
||||
|
||||
return new SQLiteStorage($dbFile);
|
||||
|
||||
case 'memory':
|
||||
|
@ -236,6 +268,12 @@ class UnifiedCacheSystem
|
|||
default:
|
||||
// Fallback to file storage
|
||||
$dir = rtrim($this->cfg['db_dir'] ?? sys_get_temp_dir() . '/cache/', '/') . '/datastore/';
|
||||
|
||||
// Create directory automatically using TorrentPier's bb_mkdir function
|
||||
if (!is_dir($dir) && !bb_mkdir($dir)) {
|
||||
throw new \RuntimeException("Failed to create datastore directory: $dir");
|
||||
}
|
||||
|
||||
return new FileStorage($dir);
|
||||
}
|
||||
}
|
||||
|
|
305
src/Database/MigrationStatus.php
Normal file
305
src/Database/MigrationStatus.php
Normal file
|
@ -0,0 +1,305 @@
|
|||
<?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
|
||||
*/
|
||||
|
||||
namespace TorrentPier\Database;
|
||||
|
||||
/**
|
||||
* Migration Status Manager
|
||||
*
|
||||
* Provides read-only access to database migration status information
|
||||
* for the admin panel. Uses TorrentPier's database singleton and config system.
|
||||
*/
|
||||
class MigrationStatus
|
||||
{
|
||||
private string $migrationTable;
|
||||
private string $migrationPath;
|
||||
private array $initialMigrations = [
|
||||
'20250619000001',
|
||||
'20250619000002'
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->migrationTable = BB_MIGRATIONS;
|
||||
$this->migrationPath = BB_ROOT . 'migrations';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get complete migration status information
|
||||
*
|
||||
* @return array Migration status data including applied/pending migrations
|
||||
*/
|
||||
public function getMigrationStatus(): array
|
||||
{
|
||||
try {
|
||||
// Check if migration table exists using Nette Database Explorer
|
||||
$tableExists = $this->checkMigrationTableExists();
|
||||
$setupStatus = $this->getSetupStatus();
|
||||
|
||||
if (!$tableExists) {
|
||||
return [
|
||||
'table_exists' => false,
|
||||
'current_version' => null,
|
||||
'applied_migrations' => [],
|
||||
'pending_migrations' => $this->getAvailableMigrations(),
|
||||
'setup_status' => $setupStatus,
|
||||
'requires_setup' => $setupStatus['needs_setup']
|
||||
];
|
||||
}
|
||||
|
||||
// Get applied migrations using Nette Database Explorer
|
||||
$appliedMigrations = DB()->query("
|
||||
SELECT version, migration_name, start_time, end_time
|
||||
FROM {$this->migrationTable}
|
||||
ORDER BY version ASC
|
||||
")->fetchAll();
|
||||
|
||||
// Convert Nette Result objects to arrays
|
||||
$appliedMigrationsArray = [];
|
||||
foreach ($appliedMigrations as $migration) {
|
||||
$appliedMigrationsArray[] = [
|
||||
'version' => $migration->version,
|
||||
'migration_name' => $migration->migration_name,
|
||||
'start_time' => $migration->start_time,
|
||||
'end_time' => $migration->end_time
|
||||
];
|
||||
}
|
||||
|
||||
// Get current version (latest applied)
|
||||
$currentVersion = null;
|
||||
if (!empty($appliedMigrationsArray)) {
|
||||
$currentVersion = end($appliedMigrationsArray)['version'];
|
||||
}
|
||||
|
||||
// Get pending migrations
|
||||
$availableMigrations = $this->getAvailableMigrations();
|
||||
$appliedVersions = array_column($appliedMigrationsArray, 'version');
|
||||
$pendingMigrations = array_filter($availableMigrations, function ($migration) use ($appliedVersions) {
|
||||
return !in_array($migration['version'], $appliedVersions);
|
||||
});
|
||||
|
||||
return [
|
||||
'table_exists' => true,
|
||||
'current_version' => $currentVersion,
|
||||
'applied_migrations' => $appliedMigrationsArray,
|
||||
'pending_migrations' => array_values($pendingMigrations),
|
||||
'setup_status' => $setupStatus,
|
||||
'requires_setup' => $setupStatus['needs_setup']
|
||||
];
|
||||
|
||||
} catch (\Exception $e) {
|
||||
bb_die('Error checking migration status: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine setup status for existing installations
|
||||
*
|
||||
* @return array Setup status information
|
||||
*/
|
||||
private function getSetupStatus(): array
|
||||
{
|
||||
try {
|
||||
// Check if core TorrentPier tables exist (indicates existing installation)
|
||||
$coreTablesExist = $this->checkCoreTablesExist();
|
||||
$migrationTableExists = $this->checkMigrationTableExists();
|
||||
|
||||
if (!$coreTablesExist) {
|
||||
// Fresh installation
|
||||
return [
|
||||
'type' => 'fresh',
|
||||
'needs_setup' => false,
|
||||
'message' => 'Fresh installation - migrations will run normally',
|
||||
'action_required' => false
|
||||
];
|
||||
}
|
||||
|
||||
if (!$migrationTableExists) {
|
||||
// Existing installation without migration system
|
||||
return [
|
||||
'type' => 'existing_needs_setup',
|
||||
'needs_setup' => true,
|
||||
'message' => 'Existing installation detected - migration setup required',
|
||||
'action_required' => true,
|
||||
'instructions' => 'Mark initial migrations as applied using --fake flag'
|
||||
];
|
||||
}
|
||||
|
||||
// Check if initial migrations are marked as applied
|
||||
$initialMigrationsApplied = $this->checkInitialMigrationsApplied();
|
||||
|
||||
if (!$initialMigrationsApplied) {
|
||||
return [
|
||||
'type' => 'existing_partial_setup',
|
||||
'needs_setup' => true,
|
||||
'message' => 'Migration table exists but initial migrations not marked as applied',
|
||||
'action_required' => true,
|
||||
'instructions' => 'Run: php vendor/bin/phinx migrate --fake --target=20250619000002'
|
||||
];
|
||||
}
|
||||
|
||||
// Fully set up
|
||||
return [
|
||||
'type' => 'fully_setup',
|
||||
'needs_setup' => false,
|
||||
'message' => 'Migration system fully configured',
|
||||
'action_required' => false
|
||||
];
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return [
|
||||
'type' => 'error',
|
||||
'needs_setup' => false,
|
||||
'message' => 'Error detecting setup status: ' . $e->getMessage(),
|
||||
'action_required' => false
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if core TorrentPier tables exist
|
||||
*
|
||||
* @return bool True if core tables exist
|
||||
*/
|
||||
private function checkCoreTablesExist(): bool
|
||||
{
|
||||
try {
|
||||
$coreTable = 'bb_users'; // Key table that should exist in any TorrentPier installation
|
||||
$escapedTable = DB()->escape($coreTable);
|
||||
$result = DB()->query("
|
||||
SELECT COUNT(*) as table_count
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = '{$escapedTable}'
|
||||
")->fetch();
|
||||
|
||||
return $result && $result->table_count > 0;
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if initial migrations are marked as applied
|
||||
*
|
||||
* @return bool True if initial migrations are applied
|
||||
*/
|
||||
private function checkInitialMigrationsApplied(): bool
|
||||
{
|
||||
try {
|
||||
$initialMigrationsCSV = implode(',', $this->initialMigrations);
|
||||
$result = DB()->query("
|
||||
SELECT COUNT(*) as migration_count
|
||||
FROM {$this->migrationTable}
|
||||
WHERE version IN ($initialMigrationsCSV)
|
||||
")->fetch();
|
||||
|
||||
return $result && $result->migration_count >= count($this->initialMigrations);
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if migration table exists
|
||||
*
|
||||
* @return bool True if table exists, false otherwise
|
||||
*/
|
||||
private function checkMigrationTableExists(): bool
|
||||
{
|
||||
try {
|
||||
// Using simple query without parameters to avoid issues
|
||||
$escapedTable = DB()->escape($this->migrationTable);
|
||||
$result = DB()->query("
|
||||
SELECT COUNT(*) as table_count
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = '{$escapedTable}'
|
||||
")->fetch();
|
||||
|
||||
return $result && $result->table_count > 0;
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available migrations from filesystem
|
||||
*
|
||||
* @return array List of available migration files
|
||||
*/
|
||||
private function getAvailableMigrations(): array
|
||||
{
|
||||
$migrations = [];
|
||||
|
||||
if (is_dir($this->migrationPath)) {
|
||||
$files = glob($this->migrationPath . '/*.php');
|
||||
foreach ($files as $file) {
|
||||
$filename = basename($file);
|
||||
if (preg_match('/^(\d+)_(.+)\.php$/', $filename, $matches)) {
|
||||
$migrations[] = [
|
||||
'version' => $matches[1],
|
||||
'name' => $matches[2],
|
||||
'filename' => $filename,
|
||||
'file_path' => $file
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by version
|
||||
usort($migrations, function ($a, $b) {
|
||||
return strcmp($a['version'], $b['version']);
|
||||
});
|
||||
|
||||
return $migrations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database schema information
|
||||
*
|
||||
* @return array Database statistics and information
|
||||
*/
|
||||
public function getSchemaInfo(): array
|
||||
{
|
||||
try {
|
||||
// Get database name using Nette Database Explorer
|
||||
$dbInfo = DB()->query("SELECT DATABASE() as db_name")->fetch();
|
||||
|
||||
// Get table count using Nette Database Explorer
|
||||
$tableInfo = DB()->query("
|
||||
SELECT COUNT(*) as table_count
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE()
|
||||
")->fetch();
|
||||
|
||||
// Get database size using Nette Database Explorer
|
||||
$sizeInfo = DB()->query("
|
||||
SELECT
|
||||
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) as size_mb
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE()
|
||||
")->fetch();
|
||||
|
||||
return [
|
||||
'database_name' => $dbInfo->db_name ?? 'Unknown',
|
||||
'table_count' => $tableInfo->table_count ?? 0,
|
||||
'size_mb' => $sizeInfo->size_mb ?? 0
|
||||
];
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return [
|
||||
'database_name' => 'Unknown',
|
||||
'table_count' => 0,
|
||||
'size_mb' => 0,
|
||||
'error' => $e->getMessage()
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
183
styles/templates/admin/admin_migrations.tpl
Normal file
183
styles/templates/admin/admin_migrations.tpl
Normal file
|
@ -0,0 +1,183 @@
|
|||
<h1>{L_MIGRATIONS_STATUS}</h1>
|
||||
|
||||
<table class="forumline" cellpadding="4" cellspacing="1" border="0" width="100%">
|
||||
<tr>
|
||||
<th class="thHead" colspan="2">{L_MIGRATIONS_DATABASE_INFO}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="row1" width="35%"><b>{L_MIGRATIONS_DATABASE_NAME}:</b></td>
|
||||
<td class="row2">{SCHEMA_DATABASE_NAME}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="row1"><b>{L_MIGRATIONS_DATABASE_TOTAL}:</b></td>
|
||||
<td class="row2">{SCHEMA_TABLE_COUNT}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="row1"><b>{L_MIGRATIONS_DATABASE_SIZE}:</b></td>
|
||||
<td class="row2">{SCHEMA_SIZE_MB} MB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="row1"><b>{L_LAST_UPDATED}:</b></td>
|
||||
<td class="row2">{CURRENT_TIME}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
<table class="forumline" cellpadding="4" cellspacing="1" border="0" width="100%">
|
||||
<tr>
|
||||
<th class="thHead" colspan="2">{L_MIGRATIONS_STATUS}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="row1" width="35%"><b>{L_MIGRATIONS_SYSTEM}:</b></td>
|
||||
<td class="row2">
|
||||
<!-- IF MIGRATION_TABLE_EXISTS -->
|
||||
<!-- IF SETUP_REQUIRES_SETUP -->
|
||||
<span style="color: orange; font-weight: bold;">⚠ {L_MIGRATIONS_NEEDS_SETUP}</span>
|
||||
<!-- ELSE -->
|
||||
<span style="color: green; font-weight: bold;">✓ {L_MIGRATIONS_ACTIVE}</span>
|
||||
<!-- ENDIF -->
|
||||
<!-- ELSE -->
|
||||
<span style="color: red; font-weight: bold;">✗ {L_MIGRATIONS_NOT_INITIALIZED}</span>
|
||||
<!-- ENDIF -->
|
||||
</td>
|
||||
</tr>
|
||||
<!-- IF SETUP_ACTION_REQUIRED -->
|
||||
<tr>
|
||||
<td class="row1"><b>{L_MIGRATIONS_SETUP_STATUS}:</b></td>
|
||||
<td class="row2">
|
||||
<div
|
||||
style="background: #fff3cd; padding: 8px; border: 1px solid #ffeaa7; border-radius: 4px; margin: 4px 0;">
|
||||
<strong>{L_MIGRATIONS_ACTION_REQUIRED}:</strong> {SETUP_MESSAGE}<br>
|
||||
<!-- IF SETUP_INSTRUCTIONS -->
|
||||
<small><strong>{L_MIGRATIONS_INSTRUCTIONS}:</strong> {SETUP_INSTRUCTIONS}</small><br>
|
||||
<!-- ENDIF -->
|
||||
<small><a href="#migration-setup-guide">{L_MIGRATIONS_SETUP_GUIDE}</a></small>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- ENDIF -->
|
||||
<tr>
|
||||
<td class="row1"><b>Current Version:</b></td>
|
||||
<td class="row2">
|
||||
<!-- IF MIGRATION_CURRENT_VERSION -->
|
||||
{MIGRATION_CURRENT_VERSION}
|
||||
<!-- ELSE -->
|
||||
<em>{L_MIGRATIONS_NOT_APPLIED}</em>
|
||||
<!-- ENDIF -->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="row1"><b>{L_MIGRATIONS_APPLIED}:</b></td>
|
||||
<td class="row2">{MIGRATION_APPLIED_COUNT}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="row1"><b>{L_MIGRATIONS_PENDING}:</b></td>
|
||||
<td class="row2">
|
||||
<!-- IF MIGRATION_PENDING_COUNT > 0 -->
|
||||
<span style="color: orange; font-weight: bold;">{MIGRATION_PENDING_COUNT} {L_MIGRATIONS_PENDING_COUNT}</span>
|
||||
<!-- ELSE -->
|
||||
<span style="color: green;">{L_MIGRATIONS_UP_TO_DATE}</span>
|
||||
<!-- ENDIF -->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- IF MIGRATION_APPLIED_COUNT > 0 -->
|
||||
<br/>
|
||||
<table class="forumline" cellpadding="4" cellspacing="1" border="0" width="100%">
|
||||
<tr>
|
||||
<th class="thHead" colspan="4">{L_MIGRATIONS_APPLIED}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="catHead" width="15%"><b>{L_MIGRATIONS_VERSION}</b></td>
|
||||
<td class="catHead" width="35%"><b>{L_MIGRATIONS_NAME}</b></td>
|
||||
<td class="catHead" width="25%"><b>{L_MIGRATIONS_APPLIED_AT}</b></td>
|
||||
<td class="catHead" width="25%"><b>{L_MIGRATIONS_COMPLETED_AT}</b></td>
|
||||
</tr>
|
||||
<!-- BEGIN applied_migrations -->
|
||||
<tr>
|
||||
<td class="{applied_migrations.ROW_CLASS}">{applied_migrations.VERSION}</td>
|
||||
<td class="{applied_migrations.ROW_CLASS}">{applied_migrations.NAME}</td>
|
||||
<td class="{applied_migrations.ROW_CLASS}">{applied_migrations.START_TIME}</td>
|
||||
<td class="{applied_migrations.ROW_CLASS}">{applied_migrations.END_TIME}</td>
|
||||
</tr>
|
||||
<!-- END applied_migrations -->
|
||||
</table>
|
||||
<!-- ENDIF -->
|
||||
|
||||
<!-- IF MIGRATION_PENDING_COUNT > 0 -->
|
||||
<br/>
|
||||
<table class="forumline" cellpadding="4" cellspacing="1" border="0" width="100%">
|
||||
<tr>
|
||||
<th class="thHead" colspan="3">{L_MIGRATIONS_PENDING}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="catHead" width="15%"><b>{L_MIGRATIONS_VERSION}</b></td>
|
||||
<td class="catHead" width="35%"><b>{L_MIGRATIONS_NAME}</b></td>
|
||||
<td class="catHead" width="50%"><b>{L_MIGRATIONS_FILE}</b></td>
|
||||
</tr>
|
||||
<!-- BEGIN pending_migrations -->
|
||||
<tr>
|
||||
<td class="{pending_migrations.ROW_CLASS}">{pending_migrations.VERSION}</td>
|
||||
<td class="{pending_migrations.ROW_CLASS}">{pending_migrations.NAME}</td>
|
||||
<td class="{pending_migrations.ROW_CLASS}"><code>{pending_migrations.FILENAME}</code></td>
|
||||
</tr>
|
||||
<!-- END pending_migrations -->
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
<div class="alert-warning"
|
||||
style="padding: 10px; background-color: #fff3cd; border: 1px solid #ffeaa7; border-radius: 4px;">
|
||||
<strong>⚠️ Pending Migrations Detected</strong><br/>
|
||||
There are {MIGRATION_PENDING_COUNT} migration(s) that need to be applied.
|
||||
Contact your system administrator to run:<br/>
|
||||
<code style="background: #f8f9fa; padding: 2px 4px;">php vendor/bin/phinx migrate</code>
|
||||
</div>
|
||||
<!-- ENDIF -->
|
||||
|
||||
<br/>
|
||||
<div class="info-box" style="padding: 15px; background-color: #e9ecef; border-radius: 4px;">
|
||||
<h3>Migration Management</h3>
|
||||
<p>This panel provides read-only information about the database migration status.
|
||||
To manage migrations, use the command line interface:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Check status:</strong> <code>php vendor/bin/phinx status</code></li>
|
||||
<li><strong>Run migrations:</strong> <code>php vendor/bin/phinx migrate</code></li>
|
||||
<li><strong>Create new migration:</strong> <code>php vendor/bin/phinx create MigrationName</code></li>
|
||||
<li><strong>Rollback last migration:</strong> <code>php vendor/bin/phinx rollback</code></li>
|
||||
</ul>
|
||||
|
||||
<p><strong>⚠️ Important:</strong> Always backup your database before running migrations in production!</p>
|
||||
</div>
|
||||
|
||||
<!-- IF SETUP_REQUIRES_SETUP -->
|
||||
<br/>
|
||||
<div id="migration-setup-guide" class="setup-guide"
|
||||
style="padding: 15px; background-color: #f8d7da; border: 1px solid #f5c6cb; border-radius: 4px;">
|
||||
<h3 style="color: #721c24;">🔧 Migration Setup Required</h3>
|
||||
<p>Your installation has existing data but hasn't been set up for migrations yet. Follow these steps:</p>
|
||||
|
||||
<h4>Step 1: Backup Your Database</h4>
|
||||
<pre style="background: #f8f9fa; padding: 10px; border-radius: 4px;">mysqldump -u username -p database_name > backup_$(date +%Y%m%d_%H%M%S).sql</pre>
|
||||
|
||||
<h4>Step 2: Initialize Migration System</h4>
|
||||
<pre style="background: #f8f9fa; padding: 10px; border-radius: 4px;">php vendor/bin/phinx init</pre>
|
||||
|
||||
<h4>Step 3: Mark Initial Migrations as Applied</h4>
|
||||
<pre style="background: #f8f9fa; padding: 10px; border-radius: 4px;">php vendor/bin/phinx migrate --fake --target=20250619000001
|
||||
php vendor/bin/phinx migrate --fake --target=20250619000002</pre>
|
||||
|
||||
<h4>Step 4: Verify Setup</h4>
|
||||
<pre style="background: #f8f9fa; padding: 10px; border-radius: 4px;">php vendor/bin/phinx status</pre>
|
||||
|
||||
<p><strong>What this does:</strong> The <code>--fake</code> flag marks migrations as applied without actually
|
||||
running them,
|
||||
since your database already has the schema. This allows future migrations to work normally.</p>
|
||||
|
||||
<p><strong>📖 Need help?</strong> See the complete guide in the
|
||||
<a href="https://github.com/torrentpier/torrentpier/blob/master/UPGRADE_GUIDE.md#migration-setup-for-existing-installations"
|
||||
target="_blank">UPGRADE_GUIDE.md</a></p>
|
||||
</div>
|
||||
<!-- ENDIF -->
|
Loading…
Add table
Add a link
Reference in a new issue