Desenvolupament corporatiu amb Drupal

1. Bones pràctiques

Com a bones pràctiques i de forma general per qualsevol projecte web: 

  • Intentarem seguir les best practices del producte i els seus estàndards de codificació: https://www.drupal.org/docs/develop/standards
  • Per al javascript i els estils utilitzarem fitxers .css i .js, mai styles o scripts inline.
  • Per al HTML intentarem que el codi estigui principalment en fitxers .twig o es generi a través d'un editor WYSIWYG amb filtratge i correcció d'HTML activat.
  • Les actualitzacions i els patches es gestionen sempre via composer, i el fitxer composer.json ha d'estar al dia i reflexar els mòduls i versions que necessita el projecte.
  • Per raons de seguretat no pot haver-hi javascript en base de dades i els usuaris drupal no han de poder escriure codi javascript, tampoc l'usuari administrador.
  • El projecte s'ha d'entregar amb tots els mòduls i core a la última versió estable o a la última versió dev si fos imprescindible.
  • La web ha de complir els estàndard d'accessibilitat (Validadors recomanats: WAVE per Chrome i https://validator.w3.org.)

2. Instal·lació del Drupal

Per desenvolupar amb Drupal s'utilitzarà composer per fer la instal·lació i gestionar els patches i les dependències. Utilitzarem la darrera versió estable de Drupal compatible amb la nostre versió de PHP:

$ composer create-project drupal/recommended-project DIRECTORY-PROJECTE 10.*

Per evitar problemes de versions definirem la versió PHP de l'entorn en el composer.json per instal·lar les versions compatibles dels paquets i evitar incompatibilitats. Les versions PHP són: LAMP4 = 8.2 (servidors antics: LAMP 2 = 5.3, LAMP 3 = 7.2 i LAMP3HA = 7.4)

$ composer config platform.php 8.2.26
"prefer-stable": true,
"config": {
    "sort-packages": true,
    "process-timeout": 0,
    "platform": {
        "php": "X.Y.Z"
    }
}

Per seguretat el projecte disposarà d'un subdomini que apuntarà a la carpeta /web on hi haurà el core de drupal i els mòduls, themes i fitxers de la web.

Els directori de /vendors i els fixters privats /private i les configuracions del site /config/sync aniran a l'arrel del projecte i no seràn accessibles per URL directe.

3. Afegir un nou mòdul

$ composer require 'drupal/responsivewrappers:^2.0' --prefer-dist

4. Parxejar amb un hotfix

Per afegir un patch editarem el fitxer composer.json i afegirem el fitxers de diferències el-fix-a-aplicat.patch a la secció "patches" d'aquest. Indicarem sempre una petita descripció del que fa aquell hotfix i una referència al fitxer que cal aplicar.

Exemple composer.json:

"extra": { 
  "patches": { 
    "drupal/address": { "Drupal Addess fix default syncing": "patches/address_syncing.patch" } 
  }
}

Un cop editat el composer.json un simple: $ composer update serà suficient perquè s'apliqui el hotfix.

Això garantirà que el fix es segueix aplicant automàticament al llarg de les actualitzacions i no caldrà re-aplicar els hotfixes cada cop que s'actualitza el codi.

Si enlloc de parxejar el mòdul general de tots els sites volem aplicar el hotfix només al nostre projecte farem el següent:

  1. Copiarem el mòdul a la carpeta /web/sites/elmeuprojecte.diba.cat/modules/contrib/elmeumodul
  2. Copiarem el patch a /web/sites/elmeuprojecte.diba.cat/modules/contrib/elmeumodul/patches
  3. Editarem el composer.json del mòdul en qüestió afegint el patch
  4. Executarem un composer update des de dins de la carpeta del mòdul.

5. Actualització del codi a les últimes versions estables

$ composer update --with-dependencies --prefer-dist

6. Altres consideracions sobre les versions dels mòduls al composer

Les versions dels mòdul s'han de definit de la següent manera:

  • Sempre que es pugui definirem només la versió mínim requerida amb ^, per exemple: "^2.0"
  • Si cal fixar una subversió, prioritàriament deixarem oberta les actualitzacions de bugfixing: "9.5.*"
  • Si cal finar una versió concreta ho justificarem.
  • Eliminarem el forçat de versions @RC, @beta o @alfa sempre que sigui possible, per exemple: "^2.0@beta" és una especificació a evitar perquè quan surti una versió estable ens quedarem sempre a la beta. Milllor eliminarem el @beta i actualizem el "minimum-stability":"dev" per acceptar versions beta.
"dompdf/dompdf": "2.0.3" == millor ==> "^2.0"
"drupal/address": "^1.10@beta" == millor ==> "^1.10"
"drupal/core-recomended": "10.2.10" == millor ==> "10.2.*"

7. Settings

Tots els projectes utilitzaran el settings.local.php con configuració general de la web estarà en el settings.php però els configruació específiques de l'entorn (com per exemple l'usuari/password de la base de dades) estaran al settings.local.php.

8. Base de dades

La LAMP3HA utilitza una plataforma en alta disponibilitat amb tres nodes MariaDB. Dos nodes poden fer de master i un de slave, pel que poden configurar el sistema com a master/master/slave o master/slave/slave.

Per connectar-se es fa a través del balancejador maxScale:

Desenvolupament: 192.168.156.88:3307

Tots els projectes drupal sempre definiran un prefix a les seves taules (unes poques lletres identificatives del projecte seguides d'un guió baix, per exemple: $prefix = 'db_'). Si és un projecte donat d'alta al GVUS es pot utilitzar el codi del projecte per prefixar les taules.

9. Integració amb el VUS i mòduls corporatius (Drupal 10)

Tots els projectes Drupal de la Diputacció de Barcelona portaran instal.lat i activt el següent mòdul:

composer require 'drupal/diba_integration'

Aquest mòdul inclou la integracció amb el VUS i la resta de mòduls que utilitza la corporacció per fer manteniment o estadístiques

10. Integració amb el VUS i mòduls corporatius (Drupal 9 obsolet)

La Diputació de Barcelona utilitza el projecte VUS com a sistema de Validació d'USuaris corporatius. Actualment hi ha un mòdul d'integració del Drupal 8/9/10 amb el VUS que pots incorporar al teu projecte utilitzant el composer.

Per afegir el mòdul VUS o la sincronització de l'organigrama, municipis o comarques al teu projecte et cal demanar accés al repositori privat del GitLab on es manté aquest mòdul. Un cop tens un usuari amb accés simplement has d'afegir el repositori al fitxer composer.json de l'arrel del teu project, quedant de la següent forma:

"repositories": [
    {
        "type": "vcs",
        "url": "https://gitlab.com/diputacioBCN/drupal8/vus"
    },
    {
        "type": "vcs", 
        "url": "https://gitlab.com/diputacioBCN/drupal8/taxonomy_dibasync" 
    },
    {
        "type": "vcs",
        "url": "https://gitlab.com/diputacioBCN/drupal8/tag-manager-cookie-warn"
    }
]

I requerir els mòduls que necesitis en el teu projecte:

composer require 'drupal/vus'
composer require 'drupal/tag_manager_cookie_warn'
composer require 'drupal/taxonomy_dibasync'

Aquesta comanda afegirà automàticament la darrera versió del mòdul al teu projecte i l'actualitzarà cada cop que surti una nova versió i llencis un: composer udpate del teu projecte.

Un cop hagis incorporat el mòdul del VUS al teu projecte simplement has de desplegar el codi i activar el mòdul a la teva instal·lació del Drupal.

Els alres 2 mòduls serveixen per:

  • tag_manager_cookie_warn: Activar i gestionar el misstage d'advertència de les cookies, junament amb el tag manager de Google.
  • taxonomy_diasync: Sincronitzar els noms dels municipis, comarques o orgànics en una taxonomia Drupal.

11. Mòduls no recomanats

No usarem mòduls de Drupal que hagin tingut molt poc us, és a dir, que a la informació del projecte digui que el mòdul l'estan usant molt pocs sites.

El mòdul reCAPTCHA no és gratuït per la nostra organtizació, per tant, no l'usarem. 

12. Esborrat de fitxers no utilitzats

Per tal de no acumular fitxer innecesaris cal marcar al fitxer settings.php o settings.local.php la variable:

$config['file.settings']['make_unused_managed_files_temporary'] = TRUE;

Sinó els fitxers o imatges que algun cop s'han pujat al servidor no s'esborren MAI.

Aquesta configuració NO es retroactiva, pel que si cal fer neteja i revisar els fitxers i imatges no utilitzats al servidor es poden utilitzar mòduls com Audit FilesFancy file delete o File Delete.

13. Disseny corporatiu (Drupal 10)

Per fer webs amb disseny corporatiu hi ha un tema que ja aplica el disseny corporatiu. Es recomana crear un sub-tema pel projecte per tal de poder sobre-escriure tot allò que es necessiti del tema original.

Diba Clean, és el tema corporatiu mantingut que alhora és un subtema del tema Boostrap basat en Bootstrap 5: https://www.drupal.org/project/diba_clean

Instal·lació:

composer require 'drupal/diba_clean'

Per crear el teu sub-tema del projecte el fitxer el-meu-tema.info.yml hauria de tenir un format silimar a això:

name: El meu tema
type: theme
description: 'Tema del meu projecte desenvolupat per XYZ.'
base theme: diba_core

Nota: Això només aplica en el cas de fer una web amb disseny corporatiu complet.

14. Llibreries JS

Si el teu projecte utilitza llibreries, cal vincular la seva actualització via composer.

Per fer això farem el següent:

  • Executar: composer require --prefer-dist composer/installers. Aquest paquet facilit la instal·lació amb el composer de paquets en directoris diferents al "/vendors" (per  exemple "/libraries").
  • Ala secció: "installer-paths" del "composer.json" assegurat que existeix la ruta: "web/libraries/{$name}": ["type:drupal-library"],
  • Afegieix les llibreries JS a la secció "repositories" del composer.json que vols utilitzar. Per exemple, si volem afegir la llibreria del Google Charts simplement afegim el seu repositori com un repositori més:
"repositories": [
        {
            "type": "package",
            "package": {
                "name": "google/charts",
                "version": "45",
                "type": "drupal-library",
                "extra": {
                    "installer-name": "google_charts"
                },
                "dist": {
                    "url": "https://www.gstatic.com/charts/loader.js",
                    "type": "file"
                },
                "require": {
                    "composer/installers": "~1.0"
                }
            }
        }
]
  • I per últim podem llençar la següent comanda per afegir la dependència de la nova llibreria pel nostre projecte i es descarregarà i actualitzarà la llibreria a la carpeta /libraries del nostre projecte amb totes les seves dependències: composer require --prefer-dist google/charts:45

Exemple referenciant una llibreria externa compactada en un zip (Chosen):

        {
            "type": "package",
            "package": {
                "name": "harvesthq/chosen",
                "version": "1.8.7",
                "type": "drupal-library",
                "extra": {
                    "installer-name": "chosen"
                },
                "dist": {
                    "url": "https://github.com/harvesthq/chosen/releases/download/v1.8.7/chosen_v1.8.7.zip",
                    "type": "zip"
                },
                "require": {
                    "composer/installers": "~1.0"
                }
            }
        }

Per efegir-la:

 composer require harvesthq/chosen:1.8.7

Exemple d'un fitxer d'un projecte corporatiu: composer.json

15. Composer Merge Plugin

Si un mòdul utilitza vàries llibreries externes, per exemple múltiples llibreries JS es una bona pràctica que el mateix mòdul defineixi les seves dependències en el seu propi fitxer de configuració i utilitzar el Composer Merge Plugin per afegir descarregar totes les llibreries externes.

Un exemple concret són les llibreries que utilitza el mòdul Webform, i que és la via recomanada per instal·lar-les:

https://www.drupal.org/node/3003140

16. Altres mòduls corporatius per a Drupal

Per tal de donar resposta a altres necessitats, a la Diputació de Barcelona s'han desenvolupat altres mòduls que poden ser d'utilitat pels projectes de la corporació:

17. Usuaris i rols d'usuari

Tot projecte ha de tenir, com a mínim, els següents rols:

  1. Administrador: Te tots els permisos i el gestiona informàtica de la Diputació de Barcelona.
  2. Gestor: Pot gestionar usuaris, menús, taxonomies i el que requereixi l'aplicació. Aquest rol no ha de tenir capacitats per activar nous mòduls o fer tasques d'administració, i el tindrà l'equip departamental responsable
  3. Editor: Pot crear/editar contingut. Aquest rol no ha de tenir capacitats per activar nous mòduls o fer tasques d'administració.

Per defecte sempre ha d'existir un usuari amb rol superadministrador amb nom: admindiba, que correspondrà a l'usuari amb identificador 1 (uid=1) i serà l'utilitzat per l'Oficina Tècnica d'Internet per administrar la web i tindrà tots els permisos.. Anirà associat al rol administrador.

Els rols, com el rol Gestor, que gesiona usuaris/rols, no podrà mai assignar-se el rol administrador. Recomanem algun dels següents mòduls, per evitar-ho:

18. Reverse Proxy

L'entorn de producció utilitza un reverse proxy pel que cal configurar-lo als settings:

$settings['reverse_proxy'] = TRUE;
$settings['reverse_proxy_addresses'] = [@$_SERVER['REMOTE_ADDR']];
$settings['reverse_proxy_trusted_headers'] = \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_FOR | \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_HOST | \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PORT | \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PROTO | \Symfony\Component\HttpFoundation\Request::HEADER_FORWARDED;

19. Servidors de confiança

Cal definir al drupal els trusted_host corporatius al fitxer de settings que en cas de tenir subdoini diba seràn:

 $settings['trusted_host_patterns'] = [
   '^diba\.cat$',
   '^.+\.diba\.cat$',
   '^diba\.es$',
   '^.+\.diba\.es$',
 ];

20. Directori de fitxers

Definirem el directori de fitxers privats, de configuració i de temporals fora de la part accesible per url i dins de la carpeta del projecte:

$settings["config_sync_directory"] = '../config/sync';
​$settings['file_private_path'] = '../private';
$settings['file_temp_path'] = '../private/tmp';

A més, cal habilitar les opcions de transliteracció peruqè els fitxers i imatges que s'afegeixin a tarvés del backoffice es transliterin automàticament als caràcters ASCII96, en minúscules i sense espais ni caràcters especials.

21. Continguts paginats, exportació de continguts, generació de pdfs, Excel, csv, etc..

Els recursos del servidor son limitats, per tant, a l'igual que les cerques de contingut no poden mostrar infinits resultats ja que això penalitzaria molt la web i s'han de paginar, s’ha de preveure que si és genera un fitxer, d’un o varis continguts que poden anar creixent amb el temps, la descarregar del fitxer s'ha de fer en diversos fitxers. Una solució és fer que el fitxer a descarregar sigui el resultat d'una cerca paginada, així que cada pàgina permet descarregar un fitxer nou. Tingueu en conta que afegir imatges, consumeix molts recursos, així que intenteu afegir el mínim d'imatges i el més optimitzades possibles.

22. Mida de les imatges

Els camps d'imatge definirem un mida màxima d'imatge, així evitem que Drupal guardi imatges gegants, amb un màxim de pes, de per exemple 10MB, segons les necessitats.

Al mostrar la imatge, definirem un estil d'imatge de Drupal per visualitzar-la (Els estils d'imatge es defineixen a: /admin/config/media/image-styles i s'assignen al gestionar la presentació del  tipus de contingut que té la imatge.) Amb això optimitzem la pàgina web perquè carregui la web ràpidament amb la imatge de les mides exactes a les necessitades.

Si el ckeditor permet pujar imatges, limitarem també les dimensions i pes màxim d'aquestes (/admin/config/content/formats/).

23. Composer i timeout

Si a l'executar composer, aquest dona problemes de timeout, és poden afegir les següents instruccions:

    "config": {
        "process-timeout": 0,
    },

24. Passos mínims en el desenvolupament d'un nou producte

  1. Abans d'iniciar el projecte:
    • L'empresa que fa el desenvolupament ha de realitzar una reunió amb els tècnics d'informàtica per pactar tecnologies, versions i solucions. NO ÉS POT INICIAR EL DESENVOLUPAMENT SENSE UNA REUNIÓ TÈCNICA PRÈVIA AMB EL SERVEI D'INFORMÀTICA.
    • Es llegiran i seguiran les pràctiques descrites en aquest document.
  2. Abans d'entregar el projecte:
    • El servei client de la Diputació ha d'haver validat i revisat el projecte a nivell funcional prèviament abans de l'entrega del projecte al servei d'informàtica amb contingut realista i de prova.
    • S'ha de facilitar un url d'accés o un projecte dockeritzat amb continguts realistes i un usuari d'administrador al servei d'informàtica per poder fer una revisió inicial abans de cap entrega o instal·lació als servidors corporatius.
    • S'ha de facilitar en tot moment abans de cap entrega o instal·lació fitxers clau com el: composer.json per a una revisió inicial.
  3. Entrega del projecte:
    • S'entregarà el projecte sense vendors ni libraries, amb un composer.json funcional i capaç de generar tots els vendors i libraries executant la comanda: composer install. Si el composer install no funciona correctament no s'acceptarà l'entrega.
    • Les versions del core i mòduls entregats no poden tenir pendent cap actualització de seguretat, i cal tenir la resta de mòduls i llibreries el més actualitzats possible. Si hi ha actualitzacions de seguretat pendents o actualitzacions de bugfixing pendents des de fa més de 3 mesos no s'acceptarà l'entrega.
    • El servei d'informàtica revisarà el codi del projecte i envirà feedback de coses a solucionar abans de cap instal·lació.

25. Revisions finals

  • El projecte ha de ser instal·lable i actualitzable via composer.
  • El composer.json només ha de tenir els mòduls necessaris i utilitzats, feu neteja de mòduls si no s'utilitzen.
  • En el composer.json, els pegats de seguretat de Drupal han de tenir el codi de referencia de Drupal, per trobar-los amb facilitat.
  • El mòdul devel no ha d'estar actiu.
  • Els mòduls i themes contribuïts han danar a /modules/contrib i themes/contrib, els mòduls i temes a mida han d'anar a /modules/custom i themes/custom. Els mòduls i themes contribuïts però modificats han d'anar a */contrib amb un patch que apliqui els canvis realitzats.
  • Per seguretat, només han d'estar actives les vistes o formularis utilitzats, deshabiliteu els que no s'utilitzin com la vista search o el formulari de contacte, si no s'utilitza.
  • La transliteracció de fitxers està activada. A Drupal 10+ es: /admin/config/media/file-system
  • El cercador per defecte de drupal (search), si no s'utilitza, treieu-li els permisos d'accés als usuaris anònim o als usuaris que no hagin de tenir accés: /admin/people/permissions
  • No permeteu que els usuaris anònims puguin crear nous usuaris si no és estrictament necessari, i sempre requeriu la confirmació del correu i a ser possible l'aprovació d'un administrador.
  • Oculteu els missatges d'error: /admin/config/development/logging
  • Reviseu el log d'error de Drupal (/admin/reports/dblog), aquest no pot generar avisos de themes, blocks, hooks, etc.. no trobats , ni errors de cap tipus.
  • Urls dels continguts de la web han de ser amigables (que no apareguin urls del tipus /node/213123)
  • L'informe d'estat no ha de donar errors i s'han d'arreglar les alertes, si es possible: /admin/reports/status
  • La web ha de ser accessible al nivell AA i ha tenir una pàgina pròpia d'accessiblitat, similar a: https://www.diba.cat/ca/accessibilitat, però exclusiva pel seu site. La web ha de tenir un l'avís legal, cal validar si s'ajusta a l'avís legal corporatiu i enllaçar-lo (https://www.diba.cat/avislegal) o si cal crear-ne un de propi.
  • La web ha de complir la normativa de cookies. En general, haurà de tenir el mòdul diba_integration instal·lat i configurat perquè enllaci a la pàgina d'avis legal.
  • Drupal envia correus, per registrar-se, recuperar contrasenya, etc. per tant, haurà de venir configurat amb una bustia corporativa (domini diba.cat): /admin/config/system/site-information
  • favicon correcte, en el cas de ser el corportaiu ha de ser: https://maqueta.diba.cat/v3/assets/img/favicon.ico