7.x

Trier une View par longueur de chaîne

On continue dans les bouts de code pratiques. Voici, en 4 lignes, comment trier les résultats d'une view selon la longueur de chaîne du titre.

1
2
3
4
5
6
7
8
9
10
11
<?php
 
/**
 * Implements hook_query_TAG_alter().
 *
 * @param SelectQuery $query
 */
function glossaire_query_views_export_alter(SelectQuery $query) {
  $query->addExpression('LENGTH(node.title)', 'title_length');
  $query->orderBy('title_length', 'DESC');
}

Ce code provient du module personnalisé du glossaire de traduction française et a été construit depuis la documentation disponible sur drupal.org.

Forcer le téléchargement d'un fichier sous Drupal 7

Nouveau billet rapide pour vous partager une fonctionnalité.

Pour forcer le téléchargement d'un fichier, comme d'habitude avec Drupal, il y a un module pour ça. Dans ce cas précis il y en a même deux : Download file et File force. Mais bon comme d'habitude, la flemme d'installer un module pour une si petite fonctionnalité ! Alors voici la solution en quelques lignes de code :

Voici un bout de code se basant sur la File API. Il est plus sécurisé par rapport au deuxième mais ne fonctionnera que pour les fichiers gérés par Drupal (quelque soit la méthode de téléchargement) : je le recommande donc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
/**
 * Implementation of hook_menu()
 */
function mymodule_menu() {
  $items['download/%file'] = array(
    'page callback' => 'mymodule_download_file',
    'access arguments' => array('administer site configuration'),
    'type' => MENU_CALLBACK,
  );
  return $items;
}
 
/**
 * Page callback for forcing a file to download
 */
function mymodule_download_file($file) {
  if($file) {
    file_transfer($file->uri, array('Content-disposition' => 'attachment; filename='.$file->filename));
  }
  else {
    return drupal_access_denied();
  }
}

Il suffira d'appeler le fichier sous la forme http://mysite.com/download/123 où 123 est l'identifiant fid du fichier à télécharger.

Ce deuxième bout de code présente un danger pour la sécurité ! Il est recommandé de l'utiliser en dernier recours lorsque les fichiers ne sont pas gérés par Drupal. Pour accroître la sécurité on proposera cette fonctionnalité seulement aux administrateurs, et on filtrera les extensions autorisées au téléchargement.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
/**
 * Implementation of hook_menu()
 */
function mymodule_menu() {
  $items['download'] = array(
    'page callback' => 'mymodule_download_file',
    'access arguments' => array('administer site configuration'),
    'type' => MENU_CALLBACK,
  );
  return $items;
}
 
/**
 * Page callback for forcing a file to download
 */
function mymodule_download_file() {
  if (!isset($_GET['file']) || !file_exists($_GET['file'])) {
    return drupal_not_found();
  }
  $filepath = $_GET['file'];
  $realpath = realpath($path);
  $filename = basename($filepath);
  $extension = pathinfo($filepath, PATHINFO_EXTENSION);
  // Vérification de l'extension et restriction aux fichiers dans DRUPAL_ROOT
  if(in_array($extension, array('jpg', 'png', 'gif', 'mp4')) && substr($path, 0, strlen(DRUPAL_ROOT)) === DRUPAL_ROOT) {
    drupal_add_http_header('Content-disposition', 'attachment; filename=' . $filename);
    readfile($filepath);
  }
  else {
    return drupal_access_denied();
  }
}

Il vous suffira ensuite de créer votre lien sous la forme http://mysite.com/download?file=sites/default/files/monimage.png

Ceci ne fonctionne que pour la méthode de téléchargement publique mais c'est la plus répandue.

Erreur 500 pendant la mise à jour Drupal 7

En mettant à jour ce blog vers Drupal 7 en suivant les instructions d'UPGRADE.txt, je suis tombé sur une erreur 500 sur la page update.php?op=info.

Imaginant que c'était une erreur due au fichier .htaccess, je l'ai renommé : pas de changement. Finalement j'ai mis le nez dans le code du fichier update.php pour trouver à la ligne 340 :

1
        ini_set('display_errors', FALSE);

Ceci cache l'affichage de toutes les erreurs et génère une page d'erreur 500. Donc à moins que vous n'utilisiez les fichiers de log pour stocker les erreurs php, vous pouvez pas voir ce qui ce passe. Je ne sais pas pourquoi a choisi de faire ça (il a l'air d'agir comme Steve Jobs ces jours-ci wink ) mais ce n'est pas très pratique et cela m'a pris une heure pour débogger ceci...

Vous avez juste à commenter cette ligne ou à mettre TRUE au lieu de FALSE et voilà, vous savez exactement quel est le problème. Pour moi c'était le module token qui définissait des doublons de fonctions avec le même nom, c'est facilement désactivable par un "drush sqlc" et :

1
        UPDATE system SET status = 0 WHERE name = 'token' AND type = 'module';

C'est aussi faisable avec PhpMyAdmin.

Bonne chance pour le passage de Drupal 6 à Drupal 7 !

Migration du blog sous Drupal 7

Ça fait quelques soirées que je suis dessus maintenant, je me suis amusé à passer ce blog sous Drupal 7, et voici mes premières conclusions :

Les Moins

Beaucoup de modules ne sont pas encore disponibles

Malgré la #D7CX, beaucoup de modules ne sont pas encore portés même en release de développement. Alors vous allez me dire "Arrête de te plaindre !"... et oui, faut que j'arrête de me plaindre, car selon les anciens (oui je suis un petit jeune arrivé quand Drupal était en 6.9 smiley) c'était bien pire lors du passage de D5 à D6.
Donc on peut finalement dire que les modules les plus importants et les plus utilisés sont présents, parfois en bêta et un peu buggés mais les dev sont réactifs.

Je compte dans les absents qui m'ont étonné : 

Beaucoup d'entre eux sont encore dans le foetus git ou dans des patchs dans les issues mais ils ne devraient pas tarder.

La majeure parties des modules sont en dev

Sur les 33 modules tiers que j'ai activé, 9 sont en dev et 13 ont une release stable.

En voici la preuve :

blog@sebcorbin:~/public_html$ drush pml --status="enabled" --no-core --type="module"
Package         Nom                                                     Version        
 Administration  Administration Development tools (admin_devel)          7.x-3.0-rc1    
 Administration  Administration menu (admin_menu)                        7.x-3.0-rc1    
 Administration  Administration menu Toolbar style (admin_menu_toolbar)  7.x-3.0-rc1    
 Development     Devel (devel)                                           7.x-1.0        
 Filters         GeSHi Filter (geshifilter)                              7.x-1.x-dev    
 Mail            HTML Mail (htmlmail)                                    7.x-1.x-dev    
 Media           IMCE (imce)                                             7.x-1.2        
 Mobile          Mobile Tools (mobile_tools)                             7.x-2.x-dev    
 Multilanguage   Language icons (languageicons)                          7.x-1.0-alpha1 
 Multilanguage   Locale updater (l10n_update)                            7.x-1.0-alpha3 
 Multilingual    Internationalization (i18n)                             7.x-1.x-dev    
 Multilingual    Multilingual select (i18n_select)                       7.x-1.x-dev    
 Other           AddToAny (addtoany)                                     7.x-3.0        
 Other           Backup and Migrate (backup_migrate)                     7.x-2.1        
 Other           CSS Injector (css_injector)                             7.x-1.4        
 Other           Disqus (disqus)                                         7.x-1.1        
 Other           Global Redirect (globalredirect)                        7.x-1.3        
 Other           Inline Messages (inline_messages)                       7.x-1.0        
 Other           Mollom (mollom)                                         7.x-1.0        
 Other           Page Title (page_title)                                 7.x-2.4-beta1  
 Other           Pathauto (pathauto)                                     7.x-1.0-beta1  
 Other           Scheduler (scheduler)                                   7.x-1.x-dev    
 Other           Search 404 (search404)                                  7.x-1.0        
 Other           Token (token)                                           7.x-1.0-beta1  
 Other           Tweetbutton (tweetbutton)                               7.x-1.1        
 Other           Variable API (variable)                                 7.x-1.0-beta2  
 Statistics      Google Analytics (googleanalytics)                      7.x-1.1        
 User interface  CKEditor (ckeditor)                                     7.x-1.x-dev    
 User interface  External Links (extlink)                                7.x-1.12       
 XML sitemap     XML sitemap (xmlsitemap)                                7.x-2.0-beta2  
 XML sitemap     XML sitemap engines (xmlsitemap_engines)                7.x-2.0-beta2  
 XML sitemap     XML sitemap menu (xmlsitemap_menu)                      7.x-2.0-beta2  
 XML sitemap     XML sitemap node (xmlsitemap_node)                      7.x-2.0-beta2 

C'est un bien et un mal, avec la version de dev, on est a peu prêt sûr que les modules vont fonctionner, mais on ne peut pas suivre le processus normal de développement. En gros, on est pas notifié lors de la sortie d'une nouvelle version de dev, ou même lors d'une sortie de version stable.

Ne pas avoir peur de mettre les mains dans le camboui

Quand on recontre une erreur fatale sur une fonction qui n'existe pas, il ne faut pas hésiter à aller voir ce qui se passe directement dans le code, ce sont en général des fonctions d'API supprimées dans D7 qu'il suffit de replacer par leurs homologues et le tour est joué. Ne pas oublier d'aller voir dans les issues du modules pour voir si celle-ci n'a pas été corrigée et dans ce cas là appliquer le patch.

Les plus

Quel plaisir ce Drupal 7 sinon ! L'overlay est un délice et le design de l'administration donne envie d'y rester, j'ai cutomizé Bartik à mon goût et j'en suis content, ça donne vraiment un coup de jeune au site.
Les modules sont mieux triés dans les menus même s'il faut perdre l'habitude de ceux de Drupal 6. Des menus contextuels sont disponibles sur les blocks et les nodes. Les onglets verticaux gagnent autant de place que les fieldset collapsibles de D6 mais affichent en plus un résumé des paramètres dans ceux-ci.

J'en ai également profité pour passer mon blog sur une autre URL et j'ai aussi installé le module Disqus, un gestionnaire de commentaire complet qui prend en charge le login depuis twitter ou facebook, les tweetback, etc.. n'hésitez pas à le tester (pour ma part j'ai enlevé le système de commentaires du Core) : dites-moi ce que vous en pensez en postant un petit commentaire wink

Drupal Gardens

J'ai reçu il y a un mois maintenant mon invitation pour la beta de Drupal Gardens. Ce service, fourni par Acquia, offre un hébergement de site sous Drupal 7.

 

Drupal as a service

Ce service est une plateforme d'hébergement complète, avec la possibilité de créer plusieurs sites, de sauvegarder, restaurer et exporter votre site web. Chaque site aura une adresse de type monsite.drupalgardens.com, on peut rapprocher ce type de service à Wordpress qui offre également un service gratuit de blogging.
Dans ce sens on parlera de "Drupal as a service".

Le constructeur de thème

Acquia a focalisé le développement de sa distribution préinstallée sur chaque site afin qu'elle soit la plus intuitive possible. L'utilisateur pourra charger et modifier son thème "en live" puis enregistrer ou annuler ses changements. La majorité des changements sont visibles directement dans le navigateurs puisque tout est fait via AJaX.

Une petite zone d'administration vous permettra tout cela :

On nous propose 7 thèmes par défaut, avec pour chacun la possibilité de modifier la palette de couleur (couleur des liens, titres, puces, ...), le logo et la favicon, la structure (nombre et largeur des colonnes), la police, les bordures et marges, l'arrière-plan. et si ce n'est pas encore assez, vous pouvez même ajouter votre propre code CSS !

Quand tout vous plaît, vous enregistrez et/ou vous appliquez votre thème perso.

L'administration

Elle s'organise à travers une barre de menu en haut de la page, ressemblant étrangement à celle du module admin. Les préférences s'affichent et se modifient via des popup AJaX rendant toute l'administration fluide et intuitive, on doit bien sûr cela à Drupal 7.

Le bilan

Acquia nous offre ici une solution viable à l'installation manuelle de Drupal, définitivement utile pour un blog de petite envergure ou un site rapide pour la tenue d'un évènement par exemple. On devra voir apparaître à la fin de la beta des formules avec de la publicité et certaines limitations pour continuer à utiliser le service gratuitement, et d'autres payantes offrant plus d'espace disque et de ressources.
 

Pour s'inscrire, ça se passe ici.

Drupal 7 : l'API de la base de données

Il est à noter que je n'ai pu installer Drupal 7 pour monter ce blog car impossible avec OVH.
Cependant en cherchant d'où venait l'erreur (on obtient un méchant SQLSTATE[70100]: <>: 1317 Query execution was interrupted) j'ai pu fouiller pour la première fois dans le code de la nouvelle release. Et là Oooooooh surprise de la POO !

En effet j'ai pu découvrir (avec grand bonheur, soit dit en passant) que la couche entière 'Base de données' de Drupal a été remaniée pour être programmée en POO.

Du coup ni une ni deux j'ai tripatouillé le code pour m'afficher toutes les propriétés de l'exception lancée et trouver la requête qui mettait le souk : SELECT 1 FROM information_schema.tables WHERE (table_schema = :db_condition_placeholder_4) AND (table_name = :db_condition_placeholder_5) 
Là il suffit d'un peu de jugeote : je suis sur OVH mutualisé, je n'ai donc pas accès à information_shema, le bug est posté y'a plus qu'à attendre voir si la communauté est prête à prendre en compte ce comportement.

Voici quelques exemples, récupérer la valeur d'un champ :

1
2
3
4
5
//Drupal 6 
$value = db_result(db_query('SELECT champ FROM {table}')); 
 
//Drupal 7 
$value = db_query('SELECT champ FROM {table}')->fetchField();

Récupérer un objet :

1
2
3
4
5
6
7
8
9
10
11
//Drupal 6: 
$result = db_query('SELECT champ FROM {table} WHERE condition = %d', $variable); 
while ($row = db_fetch_object($result)) { 
    // Boucler sur les résultats pour les traiter 
} 
 
//Sous Drupal 7 il n'y a pas de db_fetch_object() ou de db_fetch_array(): 
$result = db_query('SELECT champ FROM {table} WHERE condition = :substituant', array(':substituant' => $variable)); 
foreach ($result as $row) {
    // Boucler sur les résultats pour les traiter 
}

Autres requêtes:

1
2
3
4
5
6
7
8
9
10
//Une requête de suppression dans Drupal 7: 
db_delete('table') ->condition('champ_condition', $variable) ->execute(); 
 
//Une requête de mise à jour dans Drupal 7: 
db_update('table') ->fields( 
  array( 
    'champ_1' => $variable_1, 
    'champ_2' => $variable_2, 
  ) 
) ->condition('champ_condition', $variable_condition) ->execute();

Pour plus d'infos, je vous invite à jeter un coup d'oeil à l'API de drupal 7.

Via source.

Tags: 
S'abonner à RSS - 7.x