From OpenEMR Project Wiki
This is a work in progress right now as we document the ZH Module Creation System.
Currently OpenEMR has embedded within it the Zend MVC Framework version 2.5.3 (March 2019).
Details on how this framework works can be read here: https://framework.zend.com/manual/2.4/en/modules/zend.mvc.intro.html (The documentation is for 2.4 which is the latest documentation for the 2.X release of Zend).
There are two documents that ZH put together explaining how to use the Module Installer. They are listed below. Note that some of this is out of date as these documents were put together in 2016.
A module can integrate into the menu system by defining hooks. These are actually added in by the library/menu/src/MainMenuRole.php file. See updateModulesModulesMenu(&$menu_list) for more details.
A module can expose either HTML or AJAX responses and are called by making requests against /interface/zend_modules/public/. The .htaccess file there maps the URLs to controller/:action formats that are then passed into the corresponding module file. This is configured via the router key inside the module.config.php file inside the config folder of the module.