This guide provides information about the implementation of the presentation layer (also known as a "graphic interface" or "user layer") of a Commerce using LogiCommerce Framework for PHP.
First of all, it gives an overview of the software used, as well as the architecture and logic applied. Next, it explains the basic circuit for a request, giving a general idea of how the application works.
Throughout the guide intermediate/advanced knowledge of the object-oriented programming paradigm is assumed, as well as knowledge of Twig and PHP language.
Software and Components
Below is a list of the software and components used to develop the Commerce's presentation layer.
LogiCommerce API Headless
The LogiCommerce FWK bases its whole functioning on LogiCommerce API Headless. Access to this API is necessary for the system to operate normally.
All the LogiCommerce FWK code is developed for PHP version 7.4 and, by extension, first-party code and that of the Commerce will also work in the same version.
The following modules are added to the PHP engine:
- Xdebug: Error logging and code verification tools use functions from the Xdebug extension.
- Twig: This extension is used to represent and display responses.
- PHAR: The PHP code in the production environment is executed through PHAR-type packed files.
- Composer: This is the package management tool used in the project to handle dependencies and libraries.
The Commerce's website has a cache layer managed by the Varnish version 4.0 application.
The Commerce's website has Redis as a service for storing data in memory, used to store sessions (persistent information between requests) and as an object cache.
Each project consists of 3 blocks of code. Two of these repositories are provided by LogiCommerce; the third consists of the Commerce's own, first-party code.
The logic used to structure the different parts of the code is outlined below.
LogiCommerce SDK for PHP
T his is LogiCommerce's own SDK in its Cloud distribution and represents the lowest-level component. It deals with encapsulating the direct logic of interaction with the LogiCommerce API and, in many cases, simplifies the implementation of certain complex processes.
It also contains all the commonly-used classes valid for any framework written in PHP. However, in this guide we will focus on LogiCommerce's own framework.
The LogiCommerce SDK is divided into 4 blocks:
Core: The base classes on which the rest of the LogiCommerce SDK depends. These are the main classes extended or used by the SDK.
Dtos: Classes for flat objects that store and carry the information received from the LogiCommerce API without manipulating it.
Enums: Enumerated types created in order to make the code easier to read, avoiding having to use magic numbers or fixed character strings in the code.
Models: Classes that deal with receiving information from the LogiCommerce API and returning it via the DTOs that store it.
LogiCommerce Framework for PHP
This is LogiCommerce's own framework in its Cloud distribution. It deals with managing and interacting with the information returned by the LogiCommerce SDK and introduces a logic layer related to the most common processes in a Commerce.
The purpose of this FWK is to unify processes and centralize them according to a single operating criterion. As from a logical point of view it stands between the LogiCommerce SDK and the Commerce's first-party code, it brings functions together and standardizes habitual processes.
The system is based on MVC (Model-View-Controller), so it is structured in two broad blocks:
This directory contains the Twig scripts used to display the response. These scripts are conceptually divided by themes. The FWK contains two of them by default:
- Core: This is not a presentation theme as such. It is loaded from Twig, but its purpose is to provide a library of commonly-used macros shared across all the projects.
Internal: This is the theme FWK uses internally for internal requests or those with a predefined response structure, such as a standard AJAX request.
This directory contains the PHP code for the FWK. This code is divided into the following directories:
- Apps: Directory reserved for future uses.
- Controllers: This contains all the controllers that deal with managing information depending on the type of request made.
- Core: Basic classes on which the rest of the FWK depends. These are the main classes extended or used by the FWK.
- Enums: Enumerated types created in order to make the code easier to read, avoiding having to use magic numbers or fixed character strings in the code.
- Languages: The different language sheets used in the project are found in this directory.
- Services: The services go here. They are extensions of the models created in the LogiCommerce SDK to add actions to a request from a model or create functions to simplify requests for common resources.
- ThemesConfigurations: The different classes loading the configurations depending on the theme or theme and version go in this directory.
- Twig: This contains the classes directly linked to loading the Twig engine, as well as expanding its functions.
ViewHelpers: This directory contains the different ViewHelpers, separated by types of presentation layer resources. These are a series of objects to help with viewing, but which are not linked to the Twig classes.
This block contains the definition of everything to customize each of the projects according to their individual operating and design specifications. Commerce code obeys the same logic in terms of directory structure as the FWK, as it is considered an extension of the FWK. For this to work, any overwriting of Commerce code must be in the same path as its homonym in the FWK.
Like the FWK, it is based on MVC and structured in two broad blocks:
In this directory are the Twig scripts used to display the response. These scripts are divided into themes and there is a directory for each of them. The sub-levels in this area are described in more detail in the "Twig Theme Structure" section.
Regarding the directories created at this level, it is important to take into account that the directories for the Core and Internal themes are an extension of the FWK, so the scripts defined in them will overwrite their homonym in the FWK.
This directory contains all the static content that makes up the project, structured in areas. These are the main areas:
- commerce: Containing the files used as the base for the project, regardless of theme.
- themes: Containing the files directly related to the themes. Within it a directory must be created for each theme. Within each of them are hosted, firstly, the static content that serves as a base or are common to all the versions created, and secondly, there is a versions directory that in turn contains a directory per version, containing the specific static content for each version.
In order to be able to make references to this static content in code, they must be included in the file assets.json. This file contains all the references to the different areas, versions, and types of static content.
The file assets.json will also be used in the process of merging production files, unifying all the references indicated in the files block. For example, all the references to files there may be in commerce → css → default → files will be put together in a single file, and also, according to the instructions in the relevant minify attribute, the resulting file will or will not be minified.
It is important to emphasize that the production deployment process only publishes the files that are in the commerce and themes directories. If files outside these directories are used in a local environment, this will work in this environment, but as they are not uploaded the production environment will not find these files.
This directory contains the PHP code for the Commerce code. This code is structured in the same way as the FWK, mainly because all the elements in the Commerce code are extensions of the FWK elements adapted to the operating and design specifications of the project.
In the root directory there are two essential PHP files:
- _config.php: This file contains the definition of the constants used in the code. This makes it possible to have a single place in which to enable or disable the Twig cache system, specify where the LogiCommerce SDK and FWK code is and the lifetime of the session, among other configurable values.
- index.php: This file is the starting point for requests. In it the LogiCommerce SDK and FWK code is imported into the Commerce code project and the request is resolved.
Logic of a Request
Next, the basic stages in a request within the code are explained; putting the request through.htaccess rules, cache or router systems is avoided.
This file is the gateway for all requests to the project. It loads the project configuration (_config.php) and then the LogiCommerce SDK and FWK repositories. Once all the code is assembled, a Shop-type object is created, and this initiates the processing of the request.
This object deals with initializing, loading, and managing the main components used to process the request. To do this:
First the application is initialized. At this stage, the connection with the LogiCommerce API is established to get the access token to allow requests to be made to the API. Next, the Commerce's settings and configurations as defined in LogiCommerce are obtained and stored in cache, allowing rapid access to any configuration without needing to repeat requests to the API. The lifetime of this cache is defined by the constant CACHE_LIFE_TIME (its default value is 30 minutes).
The next step is to initialize the session, i.e. the system of persistence of information between requests. Depending on the value of the constant REDIS_SESSIONS, the session information will be stored in Redis or on the first-party PHP server.
The project uses the native PHP session system, but to control the information saved and maintain a proper match between the data, $_SESSION is only accessed through a first-party class called “Session”. This class deals with managing everything stored and obtained from $_SESSION. On initialization, if a session is not yet available, empty objects are assigned to Session and then used to store information such as the user, viewing theme or items for the comparator.
At this point in the session we have a session and a connection with the LogiCommerce API. Next, this request is analyzed. To do this, an instance of the Router object is created from the Shop object.
In this class the path of the resource asked for in the request made by the client is analyzed and it is determined which controller is to process it. First it is necessary to distinguish between two types of request:
Internal: Internal requests are those where the project's internal logic is able to determine by itself which controller is to deal with processing it, such as loading the error page or page not found controller, actions like adding a product to the shopping cart or resolving the start of a user session.
External: For these requests the LogiCommerce API must be queried to know which controller is to be loaded. The API will return all the associated information, such as the type, and this makes it possible to determine which controller is needed, the viewing theme, currencies, languages and so on.
Whether it is internal or external, at this stage in the request the system has the information to decide which controller is to be loaded. Therefore, the Controller object of the required type is created and the run message is launched.
According to the MVC pattern, the Controller object will get and calculate all the data necessary for the request. This information is obtained through requests against the LogiCommerce API, primarily using two strategies:
Batch requests: These requests are a very useful API tool (Bulk API) allowing us to put several GET-type calls together in a single request, to be resolved in parallel in the API. As loading times obviously need to be minimized, by default each controller creates one of these requests so that the programmer includes in it all the calls that do not require the result of a previous call.
Single requests: If the request made to the LogiCommerce API is of the POST or PUT type or cannot be included in a batch request, unitary requests to the API must be used.
These two routes for requests that can be made against the API have been passed on to the controller in two functions that are executed automatically. This way, first the batch request is resolved so that the system has all the corresponding results, and then the information is complemented with single requests if necessary.
With all this information, plus calculations or logic resolved in the controller, a model key-value type table will be created, and this is sent to the Twig engine to then be used in the Twig scripts; by using the key the value can be accessed.
The Controller object will create the Twig engine using the TwigLoaderclass. This engine will primarily have five new blocks assigned to it:
Macros: In the FWK a full block of macros has been generated, integrated into Twig to be usable at any time. The macro block is conditioned by modes so that, without the intervention of the developer, it can detect whether it has to return the code in formats including Boostrap3, Boostrap4 or AMP, among others.
Global variables: By default a block of global variables is loaded, including session data, Commerce configuration, path information, language sheets and so on, so that they can be used easily from any part of the Twig scripts.
Helpers: These are objects that make it easier to get output. They are created from an object and make it easier to get outputs from it.
A product helper, for example, could return, among other things, this product object converted to json under a particular format.
Functions: A series of functions that are not included by default are added to Twig, such as dump(), abort(), localizedCurrency() and ucwords(), among many others.
Data: At this point, the Twig engine has all the data calculated in the controller into it so that they can be used in the scripts.
Finally, the response is interpreted. To do this, the Twig engine has the name of the theme to be loaded assigned to it, having got it from the path information. From this point, all the paths will be relative to this theme. Also, the appropriate template and layout are assigned, including the details of the output to be constructed.
Finally, the text resulting from interpreting is sent to the Response class.
This class deals with centralizing the response information. In the course of the request the headers to be returned in the response to the request have been added to this class, and now it has the body generated in the Twig engine.
The process therefore ends by assigning the headers of the request and its body. This completes the request cycle, it goes back to the Shop class and the response is returned to the client.
Structure of Twig Themes
The Twig themes that the project will apply are divided into 5 types of element:
- Theme: This is the main element and includes a graphic style that can be applied to the different versions it contains.
- Versions: Versions are the different applicable theme designs. For example, the desktop version would be for clients displaying on ordinary monitors, while the mobile version is designed for clients displaying on mobiles or tablets.
- Layouts: These are the different structures or layouts that can be applied within a version to fit the content into.
- Content: this is the template for the final content to be shown, based on a layout. For example, it might be category, product, or shopping cart content.
- Snippet: These are generic elements that can be used in a layout or in content; they can be re-used as needed. In the Twig engine they can be used as Includes or Macros.
Layout of Elements
Within the project themes directory are the different themes and, in turn, for each of them, the different elements that make them up are included.
Themes may or may not have versions. If they do not have them, the layouts, content, and snippets directories will depend directly on the root for the theme. Otherwise there will be a directory for each version within the theme. Within each of the versions the respective layouts, content and snippets directories will be included.
Controller - Layout - Content
Based on the controller type obtained through the Router object (as explained above) and the theme the latter assigns, the system automatically generates the paths to get the appropriate layout and content.
File name: This is defined in the Theme object with which TwigLoader was initialized. This value will be the main part of the Twig filename to be loaded, and to which the appropriate format must be added, for example "html", "js", "json", plus twig at the end. The full name could be "default.html.twig".
Location: This file should be in the "layouts" directory, defined in the root of the version of the theme if there are versions, or in the root of the theme if there are no versions.
For example: themes\default\desktop\layouts\default.html.twig
Filename: As with the layout, the content is defined in the Theme object, and likewise, its name will be followed by the format and "twig". It could, for example, be "default.html.twig".
Location: As a general rule, a content-type file is associated with a controller. For this reason, the same logic applies to its location as to that of the controllers, which are structured according to the element type.
Therefore, the directories to reach the content start with a capital letter, as do the packets and classes until the controller is reached. For example, the content associated with the product datafile controller would be: