Contributing Guide

Thank you for considering contributing to the OpenCart Migration Tool!

Table of contents

  1. Code of Conduct
    1. Our Standards
  2. How to Contribute
    1. Reporting Bugs
    2. Suggesting Features
  3. Development Setup
    1. Prerequisites
    2. Setup Instructions
    3. Development Environment
  4. Coding Standards
    1. PHP Standards (PSR-12)
    2. Documentation Standards
    3. File Organization
  5. Git Workflow
    1. Commit Message Convention
    2. Branch Naming
    3. Pull Request Process
  6. Adding New Features
    1. Adding a Migration Step
  7. Testing
    1. Manual Testing
    2. Writing Tests
  8. Code Review Guidelines
    1. For Contributors
    2. For Reviewers
  9. Documentation
    1. Updating Documentation
  10. Release Process
    1. Version Numbering
    2. Creating a Release
  11. [1.1.0] - 2025-10-15
    1. Added
    2. Fixed
  12. Community
    1. Getting Help
    2. Recognition
  13. License
  14. Questions?

Code of Conduct

This project follows a Code of Conduct. By participating, you agree to uphold professional standards.

Our Standards

✅ Positive Behaviors:

  • Using welcoming and inclusive language
  • Being respectful of differing viewpoints
  • Gracefully accepting constructive criticism
  • Focusing on what’s best for the community
  • Showing empathy towards others

❌ Unacceptable Behaviors:

  • Trolling, insulting comments, personal attacks
  • Public or private harassment
  • Publishing others’ private information
  • Other unprofessional conduct

How to Contribute

Reporting Bugs

Before reporting:

  • Search existing issues
  • Check if it’s already fixed in latest version
  • Verify it’s not a configuration issue

Bug Report Template:

### Environment
- OpenCart 3: 3.0.3.8
- OpenCart 4: 4.0.2.3
- Tool Version: 1.0.0
- PHP: 8.1.2
- MySQL: 8.0.32
- OS: Ubuntu 22.04

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

### Expected Behavior
What should happen

### Actual Behavior
What actually happens

### Error Logs

Paste logs here

Suggesting Features

Feature Request Template:

### Problem Statement
Describe the problem this feature would solve

### Proposed Solution
How you envision the feature working

### Use Case
Who would benefit and how

### Alternatives Considered
Other solutions you've thought about

Development Setup

Prerequisites

  • PHP 7.4+
  • MySQL 5.7+ or MariaDB 10.2+
  • Git
  • Test OpenCart 3 & 4 installations

Setup Instructions

# 1. Fork repository on GitHub

# 2. Clone your fork
git clone https://github.com/YOUR_USERNAME/opencart-migration-tool.git
cd opencart-migration-tool

# 3. Add upstream remote
git remote add upstream https://github.com/kunwar-shah/opencart-migration-tool.git

# 4. Create development config
cp config/config.example.php config/config.php
# Edit with test database credentials

# 5. Create feature branch
git checkout -b feature/your-feature-name

Development Environment

Recommended: Docker

# docker-compose.dev.yml
version: '3.8'
services:
  migration-tool:
    build: .
    volumes:
      - ./:/var/www/html
    ports:
      - "8080:80"
    environment:
      - PHP_DISPLAY_ERRORS=On

  mysql-oc3:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: test
      MYSQL_DATABASE: opencart3_test
    ports:
      - "3306:3306"

  mysql-oc4:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: test
      MYSQL_DATABASE: opencart4_test
    ports:
      - "3307:3306"
docker-compose -f docker-compose.dev.yml up -d

Coding Standards

PHP Standards (PSR-12)

<?php

// 1. Strict types
declare(strict_types=1);

// 2. Class naming: PascalCase
class ProductMigrationStep extends CleanAutomaticMigrationStep
{
    // 3. Constants: UPPER_CASE
    private const DEFAULT_BATCH_SIZE = 1000;

    // 4. Properties: camelCase
    private DatabaseInterface $sourceDb;
    private array $options = [];

    // 5. Methods: camelCase with type hints
    public function migrateData(array $options): array
    {
        // 6. Variables: camelCase
        $sourceDatabase = $this->getSourceDb();

        // 7. Early returns to avoid nesting
        if (!$this->isReady()) {
            return ['success' => false];
        }

        // 8. Keep methods small (< 50 lines)
        return $this->processRecords();
    }

    // 9. Private methods for complex logic
    private function processRecords(): array
    {
        // Implementation
    }
}

Documentation Standards

/**
 * Migrate orders from OpenCart 3 to OpenCart 4
 *
 * This method handles complete order migration including:
 * - Order details and totals
 * - Order products with options
 * - Order history and status tracking
 * - Customer and payment information
 *
 * @param array $options Migration options
 *     - 'batch_size' (int): Records per batch
 *     - 'skip_validation' (bool): Skip pre-validation
 * @return array Migration results
 *     - 'success' (bool): Overall success status
 *     - 'processed' (int): Total records processed
 *     - 'errors' (array): List of errors if any
 * @throws MigrationException If critical error occurs
 * @since 1.0.0
 */
public function migrateOrders(array $options = []): array
{
    // Implementation
}

File Organization

src/
├── Controllers/          # Request handlers
│   ├── Automatic/       # Automated migrations
│   └── Manual/          # Manual steps
├── Migration/
│   ├── Steps/           # Migration implementations
│   └── Validations/     # Validation logic
├── Services/            # Business logic
├── Utils/               # Table definitions & helpers
└── Traits/              # Reusable functionality

Git Workflow

Commit Message Convention

Follow Conventional Commits:

<type>(<scope>): <subject>

<body>

<footer>

Types:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • style: Formatting (no code change)
  • refactor: Code refactoring
  • test: Adding tests
  • chore: Maintenance tasks

Examples:

feat(products): add support for product bundles

- Added bundle detection logic
- Implemented bundle item migration
- Added validation for bundle relationships

Closes #123

---

fix(images): resolve path issues on Windows

Image transfer was using Unix paths which failed on Windows.
Updated to use OS-independent path resolution.

Fixes #456

---

docs(api): update authentication examples

Updated API docs with new auth flow examples

Branch Naming

feature/add-bundle-support
fix/image-path-windows
docs/update-api-guide
refactor/cleanup-validation
test/add-product-tests

Pull Request Process

  1. Update your fork:
    git fetch upstream
    git rebase upstream/main
    
  2. Run tests:
    php tests/run_all_tests.php
    
  3. Push to your fork:
    git push origin feature/your-feature-name
    
  4. Create Pull Request:
    • Use clear, descriptive title
    • Reference related issues (#123)
    • Describe changes in detail
    • Include screenshots for UI changes

Adding New Features

Adding a Migration Step

1. Create Table Dictionary:

// src/Utils/BundlesTables.php
class BundlesTables extends SimpleTableDataDictionary
{
    protected static function defineTablesConfiguration(): array
    {
        return [
            'product_bundle' => [
                'primary_key' => 'bundle_id',
                'oc3_columns' => ['bundle_id', 'product_id', 'name'],
                'oc4_columns' => ['bundle_id', 'product_id', 'name', 'status'],
                'transformations' => [
                    'status' => function($value, $record) {
                        return 1; // Default enabled
                    },
                    'product_id' => 'ID_MAPPING:product'
                ],
                'migration_strategy' => 'migrate_all_data',
                'depends_on' => ['products']
            ]
        ];
    }
}

2. Create Migration Step:

// src/Migration/Steps/BundlesMigrationStep.php
class BundlesMigrationStep extends CleanAutomaticMigrationStep
{
    public function __construct($sourceDb, $targetDb, $tableDataClassName = 'BundlesTables')
    {
        if ($tableDataClassName !== 'BundlesTables') {
            throw new Exception("Must use BundlesTables class");
        }
        parent::__construct($sourceDb, $targetDb, $tableDataClassName);
    }
}

3. Create Controller:

// src/Controllers/Automatic/BundlesController.php
class BundlesController extends BaseStepController
{
    protected function setStepId()
    {
        $this->stepId = 'bundles';
    }

    protected function initializeStep()
    {
        $this->stepInstance = new BundlesMigrationStep(
            $this->sourceDb,
            $this->targetDb
        );
    }
}

4. Add Routes:

// src/Routes/BundlesRoutes.php
class BundlesRoutes
{
    public static function bootstrap(Router $router)
    {
        $router->get('/bundles', 'BundlesController', 'index');
        $router->post('/bundles/migrate', 'BundlesController', 'migrate');
        $router->post('/bundles/reset', 'BundlesController', 'reset');
    }
}

5. Add Database Entry:

The step will be auto-created on first access via database/init.php migration system.


Testing

Manual Testing

# Test specific step
php tests/test_bundles.php

# Test with small dataset
# Modify config to use test database with 100 records

Writing Tests

// tests/test_bundles.php
<?php

require_once __DIR__ . '/../src/autoload.php';

class BundlesTest
{
    public function testMigration()
    {
        // Setup
        $sourceDb = getSourceDatabase();
        $targetDb = getTargetDatabase();

        // Execute
        $step = new BundlesMigrationStep($sourceDb, $targetDb);
        $result = $step->migrate();

        // Assert
        assert($result['success'] === true, 'Migration should succeed');
        assert($result['processed'] > 0, 'Should process records');

        // Validate
        $sourceCount = $sourceDb->fetchColumn("SELECT COUNT(*) FROM oc_product_bundle");
        $targetCount = $targetDb->fetchColumn("SELECT COUNT(*) FROM oc_product_bundle");
        assert($sourceCount === $targetCount, 'Record counts should match');

        echo "✓ Bundles migration test passed\n";
    }
}

$test = new BundlesTest();
$test->testMigration();

Code Review Guidelines

For Contributors

  • ✅ Self-review code before submitting
  • ✅ Add comments for complex logic
  • ✅ Update documentation
  • ✅ Test thoroughly
  • ✅ Follow coding standards

For Reviewers

  • ✅ Check code quality and standards
  • ✅ Verify functionality works
  • ✅ Ensure proper error handling
  • ✅ Validate test coverage
  • ✅ Review security implications

Documentation

Updating Documentation

Code Documentation:

// Always document public methods
// Use proper PHPDoc format
// Explain WHY, not just WHAT

User Documentation:

  • Update README.md for new features
  • Add to appropriate guide (Installation, Features, etc.)
  • Include code examples
  • Add screenshots for UI changes

API Documentation:

  • Update API reference for new endpoints
  • Include request/response examples
  • Document error codes

Release Process

Version Numbering

We follow Semantic Versioning:

  • MAJOR (1.0.0): Breaking changes
  • MINOR (1.1.0): New features, backward compatible
  • PATCH (1.0.1): Bug fixes

Creating a Release

  1. Update version:
    // config/config.example.php
    'version' => '1.1.0',
    
  2. Update CHANGELOG.md: ```markdown

    [1.1.0] - 2025-10-15

Added

  • Product bundles migration
  • Bulk product editing support

Fixed

  • Image path issues on Windows
  • Memory leak in large datasets ```
  1. Create release:
    git tag -a v1.1.0 -m "Release v1.1.0"
    git push origin v1.1.0
    
  2. Create GitHub Release:
    • Go to GitHub Releases
    • Create new release from tag
    • Copy changelog content
    • Attach any binaries/assets

Community

Getting Help

Development Questions:

  • Open a GitHub Discussion
  • Check existing discussions first
  • Be specific and provide context

Bug Reports:

  • Use GitHub Issues
  • Follow bug report template
  • Include all requested information

Recognition

Contributors are recognized in:

  • README.md contributors section
  • Release notes
  • GitHub contributor graphs

License

By contributing, you agree that your contributions will be licensed under the MIT License.


Questions?

Thank you for contributing! 🙏


Back to top

Copyright © 2025 Cybernamix AI. Made for the OpenCart community with ❤️