david linnard

› Preventing Issues between Dev, Stage and Live environments in eZ Publish

If you are reliant on node IDs in your code it can lead to issues when moving your code between your dev, stage and live environments. Since your live site will have content added much more often, node IDs will tend to be much higher on that compared to your dev and stage environments. It [...]
09/05/2010 9:21 pm (UTC)   David Linnard   View entry   Digg!  digg it!   del.icio.us  del.icio.us

gilles guirand

› Développement avancé avec eZ Find (partie 1 : La gestion des datatypes entre eZ Find & Solr)

Après 2 billets un peu "rapides" sur eZ Find et la gestion des datatypes, ainsi que l'utilisation des facettes pour construire un nuage de tags, voici le premier billet d'une série de tutoriels à propos d'eZ Find, qui décrivent plus en détail son fonctionnement et son utilisation avancée dans divers contextes. Cette série de tutoriels introduit quelques nouveautés de la version 2.2, sera traduite progressivement sur le share.ez.no, et servira de base pour une conférence de la eZ Conference 2010, ainsi qu'aux Recontres Mondiales du Logiciel Libre 2010

Cet article décrit comment eZ Find transforme et adapte les contenus eZ Publish, et leurs datatypes respectifs pour les indexer dans Solr. La compréhension de ces mécanismes bas niveaux d'eZ Find sont des prérequis indispensables lors des phases de développement et de debug, ne serait ce que pour savoir ou chercher et lire les portions de codes permettant de comprendre le rôle exact d'un settings, d'un paramètre ou d'un filtre.

Etape 1 : Prérequis avant de démarrer

Cet article n'a pas vocation à expliquer à nouveau comment installer et indexer son contenu avec eZ Find. La documentation décrit avec précision les opérations à effectuer. Cependant voici quelques astuces permettant de développer dans de bonnes conditions :

Relancer l'indexation du contenu après une modification

Il est parfois laborieux de relancer une indexation complète juste pour tester l'impact d'une modification mineure. Alors il existe pour cela quelques paramètres cachés dans le script /bin/php/updatesearchindexsolr.php, qui permettent de désigner un noeud parent de départ, ainsi q'une limite (attention les 3 paramètres combinés sont nécessaires) :

php extension/ezfind/bin/php/updatesearchindexsolr.php --siteaccess=monsiteaccess --topNodeID=2546 --offset=0 --limit=10
 
 

Vérifier ce que Solr a réellement indexé

Pour savoir si vos contenus et vos attributs sont correctement indexés, il suffit d'effectuer une recherche dans l'interface Web d'administration de Solr : http://localhost:8983/solr/admin/. Cette interface est également utile pour vérifier comment les champs Solr ont été nommés, par exemple sur la version d'eZ Find 2.2, on peut observer 2 champs qui semblent des doublons concernent les titres des articles : attr_title_s et attr_title_t. La suite du billet détaille le comment et le pourquoi de ce comportement.

Debug direct avec Solr

En laissant une console active, pour pourrez observer les messages envoyés vers Solr de la forme :

INFO: [] webapp=/solr path=/select params={ ... MESSAGE ... } status=400 QTime=5
 

Ce message peut être copier / coller à partir de la console, vers la fin de l'URL dans l'interfaçe d'administration de Solr : http://localhost:8983/solr/select/?MESSAGE. On obtient ainsi une sortie exacte de ce que Solr envois à eZ Find avant transformation. Cette manipulation est utile lors des phases de Debug, par exemple en manipulant directement le message pour obtenir exactement le résultat attendu.

Etape 2 : Comment eZ Find pousse le contenu eZ Publish vers Solr

Voici le parcours d'exécution du code lors de l'ajout / modification d'un contenu eZ Publish :

  • Exécution de la méthode registerSearchObject, de la classe eZContentOperationCollection
    Si DelayedIndexing activé (voir détail ci dessous) : ajout d'objectID à la table 'ezpending_actions' pour un traitement ultérieur
  • Si DelayedIndexing désactivé, fetch de l'objet et transmission de l'objet à la méthode eZSearch::addObject( $object, $needCommit )
  • Si eZ Find installé et activé, appel de la méthode eZSolr::addObject( $contentObject, $commit = true )
  • Au final, une fois les contenus préparés, appel de la méthode addDocs de la classe /extension/ezfind/classes/ezsolrbase.php, qui POST ensuite les données via HTTP à l'aide de cURL

eZ Find, un plug-in de recherche

eZ Find est construit comme un plug-in de recherche, c'est à dire que le module /content/search a été nativement construit pour être déporté sous forme de plug-in. Ainsi dans l'extension /ezfind/settings/site.ini.append.php on trouve la déclaration du plug-in :

[SearchSettings]
SearchEngine=ezsolr
 
 

C'est ensuite la méthode getEngine() (kernel/classes/ezsearch.php) qui s'occupe d'affecter la bonne classe PHP pour interfacer le plug-in de recherche, à savoir : /search/plugins/ezsolr/ezsolr.php

eZ Find et le mécanisme natif du DelayedIndexing

Lors des différentes opérations de mises à jours de contenus, la méthode addObject de la classe eZSolr sera invoqué. Ce mode de fonctionnement en plug-in permet également d'hériter des autres mécanismes natifs de la recherche eZ Publish, comme par exemple le DelayedIndexing, qui permet de déporter l'indexation (complète ou par classes) vers une tache planifiée : indexcontent.php :

[SearchSettings]
DelayedIndexing=disabled|enabled|classbased
DelayedIndexingClassList[]
DelayedIndexingClassList[]=mycontentclass
 

A noter : Cette technique est relativement efficace pour optimiser les temps de réponses Back Office, ou les imports de contenus régulier. Cependant, le DelayedIndexing souffre de quelques limites, puisqu'il est générique (et non optimisé spécifiquement pour eZ Find) et qu'il se contente donc de boucler sur la table 'ezpending_actions' afin d'indexer les objets un par un sans se préoccuper des autres finesses de Solr, comme par exemple l'ajout massif de contenus à indexer, suivi d'un unique 'commit'.

Etape 3 : Le fonctionnement de la méthode addObject

La méthode addObject (/search/plugins/ezsolr/ezsolr.php) reçoit :

  • un unique objet de contenu en paramètre
  • un paramètre optionnel indiquant s'il faut 'commiter' ou non le contenu ajouté (une très bonne façon d'optimiser les indexations massives de contenus)

Cette méthode agit de la façon suivante, dans les grandes lignes :

  • Vérification s'il faut indexer ou non le contenu, en fonction des classes exclues (settings : [IndexExclude])
  • Récupération des méta données de l'objet, et création des noms et valeurs des champs pour Solr
  • Récupération des méta données des noeuds, et création des noms et valeurs des champs pour Solr
  • Récupération des données des attributs de l'objet, dans chacune des langues, et création des noms et valeurs des champs pour Solr
  • Insertion dans l'index de Solr de l'ensemble des données collectées, en mono ou multicore selon les settings
  • Commit final, en fonction du paramètre optionnel de la méthode addObject

A noter : Depuis eZ Find 2.2, il est possible d'utiliser des 'cores' spécifiques à chaque langues (/extension/ezfind/java/solr.multicore), ce qui permet de dédier des index et des fichiers de configurations spécifiques à chaque langue (spellings.txt, synonmys.txt, stopwords.txt, etc.)

Etape 4 : Les nommage des champs côté Solr

Il est nécessaire de revenir sur la façon dont eZ Find nomme les champs transmis à Solr. Les principales techniques d'exploitations avancées d'eZ Find pour eZ Publish nécessitent de bien comprendre la sémantique et le mécanisme de nommage des champs.
C'est la classe /ezfind/classes/ezfsolrdocumentfieldbase.php, ou d'éventuelles classes héritées pour certains datatypes complexes (voir ma contribution ezfsolrdocumentfieldobjectrelation par exemple) qui a vocation à créer les noms des champs pour Solr, en respectant une sémantique très précise. On obtient ainsi la sémantique suivante :

Le nom des attributs :

  • Nom Solr : attr_[contentattributename]_[contentattributetype], exemple : 'attr_title_s'. Il faut noter l'absence de l'identifiant de la classe, ce qui ouvre des perspectives d'exploitation des attributs Solr pour filtrer plusieurs classes sur des attributs homonymes (l'objet d'un prochain billet).
  • Mapping dans un Fetch eZ Find (filtre par exemple) : [contentclassname]/[contentattributename]/[contentsubattributename], par exemple 'article/title'.
    Le nom de la classe 'article' est utilisé comme un filtre supplémentaire lors de la construction de la requête
  • Le 'title' est tranformé en 'attr_title_s', le _s étant déduit de settings eZ Find (voir ci-dessous)

Le nom des métadonnées :

  • Nom Solr : meta_[metadataname]_[metadatatype], exemple : meta_class_identifier_s
  • Mapping dans un Fetch eZ Find (tri par exemple) : usage interne, par exemple pour un tri par 'class_identifier'

Le nom des sous-attributs (inexploité par défaut) :

  • Nom Solr : subattr_[contentsubattributename]_[contentsubattributetype], exemple : subattr_mysubfield_s

Nativement, les sous attributs sont peu ou pas exploités. C'est par contre un formidable outil pour étendre le fonctionnement d'eZ Find et indexer des champs supplémentaire. Voir par exemple ma contribution : ezfsolrdocumentfieldobjectrelation, qui indexe tous les attributs des objets en relations, en les stockant dans des sous attributs, ce qui permet ensuite d'effectuer toutes les opérations nécessaires sur ces sous attributs (recherche, filtre, facettes), selon la syntaxe 'myclass/myattribute/mysubattribute'. Les prochains billets détailleront comment exploiter ce mécanisme pour bien d'autres usages.

Etape 5 : La gestion des types de champs côté eZ Find

Dans les noms de champs Solr, la dernière information désigne le type de champs, et donc comment Solr va devoir considérer l'information (entre un string, un texte, une date, un tableau, etc.)
Coté eZ Find, cette définition se fait comme toujours dans les settings. Depuis eZ Find 2.2, il est maintenant possible de définir un type de champs spécifique à chaque contexte d'utilisation :

  • DatatypeMap[] : le setting global, s'appliquant à tous les contextes par défaut
  • DatatypeMapSort[] : settings spécifique pour les tris
  • DatatypeMapFacet[] : settings spécifique pour les facettes
  • DatatypeMapFilter[] : settings spécifique pour les filtres

Par exemple, par défaut, dans la version actuelle d'eZ Find 2.2, les attributs de type 'textline' sont définis différemment pour les tris :

  • DatatypeMap[ezstring]=text
  • DatatypeMapSort[ezstring]=string

L'impact au niveau de Solr, c'est que tous les attributs de type 'textline' auront systématiquement 2 champs de correspondance :

  • attr_title_t (utilisé pour la recherche, les facettes et les filtres)
  • attr_title_s (utilisé pour les tris)

A noter : il est conseillé d'utiliser également le type 'string' pour les facettes, afin de considérer le caractère espace comme un caractère lambda, et ainsi obtenir des facettes de type 'ma facette', plutôt que 'ma' et 'facette'.

Etape 6 : La gestion des types de champs côté Solr

Solr possède un fichier de configuration permettant à eZ Find de lui spécifier que le '_s' signifie un string, le '_t' un texte, etc. Il s'agit du fichier /ezfind/java/solr/conf/schema.xml
Ce fichier de configuration contient la définition d'un certain nombre de noms de champs en dur (pour les meta-données par exemple), mais définie également les correspondances pour tous les noms de champs dynamiques (nos fameux attributs de classes eZ Publish) :

<dynamicField name="*_i" type="int" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_f" type="float" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_d" type="double" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_si" type="sint" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_sf" type="sfloat" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_sd" type="sdouble" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_s" type="string" indexed="true" stored="true" multiValued="true" termVectors="true"/>
<dynamicField name="*_sl" type="slong" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_l" type="long" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_t" type="text" indexed="true" stored="true" multiValued="true" termVectors="true"/>
<dynamicField name="*_b" type="boolean" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_dt" type="date" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_random" type="random" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_k" type="keyword" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_lk" type="lckeyword" indexed="true" stored="true" multiValued="true"/>
<!-- some trie-coded dynamic fields for faster range queries -->
<dynamicField name="*_ti" type="tint" indexed="true" stored="true"/>
<dynamicField name="*_tl" type="tlong" indexed="true" stored="true"/>
<dynamicField name="*_tf" type="tfloat" indexed="true" stored="true"/>
<dynamicField name="*_td" type="tdouble" indexed="true" stored="true"/>
<dynamicField name="*_tdt" type="tdate" indexed="true" stored="true"/>
<!-- geopoint for geospatial/location searches, boosting, ... -->
<dynamicField name="*_gpt" type="geopoint" indexed="true" stored="true"/>
 

Ce fichier permet aussi de définir des comportements plus complexes sur certains datatypes eZ Publish, comme par exemple les mots clés (keyword). On y trouve par exemple 2 types de champs différents pour la gestion des keywords ('keyword' pour un respect de la casse et 'lckeyword' pour une casse en lowercase), qui peuvent etre exploité indifféremment au niveau d'eZ Find (DatatypeMap).

<fieldtype name="lckeyword" class="solr.TextField" positionIncrementGap="100">
 <analyzer type="index">
 <tokenizer class="solr.PatternTokenizerFactory" pattern=", *" />
 <filter class="solr.TrimFilterFactory" />
 <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
 <filter class="solr.LowerCaseFilterFactory"/>
 <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
 </analyzer>
 <analyzer type="query">
 <tokenizer class="solr.PatternTokenizerFactory" pattern=", *" />
 <filter class="solr.TrimFilterFactory" />
 <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
 <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
 <filter class="solr.LowerCaseFilterFactory"/>
 <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
 </analyzer>
</fieldtype>
 

La définition des keywords est riche d'enseignement sur la configuration de Solr. On peut observer le fonctionnement des appels des filtres Solr, et comment sont traités les séparations de mots par des virgules (PatternTokenizerFactory), la gestion de la casse (LowerCaseFilterFactory), ou encore la suppression des doublons (RemoveDuplicatesTokenFilterFactory), etc.

09/05/2010 3:07 pm (UTC)   Gilles Guirand   View entry   Digg!  digg it!   del.icio.us  del.icio.us

ez projects

› First beta version of Memcache Mutex imported

Enjoy!

More background information about this extension on Netgen Blog.

07/05/2010 5:04 pm (UTC)   eZ Projects   View entry   Digg!  digg it!   del.icio.us  del.icio.us

ez projects

› Now supporting upgrades 3.8.6 > 4.3.0

eZ Upgrade has been extended, supporting upgrades of eZ installations as old as 3.8.6, and upgrading them up to 4.3.0.

Now there's no excuse for not moving your 3.x site over to that shiny, new PHP 5 server. :)

06/05/2010 9:42 pm (UTC)   eZ Projects   View entry   Digg!  digg it!   del.icio.us  del.icio.us

ymc

› YMC publishes the best of 7 years of eZ Publish development

The Open Source CMS market is complex, with hundreds of projects readily available. Some are written in clean code, others turn out as horrible collections of dirty hacks. Some have sprung out of the anonymous dark, others are maintained by professional teams with release roadmaps, contribution reviews and certifications, and get supported by development guidelines, professional integration and maintenance services. Some of them have huge feature lists. Others keep their kernels small and establish an ecosystem for plugin manufacturers. The third group only accepts generic functionality in the core, so that the majority of practical needs can be met by editing data classes, templates and permissions, which renders plugins meaningless.

In 2003, YMC has chosen eZ Publish as our primary CMS. Over the years, we managed nearly a hundred projects of all sizes, and on the way, trained dozens of developers. With all the experience, we still deem eZ Publish as the most versatile Open Source Content Management Framework in existence. It has allowed for a smooth upgrade path, as it is strictly generalistic in design and both upwards and backwards compatible. Its thourough object orientation might be hard for the beginner, however, the advantages cannot be turned down when it comes to more complex multi-client installations that will be migrated to new versions of the CMS and even PHP. The professional vendor behind eZ Publish (eZ Systems), and the industry-grade services available directly from them (namely eZ Premium and developer certifications), are indespensable for a professional software investment.

In our work as consultants and programmers, we have specialized in two ways. First, we serve large media companies to meet their high-end demands, such as complex migration scenarios, flexible editorial workflows, quick release cycles, seamless scalability and uninterrupted business during migrations. Secondly, YMC has developed an appetite for the new and the fancy, especially in the media sector. We are strong advocats for user generated content, and we can help to create value from it, the more so as we have invested our expertise in several Web 2.0 startups.

Today, YMC initiates a third line of action. We intend to give back to the Open Source community. Therefore, we will publish selected modules under the GPL. All of them have been in stable use for years and undergone several evolutionary iterations. We hope that they will prove useful for other Open Source enthusiasts and help to further promote Open Source at the Enterprise level. Of course, we appreciate any feedback and any suggestions you might have.

We will use Google Code. Here is a list of recent and planned publications. Descriptions for the other numbers will be added shortly.

1) ymcExtensionLoader

Adds enterprise-grade multi-client capability to eZ Publish. Enables a more flexible handling of extensions and settings, sharing settings between clients, and nesting extensions.

2) ymcBootstrap

Introduces an alternative way to control patches to eZ Publish. Changes to the eZ kernel and the database are logged and can be automatically deployed onto a multi-server environment in a reliable manner. This will aid upwards compatibility to further versions of eZ Publish.

3) ymcLibrary

4) ymcClusterManagement

5) ymcDistributedCache

6) ymcMetaNavigation

7) ymcDistributedStorage

8) ymcCommunity

03/05/2010 6:00 pm (UTC)   YMC   View entry   Digg!  digg it!   del.icio.us  del.icio.us

derick rethans

› Find my Xdebug download wizard

Find my Xdebug download wizard

Installing Xdebug seems to be a problem for some users. The main trouble is for Windows users that don't know which file to download. Over the past few days I've worked on a wizard that analyses phpinfo()'s output and for Windows users suggests:

  • which file to download

  • where to put the file

  • which php.ini file to modify, and how

For Unix users, it explains:

  • which source tarball to download

  • how to compile

  • which php.ini file to modify, and how

I hope this makes it a bit easier to get going with Xdebug. Next up (hopefully this week) is release candidate 2 for Xdebug 2.1.0.

03/05/2010 11:00 am (UTC)   Derick Rethans   View entry   Digg!  digg it!   del.icio.us  del.icio.us

ez projects

› NovenINIUpdate 3.0 released !

NovenINIUpdate 3.0 has just been released.

Many new and useful features such as :

  • Backup config files before switching
  • Diff feature in CLI
  • Policy limitations support (you can limit environment switching depending on allowed environments)
  • config.php support
  • eZDFSFileHandler support

This release also comes with a few bugfixes.

You may check the full changelog.

Go download and upgrade ;-) !

02/05/2010 12:30 pm (UTC)   eZ Projects   View entry   Digg!  digg it!   del.icio.us  del.icio.us

ez projects

› Version 0.9.2 has been released

Version 0.9.2 of the PDF catalogue has just been released. This release comes with a new feature that allows one to add any content node to a common PDF catalogue from which users can create a personal PDF catalogue.

A demonstration of the PDF catalogue is available here: http://www.alexander-block.net/eng/Business/eZ-Systems/Personal-PDF-Catalogue (it does currently not support the common PDF catalogue feature)

01/05/2010 5:48 pm (UTC)   eZ Projects   View entry   Digg!  digg it!   del.icio.us  del.icio.us

david linnard

› Useful Debugging in eZ Publish

There are lots of settings and helper functions which can really assist with debugging your eZ Publish site. Here are the key tips I use when I need to work through any issues. I would also recommend a read of an article by Łukasz Serwatka on the eZ Publish website. Updating your Debug Settings Here are the [...]
01/05/2010 5:46 pm (UTC)   David Linnard   View entry   Digg!  digg it!   del.icio.us  del.icio.us

eZ publish™ copyright © 1999-2005 eZ systems as