{"id":1835,"date":"2011-01-01T09:24:49","date_gmt":"2011-01-01T08:24:49","guid":{"rendered":"http:\/\/flaven.fr\/?p=1835"},"modified":"2013-11-27T07:03:37","modified_gmt":"2013-11-27T06:03:37","slug":"drupal-module-php-concevoir-et-realiser-un-module-sous-drupal","status":"publish","type":"post","link":"https:\/\/flaven.fr\/2011\/01\/drupal-module-php-concevoir-et-realiser-un-module-sous-drupal\/","title":{"rendered":"Drupal, Module, PHP &#8211; Concevoir et r\u00e9aliser un module sous Drupal"},"content":{"rendered":"<p><!-- Drupal, Module, PHP - Concevoir et r\u00e9aliser un module sous Drupal --><br \/>\n<!--  Drupal, Module, PHP, MySQL, Tutorial, 6.x, 5.x, d\u00e9veloppement --><br \/>\nComme un plugin sous WordPress, un module Drupal a pour fonction d&#8217;\u00e9tendre les fonctionnalit\u00e9s de votre CMS et de l&#8217;\u00e9tendre dans le sens qui vous convient c&#8217;est \u00e0 dire ne fonction des besoins de gestion de de contenu de votre site sous Drupal.<!--more--> Voici la d\u00e9finition simple et officielle de ce qu&#8217;est un module Drupal.<\/p>\n<p><b>Une d\u00e9finition simple d&#8217;un module Drupal<\/b><\/p>\n<blockquote><p>A module is a collection of functions that link into Drupal, providing additional functionality to your Drupal installation. After reading this tutorial, you will be able to create a basic block module and use it as a template for more advanced modules and node modules.<\/p><\/blockquote>\n<p>Avant de se lancer dans la lecture de cet article et de se livrer \u00e0 une exp\u00e9rience <i>d&#8217;extreme coding :):)<\/i>. Un juste rappel de l&#8217;environnement de d\u00e9veloppement. Notre d\u00e9veloppement se fait sur une version de Drupal 5.14 et en local sur un MAMP. Pour installer MAMP sur Mac, reportez aux nombreux articles de ce blog. Vous pouvez r\u00e9aliser la m\u00eame op\u00e9ration sur un PC \u00e0 l&#8217;aide de Easyphp.<\/p>\n\t\t\t\t\t<div class=\"textwidget-unique text\">\n\n\t\t\t\t\t        <div class=\"textwidget-photo\">\n\t\t\t\t\t                <a href=\"https:\/\/flaven.fr\/books\/leveraging-drupal-getting-your-site-done-right\/\" class=\"photo\" title=\"Leveraging Drupal: Getting Your Site Done Right\"><img loading=\"lazy\" decoding=\"async\" alt=\"Leveraging Drupal: Getting Your Site Done Right\" src=\"http:\/\/ecx.images-amazon.com\/images\/I\/41gnzk7TYDL._SL160_.jpg\" width=\"121\" height=\"160\"><\/a>\n\t\t\t\t\t            <\/div>\n\t\t\t\t\t\t<div class=\"info half\">\n\t\t\t\t\t\t\t<h2 class=\"product-title\"><a class=\"head\" href=\"https:\/\/flaven.fr\/books\/leveraging-drupal-getting-your-site-done-right\/\" title=\"Leveraging Drupal: Getting Your Site Done Right\">Leveraging Drupal: Getting Your Site Done Right<\/a><\/h2>\n\t\t\t\t\t\t\t\n\t\t\t\t\t        <p class=\"product-excerpt\">Un excellent livre sur le CMS Drupal, qui prend vraiment le partie d'une approche pragmatique et efficace. Rien n'est laiss\u00e9 de c\u00f4t\u00e9 sur la compr\u00e9hension de Drupal (th\u00e8me, module...etc) mais il n'y a rien de superflu non plus. Par ailleurs, une chose rare qui m\u00e9rite d'\u00eatre signal\u00e9e c'est une application concr\u00e8te de la m\u00e9thode Agile avec \"User storie\", \"Acceptance Test\" pour mener \u00e0 bien le d\u00e9veloppement d'un site sous Drupal. Un livre tr\u00e8s complet.<\/p>\n\t\t\t\t\t\t\t\tGenre(s) : <a href=\"https:\/\/flaven.fr\/book-type\/agile\/\" rel=\"tag\">Agile<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/agile-scrum\/\" rel=\"tag\">Agile Scrum<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/ajax\/\" rel=\"tag\">Ajax<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/api\/\" rel=\"tag\">API<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/apis\/\" rel=\"tag\">APIs<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/applications\/\" rel=\"tag\">Applications<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/cms\/\" rel=\"tag\">CMS<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/development\/\" rel=\"tag\">Development<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/direction-de-projet-agile\/\" rel=\"tag\">Direction de projet<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/drupal\/\" rel=\"tag\">Drupal<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/javascript\/\" rel=\"tag\">Javascript<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/jquery\/\" rel=\"tag\">jQuery<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/jquery-ui\/\" rel=\"tag\">jQuery UI<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/open-source-agile-developpement\/\" rel=\"tag\">Open Source<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/php\/\" rel=\"tag\">PHP<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/php-applications\/\" rel=\"tag\">PHP Applications<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/theme-2\/\" rel=\"tag\">Theme<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/user-stories\/\" rel=\"tag\">User stories<\/a>, <a href=\"https:\/\/flaven.fr\/book-type\/website\/\" rel=\"tag\">Website<\/a><br>Auteur(s) : <a href=\"https:\/\/flaven.fr\/book-author\/victor-kane\/\" rel=\"tag\">Victor Kane<\/a><br>Edition(s) : <a href=\"https:\/\/flaven.fr\/book-description\/john-wiley-sons\/\" rel=\"tag\">John Wiley &amp; Sons<\/a><br>\n\t\t\t\t\t<div class=\"but-wrap\"><a href=\"http:\/\/www.amazon.fr\/Leveraging-Drupal-Getting-Your-Right\/dp\/0470410876%3FSubscriptionId%3DAKIAJYB2QGGQOTHQLRPA%26tag%3Dhecubenet-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0470410876\" class=\"button\"><span><i class=\"more\"><\/i>+ d'infos<\/span><\/a><\/div>\n\t\t\t\t\t\t<\/div>\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t\n<ul>\n<li>Drupal &#8211; Installation de Drupal 6<br \/>\n\t<a href=\"http:\/\/social.hecube.net\/blog\/2009\/06\/09\/drupal-installation-de-drupal-6\/\">http:\/\/social.hecube.net\/blog\/2009\/06\/09\/drupal-installation-de-drupal-6\/<\/a>\n\t<\/li>\n<\/ul>\n<h4>Pour bien commencer<\/h4>\n<p>Il vous faudra cr\u00e9er un r\u00e9pertoire dans <code>sites\/all\/modules\/onthisdate<\/code>. Il est possible que vous ayez \u00e0 cr\u00e9er pr\u00e9alablement le r\u00e9pertoire <code>sites\/all\/modules<\/code> <\/p>\n<p>Le chemin absolu de notre repertoire sera donc <code>\/Applications\/MAMP\/htdocs\/DRUPAL_5_14\/sites\/all\/modules\/<\/code><\/p>\n<p>Cr\u00e9er et placer un fichier PHP nomm\u00e9 <code>onthisdate.module<\/code> dans le r\u00e9pertoire nouvellement cr\u00e9\u00e9 <code>\/Applications\/MAMP\/htdocs\/DRUPAL_5_14\/sites\/all\/modules\/onthisdate\/<\/code><\/p>\n<p>Pourquoi dans ce r\u00e9pertoire comme il ne s&#8217;agit pas d&#8217;un core module mais d&#8217;un module de votre composition, il vous sera plus facile de faire les mises \u00e0 jour des core modules sans \u00e9craser vos modules sur-mesure.<\/p>\n<p>Selon les standards de coding de Drupal, vous devez commencer par la balise d&#8217;ouverture PHP compl\u00e8te au d\u00e9but de votre fichier <code>&lt;?php<\/code> mais de ne pas faire de balise de fermeture type <code>?&gt;<\/code><\/p>\n<p><b>le code source de <code>onthisdate.module<\/code> est le suivant.<\/b><\/p>\n<pre lang=\"php\" escaped=\"true\">\r\n&lt;?php\r\n\/* $Id$ *\/\r\n<\/pre>\n<p>La string <code>$Id$<\/code> n&#8217;est utile que si vous souhaitez comptabiliser la date et la version de votre module via un outil de gestion de version (CVS).<\/p>\n<p><b>La d\u00e9finition officielle du <code>_hook<\/code><\/b><\/p>\n<blockquote><p>All functions in your module that will be used by Drupal are named {modulename}_{hook}, where &#8220;hook&#8221; is a pre-defined function name suffix. Drupal will call these functions to get specific data, so having these well-defined names means Drupal knows where to look. We will come to hooks in a while.<\/p><\/blockquote>\n<p>On retrouve la m\u00eame terminologie que dans le CMS WordPress.<\/p>\n<p><b>Le code du fichier <code>onthisdate.info<\/code><\/b><\/p>\n<pre lang=\"text\">\r\n\r\n; $Id: blog.info,v 1.5 2007\/06\/08 05:50:53 dries Exp $\r\nname = On this date\r\ndescription = A block module that lists links to content such as blog entries or forum discussions that were created one week ago.\r\npackage = Non-Core - optional\r\nversion = VERSION\r\ncore = 5.x\r\n\r\n; Test of module creation made by hecube.net\r\n<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2011\/01\/module_coding_drupal_5_14_1.jpg\" alt=\"Drupal, Module, PHP - Concevoir et r\u00e9aliser un module sous Drupal\" width=\"500\" height=\"265\" \/><\/p>\n<p>On peut rajouter du commentaire et\/ou donner plus d&#8217;information dans des champs optionnels. Cela est toujours utile quand un autre d\u00e9veloppeur doit passer derri\u00e8re, ne soyez jamais avare d&#8217;informations, c&#8217;est un fichier d&#8217;informations !<\/p>\n<pre lang=\"text\">\r\ndependencies = module1 module2 module3\r\npackage = \"Your arbitrary grouping string\"\r\nversion = \"$Name$\"\r\n<\/pre>\n<p><b>Un compl\u00e9ment d&#8217;informations sur les autres champs du <code>.info<\/code><\/b><\/p>\n<ul>\n<li>Ne pas compl\u00e9ter <code>package<\/code> fera que votre module sera class\u00e9 une non cat\u00e9gorie ou la cat\u00e9gorie par d\u00e9faut (Uncategorized).<\/li>\n<li>Si vous compl\u00e9tez le champs <code>dependencies<\/code>, le module ne pourra \u00eatre activ\u00e9 que si les &#8220;dependencies&#8221;  requises sont install\u00e9es par exemple CCK, Views<br \/>\n&#8230;etc.<\/li>\n<\/ul>\n<p><b>Une partie du code source de <code>onthisdate.module<\/code><\/b><br \/>\nLa totalit\u00e9 du code est disponible en fin de cet article.<\/p>\n<pre lang=\"php\" escaped=\"true\">\r\n\r\n\t&lt;?php\r\n\t\/* $Id$ *\/\r\n\r\n\r\n\t\/**\r\n\t* Display help and module information\r\n\t* @param section which section of the site we're displaying help\r\n\t* @return help text for section\r\n\t*\/\r\n\tfunction onthisdate_help($section='') {\r\n\t\t\t\t$output = '';\r\n\t\t\t\tswitch ($section) {\r\n\t\t\t\t\tcase \"admin\/help#onthisdate\":\r\n\t\t\t\t\t$output = '&lt;p&gt;'. t(\"Displays links to nodes created on this date\"). '&lt;\/p&gt;';\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\treturn $output;\r\n\t\t\t} \/\/ function onthisdate_help\r\n\r\n\r\n\r\n\t\/**\r\n\t* Valid permissions for this module\r\n\t* @return array An array of valid permissions for the onthisdate module\r\n\t*\/\r\n\t\tfunction onthisdate_perm() {\r\n\t\t\treturn array('access onthisdate content');\r\n\t\t} \/\/ function onthisdate_perm()\r\n\r\n\r\n\t\/**\r\n\t* Generate HTML for the onthisdate block\r\n\t* @param op the operation from the URL\r\n\t* @param delta offset\r\n\t* @returns block HTML\r\n\t*\/\r\n\t\tfunction onthisdate_block($op='list', $delta=0) {\r\n\t\t\/\/ listing of blocks, such as on the admin\/block page\r\n\t\t\tif ($op == \"list\") {\r\n\t\t\t\t$block[0][\"info\"] = t(\"On This Date\");\r\n\t\t\t\treturn $block;\r\n\t\t\t\t} else if ($op == 'view') {\r\n\t\t\t\/\/ our block content\r\n\t\t\t\/\/ content variable that will be returned for display\r\n\t\t\t$block_content = '';\r\n\t\t\t\/\/ Get today's date\r\n\t\t\t$today = getdate();\r\n\t\t\t\/\/ calculate midnight one week ago\r\n\t\t\t$start_time = mktime(0, 0, 0,$today['mon'],\r\n\t\t\t($today['mday'] - 7), $today['year']);\r\n\t\t\t\/\/ we want items that occur only on the day in question, so\r\n\t\t\t\/\/calculate 1 day\r\n\t\t\t$end_time = $start_time + 86400;\r\n\t\t\t\/\/ 60 * 60 * 24 = 86400 seconds in a day\r\n\t\t$query = \"SELECT nid, title, created FROM \".\"{node} WHERE created &gt;= '\".$start_time.\"' AND created &lt;= '\".$end_time.\"'\";\r\n\t\t\/\/ get the links\r\n\t\t$queryResult = db_query($query);\r\n\t\t\twhile ($links = db_fetch_object($queryResult)) {\r\n\t\t\t\t$block_content .= l($links-&gt;title,'node\/'.$links-&gt;nid).'&lt;br\/&gt;';\r\n\t\t\t\t}\r\n\t\t\/\/ check to see if there was any content before setting up the block\r\n\t\t\tif ($block_content == '') {\r\n\t\t\t\t\/\/ no content from a week ago, return nothing.\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\/\/ set up the block\r\n\t\t\t$block['subject'] = 'On This Date';\r\n\t\t\t$block['content'] = $block_content;\r\n\t\t\treturn $block;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\r\n\t\r\n<\/pre>\n<h4>Cr\u00e9er une page de configuration du module<\/h4>\n<p>Une fois que notre module est activ\u00e9, il ne nous reste plus qu&#8217;\u00e0 cr\u00e9er une page de configuration pour notre module <code>onthisdate<\/code> o\u00f9 l&#8217;administrateur du site pourra d\u00e9finir les modalit\u00e9s de fonctionnement de son module bref le param\u00e9trer.<\/p>\n<p>On va cr\u00e9er une fonction <code>onthisdate_admin<\/code> mais il est \u00e0 noter que <code>_admin<\/code> n&#8217;est pas un <b>hook<\/b> on aurait pu donc appeler notre fonction <code>onthisdate_adminitration_parametrage<\/code> par exemple.<\/p>\n<p><b>Les fonctions \u00e0 ajouter \u00e0 <code>onthisdate.module<\/code> pour autoriser le param\u00e9trage de votre module sont les suivantes. Elles sont isol\u00e9es ci-dessous.<\/b><\/p>\n<pre lang=\"php\" escaped=\"true\">\r\n\t\/**\r\n\t * @file\r\n\t * Enables to show the principles to build a module for Drupal 5.14.\r\n\t *\/\r\n\r\n\tfunction onthisdate_admin() {\r\n\t\t\t$form['onthisdate_maxdisp'] = array(\r\n\t\t\t\t'#type' =&gt; 'textfield',\r\n\t\t\t\t'#title' =&gt; t('Maximum number of links'),\r\n\t\t\t\t'#default_value' =&gt; variable_get('onthisdate_maxdisp', 3),\r\n\t\t\t\t'#size' =&gt; 2,\r\n\t\t\t\t'#maxlength' =&gt; 2,\r\n\t\t\t\t'#description' =&gt; t(\"The maximum number of links to display in the block.\")\r\n\t\t\t\t);\r\n\t\t\treturn system_settings_form($form);\r\n\t\t}\r\n\r\n\r\n\t\tfunction onthisdate_menu() {\r\n\t\t\t$items = array();\r\n\t\t\t$items[] = array(\r\n\t\t\t\t'path' =&gt; 'admin\/settings\/onthisdate',\r\n\t\t\t\t'title' =&gt; t('On this date module settings'),\r\n\t\t\t\t'description' =&gt; t('Description of your on this date settings control'),\r\n\t\t\t\t'callback' =&gt; 'drupal_get_form',\r\n\t\t\t\t'callback arguments' =&gt; 'onthisdate_admin',\r\n\t\t\t\t'access' =&gt; user_access('access administration pages'),\r\n\t\t\t\t'type' =&gt; MENU_NORMAL_ITEM,\r\n\t\t\t\t);\r\n\r\n\t\t\t\/\/this is added for this current tutorial.\r\n\t\t\t$items[] = array(\r\n\t\t\t\t'path' =&gt; 'onthisdate',\r\n\t\t\t\t'title' =&gt; t('on this date'),\r\n\t\t\t\t'callback' =&gt; 'onthisdate_all',\r\n\t\t\t\t'access' =&gt; user_access('access onthisdate content'),\r\n\t\t\t\t'type' =&gt; MENU_CALLBACK\r\n\t\t\t\t\/\/ 'type' =&gt; MENU_NORMAL_ITEM\r\n\r\n\r\n\t\t\t\t);\r\n\t\t\treturn $items;\r\n\t\t}\r\n\t\r\n<\/pre>\n<p><b>Changement d&#8217;un des param\u00e8tres<\/b><br \/>\nSi on active <code>'type' =&gt; MENU_NORMAL_ITEM<\/code><\/p>\n<pre lang=\"php\" escaped=\"true\">\r\n\/\/ 'type' =&gt; MENU_CALLBACK\r\n'type' =&gt; MENU_NORMAL_ITEM\r\n<\/pre>\n<p>Vous pouvez voir le r\u00e9sultat de votre param\u00e9trage \u00e0 la page suivante :<br \/>\n<code>http:\/\/127.0.0.1\/DRUPAL_5_14\/?q=onthisdate<\/code><\/p>\n<p><b>Avec la valeur MENU_CALLBACK activ\u00e9e<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2011\/01\/module_coding_drupal_5_14_2.jpg\" alt=\"Drupal, Module, PHP - Concevoir et r\u00e9aliser un module sous Drupal\" width=\"500\" height=\"265\" \/><\/p>\n<p><b>Avec la valeur MENU_NORMAL_ITEM activ\u00e9e<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2011\/01\/module_coding_drupal_5_14_3.jpg\" alt=\"Drupal, Module, PHP - Concevoir et r\u00e9aliser un module sous Drupal\" width=\"500\" height=\"265\" \/><\/p>\n<p>Pour voir l&#8217;aide concernant le module<br \/>\n<code>http:\/\/127.0.0.1\/DRUPAL_5_14\/?q=admin\/help\/onthisdate<\/code><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2011\/01\/module_coding_drupal_5_14_4.jpg\" alt=\"Drupal, Module, PHP - Concevoir et r\u00e9aliser un module sous Drupal\" width=\"500\" height=\"265\" \/><\/p>\n<p>Pour param\u00e8trer l&#8217;acc\u00e8s \u00e0 votre module pour des utilisateurs loggu\u00e9s ou non&#8230;<br \/>\n<code>http:\/\/127.0.0.1\/DRUPAL_5_14\/?q=admin\/user\/access#module-onthisdate<\/code><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2011\/01\/module_coding_drupal_5_14_5.jpg\" alt=\"Drupal, Module, PHP - Concevoir et r\u00e9aliser un module sous Drupal\" width=\"500\" height=\"265\" \/><\/p>\n<p>Un conseil, si la page de configuration ou la page de resulat de votre module <code>http:\/\/127.0.0.1\/DRUPAL_5_14\/?q=admin\/settings\/onthisdate<\/code> n&#8217;existe pas, le mieux de d\u00e9sactiver puis de r\u00e9activer le module, vous devriez voir ensuite apparaitre la page de configuration.<\/p>\n<p><b>Dans nos exemples d&#8217;URL donn\u00e9es ci-dessus, nous n&#8217;avons pas activ\u00e9 l&#8217;option <code>Clean URLs<\/code><\/b><\/p>\n<h4>Les informations sur l&#8217;environnement de test<\/h4>\n<p>On a fait une installation de test sur MAMP de Drupal 5.14<\/p>\n<p>URL : <code>http:\/\/127.0.0.1\/DRUPAL_5_14\/<\/code><\/p>\n<p><b>Le couple admin:motdepasse<\/b><\/p>\n<ul>\n<li>user: bruno<\/li>\n<li>pwd: demo<\/li>\n<\/ul>\n<p><b>Les information essentielles sur la base de donn\u00e9es adoss\u00e9e au Drupal 5.14<\/b><\/p>\n<blockquote><p>\nDatabase Name = drupal5_14<br \/>\nDatabase User name = drupal5_14<br \/>\nDatabase Password = drupal5_14<br \/>\nDatabase Host = localhost<br \/>\nTable prefix: d_\n<\/p><\/blockquote>\n<pre lang=\"sql\">\r\n\t\/Applications\/MAMP\/Library\/bin\/mysql -u root -p\r\n<\/pre>\n<pre lang=\"sql\">\r\n# Cr\u00e9ation simultan\u00e9e de la base drupal5_14 \r\n# et de l'utilisateur drupal5_14 \r\n\r\nCREATE USER 'drupal5_14'@'localhost' IDENTIFIED BY 'drupal5_14'; GRANT USAGE ON *.* TO 'drupal5_14'@'localhost' IDENTIFIED BY 'drupal5_14'WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0; CREATE DATABASE IF NOT EXISTS drupal5_14;GRANT ALL PRIVILEGES ON drupal5_14.* TO 'drupal5_14'@'localhost';\r\n\r\n<\/pre>\n<h4>Le code du fichier <code>onthisdate.module<\/code><\/h4>\n<p>Voici le code complet du fichier du module <code>onthisdate<\/code><\/p>\n<pre lang=\"php\" escaped=\"true\">\r\n\t&lt;?php\r\n\t\/* $Id: onthisdate.module,v 1.0 28\/12\/2010 08:30:45 $ *\/\r\n\r\n\t\/**\r\n\t * @file\r\n\t * Enables to show the principles to build a module for Drupal 5.14.\r\n\t *\/\r\n\r\n\tfunction onthisdate_admin() {\r\n\t\t\t$form['onthisdate_maxdisp'] = array(\r\n\t\t\t\t'#type' =&gt; 'textfield',\r\n\t\t\t\t'#title' =&gt; t('Maximum number of links'),\r\n\t\t\t\t'#default_value' =&gt; variable_get('onthisdate_maxdisp', 3),\r\n\t\t\t\t'#size' =&gt; 2,\r\n\t\t\t\t'#maxlength' =&gt; 2,\r\n\t\t\t\t'#description' =&gt; t(\"The maximum number of links to display in the block.\")\r\n\t\t\t\t);\r\n\t\t\treturn system_settings_form($form);\r\n\t\t}\r\n\r\n\r\n\t\tfunction onthisdate_menu() {\r\n\t\t\t$items = array();\r\n\t\t\t$items[] = array(\r\n\t\t\t\t'path' =&gt; 'admin\/settings\/onthisdate',\r\n\t\t\t\t'title' =&gt; t('On this date module settings'),\r\n\t\t\t\t'description' =&gt; t('Description of your on this date settings control'),\r\n\t\t\t\t'callback' =&gt; 'drupal_get_form',\r\n\t\t\t\t'callback arguments' =&gt; 'onthisdate_admin',\r\n\t\t\t\t'access' =&gt; user_access('access administration pages'),\r\n\t\t\t\t'type' =&gt; MENU_NORMAL_ITEM,\r\n\t\t\t\t);\r\n\r\n\t\t\t\/\/this is added for this current tutorial.\r\n\t\t\t$items[] = array(\r\n\t\t\t\t'path' =&gt; 'onthisdate',\r\n\t\t\t\t'title' =&gt; t('on this date'),\r\n\t\t\t\t'callback' =&gt; 'onthisdate_all',\r\n\t\t\t\t'access' =&gt; user_access('access onthisdate content'),\r\n\t\t\t\t'type' =&gt; MENU_CALLBACK\r\n\t\t\t\t\/\/ 'type' =&gt; MENU_NORMAL_ITEM\r\n\r\n\r\n\t\t\t\t);\r\n\t\t\treturn $items;\r\n\t\t}\r\n\r\n\t\/**\r\n\t* Display help and module information\r\n\t* @param section which section of the site we're displaying help\r\n\t* @return help text for section\r\n\t*\/\r\n\tfunction onthisdate_help($section='') {\r\n\t\t\t\t$output = '';\r\n\t\t\t\tswitch ($section) {\r\n\t\t\t\t\tcase \"admin\/help#onthisdate\":\r\n\r\n\t\t\t\t\t$output = '&lt;p&gt;'. t('This module displays links to &lt;i&gt;nodes&lt;\/i&gt; created on this date. &lt;b&gt;The following text has been written by Hecube.net to demonstrate that it is easy to add text, links, explanations in the help section of the module.&lt;\/b&gt;') .'&lt;\/p&gt;';\r\n\r\n\r\n\r\n\r\n\t\t\t\t$output .= '&lt;p&gt;'. t('You can find more articles about Drupal on our blog &lt;a href=\"@hecube\" target=\"_blank\"&gt;@ social.hecube.net&lt;\/a&gt;. These &lt;em&gt;articles&lt;\/em&gt; deal with numerous subjects about Drupal: Drupal 6.x themes web design, Drupal service activation and content type, e-commerce with Drupal 6.x.', array('@hecube' =&gt; 'http:\/\/social.hecube.net\/')) .'&lt;\/p&gt;';\r\n\r\n\r\n\t\t\t\t      $output .= '&lt;p&gt;'. t('For this module, it can be called in a block that could be named &lt;em&gt;On this date&lt;\/em&gt;. This block may be enabled at the &lt;a href=\"@blocks\"&gt;blocks administration page&lt;\/a&gt;.', array('@blocks' =&gt; url('admin\/build\/block'))) .'&lt;\/p&gt;';\r\n\r\n\r\n\t\t\t\t      $output .= '&lt;p&gt;'. t('To use this module, be sure to &lt;a href=\"@modules\"&gt;enable&lt;\/a&gt; the module, in the modules page and define a &lt;a href=\"@blocks\"&gt;position&lt;\/a&gt;.', array('@modules' =&gt; url('admin\/build\/modules'), '@blocks' =&gt; url('admin\/build\/block'))) .'&lt;\/p&gt;';\r\n\t\t\t\t      $output .= '&lt;p&gt;'. t('For more information, see the online handbook on &lt;a href=\"@drupal\"&gt;Drupal.org&lt;\/a&gt;.', array('@drupal' =&gt; 'http:\/\/drupal.org\/handbook\/')) .'&lt;\/p&gt;';\r\n\r\n\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\treturn $output;\r\n\t\t\t} \/\/ function onthisdate_help\r\n\r\n\r\n\r\n\t\/**\r\n\t* Valid permissions for this module\r\n\t* @return array An array of valid permissions for the onthisdate module\r\n\t*\/\r\n\t\tfunction onthisdate_perm() {\r\n\t\t\treturn array('access onthisdate content');\r\n\t\t} \/\/ function onthisdate_perm()\r\n\r\n\r\n\t\/**\r\n\t* Generate HTML for the onthisdate block\r\n\t* @param op the operation from the URL\r\n\t* @param delta offset\r\n\t* @returns block HTML\r\n\t*\/\r\n\t\tfunction onthisdate_block($op='list', $delta=0) {\r\n\t\t\/\/ listing of blocks, such as on the admin\/block page\r\n\t\t\tif ($op == \"list\") {\r\n\t\t\t\t$block[0][\"info\"] = t(\"On This Date\");\r\n\t\t\t\treturn $block;\r\n\t\t\t\t} else if ($op == 'view') {\r\n\t\t\t\/\/ our block content\r\n\t\t\t\/\/ content variable that will be returned for display\r\n\t\t\t$block_content = '';\r\n\t\t\t\/\/ Get today's date\r\n\t\t\t$today = getdate();\r\n\t\t\t\/\/ calculate midnight one week ago\r\n\t\t\t$start_time = mktime(0, 0, 0,$today['mon'],\r\n\t\t\t($today['mday'] - 7), $today['year']);\r\n\t\t\t\/\/ we want items that occur only on the day in question, so\r\n\t\t\t\/\/calculate 1 day\r\n\t\t\t$end_time = $start_time + 86400;\r\n\t\t\t\/\/ 60 * 60 * 24 = 86400 seconds in a day\r\n\r\n\t\t\t\/* The query changed to enable configuration from admin *\/\r\n\t\t\t$limitnum = variable_get('onthisdate_maxdisp', 3);\r\n\t\t\t\/* $query = \"SELECT nid, title, created FROM \".\"{node} WHERE created &gt;= '\".$start_time.\"' AND created &lt;= '\".$end_time. \"' LIMIT \".$limitnum; *\/\r\n\r\n\t$query = \"SELECT nid, title, created FROM \".\"{node} WHERE created &gt;= %d \".\"AND created &lt;= %d\";\r\n\r\n\t\t\t$queryResult = db_query_range($query, $start_time, $end_time, 0,\r\n\t\t\t$limitnum);\r\n\r\n\r\n\r\n\t\t\/\/ get the links\r\n\t\t$queryResult = db_query($query);\r\n\t\t\twhile ($links = db_fetch_object($queryResult)) {\r\n\t\t\t\t$block_content .= l($links-&gt;title,'node\/'.$links-&gt;nid).'&lt;br\/&gt;';\r\n\t\t\t\t}\r\n\t\t\/\/ check to see if there was any content before setting up the block\r\n\t\t\tif ($block_content == '') {\r\n\t\t\t\t\/\/ no content from a week ago, return nothing.\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\/\/ set up the block\r\n\t\t\t$block['subject'] = 'On This Date';\r\n\t\t\t$block['content'] = $block_content;\r\n\r\n\t\t\treturn $block;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\r\n\t\tfunction onthisdate_all() {\r\n\t\t\/\/ content variable that will be returned for display\r\n\t\t$page_content = '';\r\n\t\t\/\/ Get today's date\r\n\t\t$today = getdate();\r\n\t\t\/\/ calculate midnight one week ago\r\n\t\t$start_time = mktime(0, 0, 0, $today['mon'], ($today['mday'] - 7),\r\n\t\t$today['year']);\r\n\t\t\/\/ we want items that occur only on the day in question,\r\n\t\t\/\/ so calculate 1 day\r\n\t\t$end_time = $start_time + 86400;\r\n\t\t\/\/ 60 * 60 * 24 = 86400 seconds in a day\r\n\r\n\t\t\/* $query = \"SELECT nid, title, created FROM \".\"{node} WHERE created &gt;= '\".$start_time.\"' AND created &lt;= '\". $end_time . \"'\"; *\/\r\n\t\t\/* $query = \"SELECT nid, title, created FROM \".\"{node}\"; *\/\r\n\t\t$limitnum = variable_get('onthisdate_maxdisp', 3);\r\n\t\t\/* $query = \"SELECT nid, title, created FROM \".\"{node} LIMIT 0, \".$limitnum.\"\"; *\/\r\n\t\t$query = \"SELECT nid, title, created FROM \".\"{node} LIMIT \".$limitnum.\"\";\r\n\r\n\t\t\/\/ get the links (no range limit here)\r\n\t\t$queryResult = db_query($query);\r\n\t\t\t\twhile ($links = db_fetch_object($queryResult)) {\r\n\t\t\t\t\t$page_content .= l($links-&gt;title, 'node\/'.$links-&gt;nid).'&lt;br \/&gt;';\r\n\t\t\t\t}\r\n\t\t\t\t\/\/ add a more link to our page that displays all the links\r\n\t\t\t\t$page_content .=\"&lt;div class=\"more-link\"&gt;\".l(t(\"more\"),\"onthisdate\", array(\"title\" =&gt; t(\"More events on this day.\"))).\"&lt;\/div&gt;\";\r\n\r\n\t\t\t\t\/\/ check to see if there was any content before\r\n\t\t\t\t\/\/ setting up the block\r\n\t\t\t\tif ($page_content == '') {\r\n\t\t\t\t\/\/ no content from a week ago, let the user know\r\n\t\t\t\t$page_content = \"No events occurred on this site on this date in\r\n\t\t\t\thistory.\";\r\n\t\t\t\t}\r\n\r\n\t\t\treturn $page_content;\r\n\t\t} \/\/ end function onthisdate_all\t\r\n\t\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Comme un plugin sous WordPress, un module Drupal a pour fonction d&#8217;\u00e9tendre les fonctionnalit\u00e9s de votre CMS et de l&#8217;\u00e9tendre dans le sens qui vous&hellip; <\/p>\n<p class=\"text-center\"><a href=\"https:\/\/flaven.fr\/2011\/01\/drupal-module-php-concevoir-et-realiser-un-module-sous-drupal\/\" class=\"more-link\">Continue reading &rarr; <span class=\"screen-reader-text\">Drupal, Module, PHP &#8211; Concevoir et r\u00e9aliser un module sous Drupal<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":9430,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"bf_ai_meta_description":"Concevoir et r\u00e9aliser un module sous Drupal. Ma\u00eetrisez les outils PHP pour cr\u00e9er des blocs et des modules de n\u0153uds avanc\u00e9s.","bf_ai_og_title":"Module Drupal: Concevoir et R\u00e9aliser","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[3454,3444,3447,3449,3451,3435,3452],"tags":[361,362,138,2225,238,2211,20,363],"class_list":["post-1835","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-journalism-writing","category-programming-databases","category-technology-trends","category-tutorials-how-to","category-web-design-front-end","category-web-development","category-wordpress-cms","tag-5x","tag-6x","tag-developpement","tag-drupal","tag-module","tag-mysql","tag-php","tag-tutorial"],"jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p3Vuhl-tB","jetpack_featured_media_url":"https:\/\/flaven.fr\/wp-content\/uploads\/2011\/01\/drupal_generic_g_bf.jpg","_links":{"self":[{"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/posts\/1835","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/comments?post=1835"}],"version-history":[{"count":2,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/posts\/1835\/revisions"}],"predecessor-version":[{"id":10178,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/posts\/1835\/revisions\/10178"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/media\/9430"}],"wp:attachment":[{"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/media?parent=1835"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/categories?post=1835"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/tags?post=1835"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}