{"id":194,"date":"2011-08-18T09:25:09","date_gmt":"2011-08-18T07:25:09","guid":{"rendered":"http:\/\/www.h-hennes.fr\/blog\/?p=194"},"modified":"2016-01-09T11:34:06","modified_gmt":"2016-01-09T09:34:06","slug":"creation-dun-plugin-de-suivi-de-temps-pour-mantis-bugtracker","status":"publish","type":"post","link":"https:\/\/www.h-hennes.fr\/blog\/2011\/08\/18\/creation-dun-plugin-de-suivi-de-temps-pour-mantis-bugtracker\/","title":{"rendered":"Cr\u00e9ation d&rsquo;un plugin de suivi de temps pour Mantis Bugtracker"},"content":{"rendered":"<p><span style=\"text-decoration: underline;\">Mantis BugTracker\u00a0: Cr\u00e9ation d\u2019un plugin \u00ab\u00a0Suivi du temps\u00a0\u00bb<\/span><\/p>\n<p><strong>Edit 29\/04\/2013 :<\/strong>\u00a0 Derni\u00e8re informations sur le plugin :\u00a0<a href=\"https:\/\/www.h-hennes.fr\/blog\/plugin-suivi-de-temps-pour-mantis-bugtracker\/\">https:\/\/www.h-hennes.fr\/blog\/plugin-suivi-de-temps-pour-mantis-bugtracker\/<\/a><\/p>\n<p>J\u2019utilise au quotidien la plateforme Mantis Bugtracker pour g\u00e9rer mes t\u00e2ches en cours, et suivre le temps que je passe sur les diff\u00e9rents projets.<\/p>\n<p>A ce titre j\u2019ai customis\u00e9 l\u2019installation de base avec l\u2019ajout de nouvelles fonctionnalit\u00e9s \u00a0tels que la mise en place d\u2019un \u00e9diteur wysywig(TinyMce) ou la possibilit\u00e9 de cr\u00e9er un bug directement via l\u2019envoi d\u2019un email.<\/p>\n<p>Aujourd\u2019hui je vais vous pr\u00e9senter un plugin que je viens de d\u00e9velopper pour afficher le temps que je passe sur chaque intervention.<br \/>\nNous allons voir ensemble toutes les \u00e9tapes de son d\u00e9veloppement.<br \/>\n( Ma version de mantis est la 1.2.4)<\/p>\n<p>Voici un apper\u00e7u du rendu final du plugin :<\/p>\n<p><a href=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2011\/08\/mantis-suvi-temps-calendrie.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-197 alignnone\" title=\"mantis-suvi-temps-calendrie\" src=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2011\/08\/mantis-suvi-temps-calendrie-1024x811.jpg\" alt=\"Calendrier Mantis\" width=\"614\" height=\"487\" srcset=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2011\/08\/mantis-suvi-temps-calendrie-1024x811.jpg 1024w, https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2011\/08\/mantis-suvi-temps-calendrie-300x237.jpg 300w, https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2011\/08\/mantis-suvi-temps-calendrie.jpg 1903w\" sizes=\"auto, (max-width: 614px) 100vw, 614px\" \/><\/a><br \/>\nAvant toute chose pour que ce plugin fonctionne il est n\u00e9cessaire d\u2019activer la gestion du temps dans Mantis.<\/p>\n<p>Pour ce faire il est n\u00e9cessaire de rajouter la ligne suivante dans le fichier \u00ab\u00a0config.inc.php\u00a0\u00bb<\/p>\n<p><strong>$g_time_tracking_enabled = ON;<\/strong><\/p>\n<p><a href=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2011\/08\/mantis-suivi-temps1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-196 alignleft\" title=\"mantis-suivi-temps\" src=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2011\/08\/mantis-suivi-temps1-300x82.jpg\" alt=\"Suivi du temps avec Mantis bugtracker\" width=\"654\" height=\"179\" srcset=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2011\/08\/mantis-suivi-temps1-300x82.jpg 300w, https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2011\/08\/mantis-suivi-temps1-1024x279.jpg 1024w, https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2011\/08\/mantis-suivi-temps1.jpg 1167w\" sizes=\"auto, (max-width: 654px) 100vw, 654px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Cette ligne rajoute l\u2019option \u201cSuivi du temps (HH::MM) dans l\u2019ajout des commentaires sur les bugs.<\/p>\n<p>Une fois cette option mise en place nous allons proc\u00e9der au d\u00e9veloppement du \u00ab\u00a0plugin\u00a0\u00bb, pour la gestion du calendrier, nous allons nous baser sur le script opensource \u00ab\u00a0fullcallendar\u00a0\u00bb disponible \u00e0 l\u2019adresse suivante\u00a0: <a href=\"http:\/\/arshaw.com\/fullcalendar\/\">http:\/\/arshaw.com\/fullcalendar\/<\/a> .<br \/>\nCe script est bien document\u00e9 et facile \u00e0 utiliser, et il propose directement un mode qui r\u00e9cup\u00e8re des donn\u00e9es json. C\u2019est ce mode que nous allons utiliser.<\/p>\n<p><strong>Cr\u00e9ation de la structure de base du plugin.<\/strong><\/p>\n<p>Nous allons nommer ce plugin \u00ab\u00a0Agenda\u00a0\u00bb et sa structure contiendra les fichiers suivants\u00a0:<\/p>\n<ul>\n<li>Calendrier\n<ul>\n<li>Css\n<ul>\n<li>Fullcalendar.css<\/li>\n<li>Fullcalendar.print.css<\/li>\n<li>Agenda.css<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>Js\n<ul>\n<li>Fullcalendar.min.js<\/li>\n<li>Fullcalendar_init.js<\/li>\n<li>Jquery-1.5.2.min.js<\/li>\n<li>Jquery-ui-1.8.11.custom.min.js<\/li>\n<\/ul>\n<\/li>\n<li>Lang\n<ul>\n<li>Strings_french.txt<\/li>\n<li>String_english.txt<\/li>\n<\/ul>\n<\/li>\n<li>Pages\n<ul>\n<li>Agenda_page.php<\/li>\n<li>Json-events.php<\/li>\n<\/ul>\n<\/li>\n<li>Agenda.php<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p><strong>Cr\u00e9ation de la classe du module<\/strong><\/p>\n<p>Nous allons \u00e0 pr\u00e9sent passer \u00e0 l\u2019\u00e9dition du fichier \u00ab\u00a0Agenda_inc.php\u00a0\u00bb<\/p>\n<p>Voici le code qui le compose\u00a0:<\/p>\n<pre lang=\"php\">&lt;?php \/* Plugin Agenda pour Mantis BugTracker : - Affichage du temps pass\u00e9 sur les bugs dans un calendrier (N\u00e9cessite l'activation de la fonctionnalit\u00e9 $g_time_tracking_enabled) - Bas\u00e9 sur le script de Calendrier \"FullCalendar\" disponible \u00e0 l'adresse suivante : http:\/\/arshaw.com\/fullcalendar\/download\/ Version 0.1 \u00a9 Hennes Herv\u00e9 - 2011 *\/\r\nclass AgendaPlugin extends MantisPlugin {   function register() {\r\n      $this-&gt;name\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0= 'AgendaPlugin';\r\n     $this-&gt;description = 'Affichage du temps pass\u00e9 sur les bugs dans un calendrier';\r\n     $this-&gt;version\u00a0\u00a0\u00a0\u00a0 = '0.1';\r\n     $this-&gt;requires\u00a0\u00a0\u00a0 = array('MantisCore'\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 =&gt; '1.2.0',);\r\n     $this-&gt;;author\u00a0\u00a0\u00a0\u00a0\u00a0 = 'Hennes Herv\u00e9';\r\n     $this-&gt;;url\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 = 'https:\/\/www.h-hennes.fr';\r\n }\r\n\r\n function init() {\r\n    plugin_event_hook( 'EVENT_MENU_SUMMARY', 'agendamenu' );\r\n }\r\n\r\n function agendamenu() {\r\n   return array('&lt;a href=\"' . plugin_page('Agenda_page.php') . '\"&gt;' .lang_get('see_agenda') . '&lt;\/a&gt;');\r\n }\r\n}\r\n?&gt;<\/pre>\n<p><span style=\"text-decoration: underline;\">Le fichier est compos\u00e9 de 3 fonctions\u00a0:<\/span><\/p>\n<p><strong>Register() :<\/strong> enregistrement des informations du plugin, pas de consignes particuli\u00e8res<\/p>\n<p><strong>Init()\u00a0:<\/strong><br \/>\nInitialisation du plugin, c\u2019est ici qu\u2019on va rattacher le plugin au hook souhait\u00e9 et d\u00e9finir la fonction qui doit \u00eatre effectu\u00e9e pour son initialisation \u00e0 savoir \u00ab\u00a0<em>Agendamenu<\/em> \u00bb<br \/>\nDans notre cas je souhaite que le plugin soit visible sur la page de synth\u00e8se de mantis \u00ab\u00a0summary_page.php\u00a0\u00bb.<br \/>\nCependant si vous souhaitez l\u2019afficher sur une autre page, la liste compl\u00e8te des event menu est disponible sur la page\u00a0: <a href=\"http:\/\/www.mantisforge.org\/dev\/manual\/master\/en\/developers.html#DEV.EVENTREF.OUTPUT.MENU\">http:\/\/www.mantisforge.org\/dev\/manual\/master\/en\/developers.html#DEV.EVENTREF.OUTPUT.MENU<\/a><\/p>\n<p><strong>AgendaMenu\u00a0:<\/strong><br \/>\nFonction effectu\u00e9e \u00e0 l\u2019initialisation du plugin.Dans notre cas, cette fonction renvoie uniquement un lien \u00e0 rajouter dans le menu.<\/p>\n<p>Pour pouvoir l\u2019afficher correctement et avec la gestion de la langue, il est n\u00e9cessaire d\u2019ajouter le contenu suivant dans le fichier lang\/strings_french.txt<\/p>\n<pre>&lt;?php\r\n\r\n$s_see_agenda = \"Voir agenda\";<\/pre>\n<p><strong>Cr\u00e9ation des pages du module :<\/strong><\/p>\n<p>Pla\u00e7ons nous maintenant dans le dossier \u00ab\u00a0pages\u00a0\u00bb, nous allons commencer par \u00e9diter le contenu de la page \u00ab\u00a0Agenda_page.php\u00a0\u00bb<\/p>\n<p>Voici le contenu de cette page<\/p>\n<pre lang=\"php\">&lt;?php\r\n\/*\r\nPlugin Agenda pour Mantis BugTracker :\r\n- Page d'affichage du calendrier\r\nVersion 0.\r\n\u00a9 Hennes Herv\u00e9 - 2011\r\n*\/\r\n\r\nhtml_page_top1( lang_get( 'see_agenda' ) );\r\nhtml_page_top2();\r\nprint_summary_menu( 'summary_page.php' );\r\nprint_summary_submenu();\r\n?&gt;\r\n\r\n&lt;link rel='stylesheet' type='text\/css' href='plugins\/Agenda\/css\/fullcalendar.css' \/&gt;\r\n&lt;link rel='stylesheet' type='text\/css' href='plugins\/Agenda\/css\/Agenda.css' \/&gt;\r\n&lt;link rel='stylesheet' type='text\/css' href='plugins\/Agenda\/css\/fullcalendar.print.css' media='print' \/&gt;\r\n&lt;script type='text\/javascript' src='plugins\/Agenda\/javascript\/jquery-1.5.2.min.js'&gt;&lt;\/script&gt;\r\n&lt;script type='text\/javascript' src='plugins\/Agenda\/javascript\/jquery-ui-1.8.11.custom.min.js'&gt;&lt;\/script&gt;\r\n&lt;script type='text\/javascript' src='plugins\/Agenda\/javascript\/fullcalendar.min.js'&gt;&lt;\/script&gt;\r\n&lt;script type='text\/javascript' src='plugins\/Agenda\/javascript\/fullcalendar_init.js'&gt;&lt;\/script&gt;\r\n\r\n&lt;div id='loading' style='display:none'&gt;loading...&lt;\/div&gt;\r\n&lt;div id=\"event_details\"&gt;\r\n &lt;p&gt;&lt;a id=\"event_details_close\" href=\"#event_details\" name=\"event_details\"&gt;Fermer le d\u00e9tail &lt;\/a&gt;&lt;\/p&gt;\r\n &lt;div id=\"event_details_content\"&gt;&lt;\/div&gt;\r\n&lt;\/div&gt;\r\n\r\n&lt;div id='calendar'&gt;&lt;\/div&gt;\r\n\r\n&lt;??php\r\nhtml_page_bottom1( __FILE__ );<\/pre>\n<p>Rien de tr\u00e8s compliqu\u00e9 dans cette page, on inclut tout d\u2019abord l\u2019ensemble des css et des javascript n\u00e9cessaires au bon fonctionnement de l\u2019application.<br \/>\nLe calendrier apparaitra automatiquement dans la div \u00ab\u00a0calendar\u00a0\u00bb et j\u2019ai cr\u00e9\u00e9 une div \u00ab\u00a0event_details\u00a0\u00bb qui affichera via jquery le contenu des d\u00e9tails des \u00e9v\u00e9nements.<\/p>\n<p><strong>R\u00e9cup\u00e9ration des \u00e9v\u00e8nements du calendrier\u00a0: json-events.php<\/strong><\/p>\n<pre lang=\"php\">&lt;?php \r\n\/* Connexion \u00e0 la BDD et r\u00e9cup\u00e9ration des bugs avec leurs horraires *\/ \r\ninclude('..\/..\/..\/config_inc.php');\r\n try {  $db = new PDO('mysql:host='.$g_hostname.';dbname='.$g_database_name,$g_db_username,$g_db_password); } \r\ncatch (Exception $e) {  die($e-&gt;getMessage()); } \r\n\/\/Recherche des informations sur les bugs\r\n $query = $db-&gt;query('SELECT mbt.time_tracking, mbt.date_submitted, mbtt.note, mbug.description,mbg.summary title, mbg.id bug_id, mbt.id, mpt.name, mut.realname\r\n                     FROM mantis_bug_table mbg\r\n                     LEFT JOIN mantis_project_table mpt ON ( mpt.id = mbg.project_id)\r\n                     LEFT JOIN\u00a0 mantis_bugnote_table mbt ON (mbt.bug_id = mbg.id)\r\n                     LEFT JOIN mantis_bugnote_text_table mbtt ON (mbtt.id = mbt.bugnote_text_id)\r\n                     LEFT JOIN mantis_user_table mut ON (mbt.reporter_id = mut.id)\r\n                     LEFT JOIN mantis_bug_text_table mbug ON (mbug.id = mbt.bug_id)\r\n                   ');\r\n\r\nwhile ( $result = $query-&gt;fetch() ) {\r\n\r\n if ( $result['id'] != NULL ) {\r\n  $date_deb = date('Y-m-d H:i:s',$result['date_submitted']);\r\n  $temps_deb = date('d-m-Y \u00e0 H:i:s',$result['date_submitted']);\r\n\r\n  if ( $result['time_tracking'] != 0 ){\r\n   $date_fin = date('Y-m-d H:i:s',mktime(substr($date_deb,11,2),($result['time_tracking']+substr($date_deb,14,2)),0,substr($date_deb,5,2),substr($date_deb,8,2),substr($date_deb,0,4)));\r\n   $temps_fin = date('d-m-Y \u00e0 H:i:s',mktime(substr($date_deb,11,2),(substr($date_deb,14,2)-$result['time_tracking']),0,substr($date_deb,5,2),substr($date_deb,8,2),substr($date_deb,0,4)));\r\n  }\r\n\r\n  $results[] = array(\r\n                'id' =&gt; $result['id'],\r\n                'title' =&gt;; utf8_encode($result['name']).' : '.utf8_encode($result['title']),\r\n                'start' =&gt; $date_deb,\r\n                'end' =&gt; $date_fin,\r\n                'temps_deb' =&gt; $temps_deb,\r\n                'temps_fin' =&gt; $temps_fin,\r\n                'auteur' =&gt;; utf8_encode($result['realname']),\r\n                'note' =&gt; utf8_encode($result['note']),\r\n                'description' =&gt; utf8_encode($result['description']),\r\n                'time_tracking' =&gt; $result['time_tracking'],\r\n                'allDay' =&gt; false\r\n             );\r\n\r\n }\r\n\r\n}\r\n\r\n\/\/Affichage des donn\u00e9es en Ajax\r\necho json_encode($results);\r\n?&gt;<\/pre>\n<p>Ce script peut \u00eatre s\u00e9par\u00e9 en 3 parties\u00a0:<\/p>\n<ul>\n<li>Connexion \u00e0 la base de donn\u00e9es<\/li>\n<li>R\u00e9cup\u00e9ration et traitement des infos<\/li>\n<li>Affichage des informations<\/li>\n<\/ul>\n<p>Si vous souhaitez ajouter des informations compl\u00e9mentaires, il est ais\u00e9 de rajouter des crit\u00e8res \u00e0 la requ\u00eate initiale.<\/p>\n<p><strong>Initialisation javascript du plugin<\/strong><\/p>\n<p>Pour terminer ce plugin il est \u00e0 pr\u00e9sent n\u00e9cessaire d\u2019initialiser le plugin\u00a0\u00ab\u00a0fullcalendar\u00a0\u00bb \u00e0 l\u2019aide du fichier \u00ab\u00a0js\/fullcalendar_init.js\u00a0\u00bb<\/p>\n<p>Voici le contenu de ce fichier\u00a0:<\/p>\n<pre lang=\"javascript\">$(document).ready(function() {\r\n $('#calendar').fullCalendar({\r\n\r\n editable: true,\r\n\r\n \/\/En t\u00eate\r\n header: {\r\n       left: 'prev,next today',\r\n       center: 'title',\r\n       right: 'month,agendaWeek,agendaDay'\r\n },\r\n \/\/Format des colonnes\r\n columnFormat: {\r\n month: 'ddd',\r\n week: 'ddd d\/M',\r\n day: 'dddd d\/M'\r\n },\r\n\/\/Premier jour de la semaine : Lundi\r\nfirstDay: 1,\r\n\/\/Pas besoin d'afficher les weeks ends\r\nweekends : false,\r\n\/\/Affichage diff\u00e9rent selon les mois\r\nweekMode: 'variable',\r\n\/\/Configuration des variables Jours et mois en FR\r\n monthNames: ['Janvier','F\u00e9vrier','Mars','Avril','Mai','Juin','Juillet','Aout','Septembre','Octobre','Novembre','Decembre'],\r\nmonthNamesShort: ['Jan','Fev','Mar','Avr','Mai','Jun','Jul','Aou','Sep','Oct','Nov','Dec'],\r\ndayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'],\r\ndayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'],\r\nbuttonText: {\r\n          prev: '&amp;nbsp;&amp;#9668;&amp;nbsp;',\r\n          next: '&amp;nbsp;&amp;#9658;&amp;nbsp;',\r\n          prevYear: '&amp;nbsp;&amp;lt;&amp;lt;&amp;nbsp;',\r\n          nextYear: '&amp;nbsp;&amp;gt;&amp;gt;&amp;nbsp;',\r\n          today: 'Aujourd\\'hui',\r\n          month: 'Mois',\r\n          week: 'Semaine',\r\n          day: 'Jour'\r\n},\r\nevents: \"plugins\/Agenda\/pages\/json-events.php\",\r\n\r\n\/\r\nAffichage des informations au click :\r\n- On mets une div avec le d\u00e9tails\r\n*\/\r\n eventClick: function(calEvent, jsEvent, view) {\r\n\r\n  \/\/On affiche le block d'infos\r\n  $('#event_details').css('display','block');\r\n\r\n  \/\/Contenu html du block\r\n  var content = '&lt;h2&gt;'+calEvent.title+'&lt;\/h2&gt;&lt;p&gt;D\u00e9but action:'+calEvent.temps_deb+'&lt;br \/&gt;Dur\u00e9e : '+calEvent.time_tracking+' min&lt;br \/&gt;'\r\n  +'Fin de l\\'action : '+calEvent.temps_fin+'&lt;\/p&gt;'\r\n  +'&lt;b&gt;D\u00e9tails de la note :&lt;\/b&gt;'+calEvent.note+'&lt;br \/&gt;'\r\n  +'Auteur : '+calEvent.auteur+'&lt;br \/&gt;'\r\n  +'&lt;a href=\"#\" id=\"event_details_description_bug_show\"&gt;Voir le descriptif du bug &lt;\/a&gt;&lt;br \/&gt;&lt;div id=\"event_details_description_bug\"&gt;'+calEvent.description+'&lt;\/div&gt;';\r\n\r\n  $('#event_details_content').html('').html(content);\r\n },\r\n\r\n \/*\r\n Au survol on change l'apparence du bloc pour pouvoir tout consulter en mode semaine ou Jour\r\n On stocke les hauteurs et largeurs initiales dans les propri\u00e9t\u00e9s min-width et min-height pour pouvoir les r\u00e9utiliser avec l'event MouseOut\r\n *\/\r\n eventMouseover: function( event, jsEvent, view ) {\r\n  if ( view.name == 'agendaWeek' || view.name == 'agendaDay' ) {\r\n   $(this).css({\r\n               'min-width':$(this).css('width'),\r\n               'width':'auto',\r\n               'min-height': $(this).css('height'),\r\n               'height':'auto',\r\n               'z-index':40\r\n   });\r\n  }\r\n },\r\n\r\n \/*\r\n A la fin du survol on r\u00e9duit de nouveau l'affichage\r\n *\/\r\n eventMouseout: function( event, jsEvent, view ) {\r\n if ( view.name == 'agendaWeek' || view.name == 'agendaDay' ) {\r\n  $(this).css({\r\n              'width':$(this).css('min-width'),\r\n              'height':$(this).css('min-height'),\r\n              'z-index':10\r\n   });\r\n }\r\n\r\n },\r\nloading: function(bool) {\r\nif (bool) $('#loading').show();\r\nelse $('#loading').hide();\r\n}\r\n});\r\n\r\n\/\/ Bouton pour fermer le d\u00e9tails\r\n$('#event_details_close').live('click',function(){\r\n $('#event_details').css('display','none');\r\n});\r\n\r\n\/\/Bouton pour afficher le d\u00e9tail du bug\r\n$('#event_details_description_bug_show').live('click',function() {\r\n $('#event_details_description_bug').toggle('slow');\r\n});\r\n});<\/pre>\n<p>Nous arrivons \u00e0 pr\u00e9sent \u00e0 la fin de la cr\u00e9ation de ce plugin.<br \/>\nPour l&rsquo;installer, il faut encore l&rsquo;uploader dans le dossier \u00ab\u00a0Plugins\u00a0\u00bb de mantis, et proc\u00e9der \u00e0 son activation \ud83d\ude42<\/p>\n<p>Si vous souhaitez vous pouvez t\u00e9l\u00e9charger directement l&rsquo;archive ici : <a title=\"Plugin Mantis Agenda\" href=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2011\/08\/PluginMantisAgenda.rar\" target=\"_blank\">PluginMantisAgenda<\/a><\/p>\n<p><strong>Edit 29\/04\/2013 :<\/strong> Une nouvelle version du <a title=\"Cr\u00e9ation d\u2019un plugin de suivi de temps pour Mantis Bugtracker : nouvelle version\" href=\"https:\/\/www.h-hennes.fr\/blog\/2013\/04\/29\/creation-dun-plugin-de-suivi-de-temps-pour-mantis-bugtracker-nouvelle-version\/\">plugin de suivi de temps pour mantis bugtracker <\/a>est disponible.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mantis BugTracker\u00a0: Cr\u00e9ation d\u2019un plugin \u00ab\u00a0Suivi du temps\u00a0\u00bb Edit 29\/04\/2013 :\u00a0 Derni\u00e8re informations sur le plugin :\u00a0https:\/\/www.h-hennes.fr\/blog\/plugin-suivi-de-temps-pour-mantis-bugtracker\/ J\u2019utilise au quotidien la plateforme Mantis Bugtracker pour g\u00e9rer mes t\u00e2ches en cours, et suivre le temps que je passe sur les diff\u00e9rents projets. A ce titre j\u2019ai customis\u00e9 l\u2019installation de base avec l\u2019ajout de nouvelles fonctionnalit\u00e9s \u00a0tels [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[247,6],"tags":[152,83,154,155,82,153],"class_list":["post-194","post","type-post","status-publish","format-standard","hentry","category-mantis-bugtracker","category-trucs-et-astuces","tag-agenda","tag-bugtracker","tag-calendrier","tag-fullcalendar","tag-mantis","tag-plugin"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts\/194","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/comments?post=194"}],"version-history":[{"count":12,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts\/194\/revisions"}],"predecessor-version":[{"id":1245,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts\/194\/revisions\/1245"}],"wp:attachment":[{"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/media?parent=194"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/categories?post=194"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/tags?post=194"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}