Médias : supprimer les médias dont le fichier physique n’existe plus

Juste un petit morceau de code utile pour nettoyer la base des médias, qui n’existent plus physiquement.

A adapter selon vos besoins !

$q = db_query('SELECT fid, uri FROM file_managed ORDER BY fid');
$medias = $q->fetchAllAssoc('fid');

$i = 0;
foreach ($medias as $fid => $media) {

  $url = file_create_url($uri);
  $exists = file_exists($media->uri);

  if (!$exists) {
    $i++;
    var_dump($media->uri, $exists);
    $file=file_load($fid);
    file_delete($file);

    if($i>0){
      return;
    }
  }
}

return;

A mon avis, ce genre de fonctionnalité devrait exister directement via le back-office du module Médias, ce serait top. Je n’ai pas eu le temps de vérifier si les futures versions aurait une fonctionnalité similaire…

node_save d’un stdClass incomplet, jusqu’ici tout allait bien !

Après un changement d’hébergeur, me revoilà de retour !

Il m’est arrivé ces derniers jours bien des problèmes suite à la mise à jour du module « field_collection ». Ce module est certes génial, et presque indispensable selon les types de contenus à mettre en place, mais alors … que de soucis … je dirais qu’en 2 ans, sur les gros soucis que j’ai pu rencontrer quant aux données pures, field_collection était souvent en cause.

Il faut dire que le module réalise quelque-chose de techniquement pas téléphoné…

Venons-en au sujet !

Les contributeurs de mon site ont soudainement retrouvé tous les « field_collection » de leurs contenus vides …

c’est plutôt gênant, heureusement que j’avais des dumps quotidiens !!

 

Pourquoi ?

Continuer la lecture de node_save d’un stdClass incomplet, jusqu’ici tout allait bien ! 

Contexte : ne pas afficher les blocs d’une page non autorisée (403) ou non trouvée (404)

En étudiant un peu les fonctionnalités d’aperçu de contenu, j’ai découvert un module très intéressant si vous utilisez le module « context » pour entourer vos contenus de divers blocs.

Le problème était que si le contenu n’était pas publié, il n’était donc visible que par son auteur dans mon cas. En revanche, les internautes non authentifiés tombaient sur une page 403, mais tous les blocs associés au contenu, eux, s’affichaient toujours, comme si de rien n’était…

 

C’est là qu’intervient le module context_error, qui permet d’ajouter une condition à votre contexte, pour dire : « ce contexte ne s’applique que si la page n’est pas une erreur 403 ou 404 ».

Le module permet également de faire l’inverse, à savoir d’appliquer un contexte à une page 403 et/ou 404.

 

Le module est très basique, il se contente de récupérer les headers HTTP définis par Drupal en amont, et regarder le statut « 404 Not found » ou « 403 Forbidden », pour en déduire que c’est une page d’erreur ou non, et de quel type.

 

 

Comment Drupal dessert-il un hook de menu par rapport à l’URL demandée ?

Après avoir passé sa phase d’initialisation (bootstrap), Drupal appelle depuis l’index.php, la fonction chargée de trouver le bon « hook » de menu qui correspond à l’URL courante.

Dans l’ordre, ça donne :

  • menu_execute_active_handler()
    • menu_get_item()
      • _menu_translate()

Quelques explications :

menu_execute_active_handler() : charge la page de maintenance si le site est en maintenance, ou celle demandée sinon.

3 cas possibles : la page est affichée, l’utilisateur n’a pas accès, la page n’est pas trouvée.

menu_get_item() : recherche le hook de menu dans la table menu_router en gros.

_menu_translate() : Comme son nom de l’indique pas… cette fonction va vérifier les droits d’accès au hook de menu trouvé (en utilisant le « access callback » déclaré dans ce hook de menu).

 

 

Cache de bloc : attention au hook_block_view !

C’est expliqué sur drupal.org, au niveau de l’API du hook_block_view, dans un commentaire :

si le bloc est en cache, dès le 2nd affichage du bloc, le hook_block_view correspondant n’est plus appelé. Logique, c’est ce qu’on veut en mettant du cache : éviter à Drupal de recalculer à chaque coup le bloc et son rendu.

Seulement, la petite bourde facile, c’est d’utiliser drupal_add_css, drupal_add_js, drupal_add_library directement dans le callback du hook_block_view.

Erreur ! Car le JS, CSS ou la librairie ne sera ajoutée qu’une seule fois, avant que le bloc ne soit en cache. Ensuite, nada, que d’chi, vous n’aurez plus vos attachements…

Solution ?

la 1ère réponse au commentaire explique qu’on peut gérer son cache soi-même, en disant à Drupal : ne cache pas ce bloc, je m’en occupe !

La 2nde, plus « best practice » à mon sens, conseille d’utiliser tout bonnement la clé #attached de votre render Array. Ah oui, j’espère que vous utilisez un render Array, sinon, c’est pas bien !

 

En même temps, il suffit de lire la doc et de respecter les standards, mais c’est si facile de se tromper que ça valait bien un article !

Quel contenu principal pour ma homepage ?

Il y a plusieurs façons de gérer le contenu principal de sa homepage. La homepage est la page « / » ou bien « /node ».

Comportement par défaut de Drupal

Le comportement par défaut de Drupal est d’afficher les N derniers articles (N étant paramétrable) promus en page d’accueil (dans les options de publication d’un contenu).

C’est son fonctionnement de base, type « blog ».

Node en guise de contenu principal

Il est également possible de dire à Drupal d’utilise un noeud particulier pour la homepage. C’est stocké dans la variable « site_frontage », et paramétrable via l’écran d’administration « admin/config/system/site-information ».

Alors là, attention, attention, car il va vous mettre un joli « cannonical » sur la homepage, et un lien vers le node sous-jacent en shortlink.

Continuer la lecture de Quel contenu principal pour ma homepage ? 

Piège d’un render_array contenant #markup

Arg, Drupal m’a bien eu ! Je viens de passer 2 heures à comprendre pourquoi mon admin_menu n’apparaissait plus sur mon site, bien que connecté.

Et j’ai découvert qu’il fallait faire gaffe aux render Arrays contenant une clé « #markup ».

Si le tableau contient une clé #markup, il aura beau avoir d’autres clés contenant des fils (clés non préfixées par #, qui sont donc considérées comme des « children »), les fils ne seront pas « rendus ».

 

Pourquoi ?

Continuer la lecture de Piège d’un render_array contenant #markup 

Les caches de Drupal7 : base de données et Memcached

Décorticons un peu le système de cache de Drupal.

Cache des pages et cache Drupal (backend) :

Accéder à la page de configuration des caches via /admin/config/development/performance.

Cocher la case « Mettre en cache les pages pour les utilisateurs anonymes » dans Configuration>Performances

Régler les temps de caches à

  • 1 minute (60sec) pour la durée de vie minimale de la mémoire cache
  • 5 minutes pour l’expiration des pages en cache

(à vous de choisir les temps que vous souhaitez, évidemment…)

Explications

Continuer la lecture de Les caches de Drupal7 : base de données et Memcached 

Field_collection et i18n

Le module field_collection est très pratique voire indispensable lorsqu’on a des types de contenus assez poussés. Je ne vais pas expliquer à quoi il sert ici, la page du module est suffisamment explicite.

Seulement, dès qu’on utilise le module i18n pour gérer de la traduction sur son site, ça devient vite la misère si on ne fait pas attention.

Pour cela, il faut bien comprendre l’architecture utilisée par le module field_collection.

Continuer la lecture de Field_collection et i18n 

Installer Capistrano 2.x sur Ubuntu Desktop 11.04

Pour installer capistrano, rien de plus simple, même si on ne connait pas Ruby.

Il suffit d’utiliser les commandes suivantes, la variable d’environnement RUBYOPT est essentielle pour qu’il retrouve bien ses dépendances à l’exécution de « cap ».

sudo apt-get install rubygems1.8
export RUBYOPT=rubygems
export CAPISTRANO_HOME=/var/lib/gems/1.8/gems/capistrano-2.8.0/
export PATH=$PATH:$CAPISTRANO_HOME/bin

 

Ensuite, il vous faut étudier le fonctionnement de Capistano, en commençant par l’article suivant :

https://github.com/capistrano/capistrano/wiki/2.x-Getting-Started

 

A suivre prochainement : un script capistrano de déploiement Drupal 7.