Aggro is the codebase that powers BMXfeed, a BMX news aggregator and video discovery platform. Running continuously since 2006, BMXfeed collects and curates BMX-related content from across the web.
- News aggregation — automatically collects and displays BMX news from various sources
- Video integration — aggregates BMX videos from YouTube and Vimeo
- RSS feed directory — maintains a curated directory of BMX-related RSS feeds
- Content curation — automatically archives old content and manages content quality
- API support — integrates with YouTube and Vimeo APIs for video metadata
- Feed generation — provides RSS/OPML feeds of aggregated content
- Responsive design — mobile-first, responsive web interface
- Error monitoring — integrated Sentry for real-time error tracking and performance monitoring
- Enhanced security — parameterized database queries, secure configuration management, input validation, CSRF protection, security headers
- Back-end — PHP 8.4+ with CodeIgniter 4 framework
- Front-end — vanilla CSS with PostCSS processing and no JavaScript!
- Database — MySQL/MariaDB (SQLite for testing)
- Testing — PHPUnit 11.5 for unit testing with coverage reporting
- Debugging — Xdebug available for local development (off by default)
- Error monitoring — Sentry for application monitoring and error tracking
- Code quality — PHP CS Fixer, PHP CodeSniffer, PHPMD, PHPStan for static analysis and code standards
- Dependencies — SimplePie for feed parsing, Composer for PHP package management, npm for front-end build tooling
Aggro follows a clean architecture pattern with separation of concerns:
- Controllers — Handle HTTP requests and coordinate responses
- Models — Core business logic and data structures
- Repositories — Data access layer for database operations
- Services — Domain-specific business logic (archiving, thumbnails)
- Helpers — Utility functions for common operations
- Libraries — Third-party integrations and custom components
This architecture improves code maintainability, testability, and follows SOLID principles. The clean separation of concerns enables unit testing with 464 tests achieving 46.22% line coverage across all architectural layers.
Aggro uses DDEV for local development. This ensures a consistent development environment across machines.
- Install DDEV
- Docker compatible host system
-
Clone the repository and enter directory:
git clone https://github.com/jsnmrs/aggro.git cd aggro -
Initialize the project:
ddev init
-
View the site:
- Open https://aggro.ddev.site in your browser
- The init process creates a local database from aggro-db.sql
Xdebug is available in the DDEV environment but disabled by default for better performance. Enable it when you need debugging or profiling:
ddev xdebug onWhen enabled, the configuration is:
- Server name —
aggro.ddev.site - Port —
9003 - IDE key —
VSCODE - Coverage — Enabled for test coverage reports
Configure VS Code to listen for Xdebug connections on port 9003. The debugger will automatically connect when triggered.
When you're done debugging, disable Xdebug to restore performance:
ddev xdebug offAggro includes several custom DDEV commands to help with development:
ddev check— Check local URL responses for errorsddev clicheck— Run application maintenance tasksddev cron— Manage crontab (sync or clear)ddev fire— Run a controller method from the CLIddev frontend— Run front-end build processddev shellcheck— Run ShellCheck on custom commandsddev tunnel— Run a controller method on the remote serverddev upgrade— Update Composer packages
Maintenance tasks can be run via CLI using ddev fire for local or ddev tunnel for remote:
aggro log— View application logaggro log-error— View error logaggro log-clean— Clean old log entriesaggro log-error-clean— Clean old error log entriesaggro news— Fetch news feedsaggro news-cache— Clear news feed cacheaggro news-clean— Archive old news itemsaggro sweep— Run all maintenance tasksaggro vimeo/VIDEO_ID— Fetch a Vimeo videoaggro youtube/VIDEO_ID— Fetch a YouTube video
Copy .env-sample to .env for your local environment. Key configurations:
CI_ENVIRONMENT— set to "development" for local workapp.baseURL— your local URL (default: https://aggro.ddev.site)- Database credentials — configured through DDEV
- API keys — for video services
SENTRY_DSN— your Sentry Data Source Name for error trackingSENTRY_ENVIRONMENT— environment name (development/production)SENTRY_RELEASE— application release versionSENTRY_SAMPLE_RATE— error sampling rate (0.0 to 1.0)SENTRY_TRACES_SAMPLE_RATE— performance monitoring sample rateSENTRY_SEND_DEFAULT_PII— whether to send personally identifiable information
The app/Config/Storage.php file centralizes all file paths and storage-related settings:
- Thumbnail storage — path, dimensions, and quality settings
- Archive periods — content archival and cleanup timeframes
- Cache durations — default cache times for various operations
- Network timeouts — connection and request timeout settings
The .crontab file defines scheduled tasks for:
- News feed updates — every 6 minutes
- YouTube video checks — every 5 minutes
- Vimeo video checks — every 7 minutes
- Archive management — daily
- Feed cache clearing — monthly
The project includes 464 tests achieving 46.22% line coverage using PHPUnit for unit testing and multiple code quality tools.
- Total Tests — 464 unit tests
- Coverage — 46.22% line coverage across all components
- Assertions — 741 test assertions ensuring thorough validation
- External Dependencies — 86 tests appropriately skipped for external services (YouTube/Vimeo APIs, Sentry, file system)
- Test Files — 28 test files covering all major components
The test suite covers:
- Controllers — HTTP request handling, response coordination, and validation (Feed: 100%, Home: 100%, BaseController: 100%)
- Models — Core business logic and data structures (AggroModels: 100%, NewsModels: 37.59%, UtilityModels: 55.88%)
- Helpers — Utility functions and common operations with parameter validation
- Services — Domain-specific business logic (ArchiveService: 96.30%, ThumbnailService: 68.63%, ValidationService: 100%)
- Repositories — Data access layer operations (ChannelRepository: 100%, VideoRepository: 82.47%)
- Libraries — Third-party integrations (SentryService: 12.84%, SentryLogHandler: 19.44%)
- Filters — Request/response filtering (SecurityFilter: 100%, CustomCSRF: 100%, SentryPerformance: 12.90%)
- Security — SQL injection prevention, input validation, CSRF protection
Tests use an in-memory SQLite database for fast, isolated testing without affecting your development database. External services are properly mocked or skipped to ensure reliable test execution.
# Run all tests (includes PHPUnit + linting)
ddev test
# Run only PHPUnit unit tests
composer test:unit
# Run tests with coverage report (requires Xdebug: ddev xdebug on)
XDEBUG_MODE=coverage composer test:coverage
# Run all Composer test scripts
composer testWhen running tests with coverage, detailed HTML reports are generated in:
- Coverage reports —
build/logs/html/index.html - Raw coverage data —
build/logs/coverage.xml - Current baseline — 46.22% line coverage, 42.52% method coverage
Open the HTML report in your browser to view detailed coverage metrics by file and function.
Note — Coverage reporting requires Xdebug to be enabled (ddev xdebug on). Use XDEBUG_MODE=coverage when running coverage commands.
# Run specific checks
ddev composer lint # PHP linting, static analysis
ddev composer test # PHP unit tests
ddev shellcheck # Shell script linting
# Individual quality tools
ddev exec vendor/bin/php-cs-fixer fix # Auto-fix PHP code style issues
ddev exec vendor/bin/phpstan analyse # Run PHPStan static analysisThe test suite follows TDD principles and best practices:
- Proper Isolation — External dependencies (APIs, file system, network) are mocked or skipped
- Fast Execution — In-memory SQLite database for rapid test runs
- Coverage — Tests cover success paths, error conditions, and edge cases
- Clean Architecture — Testable design with dependency injection
- External Service Handling — 86 tests appropriately skipped for YouTube/Vimeo APIs, Sentry, and file operations
GitHub Actions automatically runs the full test suite (464 tests) on all pull requests, including:
- PHPUnit unit tests with coverage validation
- Code style checks (PHP CS Fixer, CodeSniffer)
- Static analysis (PHPStan, PHPMD)
- Shell script linting
All tests must pass before code can be merged, ensuring code quality and preventing regressions.
The application includes the following security measures:
- CSRF Protection — Custom CSRF filter for all state-changing operations
- Input Validation — ValidationService provides sanitization for slugs, video IDs, gate keys, and integers
- SQL Injection Prevention — All database queries use parameterized statements
- Security Headers — Automatic security headers via SecurityFilter
- Null Byte Protection — Automatic null byte removal from all input
- Timing-Safe Comparisons — Used for sensitive string comparisons like gate keys
Deployment is handled through GitHub Actions and Deployer with automated testing:
- Pull Request Testing — All PRs automatically run the complete test suite (464 tests) including PHPUnit tests, code quality checks, and static analysis
- Automated deployment — Deployment to production occurs on merge to main branch (only after all tests pass)
- Front-end assets — Assets are built and included in deployment
- Environment files — Securely transferred during deployment
- Crontab updates — Scheduled tasks are updated on deployment
The CI/CD pipeline ensures code quality by requiring all tests to pass before any code reaches production.
# Deploy to development
ddev deploy dev
# Deploy to production
ddev deploy prodAggro uses Sentry for application monitoring:
- Real-time error tracking and alerting
- Performance monitoring for slow requests
- Automatic error grouping and deduplication
- Integration with deployment tracking
Configure Sentry by setting the appropriate environment variables in your .env file.
Aggro is open-source software licensed under the MIT license. See the LICENSE file for details.
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests (
ddev test) - Submit a pull request
- Developed and maintained by Jason Morris
- Built with CodeIgniter 4
- Uses SimplePie for feed parsing
- DDEV for development environment
- Issues — GitHub Issues
