4
0

StatsDAOPGSQL.php 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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, COUNT(1) AS count
  57. FROM `_entry` AS e
  58. {$restrict}
  59. GROUP BY period
  60. ORDER BY period ASC
  61. SQL;
  62. $res = $this->fetchAssoc($sql);
  63. if ($res == null) {
  64. return [];
  65. }
  66. $periodMax = match ($period) {
  67. 'hour' => 24,
  68. 'day' => 7,
  69. 'month' => 12,
  70. default => 30,
  71. };
  72. $repartition = array_fill(0, $periodMax, 0);
  73. foreach ($res as $value) {
  74. $repartition[(int)$value['period']] = (int)$value['count'];
  75. }
  76. return $repartition;
  77. }
  78. }