Skip to content
Sophist-UK edited this page Jul 17, 2013 · 9 revisions

This wiki entry is a brain-dump area for Paul to provide suggestions to Rob / Hugh for Fabrik 4.0 design.

Architectural Integrity

Create an object / methods model using a modelling tool like Modelio.

Write an architecture guide which explains at a high level how Fabrik works i.e. object relationships, the event model etc.

Write a developers guide which explains coding standards and how-tos on extending Fabrik. Provide code comments to explain what each block of code does.

Try to create and hold onto Architectural integrity i.e. be clear about objects, their relationships, their hierarchy and inheritance of methods etc. and be ruthless in keeping code clean.

There should be a clear definition of how admin and run-time transactions flow.

There should be a clear separation between admin and run-time code, so that packager can package a run-time environment without any admin functionality.

Should we allow reimport of a package so that it can be modified and then re-exported??

All common functionality should be handled by parent objects and / or helper objects. Ideally it should not be possible to find the same code in two places. If this is done sufficiently well, the code should become very readable.

The MVC model should be adhered to strictly - which means that the Controller handles all variations of input type (e.g. ajax vs. post, importcsv vs. post) and the model doesn't need to know about it. Similarly, the Controller/Model should marshall the output values for generic types (list, form, details, full) and the View should be the only place which is concerned with the format of the output i.e. HTML, PDF, email, CSV.

All of this should result in code that is more modular and easier to understand, extend and bug-fix, and which (because of its clean lines) is less likely to have bugs in the first place.

Separate Tables and Lists

Lists are currently a combination of table definitions and a tabular display of data. I believe that these should be separated into separate objects. All SQL interaction with the DB should be through the Table objects. Lists should be like Forms i.e. have a combination of Groups. We could then perhaps extend the List concept to cover headings, sub-totals etc. in a more comprehensive way so we can handle management reporting.

Each table can have 1 or more Groups.

Each group can have 0 or more Elements.

Each Form / List can display 1 or more Groups.

Two tables can be joined.

Joins can be tight or loose (tight refers to repeat group type joins - loose to databasejoin type joins).

Note: databasejoin link tables for many-to-many databasejoins are tight on one side and loose on the other.

Note: This supports nested repeating groups and other complex table relationships.

Table object handles interface with database.

Table object ensures referential integrity.

Table object marshalls SQL statements into atomic transactions and executes them in a single continuous sequence once Fabrik signals transaction ended (minimise locked records).

Group and Element objects indicate to Table which elements they need. Table object works out the SQL needed to get the data and if needed to update it.

Record locking should be implemented using locked-by and locked-deadline fields in each main table - with locked-record timeout time decided by the user i.e. if a record is locked because e.g user starts to edit a record and then closes their browser, the same user can always edit the record again, or another user can edit it if the timeout / deadline has passed (in which case they lock the record and if the other user tries to save, they get an error message because their userid doesn't match the locked-by field any more.

Ideally we should be able to avoid sessions (though I am not sure what sessions are currently used for and so not sure if they can be avoided).

Internal structure

Not only should Lists be separated into Tables and Lists-based-on-Groups, but Lists and Forms should be separated into UI based code and a separate object or objects to handle record-definitions (what fields are in a record, which ones repeat and for nested repeat groups what the relationships are) and to handle the actual data records. Most of the structuring and loading / saving etc. of records are common functions and should be done separately from the Form / List objects.

The process controlling the triggering of events for records, groups and elements could be part of the RecordDefinition or Record objects, but perhaps should be a separate object in its own right.

At present all routines go get stuff multiple times. The interfaces between objects should be clean - so that one object does not need to go inside a different object but instead should operate in general only through clean interfaces. There may be exceptions to this for performance reasons where structures can be simple and clean and unlikely to change - but these have to be very carefully thought through as any change to these would then impact a large quantity of code.

First phase of every admin / run-time transaction is to marshall all needed objects so that they can be loaded once and then easily accessed.

All user-named things should be kept separate from Fabrik internals so that user can use any name for a table, list, placeholder etc. without risk of clashes with Fabrik internals.

Internal code should not need to worry about whether a setting is held as a database field or a Joomla registry/JSON parameter string. All settings should be exposed as variables - the table object should take care of how to store the data (which means that we can easily move settings from parameters to fields or back again without recoding elsewhere).

Backward Compatibility

Existing F3.x lists would need to be split into tables, lists and new groups during upgrade.

Otherwise every current user defined setting should carry across.

Control flow

Maybe we should have a central flow-control object to clearly define what controls things happening. This could be parameterised using xml-based files to decide which events to process in which order using which methods (makes it easy to add new processing events).

Perhaps data for a transaction should be stored in a single data object in order to make it easy to get hold of it. If the structure of this is cleanly defined it would make it much easier to debug and extend the functionality.

Events should flow cleanly up and down the hierarchy. Events needed by e.g. only databasejoin element are defined in the element master object as an empty method and called for every element, but only databasejoin element would override the empty method which does something useful.

Placeholder and Repeat Groups

Placeholder would cleanly support repeat groups and even nested repeat groups.

Groups and RecordDefinitions and possibly Records would have generators to allow the list of elements to be traversed in a standardised way.

Every element would be able to get a form index which would indicate its position in a repeating group i.e. [] in the master record, [1], [2] etc. in the first-level sub-record, [1,1],[1,2],[2,1] in the second level sub-record.

Reference to a placeholder in the current record or a parent would return a singleton value - reference to a placeholder in a sub-record would return an array of values as now.

HTML

Clean and consistent use of ids and classes - all fb ids and classes should have a consistent naming convention i.e. fb_xxxx_name where xxxxx indicates what type of class or id it is, name indicates group or element no or name (TBD) in a way which makes it unique. Repeat group whatevers will have identical classes, but indexed ids.

Provide ability to override style on an element by element basis.

Provide ability to provide css on a form by form / list by list basis. (Simple textarea field holding the CSS which is added in-line so that user doesn't need to edit php files.)

I haven't spent any time working with existing JS, so not sure how cleanly architected it is. Only experience is that JS stuff seems a little unreliable - repeat groups +/- don't work on multi-page - not sure why multi-page would affect that. But same approach to architectural purity should apply to JS. Provide lots of helper functions and APIs so that code is never duplicated. Provide clean hierarchies. Provide comprehensive event model so that all JS is coded within the architecture rather than trying to bolt onto the outside. If we can extend the plugin concept in JS that would be good too.

Security

In addition to actual Joomla access levels, access levels should be defined as Inherited - so ability to do x can be explicitly set for each element or inherited from the group or inherited from the form. This should avoid a lot of defining of access levels during development and should also provide better functionality.

Constraints

Provide parameter driven admin constraints i.e. rules which say if you try to do x on a y type of object which has z attributes, then e.g. request confirmation, or deny the request or whatever.

i18n

Feed code commits up to transiflex and collect translations back down automatically.

MVC, Front-end / Back-end, php / js code separation

Provide clean MVC separation so that UI activities are handled by the Controller, whilst the Model deals with handling the activity and View displaying the results. So e.g. Ajax handling is done in Controller and we can Ajax more with a cleaner interface.

Front and back-end code should be separate so that packaging can be done cleanly with front-end code.

php code, js code and the php-code that outputs to js or gets input from js should all be kept separate so that the code is clean and files are a reasonable size.

Speelong

Fix the myriad of speelong meestooks in the code esp. stuff like i18n strings.

Testing

Find a way to define formal tests and an automated regression test suite which automatically builds an application which uses every function and regression tests it.

Community

Find a way to involve the community more, and whilst you can't enforce it, make it clear when people start to use Fabrik that it is expected that they give back once they have got up to speed according to their abilities. Could be simply welcoming new users and pointing them the way when they are still newbies - though translation, formal testing, documentation and fixing.

(There comes a point in any organisation growth when managing becomes as big a task as doing. And I think we are there. Rob (and Hugh) are struggling to cope now - they need to decide what is the core stuff they need to keep (copyright, code quality review and merging, overall design decisions, paid support and consulting, major code restructuring and development) and what can be delegated (some development and fixing, some marshalling of todo items and prioritisation, documentation, sub-contracted user development). Since this is open source, it needs to be loose and friendly and cooperative not hierarchical and autocratic.)