Quel est le concept de base derrière les crochets?

120

Je suis intermédiaire en PHP. Pour parfaire mes compétences, je commence à apprendre Drupal 7. Tout en apprenant les concepts d’architecture Drupal, les termes “ crochet” et “ bootstrapping” me passaient pour beaucoup. J'ai lu le livre "Pro Drupal development", ainsi que de la documentation sur drupal.org, mais il est très avancé pour moi d'apprendre comment les points d'ancrage dans Drupal permettent d'afficher la page Web.

Quelqu'un peut-il me dire quels crochets sont dans des mots simples?

GiLL
la source

Réponses:

107

Les autres réponses sont excellentes, précises, détaillées, mais je ne suis pas sûr que ce soient les "mots simples" qui expliquent le principe de base que le demandeur cherchait.

Je pense aux crochets comme un point où le code marque une pause et crie " Quelqu'un d'autre a quelque chose à ajouter ici? ". Tout module peut avoir une fonction qui répond à cela et qui se déclenche avec les données appropriées qui lui sont transmises à ce stade du code.

Hook_node_delete () est un bon exemple simple à utiliser . N'importe quel module peut l'utiliser pour que des choses se passent chaque fois qu'un nœud est supprimé. Les docs vous disent que ce hook transmet au module l’objet de ce nœud supprimé et qu’il décrit d’autres informations utiles, telles que le moment exact de son appel (par exemple, le moment où les données du nœud sont réellement supprimées de la base de données). , et où dans le code de Drupal le crochet est appelé (qui peut être plus d’un endroit).

Vous pouvez explorer les points d'ancrage existants et découvrir les données qui leur sont transmises en explorant des éléments tels que "point d'ancrage" dans l'api Drupal .

Les hooks fonctionnent selon une convention de nom: en utilisant hook_node_deletenotre exemple, lorsque le processus de suppression de noeud atteint le point où le hook est appelé, pour chaque module avec une fonction comme celle-ci, [modulename]_node_delete()le mot hook dans le nom du hook est remplacé par le nom du module (par exemple my_amazing_module_node_delete()), ces fonctions sont appelées.

Pourquoi? Ainsi, n'importe quel module peut faire n'importe quoi à ces points clés: par exemple, vous pouvez regarder le nœud supprimé et faire les choses s'il répond à une certaine condition (par exemple, envoyer un courrier électronique à un administrateur ou lancer un processus long).

Certains crochets vous permettent de modifier les éléments générés juste avant leur traitement. Par exemple, hook_menu_alter () vous transmet les éléments de menu actuels générés par le système. N'importe quel module peut définir une fonction some_modulename_menu_alter () et les regarder, éventuellement les modifier (en supprimer, en ajouter, les trier ...) et renvoyer le menu nouvellement modifié.

C’est simple, très puissant et est au cœur du fonctionnement de Drupal en tant que système modulaire. Les implémentations de hooks sont au cœur de la plupart des modules Drupal.

Lorsque vous parcourez le code d'un module Drupal, vous pouvez identifier les fonctions qui proviennent de hooks (par opposition aux fonctions simplement appelées depuis le code même du module), car la communauté Drupal applique une convention selon laquelle chaque implémentation d'un hook a une commentez devant comme ceci (notez le bit "Implements hook _..."):

/**
 * Implements hook_some_hook().
 *
 * Some descriptive summary of what this does
 */
function my_amazing_module_some_hook() {

Certains modules qui agissent en tant qu'API définissent leurs propres hooks. Par exemple, Vues définit de nombreux points d'ancrage qui vous permettent d'ajouter, de lire et d'éditer des données à différents moments du processus de création ou d'affichage d'une vue. Vous pouvez trouver des informations sur les points d'ancrage créés dans des modules personnalisés à partir de deux emplacements (en supposant que le module respecte les conventions, etc.):

Bootstrapping est, comme d’autres l’ont expliqué, un démarrage - je ne dupliquerai pas les autres bonnes explications claires.

utilisateur568458
la source
53

Les crochets sont principalement des implémentations des modèles Visitor et Observer .

Hook_menu , qui permet aux modules d’enregistrer de nouveaux chemins au sein d’un système Drupal, est l’une des implémentations de hooks les plus courantes .

function my_module_menu() {
  return array('myawesomefrontpage' => array(
    'page callback' => 'function_that_will_render_frontpage'
  ));
}

Un schéma très fréquent chez Drupal est d'avoir un [DATATYPE]_infocrochet et un [DATATYPE]_info_altercrochet. Si vous souhaitez créer un nouveau type de champ, vous allez implémenter le field_info-hook approprié, et si vous voulez manipuler un type existant, vous devez implémenter le field_info_alter -hook correspondant .

Edit: Comme Chx le fait remarquer dans les commentaires, le motif de l'observateur est orienté objet , ce que Drupal 7 ne l'est toujours pas. Il existe cependant une page wiki, la programmation Drupal d'un point de vue orienté objet (Créé par JonBob le 4 avril 2005), qui explique comment Drupal utilise des modèles de code orientés objet. Il est intéressant de noter que cela mentionne les observateurs, mais pas les visiteurs.

Note sur Drupal 8 Ceci est encore assez tôt et peut changer, mais je tiens à ajouter que, bien que les points d' ancrage constituent depuis de nombreuses années la norme de facto pour l'ajout de fonctionnalités à Drupal, le concept de plugins deviendra beaucoup plus visible. dans Drupal 8, et nous donnera de nouvelles façons d’interagir avec Core. Pertinente question , et la documentation .

Letharion
la source
2
Ne vous laissez pas berner par les modèles de conception OOP Ceci n'est pas un. Les crochets Drupal sont en AOP. Voir ci-dessous.
@chx, alors que je reconnais librement que vous savez mieux que moi :) et que votre réponse est correcte (je l'ai votée contre) je n'interprète pas cela comme une réponse fausse. :) Si vous êtes en désaccord, j'aimerais savoir comment j'ai mal compris les schémas de leur mise en œuvre.
Letharion
4
Wikipedia: "Le modèle d'observateur est un modèle de conception logicielle dans lequel un objet, appelé sujet, maintient une liste de ses personnes à charge, appelée observateurs". Le visiteur est plus trouble mais le même principe générique s’applique: ce qui n’est pas une POO ne peut pas avoir de modèles de POO
33

En termes simples, les crochets sont en quelque sorte des ponts qui permettent aux modules d'interagir les uns avec les autres, de modifier la structure et les données de chacun, de fournir de nouvelles données, etc.

Dans la plupart des cas, le mot hook_dans les noms de fonction est remplacé par le nom de votre module, ce qui permet à votre module d’exploiter le fonctionnement d’un autre module. Par exemple, un module de base Drupal appelé "noeud" appelle différents hooks. L'un d'eux est celui hook_node_updatequi est appelé chaque fois qu'un nœud existant est mis à jour. Lorsque ce hook est appelé, on appelle la mymodulemise en oeuvre de votre module (appelons-le ). hook_node_updateCette fonction sera dans ce cas une fonction du fichier .module de votre module appelée mymodule_node_update(évidemment, cette fonction peut être dans n'importe quel fichier du dossier de votre module il est également inclus dans le fichier .module). Ce hook recevra également les paramètres nécessaires (variables) qu’il pourra utiliser, modifier et / ou retourner à la fonction qui a appelé le hook.

Quand j'ai commencé à apprendre Drupal, j'étais dans le même bateau que vous, c'est un peu difficile à saisir au début, mais une fois que vous l'avez compris, c'est tellement simple et intuitif. Bonne chance.

Abeille
la source
1
merci pour votre réponse.il m'aide beaucoup. pouvez-vous s'il vous plaît dire quel est le concept de bootstrap dans Drupal et comment les crochets sont traités dans bootstraping en mots simples comme vous expliquez la réponse précédente ..
GiLL
@ Bayasa, s'il vous plaît entrez vos propres pensées ici. J'ajoute simplement le mien. Vous pouvez penser à boostrtapping au démarrage de votre ordinateur. Drupal possède de nombreuses API, y compris une base de données, des fichiers et des formulaires. Ceux-ci sont basés sur une "plate-forme". Au cours du démarrage, Drupal définit ces fonctions et les autres paramètres (connexion à la base de données, dossiers, etc.) afin que le reste du système puisse continuer à partir du reste.
AyeshK
32

L'un des développeurs principaux a écrit il y a quelque temps un article intitulé "Programmation Drupal dans une perspective orientée objet" . Cela explique bien comment on peut penser que les crochets implémentent de nombreux modèles de conception courants . La meilleure explication des hameçons provient de l'article:

Le système de hook de Drupal est la base de son abstraction d'interface. Les crochets définissent les opérations pouvant être effectuées sur ou par un module. Si un module implémente un hook, il conclut un contrat pour effectuer une tâche particulière ou renvoyer un type particulier d'informations lorsque le hook est appelé. Le code appelant n'a pas besoin de savoir quoi que ce soit sur le module ou sur la manière dont le hook est mis en œuvre pour pouvoir effectuer un travail utile en invoquant le hook.

mpdonadio
la source
1
J'ai corrigé la paternité de cet article selon drupal.org/node/19964
@chx, merci. J'envisage de supprimer cette réponse maintenant. Je l'ai posté car j'avais l'habitude de faire beaucoup de travail OO en clair, et je me suis habitué aux concepts OO sans objets réels. Cependant, vous avez raison sur la relation pointcut / weaver. Je ne suis toutefois pas sûr si la citation est une description précise d'un aspect (en ignorant la partie "abstraction de l'interface").
mpdonadio
21

Le bootstrap est le processus que Drupal utilise pour créer une page, qui exécute en principe tout le code de base, de thème et de module.
C'est en gros comment Drupal démarre et se prépare à faire son travail de CMS.

C’est intelligent, en ce sens qu’il nous permet de placer des points d’accès n’importe où dans nos modules et nos thèmes, et que le processus de bootstrap garantit leur exécution au bon moment.
Par exemple, si vous utilisez 'hook_form_alter' pour ajouter une case à cocher personnalisée à un formulaire, l'amorçage de Drupal s'assurera qu'il exécute ce code, juste avant le rendu de votre formulaire.

L'un des problèmes avec l'amorçage est que le processus complet prend du temps à s'exécuter, même si vous ne renvoyez qu'une petite quantité de données. Lors de l'utilisation de Drupal avec le module de services en tant qu'API et du renvoi de nombreuses petites réponses XHTML ou JSON, l'exécution de l'intégralité du bootstrap n'est pas très performante. Certaines personnes intelligentes cherchent des solutions intelligentes à ce problème pour Drupal 8.

Mais pour le rendu des pages Drupal normales, le processus d'amorçage fonctionne à merveille. Il utilise le système de mise en cache Drupal pour accélérer les opérations et vous donne un contrôle total sur toutes les parties de votre site. Si vous trouvez que votre site est lent, vous pouvez toujours utiliser quelque chose comme APC ou MemCached pour accélérer les choses.

J'espère que ma réponse était exacte et explique les choses simplement pour vous, je ne suis pas un expert, mais je pense que c'est comme ça que ça marche.

Medden
la source
15

Bootstrap est le processus au cours duquel Drupal s’initialise lui-même; le processus comprend en réalité:

  • Définition de l'erreur et des gestionnaires d'exceptions
  • Initialisation de la valeur de certaines variables spéc-globales contenues dans $_SERVER
  • Initialisation de certaines variables avec init_set()
  • Recherche de la version en cache de la page à servir
  • Initialisation de la base de données
  • Définition des gestionnaires qui chargent des fichiers lorsqu'une classe ou une interface est introuvable
  • Initialiser les variables Drupal
  • Initialiser la session PHP
  • Initialisation de la variable de langue
  • Chargement des modules activés

Certaines des opérations que j'ai décrites sont spécifiques à Drupal 7 ou supérieur, mais la plupart des opérations sont indépendantes de la version de Drupal.

Un hook est une fonction PHP qui peut être appelée à partir de Drupal, ou de modules tiers, lorsque cela est nécessaire pour effectuer une tâche. Au lieu d'avoir une liste de fonctions préfixée à appeler, la liste est construite en vérifiant les modules activés et les fonctions qu'ils implémentent.
Par exemple, Drupal utilise hook_node_update(); Lorsqu'un noeud est en cours d'enregistrement avec node_save () , le code suivant est exécuté.

// Call the node specific callback (if any). This can be
// node_invoke($node, 'insert') or
// node_invoke($node, 'update').
node_invoke($node, $op);

Ce que fait node_invoke () est le suivant:

  • Obtenir la liste de tous les modules activés
  • Vérifier si les modules activés ont une fonction dont le nom se termine par "_node_update" et commence par le nom abrégé du module
  • Appeler cette fonction en passant $nodeen paramètre

Les hooks peuvent sauvegarder leurs propres données dans une base de données ou modifier la valeur renvoyée par une fonction. Le dernier cas est, par exemple, ce qui se passe avec hook_form_alter () , qui modifie la valeur de $formpassée en tant que référence à drupal_prepare_form () .

Les hooks Drupal sont généralement appelés en utilisant trois fonctions:

drupal_alter()est la fonction utilisée pour appeler des points d' ancrage spécifiques dont le but est de modifier les données transmises en tant que référence, telles que hook_form_alter () , hook_hook_info_alter () et hook_tokens_alter () .

Il existe d'autres fonctions utilisées pour appeler des points d'ancrage, telles que node_invoke(), mais ces fonctions utilisent essentiellement l'une des fonctions que j'ai énumérées précédemment.

kiamlaluno
la source
12

Les crochets sont des coupes pointues et module_invoke_allconstituent le tisserand (hélas, nous ne sommes pas clairs dans la mise en œuvre et il existe d'autres fonctions de tissage). Autant que je sache, Drupal est le seul système à implémenter AOP avec des fonctions PHP.

Voir une autre explication sur Comment l'AOP fonctionne-t-il dans Drupal?

Communauté
la source
Pensez-vous que l'article de jhodgdon (mentionné dans ma réponse) est exact?
mpdonadio
2
C'est l'article de jonbob de 2005 qui attribue une erreur. Je voudrais en débattre, oui.
6

Si vous voulez voir les points d' ancrage que Drupal vous permet d'appeler, allez à api.drupal.org , passez au champ de recherche et tapez 'hook_'. Cela vous donnera une grande liste de la plupart des hooks définis par Drupal. Faites la même chose pour '_alter' et voyez encore plus.

La page Hooks API de nœud offre une liste chronologique de tous les hooks invoqués lors des opérations de nœud. Vous pouvez voir le module Node et les systèmes Entity et Field se donner mutuellement tour à tour pour invoquer des points d'ancrage.

Par exemple, si vous faites défiler l'écran vers le bas et regardez la section node_load(): Le module Node vous donnera un hook_load (), puis passera le contrôle au système de l'entité qui charge certains champs. Il existe toute une série de points d’accès au champ non répertoriés, puis, lorsque c’est le cas, le système d’entité invoque hook_entity_load(), avant de rendre le contrôle au nœud qui l’appelle hook_node_load().

Cela donne à votre code la possibilité d'agir sur le nœud en question au fur et à mesure de son chargement, pièce par pièce. Apprendre ces hooks et quand et pourquoi ils sont appelés fait partie de l’aventure du codage Drupal. :-)

D'autres systèmes ont aussi des crochets. Comme hook_init()et hook_boot(). Cela va à la partie bootstrap de votre question. hook_boot()est appelé par Drupal avant le chargement du système de mise en cache. Donc, si votre module doit faire quelque chose avant que Drupal ne soit vraiment démarré, et que vous voulez que votre code soit exécuté quelle que soit la mise en cache, vous l'implémenterez hook_boot(). Sinon, si vous vous souciez uniquement des pages qui ne sont pas mises en cache, vous devez les implémenter hook_init().

Cela vous donne la possibilité d’implémenter quelque chose au début du processus de chargement, avant que Drupal n’ait complètement démarré, tout en vous laissant une certaine flexibilité quant au point du processus que vous souhaitez intercepter.

Si vous devez vous assurer que Drupal a démarré à un certain point avant de continuer, vous pouvez appeler drupal_bootstrap(). Si vous cliquez sur cette documentation, vous pouvez voir les niveaux d'amorçage disponibles, de rien à tout.

Et, enfin, vous pouvez voir du code très documenté pour un sous-système donné dans le projet Exemples .

paul-m
la source
Le PO demande une définition de hook, pas une liste de hooks utilisés par Drupal.
kiamlaluno
6

Les hooks sont des fonctions php, des blocs de construction basés sur les conventions de nommage "nom_du_module>, qui sont conçus pour aider les développeurs à créer des modules .

Les modules sont la vraie affaire, car ils permettent à la fois les fonctionnalités essentielles et personnalisées de votre système Drupal. Ainsi, les modules sont constitués de hooks et lorsqu'un module est activé dans votre installation Drupal, ses fonctions hooks peuvent être appelées depuis d'autres modules grâce à la fonction module.inc module_invoke_all ($ hook) ou module_invoke.

Par conséquent, pour bien comprendre ce que sont les crochets, vous devriez vraiment vous salir les mains et essayer le développement de modules. À cette fin, commencez par télécharger et essayer certains exemples de développeurs Drupal . Vous devez également vous familiariser avec la création de modules .

Voici quelques exemples de Drupal utiles aux développeurs mentionnés ci-dessus:

hook_block_view () Exemple d'implémentation dans le module block_example

/**
 * @file examples/block_example/block_example.module line 127
 *
 * Implements hook_block_view().
 *
 * This hook generates the contents of the blocks themselves.
 */
function block_example_block_view($delta = '') {
  //The $delta parameter tells us which block is being requested.
  switch ($delta) {
    case 'example_configurable_text':
      // The subject is displayed at the top of the block. Note that it
      // should be passed through t() for translation. The title configured
      // for the block using Drupal UI supercedes this one.
      $block['subject'] = t('Title of first block (example_configurable_text)');

Ce crochet vous donne accès à la création de blocs Drupal pour afficher des blocs personnalisés sur votre site Web. C'est possible parce que le block.module a une fonction _block_render_block qui permet à tous les modules de définir leur vue hook_block (remarquez la dernière ligne de module_invoke):

/**
 * @file modules/block/block.module, line 838
 *
 * Render the content and subject for a set of blocks.
 *
 * @param $region_blocks
 *   An array of block objects such as returned for one region by _block_load_blocks().
 *
 * @return
 *   An array of visible blocks as expected by drupal_render().
 */
function _block_render_blocks($region_blocks) {
  ...
  foreach ($region_blocks as $key => $block) {
    ...
    $array = module_invoke($block->module, 'block_view', $block->delta);

hook_menu () exemple d'implémentation dans le module render_example

/**
 * @file examples/render_example/render_example.module line 22
 * 
 * Implements hook_menu().
 */
function render_example_menu() {
  ...
  $items['examples/render_example/arrays'] = array(
    'title' => 'Render array examples',
    'page callback' => 'render_example_arrays',
    'access callback' => TRUE,
  );

Ce hook est lié au système de routage URL de Drupal et définit des modèles d’URL avec les rappels de rendu associés utilisés par votre module. Il est appelé depuis system.module .

En ce qui concerne le bootstrap, vous devez simplement savoir qu’il est exécuté à chaque requête de page. Je vous conseille vraiment de lire cette réponse , qui explique comment bootstrap et les hooks sont liés mais séparés.

En ce qui concerne l'affichage de la page Web, l'affichage HTML du site Web de Drupal est principalement réalisé avec des tableaux de rendu et des thèmes.

B2F
la source
3

Partout où un module appelle module_implements () http://api.drupal.org/api/drupal/includes%21module.inc/function/module_implements/7 Drupal activera toutes les fonctions correctement nommées dans le bon ordre en fonction de leur poids. Celles-ci sont appelées fonctions de hook car dans la documentation des modules qui utilisent module_implements, vous voyez des choses comme hook_menu (lorsque le menu appelle toutes les fonctions conçues pour renvoyer des éléments de menu). Le mot "hook" doit juste être remplacé par le nom du module qui l'implémente et Drupal fait le reste.

Il existe également une fonction drupal_alter () qui déclenche toutes les fonctions de modification correctement nommées, dans le but de vous permettre de modifier des éléments précédemment enregistrés par un autre hook.

Généralement, altters transmettra les arguments par référence pour vous permettre de modifier l'objet directement, alors que les points d'ancrage "normaux" vous permettent généralement de renvoyer de nouvelles choses.

L'idée est que n'importe quel module (y compris le vôtre) peut facilement être étendu en demandant à Drupal d'appeler toutes les fonctions de hook requises et de récupérer ce qu'elles retournent pour être traitées. Le module appelant les fonctions de hook n'a pas besoin de savoir quoi que ce soit sur les modules qui implémentent les hooks, et les modules implémentant le hook n'ont pas vraiment besoin de savoir rien sur le module qui appelle le hook. La seule chose que les deux modules doivent savoir, c'est la structure des données renvoyées ou modifiées.

En pratique, les hameçons sont le plus souvent utilisés pour:

  • répondre aux événements, comme hook_user_login est appelé lorsqu'un utilisateur se connecte
  • enregistre quelque chose de nouveau qui peut être utilisé pour étendre le système comme hook_menu
  • thème / rendu html ou construction / validation / envoi de formulaires
David Meister
la source
1

Vous avez beaucoup de réponses ci-dessus mais je tiens à vous donner une réponse beaucoup plus simple pour comprendre le concept de base derrière les crochets. Les hooks sont en réalité des fonctions intégrées dans Drupal Core pour gérer différentes tâches. Vous pouvez synchroniser vos propres fonctions avec ces fonctions intégrées de Drupal Core pour ajouter leurs fonctionnalités à vos propres fonctions en appelant différents hooks.

J'espère que vous comprendrez!

utilisateur25892
la source
1

Pour moi, il s’agit de la fonction module_implements en matière de hooks et de core (D7). Une chose qui, je pense, est cruciale à comprendre, c’est qu’en écrivant un crochet pour modifier quelque chose, vous n’aurez en aucun cas le dernier mot sur l’évolution des structures de données avec lesquelles vous traitez. Votre hook obtient simplement dans la ligne (file d'attente) des fonctions qui agissent AUSSI sur les mêmes structures de données, qu'il s'agisse de menus, de liens de menu, de blocs, de nœuds, d'utilisateurs ou de toute entité ou élément de rendu.

Donc, pour vraiment voir vos hameçons être utilisés de la manière attendue, vous devez savoir ou savoir où vous (votre hameçon) faites la queue. Ceci est déterminé par le poids de votre mondule. Le noyau Drupal appelle simplement les crochets correctement nommés dans l’ordre de poids croissant et quoi qu’il advienne des données.

J'ai déjà écrit des crochets qui n'ont eu aucun effet, mais après des heures de tête, j'ai appris que le poids de mon module était trop léger et que les crochets suivants ne faisaient que ce que je faisais ou les ignoraient totalement.

Un crochet bien écrit ne "manipulera" pas ou ne se "forcera" pas à être le dernier, mais "placera gentil avec les autres" en s'assurant de maintenir les structures de données comme prévu par le reste des crochets le long de la ligne.

Et en parlant de "la ligne" des crochets. Au fil des ans, j'ai parcouru Google pour les contenus Drupal. Cette image semble être une bonne représentation de la liste des possibilités de pré-processus et de processus.
entrez la description de l'image ici

Dan Shumaker
la source
1

De manière beaucoup plus simple, les crochets aident le développeur à modifier les fonctionnalités existantes en fonction des besoins sans modifier le code existant. Plus comme fonction abstraite en php.

Exemple: Vous avez créé un module pour réserver un billet de bus. Selon votre code, si le billet est réservé une fois, l'emplacement de prise en charge n'est pas modifiable, ce qui était votre exigence pour ce projet. Supposez que votre ami ait besoin du même module pour une exigence similaire, à l'exception du fait que l'utilisateur peut modifier l'emplacement de prise en charge. D'une manière ou d'une autre, il doit utiliser votre module et vous ne voulez pas qu'il modifie le code. Vous fournissez donc une interface (crochet dans notre cas) où il pourrait mettre en œuvre ses modifications sans apporter de modifications à votre module.

De drupal à drupal-7, nous avons des points d'ancrage pour les modules et les thèmes. Pour savoir comment fonctionne crochet vérifier est drupal.org crochets pour créer un contrôle de crochet personnalisé ce lien

Anamika
la source
0

Crochets Autoriser les modules à interagir avec le noyau Drupal. Le système de modules de Drupal est basé sur le concept de "crochets". Un hook est une fonction PHP nommée foo_bar (), où "foo" est le nom du module (dont le nom de fichier est donc foo.module) et "bar" est le nom du hook.

Amrendra Mourya
la source