Comment éviter de modifier le noyau Drupal?

21

Je construisais un échange avec un service XML partenaire, et je ne pouvais pas obtenir le bon XML, mais comme pour tout ce qui concerne Drupal, la journalisation des erreurs et des actions xmlrpc est moins que robuste.

J'ai donc fait cela dans includes / xmlrpc.inc.

function xmlrpc_request($method, $args) {
  $xmlrpc_request = new stdClass();
  $xmlrpc_request->method = $method;
  $xmlrpc_request->args = $args;
  $xmlrpc_request->xml = <<<EOD
<?xml version="1.0"?>
<methodCall>
<methodName>{$xmlrpc_request->method}</methodName>
<params>
EOD;
  foreach ($xmlrpc_request->args as $arg) {
    $xmlrpc_request->xml .= '<param><value>';
    $v = xmlrpc_value($arg);
    $xmlrpc_request->xml .= xmlrpc_value_get_xml($v);
    $xmlrpc_request->xml .= "</value></param>\n";
  }
  $xmlrpc_request->xml .= '</params></methodCall>';

  /* This part here */
  watchdog('xmlrpc',$xmlrpc_request->xml);
  /* End ridiculously tiny hack */

  return $xmlrpc_request;
}

J'ai obtenu les données dont j'avais besoin et en 10 minutes, l'interface partenaire a répondu correctement à ma demande car (choquant je sais) les journaux sont bons.

J'aime la journalisation supplémentaire et je veux la conserver. Quelle est la façon la plus simple, la plus simple et la plus approuvée par Drupal de procéder?

OhkaBaka
la source
2
Je ne vois pas pourquoi cela a été rejeté. Oui, l'édition du noyau est déconseillée mais @OhkaBaka a reconnu que cela demandait des suggestions sur la façon de gérer cela et a fourni un exemple concret. Outre la nécessité de déboguer les situations, il existe des raisons légitimes de modifier le noyau. Il y a quelques bogues dans le noyau avec des correctifs de travail dans la file d'attente des problèmes qui ne sont tout simplement pas appliqués, et il y a quelques choses qui n'ont pas vraiment de solutions de contournement.
mpdonadio
1
Les réponses ci-dessous sont excellentes. Une chose que j'ajouterai, cependant, c'est que vous n'avez pas besoin que la journalisation soit activée tout le temps sur votre site en direct. Désactivez votre module personnalisé lorsque vous ne l'utilisez pas ou appliquez votre correctif ou module à votre site de développement uniquement. Minimiser les changements et documenter soigneusement vous gardera sain d'esprit.
greg_1_anderson
@ greg_1_anderson - Vous constaterez que ma solution ci-dessous résout déjà ce problème en utilisant une variable log_level (bien que l'utilisation de constantes serait évidemment plus propre, je les ai omises pour mettre l'accent sur le modèle). De cette façon, vous pouvez utiliser la même méthode wrapper sur dev / live et le reste de votre code peut en dépendre sans changer d'appels de fonction. Tout ce dont vous avez besoin est de définir le niveau de journalisation de votre module à l'aide d' variable_set()un mécanisme similaire qui peut être exporté si nécessaire. :]
David Watson
1
@David: Oui, c'est génial. J'aime garder les modules de développement désactivés en direct et les activer dans un hook post-sql-sync, par drupalcode.org/project/drush.git/blob/HEAD:/examples/… Votre technique obtient également les meilleures notes, même si je pense que je ferais aussi le variable_set dans un crochet de post-synchronisation drush plutôt qu'une fonctionnalité. Appliquer un correctif sur le système de développement uniquement, comme je l'ai dit ci-dessus, est probablement une mauvaise idée à moins que vous ne soyez sûr que le système est vraiment un système à gratter; sinon, le match pourrait être accidentellement validé et poussé. Aie.
greg_1_anderson
@ greg_1_anderson - Je voulais en fait vérifier si de tels crochets existent et je ne savais pas qu'il y avait déjà des exemples en place; merci beaucoup pour le lien! Sachant maintenant que cela est possible, je conviens que le définir au niveau de l'environnement est certainement la voie à suivre, à la fois pour les raisons que vous suggérez et pour aider à maintenir la configuration du site générique découplée de la configuration spécifique à l'environnement.
David Watson

Réponses:

11

Le hacking core est fortement déconseillé aux non-initiés car il réduit efficacement la communauté de support de milliers de personnes à une communauté de support (ou quelle que soit la taille de votre équipe). Sans cette meilleure pratique, aider les nouveaux venus à Drupal serait presque impossible. Elle entrave également la modularité et, dans certains cas, la sécurité.

Cela dit, le piratage de base n'est pas toujours aussi mauvais que nous aimons le faire croire. Sans modifier le noyau, nous n'aurions pas de distributions comme Pressflow et similaires qui augmentent le noyau de manière intéressante. Il est extrêmement important que vous sachiez exactement ce que vous faites, que vous distribuez vos correctifs avec votre distribution (de préférence d'une manière qui vous permette de les réappliquer automatiquement après la mise à niveau), et que vous gardiez une documentation détaillée de ce que vous avez changé et pourquoi vous l'avez changé.

Selon la façon dont vous avez structuré les choses, vous pouvez certainement apporter la modification ci-dessus à xmlrpc_request(), créer un patch, puis utiliser quelque chose comme Drush Make pour automatiser son application (notez que Drush Make se déplace dans le projet Drush lui-même pour la version 5.x ), tout en fournissant une documentation supplémentaire dans le makefile et ailleurs sur ce que le changement fait et pourquoi il est nécessaire / souhaité.

Un autre modèle courant pour améliorer les fonctions de base consiste à créer un wrapper qui ajoute un tout petit peu de fonctionnalités à une fonction de base et à appeler le wrapper à la place de l'implémentation de core. Lorsque cela est possible, cela rend les choses beaucoup plus modulaires. Considérer ce qui suit:

/**
 * Wrapper function for xmlrpc_request() to provide logging.
 */
function mymodule_xmlrpc_request($method, $args) {
  $xrr = xmlrpc_request($method, $args);
  watchdog('xmlrpc', $xrr->xml);
  return $xrr;
}

Encore une fois, selon ce que vous faites, cela peut ou non être faisable, mais quand c'est le cas, vous vous êtes évité quelques maux de tête en essayant de vous assurer que le noyau reste corrigé et documenté. Bien que dans ce cas, une fonction unique comme celle-ci semble être un candidat parfait pour un tel wrapper. Si votre implémentation est capturée dans un module, vous pouvez même l'étendre pour contrôler le niveau de journalisation de l'ensemble de votre solution, désactivant cette fonctionnalité sur les sites de production:

/**
 * Wrapper function for xmlrpc_request() to provide logging (if enabled).
 */
function mymodule_xmlrpc_request($method, $args) {
  $xrr = xmlrpc_request($method, $args);
  if (variable_get('mymodule_log_level', 0) > 0) {
    watchdog('xmlrpc', $xrr->xml);
  }
}

En bref, vous voulez maximiser ce que vous pouvez faire avec les modules (et vous pouvez faire beaucoup), mais il y a des raisons légitimes de modifier le cœur. Il faut le faire avec soin, c'est tout.

David Watson
la source
9

Si vous devez modifier des modules de base ou contrib, vous devez.

  1. Créez un patch avec des modifications.
  2. Utilisez un système de déploiement comme drush make qui réappliquera automatiquement les correctifs lorsque vous mettez à jour le noyau ou les modules.
  3. Document document document.
googletorp
la source
1
Je ne m'attendais vraiment pas à une validation de la modification du noyau par un effort d'imagination ... alors je suis maintenant obligé de passer à une question secondaire: est-ce mieux que de faire la même chose dans un module autonome?
OhkaBaka