Nous allons voir en détails comment réaliser un module dashboard sur prestashop ( Ce tuto a été testé sur les dernières versions à date de PS 1.6 et PS 1.7)

La documentation officielle présente de nombreuses informations mais elle n’est pas super détaillée sur les différents type de données possibles nativement, ni sur comment traiter les graphiques.

C’est parti pour voir en détails comment les modules dashboard fonctionnent :
Le nom du module sera hh_dashmodule

Pour commencer notre module sera greffé sur les hooks suivants :

dashboardZoneTwo ( Bloc central du dashboard ) OU dashboardZoneOne ( Colonne de gauche du dashboard )
dashboardData ( Récupérations des données du dashboard)
actionAdminControllerSetMedia ( Pour ajouter le js spécifique du module.)

Le code est volontairement simplifié pour comprendre l’essentiel.

Je passe rapidement sur les hooks
actionAdminControllerSetMedia dont le code sera le suivant :

    /**
     * Ajout du js spécifique du module dans le dashboard
     */
    public function hookActionAdminControllerSetMedia()
    {
        if (get_class($this->context->controller) == 'AdminDashboardController') {
            $this->context->controller->addJs($this->_path.'views/js/'.$this->name.'.js');
        }
    }

ansi que sur le hook hookDashboardZoneTwo qui affiche uniquement un template smarty.

     /**
     * Hook Dasboard Principale
     * @return type
     */
    public function hookDashboardZoneTwo()
    {
        return $this->display(__FILE__, 'views/templates/hook/hookDashboardZoneTwo.tpl');
    }

La particularité des modules de type dashboard et que les données sont mises à jour via des scripts ajax, qui appellent le hook DashboardData des modules.

C’est donc dans cette fonction qu’il va falloir renvoyer les informations à afficher.

    /**
     * Hook de récupération des données
     * @param type $params
     */
    public function hookDashboardData($params)
    {
        /**
         * Paramètres envoyés par leur dashboard pour actualiser les stats
         */
        $from = $params['date_from'];
        $to = $params['date_to'];
 
        //Exemple de requête qui utilise les pramètres
        $customers = Db::getInstance()->executeS("SELECT DATE(date_add) AS date, COUNT(*) AS nbre "
                . "FROM " . _DB_PREFIX_ . "customer "
                . "WHERE DATE(date_add) >= '" . pSQL($from) . "' AND DATE(date_add) <= '" . pSQL($to) . "' " . "GROUP BY DATE(date_add)"); //Renvoi de tous les types de données possibles return [ 'data_value' =>
            [
                'current_time' => time(),
                'customers' => $customers,
                'sample_data' => '<strong>Test de données fixe</strong>',
            ],
            'data_table' => $this->_getSampleDataTable(),
            'data_trends' => $this->_getSampleDataTrends(),
            'data_list_small' => $this->_getSampleDataListSmall(),
            'data_chart' => $this->_getSampleDataChart(),
        ];
    }

Les plages de dates sélectionnées via le tableau de bord sont disponibles lors de l’appel comme vous pouvez le voir dans le code, et ce sont ces paramètres qui vont nous permettre de renvoyer les données adéquates

Les types de données natifs sont les suivants :

  • data_value
  • data_table
  • data_trends
  • data_list_small
  • data_chart

Nous allons voir type par type comment gérer leur affichage, qui nécessitera à la fois du code dans le fichier tpl « views/templates/hook/hookDashboardZoneTwo.tpl » et dans le fichier php

– Type data_value

Le type data_value est le plus simple, il suffit de renvoyer une valeur ( int / string ) dans le tableau
‘data_value’ du hook comme dans l’exemple ci-dessous.

return [
            'data_value' =>
            [
                'current_time' => time(),
                'sample_data' => '<strong>Test de données fixe</strong>',
            ],
];

Dans le tpl il est nécessaire de mettre le code suivant :

<div class="data_value">
{* Information remplie automatiquement par le script l'id correspond à la clé du tableau renvoyé dans data-value *}
<span id="current_time"></span>
<span id="sample_data"></span>
</div>

Le rendu sera le suivant :

Prestashop dashoard value

– Type data_table

Pour le type data_table il est nécessaire de renvoyer un tableau formaté sous la forme suivante :

return [
            'table_hh_sample_table' => [
                //Header de la table
                'header' => [
                    //Champ(s) wrapper(s) optionnel(s)
                    ['title' => 'sample_column_1','class' => 'text-left' , 'wrapper_start' => '<strong>','wrapper_stop' => '</strong>'],
                    ['title' => 'sample_column_2','class' => 'text-left'],
                    ['title' => 'sample_column_2','class' => 'text-left'],
                ],
                //Corps de la table
                'body' => [
                   [
                       //Champ wrapper optionnel
                       ['id' => 'sample_column_1','value' => 'test value', 'class' => 'text-left'],
                       ['id' => 'sample_column_2','value' => 'test value column2', 'class' => 'text-left','wrapper_start' => '<strong>','wrapper_stop' => '</strong>'],
                       ['id' => 'sample_column_3','value' => 'test value column3', 'class' => 'text-left'],
                   ],
                   [
                       ['id' => 'sample_column_1','value' => 'test value row 2', 'class' => 'text-left'],
                       ['id' => 'sample_column_2','value' => 'test value row 2 column2', 'class' => 'text-left'],
                       ['id' => 'sample_column_3','value' => 'test value row 2 column3', 'class' => 'text-left'],
                   ],
                   [
                       ['id' => 'sample_column_1','value' => 'test value row 3', 'class' => 'text-left'],
                       ['id' => 'sample_column_2','value' => 'test value row 3 column2', 'class' => 'text-left'],
                       ['id' => 'sample_column_3','value' => 'test value row 3 column3', 'class' => 'text-left'],
                   ]
                ]
            ],
        ];

Dans le tpl il est nécessaire de mettre le code suivant :

<table class="table data_table" id="table_hh_sample_table">
<thead></thead>
<tbody></tbody>
</table>

Le rendu sera le suivant :

Prestashop dashoard table

– Type data_trends

Pour le type data_trends il est nécessaire de renvoyer un tableau formatté sous la forme suivante :

 return [
            'dash_trend_sample_1' => [
                'way' => 'up',
                'value' => 3,
            ],
            'dash_trend_sample_2' => [
                'way' => 'down',
                'value' => 3,
            ]
        ];

 

Dans le tpl il est nécessaire de mettre le code suivant :

{l s='trend up' mod='hh_dashmodule'}<dd class="dash_trend"><span id="dash_trend_sample_1"></span></dd>
{l s='trend down' mod='hh_dashmodule'}<dd class="dash_trend"><span id="dash_trend_sample_2"></span></dd>

Le rendu sera le suivant :

Prestashop dashoard trends

– Type data_list_small

Pour le type data_list_small il est nécessaire de renvoyer un tableau formaté sous la forme suivante :

return [
            'dash_list_small_sample' => [
                   'key1 : ' => ' value1',
                   'key2 : ' => ' value2',
                   'key3 : ' => [ 'value1', 'value2'],
            ],
        ];

Dans le tpl il est nécessaire de mettre le code suivant :

<div class="dash_list_small">
<ul id="dash_list_small_sample1">
</ul>
</div>

Le rendu sera le suivant :

Prestashop dashoard list

– Type data_chart

Le type chart est lui plus complexe et nécessite l’ajout d’un fichier javascript spécifique au module.
Les graphiques sont générés via la librairie javascript nv3d http://nvd3.org/examples/index.html

Il est donc possible de générer l’ensemble des types de graphiques présentés par la librairie, le format de données attendu étant spécifique à chaque type de graphique, voici le principe général et comment faire à travers 2 exemples de type « line » et « bar ».
Pour tous les autres types, je vous invites à voir directement sur le site de la libairie nv3d.

Les données exportées via le php seront les suivantes :

return [
            //Graphique de type ligne
            'data_chart_sample_1' => [
                'chart_type' => 'sample_chart_line_model', //Nom de la fonction d'initialisation dans le fichier hh_dashmodule.js
                'chart_xaxis_label' => 'X axis Label',
                'chart_yaxis_label' => 'Y axis Label',
                'data' => [
                    [
                        'color' => '#7777ff',
                        'area' => true,
                        'values' => [
                            ['x' => '1', 'y' => 10],
                            ['x' => '2', 'y' => 20],
                            ['x' => '3', 'y' => 30],
                            ['x' => '4', 'y' => 60],
                        ]
                    ],
                ]
            ],
            'data_chart_sample_2' => [
                'chart_type' => 'sample_chart_bar_model', //Nom de la fonction d'initialisation dans le fichier hh_dashmodule.js
                'chart_xaxis_label' => 'X axis Label',
                'chart_yaxis_label' => 'Y axis Label',
                'data' => [
                    [
                        'values' => [
                            ['label' => '2017-09-20', 'value' => 10],
                            ['label' => '2017-09-21', 'value' => 20],
                            ['label' => '2017-09-22', 'value' => 15],
                            ['label' => '2017-09-23', 'value' => 7],
                            ['label' => '2017-09-24', 'value' => 35],
                        ]
                    ],
                ]
            ],
        ];

Dans le tpl il est nécessaire de mettre le code suivant :

  <div id="data_chart_sample_1" class="chart with-transitions">
 <svg></svg>
 </div>
 
 <p>{l s='Bar Chart' mod='hh_dashmodule'}</p>
 <div id="data_chart_sample_2" class="chart with-transitions">
 <svg></svg>
 </div>

En supplément il faut également rajouter le contenu suivant dans le fichier views/js/hh_dashmodule.js
Le point essentiel à retenir étant que les données de notre tableau sont envoyées dans la variable chart_details

/**
 * La librairie utilisée est nvd3 : pour plus d'informations => http://nvd3.org/examples/index.html
 *  documentation : https://nvd3-community.github.io/nvd3/examples/documentation.html
 */
 
/**
 * Modèle d'exemple de graphique en ligne
 * @param string widget_name
 * @param array chart_details
 * @returns chart
 */
function sample_chart_line_model(widget_name, chart_details) {
 
    nv.addGraph(function () {
        var chart = nv.models.lineChart()
                .margin({left: 100})  //Adjust chart margins to give the x-axis some breathing room.
                .useInteractiveGuideline(true)  //We want nice looking tooltips and a guideline!
                .transitionDuration(350)  //how fast do you want the lines to transition?
                .showLegend(true)       //Show the legend, allowing users to turn on/off line series.
                .showYAxis(true)        //Show the y-axis
                .showXAxis(true)        //Show the x-axis
                ;
 
        //Chart x-axis settings        
        chart.xAxis
                .axisLabel(chart_details.chart_xaxis_label)
                .tickFormat(d3.format('d'));
 
        //Chart y-axis settings        
        chart.yAxis
                .axisLabel(chart_details.chart_yaxis_label)
                .tickFormat(d3.format('d'));
 
        d3.select('#data_chart_sample_1 svg')    //Select the  element you want to render the chart in.   
                .datum(chart_details.data)         //Populate the  element with chart data...
                .call(chart);          //Finally, render the chart!
 
        //Update the chart when window resizes.
        nv.utils.windowResize(function () {
            chart.update()
        });
        return chart;
    });
}
/**
 * Modèle d'exemple de graphique en barre
 * @param string widget_name
 * @param array chart_details
 * @returns chart
 */
function sample_chart_bar_model(widget_name, chart_details) {
 
    nv.addGraph(function () {
        var chart = nv.models.discreteBarChart()
                .x(function (d) {
                    return d.label
                })    //Specify the data accessors.
                .y(function (d) {
                    return parseInt(d.value)
                })
                .staggerLabels(true)    //Too many bars and not enough room? Try staggering labels.
                .tooltips(false)        //Don't show tooltips
                .showValues(true)       //...instead, show the bar value right on top of each bar.
                .transitionDuration(350)
                .valueFormat(d3.format('d'))
                ;
 
        //Chart x-axis settings        
        chart.xAxis.axisLabel(chart_details.chart_xaxis_label);
 
        //Chart y-axis settings        
        chart.yAxis
                .axisLabel(chart_details.chart_yaxis_label)
                .tickFormat(d3.format('d'));
 
        d3.select('#data_chart_sample_2 svg')
                .datum(chart_details.data)
                .call(chart);
 
        nv.utils.windowResize(chart.update);
 
        return chart;
    });
}

Le rendu sera le suivant :

Prestashop dashoard chart

 

Et voila nous avons fait le tour du fonctionnement des modules de type dashboard sous Prestashop.
N’hésitez pas à remonter vos questions 😉

 

Vous pouvez récupérer le module complet d’exemple ici