Skip to content

Latest commit

 

History

History
188 lines (138 loc) · 5.07 KB

File metadata and controls

188 lines (138 loc) · 5.07 KB

OpenEMR Development Guide

Project Structure

/src/              - Modern PSR-4 code (OpenEMR\ namespace)
/library/          - Legacy procedural PHP code
/interface/        - Web UI controllers and templates
/templates/        - Smarty/Twig templates
/tests/            - Test suite (unit, e2e, api, services)
/sql/              - Database schema and migrations
/public/           - Static assets
/docker/           - Docker configurations
/modules/          - Custom and third-party modules

Technology Stack

  • PHP: 8.2+ required
  • Backend: Laminas MVC, Symfony components
  • Templates: Twig 3.x (modern), Smarty 4.5 (legacy)
  • Frontend: Angular 1.8, jQuery 3.7, Bootstrap 4.6
  • Build: Gulp 4, SASS
  • Database: MySQL via ADODB wrapper
  • Testing: PHPUnit 11, Jest 29

Local Development

See CONTRIBUTING.md for full setup instructions. Quick start:

cd docker/development-easy
docker compose up --detach --wait

Testing

Tests run inside Docker via devtools. Run from docker/development-easy/:

# Run all tests
docker compose exec openemr /root/devtools clean-sweep-tests

# Individual test suites
docker compose exec openemr /root/devtools unit-test
docker compose exec openemr /root/devtools api-test
docker compose exec openemr /root/devtools e2e-test
docker compose exec openemr /root/devtools services-test

# View PHP error log
docker compose exec openemr /root/devtools php-log

Tip: Install openemr-cmd for shorter commands (e.g., openemr-cmd ut for unit tests) from any directory.

Isolated tests (no Docker required)

Isolated tests run on the host without a database or Docker:

composer phpunit-isolated        # Run all isolated tests

Twig template tests

Twig templates have two layers of testing (both isolated):

  • Compilation tests verify every .twig file parses and references valid filters/functions/tests. These run automatically over all templates.
  • Render tests render specific templates with known parameters and compare the full HTML output to expected fixture files in tests/Tests/Isolated/Common/Twig/fixtures/render/.

When modifying a Twig template that has render test coverage, update the fixture files:

composer update-twig-fixtures    # Regenerate fixture files

Review the diff before committing. See the fixtures README for details on adding new test cases.

Code Quality

These run on the host (requires local PHP/Node):

# Run all PHP quality checks (phpcs, phpstan, rector)
composer code-quality

# Individual checks (composer scripts handle memory limits)
composer phpstan          # Static analysis
composer phpcs            # PHP code style check
composer phpcbf           # PHP code style auto-fix
composer rector-check     # Code modernization (dry-run)

# JavaScript/CSS
npm run lint:js           # ESLint check
npm run lint:js-fix       # ESLint auto-fix
npm run stylelint         # CSS/SCSS lint

Build Commands

npm run build        # Production build
npm run dev          # Development with file watching
npm run gulp-build   # Build only (no watch)

Coding Standards

  • Indentation: 4 spaces
  • Line endings: LF (Unix)
  • No strict_types: Project doesn't use declare(strict_types=1)
  • Namespaces: PSR-4 with OpenEMR\ prefix for /src/
  • New code goes in /src/, legacy helpers in /library/

Commit Messages

Follow Conventional Commits:

<type>(<scope>): <description>

Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert

Examples:

  • feat(api): add PATCH support for patient resource
  • fix(calendar): correct date parsing for recurring events
  • chore(deps): bump monolog/monolog to 3.10.0

Service Layer Pattern

New services should extend BaseService:

namespace OpenEMR\Services;

class ExampleService extends BaseService
{
    public const TABLE_NAME = "table_name";

    public function __construct()
    {
        parent::__construct(self::TABLE_NAME);
    }
}

File Headers

When modifying PHP files, ensure proper docblock:

/**
 * Brief description
 *
 * @package   OpenEMR
 * @link      https://www.open-emr.org
 * @author    Your Name <your@email.com>
 * @copyright Copyright (c) YEAR Your Name or Organization
 * @license   https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
 */

Preserve existing authors/copyrights when editing files.

Common Gotchas

  • Multiple template engines: check extension (.twig, .html, .php)
  • Event system uses Symfony EventDispatcher
  • Pre-commit hooks available via .pre-commit-config.yaml

Key Documentation

  • CONTRIBUTING.md - Contributing guidelines
  • API_README.md - REST API docs
  • FHIR_README.md - FHIR implementation
  • tests/Tests/README.md - Testing guide