StatsDAOPGSQL.php 2.5 KB

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