Skip to content

Architecture

Martin Polanka edited this page Apr 29, 2017 · 9 revisions

Architecture

CUK system is PHP application presented through HTML web pages generated within. Some of the systems code can be written with features from PHP version 7, therefore this is its minimal usable version. Whole system is built on top of the Nette framework in the version 2.3 and due to some problems with forms, it cannot be updated to further versions without massive rewritting. Generation of HTML content is done through Latte templating framework.

In this article you will find description of important parts of the system and its artitecture alongside with some interesting observations.

Nette Overview

Nette is one of the top PHP frameworks according to developers. It is a project developed by community and licensed by BSD license or the GNU GPL. On the framework pages you can find a lot of examples and tutorials which covers basic framework capabilities. In addition there is quite active forum in which you may ask anything you want about the Nette project.

Before reading and understanding CUK system you should be at least minimally familiar with Nette and its principles.

Routing

Basic routing in Nette is quite simple and straightforward, but if there is complexity needed, it can be polished into very complex structure. Routing in CUK is fortunatelly simple and uses automatic detection of presenters and actions. This is managed through App\RouterFactory factory class in create() method.

Handling of Exceptions

By default in production mode Nette runtime will catch all exceptions thrown during execution and engage exception handler. Exception handler is defined within configuration and points to user defined Error presenter. In the CUK system there is App\Presenters\ErrorPresenter which handles logging and sending/displaying the right error codes and pages. In here there can be engage some custom handling of some particular exception, but so far there is none.

Users Management

All features concerning users management are placed within App\Users namespace. But the most important part is how to store and authenticate logged in users. In Nette logged users and information about them are by default stored in Sessions on the server. And authentication of them is done through Nette\Security\IAuthenticator implementation.

Considering used Doctrine framework, information about user in the CUK system is stored in the User entity, so it would be handy to somehow store this entity or its identification. In CUK this is done through Nette addon nette-identity-doctrine. Of course we have to somehow engage User entity as the Nette Identity which is handled by App\Users\MyAuthenticator implementation of authentication. Because of this on every page load new information about user will be fetched from database according to stored user identification.

With users management is tightly coupled authorization of access to the resources. In CUK there are two classes concerning authorization: App\Users\AuthorizatorFactory which uses Nette basic authorization mechanism and App\Users\MyAuthorizator which somehow handles cases where basic authorization fails. The list of all users roles can be found in App\Users\AuthorizatorFactory in create() function, alongside with definitions of resources and permission rules. For some humanly readable description of user roles there is App\Users\RolesManager helper.

Database Layer

There is no reason to use plain SQL, thus database abstraction was engaged, specifically well-known Doctrine 2 ORM framework. Configuration of Doctrine was described previously in Configuration article. All repositories and entities are placed within App\Model namespace, repositories are in subnamespace Repository and entities in Entity.

Entities introduced in CUK system are in most of the cases self-explainable and corresponds with the systems features, therefore is no need to describe them in detail. If there is need to serialize the entity into simple array BaseEntity can be used to achieve this.

Repositories are kind of helper classes which are able to do some general operations on entities or engage custom operations which makes sense for some particular entities. For the general stuff there is BaseRepository from which all others should extend. Alongside with fetching there is also functionality of persisting or deleting entities.

For better initial population/initiation of database there are prepared fixtures which are able to fill all countries, initial faculty with administrator and also with initial blank articles which are editable by the systems users. Whole this fun is located in fixtures folder and uses DoctrineFixtures.

Remote Loading

One reason why the CUK system was created is to make acquiring of information from ifmsa.org simpler. On ifmsa.org information about incomings or outgoings are splitted into multiple documents/pages. Which makes it quite hard to harvest them and make one overall document with all information. This procedure can be automated and therefore was integrated into CUK.

Bit of problem with this approach is that ifmsa.org has only web pages (HTML) and not some publicly accessible simple API (for instance REST - JSON format). That is why CUK has to fetch whole web pages and parse them. Which is not fast and simple and can be somehow tricky because of changes in the pages structure which might come in the future. For the purpose of fetching pages, Guzzle library is used.

Right now all code concerning loading of data from ifmsa.org is situated alongside with App\Helpers\IfmsaConnectionHelper class. There are multiple helper classes which should be separated into individual files and the code of the IfmsaConnectionHelper class itself is spaghetti-like and should be refactored.

Tables and PDFs Generation

On multiple places in the CUK system there is need to generate tables or PDF documents. PDF generation functionality is coupled in the App\Helpers\Pdf namespace and for generation TCPDF library is used.

Generation of tables uses two libraries: PHP_XLSXWriter and PHPExcel. And this functionality is united in App\Helpers\Table namespace.

Payment Gateway

More about payment gateway, its implementation and integration within external service, can be found in separate article Payment Gateway.