Implementation Guide

Introducción

En esta guía se ofrece información sobre la implementación de la capa de presentación (también conocida como “interfaz gráfica” o “capa de usuario”) de un Commerce usando LogiCommerce Framework for PHP.

En primer lugar, se da una visión global sobre el software que se utiliza, así como la arquitectura y la lógica aplicada. Posteriormente, se explica el circuito básico de una petición, con lo que se obtiene una idea general del funcionamiento de la aplicación.

A lo largo de la guía se da por hecho que se tiene un conocimiento medio-alto de la terminología del paradigma de la programación orientada a objetos, así como conocimientos de lenguaje PHP y Twig.

Software y componentes

A continuación, se enumeran el software y los componentes que se utilizan para desarrollar la capa de presentación del Commerce.

LogiCommerce API Headless

El FWK de LogiCommerce basa todo su funcionamiento en LogiCommerce API Headless. Es necesario disponer de acceso a dicha API para que el sistema pueda operar normalmente.

PHP 7.4

Todo el código del FWK de LogiCommerce está desarrollado para la versión 7.4 de PHP y, por extensión, el código propio y el del Commerce también trabajarán con la misma versión.

Al motor de PHP se le añaden los siguientes módulos:

  • Xdebug: las herramientas de comprobación de código y registro de errores usan funciones de la extensión Xdebug.
  • Twig: esta extensión se usa para la representación y visualización de las respuestas.
  • Phar: el código PHP del entorno de producción se ejecuta a través de archivos empaquetados de tipo PHAR.
  • Composer: es la herramienta de gestión de paquetes que se usa en el proyecto para gestionar dependencias y librerías.

Varnish 4.0

El sitio web del Commerce dispone de una capa de caché gestionada por la aplicación Varnish versión 4.0.

Redis

El sitio web del Commerce dispone de Redis como servicio de almacenamiento de datos en memoria, el cual se usa para almacenar sesiones (información persistente entre peticiones) y también como caché de objetos.

Distribución del código

Cada proyecto se compone de 3 bloques de código. Dos de estos repositorios los ofrece LogiCommerce; el tercero corresponde al código propio del Commerce.

A continuación, se explica la lógica aplicada para estructurar las distintas partes del código.

LogiCommerce SDK for PHP

Es el SDK propio de LogiCommerce en su distribución Cloud y representa el componente de más bajo nivel. Se encarga de encapsular la lógica directa de interacción con la API de LogiCommerce y, en muchos casos, facilita la implementación de ciertos procesos complejos.

También contiene todas aquellas clases de uso común, válidas para cualquier framework escrito en PHP. Sin embargo, en esta guía nos centraremos en el framework propio de LogiCommerce.

El SDK de LogiCommerce se divide en 4 bloques:

  • Core: las clases básicas de las que depende el resto del SDK de LogiCommerce. Son las clases principales que el SDK extiende o utiliza.

  • Dtos : clases para objetos planos que almacenan y transportan la información recibida desde el servicio de la API de LogiCommerce sin manipularla.

  • Enums: enumerados creados con el objetivo de facilitar la lectura del código, lo que evita tener que usar números mágicos o cadenas de caracteres fijas en el código.

  • Models: clases que se encargan de recibir la información de la API de LogiCommerce y devolverla mediante los DTO que la almacenan.

LogiCommerce Framework for PHP

Es el framework propio de LogiCommerce en su distribución Cloud. Se encarga de la gestión e interacción con la información que devuelve el SDK de LogiCommerce e introduce una capa de lógica respecto a aquello que se desarrolla más comúnmente en un Commerce.

El objetivo de este FWK es unificar los procesos y centralizarlos bajo un mismo criterio operativo. Puesto que, desde un punto de vista lógico, se encuentra entre el SDK de LogiCommerce y el código propio del Commerce, aglutina funciones y normaliza procesos habituales.

El sistema está basado en MVC (Modelo Vista Controlador), por lo que se estructura en dos grandes bloques:

themes

En este directorio están los scripts de Twig que se utilizan en la visualización de la respuesta. Estos scripts están divididos conceptualmente en temas. FWK contiene dos de forma predeterminada:

  • Core: no es un tema de presentación como tal. Se carga desde Twig, pero su propósito es proporcionar una librería compartida con todos los proyectos de macros de uso común.
  • Internal: es el tema que FWK aplica internamente para peticiones internas o que tienen una estructura de respuesta predefinida, como por ejemplo, una respuesta AJAX estándar.

src

Dentro de este directorio se encuentra el código PHP de FWK. Este código está separado en los directorios:

  • Apps: directorio reservado para usos futuros.
  • Controllers: aquí se encuentran todos los controladores que se encargan de gestionar la información según el tipo de petición que se haga.
  • Core: clases básicas de las que depende el resto del FWK. Son las clases principales que el FWK extiende o utiliza.
  • Enums: enumerados creados con el objetivo de facilitar la lectura del código, con lo que se evita tener que usar números mágicos o cadenas de caracteres fijas en el código.
  • Languages: en este directorio se encuentran las distintas hojas de idiomas que se emplean en el proyecto.
  • Services: aquí se encuentran los servicios. Son extensiones de los modelos creados en el SDK de LogiCommerce que añaden acciones a una petición de un modelo o crean funciones para simplificar la petición de recursos comunes.
  • ThemesConfigurations: en este directorio se encuentran las distintas clases que cargan las configuraciones, según tema o tema y versión.
  • Twig: se encuentran las clases directamente vinculadas con la carga del motor de Twig, así como la ampliación de sus funciones.
  • ViewHelpers : en este directorio, separados por tipos de recursos de capa de presentación, están los distintos ViewHelpers. Son una serie de objetos que sirven de ayuda en la visualización, pero que no están vinculados a las clases de Twig.

Código de Commerce

En este bloque se encuentra la definición de todo aquello que personalizará cada uno de los proyectos según las especificaciones de diseño y operativas particulares. El código de Commerce tiene la misma lógica de estructura de directorios que FWK, ya que se considera una extensión de este. Para que esto sea efectivo, cualquier sobrescritura que se haga en el código de Commerce deberá ser en la misma ruta que su homónimo en FWK.

Al igual que FWK, también está basado en MVC y se estructura en dos grandes bloques:

themes

En este directorio están los scripts de Twig que se usan en la visualización de la respuesta. Estos scripts están divididos en temas y hay un directorio para cada uno de ellos. En el apartado “Estructura de los temas de Twig” se define con más detalle los subniveles de esta parte.

En cuanto a los directorios creados en este nivel, es importante tener en cuenta que los directorios de los temas Core e Internal son una extensión de FWK, por lo que los scripts que se definan en ellos sobrescribirán a sus homónimos en FWK.

assets

En este directorio se encuentra todo el contenido estático, estructurado en ámbitos, que compone el proyecto. Estos son los ámbitos principales:

  • commerce: donde se encuentran los archivos que se usan como base para el proyecto, independientemente del tema.
  • themes: donde se encuentran los archivos directamente relacionados con los temas. En su interior hay que crear un directorio para cada tema. Dentro de cada uno de ellos, se alojan, por un lado, los contenidos estáticos que sirven de base o son comunes para todas las versiones creadas y, por otro, existe un directorio versions que contiene, a su vez, un directorio por versión, donde se ubican los contenidos estáticos específicos de dicha versión.

Para poder hacer referencias a estos contenidos estáticos en código, hay que incluirlos en el archivo assets.json. Este archivo contiene el conjunto de referencias a los distintos ámbitos, versiones y tipos de contenido estático.

El archivo assets.json también se usará en el proceso de fusión de los archivos en producción, uniendo todas las referencias que se indiquen dentro del bloque files. Por ejemplo, todas las referencias a archivos que haya en commerce → css → default → files se unirán en un único archivo y, además, según lo que se indique en el correspondiente atributo minify, se minificará el archivo resultante o no.

Es importante destacar que el proceso de despliegue en producción solo publica los archivos que están dentro de los directorios commerce y themes . Si en un entorno local se trabaja con archivos fuera de estos directorios, en ese entorno funcionará, pero, al no subirlos, el entorno de producción no encontrará esos archivos.

src

Dentro de este directorio se encuentra el código PHP del código de Commerce. Este código está estructurado de la misma manera que FWK, ya que, principalmente, todos los elementos que están en el código de Commerce son extensiones de elementos de FWK adaptados a las especificaciones operativas y de diseño del proyecto.

En la raíz de esta carpeta hay dos archivos de PHP esenciales:

  • _config.php: este archivo contiene la definición de las constantes que se usan en el código. Esto permite disponer de un único punto donde habilitar o deshabilitar el sistema de caché de Twig, indicar dónde está el código del FWK y del SDK de LogiCommerce o el tiempo de vida de la sesión, entre otros valores configurables.
  • index.php: este archivo es el punto de inicio de las peticiones. En él se importa el código del SDK y del FWK de LogiCommerce al proyecto del código de Commerce, y resuelve la petición.

Lógica de una petición

A continuación, se explican las etapas básicas de una petición dentro del código; se obviará el paso de la petición por sistemas enrutadores, caché o normas de .htaccess.

index.php

Este archivo es la puerta de entrada de todas las peticiones al proyecto. Carga la configuración del proyecto (_config.php) y, posteriormente, los repositorios del SDK y del FWK de LogiCommerce. Una vez montado todo el código, se crea un objeto de tipo Shop, que iniciará el procesado de la petición.

Shop

Este objeto se encarga de inicializar, cargar y gestionar los componentes principales que se utilizarán para procesar la petición. Para ello:

  • En primer lugar se inicializa la aplicación. En este paso se establece la conexión con la API de LogiCommerce para obtener el token de acceso, el cual permitirá realizar peticiones a dicha API. A continuación, se obtienen los ajustes y las configuraciones del Commerce que se hayan definido en LogiCommerce y se almacenan en caché, lo que permitirá acceder rápidamente a cualquier configuración sin necesidad de repetir peticiones a la API. El tiempo de vida de esta caché viene definido por la constante CACHE_LIFE_TIME (su valor predeterminado es de 30 minutos).

  • El siguiente paso es inicializar la sesión, es decir, el sistema de persistencia de la información entre peticiones. Según el valor de la constante REDIS_SESSIONS, la información de sesión se almacenará en Redis o en el propio servidor PHP.

El proyecto usa el sistema de sesión nativo de PHP, pero para controlar la información que se guarda y mantener una correcta concordancia entre los datos, solo se accede a $_SESSION a través de una clase propia llamada “Session”. Esta clase es la encargada de gestionar todo lo que se almacena y se obtiene de $_SESSION. En la inicialización, si es que aún no se dispone de sesión, se asignan a Session objetos vacíos que, posteriormente, se irán usando para guardar información, como el usuario, el tema de visualización o artículos para el comparador.

En este momento de la petición disponemos de sesión y de conexión con la API de LogiCommerce. A continuación, se analiza esa petición. Para ello, se crea una instancia del objeto Router desde el objeto Shop.

Router

Bajo esta clase se analiza la ruta del recurso que se ha solicitado en la petición que ha realizado el cliente y se determina qué controlador debe procesarla. Es necesario distinguir primero entre dos tipos de peticiones:

  • Internas: las peticiones internas son las que la misma lógica del proyecto sabe determinar de manera autosuficiente qué controlador es el encargado de procesarla, como por ejemplo, cargar el controlador de la página de error, de página no encontrada, acciones como añadir un producto a la cesta de la compra o resolver el inicio de sesión de usuario.

  • Externas: para estas peticiones se requiere hacer una consulta a la API de LogiCommerce para saber qué controlador se debe cargar. La API devolverá toda la información asociada, como puede ser el tipo, y de esta manera, saber qué controlador se necesita, el tema de visualización, monedas, idiomas, etc.

Tanto si es por vía interna como externa, en esta fase de la petición ya se dispone de información para saber qué controlador se debe cargar. Por lo tanto, se procede a crear el objeto Controller del tipo requerido y se lanza el mensaje run.

Controller

Siguiendo el esquema MVC, el objeto Controller obtendrá y calculará todos los datos necesarios para la petición. Esta información se obtendrá a través de peticiones a la API de LogiCommerce usando, principalmente, dos estrategias:

  • Peticiones por lotes: estas peticiones son una herramienta muy útil de la API (Bulk API) que nos permite unificar en una sola petición varias llamadas de tipo GET, las cuales se resuelven en la API de forma paralela. Como la optimización en tiempos de carga es muy patente, de manera predeterminada cada controlador crea una de estas peticiones para que el programador vaya incluyendo en ella todas las llamadas que no requieran el resultado de una llamada anterior.

  • Peticiones unitarias: si la petición que se realiza a la API de LogiCommerce es de tipo POST o PUT o no se puede incluir en una petición por lotes, habrá que optar por peticiones unitarias a la API.

Estas dos vías de petición que se pueden realizar a la API se han trasladado al controlador en dos funciones que se ejecutan automáticamente. De esta manera, primero se resuelve la petición por lotes para que el sistema disponga de todos sus resultados, y luego se complementa esta información con peticiones unitarias, si es necesario.

Con toda esta información, más cálculos o lógicas resueltas en el controlador, se creará una tabla modelo de tipo clave-valor, que será la que se envíe al motor de Twig para después usarla en los scripts de Twig; mediante el uso de la clave se podrá acceder al valor.

Twig

El objeto Controller creará el motor de Twig a través de la clase TwigLoader. A dicho motor se le asignarán, principalmente, cinco bloques nuevos:

  • Macros: en FWK se ha generado un bloque completo de macros que se integran dentro de Twig para que se puedan utilizar en cualquier punto. El bloque de macros está condicionado por modos para que, sin intervención del programador, este detecte si tiene que devolver el código en formato Boostrap3, Boostrap4 o AMP, entre otros.

  • Variables globales: de forma predeterminada se carga un bloque de variables globales, como podrían ser los datos de sesión, configuración del Commerce, información de la ruta, hojas de idiomas, etc. para que puedan usarse fácilmente desde cualquier parte de los scripts de Twig.

  • Helpers: son objetos que facilitan la obtención de salidas. Se crean a partir de un objeto y permiten obtener salidas de este de una manera más fácil.

Un Helper de producto, por ejemplo, podría devolver, entre otras cosas, ese objeto de producto convertido a json bajo un determinado formato.

  • Funciones: se añaden a Twig una serie de funciones que no incluye de forma predeterminada, como pueden ser dump(), abort(), localizedCurrency(), ucwords(), entre otras muchas.

  • Data: en este punto, al motor de Twig se le inyectan todos los datos calculados en el controlador para que puedan usarse en los scripts.

Finalmente se procede a interpretar la respuesta. Para ello, al motor de Twig se le asigna el nombre del tema que se debe cargar, el cual se ha obtenido de la información de la ruta. A partir de este punto, todas las rutas serán relativas a este tema. Además, se asignan la plantilla y la disposición correspondientes, que incluyen el detalle de la salida que se va a construir.

Finalmente, el texto que se obtiene de la interpretación se envía a la clase Response.

Response

Esta clase se encarga de centralizar la información de la respuesta. A lo largo de la petición se han ido añadiendo a esta clase las cabeceras que debían devolverse en la respuesta de la petición, y ahora le ha llegado el cuerpo generado en el motor de Twig.

Por lo tanto, termina el proceso asignando las cabeceras de la petición y el cuerpo de esta. Con esto, finaliza el ciclo de la petición, se vuelve de nuevo a la clase Shop y se devuelve la respuesta al cliente.

Estructura de los temas de Twig

Elementos principales

Los temas de Twig que aplicará el proyecto están divididos en 5 tipos de elementos:

  • Theme: es el elemento principal y engloba un estilo gráfico que se puede aplicar a las diferentes versiones que contiene.
  • Versions: las versiones son los distintos diseños aplicables del tema. Por ejemplo, la versión desktop sería para clientes que se muestran en monitores normales, mientras que la versión mobile está diseñada para clientes que se muestran en móviles o tablets.
  • Layouts: son las distintas estructuras o disposiciones que se pueden aplicar dentro de una versión para que pueda encajar el contenido.
  • Content: es la plantilla del contenido final que se va a mostrar y se basa en una disposición (layout). Por ejemplo, puede ser un contenido de categoría, de producto o de la cesta de la compra.
  • Snippet: son elementos genéricos que se pueden usar en un layout o en un content; se pueden reutilizar donde se necesite. En el motor de Twig se podrán usar a modo de Includes o de Macros.

Distribución de los elementos

Dentro del directorio themes del proyecto se encuentran los distintos temas y, a su vez, para cada uno de estos, se incluyen los distintos elementos que los componen.

Los temas pueden tener versiones o no. En caso de no tenerlas, los directorios layouts, content y snippets dependerán directamente de la raíz del tema. En caso contrario, adicionalmente dentro del tema, habrá un directorio por versión. En el interior de cada una de las versiones se incluirán sus respectivos directorios layouts, content y snippets.

Controlador – Layout – Content

A partir del tipo de controlador que se obtiene a través del objeto Router (según se ha explicado anteriormente) y el tema que este asigna, el sistema genera automáticamente las rutas para obtener la correspondiente disposición (layout) y contenido (content).

Disposición (layout):

Nombre del archivo: viene definido en el objeto Theme con el que hemos inicializado el TwigLoader. Este valor será la parte principal del nombre del archivo Twig que se va a cargar, y al que se debe añadir el formato que corresponda, como por ejemplo, “html”, “js”, “json”, y el sufijo final twig. El nombre completo podría ser "default.html.twig".

Ubicación: este archivo se buscará en el directorio "layouts", definido en la raíz de la versión del tema, si tiene versiones, o en la raíz del tema, si no dispone de versiones.

Por ejemplo: themes\default\desktop\layouts\default.html.twig


Contenido (content):

Nombre del archivo: del mismo modo que la disposición, el contenido viene definido en el objeto Theme, y de igual forma, a su nombre se le concatenará el formato y el sufijo "twig". Podría obtenerse, por ejemplo, "default.html.twig".

Ubicación: por norma general, un archivo de tipo content está asociado a un controlador. Por ello, se ha aplicado la misma lógica de ubicación que la usada para los controladores, los cuales se estructuran según el tipo de elemento.

Como reflejo de ello, los directorios para llegar al content, empiezan por letra mayúscula, como los paquetes y clases hasta llegar al controlador. Por ejemplo, el content asociado al controlador de la ficha de producto sería: