From 8752cf3405de3c3bee484c69d8922b3c1db4698d Mon Sep 17 00:00:00 2001 From: pbarroca <pbarroca@afi-sa.fr> Date: Fri, 17 Jan 2014 18:36:37 +0100 Subject: [PATCH] =?UTF-8?q?fix=20#11822=20:=20Stats=20visu=20notices=20par?= =?UTF-8?q?=20mois=20d=C3=A9sormais=20dans=20des=20sections=20par=20an?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controllers/StatController.php | 90 +++++++------------ .../scripts/stat/reservationnotice.phtml | 40 +++------ .../admin/views/scripts/stat/visunotice.phtml | 57 ++++++------ library/Class/StatsNotices.php | 44 +++------ .../ZendAfi/View/Helper/Admin/BlocStats.php | 75 ++++++++++++++++ .../admin/controllers/StatControllerTest.php | 72 +++++++++++++++ 6 files changed, 230 insertions(+), 148 deletions(-) create mode 100644 library/ZendAfi/View/Helper/Admin/BlocStats.php diff --git a/application/modules/admin/controllers/StatController.php b/application/modules/admin/controllers/StatController.php index e23e2c59e0d..91459510d06 100644 --- a/application/modules/admin/controllers/StatController.php +++ b/application/modules/admin/controllers/StatController.php @@ -18,82 +18,58 @@ * along with AFI-OPAC 2.0; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -//----------------------------------------------------------------------- -// OPAC3 - Statistiques notices -//----------------------------------------------------------------------- -class Admin_StatController extends Zend_Controller_Action -{ - private $cls_stat; // Instance classe stat - function indexAction() - { - $this->_redirect('admin/index'); - } +class Admin_StatController extends Zend_Controller_Action { + private $cls_stat; // Instance classe stat -//----------------------------------------------------------------------- -// Initialisation -//----------------------------------------------------------------------- - function init() - { - $this->cls_stat=new Class_StatsNotices(); + public function init() { + $this->cls_stat = new Class_StatsNotices(); $css = '<link rel="stylesheet" type="text/css" media="screen" href="'.URL_ADMIN_CSS.'statistique.css" />'; $this->getResponse()->setBody($css); } -//----------------------------------------------------------------------- -// Visualisations de notices -//----------------------------------------------------------------------- - function visunoticeAction() - { + + public function preDispatch() { + $this->view->periode = $this->cls_stat->getPeriode(); + } + + + public function indexAction() { + $this->_redirect('admin/index'); + } + + + public function visunoticeAction() { $this->view->titre = 'Statistiques de visualisation des notices'; - $this->view->periode=$this->cls_stat->getPeriode(0,0); - $this->view->table_stat=$this->cls_stat->getRecapVisu(); + $this->view->table_stat = $this->cls_stat->getRecapVisu(); } -//----------------------------------------------------------------------- -// Palmares Visualisations de notices -//----------------------------------------------------------------------- - function palmaresvisunoticeAction() - { + + public function palmaresvisunoticeAction() { $this->view->titre = 'Palmarès des visualisations de notices'; - $this->view->periode = $this->cls_stat->getPeriode(0,0); - $this->view->table_stat = $this->cls_stat->getPalmaresVisu($_REQUEST["type_doc"]); + $this->view->table_stat = $this->cls_stat->getPalmaresVisu($this->_getParam('type_doc')); } -//----------------------------------------------------------------------- -// Recherches infructueuses -//----------------------------------------------------------------------- - function rechercheinfructueuseAction() - { + + public function rechercheinfructueuseAction() { $this->view->titre = 'Recherches infructueuses'; + $page = $this->_getParam('page', 1); $this->view->nb_par_page = 20; - $page = $this->_getParam('page'); - if(!$page) $page=1; - $this->view->page=$page; - $limit=($page-1) * $this->view->nb_par_page; - $limit=" limit ".$limit.",".$this->view->nb_par_page; - $this->view->nombre_total=fetchOne("select count(*) from stats_recherche_echec"); - $req="select * from stats_recherche_echec order by id desc ".$limit; - $this->view->liste = fetchAll($req); + $start = ($page-1) * $this->view->nb_par_page; + $this->view->liste = $this->cls_stat->getNotFoundByPage($page, $this->view->nb_par_page); + $this->view->nombre_total = $this->cls_stat->getTotalNotFound(); + $this->view->page = $page; } -//----------------------------------------------------------------------- -// Réservations de notices -//----------------------------------------------------------------------- - function reservationnoticeAction() - { + + public function reservationnoticeAction() { $this->view->titre = 'Statistiques des réservations de notices'; - $this->view->periode=$this->cls_stat->getPeriode(0,0); - $this->view->table_stat=$this->cls_stat->getRecapReservation(); + $this->view->table_stat = $this->cls_stat->getRecapReservation(); } -//----------------------------------------------------------------------- -// Palmares Réservations de notices -//----------------------------------------------------------------------- - function palmaresreservationnoticeAction() - { + + public function palmaresreservationnoticeAction() { $this->view->titre = 'Palmarès des réservations de notices'; - $this->view->periode=$this->cls_stat->getPeriode(0,0); - $this->view->table_stat=$this->cls_stat->getPalmaresReservation($_REQUEST["type_doc"]); + $this->view->table_stat = $this->cls_stat->getPalmaresReservation($this->_getParam('type_doc')); } } \ No newline at end of file diff --git a/application/modules/admin/views/scripts/stat/reservationnotice.phtml b/application/modules/admin/views/scripts/stat/reservationnotice.phtml index ecc0ea3d1e6..b635c301e7e 100644 --- a/application/modules/admin/views/scripts/stat/reservationnotice.phtml +++ b/application/modules/admin/views/scripts/stat/reservationnotice.phtml @@ -1,33 +1,15 @@ +<h2 class="stat"><?php echo $this->periode;?>, +<?php echo number_format($this->table_stat["total"], 0, ',', ' ');?> +demandes de réservation ont été effectuées</h2> + +<h3 class="stat">Détail par années</h3> <?php -print('<h2 class="stat">'.$this->periode.", ".number_format($this->table_stat["total"], 0, ',', ' ').' demandes de réservation ont été effectuées</h2>'); -print('<h3 class="stat">Détail par années</h3>'); -printBlocStat("Année",$this->table_stat["annees"],$this->table_stat["graphes"]["annees"]); -print('<h3 class="stat">Détail par mois</h3>'); -printBlocStat("Mois",$this->table_stat["mois"],$this->table_stat["graphes"]["mois"]); + if (isset($this->table_stat['annees'])) + echo $this->blocStats('Année', $this->table_stat['annees']);?> -// Bloc stat : tableau et graphe -function printBlocStat($titre,$table,$graphe) -{ - // container principal - print('<table><tr><td valign="top">'); - // Tableau - print('<table class="stat" style="width:180px;margin-left:10px"><tr>'); - print('<th class="stat" width="70%">'.$titre.'</th>'); - print('<th class="stat" width="30%">Nombre</th>'); - print('</tr>'); - foreach($table as $libelle => $nombre) - { - print('<tr>'); - print('<td class="stat_libelle">'.$libelle.'</td>'); - print('<td class="stat_nombre">'.$nombre.'</td>'); - print('</tr>'); - } - print('</table></td>'); - // Graphe - print('<td>'.$graphe.'</td>'); - // Fini - print('</tr></table>'); -} -?> +<h3 class="stat">Détail par mois</h3> +<?php + if (isset($this->table_stat['mois'])) + echo $this->blocStats('Mois', $this->table_stat['mois']);?> <br> diff --git a/application/modules/admin/views/scripts/stat/visunotice.phtml b/application/modules/admin/views/scripts/stat/visunotice.phtml index 78ef09b53ce..e9fdf4e3361 100644 --- a/application/modules/admin/views/scripts/stat/visunotice.phtml +++ b/application/modules/admin/views/scripts/stat/visunotice.phtml @@ -1,35 +1,28 @@ -<?php -print('<h2 class="stat">'.$this->periode.", ".number_format($this->table_stat["total"], 0, ',', ' ').' notices ont été visualisées</h2>'); -print('<h3 class="stat">Détail par années</h3>'); -printBlocStat("Année",$this->table_stat["annees"],$this->table_stat["graphes"]["annees"]); -print('<h3 class="stat">Détail par mois</h3>'); -printBlocStat("Mois",$this->table_stat["mois"],$this->table_stat["graphes"]["mois"]); +<h2 class="stat"> +<?php echo $this->periode;?>, +<?php echo number_format($this->table_stat["total"], 0, ',', ' ');?> notices ont été visualisées +</h2> + +<script> + $(function(){$('#accordion').accordion({autoHeight:false, collapsible:true});}); +</script> -// Bloc stat : tableau et graphe -function printBlocStat($titre,$table,$graphe) -{ - if (!$table) - return; - // container principal - print('<table><tr><td valign="top">'); - // Tableau - print('<table class="stat" style="width:180px;margin-left:10px"><tr>'); - print('<th class="stat" width="70%">'.$titre.'</th>'); - print('<th class="stat" width="30%">Nombre</th>'); - print('</tr>'); - foreach($table as $libelle => $nombre) - { - print('<tr>'); - print('<td class="stat_libelle">'.$libelle.'</td>'); - print('<td class="stat_nombre">'.$nombre.'</td>'); - print('</tr>'); - } - print('</table></td>'); - // Graphe - print('<td>'.$graphe.'</td>'); - // Fini - print('</tr></table>'); -} -?> +<?php if (isset($this->table_stat)) { ?> +<h3 class="stat">Détail par années</h3> +<?php +$years = []; +foreach ($this->table_stat as $label => $datas) + if (isset($datas['total'])) + $years[$label] = $datas['total']; +echo $this->blocStats('Année', $years);?> +<h3 class="stat">Détail par mois</h3> +<div id="accordion"> +<?php foreach ($this->table_stat as $label => $datas) { +if (!isset($datas['mois'])) continue;?> +<h4><?php echo $label;?></h4> +<?php echo $this->blocStats('Mois', $datas['mois']);?> +<?php } ?> +</div> +<?php } ?> <br> diff --git a/library/Class/StatsNotices.php b/library/Class/StatsNotices.php index 88f9d747b7d..629b241eff9 100644 --- a/library/Class/StatsNotices.php +++ b/library/Class/StatsNotices.php @@ -64,7 +64,7 @@ class Class_StatsNotices { $msg = 'en ' . $msg; } else { if ($annee = fetchOne('select min(annee) from stats_notices')) - $mois = fetchOne("select min(mois) from stats_notices where annee=$annee"); + $mois = fetchOne('select min(mois) from stats_notices where annee=' . $annee); $msg = 'depuis ' . $this->lib_mois[$mois] . ' ' . $annee; } return $msg; @@ -72,27 +72,24 @@ class Class_StatsNotices { public function getRecapVisu() { - // Par années - $liste = fetchAll("Select annee, sum(nb_visu) from stats_notices group by 1"); + $ret = ['total' => 0, 'annees' => [], 'mois' => [], 'graphes' => []]; + $liste = fetchAll('Select annee, sum(nb_visu) from stats_notices group by 1 order by annee desc'); $total = 0; foreach($liste as $stat) { $annee = $stat["annee"]; $nombre = $stat["sum(nb_visu)"]; $total += $nombre; - $ret["annees"][$annee]=$nombre; + $ret[$annee] = ['total' => $nombre, 'mois' => []]; } $ret["total"] = $total; - $ret["graphes"]["annees"] = $this->getGraphe($ret["annees"], $total); - // Par mois - $liste = fetchAll("Select mois, sum(nb_visu) as cnt from stats_notices group by 1"); + $liste = fetchAll("Select annee, mois, nb_visu as cnt from stats_notices order by annee desc, mois desc"); foreach ($liste as $stat) { - $mois = $this->lib_mois[$stat["mois"]]; - $nombre = $stat["cnt"]; - $ret["mois"][$mois] = $nombre; + $mois = $this->lib_mois[$stat['mois']]; + $nombre = $stat['cnt']; + $ret[$stat['annee']]['mois'][$mois] = $nombre; } - $ret["graphes"]["mois"] = $this->getGraphe($ret["mois"], $total); return $ret; } @@ -168,27 +165,14 @@ class Class_StatsNotices { } - public function getGraphe($data_graphe, $total) { - $nb_rubriques = count($data_graphe); - if (!$nb_rubriques) - return false; - - // Constituer les arguments pour google - $datas = $labels = []; - foreach($data_graphe as $label => $data) { - $datas[] = ($data and $total) ? (int)($data / $total * 100) : 0; - $labels[] = $label; - } - - $chd = implode(',', $datas); - $chl = implode('|', $labels); + public function getTotalNotFound() { + return fetchOne('select count(*) from stats_recherche_echec'); + } - $taille = ($nb_rubriques < 5) ? - 'chs=200x120&cht=bvg': - 'chs=450x200&cht=p3'; - $url_google = $this->url_google . $taille . "&chd=t:" . $chd . "&chl=" . $chl; - return '<img src="' . $url_google . '" border="0">'; + public function getNotFoundByPage($start, $count) { + return fetchAll(sprintf('select * from stats_recherche_echec order by id desc limit %s, %s', + $start, $count)); } diff --git a/library/ZendAfi/View/Helper/Admin/BlocStats.php b/library/ZendAfi/View/Helper/Admin/BlocStats.php new file mode 100644 index 00000000000..ed6d064fde7 --- /dev/null +++ b/library/ZendAfi/View/Helper/Admin/BlocStats.php @@ -0,0 +1,75 @@ +<?php +/** + * Copyright (c) 2012, Agence Française Informatique (AFI). All rights reserved. + * + * AFI-OPAC 2.0 is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * AFI-OPAC 2.0 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with AFI-OPAC 2.0; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +class ZendAfi_View_Helper_Admin_BlocStats extends ZendAfi_View_Helper_BaseHelper { + const GOOGLE_URL = 'http://chart.apis.google.com/chart?'; + + public function blocStats($title, $datas) { + if (!$datas) + return; + + $html = '<table><tr><td valign="top">' + . '<table class="stat" style="width:180px;margin-left:10px"><tr>' + . '<th class="stat" width="70%">' . $title . '</th>' + . '<th class="stat" width="30%">Nombre</th>' + . '</tr>'; + + foreach ($datas as $label => $count) + $html .= $this->_dataFor($label, $count); + + $html .= '</table></td>' + . '<td>'. $this->_graph($datas) . '</td>' + . '</tr></table>'; + + return $html; + } + + + protected function _dataFor($label, $count) { + return '<tr>' + . '<td class="stat_libelle">' . $label . '</td>' + . '<td class="stat_nombre">' . $count . '</td>' + . '</tr>'; + } + + + protected function _graph($graph_datas) { + if (empty($graph_datas)) + return false; + + $total = 0; + array_walk($graph_datas, function($item) use (&$total) {$total += $item;}); + + $datas = $labels = []; + array_walk($graph_datas, function($data, $label) use ($total, &$datas, &$labels) { + $datas[] = ($data and $total) ? (int)($data / $total * 100) : 0; + $labels[] = $label; + }); + + $chd = implode(',', $datas); + $chl = implode('|', $labels); + + $taille = (count($datas) < 5) ? + 'chs=200x120&cht=bvg': + 'chs=450x200&cht=p3'; + + return '<img src="' . self::GOOGLE_URL . $taille . "&chd=t:" . $chd . "&chl=" . $chl . '" border="0">'; + } +} \ No newline at end of file diff --git a/tests/application/modules/admin/controllers/StatControllerTest.php b/tests/application/modules/admin/controllers/StatControllerTest.php index a75b8bffa97..5cc95f27717 100644 --- a/tests/application/modules/admin/controllers/StatControllerTest.php +++ b/tests/application/modules/admin/controllers/StatControllerTest.php @@ -36,6 +36,30 @@ class Admin_StatControllerRecherchesInfructueusesTest extends Admin_AbstractCont class Admin_StatControllerVisunoticeTest extends Admin_AbstractControllerTestCase{ public function setUp() { parent::setUp(); + $this->sql = $this->mock() + ->whenCalled('fetchAll') + ->with('Select annee, sum(nb_visu) from stats_notices group by 1 order by annee desc', false) + ->answers([['annee' => '2000', 'sum(nb_visu)' => 6000],]) + + ->whenCalled('fetchAll') + ->with('Select annee, mois, nb_visu as cnt from stats_notices order by annee desc, mois desc', + false) + ->answers([['annee' => '2000', 'mois' => 1, 'cnt' => 42],]) + + ->whenCalled('fetchOne') + ->with('select min(annee) from stats_notices') + ->answers('2000') + + ->whenCalled('fetchOne') + ->with("select min(mois) from stats_notices where annee=2000") + ->answers('1') + + ->whenCalled('fetchOne') + ->answers('1'); + + + Zend_Registry::set('sql', $this->sql); + $this->dispatch('/admin/stat/visunotice', true); } @@ -44,6 +68,54 @@ class Admin_StatControllerVisunoticeTest extends Admin_AbstractControllerTestCas public function titreShouldBeVisualisationNotice() { $this->assertXPathContentContains('//h1', 'visualisation des notices'); } + + + /** @test */ + public function shouldHaveYearDetails() { + $this->assertXPathContentContains('//h3', 'Détail par années'); + } + + + /** @test */ + public function shouldHaveYear2000Label() { + $this->assertXPathContentContains('//td', '2000'); + } + + + /** @test */ + public function shouldHaveYear2000Detail() { + $this->assertXPathContentContains('//td', '6000'); + } + + + /** @test */ + public function shouldHaveYearsGraph() { + $this->assertXPath('//img[contains(@src, "chl=2000")]'); + } + + + /** @test */ + public function shouldHaveMonthDetails() { + $this->assertXPathContentContains('//h3', 'Détail par mois'); + } + + + /** @test */ + public function shouldHaveMonth1DetailLabel() { + $this->assertXPathContentContains('//td', 'janvier'); + } + + + /** @test */ + public function shouldHaveMonth1DetailCount() { + $this->assertXPathContentContains('//td', '42'); + } + + /** @test */ + public function shouldHaveMonthsGraph() { + $this->assertXPath('//img[contains(@src, "janvier")]', + $this->_response->getBody()); + } } ?> \ No newline at end of file -- GitLab