OpenEMR System Architecture

From OpenEMR Project Wiki

OpenEMR System Architecture

Introduction

This is a compilation of notes that will be of interest to developers who wish to become involved with OpenEMR, or to users who are interested in technical aspects of the project. The initial creation of this document was generously sponsored by Sam Rajan, IPPF, and has since been updated by volunteer contributors.

Other Resources

Online Resources

The http://www.open-emr.org/ is the home page for the project, which includes a manual, demo site, forums and a documentation wiki.

Resources included within the OpenEMR package

  • Current:
    • Documentation/INSTALL provides installation and upgrading instructions
    • README.md provides a general description of OpenEMR
    • Documentation/Complete_Vaccine_Listing.pdf A standard listing of vaccinations.
    • de_identification_readme.txt Instructions for setting up de- identification of patient data.
    • Documentation/Emergency_User_README.txt Describes how to use the Emergency Login feature
    • Documentation/Payment_Posting_ZHH.pdf Description of how to use the billing module.
    • Documentation/README.phpgacl discusses phpGACL, which OpenEMR uses for access control.
    • Documentation/README-Log-Backup.txt How to set up a log rotation in OpenEMR.
    • Documentation/SystemArchitecture.txt provides a link to this wiki page.
  • Outdated:
    • Documentation/IPPF_Guides directory contains some nice visual documentation.(outdated)
    • Documentation/User_Guide directory contains the OpenEMR 4.0 User Manual (HTML version). Note this is now considered outdated since OpenEMR 4.1+ and above maintain the User Manual on the wiki.(outdated and removed from package 7/16/2016)
    • Documentation/3rd_Party_Form_API.txt describes the interface as originally designed for encounter forms.(outdated and removed from package 7/16/2016)
    • Documentation/Database.pdf has some information about the original database design.(outdated and removed from package 7/16/2016)
    • Documentation/FAQ is also quite old and doesn't cover much.(outdated and removed from package 7/16/2016)
    • Documentation/Functions.pdf describes interfaces implemented by some modules in the library directory.(outdated and removed from package 7/16/2016)
    • Documentation/HISTORY.txt is a brief summary of OpenEMR versions thru about 2002.(outdated and removed from package 7/16/2016)
    • Documentation/modifications.txt is a brief list of the modules that must change in order to add data items to patient demographics.(outdated and removed from package 7/16/2016)
    • Documentation/NoIP.txt is an obsolete list of broken links.(outdated and removed from package 7/16/2016)
    • OpenEMR_Backend_Spec.txt is a description of some interfaces implemented in the library directory.(outdated and removed from package 7/16/2016)
    • Documentation/OpenEMR-Win2003-server-install-new.html briefly discusses installation of OpenEMR on Windows 2003.(outdated and removed from package 7/16/2016)
    • Documentation/Package.txt has some old notes about creating an OpenEMR distribution release.(outdated and removed from package 7/16/2016)
    • Documentation/Readme.txt seems to be mostly a disclaimer regarding HIPAA compliance.(outdated and removed from package 7/16/2016)

Customization of OpenEMR

  • Most configuration happens within OpenEMR at Administration->Globals.
  • If you code your encounters using methods other than CPT4, ICD9 and HCPCS then you will want to customize this at Administration->Lists->'Code Types' and also load your custom codes into the "codes" table.
  • There are also configuration settings within OpenEMR at Administration->Files:
    • config.php
    • clickoptions.txt - May be customized to contain your preferred selections for issue titles (names of medical problems, allergies, etc.). Needs to be done concurrently with manual editing of the library/lists.inc file.
    • statement.inc.php - This is your template for patient statements or collection letters. It must be customized for your practice.
  • custom/export_demographics.php - A placeholder for a script to export patient demographics to another system. export_labworks.php and export_xml.php are examples of such scripts.
  • custom/refer.php - A placeholder for a referral management system. One option is to subscribe to refercare.org and then replace this script with the provided refercare.php script.
  • interface/billing/billing_process.php - Customize X12 partner settings.
  • library/lists.inc - Customize Issue Types.
  • library/classes/class.ezpdf.php - Customize some general pdf settings.

Calendar Architecture

From some old notes when studying the PostNuke calendar design:

  • openemr_postcalendar_events is referenced in:
    • interface/main/calendar/modules/PostCalendar/pnuser.php
    • interface/main/calendar/modules/PostCalendar/pnuserapi.php
    • interface/main/calendar/modules/PostCalendar/pninit.php
    • interface/main/calendar/modules/PostCalendar/common.api.php
    • interface/main/calendar/modules/PostCalendar/pntables.php
    • interface/main/calendar/modules/PostCalendar/pnadmin.php
    • interface/main/calendar/modules/PostCalendar/pnadminapi.php
    • interface/main/calendar/modules/PostCalendar/plugins/function.pc_filter.php
    • interface/reports/appt_encounter_report.php
  • pnuser.php: function postcalendar_user_submit($args): invoked on event submission, at end writes success message, clears form vars, calls buildSubmitForm.
  • common.api.php: function postcalendar_userapi_buildSubmitForm($args,$admin=false) creates a ton of output which is then written via the submit.html template.
  • submit.html: is the template used to generate the redisplayed submit form.
  • small_navigation.html: included to generate the date selector and view buttons.
  • function.pc_date_select.php: builds date selector with jump button, should maybe enhance this to accept a specified default date, or else change the PostCalendar current working date from submit.html.
  • function.pc_url.php: builds the urls for the links in the view buttons.


OpenEMR Dependencies

Ubuntu 16.04 and Mint 18 and Debian 9 and greater versions (PHP7) (With MySQL or MariaDB)

This will use default php of the OS, which is php7. Note php-mbstring and php-zip was added for php7 (for some reason, these are not automatically included as it was with php5). Also have to set a mysql root password; do not use a blank mysql root password or MySQL will be broken. Here is list of required dependencies (see below for how to install these quickly from the commandline):
  • apache2
  • mysql-server (or if using mariadb, then use 'mariadb-server' instead)
  • libapache2-mod-php
  • libdate-calc-perl
  • libdbd-mysql-perl
  • libdbi-perl
  • libhtml-parser-perl
  • libtiff-tools
  • libwww-mechanize-perl
  • libxml-parser-perl
  • php
  • php-mysql
  • php-cli
  • php-gd
  • php-xsl
  • php-curl
  • php-mcrypt
  • php-soap
  • php-json
  • php-gettext
  • imagemagick
  • php-mbstring
  • php-zip


Commandline for when using MySQL:
sudo apt-get install apache2 mysql-server libapache2-mod-php libdate-calc-perl libdbd-mysql-perl libdbi-perl libhtml-parser-perl libtiff-tools libwww-mechanize-perl libxml-parser-perl php php-mysql php-cli php-gd php-xsl php-curl php-mcrypt php-soap php-json php-gettext imagemagick php-mbstring php-zip

(You have to set a mysql password or else MySQL will not work! Again, if you set the password to be empty, then mysql will not work.)

sudo service apache2 restart


Commandline for when using MariaDB:
sudo apt-get install apache2 mariadb-server libapache2-mod-php libdate-calc-perl libdbd-mysql-perl libdbi-perl libhtml-parser-perl libtiff-tools libwww-mechanize-perl libxml-parser-perl php php-mysql php-cli php-gd php-xsl php-curl php-mcrypt php-soap php-json php-gettext imagemagick php-mbstring php-zip
sudo service apache2 restart

(If you were unable to set the MariaDB root password during the installation, then need to follow the steps below. If you were able to set the MariaDB root password during the installation(do not set it to blank or else it will not work), then skip below to the 'sudo service apache2 restart' command.)

sudo mysql -u root
use mysql;
update user set plugin='' where User='root';
flush privileges;
\q
mysql_secure_installation

(Set a mariaDB root password and select all the default settings)

sudo service apache2 restart
sudo service mysql restart



Ubuntu, Mint and Debian (PHP 5) (With MySQL or MariaDB)

Here is list of required dependencies (see below for how to install these quickly from the commandline):
  • apache2
  • mysql-server (or if using mariadb, then use 'mariadb-server' instead)
  • libapache2-mod-php5
  • libdate-calc-perl
  • libdbd-mysql-perl
  • libdbi-perl
  • libhtml-parser-perl
  • libtiff-tools
  • libwww-mechanize-perl
  • libxml-parser-perl
  • php5
  • php5-mysql
  • php5-cli
  • php5-gd
  • php5-xsl
  • php5-curl
  • php5-mcrypt
  • php-soap
  • php5-json
  • php-gettext
  • imagemagick


For the commandline instructions below. If using Debian, then remove the 'sudo' from below commands; and before entering in the commands, type 'su' and then the return key and then enter the root password to gain root permission.


Commandline for when using MySQL:
sudo apt-get install apache2 mysql-server libapache2-mod-php5 libdate-calc-perl libdbd-mysql-perl libdbi-perl libhtml-parser-perl libtiff-tools libwww-mechanize-perl libxml-parser-perl php5 php5-mysql php5-cli php5-gd php5-xsl php5-curl php5-mcrypt php-soap php5-json php-gettext imagemagick
sudo service apache2 restart


Commandline for when using MariaDB:
sudo apt-get install apache2 mariadb-server libapache2-mod-php5 libdate-calc-perl libdbd-mysql-perl libdbi-perl libhtml-parser-perl libtiff-tools libwww-mechanize-perl libxml-parser-perl php5 php5-mysql php5-cli php5-gd php5-xsl php5-curl php5-mcrypt php-soap php5-json php-gettext imagemagick
sudo service apache2 restart

(If you were unable to set the MariaDB root password during the installation, then need to follow the steps below. If you were able to set the MariaDB root password during the installation, then skip below to the 'sudo service apache2 restart' command.)

sudo mysql -u root
use mysql;
update user set plugin='' where User='root';
flush privileges;
\q
mysql_secure_installation

(Set a mariaDB root password and select all the default settings)

sudo service apache2 restart
sudo service mysql restart



Ubuntu, Mint and Debian (PHP 7) (With MySQL or MariaDB)

Better to instead use the instruction set here: Ubuntu 16.04 and Mint 18 and Debian 9 and greater versions (PHP7) (With MySQL or MariaDB)
This only works in distributions that offer php7. Note need to create a mysql root password during the mysql install or it will be broken. Here is list of required dependencies (see below for how to install these quickly from the commandline):
  • apache2
  • mysql-server (or if using mariadb, then use 'mariadb-server' instead)
  • libapache2-mod-php7.0
  • libdate-calc-perl
  • libdbd-mysql-perl
  • libdbi-perl
  • libhtml-parser-perl
  • libtiff-tools
  • libwww-mechanize-perl
  • libxml-parser-perl
  • php7.0
  • php7.0-mysql
  • php7.0-cli
  • php7.0-gd
  • php7.0-xsl
  • php7.0-curl
  • php7.0-mcrypt
  • php-soap
  • php7.0-json
  • php-gettext
  • imagemagick
  • php7.0-mbstring
  • php7.0-zip


For the commandline instructions below. If using Debian, then remove the 'sudo' from below commands; and before entering in the commands, type 'su' and then the return key and then enter the root password to gain root permission.


Commandline for when using MySQL:
sudo apt-get install apache2 mysql-server libapache2-mod-php7.0 libdate-calc-perl libdbd-mysql-perl libdbi-perl libhtml-parser-perl libtiff-tools libwww-mechanize-perl libxml-parser-perl php7.0 php7.0-mysql php7.0-cli php7.0-gd php7.0-xsl php7.0-curl php7.0-mcrypt php-soap php7.0-json php-gettext imagemagick php7.0-mbstring php7.0-zip

(You have to set a mysql password or else MySQL may not work! Again, if you set the password to be empty, then mysql may not work.)

sudo service apache2 restart


Commandline for when using MariaDB:
sudo apt-get install apache2 mariadb-server libapache2-mod-php7.0 libdate-calc-perl libdbd-mysql-perl libdbi-perl libhtml-parser-perl libtiff-tools libwww-mechanize-perl libxml-parser-perl php7.0 php7.0-mysql php7.0-cli php7.0-gd php7.0-xsl php7.0-curl php7.0-mcrypt php-soap php7.0-json php-gettext imagemagick php7.0-mbstring php7.0-zip
sudo service apache2 restart

(If you were unable to set the MariaDB root password during the installation, then need to follow the steps below. If you were able to set the MariaDB root password during the installation, then skip below to the 'sudo service apache2 restart' command.)

sudo mysql -u root
use mysql;
update user set plugin='' where User='root';
flush privileges;
\q
mysql_secure_installation

(Set a mariaDB root password and select all the default settings)

sudo service apache2 restart
sudo service mysql restart



CentOS

Required modules:

  • php
  • php-cli
  • php-common
  • php-ldap
  • php-mysql
  • php-pdo
  • php-soap
  • php-xml

Redhat Enterprise 5 / CentOS 5

These are the rpm package names. "yum install <pkgname>" generally works.

  • php-mysql
  • php-gd

PHP Sessions and Browser Windows

Before August of 2007 OpenEMR worked poorly, even dangerously, when used in multiple top-level browser windows on the same machine. The underlying problem is that most web browsers cannot support separate cookie-based sessions in this case, because all windows share the same cookie storage area.

Then a JavaScript-based solution was implemented as follows:

  1. interface/login/login.php was modified to delete the session cookie when a new login occurs. This ensures that a unique session ID is generated for each login (we assume you start each new browser window session with a login).
  2. A JavaScript function restoreSession() was created via the script library/restoreSession.php. This script is included in every top-level window. When called, the function restores the session cookie's value to the session ID that was supplied when the window was created.
  3. Many other scripts (about 200!) where changed to call "top.restoreSession()" wherever a server-side script is invoked. For example, "onclick='top.restoreSession()'" was added to every "<a href=...>" tag.

The effect of all this is to make the top-level window the storage area for the session cookie. So by creating multiple top-level browser windows and logging in separately to each, you can have multiple OpenEMR sessions concurrently on your desktop. This is a valuable feature for busy users who must juggle multiple tasks at once.

Naturally this impacts future development. You must include a JavaScript call to top.restoreSession() wherever you invoke a PHP script that requires current session data (which is most of them). The most common ways of doing this are by including the onclick handler as described above, and by including "onsubmit='return top.restoreSession()'" in <form> tags.