vendor/theatre/core/src/Classes/Stats/Stats.php line 489

Open in your IDE?
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 ff=unix fenc=utf8: */
  3. /**
  4.  * Classe de gestion des stats
  5.  *
  6.  * PHP version 5
  7.  *
  8.  * LICENSE: Ce programme est un logiciel libre distribué sous licence GNU/GPL
  9.  *
  10.  * @author     Yves Tannier <yves@grafactory.net>
  11.  * @copyright  2006 Yves Tannier
  12.  * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
  13.  * @version    0.1.0
  14.  * @link       http://www.grafactory.net
  15.  */
  16. /**
  17.  * Appel de la classe abstraite Theatre
  18.  *
  19.  */
  20. namespace TheatreCore\Classes\Stats;
  21. use App\Service\IdCookie;
  22. use TheatreCore\Traits\TheatreTrait;
  23. use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
  24. use Doctrine\Persistence\ManagerRegistry;
  25. use Doctrine\ORM\EntityManagerInterface;
  26. class Stats extends ServiceEntityRepository
  27. {
  28.     use TheatreTrait;
  29.     // la base statistiques
  30.     private $stats_base 'statistiques';
  31.     public function __construct(ManagerRegistry $registryEntityManagerInterface $em)
  32.     {
  33.         parent::__construct($registry, \TheatreCore\Entity\Stats::class);
  34.         $this->em $em;
  35.     }
  36.     /** Enregistre une stats
  37.      *
  38.      * Enregistre une stats dans la table correspondante
  39.      *
  40.      * @access  public
  41.      * @return  string
  42.      */
  43.     public function log($table$values)
  44.     {
  45.         // verification de la clé pour prévention flood
  46. //        if ($_GET['key'] != md5($_ENV['URL_THTV'].date('Ymd'))) return;
  47.         // logguer le cookie de session (2h)
  48.         if (!empty($_COOKIE['stats'])) {
  49.             $values['cookie_visitor'] = preg_replace('/[^a-zA-Z0-9\-]/'''$_COOKIE['stats']);
  50.         } else {
  51.             // créer le cookie si n'exste pas
  52.             $idcookie = new IdCookie('stats');
  53.             $uniqid $idcookie->get(60); /* 1 heures */
  54.             $values['cookie_visitor'] = $uniqid;
  55.         }
  56.         // table de stats de la journée
  57.         $table $table '_' date('Ymd');
  58.         // on vérifie que la table de la journée existe, sinon, on la crée
  59.         // les valeurs
  60.         foreach ($values as $k => $v) {
  61.             $keys_tab[] = $k;
  62.             $values_tab[] = '\'' $v '\'';
  63.         }
  64.         // clé unique id + cookie
  65.         $res $this->execute('INSERT IGNORE INTO ' $this->stats_base '.' $table ' (' join(','$keys_tab) . ') VALUES (' join(','$values_tab) . ')');
  66.         // si erreur, continuer l'exécution mais le loguer
  67.         if (empty($res)) {
  68.             //$this->logError('Impossible d\'enregistrer la statistique');
  69.             error_log('Impossible d\'enregistrer la stats');
  70.             $res 0;
  71.         }
  72.         return $res;
  73.     }
  74.     // }}}
  75.     //  {{{ createStatsTable()
  76.     /** Créer les tables de stats
  77.      *
  78.      * Enregistre une stats dans la table correspondante
  79.      *
  80.      * @access  public
  81.      * @return  string
  82.      */
  83.     public function createStatsTable($table$type_table 'daily'$date_stats null)
  84.     {
  85.         // la date de demain
  86.         if (empty($date_stats)) {
  87.             $date_stats date('Ymd'strtotime('+1 day'));
  88.         }
  89.         // creation
  90.         $create 'CREATE TABLE IF NOT EXISTS ' $this->stats_base '.`' $table '_' $date_stats '` (
  91.           `idmultimedia` int(11) unsigned NOT NULL,
  92.           `module` varchar(10) NOT NULL,
  93.           `time_view` timestamp NOT NULL default CURRENT_TIMESTAMP,
  94.           `cookie_visitor` varchar(50) NOT NULL,
  95.           PRIMARY KEY  (`idmultimedia`,`cookie_visitor`)
  96.         ) ENGINE=InnoDB DEFAULT CHARSET=utf8;';
  97.         // création
  98.         $this->execute($create);
  99.     }
  100.     // }}}
  101.     //  {{{ getTableDays()
  102.     /** Récupère la liste des tables de stats
  103.      *
  104.      * récupère la liste des tables de stats et filtre par type de stats
  105.      *
  106.      * @access  public
  107.      * @param string $type_table Type de table (ex : multimedias)
  108.      * @return  array
  109.      */
  110.     public function getTableDays($type_table$params = array())
  111.     {
  112.         $this->loadModule('Manager');
  113.         $tables $this->listTables($this->stats_base);
  114.         foreach ($tables as $t) {
  115.             if (preg_match('/' $type_table '_([0-9]+)/'$t$match)) {
  116.                 if (!empty($params['date_start']) && !empty($params['date_end'])) {
  117.                     if ($match[1] >= $params['date_start'] && $match[1] <= $params['date_end']) {
  118.                         $tables_tab[$match[1]] = array(
  119.                             'table' => $match[0],
  120.                             'date' => $match[1],
  121.                         );
  122.                     }
  123.                 } else {
  124.                     $tables_tab[$match[1]] = array(
  125.                         'table' => $match[0],
  126.                         'date' => $match[1],
  127.                     );
  128.                 }
  129.             }
  130.         }
  131.         return $tables_tab;
  132.     }
  133.     // }}}
  134.     //  {{{ getStatsByDays()
  135.     /** Récupère les stats de vues par jour
  136.      *
  137.      * récupère les stats de vues par jour avec différentes valeurs
  138.      *
  139.      * @access  public
  140.      * @param string $type_table Type de table (ex : multimedias)
  141.      * @return  array
  142.      */
  143.     public function getStatsByDays($type_table$params = array())
  144.     {
  145.         // liste des tables
  146.         $tables $this->getTableDays($type_table$params);
  147.         //setDebug(print_r($tables, true));
  148.         // on compte le total pour chaque jour et l'id de la vidéo la plus vues
  149.         foreach ($tables as $d => $t) {
  150.             // on souhaite une recherche par objet
  151.             if (!empty($params['object']) && !empty($params['idobject'])) {
  152.                 // joindre avec multimedias
  153.                 $sql 'SELECT COUNT(' $this->stats_base '.' $t['table'] . '.`idmultimedia`) 
  154.                         FROM ' $this->stats_base '.' $t['table'] . '
  155.                         JOIN ' $_ENV['TH_BDD'] . '.object_multimedia ON ' $this->stats_base '.' $t['table'] . '.`idmultimedia`= ' $_ENV['TH_BDD'] . '.object_multimedia.`idmultimedia` ';
  156.                 $sql .= ' WHERE ' $_ENV['TH_BDD'] . '.object_multimedia.`idobject`=' . (int)$params['idobject'] . '
  157.                           AND ' $_ENV['TH_BDD'] . '.object_multimedia.`object`=\'' $params['object'] . '\' ';
  158.             } else {
  159.                 $sql 'SELECT COUNT(idmultimedia) FROM ' $this->stats_base '.' $t['table'] . ' ';
  160.             }
  161.             $nb $this->queryOne($sql);
  162.             $stats_tab[$d] = array(
  163.                 'day' => $d,
  164.                 'day_string' => $this->getFormeDate($d'%a %d %B %Y'true),
  165.                 'day_short_string' => $this->getFormeDate($d' %d/%m/%Y'true),
  166.                 'views' => $nb,
  167.                 'most_view' => $this->getBestView($type_table'day'$d1$params),
  168.             );
  169.         }
  170.         return $stats_tab;
  171.     }
  172.     // }}}
  173.     //  {{{ getDailyMostViewed()
  174.     /** Récupère les stats de vues par jour
  175.      *
  176.      * récupère les stats de vues par jour avec différentes valeurs
  177.      *
  178.      * @access  public
  179.      * @param string $type_table Type de table (ex : multimedias)
  180.      * @return  array
  181.      */
  182.     public function getDailyMostViewed($type_table$day$nb_viewed 10$params = array())
  183.     {
  184.         // on compte le total pour chaque jour et l'id de la vidéo la plus vues
  185.         $table $this->stats_base '.' $type_table '_' $day;
  186.         // on souhaite une recherche par objet
  187.         if (!empty($params['object']) && !empty($params['idobject'])) {
  188.             // joindre avec multimedias
  189.             $sql 'SELECT COUNT(' $table '.`idmultimedia`) 
  190.                     FROM ' $table '
  191.                     JOIN ' $_ENV['TH_BDD'] . '.object_multimedia ON ' $table '.`idmultimedia`= ' $_ENV['TH_BDD'] . '.object_multimedia.`idmultimedia`
  192.                     WHERE ' $_ENV['TH_BDD'] . '.object_multimedia.`idobject`=' . (int)$params['idobject'] . '
  193.                     AND ' $_ENV['TH_BDD'] . '.object_multimedia.`object`=\'' $params['object'] . '\' ';
  194.         } else {
  195.             $sql 'SELECT COUNT(' $table '.`idmultimedia`) FROM ' $table ' ';
  196.         }
  197.         $nb $this->queryOne($sql);
  198.         $stats_tab = array(
  199.             'day' => $day,
  200.             'day_string' => $this->getFormeDate($day'%a %d %B %Y'true),
  201.             'day_short_string' => $this->getFormeDate($day' %d/%m/%Y'true),
  202.             'views' => $nb,
  203.             'most_view' => $this->getBestView($type_table'day'$day$nb_viewed$params),
  204.         );
  205.         return $stats_tab;
  206.     }
  207.     // }}}
  208.     //  {{{ getBestView()
  209.     /** La vidéo la plus vue sur une journée
  210.      *
  211.      * récupère la vidéo la plus vue sur une période et son nombre de vue
  212.      *
  213.      * @access  public
  214.      * @param string $type_table Type de table (ex : multimedias)
  215.      * @return  array
  216.      */
  217.     public function getBestView($type_table$periode 'day'$date$limit 1$params = array())
  218.     {
  219.         $table $this->stats_base '.' $type_table '_' $date;
  220.         if (!empty($params['object']) && !empty($params['idobject'])) {
  221.             // joindre avec multimedias
  222.             $sql 'SELECT ' $table '.`idmultimedia`, COUNT(' $table '.`idmultimedia`) as views
  223.                     FROM ' $table '
  224.                     JOIN ' $_ENV['TH_BDD'] . '.object_multimedia ON ' $table '.`idmultimedia`= ' $_ENV['TH_BDD'] . '.object_multimedia.`idmultimedia`
  225.                     WHERE ' $_ENV['TH_BDD'] . '.object_multimedia.`idobject`=' . (int)$params['idobject'] . '
  226.                     AND ' $_ENV['TH_BDD'] . '.object_multimedia.`object`=\'' $params['object'] . '\'
  227.                     GROUP BY ' $table '.`idmultimedia`
  228.                     ORDER BY COUNT(' $table '.`idmultimedia`) DESC
  229.                     LIMIT 0,' $limit;
  230.         } else {
  231.             $sql 'SELECT ' $table '.`idmultimedia`, COUNT(' $table '.`idmultimedia`) as views
  232.                     FROM ' $table '
  233.                     GROUP BY ' $table '.`idmultimedia`
  234.                     ORDER BY COUNT(' $table '.`idmultimedia`) DESC
  235.                     LIMIT 0,' $limit;
  236.         }
  237.         // la plus vue ou les plus vues
  238.         if ($limit 1) {
  239.             $infos $this->queryAll($sql);
  240.             if (!empty($infos)) {
  241.                 foreach ($infos as $k => $v) {
  242.                     $infos[$k] = array_merge($infos[$k], Theatre::factory($type_table)->getObjectTitle($v['idmultimedia'], array(), array('return_array' => true)));
  243.                 }
  244.             }
  245.         } else {
  246.             $infos $this->queryRow($sql);
  247.             if (!empty($infos)) {
  248.                 $infos array_merge($infosTheatre::factory($type_table)->getObjectTitle($infos['idmultimedia'], array(), array('return_array' => true)));
  249.             }
  250.         }
  251.         return $infos;
  252.     }
  253.     // }}}
  254.     //  {{{ createDaysView()
  255.     /** Créer une vue sur les x derniers jours à partir du jour
  256.      *
  257.      * créer une vue ou remplacer l'ancienne pour xjours
  258.      *
  259.      * @access  public
  260.      * @param string $nb_days Nombre de jours pour la vue
  261.      * @return  array
  262.      */
  263.     public function createDaysView($nb_days 7)
  264.     {
  265.         // créer ou remplacer la vue
  266.         $sql 'CREATE OR REPLACE VIEW ' $this->stats_base '.' date('Ymd') . '_days' $nb_days ' AS ';
  267.         for ($i 0$i $nb_days$i++) {
  268.             $table_date date('Ymd'strtotime('-' $i ' day'));
  269.             $tables_days[] = ' SELECT * FROM ' $this->stats_base '.multimedias_' $table_date ' ';
  270.         }
  271.         // union sur les tables depuis 7 jours
  272.         $sql .= join('UNION'$tables_days);
  273.         // création
  274.         $this->execute($sql);
  275.         return true;
  276.     }
  277.     // }}}
  278.     //  {{{ deleteDaysView()
  279.     /** Supprimer les vues des jours précédents
  280.      *
  281.      * supprime des vues
  282.      *
  283.      * @access  public
  284.      * @param string $nb_days Nombre de jours pour la vue
  285.      * @return  array
  286.      */
  287.     public function deleteDaysView()
  288.     {
  289.         // trouver et supprimer les vues des jours
  290.         $sql 'SELECT *
  291.                 FROM information_schema.VIEWS 
  292.                 WHERE TABLE_SCHEMA = \'statistiques\' 
  293.                 AND TABLE_NAME LIKE \'%_days%\' ';
  294.         $this->query($sql);
  295.         while ($this->fetch()) {
  296.             $sql_drop_view 'DROP VIEW ' $this->stats_base '.' $this->TABLE_NAME;
  297.             $this->exec($sql_drop_view);
  298.         }
  299.         return true;
  300.     }
  301.     // }}}
  302.     //  {{{ getMostViewed()
  303.     /** Récupère les plus vues les X derniers jours
  304.      *
  305.      * Récupère les plus vues les X derniers jours
  306.      *
  307.      * @access  public
  308.      * @param string $nb_days Nombre de jour de test
  309.      * @param string $limit nombre max d'éléments
  310.      * @param array $exclude liste des éléments devant être exclu
  311.      *
  312.      * @return  array
  313.      */
  314.     public function getMostViewed($nb_days 7$limit 5$exclude = array())
  315.     {
  316.         if (!$this->isViewExists('statistiques'date('Ymd') . '_days' $nb_days)) {
  317.             $this->createDaysView($nb_days);
  318.         }
  319.         // requête sur la vue
  320.         $sql 'SELECT idmultimedia, COUNT(idmultimedia) as views
  321.                 FROM ' $this->stats_base '.' date('Ymd') . '_days' $nb_days ' ';
  322.         if (!empty($exclude)) {
  323.             $sql .= 'WHERE idmultimedia NOT IN (' implode(','$exclude) . ') ';
  324.         }
  325.         $sql .= 'GROUP BY idmultimedia
  326.                 ORDER BY COUNT(idmultimedia) DESC
  327.                 LIMIT 0,' . (int)$limit;
  328.         $results $this->queryAll($sql, array(), nulltrue);
  329.         if (empty($results)) {
  330.             return false;
  331.         } else {
  332.             return $results;
  333.         }
  334.         return true;
  335.     }
  336.     // }}}
  337.     //  {{{ getMostDvdViewed()
  338.     /** Récupère les vidéos les plus vues avec un DVD les X derniers jours
  339.      *
  340.      *
  341.      * @access  public
  342.      * @param string $nb_days Nombre de jour de test
  343.      * @param string $type_table Type de table (ex : multimedias)
  344.      * @return  array
  345.      */
  346.     public function getMostDvdViewed($nb_days 7$limit 5)
  347.     {
  348.         if (!$this->isViewExists('statistiques'date('Ymd') . '_days' $nb_days)) {
  349.             $this->createDaysView($nb_days);
  350.         }
  351.         // requête sur la vue
  352.         $sql 'SELECT s.`idmultimedia`, COUNT(s.`idmultimedia`) as views
  353.                 FROM `' $this->stats_base '`.`' date('Ymd') . '_days' $nb_days '` as s, `' $_ENV['TH_BDD'] . '`.`dvd_multimedia` as dm
  354.                 WHERE dm.`idmultimedia`=s.`idmultimedia`
  355.                 GROUP BY dm.`iddvd`
  356.                 ORDER BY COUNT(s.`idmultimedia`) DESC
  357.                 LIMIT 0,' . (int)$limit;
  358.         $results $this->queryAll($sql, array(), nulltrue);
  359.         if (empty($results)) {
  360.             return false;
  361.         } else {
  362.             return $results;
  363.         }
  364.         return true;
  365.     }
  366.     // }}}
  367.     //  {{{ isViewExists()
  368.     /** Tester si une vue existe
  369.      *
  370.      * teste si une vue existe pour une base données
  371.      *
  372.      * @access  public
  373.      * @param string $database Base de la vue
  374.      * @param string $name Nom de la vue
  375.      * @return  array
  376.      */
  377.     public function isViewExists($database$name)
  378.     {
  379.         // si la vues n'existe pas, on la crée
  380.         $sql 'SELECT COUNT(*)
  381.                 FROM information_schema.VIEWS 
  382.                 WHERE TABLE_SCHEMA = \'' $database '\' 
  383.                 AND TABLE_NAME = \'' $name '\' ';
  384.         $result $this->queryOne($sql);
  385.         if (empty($result) || $result == 0) {
  386.             return false;
  387.         } else {
  388.             return true;
  389.         }
  390.     }
  391.     // }}}
  392.     //  {{{ getMonthStats()
  393.     /** Statistiques mensuelles
  394.      *
  395.      * @access  public
  396.      * @param string $nb_days Nombre de jours pour la vue
  397.      * @return  array
  398.      */
  399.     public function getMonthStats($type_table$params = array())
  400.     {
  401.         // liste des tables
  402.         $tables $this->getTableDays($type_table$params);
  403.         // grouper par mois
  404.         foreach ($tables as $k => $v) {
  405.             $date $v['date'];
  406.             // découpage
  407.             $annee substr($date04);
  408.             $mois substr($date42);
  409.             $jour substr($date62);
  410.             // tableau
  411.             $tabs_date[$annee][$mois][$jour] = $v;
  412.         }
  413.         $with_union false;
  414.         // les classer par mois
  415.         foreach ($tabs_date as $a => $annees) {
  416.             foreach ($annees as $k => $mois) {
  417.                 $sql_jour = array();
  418.                 foreach ($mois as $jour) {
  419.                     // on souhaite une recherche par objet
  420.                     if (!empty($params['object']) && !empty($params['idobject'])) {
  421.                         // joindre avec multimedias
  422.                         $sql '(SELECT COUNT(' $this->stats_base '.' $jour['table'] . '.`idmultimedia`) 
  423.                                 FROM ' $this->stats_base '.' $jour['table'] . '
  424.                                 JOIN ' $_ENV['TH_BDD'] . '.object_multimedia ON ' $this->stats_base '.' $jour['table'] . '.`idmultimedia`= ' $_ENV['TH_BDD'] . '.object_multimedia.`idmultimedia` ';
  425.                         $sql .= ' WHERE ' $_ENV['TH_BDD'] . '.object_multimedia.`idobject`=' . (int)$params['idobject'] . '
  426.                                   AND ' $_ENV['TH_BDD'] . '.object_multimedia.`object`=\'' $params['object'] . '\')';
  427.                         $sql_jour[] = $sql;
  428.                     } else {
  429.                         $sql_jour[] = '(SELECT COUNT(*) FROM ' $this->stats_base '.' $jour['table'] . ') ';
  430.                     }
  431.                 }
  432.                 // le mois
  433.                 $m strftime('%B'strtotime($jour['date']));
  434.                 if ($with_union) {
  435.                     $sql_mois[$a $k] = '(SELECT \'' $a '\' as year,\'' $k '\' as month, \'' $m '\' as month_string, ' join('+'$sql_jour) . ' as vues)';
  436.                 } else { // requête par requête
  437.                     $sql_mois_string '(SELECT \'' $a '\' as year,\'' $k '\' as month, \'' $m '\' as month_string, ' join('+'$sql_jour) . ' as vues)';
  438.                     $stats[] = $this->queryRow($sql_mois_string);
  439.                 }
  440.             }
  441.         }
  442.         // lourdingue
  443.         if ($with_union) {
  444.             $sql_all join(' UNION '$sql_mois);
  445.             $stats $this->queryAll($sql_all);
  446.         }
  447.         //setDebug($stats);
  448.         return $stats;
  449.     }
  450.     // }}}
  451. }