Skip to content
Extraits de code Groupes Projets
Valider c69ea417 rédigé par marcimat's avatar marcimat
Parcourir les fichiers

feat: Retour json attendu par SPIP 4.1+

parent e43c5e1e
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -5,87 +5,146 @@ if (!defined('_ECRIRE_INC_VERSION')) { ...@@ -5,87 +5,146 @@ if (!defined('_ECRIRE_INC_VERSION')) {
} }
include_spip('inc/statistiques'); include_spip('inc/statistiques');
// moyenne glissante sur 30 jours
define('MOYENNE_GLISSANTE_JOUR', 30);
// moyenne glissante sur 12 mois
define('MOYENNE_GLISSANTE_MOIS', 12);
function inc_stats_trads_to_array_dist($unite, $duree, $id_tradlang_module, $options = []) {
$now = time();
if (!in_array($unite, ['jour', 'mois'])) { include_spip('inc/statistiques');
$unite = 'jour';
/**
* Retourne les statistiques de versionnage des traductions pour une durée donnée
*
* @param string $unite jour | mois | annee
* @param ?int $duree Combien de jours | mois | annee on prend…
* @param ?string $objet (unused)
* @param ?int $id_objet (id_auteur)
* @return array [date => nb visites]
*/
function inc_stats_trads_to_array_dist($unite, ?int $duree = null, ?string $objet = null, ?int $id_objet = null) {
$unites = [
'jour' => 'day',
'day' => 'day',
'semaine' => 'week',
'week' => 'week',
'mois' => 'month',
'month' => 'month',
'annee' => 'year',
'year' => 'year',
];
$unite = $unites[$unite] ?? 'day';
$period_unit = $unite;
$period_duration = $duree;
switch ($unite) {
case 'day':
$format_sql = '%Y-%m-%d';
$format = 'Y-m-d';
$period_unit_interval = 'D';
break;
case 'week':
// https://en.wikipedia.org/wiki/ISO_week_date
$format_sql = '%x-W%v';
$format = 'o-\WW';
$n_today = (new \DateTime())->format('w'); // dimanche 0, samedi 6
// on se cale sur un lundi
$period_duration = 7 * $duree - $n_today;
$period_unit = 'day';
$period_unit_interval = 'D';
break;
case 'month':
$format_sql = '%Y-%m';
$format = 'Y-m';
$period_unit_interval = 'M';
break;
case 'year':
$format_sql = '%Y';
$format = 'Y';
$period_unit_interval = 'Y';
break;
default:
throw new \RuntimeException("Invalid unit $unite");
} }
$serveur = '';
if ($duree and $duree < 0) {
$duree = null;
}
$serveur = '';
$table = 'spip_versions'; $table = 'spip_versions';
$order = 'date'; $order = 'date';
$where = ['objet = "tradlang"', 'id_version > 0'];
$objet = 'tradlang';
$id_auteur = $id_objet;
if (!isset($options['id_auteur']) || !is_numeric($options['id_auteur'])) { $where = [
'objet = ' . sql_quote($objet),
'id_version > 0'
];
if (!$id_auteur) {
$where[] = 'id_auteur > 0'; $where[] = 'id_auteur > 0';
} else { } else {
$where[] = 'id_auteur = ' . (int) $options['id_auteur']; $where[] = 'id_auteur = ' . $id_auteur;
} }
$currentDate = (new \DateTime())->format($format);
$startDate = null;
$endDate = $currentDate;
if ($duree) { if ($duree) {
$where[] = sql_date_proche($order, -$duree, 'day', $serveur); $where[] = sql_date_proche($order, -$period_duration, $period_unit, $serveur);
// sql_date_proche utilise une comparaison stricte. On soustrait 1 jour...
$startDate = (new \DateTime())->sub(new \DateInterval('P' . ($period_duration - 1) . $period_unit_interval))->format($format);
} }
$where = implode(' AND ', $where); $where = implode(' AND ', $where);
$format = ($unite == 'jour' ? '%Y-%m-%d' : '%Y-%m-01');
$res = sql_select("COUNT(*) AS v, DATE_FORMAT($order,'$format') AS d", $table, $where, 'd', 'd', '', '', $serveur); $firstDateStat = sql_getfetsel('date', $table, $where, '', 'date', '0,1');
$format = str_replace('%', '', $format); if ($firstDateStat) {
$periode = ($unite == 'jour' ? 24 * 3600 : 365 * 24 * 3600 / 12); $firstDate = (new \DateTime($firstDateStat))->format($format);
$step = (int) round($periode * 1.1, 0); } else {
$glisse = constant('MOYENNE_GLISSANTE_' . strtoupper($unite)); $firstDate = null;
moyenne_glissante();
$data = [];
$r = sql_fetch($res, $serveur);
if (!$r) {
$r = ['d' => date($format, $now), 'v' => 0];
} }
do {
$data[$r['d']] = ['versions' => $r['v'], 'moyenne' => moyenne_glissante($r['v'], $glisse)]; $data = sql_allfetsel(
$last = $r['d']; "DATE_FORMAT($order, '$format_sql') AS formatted_date, COUNT(*) AS visites",
$table,
// donnee suivante $where,
$r = sql_fetch($res, $serveur); 'formatted_date',
// si la derniere n'est pas la date courante, l'ajouter 'formatted_date',
if (!$r && $last != date($format, $now)) { '',
$r = ['d' => date($format, $now), 'v' => 0]; '',
} $serveur
);
// completer les trous manquants si besoin
if ($r) { $data = array_map(function ($d) {
$next = strtotime($last); $d['date'] = $d['formatted_date'];
$current = strtotime($r['d']); unset($d['formatted_date']);
while (($next += $step) < $current && ($d = date($format, $next))) { return $d;
if (!isset($data[$d])) { }, $data);
$data[$d] = ['versions' => 0, 'moyenne' => moyenne_glissante(0, $glisse)];
} return [
$last = $d; 'meta' => [
$next = strtotime($last); 'unite' => $unite,
} 'duree' => $duree,
} 'id_auteur' => $id_auteur,
} while ($r); 'format_date' => $format,
'start_date' => $startDate ?? $firstDate ?? $endDate,
// projection pour la derniere barre : 'end_date' => $endDate,
// mesure courante 'first_date' => $firstDate,
// + moyenne au pro rata du temps qui reste 'columns' => [
$moyenne = end($data); 'date',
$moyenne = prev($data); 'visites',
$moyenne = ($moyenne && isset($moyenne['moyenne'])) ? $moyenne['moyenne'] : 0; ],
$data[$last]['moyenne'] = $moyenne; 'translations' => [
'date' => _T('public:date'),
// temps restant 'visites' => label_nettoyer(_T('tradlang:info_revisions_stats')),
$remaining = strtotime(date($format, strtotime(date($format, $now)) + $step)) - $now; 'moyenne' => _T('statistiques:moyenne'),
],
$prorata = $remaining / $periode; ],
'data' => array_values($data),
// projection ];
$data[$last]['prevision'] = $data[$last]['versions'] + (int) round($moyenne * $prorata);
return $data;
} }
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter