StatsDAOPGSQL.php 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. <?php
  2. declare(strict_types=1);
  3. class FreshRSS_StatsDAOPGSQL extends FreshRSS_StatsDAO {
  4. #[\Override]
  5. protected function sqlDateToIsoGranularity(string $field, int $precision, string $granularity): string {
  6. $offset = $this->getTimezoneOffset();
  7. return match ($granularity) {
  8. 'day' => "to_char(to_timestamp(($field / $precision) + $offset), 'YYYY-MM-DD')",
  9. 'month' => "to_char(to_timestamp(($field / $precision) + $offset), 'YYYY-MM')",
  10. 'year' => "to_char(to_timestamp(($field / $precision) + $offset), 'YYYY')",
  11. default => throw new InvalidArgumentException('Invalid date granularity'),
  12. };
  13. }
  14. /**
  15. * Calculates the number of article per hour of the day per feed
  16. *
  17. * @param int $feed id
  18. * @return array<int,int>
  19. */
  20. #[\Override]
  21. public function calculateEntryRepartitionPerFeedPerHour(?int $feed = null): array {
  22. return $this->calculateEntryRepartitionPerFeedPerPeriod('hour', $feed);
  23. }
  24. /**
  25. * Calculates the number of article per day of week per feed
  26. * @return array<int,int>
  27. */
  28. #[\Override]
  29. public function calculateEntryRepartitionPerFeedPerDayOfWeek(?int $feed = null): array {
  30. return $this->calculateEntryRepartitionPerFeedPerPeriod('day', $feed);
  31. }
  32. /**
  33. * Calculates the number of article per month per feed
  34. * @return array<int,int>
  35. */
  36. #[\Override]
  37. public function calculateEntryRepartitionPerFeedPerMonth(?int $feed = null): array {
  38. return $this->calculateEntryRepartitionPerFeedPerPeriod('month', $feed);
  39. }
  40. /**
  41. * Calculates the number of article per period per feed
  42. * @param string $period format string to use for grouping
  43. * @return array<int,int>
  44. */
  45. #[\Override]
  46. protected function calculateEntryRepartitionPerFeedPerPeriod(string $period, ?int $feed = null): array {
  47. $restrict = '';
  48. if ($feed) {
  49. $restrict = "WHERE e.id_feed = {$feed}";
  50. }
  51. $offset = $this->getTimezoneOffset();
  52. $sql = <<<SQL
  53. SELECT extract( {$period} from to_timestamp(e.date + {$offset})) AS period
  54. , COUNT(1) AS count
  55. FROM `_entry` AS e
  56. {$restrict}
  57. GROUP BY period
  58. ORDER BY period ASC
  59. SQL;
  60. $res = $this->fetchAssoc($sql);
  61. if ($res == null) {
  62. return [];
  63. }
  64. $periodMax = match ($period) {
  65. 'hour' => 24,
  66. 'day' => 7,
  67. 'month' => 12,
  68. default => 30,
  69. };
  70. $repartition = array_fill(0, $periodMax, 0);
  71. foreach ($res as $value) {
  72. $repartition[(int)$value['period']] = (int)$value['count'];
  73. }
  74. return $repartition;
  75. }
  76. }