░▒▓████████████████████████████████▓▒░ ░▒▓█ ▓▒░ ░▒▓█ ~ S W A M P ~ ▓▒░ ░▒▓█ ▓▒░ ░▒▓████████████████████████████████▓▒░
pplmvsvm
LOCATION:
/var/www/moodle/public/calendar/classes/output
☗ ROOT
↻ REFRESH
✎ CARVE FLESH
EDITING: humandate.php
<?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. namespace core_calendar\output; use DateInterval; use DateTimeInterface; use DateTimeImmutable; use core\output\externable; use core\output\pix_icon; use core\output\templatable; use core\output\renderable; use core\output\renderer_base; use core\clock; use core\url; use core_calendar\external\humandate_exporter; /** * Class humandate. * * This class is used to render a timestamp as a human readable date. * The main difference between userdate and this class is that this class * will render the date as "Today", "Yesterday", "Tomorrow" if the date is * close to the current date. Also, it will add alert styling if the date * is near. * * @package core_calendar * @copyright 2024 Ferran Recio <ferran@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class humandate implements externable, renderable, templatable { /** @var int|null The number of seconds within which a date is considered near. 1 day by default. */ protected ?int $near = DAYSECS; /** @var bool Whether we should show time only or date and time. */ protected bool $timeonly = false; /** @var url|null Link for the date. */ protected ?url $link = null; /** @var string|null An optional date format to apply. */ protected ?string $langtimeformat = null; /** @var bool Whether to use human relative terminology. */ protected bool $userelatives = true; /** @var clock The clock interface to handle time. */ protected clock $clock; /** * Class constructor. * * Use the factory methods, such as create_from_timestamp or create_from_datetime, instead. * * @param DateTimeImmutable $datetime The datetime. */ protected function __construct( /** @var DateTimeImmutable $datetime The datetime. **/ protected DateTimeImmutable $datetime, ) { $this->clock = \core\di::get(clock::class); } /** * Creates a new humandate instance from a timestamp. * * @param int $timestamp The timestamp. * @param int|null $near The number of seconds within which a date is considered near. 1 day by default. * @param bool $timeonly Whether we should show time only or date and time. * @param url|null $link Link for the date. * @param string|null $langtimeformat An optional date format to apply. * @param bool $userelatives Whether to use human relative terminology. * @return humandate The new instance. */ public static function create_from_timestamp( int $timestamp, ?int $near = DAYSECS, bool $timeonly = false, ?url $link = null, ?string $langtimeformat = null, bool $userelatives = true, ): self { return self::create_from_datetime( (new DateTimeImmutable("@{$timestamp}")), $near, $timeonly, $link, $langtimeformat, $userelatives ); } /** * Creates a new humandate instance from a datetime. * * @param DateTimeInterface $datetime The datetime. * @param int|null $near The number of seconds within which a date is considered near. 1 day by default. * @param bool $timeonly Whether we should show time only or date and time. * @param url|null $link Link for the date. * @param string|null $langtimeformat An optional date format to apply. * @param bool $userelatives Whether to use human relative terminology. * @return humandate The new instance. */ public static function create_from_datetime( DateTimeInterface $datetime, ?int $near = DAYSECS, bool $timeonly = false, ?url $link = null, ?string $langtimeformat = null, bool $userelatives = true, ): self { if (!($datetime instanceof DateTimeImmutable)) { // Always use an Immutable object to ensure that the value does not change externally before it is rendered. $datetime = DateTimeImmutable::createFromInterface($datetime); } return (new self($datetime)) ->set_near_limit($near) ->set_display_time_only($timeonly) ->set_link($link) ->set_lang_time_format($langtimeformat) ->set_use_relatives($userelatives); } /** * Sets the number of seconds within which a date is considered near. * * @param int|null $near The number of seconds within which a date is considered near. * @return humandate The instance. */ public function set_near_limit(?int $near): self { $this->near = $near; return $this; } /** * Sets whether we should show time only or date and time. * * @param bool $timeonly Whether we should show time only or date and time. * @return humandate The instance. */ public function set_display_time_only(bool $timeonly): self { $this->timeonly = $timeonly; return $this; } /** * Sets the link for the date. If null, no link will be added. * * @param url|null $link The link for the date. * @return humandate The instance. */ public function set_link(?url $link): self { $this->link = $link; return $this; } /** * Sets an optional date format to apply. * * @param string|null $langtimeformat Lang date and time format to use to format the date. * @return humandate The instance. */ public function set_lang_time_format(?string $langtimeformat): self { $this->langtimeformat = $langtimeformat; return $this; } /** * Sets whether to use human relative terminology. * * @param bool $userelatives Whether to use human relative terminology. * @return humandate The instance. */ public function set_use_relatives(bool $userelatives): self { $this->userelatives = $userelatives; return $this; } #[\Override] public function export_for_template(renderer_base $output): array { $userdate = $this->default_userdate(); $relative = null; if ($this->userelatives) { $relative = $this->format_relative_date(); } if ($this->timeonly) { $date = null; } else { $date = $relative ?? $userdate; } $data = [ 'timestamp' => $this->datetime->getTimestamp(), 'userdate' => $userdate, 'date' => $date, 'time' => $this->format_time(), 'ispast' => $this->datetime < $this->clock->now(), 'needtitle' => ($relative !== null || $this->timeonly), 'link' => $this->link ? $this->link->out(false) : '', ]; $icon = $this->get_near_icon(); if ($icon) { $data['isnear'] = true; $data['nearicon'] = $icon->export_for_template($output); } return $data; } /** * Returns the near icon if the date is near. * * @return pix_icon|null The near icon or null if not near. */ public function get_near_icon(): ?pix_icon { if ($this->is_near()) { return new pix_icon( pix: 'i/warning', alt: get_string('warning'), component: 'moodle', attributes: ['class' => 'me-0 pb-1'] ); } return null; } #[\Override] public function get_exporter(?\core\context $context = null): humandate_exporter { $context = $context ?? \core\context\system::instance(); return new humandate_exporter($this, ['context' => $context]); } #[\Override] public static function get_read_structure( int $required = VALUE_REQUIRED, mixed $default = null ): \core_external\external_single_structure { return humandate_exporter::get_read_structure($required, $default); } #[\Override] public static function read_properties_definition(): array { return humandate_exporter::read_properties_definition(); } /** * Returns the default user date format. * * @return string The formatted date. */ private function default_userdate(): string { $timestamp = $this->datetime->getTimestamp(); if ($this->is_current_year()) { $format = get_string('strftimedayshort', 'langconfig'); } else { $format = get_string('strftimedaydate', 'langconfig'); } return userdate($timestamp, $format); } /** * Checks if the date is near. * * @return bool Whether the date is near. */ private function is_near(): bool { if ($this->near === null) { return false; } $due = $this->datetime->diff($this->clock->now()); $intervalseconds = $this->interval_to_seconds($due); return $intervalseconds < $this->near && $intervalseconds > 0; } /** * Checks if the datetime is from the current year. * * @return bool True if the datetime is from the current year, false otherwise. */ private function is_current_year(): bool { $currentyear = $this->clock->now()->format('Y'); $datetimeyear = $this->datetime->format('Y'); return $currentyear === $datetimeyear; } /** * Converts a DateInterval object to total seconds. * * @param \DateInterval $interval The interval to convert. * @return int The total number of seconds. */ private function interval_to_seconds(DateInterval $interval): int { $reference = new DateTimeImmutable(); $entime = $reference->add($interval); return $reference->getTimestamp() - $entime->getTimestamp(); } /** * Formats the timestamp as a relative date string (e.g., "Today", "Yesterday", "Tomorrow"). * * This method compares the given timestamp with the current date and returns a formatted * string representing the relative date. If the timestamp corresponds to today, yesterday, * or tomorrow, it returns the appropriate string. Otherwise, it returns null. * * @return string|null */ private function format_relative_date(): ?string { $usertimestamp = $this->get_user_date($this->datetime->getTimestamp()); if ($usertimestamp == $this->get_user_date($this->clock->now()->getTimestamp())) { $format = get_string( 'timerelativetoday', 'calendar', get_string('strftimedateshort', 'langconfig') ); } else if ($usertimestamp == $this->get_user_date(strtotime('yesterday', $this->clock->now()->getTimestamp()))) { $format = get_string( 'timerelativeyesterday', 'calendar', get_string('strftimedateshort', 'langconfig') ); } else if ($usertimestamp == $this->get_user_date(strtotime('tomorrow', $this->clock->now()->getTimestamp()))) { $format = get_string( 'timerelativetomorrow', 'calendar', get_string('strftimedateshort', 'langconfig') ); } else { return null; } return userdate($this->datetime->getTimestamp(), $format); } /** * Formats the timestamp as a human readable time. * * @param int $timestamp The timestamp to format. * @param string $format The format to use. * @return string The formatted date. */ private function get_user_date(int $timestamp, string $format = '%Y-%m-%d'): string { $calendartype = \core_calendar\type_factory::get_calendar_instance(); $timezone = \core_date::get_user_timezone_object(); return $calendartype->timestamp_to_date_string( time: $timestamp, format: $format, timezone: $timezone->getName(), fixday: true, fixhour: true, ); } /** * Formats the timestamp as a human readable time. * * This method compares the given timestamp with the current date and returns a formatted * string representing the time. * * @return string */ private function format_time(): string { global $CFG; // Ensure calendar constants are loaded. require_once($CFG->dirroot . '/calendar/lib.php'); $timeformat = get_user_preferences('calendar_timeformat'); if (empty($timeformat)) { $timeformat = get_config(null, 'calendar_site_timeformat'); } // Allow language customization of selected time format. if ($timeformat === CALENDAR_TF_12) { $timeformat = get_string('strftimetime12', 'langconfig'); } else if ($timeformat === CALENDAR_TF_24) { $timeformat = get_string('strftimetime24', 'langconfig'); } if ($timeformat) { return userdate($this->datetime->getTimestamp(), $timeformat); } // Let's use default format. if ($this->langtimeformat === null) { $langtimeformat = get_string('strftimetime'); } return userdate($this->datetime->getTimestamp(), $langtimeformat); } }
CANCEL
Name
Type
Size
Modified
Actions
↩ ..
DIR
—
—
📄 humandate.php
PHP
13.7 KB
2026-02-11 01:44
EDIT
📄 humantimeperiod.php
PHP
8.4 KB
2026-02-11 01:44
EDIT
📄 refreshintervalcollection.php
PHP
2 KB
2026-02-11 01:44
EDIT