]> _ Git - cubeextranet.git/commitdiff
fix #3572 @0.5
authorvincent@cubedesigners.com <vincent@cubedesigners.com@f5622870-0f3c-0410-866d-9cb505b7a8ef>
Tue, 7 Apr 2020 15:23:54 +0000 (15:23 +0000)
committervincent@cubedesigners.com <vincent@cubedesigners.com@f5622870-0f3c-0410-866d-9cb505b7a8ef>
Tue, 7 Apr 2020 15:23:54 +0000 (15:23 +0000)
inc/ws/Controlleur/class.ws.stats.php

index cdab98dfd2cb35705387c959e910e7d71eac041d..2f4c1d01308a29bb81c1311cb4f255002fecda11 100644 (file)
 class wsStats\r
 {\r
 \r
-       public static $datestocorrect = array(array(22, 11, 2009), array(23, 11, 2009), array(8, 12, 2009), array(9, 12, 2009));\r
-\r
-       /**\r
-        * @var PHPExcel\r
-        */\r
-       public static $xls;\r
-\r
-       public static function exportXLS($bid, $annee = null, $mois = null)\r
-       {\r
-               $xname = self::_getXLSFile($bid, $annee, $mois);\r
-               $fname = 'stats_' . $bid;\r
-               if (!is_null($annee)) {\r
-                       $fname .= '_' . $annee;\r
-                       if (!is_null($mois)) {\r
-                               $fname .= '_' . $mois;\r
-                       }\r
-               }\r
-               $fname .= '.xlsx';\r
-\r
-               files::$mimeType['xlsx'] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';\r
-\r
-               cubeHTTP::downloadFile($xname, $fname);\r
-       }\r
-\r
-       protected static function _getXLSFile($bid, $annee = null, $mois = null)\r
-       {\r
-               self::forceComputation($bid);\r
-               $e = explode('_', $bid);\r
-               $bid = $e[0];\r
-               $xname = '/home/stats/www/xls/' . $bid;\r
-               if (!is_null($annee)) {\r
-                       $xname .= '/' . $annee;\r
-                       if (!is_null($mois)) {\r
-                               $xname .= '/' . $mois;\r
-                       }\r
-               }\r
-\r
-               $xname .= '.xlsx';\r
-\r
-               $dir = dirname($xname);\r
-               if (!file_exists($dir)) {\r
-                       mkdir($dir, 0777, true);\r
-               }\r
-\r
-               return $xname;\r
-       }\r
-\r
-       public static function display($bid, $annee = null, $mois = null)\r
-       {\r
-               global $core;\r
-\r
-               self::forceComputation($bid);\r
-\r
-               cubePHP::set_memory('12G');\r
-\r
-               self::$xls = new PHPExcel();\r
-               self::$xls->removeSheetByIndex(0);\r
-\r
-\r
-               $global = self::load_stats($bid);\r
-\r
-\r
-               $exporturl = SITE_PATH . 'statsxls/' . $bid;\r
-               if (!is_null($annee)) {\r
-                       $exporturl .= '/' . $annee;\r
-                       if (!is_null($mois)) {\r
-                               $exporturl .= '/' . $mois;\r
-                       }\r
-               }\r
-\r
-               $actions = array();\r
-               $actions[] = '<a href="' . $exporturl . '">' . $core->typo->Ajouter('Exporter au format Excel') . '</a>';\r
-\r
-               $years = $global->year;\r
-               $annees = array('<em>' . __('Toutes') . '</em>' => SITE_PATH . 'stats/' . $bid);\r
-\r
-               $listeShortcuts = array();\r
-\r
-\r
-               $listeMois = null;\r
-               foreach ($years as $y) {\r
-                       $selectedYear = __('Toutes');\r
-                       if (!is_null($annee) && $annee == (string)$y['year']) {\r
-                               $months = $y->month;\r
-                               $moiss = array('<em>' . __('Tous') . '</em>' => SITE_PATH . 'stats/' . $bid . '/' . (string)$y['year']);\r
-                               $selectedMonth = __('Tous');\r
-                               foreach ($months as $m) {\r
-                                       if ((string)$m['month'] == $mois) {\r
-                                               $selectedMonth = cubeDate::getMonth((string)$m['month']);\r
-                                       }\r
-                                       $moiss[cubeDate::getMonth((string)$m['month'])] = SITE_PATH . 'stats/' . $bid . '/' . (string)$y['year'] . '/' . (string)$m['month'];\r
-                               }\r
-                               $listeMois = new commonShortcuts(__('Mois'), $moiss, $selectedMonth);\r
-                       }\r
-                       if ((string)$y['year'] == $annee) {\r
-                               $selectedYear = $annee;\r
-                       }\r
-                       $annees[(string)$y['year']] = SITE_PATH . 'stats/' . $bid . '/' . (string)$y['year'];\r
-               }\r
-\r
-               $listeAnnees = new commonShortcuts(__('Année'), $annees, $selectedYear);\r
-               $listeShortcuts[] = $listeAnnees;\r
-               if (!is_null($listeMois)) {\r
-                       $listeShortcuts[] = $listeMois;\r
-               }\r
-\r
-               $res = commonPage::barre($listeShortcuts, 'filtreStats', 'stats', $actions);\r
-               $res .= commonPage::tMain();\r
-               if (is_null($annee) && is_null($mois)) {\r
-                       $res .= self::vue_globale($bid);\r
-               } elseif (is_null($mois)) {\r
-                       $res .= self::vue_annuelle($bid, $annee);\r
-               } else {\r
-                       $res .= self::vue_mensuelle($bid, $annee, $mois);\r
-               }\r
-               $res .= commonPage::bMain();\r
-\r
-\r
-               try {\r
-                       self::$xls->setActiveSheetIndex(0);\r
-                       $writer = new PHPExcel_Writer_Excel2007();\r
-                       $writer->setPHPExcel(self::$xls);\r
-                       $xlsfile = self::_getXLSFile($bid, $annee, $mois);\r
-                       cubePHP::set_memory('12G');\r
-                       $writer->save($xlsfile);\r
-               } catch (Exception $e) {\r
-                       die($e->getMessage());\r
-               }\r
-\r
-               return $res;\r
-       }\r
-\r
-       public static function getExtra($extra)\r
-       {\r
-               $xml = simplexml_load_string('<extra>' . $extra . '</extra>');\r
-               if ((string)$xml->extraName != '') {\r
-                       return (string)$xml->extraName;\r
-               }\r
-               return null;\r
-       }\r
-\r
-       public static function load_stats($bid, $annee = null, $mois = null)\r
-       {\r
-\r
-               $e = explode('_', $bid, 2);\r
-               $bid = $e[0];\r
-\r
-               $root = WS_STATS . 'xml/' . $bid;\r
-               if (is_null($annee)) {\r
-                       $xml = $root;\r
-                       $sort = 'globalSort';\r
-               } else if (is_null($mois)) {\r
-                       $xml = $root . '/' . $annee;\r
-                       $sort = 'yearSort';\r
-               } else {\r
-                       $xml = $root . '/' . $annee . '/' . $mois;\r
-                       $sort = 'monthSort';\r
-               }\r
-               $xml = rtrim($xml, '/');\r
-               $xml .= '.xml';\r
-               if ($x = @simplexml_load_file($xml)) {\r
-                       if (!is_null($mois)) {\r
-\r
-                       }\r
-                       $x = call_user_func(array('wsStats', $sort), $x);\r
-                       self::correctValues($x, $annee, $mois);\r
-                       return $x;\r
-               }\r
-               return null;\r
-       }\r
-\r
-       public static function correctValues($x, $y, $m)\r
-       {\r
-               return;\r
-               foreach (self::$datestocorrect as $date) {\r
-                       if ($date[2] != $y || $date[1] != $m) {\r
-                               continue;\r
-                       }\r
-                       $days = $x->xpath("//day[@day=" . $date[0] . "]");\r
-                       foreach ($days as $day) {\r
-                               break;\r
-                       }\r
-                       $visitors = (string)$day['places'] * 1.2;\r
-                       $visits = $visitors * 1.1;\r
-                       cubeXML::removeAttribute($day, 'visitors');\r
-                       cubeXML::removeAttribute($day, 'visits');\r
-                       $day->addAttribute('visitors', $visitors);\r
-                       $day->addAttribute('visits', $visits);\r
-               }\r
-       }\r
-\r
-       public static function correctPlaces($x)\r
-       {\r
-\r
-       }\r
-\r
-       public static function globalSort($xml, $root = 'stats')\r
-       {\r
-               $res = simplexml_load_string('<' . $root . ' />');\r
-               foreach ($xml->attributes() as $k => $v) {\r
-                       $res->addAttribute($k, $v);\r
-               }\r
-               $years = array();\r
-               foreach ($xml->year as $year) {\r
-                       $years[(string)$year['year']] = self::yearSort($year, 'year');\r
-               }\r
-               ksort($years);\r
-               foreach ($years as $y) {\r
-                       cubeXML::append($res, $y);\r
-               }\r
-               return $res;\r
-       }\r
-\r
-       public static function yearSort($xml, $root = 'stats')\r
-       {\r
-               $res = simplexml_load_string('<' . $root . ' />');\r
-               foreach ($xml->attributes() as $k => $v) {\r
-                       $res->addAttribute($k, $v);\r
-               }\r
-               $months = array();\r
-               foreach ($xml->month as $month) {\r
-                       $months[(string)$month['month']] = $month;\r
-               }\r
-\r
-               ksort($months);\r
-               foreach ($months as $month) {\r
-                       cubeXML::append($res, $month);\r
-               }\r
-\r
-               return $res;\r
-       }\r
-\r
-       public static function monthSort($xml, $root = 'stats')\r
-       {\r
-               $res = simplexml_load_string('<' . $root . ' />');\r
-               foreach ($xml->attributes() as $k => $v) {\r
-                       $res->addAttribute($k, $v);\r
-               }\r
-               self::daysSort($xml, $res);\r
-               self::pagesSort($xml, $res);\r
-               self::linksSort($xml, $res);\r
-               self::searchesSort($xml, $res);\r
-               self::countriesSort($xml, $res);\r
-               return $res;\r
-       }\r
-\r
-       public static function daysSort($xml, $res)\r
-       {\r
-               $x = $res->addChild('days');\r
-               $days = array();\r
-               foreach ($xml->days->day as $day) {\r
-                       $days[(string)$day['day']] = $day;\r
-               }\r
-               ksort($days);\r
-               foreach ($days as $day) {\r
-                       $places = (string)$day['places'];\r
-                       if ($places == 1) {\r
-                               $visitors = (string)$day['visitors'];\r
-                               if ($visitors > 10) {\r
-                                       cubeXML::removeAttribute($day, 'places');\r
-                                       $day->addAttribute('places', round($visitors * 0.99));\r
-                               }\r
-                       }\r
-                       cubeXML::append($x, $day);\r
-               }\r
-       }\r
-\r
-       public static function pagesSort($xml, $res)\r
-       {\r
-               $xpages = $res->addChild('pages');\r
-               $pages = array();\r
-               $trans = array();\r
-               foreach ($xml->pages->page as $page) {\r
-                       $pages[(string)$page['page']] = (string)$page['score'];\r
-                       $trans[(string)$page['page']] = $page;\r
-               }\r
-               arsort($pages);\r
-               foreach ($pages as $num => $score) {\r
-                       cubeXML::append($xpages, $trans[$num]);\r
-               }\r
-       }\r
-\r
-       public static function linksSort($xml, $res)\r
-       {\r
-               $x = $res->addChild('links');\r
-               $links = array();\r
-               $trans = array();\r
-               foreach ($xml->links->link as $link) {\r
-                       $links[(string)$link['url']] = (string)$link['click'];\r
-                       $trans[(string)$link['url']] = $link;\r
-               }\r
-               arsort($links);\r
-               $links = array_slice($links, 0, 100, true);\r
-               foreach ($links as $url => $click) {\r
-                       cubeXML::append($x, $trans[$url]);\r
-               }\r
-       }\r
-\r
-       public static function searchesSort($xml, $res)\r
-       {\r
-               $x = $res->addChild('searches');\r
-               $searches = array();\r
-               $trans = array();\r
-               foreach ($xml->searches->search as $search) {\r
-                       $searches[(string)$search['query']] = (string)$search['count'];\r
-                       $trans[(string)$search['query']] = $search;\r
-               }\r
-               arsort($searches);\r
-               $searches = array_slice($searches, 0, 100, true);\r
-               foreach ($searches as $q => $count) {\r
-                       cubeXML::append($x, $trans[$q]);\r
-               }\r
-       }\r
-\r
-       public static function countriesSort($xml, $res)\r
-       {\r
-               $x = $res->addChild('countries');\r
-               $countries = array();\r
-               $trans = array();\r
-               foreach ($xml->countries->country as $country) {\r
-                       $countries[(string)$country['code']] = (string)$country['visitors'];\r
-                       $trans[(string)$country['code']] = $country;\r
-               }\r
-               arsort($countries);\r
-               foreach ($countries as $code => $visitors) {\r
-                       cubeXML::append($x, $trans[$code]);\r
-               }\r
-       }\r
-\r
-       public static function getActives($stats, $book, &$aextra, &$adown, &$adownp, &$aprint, &$afriend)\r
-       {\r
-               $extra = self::getExtra($book->extras);\r
-               $aextra = ($extra != null && $stats['extras'] > 0);\r
-               $adown = ($book->parametres->pdf == 1 && $stats['downloads'] > 0);\r
-               $adownp = ($book->parametres->pdf == 1 && $book->parametres->pdfComplex == 1 && $stats['partDownloads'] > 0);\r
-               $aprint = ($book->parametres->print == 1);\r
-               $afriend = ($book->parametres->friend == 1);\r
-       }\r
-\r
-       public static function table($title, $colsTitles, $lines, $class, $firstColMax = true, $firstLineBold = false, $noOdd = false)\r
-       {\r
-               global $core;\r
-               if (is_string($class)) {\r
-                       $class = array($class);\r
-               }\r
-               $res = '<table class="' . implode(' ', $class) . '">';\r
-               // Titre\r
-               $res .= '<tr><th colspan="' . count($colsTitles) . '"><h1>' . $title . '</h1></th></tr>';\r
-               // Head\r
-               if (implode('', $colsTitles) != '') {\r
-                       $res .= '<tr>';\r
-                       foreach ($colsTitles as $i => $title) {\r
-                               $max = ($firstColMax && $i == 0) ? '' : ' class="stats_col"';\r
-                               $res .= '<th' . $max . '>' . $title . '</th>';\r
-                       }\r
-                       $res . '</tr>';\r
-               }\r
-               // Body\r
-               foreach ($lines as $i => $line) {\r
-                       $odd = cubeMath::isOdd($i) ? ' class="odd"' : '';\r
-                       if ($firstLineBold && $i == 0) {\r
-                               $odd = ' class="odd"';\r
-                       } elseif ($firstLineBold) {\r
-                               $odd = '';\r
-                       }\r
-                       if ($noOdd) {\r
-                               $odd = '';\r
-                       }\r
-                       $res .= '<tr' . $odd . '>';\r
-                       foreach ($line as $j => $cell) {\r
-                               $max = ($firstColMax && $j == 0) ? '' : ' class="stats_col"';\r
-                               if ($firstLineBold && $i == 0) {\r
-                                       $cell = '<strong>' . $cell . '</strong>';\r
-                               }\r
-                               $res .= '<td' . $max . '>' . $cell . '</td>';\r
-                       }\r
-                       $res .= '</tr>';\r
-               }\r
-\r
-               $res .= '</table>';\r
-\r
-               return $res;\r
-       }\r
-\r
-       /**\r
-        *\r
-        * @param string $name\r
-        * @return PHPExcel_Worksheet\r
-        */\r
-       protected static function _createSheet($name)\r
-       {\r
-               $s = self::$xls->createSheet();\r
-               $s->setTitle($name);\r
-               return $s;\r
-       }\r
-\r
-       public static function globalDatas($titre, $date_creation, $book, $stats, $afriend, $aprint, $adown, $adownp, $aextra)\r
-       {\r
-               global $xls;\r
-\r
-               $colsTitles = array('', '');\r
-               $lines = array();\r
-               $class = array('liste', 'max');\r
-\r
-               $lines[] = array($date_creation, date(__('d-m-Y'), $book->date));\r
-               //$lines[] = array(__('Nombre de lieux de visite'), $stats['places']);\r
-               $lines[] = array(__('Nombre de visiteurs uniques'), $stats['visitors']);\r
-               $lines[] = array(__('Nombre de visites'), $stats['visits']);\r
-               $lines[] = array(__('Nombre de pages vues'), $stats['pages']);\r
-               if ($afriend) {\r
-                       $lines[] = array(__('Nombre de liens envoyés'), $stats['friends']);\r
-               }\r
-               $lines[] = array(__('Nombre de liens cliqués'), $stats['links']);\r
-               if ($aprint) {\r
-                       $lines[] = array(__("Nombre d'impressions"), $stats['prints']);\r
-               }\r
-               if ($adown) {\r
-                       $lines[] = array(__('Nombre de téléchargements'), $stats['downloads']);\r
-               }\r
-               if ($adownp) {\r
-                       $lines[] = array(__('Nombre de téléchargements partiels'), $stats['partDownloads']);\r
-               }\r
-               if ($aextra) {\r
-                       $lines[] = array(__('Accès à la rubrique') . ' ' . $extra, $stats['extras']);\r
-               }\r
-\r
-               self::setSheetFromDatas(__('Résumé'), null, $lines);\r
-\r
-               return self::table($titre, $colsTitles, $lines, $class);\r
-       }\r
-\r
-       public static function indisponible()\r
-       {\r
-               $res = commonPage::bh('stats_global');\r
-               $res .= '<p class="center">' . __('Les statistiques concernant cette période ne sont actuellement pas disponibles') . '</p>';\r
-               $res .= commonPage::bf();\r
-               return $res;\r
-       }\r
-\r
-       public static function getBook($bid)\r
-       {\r
-               global $core;\r
-               $daoBook = new wsDAOBook($core->con);\r
-               return $daoBook->selectById($bid);\r
-       }\r
-\r
-       public static function vue_globale($bid, $annee = null)\r
-       {\r
-               global $core;\r
-               $book = self::getBook($bid);\r
-               $extra = self::getExtra($book->extras);\r
-               if (is_null($annee)) {\r
-                       $stats = self::load_stats($bid);\r
-               } else {\r
-                       $stats = self::load_stats($bid, $annee);\r
-               }\r
-\r
-               if (is_null($stats)) {\r
-                       return self::indisponible();\r
-               }\r
-\r
-               self::getActives($stats, $book, $aextra, $adown, $adownp, $aprint, $afriend);\r
-               $res = commonPage::bh('stats_global');\r
-               $titre = __('Statistiques de la publication « %s »');\r
-               $date_creation = __('Date de création de la publication');\r
-               $res .= self::globalDatas(sprintf($titre, $book->nom), $date_creation, $book, $stats, $afriend, $aprint, $adown, $adownp, $aextra);\r
-               $res .= commonPage::bf();\r
-               $res .= commonPage::bh();\r
-               $res .= '<table class="liste max">';\r
-               $res .= '<tr><th><h1>' . __('Détail par mois') . '</h1></th></tr>';\r
-               $res .= '<tr><th>';\r
-               $res .= '<div class="center" style="width:944px;margin:0 auto;position:relative;">';\r
-               if (is_null($annee)) {\r
-                       $res .= self::graph_global($bid, $stats);\r
-               } else {\r
-                       $res .= self::graph_annuel($bid, $annee, $stats);\r
-               }\r
-               $res .= '</div>';\r
-               $res .= '</th></tr>';\r
-               $res .= '</table>';\r
-               $res .= self::detailPeriode($book, $stats, $bid, $annee);\r
-               $res .= commonPage::bf();\r
-               return $res;\r
-       }\r
-\r
-       /**\r
-        * wsStats::vue_annuelle()\r
-        *\r
-        * @param mixed $bid\r
-        * @param mixed $annee\r
-        * @return\r
-        */\r
-       public static function vue_annuelle($bid, $annee)\r
-       {\r
-               return self::vue_globale($bid, $annee);\r
-       }\r
-\r
-       public static function vue_mensuelle($bid, $annee, $mois)\r
-       {\r
-               $datestocorrect = array(mktime(0, 0, 0, 11, 23, 2009), mktime(0, 0, 0, 12, 8, 2009), mktime(0, 0, 0, 12, 9, 2009));\r
-               global $core;\r
-               $book = self::getBook($bid);\r
-               $extra = self::getExtra($book->extras);\r
-               $stats = self::load_stats($bid, $annee, $mois);\r
-               if (is_null($stats)) {\r
-                       return self::indisponible();\r
-               }\r
-\r
-               self::getActives($stats, $book, $aextra, $adown, $adownp, $aprint, $afriend);\r
-               $time_page = mktime(0, 0, 0, $mois, 15, $annee);\r
-               $res = commonPage::bh('stats_global');\r
-               $titre = __('Statistiques de la publication « %s »');\r
-               $date_creation = __('Date de création de la publication');\r
-               $res .= self::globalDatas(sprintf($titre, $book->nom), $date_creation, $book, $stats, $afriend, $aprint, $adown, $adownp, $aextra);\r
-               $res .= commonPage::bf();\r
-               // .\r
-               $res .= commonPage::bh('stats_detail_mois');\r
-               $res .= '<div class="center" style="width:944px;position:relative;">';\r
-               $res .= self::graph_mensuel($bid, $annee, $mois, $stats);\r
-               $res .= '</div>';\r
-               $res .= self::detailJour($book, $annee, $mois, $stats);\r
-               $res .= commonPage::bf();\r
-\r
-\r
-               // .\r
-               $res .= commonPage::bh('stats_detail_pages');\r
-               $res .= self::detailPages($book, $annee, $mois, $stats);\r
-               $res .= commonPage::bf();\r
-               // .\r
-               if ($book->parametres->search == 0) {\r
-                       $idl = 'stats_links_2';\r
-                       $idc = 'stats_country_2';\r
-               } else {\r
-                       $idl = 'stats_links';\r
-                       $idc = 'stats_country';\r
-               }\r
-\r
-               $res .= '<div id="stats_30">';\r
-               $res .= commonPage::bh($idl);\r
-               $res .= self::detailLiens($book, $stats);\r
-               $res .= commonPage::bf();\r
-               if ($book->parametres->search == 1) {\r
-                       $res .= commonPage::bh('stats_search');\r
-                       $res .= self::detailSearch($book, $stats);\r
-                       $res .= commonPage::bf();\r
-               }\r
-               // Origine\r
-               $res .= commonPage::bh($idc);\r
-               $res .= self::detailOrigine($book, $stats);\r
-               $res .= commonPage::bf();\r
-               $res .= '</div>';\r
-               return $res;\r
-       }\r
-\r
-       public static function detailPeriode($book, $stats, $bid, $annee)\r
-       {\r
-               self::getActives($stats, $book, $aextra, $adown, $adownp, $aprint, $afriend);\r
-               $title = '';\r
-\r
-               $colsTitles = array(__('Période'), /*__('Lieux de visite'),*/\r
-                       __('Visiteurs uniques'), __('Visites'), __('Pages vues'));\r
-               if ($afriend) {\r
-                       $colsTitles[] = __('Liens envoyés');\r
-               }\r
-               $colsTitles[] = __('Liens cliqués');\r
-               if ($aprint) {\r
-                       $colsTitles[] = __('Impressions');\r
-               }\r
-               if ($adown) {\r
-                       $colsTitles[] = __('Téléchargements');\r
-               }\r
-               if ($adownp) {\r
-                       $colsTitles[] = __('Téléchargements partiels');\r
-               }\r
-               if ($aextra) {\r
-                       $colsTitles[] = $extra;\r
-               }\r
-\r
-               if (is_null($annee)) {\r
-                       $years = $stats->year;\r
-               } else {\r
-                       $years = array($stats);\r
-               }\r
-\r
-               $lines = array();\r
-               $noOdd = false;\r
-               foreach ($years as $year) {\r
-                       if ($year['annee'] != null) {\r
-                               $lines[] = self::linePeriod($year, $bid, $afriend, $aprint, $adown, $adownp, $aextra);\r
-                       } else {\r
-                               $noOdd = true;\r
-                       }\r
-\r
-                       foreach ($year->month as $month) {\r
-                               $lines[] = self::linePeriod($month, $bid, $afriend, $aprint, $adown, $adownp, $aextra);\r
-                       }\r
-               }\r
-\r
-               self::setSheetFromDatas(__('Détail'), $colsTitles, $lines);\r
-\r
-               return self::table($title, $colsTitles, $lines, array('max', 'liste'), true, false, $noOdd);\r
-       }\r
-\r
-       protected static function setSheetFromDatas($title, $columns, $lines)\r
-       {\r
-               $s = self::_createSheet($title);\r
-               $offset = 1;\r
-               if (!is_null($columns)) {\r
-                       $offset = 2;\r
-                       foreach ($columns as $k => $c) {\r
-\r
-                               $s->setCellValueByColumnAndRow($k, 1, $c);\r
-                               $s->getStyleByColumnAndRow($k, 1)->getFont()->setBold(true);\r
-\r
-                               if ($k == 0) {\r
-                                       $s->getStyleByColumnAndRow($k, 1)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);\r
-                               } else {\r
-                                       $s->getStyleByColumnAndRow($k, 1)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);\r
-                               }\r
-                       }\r
-               }\r
-               foreach ($lines as $k => $l) {\r
-                       foreach ($l as $c => $v) {\r
-                               $s->getColumnDimensionByColumn($c)->setAutoSize(true);\r
-                               $s->setCellValueByColumnAndRow($c, $k + $offset, strip_tags($v));\r
-\r
-                               if ($c == 0) {\r
-                                       $s->getStyleByColumnAndRow($c, $k + $offset)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);\r
-                               } else {\r
-                                       $s->getStyleByColumnAndRow($c, $k + $offset)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-\r
-       public static function linePeriod($stats, $bid, $afriend, $aprint, $adown, $adownp, $aextra)\r
-       {\r
-               $line = array();\r
-               $url = SITE_PATH . 'stats/' . $bid;\r
-               if (isset($stats['year'])) {\r
-                       $url .= '/' . $stats['year'];\r
-                       if (isset($stats['month'])) {\r
-                               $url .= '/' . $stats['month'];\r
-                               $date = strftime('%B %Y', mktime(0, 0, 0, (string)$stats['month'], 15, (string)$stats['year']));\r
-                       } else {\r
-                               $date = (string)$stats['year'];\r
-                       }\r
-               }\r
-\r
-               $line[] = '<a href="' . $url . '">' . $date . '</a>';\r
-               //$line[] = $stats['places'];\r
-               $line[] = $stats['visitors'];\r
-               $line[] = $stats['visits'];\r
-               $line[] = $stats['pages'];\r
-               if ($afriend) {\r
-                       $line[] = $stats['friends'];\r
-               }\r
-               $line[] = $stats['links'];\r
-               if ($aprint) {\r
-                       $line[] = $stats['prints'];\r
-               }\r
-               if ($adown) {\r
-                       $line[] = $stats['downloads'];\r
-               }\r
-               if ($adownp) {\r
-                       $line[] = $stats['partDownloads'];\r
-               }\r
-               if ($aextra) {\r
-                       $line[] = $stats['extras'];\r
-               }\r
-\r
-               return $line;\r
-       }\r
-\r
-       public static function detailJour($book, $annee, $mois, $stats)\r
-       {\r
-               $colsTitles = array(__('Jour'), /*__('Lieux de visite'),*/\r
-                       __('Visiteurs uniques'), __('Visites'), __('Pages vues'), __('Liens cliqués'));\r
-               $lines = array();\r
-               $xlines = array();\r
-\r
-               foreach ($stats->days->day as $day) {\r
-                       $lines[] = array(strftime('%A %d', mktime(0, 0, 0, $mois, (string)$day['day'], $annee)),\r
-                               // $day['places'],\r
-                               $day['visitors'],\r
-                               $day['visits'],\r
-                               $day['views'],\r
-                               $day['links']);\r
-                       $xlines[] = array(strftime('%d', mktime(0, 0, 0, $mois, (string)$day['day'], $annee)),\r
-                               //$day['places'],\r
-                               $day['visitors'],\r
-                               $day['visits'],\r
-                               $day['views'],\r
-                               $day['links']);\r
-               }\r
-               $time_page = mktime(0, 0, 0, $mois, 15, $annee);\r
-\r
-               self::setSheetFromDatas(__('Jours'), $colsTitles, $xlines);\r
-\r
-               return self::table(__('Détail par jour') . ' - ' . strftime('%B %Y', $time_page), $colsTitles, $lines, array('liste', 'max'), true);\r
-       }\r
-\r
-       public static function detailPages($book, $annee, $mois, $stats)\r
-       {\r
-               $colsTitles = array(__('Pages'));\r
-               if ($book->parametres->stats_score) {\r
-                       $colsTitles[] = __('Score');\r
-               }\r
-               $colsTitles[] = __('Vues');\r
-               $colsTitles[] = __('Zooms');\r
-               if ($book->parametres->bookmark) {\r
-                       $colsTitles[] = __('Marques-pages');\r
-               }\r
-               if ($book->parametres->print) {\r
-                       $colsTitles[] = __('Impressions');\r
-               }\r
-\r
-               $lines = array();\r
-               foreach ($stats->pages->page as $page) {\r
-                       $p = (string)$page['page'];\r
-                       if ($p > $book->pages || cubeMath::isOdd($p)) {\r
-                               continue;\r
-                       }\r
-                       if ($p == 0) {\r
-                               $pagen = '1';\r
-                       } elseif ($p == $book->parametres->pages) {\r
-                               $pagen = $p;\r
-                       } else {\r
-                               $pagen = $p;\r
-                               $pagen .= '-';\r
-                               $pagen .= ($p + 1);\r
-                       }\r
-\r
-                       $line = array($pagen);\r
-\r
-                       if ($book->parametres->stats_score == 1) {\r
-                               $line[] = $page['score'];\r
-                       }\r
-                       $line[] = $page['views'];\r
-                       $line[] = $page['zooms'];\r
-\r
-                       if ($book->parametres->bookmark == 1) {\r
-                               $line[] = $page['bookmarks'];\r
-                       }\r
-                       if ($book->parametres->print == 1) {\r
-                               $line[] = $page['prints'];\r
-                       }\r
-                       $lines[] = $line;\r
-               }\r
-               $time_page = mktime(0, 0, 0, $mois, 15, $annee);\r
-\r
-               self::setSheetFromDatas(__('Pages'), $colsTitles, $lines);\r
-\r
-               return self::table(__('Détail par page') . ' - ' . strftime('%B %Y', $time_page), $colsTitles, $lines, array('liste', 'max'));\r
-       }\r
-\r
-       public static function detailLiens($book, $stats)\r
-       {\r
-               $colsTitles = array(__('URL'), __('Clics'));\r
-               $lines = array();\r
-               $xlines = array();\r
-\r
-               foreach ($stats->links->link as $link) {\r
-                       $uurl = (string)$link['url'];\r
-                       $nb = (string)$link['click'];\r
-                       if (stristr($uurl, 'mailto:') || stristr($uurl, 'http://') || stristr($uurl, 'https://')) {\r
-                               $url = substr($uurl, 7);\r
-                       } else {\r
-                               $url = $uurl;\r
-                       }\r
-                       if (strlen($url) > 30) {\r
-                               $url = substr($url, 0, 30) . '...';\r
-                       }\r
-\r
-                       $lines[] = array('<a href="' . $uurl . '" class="blank" title="' . $uurl . '">' . $url . '</a>', $nb);\r
-                       $xlines[] = array($uurl, $nb);\r
-               }\r
-\r
-               self::setSheetFromDatas(__('Liens'), $colsTitles, $xlines);\r
-               return self::table(__('Liens les plus cliqués'), $colsTitles, $lines, array('liste', 'max'));\r
-       }\r
-\r
-       public static function detailSearch($book, $stats)\r
-       {\r
-               $colsTitles = array(__('Mot'), __('Recherches'));\r
-               $lines = array();\r
-\r
-               foreach ($stats->searches->search as $search) {\r
-                       $q = $search['query'];\r
-                       if (strlen($q) > 25) {\r
-                               $q = '<abbr title="' . $q . '">' . substr($q, 0, 25) . ' ...</abbr>';\r
-                       }\r
-                       $lines[] = array($q, $search['count']);\r
-               }\r
-               self::setSheetFromDatas(__('Recherches'), $colsTitles, $lines);\r
-               return self::table(__('Mots les plus recherchés'), $colsTitles, $lines, array('liste', 'max'));\r
-       }\r
-\r
-       public static function detailOrigine($book, $stats)\r
-       {\r
-               $colsTitles = array(__('Pays'), __('Visiteurs'));\r
-               $lines = array();\r
-               $xlines = array();\r
-               $i = 0;\r
-\r
-               foreach ($stats->countries->country as $country) {\r
-                       $pays = $country['code'];\r
-                       $odd = cubeMath::isOdd($i) ? ' class="odd"' : '';\r
-                       if (!$c = cubeCountry::getCountry($pays)) {\r
-                               $c = __('Origine inconnue');\r
-                       }\r
-                       $lines[] = array(cubeCountry::getFlag($pays) . ' ' . ucfirst(mb_strtolower($c)), $country['visitors']);\r
-                       $xlines[] = array(ucfirst(mb_strtolower($c)), $country['visitors']);\r
-                       $i++;\r
-               }\r
-               self::setSheetFromDatas(__('Origines'), $colsTitles, $xlines);\r
-               return self::table(__('Origine des visiteurs'), $colsTitles, $lines, array('liste', 'max'));\r
-       }\r
-\r
-       public static function getQ($max, &$maxp, &$maxpages, &$s)\r
-       {\r
-               $maxpages = $maxp;\r
-               $q = 1;\r
-               $maxp /= $q;\r
-               $maxp = max($max * 4, $maxp);\r
-               $q = $maxpages / $maxp;\r
-               foreach ($s as $time => $t) {\r
-                       $s[$time]['page'] = intval($s[$time]['page'] / $q);\r
-               }\r
-       }\r
-\r
-       public static function graph_annuel($bid, $a, $stats)\r
-       {\r
-               $img = SYSIMG . '/stats/annuel-' . $a . '-' . $bid . '.png';\r
-               $imgw = IMG . '/stats/annuel-' . $a . '-' . $bid . '.png';\r
-               $maxv = 0;\r
-               $maxp = 0;\r
-               $maxb = 0;\r
-               $s = array();\r
-               foreach ($stats->month as $month) {\r
-                       $maxb = max($maxb, (string)$month['visits']);\r
-                       $maxp = max($maxp, (string)$month['pages']);\r
-                       $maxv = max($maxv, (string)$month['visitors']);\r
-                       $time = cubeDate::round(mktime(0, 0, 0, (string)$month['month'], 15, (string)$month['year']), 'm');\r
-                       $s[$time] = array();\r
-                       $s[$time]['book'] = (string)$month['visits'];\r
-                       $s[$time]['page'] = (string)$month['pages'];\r
-                       $s[$time]['visit'] = (string)$month['visitors'];\r
-               }\r
-               // .\r
-               $max = max($maxb, $maxv);\r
-               self::getQ($max, $maxp, $maxpages, $s);\r
-               krsort($s);\r
-               $max = max($maxb, $maxv, $maxp);\r
-               $months = cubeDate::getMonths($a);\r
-               @unlink($img);\r
-               if (!file_exists($img) || filemtime($img) < cubeDate::round(null, 'H')) {\r
-                       $im = imagecreatetruecolor(944, 306);\r
-                       //imagelayereffect($im, IMG_EFFECT_REPLACE);\r
-                       $trans = imagecolorallocatealpha($im, 255, 255, 255, 0);\r
-                       imagefill($im, 0, 0, $trans);\r
-                       //imagelayereffect($im, IMG_EFFECT_ALPHABLEND);\r
-                       $i = 1;\r
-                       $x0 = 0;\r
-                       $y0 = 305;\r
-                       $h = 300;\r
-                       $c0 = imagecolorallocate($im, 0, 0, 0);\r
-                       $c1 = imagecolorallocatealpha($im, 81, 78, 73, 64);\r
-                       $hp = $h * ($maxp / $max) - 2;\r
-                       $mhp = $y0 - $hp - 6;\r
-                       imagesetstyle($im, array($c1, $c1, $c1, $c1, $c1, $trans, $trans, $trans, $trans));\r
-                       imageline($im, 0, $y0 - $hp, 944, $y0 - $hp, IMG_COLOR_STYLED);\r
-                       $c1 = imagecolorallocate($im, 81, 78, 73);\r
-                       $c2 = imagecolorallocatealpha($im, 245, 77, 0, 64);\r
-                       $hb = $h * ($maxb / $max) - 1;\r
-                       $mhb = $y0 - $hb - 6;\r
-                       imagesetstyle($im, array($c2, $c2, $c2, $c2, $c2, $trans, $trans, $trans, $trans));\r
-                       imageline($im, 0, $y0 - $hb, 944, $y0 - $hb, IMG_COLOR_STYLED);\r
-                       $c2 = imagecolorallocate($im, 245, 77, 0);\r
-                       $c3 = imagecolorallocatealpha($im, 194, 211, 19, 32);\r
-                       $hv = $h * ($maxv / $max);\r
-                       $mhv = $y0 - $hv - 6;\r
-                       imagesetstyle($im, array($c3, $c3, $c3, $c3, $c3, $trans, $trans, $trans, $trans));\r
-                       imageline($im, 0, $y0 - $hv, 944, $y0 - $hv, IMG_COLOR_STYLED);\r
-                       $c3 = imagecolorallocate($im, 194, 211, 19);\r
-                       foreach ($months as $m => $t) {\r
-                               if (isset($s[$t])) {\r
-                                       $x0 += 15;\r
-                                       $hp = $h * ($s[$t]['page'] / $max) - 2;\r
-                                       $hb = $h * ($s[$t]['book'] / $max) - 1;\r
-                                       $hv = $h * ($s[$t]['visit'] / $max);\r
-                                       imagefilledrectangle($im, $x0 + 40, $y0 - $hp, $x0, $y0, $c1);\r
-                                       imagerectangle($im, $x0 + 40, $y0 - $hp, $x0, $y0, $c0);\r
-                                       $x0 += 5;\r
-                                       imagefilledrectangle($im, $x0 + 40, $y0 - $hb, $x0, $y0, $c2);\r
-                                       imagerectangle($im, $x0 + 40, $y0 - $hb, $x0, $y0, $c0);\r
-                                       $x0 += 5;\r
-                                       imagefilledrectangle($im, $x0 + 40, $y0 - $hv, $x0, $y0, $c3);\r
-                                       imagerectangle($im, $x0 + 40, $y0 - $hv, $x0, $y0, $c0);\r
-                                       $i++;\r
-                                       $x0 += 50;\r
-                               } else {\r
-                                       $x0 += 75;\r
-                               }\r
-                       }\r
-\r
-                       imageline($im, 0, $y0, 944, $y0, $c0);\r
-                       imagepng($im, $img);\r
-               }\r
-               $res = '<div class="graphStats"><div class="graph-note" style="top:' . $mhp . 'px;color:#514e49;">' . $maxpages . '</div>';\r
-               $res .= '<div class="graph-note" style="top:' . $mhb . 'px;color:#f54d00;">' . $maxb . '</div>';\r
-               $res .= '<div class="graph-note" style="top:' . $mhv . 'px;color:#c2d313;">' . $maxv . '</div>';\r
-               $res .= '<div class="graph-container" style="background:url(' . $imgw . ')"></div>';\r
-               $res .= '<table style="width:944px;max-width:944px;table-layout:fixed;" class="echelle"><tr>';\r
-               foreach ($months as $m => $t) {\r
-                       $res .= '<td style="width:75px;max-width:75px;">' . strftime('%b %y', $t) . '</td>';\r
-               }\r
-               $res .= '<td style="width:44px;">' . cubeMedia::spacer(44, 20) . '</td>';\r
-               $res .= '</tr></table>';\r
-               $res .= '<table class="legende" style="margin-top:10px;margin-bottom:10px;"><tr>';\r
-               $res .= '<td style="width:12px;background:#514e49;height:12px;"></td><td style="width:10px;"></td><td>' . __('Pages vues') . '</td><td style="width:10px;"></td>';\r
-               $res .= '<td style="width:12px;background:#f54d00;height:12px;"></td><td style="width:10px;"></td><td>' . __('Visites') . '</td><td style="width:10px;"></td>';\r
-               $res .= '<td style="width:12px;background:#c2d313;height:12px;"></td><td style="width:10px;"></td><td>' . __('Visiteurs uniques') . '</td><td style="width:10px;"></td>';\r
-               $res .= '</tr></table></div>';\r
-               return $res;\r
-       }\r
-\r
-       public static function graph_global($bid, $stats)\r
-       {\r
-               global $core;\r
-               $img = SYSIMG . '/stats/global-' . $bid . '.png';\r
-               $imgw = IMG . '/stats/global-' . $bid . '.png';\r
-               $s = array();\r
-               foreach ($stats->year as $year) {\r
-                       foreach ($year->month as $month) {\r
-                               $time = mktime(0, 0, 0, intval((string)$month['month']), 15, (string)$month['year']);\r
-                               $s[$time]['book'] = $month['visits'];\r
-                               $s[$time]['page'] = $month['pages'];\r
-                               $s[$time]['time'] = $time;\r
-                               $s[$time]['visit'] = $month['visitors'];\r
-                       }\r
-               }\r
-\r
-               krsort($s);\r
-               $s = array_slice($s, 0, 12, true);\r
-               $maxv = 0;\r
-               $maxp = 0;\r
-               $maxb = 0;\r
-               foreach ($s as $time => $d) {\r
-                       $maxb = max($maxb, (string)$d['book']);\r
-                       $maxp = max($maxp, (string)$d['page']);\r
-                       $maxv = max($maxv, (string)$d['visit']);\r
-               }\r
-\r
-               $max = max($maxb, $maxv);\r
-               self::getQ($max, $maxp, $maxpages, $s);\r
-               $max = max($maxv, $maxb, $maxp, 1);\r
-               if (file_exists($img)) {\r
-                       unlink($img);\r
-               }\r
-               if (!file_exists($img) || filemtime($img) < cubeDate::round(null, 'H')) {\r
-                       $im = imagecreatetruecolor(944, 306);\r
-                       //imagelayereffect($im, IMG_EFFECT_REPLACE);\r
-                       $trans = imagecolorallocatealpha($im, 255, 255, 255, 0);\r
-                       imagefill($im, 0, 0, $trans);\r
-                       //imagelayereffect($im, IMG_EFFECT_ALPHABLEND);\r
-                       $i = 1;\r
-                       $x0 = 900;\r
-                       $y0 = 305;\r
-                       $h = 300;\r
-                       $c0 = imagecolorallocate($im, 0, 0, 0);\r
-                       $c1 = imagecolorallocatealpha($im, 81, 78, 73, 64);\r
-                       $hp = $h * ($maxp / $max) - 2;\r
-                       $mhp = $y0 - $hp - 6;\r
-                       imagesetstyle($im, array($c1, $c1, $c1, $c1, $c1, $trans, $trans, $trans, $trans));\r
-                       imageline($im, 0, $y0 - $hp, 944, $y0 - $hp, IMG_COLOR_STYLED);\r
-                       $c1 = imagecolorallocate($im, 81, 78, 73);\r
-                       $c2 = imagecolorallocatealpha($im, 245, 77, 0, 64);\r
-                       $hb = $h * ($maxb / $max) - 1;\r
-                       $mhb = $y0 - $hb - 6;\r
-                       imagesetstyle($im, array($c2, $c2, $c2, $c2, $c2, $trans, $trans, $trans, $trans));\r
-                       imageline($im, 0, $y0 - $hb, 944, $y0 - $hb, IMG_COLOR_STYLED);\r
-                       $c2 = imagecolorallocate($im, 245, 77, 0);\r
-                       $c3 = imagecolorallocatealpha($im, 194, 211, 19, 32);\r
-                       $hv = $h * ($maxv / $max);\r
-                       $mhv = $y0 - $hv - 6;\r
-                       imagesetstyle($im, array($c3, $c3, $c3, $c3, $c3, $trans, $trans, $trans, $trans));\r
-                       imageline($im, 0, $y0 - $hv, 944, $y0 - $hv, IMG_COLOR_STYLED);\r
-                       $c3 = imagecolorallocate($im, 194, 211, 19);\r
-                       foreach ($s as $t) {\r
-                               $x0 -= 15;\r
-                               $hp = $h * ($t['page'] / $max) - 2;\r
-                               $hb = $h * ($t['book'] / $max) - 1;\r
-                               $hv = $h * ($t['visit'] / $max);\r
-                               imagefilledrectangle($im, $x0 - 40, $y0 - $hp, $x0, $y0, $c1);\r
-                               imagerectangle($im, $x0 - 40, $y0 - $hp, $x0, $y0, $c0);\r
-                               $x0 -= 5;\r
-                               imagefilledrectangle($im, $x0 - 40, $y0 - $hb, $x0, $y0, $c2);\r
-                               imagerectangle($im, $x0 - 40, $y0 - $hb, $x0, $y0, $c0);\r
-                               $x0 -= 5;\r
-                               imagefilledrectangle($im, $x0 - 40, $y0 - $hv, $x0, $y0, $c3);\r
-                               imagerectangle($im, $x0 - 40, $y0 - $hv, $x0, $y0, $c0);\r
-                               $i++;\r
-                               $x0 -= 50;\r
-                       }\r
-\r
-                       imageline($im, 0, $y0, 944, $y0, $c0);\r
-                       imagepng($im, $img);\r
-               }\r
-               $res = '<div class="graphStats"><div class="graph-note" style="top:' . $mhp . 'px;color:#514e49;">' . $maxpages . '</div>';\r
-               $res .= '<div class="graph-note" style="top:' . $mhb . 'px;color:#f54d00">' . $maxb . '</div>';\r
-               $res .= '<div  class="graph-note" style="top:' . $mhv . 'px;color:#c2d313;">' . $maxv . '</div>';\r
-               $res .= '<div class="graph-container" style="background:url(' . $imgw . ')"></div>';\r
-               $s = array_reverse(array_pad($s, 12, false), true);\r
-               $res .= '<table style="width:944px;max-width:944px;" class="echelle"><tr>';\r
-               foreach ($s as $time => $val) {\r
-                       if (!$val) {\r
-                               $res .= '<td style="width:75px;max-width:75px;">' . cubeMedia::spacer(75, 20) . '</td>';\r
-                       } else {\r
-                               $res .= '<td style="width:75px;max-width:75px;">' . strftime('%b %y', $val['time']) . '</td>';\r
-                       }\r
-               }\r
-               $res .= '<td style="width:44px;">' . cubeMedia::spacer(44, 20) . '</td>';\r
-               $res .= '</tr></table>';\r
-               $res .= '<table class="legende"><tr>';\r
-               $res .= '<td style="width:12px;background:#514e49;height:12px;"></td><td style="width:10px;"></td><td>' . __('Pages vues') . '</td><td style="width:10px;"></td>';\r
-               $res .= '<td style="width:12px;background:#f54d00;height:12px;"></td><td style="width:10px;"></td><td>' . __('Visites') . '</td><td style="width:10px;"></td>';\r
-               $res .= '<td style="width:12px;background:#c2d313;height:12px;"></td><td style="width:10px;"></td><td>' . __('Visiteurs uniques') . '</td><td style="width:10px;"></td>';\r
-               $res .= '</tr></table></div>';\r
-               return $res;\r
-       }\r
-\r
-       public static function graph_mensuel($bid, $a, $m, $stats)\r
-       {\r
-               $img = SYSIMG . '/stats/mensuel-' . $a . '-' . $m . '-' . $bid . '.png';\r
-               $imgw = IMG . '/stats/mensuel-' . $a . '-' . $m . '-' . $bid . '.png';\r
-               $lm = cubeDate::limitMonth($a, $m);\r
-               $datestocorrect = array(mktime(0, 0, 0, 11, 23, 2009), mktime(0, 0, 0, 12, 8, 2009), mktime(0, 0, 0, 12, 9, 2009));\r
-               $maxv = 0;\r
-               $maxp = 0;\r
-               $maxb = 0;\r
-               $v = array();\r
-               $s = array();\r
-               foreach ($stats->days->day as $day) {\r
-                       $time = mktime(0, 0, 0, $m, (string)$day['day'], $a);\r
-                       $maxb = max($maxb, (string)$day['visits']);\r
-                       $maxp = max($maxp, (string)$day['views']);\r
-                       $maxv = max($maxv, (string)$day['visitors']);\r
-                       $s[$time]['book'] = $day['visits'];\r
-                       $s[$time]['page'] = $day['views'];\r
-                       $s[$time]['visit'] = $day['visitors'];\r
-                       $s[$time]['time'] = $time;\r
-               }\r
-               $max = max($maxb, $maxv);\r
-               self::getQ($max, $maxp, $maxpages, $s);\r
-               krsort($s);\r
-               $max = max($maxv, $maxb, $maxp);\r
-               $days = cubeDate::getDays($a, $m);\r
-               $space = round((900 - (count($days) * 20)) / (count($days) * 2));\r
-               @unlink($img);\r
-               if (!file_exists($img) || filemtime($img) < cubeDate::round(null, 'H')) {\r
-                       // Création de l'image\r
-                       $im = imagecreatetruecolor(944, 306);\r
-                       //imagelayereffect($im, IMG_EFFECT_REPLACE);\r
-                       $trans = imagecolorallocatealpha($im, 255, 255, 255, 0);\r
-                       imagefill($im, 0, 0, $trans);\r
-                       //imagelayereffect($im, IMG_EFFECT_ALPHABLEND);\r
-                       $i = 1;\r
-                       $x0 = 0;\r
-                       $y0 = 305;\r
-                       $h = 300;\r
-                       $c0 = imagecolorallocate($im, 0, 0, 0);\r
-                       $c1 = imagecolorallocatealpha($im, 81, 78, 73, 64);\r
-                       $hp = $h * ($maxp / $max) - 2;\r
-                       $mhp = $y0 - $hp - 6;\r
-                       imagesetstyle($im, array($c1, $c1, $c1, $c1, $c1, $trans, $trans, $trans, $trans));\r
-                       imageline($im, 0, $y0 - $hp, 944, $y0 - $hp, IMG_COLOR_STYLED);\r
-                       $c1 = imagecolorallocate($im, 81, 78, 73);\r
-                       $c2 = imagecolorallocatealpha($im, 245, 77, 0, 64);\r
-                       $hb = $h * ($maxb / $max) - 1;\r
-                       $mhb = $y0 - $hb - 6;\r
-                       imagesetstyle($im, array($c2, $c2, $c2, $c2, $c2, $trans, $trans, $trans, $trans));\r
-                       imageline($im, 0, $y0 - $hb, 944, $y0 - $hb, IMG_COLOR_STYLED);\r
-                       $c2 = imagecolorallocate($im, 245, 77, 0);\r
-                       $c3 = imagecolorallocatealpha($im, 194, 211, 19, 32);\r
-                       $hv = $h * ($maxv / $max);\r
-                       $mhv = $y0 - $hv - 6;\r
-                       imagesetstyle($im, array($c3, $c3, $c3, $c3, $c3, $trans, $trans, $trans, $trans));\r
-                       imageline($im, 0, $y0 - $hv, 944, $y0 - $hv, IMG_COLOR_STYLED);\r
-                       $c3 = imagecolorallocate($im, 194, 211, 19);\r
-                       foreach ($days as $d => $t) {\r
-                               if (isset($s[$t])) {\r
-                                       $x0 += $space;\r
-                                       $hp = $h * ($s[$t]['page'] / $max) - 2;\r
-                                       $hb = $h * ($s[$t]['book'] / $max) - 1;\r
-                                       $hv = $h * ($s[$t]['visit'] / $max);\r
-                                       imagefilledrectangle($im, $x0 + 14, $y0 - $hp, $x0, $y0, $c1);\r
-                                       imagerectangle($im, $x0 + 14, $y0 - $hp, $x0, $y0, $c0);\r
-                                       $x0 += 3;\r
-                                       imagefilledrectangle($im, $x0 + 14, $y0 - $hb, $x0, $y0, $c2);\r
-                                       imagerectangle($im, $x0 + 14, $y0 - $hb, $x0, $y0, $c0);\r
-                                       $x0 += 3;\r
-                                       imagefilledrectangle($im, $x0 + 14, $y0 - $hv, $x0, $y0, $c3);\r
-                                       imagerectangle($im, $x0 + 14, $y0 - $hv, $x0, $y0, $c0);\r
-                                       $i++;\r
-                                       $x0 += 14 + $space;\r
-                               } else {\r
-                                       $x0 += 20 + $space * 2;\r
-                               }\r
-                       }\r
-\r
-                       imageline($im, 0, $y0, 944, $y0, $c0);\r
-                       imagepng($im, $img);\r
-               }\r
-               $res = '<div class="graphStats"><div class="graph-note" style="top:' . $mhp . 'px;color:#514e49;">' . $maxpages . '</div>';\r
-               $res .= '<div class="graph-note" style="top:' . $mhb . 'px;color:#f54d00;">' . $maxb . '</div>';\r
-               $res .= '<div class="graph-note" style="top:' . $mhv . 'px;color:#c2d313;">' . $maxv . '</div>';\r
-               $res .= '<div class="graph-container" style="background:url(' . $imgw . ')"></div>';\r
-               $res .= '<table style="width:944px;max-width:944px;margin:0px;table-layout:fixed;" class="echelle"><tr>';\r
-               foreach ($days as $d => $t) {\r
-                       $res .= '<td style="width:' . (20 + $space * 2) . 'px;max-width:' . (20 + $space * 2) . 'px;text-align:center;">' . $d . '</td>';\r
-               }\r
-               $spacef = 944 - (count($days) * (20 + ($space * 2)));\r
-               $res .= '<td style="width:' . $spacef . 'px;">' . cubeMedia::spacer($spacef, 20) . '</td>';\r
-               $res .= '</tr></table>';\r
-               $res .= '<table style="margin-top:10px;margin-bottom:10px;" class="legende"><tr>';\r
-               $res .= '<td style="width:12px;background:#514e49;height:12px;"></td><td style="width:10px;"></td><td>' . __('Pages vues') . '</td><td style="width:10px;"></td>';\r
-               $res .= '<td style="width:12px;background:#f54d00;height:12px;"></td><td style="width:10px;"></td><td>' . __('Visites') . '</td><td style="width:10px;"></td>';\r
-               $res .= '<td style="width:12px;background:#c2d313;height:12px;"></td><td style="width:10px;"></td><td>' . __('Visiteurs uniques') . '</td><td style="width:10px;"></td>';\r
-               $res .= '</tr></table></div>';\r
-               return $res;\r
-       }\r
-\r
-       public static function forceComputation($id)\r
-       {\r
-               `/home/stats/www/FWStats.sh /home/stats/www onlybook=$id`;\r
-       }\r
+    public static $datestocorrect = array(array(22, 11, 2009), array(23, 11, 2009), array(8, 12, 2009), array(9, 12, 2009));\r
+\r
+    /**\r
+     * @var PHPExcel\r
+     */\r
+    public static $xls;\r
+\r
+    public static function exportXLS($bid, $annee = null, $mois = null)\r
+    {\r
+        $xname = self::_getXLSFile($bid, $annee, $mois);\r
+        $fname = 'stats_' . $bid;\r
+        if (!is_null($annee)) {\r
+            $fname .= '_' . $annee;\r
+            if (!is_null($mois)) {\r
+                $fname .= '_' . $mois;\r
+            }\r
+        }\r
+        $fname .= '.xlsx';\r
+\r
+        files::$mimeType['xlsx'] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';\r
+\r
+        cubeHTTP::downloadFile($xname, $fname);\r
+    }\r
+\r
+    protected static function _getXLSFile($bid, $annee = null, $mois = null)\r
+    {\r
+        self::forceComputation($bid);\r
+        $e = explode('_', $bid);\r
+        $bid = $e[0];\r
+        $xname = '/home/stats/www/xls/' . $bid;\r
+        if (!is_null($annee)) {\r
+            $xname .= '/' . $annee;\r
+            if (!is_null($mois)) {\r
+                $xname .= '/' . $mois;\r
+            }\r
+        }\r
+\r
+        $xname .= '.xlsx';\r
+\r
+        $dir = dirname($xname);\r
+        if (!file_exists($dir)) {\r
+            mkdir($dir, 0777, true);\r
+        }\r
+\r
+        return $xname;\r
+    }\r
+\r
+    public static function display($bid, $annee = null, $mois = null)\r
+    {\r
+        global $core;\r
+\r
+        self::forceComputation($bid);\r
+\r
+        cubePHP::set_memory('12G');\r
+\r
+        self::$xls = new PHPExcel();\r
+        if (self::$xls->getSheetCount() < 2) {\r
+            wsMaintenance::fixStats([$bid]);\r
+        }else {\r
+            self::$xls->removeSheetByIndex(0);\r
+        }\r
+\r
+        $global = self::load_stats($bid);\r
+\r
+\r
+        $exporturl = SITE_PATH . 'statsxls/' . $bid;\r
+        if (!is_null($annee)) {\r
+            $exporturl .= '/' . $annee;\r
+            if (!is_null($mois)) {\r
+                $exporturl .= '/' . $mois;\r
+            }\r
+        }\r
+\r
+        $actions = array();\r
+        $actions[] = '<a href="' . $exporturl . '">' . $core->typo->Ajouter('Exporter au format Excel') . '</a>';\r
+\r
+        $years = $global->year;\r
+        $annees = array('<em>' . __('Toutes') . '</em>' => SITE_PATH . 'stats/' . $bid);\r
+\r
+        $listeShortcuts = array();\r
+\r
+\r
+        $listeMois = null;\r
+        foreach ($years as $y) {\r
+            $selectedYear = __('Toutes');\r
+            if (!is_null($annee) && $annee == (string)$y['year']) {\r
+                $months = $y->month;\r
+                $moiss = array('<em>' . __('Tous') . '</em>' => SITE_PATH . 'stats/' . $bid . '/' . (string)$y['year']);\r
+                $selectedMonth = __('Tous');\r
+                foreach ($months as $m) {\r
+                    if ((string)$m['month'] == $mois) {\r
+                        $selectedMonth = cubeDate::getMonth((string)$m['month']);\r
+                    }\r
+                    $moiss[cubeDate::getMonth((string)$m['month'])] = SITE_PATH . 'stats/' . $bid . '/' . (string)$y['year'] . '/' . (string)$m['month'];\r
+                }\r
+                $listeMois = new commonShortcuts(__('Mois'), $moiss, $selectedMonth);\r
+            }\r
+            if ((string)$y['year'] == $annee) {\r
+                $selectedYear = $annee;\r
+            }\r
+            $annees[(string)$y['year']] = SITE_PATH . 'stats/' . $bid . '/' . (string)$y['year'];\r
+        }\r
+\r
+        $listeAnnees = new commonShortcuts(__('Année'), $annees, $selectedYear);\r
+        $listeShortcuts[] = $listeAnnees;\r
+        if (!is_null($listeMois)) {\r
+            $listeShortcuts[] = $listeMois;\r
+        }\r
+\r
+        $res = commonPage::barre($listeShortcuts, 'filtreStats', 'stats', $actions);\r
+        $res .= commonPage::tMain();\r
+        if (is_null($annee) && is_null($mois)) {\r
+            $res .= self::vue_globale($bid);\r
+        } elseif (is_null($mois)) {\r
+            $res .= self::vue_annuelle($bid, $annee);\r
+        } else {\r
+            $res .= self::vue_mensuelle($bid, $annee, $mois);\r
+        }\r
+        $res .= commonPage::bMain();\r
+\r
+\r
+        try {\r
+            self::$xls->setActiveSheetIndex(0);\r
+            $writer = new PHPExcel_Writer_Excel2007();\r
+            $writer->setPHPExcel(self::$xls);\r
+            $xlsfile = self::_getXLSFile($bid, $annee, $mois);\r
+            cubePHP::set_memory('12G');\r
+            $writer->save($xlsfile);\r
+        } catch (Exception $e) {\r
+            die($e->getMessage());\r
+        }\r
+\r
+        return $res;\r
+    }\r
+\r
+    public static function getExtra($extra)\r
+    {\r
+        $xml = simplexml_load_string('<extra>' . $extra . '</extra>');\r
+        if ((string)$xml->extraName != '') {\r
+            return (string)$xml->extraName;\r
+        }\r
+        return null;\r
+    }\r
+\r
+    public static function load_stats($bid, $annee = null, $mois = null)\r
+    {\r
+\r
+        $e = explode('_', $bid, 2);\r
+        $bid = $e[0];\r
+\r
+        $root = WS_STATS . 'xml/' . $bid;\r
+        if (is_null($annee)) {\r
+            $xml = $root;\r
+            $sort = 'globalSort';\r
+        } else if (is_null($mois)) {\r
+            $xml = $root . '/' . $annee;\r
+            $sort = 'yearSort';\r
+        } else {\r
+            $xml = $root . '/' . $annee . '/' . $mois;\r
+            $sort = 'monthSort';\r
+        }\r
+        $xml = rtrim($xml, '/');\r
+        $xml .= '.xml';\r
+        if ($x = @simplexml_load_file($xml)) {\r
+            if (!is_null($mois)) {\r
+\r
+            }\r
+            $x = call_user_func(array('wsStats', $sort), $x);\r
+            self::correctValues($x, $annee, $mois);\r
+            return $x;\r
+        }\r
+        return null;\r
+    }\r
+\r
+    public static function correctValues($x, $y, $m)\r
+    {\r
+        return;\r
+        foreach (self::$datestocorrect as $date) {\r
+            if ($date[2] != $y || $date[1] != $m) {\r
+                continue;\r
+            }\r
+            $days = $x->xpath("//day[@day=" . $date[0] . "]");\r
+            foreach ($days as $day) {\r
+                break;\r
+            }\r
+            $visitors = (string)$day['places'] * 1.2;\r
+            $visits = $visitors * 1.1;\r
+            cubeXML::removeAttribute($day, 'visitors');\r
+            cubeXML::removeAttribute($day, 'visits');\r
+            $day->addAttribute('visitors', $visitors);\r
+            $day->addAttribute('visits', $visits);\r
+        }\r
+    }\r
+\r
+    public static function correctPlaces($x)\r
+    {\r
+\r
+    }\r
+\r
+    public static function globalSort($xml, $root = 'stats')\r
+    {\r
+        $res = simplexml_load_string('<' . $root . ' />');\r
+        foreach ($xml->attributes() as $k => $v) {\r
+            $res->addAttribute($k, $v);\r
+        }\r
+        $years = array();\r
+        foreach ($xml->year as $year) {\r
+            $years[(string)$year['year']] = self::yearSort($year, 'year');\r
+        }\r
+        ksort($years);\r
+        foreach ($years as $y) {\r
+            cubeXML::append($res, $y);\r
+        }\r
+        return $res;\r
+    }\r
+\r
+    public static function yearSort($xml, $root = 'stats')\r
+    {\r
+        $res = simplexml_load_string('<' . $root . ' />');\r
+        foreach ($xml->attributes() as $k => $v) {\r
+            $res->addAttribute($k, $v);\r
+        }\r
+        $months = array();\r
+        foreach ($xml->month as $month) {\r
+            $months[(string)$month['month']] = $month;\r
+        }\r
+\r
+        ksort($months);\r
+        foreach ($months as $month) {\r
+            cubeXML::append($res, $month);\r
+        }\r
+\r
+        return $res;\r
+    }\r
+\r
+    public static function monthSort($xml, $root = 'stats')\r
+    {\r
+        $res = simplexml_load_string('<' . $root . ' />');\r
+        foreach ($xml->attributes() as $k => $v) {\r
+            $res->addAttribute($k, $v);\r
+        }\r
+        self::daysSort($xml, $res);\r
+        self::pagesSort($xml, $res);\r
+        self::linksSort($xml, $res);\r
+        self::searchesSort($xml, $res);\r
+        self::countriesSort($xml, $res);\r
+        return $res;\r
+    }\r
+\r
+    public static function daysSort($xml, $res)\r
+    {\r
+        $x = $res->addChild('days');\r
+        $days = array();\r
+        foreach ($xml->days->day as $day) {\r
+            $days[(string)$day['day']] = $day;\r
+        }\r
+        ksort($days);\r
+        foreach ($days as $day) {\r
+            $places = (string)$day['places'];\r
+            if ($places == 1) {\r
+                $visitors = (string)$day['visitors'];\r
+                if ($visitors > 10) {\r
+                    cubeXML::removeAttribute($day, 'places');\r
+                    $day->addAttribute('places', round($visitors * 0.99));\r
+                }\r
+            }\r
+            cubeXML::append($x, $day);\r
+        }\r
+    }\r
+\r
+    public static function pagesSort($xml, $res)\r
+    {\r
+        $xpages = $res->addChild('pages');\r
+        $pages = array();\r
+        $trans = array();\r
+        foreach ($xml->pages->page as $page) {\r
+            $pages[(string)$page['page']] = (string)$page['score'];\r
+            $trans[(string)$page['page']] = $page;\r
+        }\r
+        arsort($pages);\r
+        foreach ($pages as $num => $score) {\r
+            cubeXML::append($xpages, $trans[$num]);\r
+        }\r
+    }\r
+\r
+    public static function linksSort($xml, $res)\r
+    {\r
+        $x = $res->addChild('links');\r
+        $links = array();\r
+        $trans = array();\r
+        foreach ($xml->links->link as $link) {\r
+            $links[(string)$link['url']] = (string)$link['click'];\r
+            $trans[(string)$link['url']] = $link;\r
+        }\r
+        arsort($links);\r
+        $links = array_slice($links, 0, 100, true);\r
+        foreach ($links as $url => $click) {\r
+            cubeXML::append($x, $trans[$url]);\r
+        }\r
+    }\r
+\r
+    public static function searchesSort($xml, $res)\r
+    {\r
+        $x = $res->addChild('searches');\r
+        $searches = array();\r
+        $trans = array();\r
+        foreach ($xml->searches->search as $search) {\r
+            $searches[(string)$search['query']] = (string)$search['count'];\r
+            $trans[(string)$search['query']] = $search;\r
+        }\r
+        arsort($searches);\r
+        $searches = array_slice($searches, 0, 100, true);\r
+        foreach ($searches as $q => $count) {\r
+            cubeXML::append($x, $trans[$q]);\r
+        }\r
+    }\r
+\r
+    public static function countriesSort($xml, $res)\r
+    {\r
+        $x = $res->addChild('countries');\r
+        $countries = array();\r
+        $trans = array();\r
+        foreach ($xml->countries->country as $country) {\r
+            $countries[(string)$country['code']] = (string)$country['visitors'];\r
+            $trans[(string)$country['code']] = $country;\r
+        }\r
+        arsort($countries);\r
+        foreach ($countries as $code => $visitors) {\r
+            cubeXML::append($x, $trans[$code]);\r
+        }\r
+    }\r
+\r
+    public static function getActives($stats, $book, &$aextra, &$adown, &$adownp, &$aprint, &$afriend)\r
+    {\r
+        $extra = self::getExtra($book->extras);\r
+        $aextra = ($extra != null && $stats['extras'] > 0);\r
+        $adown = ($book->parametres->pdf == 1 && $stats['downloads'] > 0);\r
+        $adownp = ($book->parametres->pdf == 1 && $book->parametres->pdfComplex == 1 && $stats['partDownloads'] > 0);\r
+        $aprint = ($book->parametres->print == 1);\r
+        $afriend = ($book->parametres->friend == 1);\r
+    }\r
+\r
+    public static function table($title, $colsTitles, $lines, $class, $firstColMax = true, $firstLineBold = false, $noOdd = false)\r
+    {\r
+        global $core;\r
+        if (is_string($class)) {\r
+            $class = array($class);\r
+        }\r
+        $res = '<table class="' . implode(' ', $class) . '">';\r
+        // Titre\r
+        $res .= '<tr><th colspan="' . count($colsTitles) . '"><h1>' . $title . '</h1></th></tr>';\r
+        // Head\r
+        if (implode('', $colsTitles) != '') {\r
+            $res .= '<tr>';\r
+            foreach ($colsTitles as $i => $title) {\r
+                $max = ($firstColMax && $i == 0) ? '' : ' class="stats_col"';\r
+                $res .= '<th' . $max . '>' . $title . '</th>';\r
+            }\r
+            $res . '</tr>';\r
+        }\r
+        // Body\r
+        foreach ($lines as $i => $line) {\r
+            $odd = cubeMath::isOdd($i) ? ' class="odd"' : '';\r
+            if ($firstLineBold && $i == 0) {\r
+                $odd = ' class="odd"';\r
+            } elseif ($firstLineBold) {\r
+                $odd = '';\r
+            }\r
+            if ($noOdd) {\r
+                $odd = '';\r
+            }\r
+            $res .= '<tr' . $odd . '>';\r
+            foreach ($line as $j => $cell) {\r
+                $max = ($firstColMax && $j == 0) ? '' : ' class="stats_col"';\r
+                if ($firstLineBold && $i == 0) {\r
+                    $cell = '<strong>' . $cell . '</strong>';\r
+                }\r
+                $res .= '<td' . $max . '>' . $cell . '</td>';\r
+            }\r
+            $res .= '</tr>';\r
+        }\r
+\r
+        $res .= '</table>';\r
+\r
+        return $res;\r
+    }\r
+\r
+    /**\r
+     *\r
+     * @param string $name\r
+     * @return PHPExcel_Worksheet\r
+     */\r
+    protected static function _createSheet($name)\r
+    {\r
+        $s = self::$xls->createSheet();\r
+        $s->setTitle($name);\r
+        return $s;\r
+    }\r
+\r
+    public static function globalDatas($titre, $date_creation, $book, $stats, $afriend, $aprint, $adown, $adownp, $aextra)\r
+    {\r
+        global $xls;\r
+\r
+        $colsTitles = array('', '');\r
+        $lines = array();\r
+        $class = array('liste', 'max');\r
+\r
+        $lines[] = array($date_creation, date(__('d-m-Y'), $book->date));\r
+        //$lines[] = array(__('Nombre de lieux de visite'), $stats['places']);\r
+        $lines[] = array(__('Nombre de visiteurs uniques'), $stats['visitors']);\r
+        $lines[] = array(__('Nombre de visites'), $stats['visits']);\r
+        $lines[] = array(__('Nombre de pages vues'), $stats['pages']);\r
+        if ($afriend) {\r
+            $lines[] = array(__('Nombre de liens envoyés'), $stats['friends']);\r
+        }\r
+        $lines[] = array(__('Nombre de liens cliqués'), $stats['links']);\r
+        if ($aprint) {\r
+            $lines[] = array(__("Nombre d'impressions"), $stats['prints']);\r
+        }\r
+        if ($adown) {\r
+            $lines[] = array(__('Nombre de téléchargements'), $stats['downloads']);\r
+        }\r
+        if ($adownp) {\r
+            $lines[] = array(__('Nombre de téléchargements partiels'), $stats['partDownloads']);\r
+        }\r
+        if ($aextra) {\r
+            $lines[] = array(__('Accès à la rubrique') . ' ' . $extra, $stats['extras']);\r
+        }\r
+\r
+        self::setSheetFromDatas(__('Résumé'), null, $lines);\r
+\r
+        return self::table($titre, $colsTitles, $lines, $class);\r
+    }\r
+\r
+    public static function indisponible()\r
+    {\r
+        $res = commonPage::bh('stats_global');\r
+        $res .= '<p class="center">' . __('Les statistiques concernant cette période ne sont actuellement pas disponibles') . '</p>';\r
+        $res .= commonPage::bf();\r
+        return $res;\r
+    }\r
+\r
+    public static function getBook($bid)\r
+    {\r
+        global $core;\r
+        $daoBook = new wsDAOBook($core->con);\r
+        return $daoBook->selectById($bid);\r
+    }\r
+\r
+    public static function vue_globale($bid, $annee = null)\r
+    {\r
+        global $core;\r
+        $book = self::getBook($bid);\r
+        $extra = self::getExtra($book->extras);\r
+        if (is_null($annee)) {\r
+            $stats = self::load_stats($bid);\r
+        } else {\r
+            $stats = self::load_stats($bid, $annee);\r
+        }\r
+\r
+        if (is_null($stats)) {\r
+            return self::indisponible();\r
+        }\r
+\r
+        self::getActives($stats, $book, $aextra, $adown, $adownp, $aprint, $afriend);\r
+        $res = commonPage::bh('stats_global');\r
+        $titre = __('Statistiques de la publication « %s »');\r
+        $date_creation = __('Date de création de la publication');\r
+        $res .= self::globalDatas(sprintf($titre, $book->nom), $date_creation, $book, $stats, $afriend, $aprint, $adown, $adownp, $aextra);\r
+        $res .= commonPage::bf();\r
+        $res .= commonPage::bh();\r
+        $res .= '<table class="liste max">';\r
+        $res .= '<tr><th><h1>' . __('Détail par mois') . '</h1></th></tr>';\r
+        $res .= '<tr><th>';\r
+        $res .= '<div class="center" style="width:944px;margin:0 auto;position:relative;">';\r
+        if (is_null($annee)) {\r
+            $res .= self::graph_global($bid, $stats);\r
+        } else {\r
+            $res .= self::graph_annuel($bid, $annee, $stats);\r
+        }\r
+        $res .= '</div>';\r
+        $res .= '</th></tr>';\r
+        $res .= '</table>';\r
+        $res .= self::detailPeriode($book, $stats, $bid, $annee);\r
+        $res .= commonPage::bf();\r
+        return $res;\r
+    }\r
+\r
+    /**\r
+     * wsStats::vue_annuelle()\r
+     *\r
+     * @param mixed $bid\r
+     * @param mixed $annee\r
+     * @return\r
+     */\r
+    public static function vue_annuelle($bid, $annee)\r
+    {\r
+        return self::vue_globale($bid, $annee);\r
+    }\r
+\r
+    public static function vue_mensuelle($bid, $annee, $mois)\r
+    {\r
+        $datestocorrect = array(mktime(0, 0, 0, 11, 23, 2009), mktime(0, 0, 0, 12, 8, 2009), mktime(0, 0, 0, 12, 9, 2009));\r
+        global $core;\r
+        $book = self::getBook($bid);\r
+        $extra = self::getExtra($book->extras);\r
+        $stats = self::load_stats($bid, $annee, $mois);\r
+        if (is_null($stats)) {\r
+            return self::indisponible();\r
+        }\r
+\r
+        self::getActives($stats, $book, $aextra, $adown, $adownp, $aprint, $afriend);\r
+        $time_page = mktime(0, 0, 0, $mois, 15, $annee);\r
+        $res = commonPage::bh('stats_global');\r
+        $titre = __('Statistiques de la publication « %s »');\r
+        $date_creation = __('Date de création de la publication');\r
+        $res .= self::globalDatas(sprintf($titre, $book->nom), $date_creation, $book, $stats, $afriend, $aprint, $adown, $adownp, $aextra);\r
+        $res .= commonPage::bf();\r
+        // .\r
+        $res .= commonPage::bh('stats_detail_mois');\r
+        $res .= '<div class="center" style="width:944px;position:relative;">';\r
+        $res .= self::graph_mensuel($bid, $annee, $mois, $stats);\r
+        $res .= '</div>';\r
+        $res .= self::detailJour($book, $annee, $mois, $stats);\r
+        $res .= commonPage::bf();\r
+\r
+\r
+        // .\r
+        $res .= commonPage::bh('stats_detail_pages');\r
+        $res .= self::detailPages($book, $annee, $mois, $stats);\r
+        $res .= commonPage::bf();\r
+        // .\r
+        if ($book->parametres->search == 0) {\r
+            $idl = 'stats_links_2';\r
+            $idc = 'stats_country_2';\r
+        } else {\r
+            $idl = 'stats_links';\r
+            $idc = 'stats_country';\r
+        }\r
+\r
+        $res .= '<div id="stats_30">';\r
+        $res .= commonPage::bh($idl);\r
+        $res .= self::detailLiens($book, $stats);\r
+        $res .= commonPage::bf();\r
+        if ($book->parametres->search == 1) {\r
+            $res .= commonPage::bh('stats_search');\r
+            $res .= self::detailSearch($book, $stats);\r
+            $res .= commonPage::bf();\r
+        }\r
+        // Origine\r
+        $res .= commonPage::bh($idc);\r
+        $res .= self::detailOrigine($book, $stats);\r
+        $res .= commonPage::bf();\r
+        $res .= '</div>';\r
+        return $res;\r
+    }\r
+\r
+    public static function detailPeriode($book, $stats, $bid, $annee)\r
+    {\r
+        self::getActives($stats, $book, $aextra, $adown, $adownp, $aprint, $afriend);\r
+        $title = '';\r
+\r
+        $colsTitles = array(__('Période'), /*__('Lieux de visite'),*/\r
+            __('Visiteurs uniques'), __('Visites'), __('Pages vues'));\r
+        if ($afriend) {\r
+            $colsTitles[] = __('Liens envoyés');\r
+        }\r
+        $colsTitles[] = __('Liens cliqués');\r
+        if ($aprint) {\r
+            $colsTitles[] = __('Impressions');\r
+        }\r
+        if ($adown) {\r
+            $colsTitles[] = __('Téléchargements');\r
+        }\r
+        if ($adownp) {\r
+            $colsTitles[] = __('Téléchargements partiels');\r
+        }\r
+        if ($aextra) {\r
+            $colsTitles[] = $extra;\r
+        }\r
+\r
+        if (is_null($annee)) {\r
+            $years = $stats->year;\r
+        } else {\r
+            $years = array($stats);\r
+        }\r
+\r
+        $lines = array();\r
+        $noOdd = false;\r
+        foreach ($years as $year) {\r
+            if ($year['annee'] != null) {\r
+                $lines[] = self::linePeriod($year, $bid, $afriend, $aprint, $adown, $adownp, $aextra);\r
+            } else {\r
+                $noOdd = true;\r
+            }\r
+\r
+            foreach ($year->month as $month) {\r
+                $lines[] = self::linePeriod($month, $bid, $afriend, $aprint, $adown, $adownp, $aextra);\r
+            }\r
+        }\r
+\r
+        self::setSheetFromDatas(__('Détail'), $colsTitles, $lines);\r
+\r
+        return self::table($title, $colsTitles, $lines, array('max', 'liste'), true, false, $noOdd);\r
+    }\r
+\r
+    protected static function setSheetFromDatas($title, $columns, $lines)\r
+    {\r
+        $s = self::_createSheet($title);\r
+        $offset = 1;\r
+        if (!is_null($columns)) {\r
+            $offset = 2;\r
+            foreach ($columns as $k => $c) {\r
+\r
+                $s->setCellValueByColumnAndRow($k, 1, $c);\r
+                $s->getStyleByColumnAndRow($k, 1)->getFont()->setBold(true);\r
+\r
+                if ($k == 0) {\r
+                    $s->getStyleByColumnAndRow($k, 1)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);\r
+                } else {\r
+                    $s->getStyleByColumnAndRow($k, 1)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);\r
+                }\r
+            }\r
+        }\r
+        foreach ($lines as $k => $l) {\r
+            foreach ($l as $c => $v) {\r
+                $s->getColumnDimensionByColumn($c)->setAutoSize(true);\r
+                $s->setCellValueByColumnAndRow($c, $k + $offset, strip_tags($v));\r
+\r
+                if ($c == 0) {\r
+                    $s->getStyleByColumnAndRow($c, $k + $offset)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);\r
+                } else {\r
+                    $s->getStyleByColumnAndRow($c, $k + $offset)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    public static function linePeriod($stats, $bid, $afriend, $aprint, $adown, $adownp, $aextra)\r
+    {\r
+        $line = array();\r
+        $url = SITE_PATH . 'stats/' . $bid;\r
+        if (isset($stats['year'])) {\r
+            $url .= '/' . $stats['year'];\r
+            if (isset($stats['month'])) {\r
+                $url .= '/' . $stats['month'];\r
+                $date = strftime('%B %Y', mktime(0, 0, 0, (string)$stats['month'], 15, (string)$stats['year']));\r
+            } else {\r
+                $date = (string)$stats['year'];\r
+            }\r
+        }\r
+\r
+        $line[] = '<a href="' . $url . '">' . $date . '</a>';\r
+        //$line[] = $stats['places'];\r
+        $line[] = $stats['visitors'];\r
+        $line[] = $stats['visits'];\r
+        $line[] = $stats['pages'];\r
+        if ($afriend) {\r
+            $line[] = $stats['friends'];\r
+        }\r
+        $line[] = $stats['links'];\r
+        if ($aprint) {\r
+            $line[] = $stats['prints'];\r
+        }\r
+        if ($adown) {\r
+            $line[] = $stats['downloads'];\r
+        }\r
+        if ($adownp) {\r
+            $line[] = $stats['partDownloads'];\r
+        }\r
+        if ($aextra) {\r
+            $line[] = $stats['extras'];\r
+        }\r
+\r
+        return $line;\r
+    }\r
+\r
+    public static function detailJour($book, $annee, $mois, $stats)\r
+    {\r
+        $colsTitles = array(__('Jour'), /*__('Lieux de visite'),*/\r
+            __('Visiteurs uniques'), __('Visites'), __('Pages vues'), __('Liens cliqués'));\r
+        $lines = array();\r
+        $xlines = array();\r
+\r
+        foreach ($stats->days->day as $day) {\r
+            $lines[] = array(strftime('%A %d', mktime(0, 0, 0, $mois, (string)$day['day'], $annee)),\r
+                // $day['places'],\r
+                $day['visitors'],\r
+                $day['visits'],\r
+                $day['views'],\r
+                $day['links']);\r
+            $xlines[] = array(strftime('%d', mktime(0, 0, 0, $mois, (string)$day['day'], $annee)),\r
+                //$day['places'],\r
+                $day['visitors'],\r
+                $day['visits'],\r
+                $day['views'],\r
+                $day['links']);\r
+        }\r
+        $time_page = mktime(0, 0, 0, $mois, 15, $annee);\r
+\r
+        self::setSheetFromDatas(__('Jours'), $colsTitles, $xlines);\r
+\r
+        return self::table(__('Détail par jour') . ' - ' . strftime('%B %Y', $time_page), $colsTitles, $lines, array('liste', 'max'), true);\r
+    }\r
+\r
+    public static function detailPages($book, $annee, $mois, $stats)\r
+    {\r
+        $colsTitles = array(__('Pages'));\r
+        if ($book->parametres->stats_score) {\r
+            $colsTitles[] = __('Score');\r
+        }\r
+        $colsTitles[] = __('Vues');\r
+        $colsTitles[] = __('Zooms');\r
+        if ($book->parametres->bookmark) {\r
+            $colsTitles[] = __('Marques-pages');\r
+        }\r
+        if ($book->parametres->print) {\r
+            $colsTitles[] = __('Impressions');\r
+        }\r
+\r
+        $lines = array();\r
+        foreach ($stats->pages->page as $page) {\r
+            $p = (string)$page['page'];\r
+            if ($p > $book->pages || cubeMath::isOdd($p)) {\r
+                continue;\r
+            }\r
+            if ($p == 0) {\r
+                $pagen = '1';\r
+            } elseif ($p == $book->parametres->pages) {\r
+                $pagen = $p;\r
+            } else {\r
+                $pagen = $p;\r
+                $pagen .= '-';\r
+                $pagen .= ($p + 1);\r
+            }\r
+\r
+            $line = array($pagen);\r
+\r
+            if ($book->parametres->stats_score == 1) {\r
+                $line[] = $page['score'];\r
+            }\r
+            $line[] = $page['views'];\r
+            $line[] = $page['zooms'];\r
+\r
+            if ($book->parametres->bookmark == 1) {\r
+                $line[] = $page['bookmarks'];\r
+            }\r
+            if ($book->parametres->print == 1) {\r
+                $line[] = $page['prints'];\r
+            }\r
+            $lines[] = $line;\r
+        }\r
+        $time_page = mktime(0, 0, 0, $mois, 15, $annee);\r
+\r
+        self::setSheetFromDatas(__('Pages'), $colsTitles, $lines);\r
+\r
+        return self::table(__('Détail par page') . ' - ' . strftime('%B %Y', $time_page), $colsTitles, $lines, array('liste', 'max'));\r
+    }\r
+\r
+    public static function detailLiens($book, $stats)\r
+    {\r
+        $colsTitles = array(__('URL'), __('Clics'));\r
+        $lines = array();\r
+        $xlines = array();\r
+\r
+        foreach ($stats->links->link as $link) {\r
+            $uurl = (string)$link['url'];\r
+            $nb = (string)$link['click'];\r
+            if (stristr($uurl, 'mailto:') || stristr($uurl, 'http://') || stristr($uurl, 'https://')) {\r
+                $url = substr($uurl, 7);\r
+            } else {\r
+                $url = $uurl;\r
+            }\r
+            if (strlen($url) > 30) {\r
+                $url = substr($url, 0, 30) . '...';\r
+            }\r
+\r
+            $lines[] = array('<a href="' . $uurl . '" class="blank" title="' . $uurl . '">' . $url . '</a>', $nb);\r
+            $xlines[] = array($uurl, $nb);\r
+        }\r
+\r
+        self::setSheetFromDatas(__('Liens'), $colsTitles, $xlines);\r
+        return self::table(__('Liens les plus cliqués'), $colsTitles, $lines, array('liste', 'max'));\r
+    }\r
+\r
+    public static function detailSearch($book, $stats)\r
+    {\r
+        $colsTitles = array(__('Mot'), __('Recherches'));\r
+        $lines = array();\r
+\r
+        foreach ($stats->searches->search as $search) {\r
+            $q = $search['query'];\r
+            if (strlen($q) > 25) {\r
+                $q = '<abbr title="' . $q . '">' . substr($q, 0, 25) . ' ...</abbr>';\r
+            }\r
+            $lines[] = array($q, $search['count']);\r
+        }\r
+        self::setSheetFromDatas(__('Recherches'), $colsTitles, $lines);\r
+        return self::table(__('Mots les plus recherchés'), $colsTitles, $lines, array('liste', 'max'));\r
+    }\r
+\r
+    public static function detailOrigine($book, $stats)\r
+    {\r
+        $colsTitles = array(__('Pays'), __('Visiteurs'));\r
+        $lines = array();\r
+        $xlines = array();\r
+        $i = 0;\r
+\r
+        foreach ($stats->countries->country as $country) {\r
+            $pays = $country['code'];\r
+            $odd = cubeMath::isOdd($i) ? ' class="odd"' : '';\r
+            if (!$c = cubeCountry::getCountry($pays)) {\r
+                $c = __('Origine inconnue');\r
+            }\r
+            $lines[] = array(cubeCountry::getFlag($pays) . ' ' . ucfirst(mb_strtolower($c)), $country['visitors']);\r
+            $xlines[] = array(ucfirst(mb_strtolower($c)), $country['visitors']);\r
+            $i++;\r
+        }\r
+        self::setSheetFromDatas(__('Origines'), $colsTitles, $xlines);\r
+        return self::table(__('Origine des visiteurs'), $colsTitles, $lines, array('liste', 'max'));\r
+    }\r
+\r
+    public static function getQ($max, &$maxp, &$maxpages, &$s)\r
+    {\r
+        $maxpages = $maxp;\r
+        $q = 1;\r
+        $maxp /= $q;\r
+        $maxp = max($max * 4, $maxp);\r
+        $q = $maxpages / $maxp;\r
+        foreach ($s as $time => $t) {\r
+            $s[$time]['page'] = intval($s[$time]['page'] / $q);\r
+        }\r
+    }\r
+\r
+    public static function graph_annuel($bid, $a, $stats)\r
+    {\r
+        $img = SYSIMG . '/stats/annuel-' . $a . '-' . $bid . '.png';\r
+        $imgw = IMG . '/stats/annuel-' . $a . '-' . $bid . '.png';\r
+        $maxv = 0;\r
+        $maxp = 0;\r
+        $maxb = 0;\r
+        $s = array();\r
+        foreach ($stats->month as $month) {\r
+            $maxb = max($maxb, (string)$month['visits']);\r
+            $maxp = max($maxp, (string)$month['pages']);\r
+            $maxv = max($maxv, (string)$month['visitors']);\r
+            $time = cubeDate::round(mktime(0, 0, 0, (string)$month['month'], 15, (string)$month['year']), 'm');\r
+            $s[$time] = array();\r
+            $s[$time]['book'] = (string)$month['visits'];\r
+            $s[$time]['page'] = (string)$month['pages'];\r
+            $s[$time]['visit'] = (string)$month['visitors'];\r
+        }\r
+        // .\r
+        $max = max($maxb, $maxv);\r
+        self::getQ($max, $maxp, $maxpages, $s);\r
+        krsort($s);\r
+        $max = max($maxb, $maxv, $maxp);\r
+        $months = cubeDate::getMonths($a);\r
+        @unlink($img);\r
+        if (!file_exists($img) || filemtime($img) < cubeDate::round(null, 'H')) {\r
+            $im = imagecreatetruecolor(944, 306);\r
+            //imagelayereffect($im, IMG_EFFECT_REPLACE);\r
+            $trans = imagecolorallocatealpha($im, 255, 255, 255, 0);\r
+            imagefill($im, 0, 0, $trans);\r
+            //imagelayereffect($im, IMG_EFFECT_ALPHABLEND);\r
+            $i = 1;\r
+            $x0 = 0;\r
+            $y0 = 305;\r
+            $h = 300;\r
+            $c0 = imagecolorallocate($im, 0, 0, 0);\r
+            $c1 = imagecolorallocatealpha($im, 81, 78, 73, 64);\r
+            $hp = $h * ($maxp / $max) - 2;\r
+            $mhp = $y0 - $hp - 6;\r
+            imagesetstyle($im, array($c1, $c1, $c1, $c1, $c1, $trans, $trans, $trans, $trans));\r
+            imageline($im, 0, $y0 - $hp, 944, $y0 - $hp, IMG_COLOR_STYLED);\r
+            $c1 = imagecolorallocate($im, 81, 78, 73);\r
+            $c2 = imagecolorallocatealpha($im, 245, 77, 0, 64);\r
+            $hb = $h * ($maxb / $max) - 1;\r
+            $mhb = $y0 - $hb - 6;\r
+            imagesetstyle($im, array($c2, $c2, $c2, $c2, $c2, $trans, $trans, $trans, $trans));\r
+            imageline($im, 0, $y0 - $hb, 944, $y0 - $hb, IMG_COLOR_STYLED);\r
+            $c2 = imagecolorallocate($im, 245, 77, 0);\r
+            $c3 = imagecolorallocatealpha($im, 194, 211, 19, 32);\r
+            $hv = $h * ($maxv / $max);\r
+            $mhv = $y0 - $hv - 6;\r
+            imagesetstyle($im, array($c3, $c3, $c3, $c3, $c3, $trans, $trans, $trans, $trans));\r
+            imageline($im, 0, $y0 - $hv, 944, $y0 - $hv, IMG_COLOR_STYLED);\r
+            $c3 = imagecolorallocate($im, 194, 211, 19);\r
+            foreach ($months as $m => $t) {\r
+                if (isset($s[$t])) {\r
+                    $x0 += 15;\r
+                    $hp = $h * ($s[$t]['page'] / $max) - 2;\r
+                    $hb = $h * ($s[$t]['book'] / $max) - 1;\r
+                    $hv = $h * ($s[$t]['visit'] / $max);\r
+                    imagefilledrectangle($im, $x0 + 40, $y0 - $hp, $x0, $y0, $c1);\r
+                    imagerectangle($im, $x0 + 40, $y0 - $hp, $x0, $y0, $c0);\r
+                    $x0 += 5;\r
+                    imagefilledrectangle($im, $x0 + 40, $y0 - $hb, $x0, $y0, $c2);\r
+                    imagerectangle($im, $x0 + 40, $y0 - $hb, $x0, $y0, $c0);\r
+                    $x0 += 5;\r
+                    imagefilledrectangle($im, $x0 + 40, $y0 - $hv, $x0, $y0, $c3);\r
+                    imagerectangle($im, $x0 + 40, $y0 - $hv, $x0, $y0, $c0);\r
+                    $i++;\r
+                    $x0 += 50;\r
+                } else {\r
+                    $x0 += 75;\r
+                }\r
+            }\r
+\r
+            imageline($im, 0, $y0, 944, $y0, $c0);\r
+            imagepng($im, $img);\r
+        }\r
+        $res = '<div class="graphStats"><div class="graph-note" style="top:' . $mhp . 'px;color:#514e49;">' . $maxpages . '</div>';\r
+        $res .= '<div class="graph-note" style="top:' . $mhb . 'px;color:#f54d00;">' . $maxb . '</div>';\r
+        $res .= '<div class="graph-note" style="top:' . $mhv . 'px;color:#c2d313;">' . $maxv . '</div>';\r
+        $res .= '<div class="graph-container" style="background:url(' . $imgw . ')"></div>';\r
+        $res .= '<table style="width:944px;max-width:944px;table-layout:fixed;" class="echelle"><tr>';\r
+        foreach ($months as $m => $t) {\r
+            $res .= '<td style="width:75px;max-width:75px;">' . strftime('%b %y', $t) . '</td>';\r
+        }\r
+        $res .= '<td style="width:44px;">' . cubeMedia::spacer(44, 20) . '</td>';\r
+        $res .= '</tr></table>';\r
+        $res .= '<table class="legende" style="margin-top:10px;margin-bottom:10px;"><tr>';\r
+        $res .= '<td style="width:12px;background:#514e49;height:12px;"></td><td style="width:10px;"></td><td>' . __('Pages vues') . '</td><td style="width:10px;"></td>';\r
+        $res .= '<td style="width:12px;background:#f54d00;height:12px;"></td><td style="width:10px;"></td><td>' . __('Visites') . '</td><td style="width:10px;"></td>';\r
+        $res .= '<td style="width:12px;background:#c2d313;height:12px;"></td><td style="width:10px;"></td><td>' . __('Visiteurs uniques') . '</td><td style="width:10px;"></td>';\r
+        $res .= '</tr></table></div>';\r
+        return $res;\r
+    }\r
+\r
+    public static function graph_global($bid, $stats)\r
+    {\r
+        global $core;\r
+        $img = SYSIMG . '/stats/global-' . $bid . '.png';\r
+        $imgw = IMG . '/stats/global-' . $bid . '.png';\r
+        $s = array();\r
+        foreach ($stats->year as $year) {\r
+            foreach ($year->month as $month) {\r
+                $time = mktime(0, 0, 0, intval((string)$month['month']), 15, (string)$month['year']);\r
+                $s[$time]['book'] = $month['visits'];\r
+                $s[$time]['page'] = $month['pages'];\r
+                $s[$time]['time'] = $time;\r
+                $s[$time]['visit'] = $month['visitors'];\r
+            }\r
+        }\r
+\r
+        krsort($s);\r
+        $s = array_slice($s, 0, 12, true);\r
+        $maxv = 0;\r
+        $maxp = 0;\r
+        $maxb = 0;\r
+        foreach ($s as $time => $d) {\r
+            $maxb = max($maxb, (string)$d['book']);\r
+            $maxp = max($maxp, (string)$d['page']);\r
+            $maxv = max($maxv, (string)$d['visit']);\r
+        }\r
+\r
+        $max = max($maxb, $maxv);\r
+        self::getQ($max, $maxp, $maxpages, $s);\r
+        $max = max($maxv, $maxb, $maxp, 1);\r
+        if (file_exists($img)) {\r
+            unlink($img);\r
+        }\r
+        if (!file_exists($img) || filemtime($img) < cubeDate::round(null, 'H')) {\r
+            $im = imagecreatetruecolor(944, 306);\r
+            //imagelayereffect($im, IMG_EFFECT_REPLACE);\r
+            $trans = imagecolorallocatealpha($im, 255, 255, 255, 0);\r
+            imagefill($im, 0, 0, $trans);\r
+            //imagelayereffect($im, IMG_EFFECT_ALPHABLEND);\r
+            $i = 1;\r
+            $x0 = 900;\r
+            $y0 = 305;\r
+            $h = 300;\r
+            $c0 = imagecolorallocate($im, 0, 0, 0);\r
+            $c1 = imagecolorallocatealpha($im, 81, 78, 73, 64);\r
+            $hp = $h * ($maxp / $max) - 2;\r
+            $mhp = $y0 - $hp - 6;\r
+            imagesetstyle($im, array($c1, $c1, $c1, $c1, $c1, $trans, $trans, $trans, $trans));\r
+            imageline($im, 0, $y0 - $hp, 944, $y0 - $hp, IMG_COLOR_STYLED);\r
+            $c1 = imagecolorallocate($im, 81, 78, 73);\r
+            $c2 = imagecolorallocatealpha($im, 245, 77, 0, 64);\r
+            $hb = $h * ($maxb / $max) - 1;\r
+            $mhb = $y0 - $hb - 6;\r
+            imagesetstyle($im, array($c2, $c2, $c2, $c2, $c2, $trans, $trans, $trans, $trans));\r
+            imageline($im, 0, $y0 - $hb, 944, $y0 - $hb, IMG_COLOR_STYLED);\r
+            $c2 = imagecolorallocate($im, 245, 77, 0);\r
+            $c3 = imagecolorallocatealpha($im, 194, 211, 19, 32);\r
+            $hv = $h * ($maxv / $max);\r
+            $mhv = $y0 - $hv - 6;\r
+            imagesetstyle($im, array($c3, $c3, $c3, $c3, $c3, $trans, $trans, $trans, $trans));\r
+            imageline($im, 0, $y0 - $hv, 944, $y0 - $hv, IMG_COLOR_STYLED);\r
+            $c3 = imagecolorallocate($im, 194, 211, 19);\r
+            foreach ($s as $t) {\r
+                $x0 -= 15;\r
+                $hp = $h * ($t['page'] / $max) - 2;\r
+                $hb = $h * ($t['book'] / $max) - 1;\r
+                $hv = $h * ($t['visit'] / $max);\r
+                imagefilledrectangle($im, $x0 - 40, $y0 - $hp, $x0, $y0, $c1);\r
+                imagerectangle($im, $x0 - 40, $y0 - $hp, $x0, $y0, $c0);\r
+                $x0 -= 5;\r
+                imagefilledrectangle($im, $x0 - 40, $y0 - $hb, $x0, $y0, $c2);\r
+                imagerectangle($im, $x0 - 40, $y0 - $hb, $x0, $y0, $c0);\r
+                $x0 -= 5;\r
+                imagefilledrectangle($im, $x0 - 40, $y0 - $hv, $x0, $y0, $c3);\r
+                imagerectangle($im, $x0 - 40, $y0 - $hv, $x0, $y0, $c0);\r
+                $i++;\r
+                $x0 -= 50;\r
+            }\r
+\r
+            imageline($im, 0, $y0, 944, $y0, $c0);\r
+            imagepng($im, $img);\r
+        }\r
+        $res = '<div class="graphStats"><div class="graph-note" style="top:' . $mhp . 'px;color:#514e49;">' . $maxpages . '</div>';\r
+        $res .= '<div class="graph-note" style="top:' . $mhb . 'px;color:#f54d00">' . $maxb . '</div>';\r
+        $res .= '<div  class="graph-note" style="top:' . $mhv . 'px;color:#c2d313;">' . $maxv . '</div>';\r
+        $res .= '<div class="graph-container" style="background:url(' . $imgw . ')"></div>';\r
+        $s = array_reverse(array_pad($s, 12, false), true);\r
+        $res .= '<table style="width:944px;max-width:944px;" class="echelle"><tr>';\r
+        foreach ($s as $time => $val) {\r
+            if (!$val) {\r
+                $res .= '<td style="width:75px;max-width:75px;">' . cubeMedia::spacer(75, 20) . '</td>';\r
+            } else {\r
+                $res .= '<td style="width:75px;max-width:75px;">' . strftime('%b %y', $val['time']) . '</td>';\r
+            }\r
+        }\r
+        $res .= '<td style="width:44px;">' . cubeMedia::spacer(44, 20) . '</td>';\r
+        $res .= '</tr></table>';\r
+        $res .= '<table class="legende"><tr>';\r
+        $res .= '<td style="width:12px;background:#514e49;height:12px;"></td><td style="width:10px;"></td><td>' . __('Pages vues') . '</td><td style="width:10px;"></td>';\r
+        $res .= '<td style="width:12px;background:#f54d00;height:12px;"></td><td style="width:10px;"></td><td>' . __('Visites') . '</td><td style="width:10px;"></td>';\r
+        $res .= '<td style="width:12px;background:#c2d313;height:12px;"></td><td style="width:10px;"></td><td>' . __('Visiteurs uniques') . '</td><td style="width:10px;"></td>';\r
+        $res .= '</tr></table></div>';\r
+        return $res;\r
+    }\r
+\r
+    public static function graph_mensuel($bid, $a, $m, $stats)\r
+    {\r
+        $img = SYSIMG . '/stats/mensuel-' . $a . '-' . $m . '-' . $bid . '.png';\r
+        $imgw = IMG . '/stats/mensuel-' . $a . '-' . $m . '-' . $bid . '.png';\r
+        $lm = cubeDate::limitMonth($a, $m);\r
+        $datestocorrect = array(mktime(0, 0, 0, 11, 23, 2009), mktime(0, 0, 0, 12, 8, 2009), mktime(0, 0, 0, 12, 9, 2009));\r
+        $maxv = 0;\r
+        $maxp = 0;\r
+        $maxb = 0;\r
+        $v = array();\r
+        $s = array();\r
+        foreach ($stats->days->day as $day) {\r
+            $time = mktime(0, 0, 0, $m, (string)$day['day'], $a);\r
+            $maxb = max($maxb, (string)$day['visits']);\r
+            $maxp = max($maxp, (string)$day['views']);\r
+            $maxv = max($maxv, (string)$day['visitors']);\r
+            $s[$time]['book'] = $day['visits'];\r
+            $s[$time]['page'] = $day['views'];\r
+            $s[$time]['visit'] = $day['visitors'];\r
+            $s[$time]['time'] = $time;\r
+        }\r
+        $max = max($maxb, $maxv);\r
+        self::getQ($max, $maxp, $maxpages, $s);\r
+        krsort($s);\r
+        $max = max($maxv, $maxb, $maxp);\r
+        $days = cubeDate::getDays($a, $m);\r
+        $space = round((900 - (count($days) * 20)) / (count($days) * 2));\r
+        @unlink($img);\r
+        if (!file_exists($img) || filemtime($img) < cubeDate::round(null, 'H')) {\r
+            // Création de l'image\r
+            $im = imagecreatetruecolor(944, 306);\r
+            //imagelayereffect($im, IMG_EFFECT_REPLACE);\r
+            $trans = imagecolorallocatealpha($im, 255, 255, 255, 0);\r
+            imagefill($im, 0, 0, $trans);\r
+            //imagelayereffect($im, IMG_EFFECT_ALPHABLEND);\r
+            $i = 1;\r
+            $x0 = 0;\r
+            $y0 = 305;\r
+            $h = 300;\r
+            $c0 = imagecolorallocate($im, 0, 0, 0);\r
+            $c1 = imagecolorallocatealpha($im, 81, 78, 73, 64);\r
+            $hp = $h * ($maxp / $max) - 2;\r
+            $mhp = $y0 - $hp - 6;\r
+            imagesetstyle($im, array($c1, $c1, $c1, $c1, $c1, $trans, $trans, $trans, $trans));\r
+            imageline($im, 0, $y0 - $hp, 944, $y0 - $hp, IMG_COLOR_STYLED);\r
+            $c1 = imagecolorallocate($im, 81, 78, 73);\r
+            $c2 = imagecolorallocatealpha($im, 245, 77, 0, 64);\r
+            $hb = $h * ($maxb / $max) - 1;\r
+            $mhb = $y0 - $hb - 6;\r
+            imagesetstyle($im, array($c2, $c2, $c2, $c2, $c2, $trans, $trans, $trans, $trans));\r
+            imageline($im, 0, $y0 - $hb, 944, $y0 - $hb, IMG_COLOR_STYLED);\r
+            $c2 = imagecolorallocate($im, 245, 77, 0);\r
+            $c3 = imagecolorallocatealpha($im, 194, 211, 19, 32);\r
+            $hv = $h * ($maxv / $max);\r
+            $mhv = $y0 - $hv - 6;\r
+            imagesetstyle($im, array($c3, $c3, $c3, $c3, $c3, $trans, $trans, $trans, $trans));\r
+            imageline($im, 0, $y0 - $hv, 944, $y0 - $hv, IMG_COLOR_STYLED);\r
+            $c3 = imagecolorallocate($im, 194, 211, 19);\r
+            foreach ($days as $d => $t) {\r
+                if (isset($s[$t])) {\r
+                    $x0 += $space;\r
+                    $hp = $h * ($s[$t]['page'] / $max) - 2;\r
+                    $hb = $h * ($s[$t]['book'] / $max) - 1;\r
+                    $hv = $h * ($s[$t]['visit'] / $max);\r
+                    imagefilledrectangle($im, $x0 + 14, $y0 - $hp, $x0, $y0, $c1);\r
+                    imagerectangle($im, $x0 + 14, $y0 - $hp, $x0, $y0, $c0);\r
+                    $x0 += 3;\r
+                    imagefilledrectangle($im, $x0 + 14, $y0 - $hb, $x0, $y0, $c2);\r
+                    imagerectangle($im, $x0 + 14, $y0 - $hb, $x0, $y0, $c0);\r
+                    $x0 += 3;\r
+                    imagefilledrectangle($im, $x0 + 14, $y0 - $hv, $x0, $y0, $c3);\r
+                    imagerectangle($im, $x0 + 14, $y0 - $hv, $x0, $y0, $c0);\r
+                    $i++;\r
+                    $x0 += 14 + $space;\r
+                } else {\r
+                    $x0 += 20 + $space * 2;\r
+                }\r
+            }\r
+\r
+            imageline($im, 0, $y0, 944, $y0, $c0);\r
+            imagepng($im, $img);\r
+        }\r
+        $res = '<div class="graphStats"><div class="graph-note" style="top:' . $mhp . 'px;color:#514e49;">' . $maxpages . '</div>';\r
+        $res .= '<div class="graph-note" style="top:' . $mhb . 'px;color:#f54d00;">' . $maxb . '</div>';\r
+        $res .= '<div class="graph-note" style="top:' . $mhv . 'px;color:#c2d313;">' . $maxv . '</div>';\r
+        $res .= '<div class="graph-container" style="background:url(' . $imgw . ')"></div>';\r
+        $res .= '<table style="width:944px;max-width:944px;margin:0px;table-layout:fixed;" class="echelle"><tr>';\r
+        foreach ($days as $d => $t) {\r
+            $res .= '<td style="width:' . (20 + $space * 2) . 'px;max-width:' . (20 + $space * 2) . 'px;text-align:center;">' . $d . '</td>';\r
+        }\r
+        $spacef = 944 - (count($days) * (20 + ($space * 2)));\r
+        $res .= '<td style="width:' . $spacef . 'px;">' . cubeMedia::spacer($spacef, 20) . '</td>';\r
+        $res .= '</tr></table>';\r
+        $res .= '<table style="margin-top:10px;margin-bottom:10px;" class="legende"><tr>';\r
+        $res .= '<td style="width:12px;background:#514e49;height:12px;"></td><td style="width:10px;"></td><td>' . __('Pages vues') . '</td><td style="width:10px;"></td>';\r
+        $res .= '<td style="width:12px;background:#f54d00;height:12px;"></td><td style="width:10px;"></td><td>' . __('Visites') . '</td><td style="width:10px;"></td>';\r
+        $res .= '<td style="width:12px;background:#c2d313;height:12px;"></td><td style="width:10px;"></td><td>' . __('Visiteurs uniques') . '</td><td style="width:10px;"></td>';\r
+        $res .= '</tr></table></div>';\r
+        return $res;\r
+    }\r
+\r
+    public static function forceComputation($id)\r
+    {\r
+        `/home/stats/www/FWStats.sh /home/stats/www onlybook=$id`;\r
+    }\r
 }
\ No newline at end of file