My major artefact at matatiro solutions was a CMS called msWHW. The name is outside of any branding, and following Unix tradition. This is a drop in replacement for one that my boss wrote in the preceding months. This job wasn't covered by an NDA, so I may discuss things.
Goals of msWHW
- To reduce cost of creating web applications, by providing infrastructure;
- To create widgets for user-interface features above and beyond what the HTML standard and web browser supply;
- To provide management structures for the applications, in terms of URLs and sessions;
- To provide a standard mechanism for things like email templates and dB access, at lower cost than direct PHP manipulation;
The resultant code needs to be able to:
- Provide a framework;
- To create a common config format;
- Create forms to support an existing client editable form table-structure;
- Create page content blobs to support an existing client editable table-structure;
- Create notifications according to an existing client-editable error format;
- Create template emails according to an existing client-editable table-structure;
- Support sessions & user identification;
- Create HTML and CSS to pass w3c “accessibility” guidelines;
- Provide JS infrastructure to support all the custom build work as necessary;
- Support FMP dB access;
- Support MySQL access, although this wasn't a big feature;
- Support value list structures which the underlying dB provides;
- Support email notifications;
- Support full xhtml as an output format;
- Automate form input validation;
- Support XML as an output or input format;
- Support SOAP as an output or input format;
- Support JSON as an output format;
- Infrastructure to allow AJAX requests (doesn't need a full webpage in the response);
- Support config driven SQL interaction, as this is faster than to write than more OO code;
- Provide support for datacaches [on selects], as the underlying dB is slow;
- To do activity logging;
- System to be built in PHP5, the version which ships with FMP (5.2 ish);
This title is vague, but this is a synopsis on what I built. I built a symbol expansion system. A root request is resolved to some strings, and further list of symbols. Recursively the other symbols are expanded into their values. The strings are merged together and returned to the client. The symbol namespace allows 'symbols' which resolve to strings; 'classes', which obviously resolve to the requested object; and 'actions'. The latter is for activities such as form handling, or requests for non-strings, such as dB resultsets. The core system provided symbols for all of the formats listed in the requirements.
There may be several implementations of each symbol. A specific URL may want to have logos on each table row, so override the normal HTML table building structures for example. Each class needs to elect whether it is relevant to the current URL. When classes are relevant, the polling function visibleNamepace() returns the active symbols and their weighting. The highest weighting is used for the current page.
To make data lookup practical URLs are normalised, into lower case, and delimited by URL slashes '/'. Any IDs are after the page name, and treated extra. I inherited a page classification system, which split the pages into areas, normally “/noun/verb/id”, sometimes “/noun/preciseNoun/verb/”.
I created a hashmap structure to store setting for each page. Each of the library classes may be used in each page, but will only be active when listed in the hashmap. The hashmap also holds configuration for the dB operations, so the page doesn't need to. The hashmap is indexed via the normalised page name.
In practical terms, the code was split into library and implementation. 'Implementation' is for all the code specific to the pages in the current website, with little re-use potential. The library directory is a symbolic link to the relevant project location, as a single instance per host.
As the project was used, it acquired additional widgets for postcodes, and DnD file upload (via AJAX). There was an inherited scheme for phone numbers (where numbers are a distinct widget interface item), with targeted input validation and a number type select box. For one project we created lightboxes for popup tabs.
As a comparison with the older CMS library, it is much better OO. As this is PHP5, one may use exceptions, as a safe form of goto statement. Much less code was needed for fail conditions. Exceptions where also used to return the submitted POST data (back with a page) if it proved invalid. This is one of the features I like best about recent versions of PHP. I used a class autoloader, making the initial landing page and routing much easier to handle. I increased the amount of OO structure, increasing testing, decreasing duplicate code.
The additional features and improved ease of use mean the new system is much easier to make websites with. I am biased, I wrote it; but class variables make the system much better. The per-page code is generally shorter and more readable. The output HTML is better quality.
When this was done, a person could add a new form to an existing site by adding data to a table (people like FMP, as it provides tools to do this), updating one config file and hitting publish. The system would ensure that there was valid HTML, input validation, data capture and recording. It dynamically created SQL statements to match the table structures. Depending on what was put in the config file, access controls may be applied. As I added classes, I created unit tests.
I wrote this framework, but it was in place with existing business systems. Agile encourages quick sprints, then refactoring. This was a large scale refactoring, with architecture improvements as a focus. My work improved the qualities of the existing process. I was improving the conceptual cleanness towards an MVC approach (by adding features); but the objective was profitability not theory.