Contributing - Grazulex/laravel-arc GitHub Wiki

🤝 Contributing

Welcome Contributors!

Thank you for your interest in contributing to Laravel Arc! This guide will help you get started with contributing to the project.

📚 Table of Contents

Code of Conduct

This project and everyone participating in it is governed by our Code of Conduct. By participating, you are expected to uphold this code.

Our Pledge

We pledge to make participation in our project a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.

Our Standards

Positive behavior includes:

  • Using welcoming and inclusive language
  • Being respectful of differing viewpoints and experiences
  • Gracefully accepting constructive criticism
  • Focusing on what is best for the community
  • Showing empathy towards other community members

Unacceptable behavior includes:

  • The use of sexualized language or imagery
  • Trolling, insulting/derogatory comments, and personal or political attacks
  • Public or private harassment
  • Publishing others' private information without explicit permission
  • Other conduct which could reasonably be considered inappropriate

Getting Started

Prerequisites

  • PHP: 8.1 or higher
  • Composer: 2.0 or higher
  • Laravel: 10.0 or higher (for testing)
  • Git: For version control
  • PHPUnit: For testing (included via Composer)

Fork the Repository

  1. Fork the repository on GitHub
  2. Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/laravel-arc.git
cd laravel-arc
  1. Add the upstream repository:
git remote add upstream https://github.com/Grazulex/laravel-arc.git

Development Setup

Install Dependencies

# Install PHP dependencies
composer install

# Install development dependencies
composer install --dev

Environment Setup

# Copy environment file
cp .env.example .env

# Generate application key (if needed)
php artisan key:generate

Database Setup (for testing)

# Run migrations for testing
php artisan migrate --database=testing

Verify Installation

# Run tests to verify everything works
composer test

# Run static analysis
composer analyze

# Check coding standards
composer cs-check

How to Contribute

Types of Contributions

  1. Bug Reports - Help us identify and fix issues
  2. Feature Requests - Suggest new features or improvements
  3. Code Contributions - Submit bug fixes or new features
  4. Documentation - Improve or expand documentation
  5. Testing - Add or improve test coverage
  6. Performance - Optimize existing code

Contribution Workflow

  1. Find or Create an Issue - Check existing issues or create a new one
  2. Discuss - Comment on the issue to discuss your approach
  3. Fork & Branch - Create a feature branch from main
  4. Develop - Write your code following our standards
  5. Test - Ensure all tests pass and add new tests
  6. Document - Update documentation as needed
  7. Submit - Create a pull request

Branch Naming

Use descriptive branch names:

# Features
feature/transformation-pipeline
feature/enum-support

# Bug fixes
bugfix/validation-error-handling
bugfix/memory-leak-issue

# Documentation
docs/installation-guide
docs/api-reference

# Refactoring
refactor/property-attribute-system
refactor/validation-rules

Coding Standards

PHP Standards

We follow PSR-12 coding standards with some additional rules:

Code Style

<?php

namespace Grazulex\LaravelArc\Attributes;

use Illuminate\Support\Facades\Validator;
use InvalidArgumentException;

class Property
{
    public function __construct(
        public readonly string $type,
        public readonly bool $required = true,
        public readonly mixed $default = null,
        public readonly array $rules = [],
        public readonly ?string $message = null,
        public readonly array $messages = [],
    ) {
        if (empty($type)) {
            throw new InvalidArgumentException('Property type cannot be empty');
        }
    }

    public function getValidationRules(): array
    {
        $rules = [];

        if ($this->required) {
            $rules[] = 'required';
        }

        $rules[] = $this->type;

        return array_merge($rules, $this->rules);
    }
}

Documentation Standards

/**
 * Validates data against property rules.
 *
 * This method validates the provided data array against the validation rules
 * defined in the model's Arc properties. It supports validation groups for
 * different scenarios.
 *
 * @param array $data The data to validate
 * @param string|array|null $groups Validation groups to apply
 * @param array $only Only validate these fields
 * @param array $except Skip validation for these fields
 * @return \Illuminate\Validation\Validator
 *
 * @throws ValidationException When validation fails and auto-validation is enabled
 *
 * @example
 * ```php
 * $validator = $user->validateData(['name' => 'John', 'email' => '[email protected]']);
 * if ($validator->fails()) {
 *     // Handle validation errors
 * }
 * ```
 */
public function validateData(
    array $data,
    string|array $groups = null,
    array $only = [],
    array $except = []
): Validator {
    // Implementation...
}

Code Quality Tools

# Check coding standards
composer cs-check

# Fix coding standards automatically
composer cs-fix

# Run static analysis
composer analyze

# Run all quality checks
composer quality

Configuration Files

.php-cs-fixer.php

<?php

return (new PhpCsFixer\Config())
    ->setRules([
        '@PSR12' => true,
        '@PHP81Migration' => true,
        'array_syntax' => ['syntax' => 'short'],
        'ordered_imports' => ['sort_algorithm' => 'alpha'],
        'no_unused_imports' => true,
        'trailing_comma_in_multiline' => true,
    ])
    ->setFinder(
        PhpCsFixer\Finder::create()
            ->in(__DIR__ . '/src')
            ->in(__DIR__ . '/tests')
    );

phpstan.neon

parameters:
    level: 8
    paths:
        - src
        - tests
    ignoreErrors:
        - '#Cannot call method \w+ on mixed#'

Testing

Test Structure

tests/
├── Feature/           # Integration tests
│   ├── PropertyAttributeTest.php
│   ├── ValidationTest.php
│   └── TransformationTest.php
├── Unit/              # Unit tests
│   ├── Attributes/
│   │   └── PropertyTest.php
│   ├── Traits/
│   │   └── HasArcPropertiesTest.php
│   └── Transformers/
│       └── StringTransformerTest.php
└── TestCase.php       # Base test class

Writing Tests

Unit Test Example

<?php

namespace Tests\Unit\Attributes;

use Grazulex\LaravelArc\Attributes\Property;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;

class PropertyTest extends TestCase
{
    public function test_property_can_be_created_with_required_parameters(): void
    {
        $property = new Property(type: 'string');

        $this->assertEquals('string', $property->type);
        $this->assertTrue($property->required);
        $this->assertNull($property->default);
    }

    public function test_property_throws_exception_for_empty_type(): void
    {
        $this->expectException(InvalidArgumentException::class);
        $this->expectExceptionMessage('Property type cannot be empty');

        new Property(type: '');
    }

    public function test_validation_rules_are_generated_correctly(): void
    {
        $property = new Property(
            type: 'string',
            required: true,
            rules: ['min:5', 'max:100']
        );

        $rules = $property->getValidationRules();

        $this->assertEquals(['required', 'string', 'min:5', 'max:100'], $rules);
    }
}

Feature Test Example

<?php

namespace Tests\Feature;

use Grazulex\LaravelArc\Attributes\Property;
use Grazulex\LaravelArc\Traits\HasArcProperties;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class PropertyAttributeTest extends TestCase
{
    use RefreshDatabase;

    public function test_model_with_property_attribute_validates_correctly(): void
    {
        $user = new TestUser();
        $validator = $user->validateData([
            'name' => 'John Doe',
            'email' => '[email protected]',
        ]);

        $this->assertFalse($validator->fails());
    }

    public function test_model_validation_fails_for_invalid_data(): void
    {
        $user = new TestUser();
        $validator = $user->validateData([
            'name' => '', // Required field
            'email' => 'invalid-email', // Invalid format
        ]);

        $this->assertTrue($validator->fails());
        $this->assertArrayHasKey('name', $validator->errors()->toArray());
        $this->assertArrayHasKey('email', $validator->errors()->toArray());
    }
}

class TestUser extends Model
{
    use HasArcProperties;

    #[Property(type: 'string', required: true, minLength: 2, maxLength: 100)]
    public string $name;

    #[Property(type: 'email', required: true)]
    public string $email;
}

Running Tests

# Run all tests
composer test

# Run specific test file
vendor/bin/phpunit tests/Unit/Attributes/PropertyTest.php

# Run tests with coverage
composer test-coverage

# Run only feature tests
vendor/bin/phpunit tests/Feature/

# Run only unit tests
vendor/bin/phpunit tests/Unit/

Test Coverage

We aim for 90%+ test coverage. Check coverage with:

composer test-coverage

This generates a coverage report in build/coverage/index.html.

Documentation

Types of Documentation

  1. Code Documentation - PHPDoc comments
  2. API Documentation - Method and class documentation
  3. User Guide - Usage examples and tutorials
  4. Wiki Pages - Comprehensive guides
  5. README - Quick start and overview

Documentation Standards

PHPDoc Comments

/**
 * Transforms a value through the configured transformation pipeline.
 *
 * This method applies a series of transformations to the input value
 * based on the property's transformation configuration. Transformations
 * are applied in the order they are defined.
 *
 * @param mixed $value The value to transform
 * @param array $transformers List of transformer names or callables
 * @return mixed The transformed value
 *
 * @throws TransformationException When a transformation fails
 *
 * @example
 * ```php
 * // Simple transformation
 * $result = $this->transform('  Hello World  ', ['trim', 'lowercase']);
 * // Result: 'hello world'
 *
 * // Complex transformation with parameters
 * $result = $this->transform(19.999, ['round:2', 'number_format:2']);
 * // Result: '20.00'
 * ```
 *
 * @see TransformationPipeline
 * @since 2.0.0
 */
public function transform(mixed $value, array $transformers): mixed
{
    // Implementation...
}

Wiki Documentation

When adding new features, update relevant wiki pages:

Building Documentation

# Generate API documentation
composer docs-build

# Serve documentation locally
composer docs-serve

# Check documentation links
composer docs-check

Pull Request Process

Before Submitting

  1. Update your fork:

    git fetch upstream
    git checkout main
    git merge upstream/main
    
  2. Create a feature branch:

    git checkout -b feature/your-feature-name
    
  3. Make your changes and commit:

    git add .
    git commit -m "Add feature: your feature description"
    
  4. Run quality checks:

    composer quality
    composer test
    
  5. Push to your fork:

    git push origin feature/your-feature-name
    

PR Guidelines

PR Title Format

Type: Brief description

# Examples:
feat: Add transformation pipeline system
fix: Resolve validation error handling issue
docs: Update installation guide
refactor: Improve property attribute system
test: Add coverage for enum support

PR Description Template

## Description
Brief description of what this PR does.

## Type of Change
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring

## Testing
- [ ] Tests pass locally
- [ ] Added tests for new functionality
- [ ] Updated existing tests if needed
- [ ] Test coverage maintained or improved

## Documentation
- [ ] Code is properly documented
- [ ] README updated if needed
- [ ] Wiki pages updated if needed
- [ ] CHANGELOG.md updated

## Checklist
- [ ] Code follows project style guidelines
- [ ] Self-review of code completed
- [ ] No merge conflicts
- [ ] Related issues are linked

## Related Issues
Fixes #123
Closes #456
Related to #789

## Screenshots (if applicable)
[Add screenshots here]

## Additional Notes
[Any additional information]

Review Process

  1. Automated Checks - CI/CD pipeline runs tests and quality checks
  2. Code Review - Maintainers review code, architecture, and tests
  3. Discussion - Address feedback and make requested changes
  4. Approval - Once approved, PR will be merged

Review Criteria

  • Functionality - Does it work as intended?
  • Code Quality - Follows coding standards and best practices?
  • Tests - Adequate test coverage and quality?
  • Documentation - Properly documented?
  • Performance - No performance regressions?
  • Backward Compatibility - Maintains backward compatibility?

Issue Reporting

Bug Reports

Use the bug report template:

## Bug Description
A clear and concise description of what the bug is.

## Steps to Reproduce
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

## Expected Behavior
A clear and concise description of what you expected to happen.

## Actual Behavior
A clear and concise description of what actually happened.

## Environment
- Laravel Arc version: [e.g. 2.0.1]
- PHP version: [e.g. 8.1.0]
- Laravel version: [e.g. 10.0.0]
- Operating System: [e.g. Ubuntu 22.04]

## Code Examples
```php
// Minimal code example to reproduce the issue

Error Messages

Paste any error messages here

Additional Context

Add any other context about the problem here.


### Security Issues

**Do not report security vulnerabilities publicly.** Instead:

1. Email: [email protected]
2. Include "Laravel Arc Security" in the subject
3. Provide detailed information about the vulnerability
4. Allow reasonable time for the issue to be addressed

## Feature Requests

### Feature Request Template

```markdown
## Feature Description
A clear and concise description of the feature you'd like to see.

## Problem/Use Case
Describe the problem this feature would solve or the use case it addresses.

## Proposed Solution
Describe how you envision this feature working.

## Alternative Solutions
Describe any alternative solutions or features you've considered.

## Examples
```php
// Code examples showing how the feature would be used

Additional Context

Add any other context, screenshots, or examples about the feature request.


### Feature Development Process

1. **Discussion** - Community discusses the feature
2. **Approval** - Maintainers approve the feature for development
3. **Design** - Technical design and API decisions
4. **Implementation** - Development of the feature
5. **Testing** - Comprehensive testing
6. **Documentation** - User and developer documentation
7. **Release** - Feature included in next release

## Community

### Communication Channels

- **GitHub Issues** - Bug reports and feature requests
- **GitHub Discussions** - General questions and community discussion
- **Twitter** - Follow [@grazulex](https://twitter.com/grazulex) for updates
- **Email** - [email protected] for business inquiries

### Community Guidelines

1. **Be Respectful** - Treat everyone with respect and kindness
2. **Be Helpful** - Help others when you can
3. **Be Patient** - Maintainers and contributors are often volunteers
4. **Search First** - Check existing issues and discussions before posting
5. **Provide Context** - Give enough information for others to help
6. **Follow Templates** - Use issue and PR templates when provided

### Recognition

We recognize contributors in several ways:

- **Contributors List** - Listed in README and releases
- **Changelog** - Credited in changelog entries
- **Social Media** - Recognition on Twitter and other platforms
- **Special Badges** - GitHub contributor badges

## Development Tips

### Debugging

```php
// Enable debug mode in tests
putenv('APP_DEBUG=true');

// Use dump/dd for debugging
dump($variable);
dd($complexVariable);

// Enable Arc debugging
$model->enableArcDebug();
$log = $model->getDebugLog();

Performance Testing

# Run performance benchmarks
composer benchmark

# Profile memory usage
composer profile-memory

# Test with large datasets
composer test-performance

IDE Setup

PhpStorm Configuration

  1. Code Style: Import .editorconfig
  2. Inspections: Enable PHP 8.1+ inspections
  3. Composer: Enable Composer integration
  4. PHPUnit: Configure PHPUnit test runner

VS Code Extensions

  • PHP Intelephense - PHP language support
  • PHPUnit - Test runner integration
  • EditorConfig - Code style consistency
  • GitLens - Git integration

Release Process

Semantic Versioning

We follow Semantic Versioning:

  • MAJOR (v2.0.0) - Breaking changes
  • MINOR (v2.1.0) - New features, backward compatible
  • PATCH (v2.1.1) - Bug fixes, backward compatible

Release Checklist

# 1. Update version numbers
# 2. Update CHANGELOG.md
# 3. Update documentation
# 4. Run full test suite
# 5. Create release notes
# 6. Tag release
# 7. Publish to Packagist

Thank You!

Thank you for contributing to Laravel Arc! Your contributions help make this package better for everyone. Whether you're reporting bugs, suggesting features, improving documentation, or submitting code, every contribution is valuable.

Happy coding! 🚀


Questions? Feel free to ask in GitHub Discussions or open an issue.