Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
lippserd committed Feb 17, 2023
1 parent afe46d9 commit c8186ff
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 141 deletions.
52 changes: 16 additions & 36 deletions src/RRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ public function isExpired(DateTimeInterface $dateTime): bool
/**
* Set the start time of this frequency
*
* The given datetime will be cloned and microseconds removed since iCalendar datetimes only work to the second.
*
* @param DateTimeInterface $start
*
* @return $this
Expand All @@ -172,7 +174,7 @@ public function startAt(DateTimeInterface $start): self
// the transformer operates only up to seconds level. See also the upstream issue #155
$startDate->setTime($start->format('H'), $start->format('i'), $start->format('s'));

$this->rrule->setStartDate($startDate);
$this->rrule->setStartDate($startDate, true);

return $this;
}
Expand All @@ -185,12 +187,17 @@ public function getStart(): ?DateTimeInterface
/**
* Set the end time of this frequency
*
* The given datetime will be cloned and microseconds removed since iCalendar datetimes only work to the second.
*
* @param DateTimeInterface $end
*
* @return $this
*/
public function endAt(DateTimeInterface $end): self
{
$end = clone $end;
$end->setTime($end->format('H'), $end->format('i'), $end->format('s'));

$this->rrule->setEndDate($end);

return $this;
Expand Down Expand Up @@ -257,47 +264,20 @@ public function getNextRecurrences(

public static function fromJson(string $json): Frequency
{
$data = json_decode($json, true);
if (! isset($data['FREQ'])) {
throw new InvalidRRule('Missing required attribute "FREQ"');
}

if (! isset($data['INTERVAL'])) {
$self = static::fromFrequency($data['FREQ']);
if (isset($data['DTSTART'])) {
$self->startAt(new DateTime($data['DTSTART']));
}

if (isset($data['DTEND'])) {
$self->endAt(new DateTime($data['DTEND']));
}

return $self;
}
$data = json_decode($json);
$self = new static($data->rrule);
$self->frequency = $data->frequency;

return new static($data);
return $self;
}

#[\ReturnTypeWillChange]
public function jsonSerialize()
{
$data = $this->rrule->parseString($this->rrule->getString());
if ($this->getFrequency() === static::QUARTERLY) {
$data['FREQ'] = static::QUARTERLY;
unset($data['INTERVAL']);
}

$start = $this->getStart();
if ($start) {
$data['DTSTART'] = $start->format(static::SERIALIZED_DATETIME_FORMAT);
}

$end = $this->getEnd();
if ($end) {
$data['DTEND'] = $end->format(static::SERIALIZED_DATETIME_FORMAT);
}

return json_encode($data);
return [
'rrule' => $this->rrule->getString(),
'frequency' => $this->frequency
];
}

/**
Expand Down
1 change: 1 addition & 0 deletions tests/Lib/BaseTestFrequency.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public static function fromJson(string $json): Frequency
throw new LogicException('Not implemented');
}

#[\ReturnTypeWillChange]
public function jsonSerialize()
{
throw new LogicException('Not implemented');
Expand Down
120 changes: 15 additions & 105 deletions tests/RRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public function testGetNextDueWithoutEndTime()
public function testGetNextDueWithEndTime()
{
$end = new DateTime('+5 minutes');
$end->setTime($end->format('H'), $end->format('i'), $end->format('s'));
$rrule = RRule::fromFrequency(RRule::MINUTELY)
->startAt(new DateTime())
->endAt($end);
Expand Down Expand Up @@ -132,118 +133,27 @@ public function testQuarterlyFrequency()
$this->assertEquals($start->modify('+3 months'), $recurrences->current());
}

public function testJsonSerializeMinutelyFrequency()
public function testJSON()
{
$rule = RRule::fromFrequency(RRule::MINUTELY);
$this->assertSame('{"FREQ":"MINUTELY"}', $rule->jsonSerialize());

$start = new DateTime('2023-02-15T15:11:00');
$rule->startAt($start);

$this->assertSame(
sprintf('{"FREQ":"MINUTELY","DTSTART":"%s"}', $start->format(Frequency::SERIALIZED_DATETIME_FORMAT)),
$rule->jsonSerialize()
);

$end = new DateTime();
$rule->endAt($end);

$this->assertSame(
sprintf(
'{"FREQ":"MINUTELY","DTEND":"%s","DTSTART":"%s"}',
$end->format(Frequency::SERIALIZED_DATETIME_FORMAT),
$start->format(Frequency::SERIALIZED_DATETIME_FORMAT)
),
$rule->jsonSerialize()
);
}
$rrule = RRule::fromFrequency(RRule::QUARTERLY)
->startAt(new DateTime('tomorrow'))
->endAt(new DateTime('next week'));

public function testJsonSerializeQuarterly()
{
$rule = RRule::fromFrequency(RRule::QUARTERLY);
$this->assertSame('{"FREQ":"QUARTERLY"}', $rule->jsonSerialize());

$start = new DateTime('2023-02-15T15:11:00');
$rule->startAt($start);

$this->assertSame(
sprintf('{"FREQ":"QUARTERLY","DTSTART":"%s"}', $start->format(Frequency::SERIALIZED_DATETIME_FORMAT)),
$rule->jsonSerialize()
);

$end = new DateTime();
$rule->endAt($end);

$this->assertSame(
sprintf(
'{"FREQ":"QUARTERLY","DTEND":"%s","DTSTART":"%s"}',
$end->format(Frequency::SERIALIZED_DATETIME_FORMAT),
$start->format(Frequency::SERIALIZED_DATETIME_FORMAT)
),
$rule->jsonSerialize()
);
}
$this->assertEquals($rrule, RRule::fromJson(json_encode($rrule)));

public function testFromJsonWithInvalidData()
{
$this->expectException(InvalidRRule::class);
$rrule = RRule::fromFrequency(RRule::QUARTERLY)
->endAt(new DateTime('next week'));

RRule::fromJson('{}');
}
$this->assertEquals($rrule, RRule::fromJson(json_encode($rrule)));

public function testFromJsonMinutelyFrequency()
{
$this->assertEquals(RRule::fromFrequency(RRule::MINUTELY), RRule::fromJson('{"FREQ":"MINUTELY"}'));
$rrule = RRule::fromFrequency(RRule::QUARTERLY);

$start = new DateTime();
$rule = RRule::fromFrequency(RRule::MINUTELY)->startAt($start);
$this->assertEquals(
$rule,
RRule::fromJson(
sprintf('{"FREQ":"MINUTELY","DTSTART":"%s"}', $start->format(Frequency::SERIALIZED_DATETIME_FORMAT))
)
);

$end = new DateTime();
$rule->endAt($end);

$this->assertEquals(
$rule,
RRule::fromJson(
sprintf(
'{"FREQ":"MINUTELY","DTEND":"%s","DTSTART":"%s"}',
$end->format(Frequency::SERIALIZED_DATETIME_FORMAT),
$start->format(Frequency::SERIALIZED_DATETIME_FORMAT)
)
)
);
}
$this->assertEquals($rrule, RRule::fromJson(json_encode($rrule)));

public function testFromJsonQuarterlyFrequency()
{
$this->assertEquals(RRule::fromFrequency(RRule::QUARTERLY), RRule::fromJson('{"FREQ":"QUARTERLY"}'));
$rrule = (new RRule('FREQ=MINUTELY'))
->startAt(new DateTime('tomorrow'))
->endAt(new DateTime('next week'));

$start = new DateTime();
$rule = RRule::fromFrequency(RRule::QUARTERLY)->startAt($start);
$this->assertEquals(
$rule,
RRule::fromJson(
sprintf('{"FREQ":"QUARTERLY","DTSTART":"%s"}', $start->format(Frequency::SERIALIZED_DATETIME_FORMAT))
)
);

$end = new DateTime();
$rule->endAt($end);

$this->assertEquals(
$rule,
RRule::fromJson(
sprintf(
'{"FREQ":"QUARTERLY","DTEND":"%s","DTSTART":"%s"}',
$end->format(Frequency::SERIALIZED_DATETIME_FORMAT),
$start->format(Frequency::SERIALIZED_DATETIME_FORMAT)
)
)
);
$this->assertEquals($rrule, RRule::fromJson(json_encode($rrule)));
}
}

0 comments on commit c8186ff

Please sign in to comment.