WebArea/Compat/Drupal6/Fr

From TuxFamilyFAQ
Jump to navigationJump to search

Drupal 6

Déportation du répertoire "files"

Patch de Drupal Core

D'après cette page, Drupal 6 n'est pas conçu pour déporter le répertoire dans lequel il stocke les fichiers uploadés (exemple : images) en dehors du DocumentRoot, et encore moins pour servir ces fichiers via une URL spécifique.

Voici un patch pour Drupal 6.19 (qui devrait être facilement maintenable pour les versions 6.x suivantes, mais pas forcément pour les versions 7.x) :

--- includes/file.inc  2010-08-30 21:19:31.000000000 +0200
+++ includes/file.inc  2010-08-30 22:07:19.000000000 +0200
@@ -14,6 +14,7 @@
 
 define('FILE_DOWNLOADS_PUBLIC', 1);
 define('FILE_DOWNLOADS_PRIVATE', 2);
+define('FILE_DOWNLOADS_PUBLIC_REPOSITORY', 3);
 define('FILE_CREATE_DIRECTORY', 1);
 define('FILE_MODIFY_PERMISSIONS', 2);
 define('FILE_EXISTS_RENAME', 0);
@@ -48,6 +49,8 @@
       return $GLOBALS['base_url'] .'/'. file_directory_path() .'/'. str_replace('\\', '/', $path);
     case FILE_DOWNLOADS_PRIVATE:
       return url('system/files/'. $path, array('absolute' => TRUE));
+    case FILE_DOWNLOADS_PUBLIC_REPOSITORY:
+      return rtrim(variable_get('files_url_prefix', $GLOBALS['base_url']), '/').'/'.$path;
   }
 }
 
--- modules/system/system.admin.inc    2010-08-30 21:19:45.000000000 +0200
+++ modules/system/system.admin.inc    2010-08-30 22:07:19.000000000 +0200
@@ -1399,10 +1399,20 @@
     '#type' => 'radios',
     '#title' => t('Download method'),
     '#default_value' => variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC),
-    '#options' => array(FILE_DOWNLOADS_PUBLIC => t('Public - files are available using HTTP directly.'), FILE_DOWNLOADS_PRIVATE => t('Private - files are transferred by Drupal.')),
+    '#options' => array(
+              FILE_DOWNLOADS_PUBLIC => t('Public - files are available using HTTP directly.'),
+              FILE_DOWNLOADS_PRIVATE => t('Private - files are transferred by Drupal.'),
+              FILE_DOWNLOADS_PUBLIC_REPOSITORY => t('Public repository - files are served using a specific URL prefix'),
+      ),
     '#description' => t('Choose the Public download method unless you wish to enforce fine-grained access controls over file downloads. Changing the download method will modify all download paths and may cause unexpected problems on an existing site.')
   );
 
+  $form['files_url_prefix'] = array(
+    '#type' => 'textfield',
+    '#title' => t('URL prefix for files'),
+    '#default_value' => variable_get('files_url_prefix', 'http://your.repository.server/some/directory/'),
+    '#description' => t('URL prefix used when generating links to files. Note that this settings will be used only if the download method is set to "Public repository".'),
+  );
   return system_settings_form($form);
 }
 

Il peut être appliqué traditionnellement avec l'utilitaire GNU patch :

user@pastis:~/votreprojet/votreprojet.org-web/htdocs$ patch -p0 < drupal.patch

Il faut ensuite se rendre dans l'interface d'administration Drupal, section Site configuration > File system :

  1. Une troisième méthode de téléchargement est normalement apparue : "Public repository - files are served using a specific URL prefix" -- choisissez cette option.
  2. Spécifiez ensuite dans "File system path" le chemin d'accès à votre espace de téléchargement sur les serveurs web (typiquement /data/votreprojet) ; exemple : /data/votreprojet/drupal-files
  3. Saisissez l'URL correspondante dans le champ "URL prefix for files" ; exemple : http://download.tuxfamily.org/votreprojet/drupal-files
  4. Cliquez sur "Save configuration"

Drupal-filesystem-french.png

Si vous avez déjà des fichiers, il peut être nécessaire de les déplacer :

  1. Au niveau du système de fichiers : mv /home/votreprojet/votreprojet.org-web/htdocs/sites/default/files/* /home/votreprojet/votreprojet-repository/drupal-files/
  2. Au niveau de la table {files} de Drupal : UPDATE drupal_files SET filepath=REPLACE(filepath, 'sites/default/files', '/data/votreprojet/drupal-files')

N'oubliez pas de réappliquer le patch en cas de mise à jour de Drupal.

Limitations :

  • Des tentatives ont été faites pour éviter de patcher le core de Drupal, et proposer une version alternative du populaire module "Image" - hélas, ce module ne propose pas de prendre en charge les conversions filepath -> URL via une API que les autres modules auraient réutilisée. De fait, les nombreux autres modules ayant "Image" en dépendance appellent eux-mêmes les fonctions file_create_url et file_create_path fournies par le core Drupal. Voilà pourquoi le patch ci-dessus s'attaque finalement au core de Drupal.
  • En l'état actuel des choses, ce patch n'empêche pas Drupal d'appeler la fonction PHP realpath à tout bout de champ lorsqu'il manipule un fichier connu en base ; cela génère donc des appels systèmes lstat64 vers l'espace de téléchargement. La casse est toutefois limitée par l'implémentation d'un cache realpath. La fonction incriminée est file_check_location, appelée par file_create_path.

Patch supplémentaire pour ImageCache

ImageCache est un module Drupal assez courant qui permet de générer plusieurs variantes (on parle de "presets") d'une image. Il est couramment employé en conjonction avec ImageField pour créer facilement de nouveaux types de contenus intégrant des images. Hélas, afin de déporter les fichiers Drupal sur un espace de téléchargement distinct, il est nécesssaire de patcher également ImageCache.

Voici le patch en question : File:Drupal-imagecache-tuxfamily.diff Ce patch ne nécessite pas de configuration supplémentaire.

Fonctionnement

Avant de comprendre comment ce patch fonctionne, il est utile de saisir comment fonctionne ImageCache lui-même. Le lien suivant (en anglais) explique très bien les choses : ImageCache: How does it work? En résumé, ImageCache n'est appelé par Apache que si le fichier cache demandé n'existe pas déjà, autrement celui-ci est servi directement par Apache.

Malheureusement, comme nous changeons l'URL d'appel de ces images en une URL vers un fichier statique vers une toute autre architecture qui n'a aucune chance de déclencher le code d'ImageCache, nous ne pouvons pas garder exactement le même fonctionnement. Aussi, ce patch s'arrange pour que l'URL vers le code ImageCache ne soit affichée sur une page que si le fichier cache concerné n'existe pas déjà. Dans le cas contraire, il générera une URL vers l'espace de téléchargement. À noter que ce patch n'est pas parfait ; il comprend un appel à la fonction file_exists() qui va aller vérifier l'existence du fichier sur l'espace de téléchargement, générant ainsi des appels systèmes lstat64. Cela pourrait être remplacé par une table MySQL qui garderait la trace des couples preset/path déjà générés.