AutorÃa | Ultima modificación | Ver Log |
<?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 DateTimeInterface;use DateTimeImmutable;use core\output\templatable;use core\output\renderable;use core\output\renderer_base;use core\url;/*** Class humantimeperiod.** This class is used to render a time period 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 styling if the date* is near.** @package core_calendar* @copyright 2025 Amaia Anabitarte <amaia@moodle.com>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class humantimeperiod implements renderable, templatable {/** @var int|null Number of seconds that indicates a nearby date. Default to DAYSECS. Use null for no indication. */protected $near = DAYSECS;/** @var url|null URL to link the date to. */protected ?url $link = null;/** @var string|null An optional date format to apply. */protected ?string $langtimeformat = null;/** @var bool Whether to use human common words or not. */protected bool $userelatives = true;/*** Class constructor.** @param DateTimeImmutable $startdatetime The starting timestamp.* @param DateTimeImmutable|null $enddatetime The ending timestamp.*/protected function __construct(/** @var DateTimeImmutable $startdatetime The starting date time. */protected DateTimeImmutable $startdatetime,/** @var DateTimeImmutable|null $enddatetime The ending date time. */protected ?DateTimeImmutable $enddatetime,) {}/*** Creates a new humantimeperiod instance from a timestamp.** @param int $starttimestamp The starting timestamp.* @param int|null $endtimestamp The ending timestamp.* @param int|null $near The number of seconds that indicates a nearby date. Default to DAYSECS, use null for no indication.* @param url|null $link URL to link the date to.* @param string|null $langtimeformat Lang date and time format to use to format the date.* @param bool $userelatives Whether to use human common words or not.* @return humantimeperiod The new instance.*/public static function create_from_timestamp(int $starttimestamp,?int $endtimestamp,?int $near = DAYSECS,?url $link = null,?string $langtimeformat = null,bool $userelatives = true,): self {return self::create_from_datetime((new DateTimeImmutable("@{$starttimestamp}")),$endtimestamp ? (new DateTimeImmutable("@{$endtimestamp}")) : null,$near,$link,$langtimeformat,$userelatives);}/*** Creates a new humantimeperiod instance from a datetime.** @param DateTimeInterface $startdatetime The starting datetime.* @param DateTimeInterface|null $enddatetime The ending datetime.* @param int|null $near The number of seconds that indicates a nearby date. Default to DAYSECS, use null for no indication.* @param url|null $link URL to link the date to.* @param string|null $langtimeformat Lang date and time format to use to format the date.* @param bool $userelatives Whether to use human common words or not.* @return humantimeperiod The new instance.*/public static function create_from_datetime(DateTimeInterface $startdatetime,?DateTimeInterface $enddatetime,?int $near = DAYSECS,?url $link = null,?string $langtimeformat = null,bool $userelatives = true,): self {// Always use an Immutable object to ensure that the value does not change externally before it is rendered.if (!($startdatetime instanceof DateTimeImmutable)) {$startdatetime = DateTimeImmutable::createFromInterface($startdatetime);}if ($enddatetime != null && !($enddatetime instanceof DateTimeImmutable)) {$enddatetime = DateTimeImmutable::createFromInterface($enddatetime);}return (new self($startdatetime, $enddatetime))->set_near_limit($near)->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 humantimeperiod The instance.*/public function set_near_limit(?int $near): self {$this->near = $near;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 humantimeperiod 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 humantimeperiod 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 humantimeperiod 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 {$period = $this->format_period();return ['startdate' => $period['startdate']->export_for_template($output),'enddate' => $period['enddate'] ? $period['enddate']->export_for_template($output) : null,];}/*** Format a time periods based on 2 dates.** @return array An array of one or two humandate elements.*/private function format_period(): array {$linkstart = null;$linkend = null;if ($this->link) {$linkstart = new url($this->link, ['view' => 'day', 'time' => $this->startdatetime->getTimestamp()]);$linkend = new url($this->link, ['view' => 'day', 'time' => $this->enddatetime->getTimestamp()]);}$startdate = humandate::create_from_datetime(datetime: $this->startdatetime,near: $this->near,link: $linkstart,langtimeformat: $this->langtimeformat,userelatives: $this->userelatives);if ($this->enddatetime == null || $this->startdatetime == $this->enddatetime) {return ['startdate' => $startdate,'enddate' => null,];}// Get the midnight of the day the event will start.$usermidnightstart = usergetmidnight($this->startdatetime->getTimestamp());// Get the midnight of the day the event will end.$usermidnightend = usergetmidnight($this->enddatetime->getTimestamp());// Check if we will still be on the same day.$issameday = ($usermidnightstart == $usermidnightend);$enddate = humandate::create_from_datetime(datetime: $this->enddatetime,near: $this->near,timeonly: $issameday,link: $linkend,langtimeformat: $this->langtimeformat,userelatives: $this->userelatives);return ['startdate' => $startdate,'enddate' => $enddate,];}}