Carnet d'un développeur

les pérégrinations d'un developpeur sur le Web

Alors aujourd’hui pour continuer un peu la série migration, voilà une nouvelle problématique : le mode cluster et index_cluster.php pour la distribution des images.

Pour l’historique, en eZpublish 4.6, j’utilise le mode cluster fichiers. C’est à dire une base de données pour stocker les « metadatas » (en fait c’est pour gérer les dates et les expirations, pas des metadatas comme pour les images) et un système de fichier nfs pour partager les fichiers entre plusieurs frontaux.
Dans l’ancien système, c’est plutôt simple : index_cluster.php interroge la base de données pour récupérer des infos comme la date de dernière modif et crache l’image avec un header qui va bien.
L’idée c’est que lire des infos comme la date de dernière modif sur un système de fichier comme nfs ça n’a pas toujours été très fiable. Du coup on découple le fichier physique et les infos liées à ce même fichier en les stockant dans une base de données.

Avec eZpublish 5.4, il y a une évolution par rapport à la 5.3. Dans le fichier de conf apache recommandé (voir \doc\apache2\vhost.Template à la racine de votre install d’eZ), on a :

# If using cluster, uncomment the following two lines:
## For 5.4 and higher:
#RewriteRule ^/var/([^/]+/)?storage/images(-versioned)?/.* /index.php [L]
#RewriteRule ^/var/([^/]+/)?cache/(texttoimage|public)/.* /index_cluster.php [L]
## Versions prior to 5.4:
#RewriteRule ^/var/([^/]+/)?storage/images(-versioned)?/.* /index_cluster.php [L]
#RewriteRule ^/var/([^/]+/)?cache/(texttoimage|public)/.* /index_cluster.php [L]

Donc bien sur, dans mon cas j’ai décommenté les premières lignes. La différence c’est qu’en 5.4, on utilise le stack symfony. Et comme l’idée dans le futur c’est quand même bien de dire au revoir à ez legacy, je me suis empressé de tester ça.

Et là … je dois dire que j’en ai chié … Moi je croyais que c’était magique que ça allait marcher sans rien faire de plus :).
Donc d’abord, on commence par une magnifique exception symfony :

Error: Call to a member function getTimestamp() on a non-object in /var/www/vendor/ezsystems/ezpublish-kernel/eZ/Bundle/EzPublishIOBundle/BinaryStreamResponse.php line 107
500 Internal Server Error - FatalErrorException

Bon forcément, d’un coté (legacy) on a un chemin nfs, de l’autre on lui a rien dit … Forcément, ça doit coincer au niveau de l’emplacement du fichier :). A ce moment commence la recherche du paramétrage à modifier pour changer le chemin des fichiers.

Après quelques recherches, on finit par tomber sur la doc eZ : https://github.com/ezsystems/ezpublish-kernel/blob/master/doc/specifications/io/legacy_dfs_cluster.md

Malheureusement, en recopiant les infos de cette doc, ça ne marche pas (je signale qu’on trouve aussi des versions différentes de la doc qui ne marchent pas mieux).

Première erreur :

ServiceNotFoundException: The service "ezpublish.core.io.metadata_handler.legacy_dfs_cluster.dfs" has a dependency on a non-existent service "ezdfs_connection".

Cette erreur est causée par le fait que legacy_dfs_cluster.dfs veut un service et on lui fournit un scalar. Après m’être posé des questions existensielles sur si ma connexion dbal était bien paramétrée ou pas, j’ai fini par arriver à la doc de symfony, qui dit :

Each connection is also accessible via the doctrine.dbal.[name]_connection service where [name] is the name of the connection.

Donc, pour résumer, il faut donc remplacer :

ez_io:
    binarydata_handlers:
        nfs:
            local:
                adapter: nfs_adapter
    metadata_handlers:
        dfs:
            legacy_dfs_cluster:
                connection: ezdfs

par

ez_io:
    binarydata_handlers:
        nfs:
            local:
                adapter: nfs_adapter
    metadata_handlers:
        dfs:
            legacy_dfs_cluster:
                connection: doctrine.dbal.ezdfs_connection

Premier problème résolu.

Après (ou avant) on a une erreur simple …

ez_io:
    binarydata_handlers:
        nfs:
            local:
                adapter: nfs_adapter
    metadata_handlers:
        dfs:
            legacy_dfs_cluster:
                connection: ezdfs

oneup_flysystem:
    adapters:
        nfs:
            local:
                # The last part, $var_dir$/$storage_dir$, is required for legacy compatibility
                directory: "/path/to/nfs/$var_dir$/$storage_dir$"

ça ne marche pas car il faut écrire :

oneup_flysystem:
    adapters:
        nfs_adapter:
            local:
                # The last part, $var_dir$/$storage_dir$, is required for legacy compatibility
                directory: "/path/to/nfs/$var_dir$/$storage_dir$"

C’est un peu l’inverse du problème précédent.

Maintenant, on tape bien dans la base définie pour le cluster, y a plus d’erreur d’adapter indéfini, mais par contre on revient à l’erreur originelle.
Après avoir testé :

ezpublish:
    system:
        default:
            io:
                metadata_handler: dfs
                binarydata_handler: dtc

Et n’avoir pas reçu la moindre erreur (je n’ai bien sur pas défini « dtc »), j’en ai déduit que le binarydata_handler, ben il s’en contrefichait pas mal. Je n’ai pas creusé plus, je suppose que tout n’est peut être pas encore complètement implémenté sur l’aspect « définir des espace de stockage via drivers par siteaccess », surtout que dans l’immédiat, c’est bien beau mais l’admin est loin de supporter tous les systèmes de fichiers proposés.

Quoiqu’il en soit, j’ai trouvé un moyen de faire fonctionner la chose, il suffit tout simplement de redéfinir ez_io.binarydata_handlers.default :

ez_io:
    binarydata_handlers:
        default:
            flysystem:
                adapter: nfs_adapter
    metadata_handlers:
        dfs:
            legacy_dfs_cluster:
                connection: doctrine.dbal.ezdfs_connection

Et là, c’est miraculeux, j’ai mes images de mon partage nfs qui s’affichent !!!
J’espère que ces quelques infos permettront à quelqu’un de ne pas perdre des heures comme moi à lire des tonnes de docs contradictoires.

 

janvier 24th, 2015

Posted In: Developpement Web

Leave a Comment

Afin de bien comprendre ma démarche je vais essayer de résumer la problématique de manière simple :
J’ai X sites (siteaccess) partageant tout un tas de fonctionnalités communes, mais dont l’aspect peut potentiellement changer selon les envies des différents services concernés.
Dans ezpublish 4.6, j’ai plusieurs design pour mettre en commun certaines choses de cette manière :

[DesignSettings]
SiteDesign=siteaccess_name
AdditionalSiteDesignList[]=designcommun2
AdditionalSiteDesignList[]=designcommun1
AdditionalSiteDesignList[]=base

Avant, pour personnaliser un Template spécifique à mon siteaccess, c’est facile, il suffit d’ajouter le Template en question dans le design siteaccess_name et le tour est joué. Mais ça, c’était avant …

Comme tout a changé dans eZpublish 5 avec l’arrivée de symfony, il faut donc se mettre à la mode.
J’ai donc choisi de partir sur la création d’un Bundle « common » pour mettre tout ce que je considère comme commun en terme de design/fonctionnalités. Pour les particularités, je vais créer 1 bundle par siteaccess.
Comme je suis un feignant, je vais essayer de maximiser l’utilisation du fichier de config autant que possible pour éviter de coder des contrôleurs partout pour n’importe quoi et je vais beaucoup m’inspirer du demoBundle qui sera en quelque sorte ma doc.

Je vais passer sur la mise en place des siteaccess et d’une admin fonctionnelle en partant des datas de la 4.6 (je n’avais pas envie de me frapper d’écrire des articles moi même :)).

Afin de gérer mon pseudo héritage, j’ai créé un groupe de siteaccess. Ce groupe me permet de définir des règles pour les templates qui seront écrasées si je les redéfinis au niveau du siteaccess.
C’est super ça marche parfaitement bien pour tout ce qui est location_view & cie.
En suivant l’exemple de ezdemo, j’ai eu tendance à faire des templates pour les view full commençant par :

{% extends "eZDemoBundle::pagelayout.html.twig" %}

ou j’ai remplacé eZDemoBundle par mon CommonBundle.
Le pagelayout.html.twig en question contient tout un tas d’inclusion permettant de définir des morceaux non gérés dans l’admin d’eZ (header, footer, menu, meta & cie).
Evidemment, moi j’ai besoin de redéfinir un peut l’habillage car c’est exactement ce qui a tendance à varier au niveau des sites : un menu avec un look différent, un header spécifique, un footer ne contenant pas les mêmes infos.

En gros j’aimerais beaucoup commencer par un truc du genre

{% extends viewbaseLayout %}

Ou je pourrais faire varier viewbaseLayout selon le siteaccess. C’est à dire que mon Template contenu dans CommonBundle soit capable de faire un extends du layout avec le bon design correspondant au siteaccess.

Après avoir cherché un bout de temps si il existait un moyen simple de changer le viewbaseLayout (qui existe de base et charge EzPublishCoreBundle::viewbase_layout.html.twig), j’ai fini par trouver une solution.

En fait, j’ai trouvé une solution en cherchant des infos sur le configResolver grâce à cet article de la doc : https://doc.ez.no/display/EZP/Dynamic+settings+injection.
Une nouveauté de la version 5.4 (quelle chance) : l’injection dynamique de settings !!!

J’avais remarqué que dans la conf de base on a :

parameters:
    ezpublish.content_view.viewbase_layout: "EzPublishCoreBundle::viewbase_layout.html.twig"

services:
    ezpublish.view_manager:
        class: %ezpublish.view_manager.class%
        arguments:
            - @templating
            - @event_dispatcher
            - @ezpublish.api.repository
            - @ezpublish.config.resolver
            - %ezpublish.content_view.viewbase_layout%
            - @?logger

Et je me suis dit que ce serait bien pratique de pouvoir utiliser l’injection afin de définir un Template par siteaccess.
Et bien ça marche parfaitement bien en modifiant mon fichier de conf de mon CommonBundle :

parameters:
    ezpublish.siteaccess1.content_view.viewbase_layout: "siteaccess1Bundle::pagelayout.html.twig"
    ezpublish.siteaccess2.content_view.viewbase_layout: "siteaccess2Bundle::pagelayout.html.twig"
services:
    ezpublish.view_manager:
        class: %ezpublish.view_manager.class%
        arguments:
            - @templating
            - @event_dispatcher
            - @ezpublish.api.repository
            - @ezpublish.config.resolver
            - "$content_view.viewbase_layout;ezpublish$"
            - @?logger

Et le tour est joué, je peux maintenant faire des pageLayout spécifique comme bon me semble simplement en utilisant les fichiers de conf.

Update

Afin que le reste fonctionne correctement il ne faut pas oublier de mettre un layout par defaut :

ezpublish.default.content_view.viewbase_layout: « EzPublishCoreBundle::viewbase_layout.html.twig »

 

janvier 21st, 2015

Posted In: eZPublish

Leave a Comment

ez_and_symfony_largeAlors pour le premier article de l’année, je vais essayer de parler de ce que je fais en ce moment : prendre mes marques sur eZPublish 5.
Je travaille actuellement sur la version 4.6 et sur un potentiel projet de migration vers la 5.4. Je dois donc me familiariser avec les nouveaux concepts ainsi que le Framework symfony 2.
Je vais essayer de partager mes petites trouvailles dans une série d’articles (j’espère en écrire plus d’un).

 

Attention !!!

Je ne prétends pas que ce sont les bonnes pratiques, les informations que je partagerai au fur et à mesure ont juste résolu mon problème à moment T et j’encourage vivement à ne pas prendre ces informations pour argent comptant.
Il est bien possible que quand vous lirez une des astuces que j’écrirai elle ne soit plus valide ou ne corresponde pas aux bonnes pratiques. Je vous invite donc à la prudence :).

Contexte :

Le contexte est important car les problématiques que je vais rencontrer ne sont pas forcément courante (mais bon j’imagine bien qu’elles ne sont pas si rare non plus :)).
Le contexte est donc le suivant :

  • + de 40 siteaccess.
  • Un design partagé/overridé.
  • Du contenu partagé.
  • mode Cluster.
  • cross link.
  • Multi front (pour l’infra).
  • une DB avec une table ezcontentobject_attribut de 9 Go.

Il y a donc plein de choses à tester et à mettre en place pour explorer les possibilités de la version 5.

 

janvier 21st, 2015

Posted In: eZPublish

Leave a Comment

Page suivante »