Directory Structure
The scripts that make up the system are seperated into several directories. However, the main bulk of the KwaMoja scripts are in the top level directory.
- The top level directory contains all the scripts that are called directly from links in the system. A fundamental design crieria was to avoid the casual and perhaps novice PHP programmer having to examine code in many different files to obtain an understanding of the logic.The developer will rarely need to look beyond the main root directory of the KwaMoja scripts and the includes directory.
- Scripts or portions of scripts that are included in one or more of the main scripts are held in the includes/ sub-directory. Many of these includes are used in a way similar to functions.
- A number of sub-directories under the includes directory are worthy of note, in particular the php-plot directory contains the php-plot class (by Miguel de Benito Delgado and others - maintained as a separate project) which is the code used by KwaMoja to create charts for sales analysis inquiries. The php-gettext class (by Danilo Segan) is used by KwaMoja to attempt to translate using the files under the locale directories where php binary gettext libraries are not installed. In practise it is much better to have gettext libraries installed when operating KwaMoja in a multi-language installation. Also, the TCPDF class which is a derivative of Olivier Plathey's FPDF class developed by Nicola Asuni that enables pdf files to be created by KwaMoja using the utf-8 character set and CID fonts - this allows KwaMoja to create lightweight pdf files where the fonts for all languages are bundled by adobe acrobat reader. Although this class is maintained as a separate project there have been some modifications to this class by Javier de Lorenzo-Cáceres that allow CID fonts to be mapped correctly. This class is a very large collection of files and it has been trimmed significantly for the KwaMoja distribution excluding all the TCPDF documentation and examples.
- The scripts to create the database are held under the sql directory. Underneath this directory there is currently only a mysql directory since only the mysql RDBMS is supported. Previously there was a pg directory for postgres sql scripts. Under the mysql subdirectory of the sql directory - are sql scripts created by mysqldump. There is a script to create a new installation with only minimal data to start a new system off - kwamoja-new.sql. There is also a script to make a demo system - kwamoja-demo.sql.
- The locale directory contains all the different language translations installed. Only the en_GB.utf8 language is installed by default. Many other language packs can be downloaded and installed under this directory. Under the locale directory each of the languages must be under a directory name that matches to a locale installed on the web-server. Under this directory the LC_MESSAGES directory contains two files the messages.po - which contains the translations and a messages.mo that is compiled as a binary indexed file for looking up the translations as fast as possible using the gettext functionality for internationalisation of applications
- Documentation is under the doc/ sub-directory where this manual is under the Manual subdirectory of the doc directory. Manuals specific to a given language/locale are under the locale/ and language sub-directory
- The api directory contains all of the api scripts
- The xmlrpc directory contains the XML-RPC client and server code required for the api - KwaMoja uses a class created by G. Giunta for this purpose - the whole tree of this XML-RPC class
- The Numbers directory contains the PEAR class for converting numbers to words - this code is used by the cheque writing code in KwaMoja. The PEAR installation of the class is not required since PEAR adds a lot of overhead to PHP it is not required as a dependency to use KwaMoja and so this code is bundled with KwaMoja.
- The install the directory is where the minimal installer scripts are held - these can be deleted if required after installation. Only when the file config.php does not exist - in a new installation will the scripts in this directory be used.
- The flags directory contains small images of national flags appropriate to the ISO 4217 currency code abbreviations - each file is named by the ISO code .jpg these are displayed on the currencies form in KwaMoja.
- FPDI directory is an extension to the TCPDF pdf creation class that allows other pdf files to be concatenated onto pdfs created from the system - this class is created and maintained as a separate project by Setasign - Jan Slabon. KwaMoja allows user selectable document(s) to be appended to invoices - this functionality requires this class and the files under this directory
- Formatting style sheets are held under the css - see the themes section under getting started above. Under the css directory there is a directory tree for each of the themes that come with the distribution. To create a new theme simply copy one of the existing directory trees over to a new one under the css directory - it will automatically be able to be selected as a new theme by KwaMoja.
- The javascripts directory contains just one file that is included in the HEAD section of each KwaMoja script and contains all the javascript used by KwaMoja
- the reportwriter directory contains the sql report writer used with KwaMoja - this contribution from Dave Premo - the author of Phreebooks does not follow any of the conventions of the rest of KwaMoja but adds important functionality to KwaMoja. There is a whole other directory structure under the reportwriter directory and the code is more difficult to follow. Happily Dave wrote some good help to enable it to be used
Construction of new scripts should make use of the following building blocks that are used throughout the system.
session.php
This page must be included and has the following functons:
- Establishes a session if none already exists and checks that an authorised user is logged in - if so it checks that the user is authorised for the specific page being called, based on the value of $PageSecurity.
- It in turn includes the scripts:
- config.php - this script contains the details required to connect to the datbase.
- The GetConfig.php script ensures that all system variables defined and stored in the database are retrieved and available to the system as SESSION variables. The GetConfig.php reads the companies table in the database that contains just a single company record. It also reads the config table in the database - which contains all the system configuration parameters - these are stored in session variables to avoid round trips to the database with every page. The developer needs to study these parameters which are explained in the SystemParameters.php page from Setup --> Configuration Settings
- ConnectDB.php - this script (which in turn include includes/ConnectDB_mysql.php or includes/ConnectDB_mysqli.php - historically includes/ConnectDB_Postgres.php was also an option) initiates a connection to the database and contains all the database abstraction functions. When interacting with the database, only functions defined in this script are used, not the mysql specific functions, since a change in database would be otherwise be difficult to effect. By using this file, only the functions in this script need to be modified for any other database to be used.
- LanguageSetup.php - this sets the locale and handles the fall-back to php-gettext if the local gettext libraries are not available on the web-server
header.php
This file should be included after the variable $Title has been set to the name of the page. This file relies on config.php being already loaded, so session.php (which in turn includes config.php) must be included before header.php. The code in this script has the following functions:
- Includes the javascript functions used in scripts from the file javascripts/MiscFunctions.js
- Sets up the normal system banner with the links to the menu, item selection, customer and supplier selection pages.
- Sets the style sheet used throughout the system - by referencing the theme directory to use for css
footer.php
This file contains the small logo, company name and copyright notice with the closing "" tags.
config.php
The variables in config.php are available to all of tcripts that have included session.php. There are not many now most of the configuration is stored in the database using the config table. However, the variables that give the software the information to connect to the database such as datbase user, password and host, together with the database type - dbtype - in fact only mysql is supported but there are two libraries that can be used the mysqli and the old mysql functions. There are a couple of other variables including the timezone, $RootPath which is the directory where the web server holds the system files. Also the php error_reporting code.
Having started the page with session.php and header.php - and then finishing with footer.php much of the work to ensure a consistent look and feel is already done.
An Example KwaMoja Script Template
Following from the discussion of the key component scripts of KwaMoja, the general form of a KwaMoja script would look like the following:
<?php
/* session.php is the script that brings in session
* management, database management, and performs
* any other housekeeping tasks related to the running
* of KwaMoja. and so should be included right at the
* top of every script.
*/
include('includes/session.php');
/* A title for the script must be assigned prior to
* including the header.php script
*/
$Title = _('Simple KwaMoja Script');
/* The $ViewTopic variable should be set to the name
* of the manual page for this functionality and the
* $BookMark variable is the place in that manual page
* specifically for this functionality
*/
$ViewTopic = 'SimpleScript';
$BookMark = 'GeneralTopics';
/* The header.php file sends all the http headers needed,
* links in the style sheets and downloads any javascript
* files that are needed. It also draws the header on the
* screen. Muse be included before any output is sent to
* the browser.
*/
include('includes/header.php');
if (!isset($_POST['Submit'])) {
/* In this section should go the code to validate the data
* submitted in the form, and if all is well it should
* post that data to the database. If there is more than
* one table to be updated that transactions should be used
* in order to maintain the database integrity.
* If the form does not validate then it processing can just
* fall through to the next section, but show any required
* messages.
*/
}
/* This section is where any of the display code goes.
* Typically this will contain a table of the existing data,
* and a form for entry of new details.
*/
/* Finally we must include footer.php to draw the footer on
* the screen, display any error messages, and close off the
* html tags in the page.
*/
include('includes/footer.php');
?>
PDFStarter.php
The only time when it is not appropriate to include session.php or header.php is when a pdf script is to be created. Here the file PDFStarter.php contains the initiation of the session and the check for proper user authentication and authorisation for the specific page using the $PageSecurity variable which must be defined before PDFStarter.php is included. Normally, config.php and ConnectDB.php are included seperately (and before PDF_starter_ros.php) in PDF scripts. PDF report scripts all make use of the FPDF class by Olivier Plathey but previously a differnt class was used so there is an extension to this which translates the calls to the old pdf class to the FPDF class. Probably better to write new scripts using the FPDF syntax.
Database Abstraction - ConnectDB.php
Whilst the system has been developed using MySql it has always been envisaged that users should not be forced to use Mysql - in keeping with open source principles. For this reason all requests of the database are made via abstraction functions in ConnectDB.php. This policy has been rigorously maintained and developing extensions to the system which do not conform to this scheme would destroy the portability currently available between databases. Instead of using the PHP database specific functions then the functions defined in ConnectDB_mysql.php should be used
- $DB_result_handle = DB_query($SQL,$ErrorMessage='',$DebugMesage='',$InsideATransaction=0)
- $NumberOfRowsReturned = DB_num_rows($DB_result_handle)
- $QueryResultNamedElementArray = DB_fetch_array($DB_result_handle)
- $QueryResultArray = DB_fetch_row($DB_result_handle)
The full list of functions should be reviewed from the file includes/ConnectDB_mysql.php - which contains the mysql specific abstraction functions. Only these functions should be used in other scripts. Care has been taken to ensure that standards compliant SQL is used throughout, to ensure any database conversion issues are minimal. SQL specific to any RDBMS even mysql should be avoided in favour of generic standards compliant SQL. There are instances where mysql specific SQL has been used such as INTERVAL and SHOW TABLES - these are historical.
DateFunctions.php
This script holds a number of functions for manipulating dates used throughout the system - these functions all depend upon the system configuration for SESSION['DefaultDateFormat']. Amongst the most useful:
- DateDiff - calculates the difference between two dates has parameters for the number of days, weeks or months.
- FormatDateForSQL converts a date in the format specified by $DefaultDateFormat in config.php to the format required for SQL - yyyy-mm-dd.
- ConvertSQLDate - Converts a date in SQL format yyyy-mm-dd to the date defined in config.php $DefaultDateFormat
- GetPeriodNo - Gets the period number for a given date by looking up the date in the period table - it creates new periods as necessary to ensure a valid period is returned.
SQL_CommonFuctions.php
This script has some common functions used throughout the system - in particular:
- GetNextTransNo - that retrieves the next transaction number for a given transaction type - see the table systypes for a list of the valid transaction type codes.