Skip to content

Contributing Guide

Thank you for considering contributing to Data Helpers! This guide will help you get started.

  • PHP 8.2 or higher
  • Composer
  • Git
  • Docker & Docker Compose (recommended)
  • Task (optional but recommended)
  1. Fork the repository on GitHub

  2. Clone your fork:

    Terminal window
    git clone git@github.com:YOUR_USERNAME/data-helpers.git
    cd data-helpers
  3. Setup development environment:

    Terminal window
    task dev:setup

    Or manually:

    Terminal window
    docker-compose up -d --build
    docker exec -it data-helpers-php84 composer install
  4. Verify installation:

    Terminal window
    task test:run

See Development Setup for detailed instructions.

Terminal window
git checkout -b feature/my-feature

Branch naming conventions:

  • feature/ - New features
  • fix/ - Bug fixes
  • docs/ - Documentation changes
  • refactor/ - Code refactoring
  • test/ - Test improvements
  • Write clean, readable code
  • Follow PSR-12 coding standards
  • Add tests for new features
  • Update documentation if needed
Terminal window
# Fix code style
task quality:ecs:fix
# Run static analysis
task quality:phpstan
# Run tests
task test:run
# Or run all checks at once
task dev:pre-commit

Use Conventional Commits:

Terminal window
git add .
git commit -m "feat: add new feature"

Commit types:

  • feat: - New feature
  • fix: - Bug fix
  • docs: - Documentation changes
  • style: - Code style changes (formatting)
  • refactor: - Code refactoring
  • test: - Test changes
  • chore: - Build/tooling changes
Terminal window
git push origin feature/my-feature

Then create a Pull Request on GitHub.

We use Pest for testing. All contributions must include tests.

Terminal window
# Run all tests
task test:run
# Run unit tests only
task test:unit
# Run E2E tests only
task test:e2e
# Run specific test file
task test:unit -- tests/Unit/DataMapper/DataMapperTest.php
# Run tests with filter
task test:unit -- --filter="maps nested key"
# Run with coverage (requires Xdebug)
task test:coverage

Place tests in the appropriate directory:

  • tests/Unit/ - Unit tests
  • tests-e2e/ - End-to-end tests

Use descriptive test names:

test('maps nested data correctly', function (): void {
$source = ['user' => ['name' => 'Alice']];
$mapping = ['name' => '{{ user.name }}'];
$result = DataMapper::from($source)
->template($mapping)
->map()
->getTarget();
expect($result)->toBe(['name' => 'Alice']);
});
  • ✅ Test one thing per test
  • ✅ Use descriptive test names
  • ✅ Follow AAA pattern (Arrange, Act, Assert)
  • ✅ Test edge cases and error conditions
  • ✅ Aim for high code coverage
  • ✅ Keep tests fast and isolated

We follow PSR-12 coding standards and use PHP Easy Coding Standard (ECS).

Terminal window
# Check code style
task quality:ecs
# Fix code style automatically
task quality:ecs:fix
  • Use 4 spaces for indentation
  • Use type hints for all parameters and return types
  • Use strict types: declare(strict_types=1);
  • Use readonly properties where possible
  • Document complex logic with comments
  • Keep methods short and focused

We use PHPStan at Level 9 for static analysis.

Terminal window
# Run PHPStan
task quality:phpstan
# Generate baseline (if needed)
task quality:phpstan:baseline
  • Fix all PHPStan errors before submitting PR
  • Don’t add to baseline unless absolutely necessary
  • Use proper type hints to avoid PHPStan errors
  • Use @phpstan-ignore-next-line sparingly
  • Add PHPDoc blocks for all public methods
  • Document parameters and return types
  • Include usage examples for complex features
  • Keep documentation up to date

Example:

/**
* Maps source data to target structure using template expressions.
*
* @param array<string, mixed> $source Source data
* @param array<string, mixed> $source Source data
* @param array<string, string> $mapping Mapping configuration
* @return array<string, mixed> Mapped result
*
* @example
* $result = DataMapper::from(['user' => ['name' => 'Alice']])
* ->template(['name' => '{{ user.name }}'])
* ->map()
* ->getTarget();
*/
public static function map(array $source, array $target, array $mapping): array
{
// Implementation
}

If your contribution adds new features:

  1. Update relevant documentation pages in documentation/src/content/docs/
  2. Add code examples
  3. Update the changelog
  • ✅ All tests pass: task test:run
  • ✅ Code style is correct: task quality:ecs:fix
  • ✅ PHPStan passes: task quality:phpstan
  • ✅ Documentation is updated
  • ✅ Changelog is updated (if applicable)
  1. Title: Use conventional commit format

    • Example: feat: add support for nested wildcards
  2. Description: Include:

    • What changes were made
    • Why the changes were needed
    • How to test the changes
    • Related issues (if any)
  3. Size: Keep PRs focused and reasonably sized

    • Large PRs are harder to review
    • Consider splitting into multiple PRs
  4. Tests: Include tests for all changes

    • New features must have tests
    • Bug fixes should include regression tests
  1. Automated checks will run (tests, code style, PHPStan)
  2. Maintainers will review your code
  3. Address any feedback or requested changes
  4. Once approved, your PR will be merged

Include:

  • PHP version
  • Framework version (Laravel/Symfony)
  • Steps to reproduce
  • Expected behavior
  • Actual behavior
  • Code example (if possible)

Include:

  • Use case description
  • Proposed solution
  • Alternative solutions considered
  • Code examples (if applicable)
  • Be respectful and inclusive
  • Welcome newcomers
  • Focus on constructive feedback
  • Assume good intentions

Thank you for contributing! 🎉