Contributing Guide
Thank you for considering contributing to the OpenCart Migration Tool!
Table of contents
- Code of Conduct
 - How to Contribute
 - Development Setup
 - Coding Standards
 - Git Workflow
 - Adding New Features
 - Testing
 - Code Review Guidelines
 - Documentation
 - Release Process
 - [1.1.0] - 2025-10-15
 - Community
 - License
 - 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 featurefix: Bug fixdocs: Documentation changesstyle: Formatting (no code change)refactor: Code refactoringtest: Adding testschore: 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
- Update your fork:
    
git fetch upstream git rebase upstream/main - Run tests:
    
php tests/run_all_tests.php - Push to your fork:
    
git push origin feature/your-feature-name - 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
- Update version:
    
// config/config.example.php 'version' => '1.1.0', - 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 ```
 
- Create release:
    
git tag -a v1.1.0 -m "Release v1.1.0" git push origin v1.1.0 - 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?
- General questions: GitHub Discussions
 - Bug reports: GitHub Issues
 - Feature requests: GitHub Issues
 
Thank you for contributing! 🙏