# Contributing to Core PHP Framework Thank you for considering contributing to Core PHP Framework! This guide will help you get started. ## Code of Conduct Be respectful, professional, and constructive. We're building open-source software together. ## How to Contribute ### Reporting Bugs Before creating a bug report: - Check existing issues to avoid duplicates - Verify the bug exists in the latest version - Collect relevant information (PHP version, Laravel version, error messages) **Good Bug Report:** ```markdown **Description:** API key validation fails with bcrypt-hashed keys **Steps to Reproduce:** 1. Create API key: `$key = ApiKey::create(['name' => 'Test'])` 2. Attempt authentication: `GET /api/v1/posts` with key 3. Receive 401 Unauthorized **Expected:** Authentication succeeds **Actual:** Authentication fails **Version:** v1.0.0 **PHP:** 8.2.0 **Laravel:** 11.x ``` ### Suggesting Features Feature requests should include: - Clear use case - Example implementation (if possible) - Impact on existing functionality - Alternative approaches considered ### Pull Requests 1. **Fork the repository** 2. **Create a feature branch:** `git checkout -b feature/my-feature` 3. **Make your changes** (see coding standards below) 4. **Write tests** for your changes 5. **Run test suite:** `composer test` 6. **Commit with clear message:** `feat: add API key rotation` 7. **Push to your fork** 8. **Open pull request** against `main` branch ## Development Setup ### Prerequisites - PHP 8.2+ - Composer - MySQL/PostgreSQL - Redis (optional, for cache testing) ### Installation ```bash # Clone your fork git clone https://github.com/YOUR_USERNAME/core-php.git cd core-php # Install dependencies composer install # Copy environment file cp .env.example .env # Run tests composer test ``` ### Running Tests ```bash # All tests composer test # Specific test file ./vendor/bin/phpunit packages/core-php/tests/Feature/ActivityLogServiceTest.php # With coverage ./vendor/bin/phpunit --coverage-html coverage ``` ## Coding Standards ### PSR-12 Compliance Follow [PSR-12](https://www.php-fig.org/psr/psr-12/) coding standards: ```php validated()); return response()->json($post, 201); } // ❌ Bad public function store($request) { $post = CreatePost::run($request->validated()); return response()->json($post, 201); } ``` ### Docblocks Use docblocks for complex methods: ```php /** * Generate OG image for blog post. * * @param Post $post The blog post * @param array $options Image generation options * @return string Path to generated image * @throws ImageGenerationException */ public function generateOgImage(Post $post, array $options = []): string { // Implementation } ``` ### Naming Conventions **Classes:** - PascalCase - Descriptive names - Singular nouns for models ```php class Post extends Model {} class CreatePost extends Action {} class PostController extends Controller {} ``` **Methods:** - camelCase - Verb-based names - Descriptive intent ```php public function createPost() {} public function publishPost() {} public function getPublishedPosts() {} ``` **Variables:** - camelCase - Descriptive names - No abbreviations ```php // ✅ Good $publishedPosts = Post::published()->get(); $userWorkspace = $user->workspace; // ❌ Bad $p = Post::published()->get(); $ws = $user->workspace; ``` ## Module Structure Follow the established module pattern: ``` src/Mod/MyModule/ ├── Boot.php # Module entry point ├── Controllers/ │ ├── Web/ │ └── Api/ ├── Models/ ├── Actions/ ├── Migrations/ ├── Routes/ │ ├── web.php │ └── api.php ├── Views/ │ └── Blade/ ├── Lang/ │ └── en_GB/ └── Tests/ ├── Feature/ └── Unit/ ``` **Boot.php Example:** ```php 'onWebRoutes', AdminPanelBooting::class => 'onAdminPanel', ]; public function onWebRoutes(WebRoutesRegistering $event): void { $event->views('mymodule', __DIR__.'/Views'); $event->routes(fn () => require __DIR__.'/Routes/web.php'); } public function onAdminPanel(AdminPanelBooting $event): void { $event->menu(new MyModuleMenuProvider()); } } ``` ## Testing Guidelines ### Write Tests First Follow TDD when possible: ```php // 1. Write test public function test_creates_post(): void { $post = CreatePost::run([ 'title' => 'Test Post', 'content' => 'Content', ]); $this->assertDatabaseHas('posts', [ 'title' => 'Test Post', ]); } // 2. Implement feature class CreatePost { use Action; public function handle(array $data): Post { return Post::create($data); } } ``` ### Test Coverage Aim for 80%+ coverage on new code: ```bash ./vendor/bin/phpunit --coverage-text ``` ### Test Organization ```php class PostTest extends TestCase { // Feature tests - test complete workflows public function test_user_can_create_post(): void {} public function test_user_cannot_create_post_without_permission(): void {} // Unit tests - test isolated components public function test_post_is_published(): void {} public function test_post_has_slug(): void {} } ``` ## Commit Messages Follow [Conventional Commits](https://www.conventionalcommits.org/): ``` ():