/src/View/Helper/TimeHHelper.php

https://github.com/Schlaefer/Saito · PHP · 198 lines · 115 code · 30 blank · 53 comment · 9 complexity · 0316f0c05346c8fb9253242fa804753e MD5 · raw file

  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * Saito - The Threaded Web Forum
  5. *
  6. * @copyright Copyright (c) the Saito Project Developers
  7. * @link https://github.com/Schlaefer/Saito
  8. * @license http://opensource.org/licenses/MIT
  9. */
  10. namespace App\View\Helper;
  11. use Cake\Core\Configure;
  12. use DateTime;
  13. use DateTimeZone;
  14. class TimeHHelper extends AppHelper
  15. {
  16. public $helpers = [
  17. 'Time',
  18. ];
  19. protected static $_timezoneGroups = [
  20. 'UTC' => DateTimeZone::UTC,
  21. 'Africa' => DateTimeZone::AFRICA,
  22. 'America' => DateTimeZone::AMERICA,
  23. 'Antarctica' => DateTimeZone::ANTARCTICA,
  24. 'Asia' => DateTimeZone::ASIA,
  25. 'Atlantic' => DateTimeZone::ATLANTIC,
  26. 'Europe' => DateTimeZone::EUROPE,
  27. 'Indian' => DateTimeZone::INDIAN,
  28. 'Pacific' => DateTimeZone::PACIFIC,
  29. ];
  30. /** @var int unix timestamp of current time */
  31. protected $_now = null;
  32. /** @var int unix timestamp of today */
  33. protected $_today;
  34. protected $_timeDiffToUtc = 0;
  35. /**
  36. * {@inheritDoc}
  37. */
  38. public function beforeRender()
  39. {
  40. $this->_now = time();
  41. $this->_today = mktime(0, 0, 0);
  42. // @td reimplement unsing Cake 2.2 CakeTime (?)
  43. $timezone = Configure::read('Saito.Settings.timezone');
  44. if (empty($timezone)) {
  45. $timezone = 'UTC';
  46. }
  47. $timezone = new DateTimeZone($timezone);
  48. $timeInTimezone = new DateTime('now', $timezone);
  49. $timeOnServer = new DateTime('now');
  50. $this->_timeDiffToUtc = $timeOnServer->getOffset() - $timeInTimezone->getOffset();
  51. }
  52. /**
  53. * Get timezone list for select popup
  54. *
  55. * @return array timezones
  56. */
  57. public function getTimezoneSelectOptions()
  58. {
  59. $options = [];
  60. foreach (self::$_timezoneGroups as $groupTitle => $groupId) {
  61. $timeZones = DateTimeZone::listIdentifiers($groupId);
  62. foreach ($timeZones as $timeZoneTitle) {
  63. $timezone = new DateTimeZone($timeZoneTitle);
  64. $timeInTimezone = new DateTime('now', $timezone);
  65. $timeDiffToUtc = $timeInTimezone->getOffset() / 3600;
  66. if ($timeDiffToUtc > 0) {
  67. $timeDiffToUtc = '+' . $timeDiffToUtc;
  68. }
  69. $tz = $timeZoneTitle . ' – ' . $timeInTimezone->format('H:i');
  70. if ($timeDiffToUtc !== 0) {
  71. $tz .= ' (' . $timeDiffToUtc . ')';
  72. }
  73. $options[$groupTitle][$timeZoneTitle] = $tz;
  74. }
  75. }
  76. return $options;
  77. }
  78. /**
  79. * Format timestamp to readable string
  80. *
  81. * @param DateTime $timestamp timestamp
  82. * @param string $format format
  83. * @param array $options options
  84. * @return string
  85. */
  86. public function formatTime(\DateTimeInterface $timestamp, $format = 'normal', array $options = []): string
  87. {
  88. // Stopwatch::start('formatTime');
  89. $options += ['wrap' => []];
  90. $unixTimestamp = $timestamp->format('U');
  91. $timestamp = $unixTimestamp - $this->_timeDiffToUtc;
  92. switch ($format) {
  93. case 'normal':
  94. $string = $this->_formatRelative($timestamp);
  95. break;
  96. case 'short':
  97. $string = date('d.m.', $timestamp);
  98. break;
  99. case 'eng':
  100. $string = strftime('%F %T', $timestamp);
  101. break;
  102. default:
  103. $string = strftime($format, $timestamp);
  104. }
  105. if ($options['wrap'] !== false) {
  106. $string = $this->timeTag($string, $timestamp, $options['wrap']);
  107. }
  108. // Stopwatch::stop('formatTime');
  109. return $string;
  110. }
  111. /**
  112. * Format timestamp relative to age
  113. *
  114. * @param int $timestamp unix-timestamp
  115. * @return string formated time
  116. */
  117. protected function _formatRelative($timestamp)
  118. {
  119. if ($timestamp > $this->_today || $timestamp > ($this->_now - 21600)) {
  120. // today or in the last 6 hours
  121. $time = strftime("%H:%M", $timestamp);
  122. } elseif ($timestamp > ($this->_today - 64800)) {
  123. // yesterday but in the last 18 hours
  124. $time = __('yesterday') . ' ' . strftime("%H:%M", $timestamp);
  125. } else {
  126. // yesterday and 18 hours and older
  127. $time = strftime("%d.%m.%Y", $timestamp);
  128. }
  129. return $time;
  130. }
  131. /**
  132. * Create HTML time tag
  133. *
  134. * @performance Is used hundreds of times on homepage.
  135. *
  136. * @param string $content Content for tag
  137. * @param int $timestamp unix-timestamp
  138. * @param array $options options will become attributes in time-tag
  139. * @return string HTML
  140. */
  141. public function timeTag($content, $timestamp, array $options = [])
  142. {
  143. $options += [
  144. 'datetime' => date(DATE_RFC3339, $timestamp),
  145. 'title' => strftime("%F %T", $timestamp),
  146. ];
  147. $attributes = [];
  148. foreach ($options as $attribute => $value) {
  149. $attributes[$attribute] = "$attribute=\"$value\"";
  150. }
  151. $attributes = implode(' ', $attributes);
  152. $timestamp = "<time $attributes>$content</time>";
  153. return $timestamp;
  154. }
  155. /**
  156. * Converts time value to ISO time string
  157. *
  158. * @param mixed $date date
  159. * @return bool|null|string
  160. */
  161. public function dateToIso($date)
  162. {
  163. if ($date === null) {
  164. return null;
  165. }
  166. return dateToIso($date);
  167. }
  168. }