Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix issue #646 #649

Merged
merged 4 commits into from May 9, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/Document.php
Expand Up @@ -167,7 +167,7 @@ public function createComponent(string $name, ?array $children = null, bool $def
*
* @throws InvalidDataException
*/
public function createProperty(string $name, $value = null, ?array $parameters = null, ?string $valueType = null): Property
public function createProperty(string $name, $value = null, ?array $parameters = null, ?string $valueType = null, ?int $lineIndex = null, ?string $lineString = null): Property
{
// If there's a . in the name, it means it's prefixed by a group name.
if (false !== ($i = strpos($name, '.'))) {
Expand Down Expand Up @@ -201,7 +201,7 @@ public function createProperty(string $name, $value = null, ?array $parameters =
$parameters = [];
}

return new $class($this, $name, $value, $parameters, $group);
return new $class($this, $name, $value, $parameters, $group, $lineIndex, $lineString);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion lib/Parser/MimeDir.php
Expand Up @@ -445,7 +445,7 @@ protected function readProperty(string $line)
}
}

$propObj = $this->root->createProperty($property['name'], null, $namedParameters);
$propObj = $this->root->createProperty($property['name'], null, $namedParameters, null, $this->startLine, $line);

foreach ($namelessParameters as $namelessParameter) {
$propObj->add(null, $namelessParameter);
Expand Down
24 changes: 23 additions & 1 deletion lib/Property.php
Expand Up @@ -51,6 +51,20 @@ abstract class Property extends Node
*/
public string $delimiter = ';';

/**
* The line number in the original iCalendar / vCard file
* that corresponds with the current node
* if the node was read from a file.
*/
public ?int $lineIndex;

/**
* The line string from the original iCalendar / vCard file
* that corresponds with the current node
* if the node was read from a file.
*/
public ?string $lineString;

/**
* Creates the generic property.
*
Expand All @@ -61,7 +75,7 @@ abstract class Property extends Node
* @param array $parameters List of parameters
* @param string|null $group The vcard property group
*/
public function __construct(Component $root, ?string $name, $value = null, array $parameters = [], ?string $group = null)
public function __construct(Component $root, ?string $name, $value = null, array $parameters = [], ?string $group = null, ?int $lineIndex = null, ?string $lineString = null)
{
$this->name = $name;
$this->group = $group;
Expand All @@ -75,6 +89,14 @@ public function __construct(Component $root, ?string $name, $value = null, array
if (!is_null($value)) {
$this->setValue($value);
}

if (!is_null($lineIndex)) {
$this->lineIndex = $lineIndex;
}

if (!is_null($lineString)) {
$this->lineString = $lineString;
}
}

/**
Expand Down
43 changes: 43 additions & 0 deletions tests/VObject/Component/VCalendarTest.php
Expand Up @@ -756,6 +756,49 @@ public function testCalDAVMETHOD(): void
);
}

public function testNodeInValidationErrorHasLineIndexAndLineStringProps(): void
{
$defectiveInput = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
PRODID:vobject
BEGIN:VEVENT
UID:foo
CLASS:PUBLIC
DTSTART;VALUE=DATE:19931231
DTSTAMP:20240422T070855Z
CREATED:
LAST-MODIFIED:
DESCRIPTION:bar
END:VEVENT
ICS;

$vcal = VObject\Reader::read($defectiveInput);
$result = $vcal->validate();
$warningMessages = [];
foreach ($result as $error) {
$warningMessages[] = $error['message'];
}
self::assertCount(2, $result, 'We expected exactly 2 validation messages, instead we got '.count($result).' results:'.implode(', ', $warningMessages));
foreach ($result as $idx => $warning) {
self::assertArrayHasKey('node', $warning, 'The validation errors should contain a node key');
self::assertInstanceOf(VObject\Property\ICalendar\DateTime::class, $warning['node'], 'We expected the defective node to be of type Sabre\VObject\Property\ICalendar\DateTime, instead we got type '.gettype($warning['node']));
self::assertObjectHasProperty('lineIndex', $warning['node'], 'We expected the defective node in the validation errors array to have a "lineIndex" property');
self::assertObjectHasProperty('lineString', $warning['node'], 'We expected the defective node in the validation errors array to have a "lineString" property');
switch ($idx) {
case 0:
self::assertEquals('10', $warning['node']->lineIndex, 'We expected the "lineIndex" property of the first defective node to be 10, instead it was '.$warning['node']->lineIndex);
self::assertEquals('CREATED:', $warning['node']->lineString, 'We expected the "lineString" property of the first defective node to be "CREATED:", instead it was '.$warning['node']->lineString);
break;
case 1:
self::assertEquals('11', $warning['node']->lineIndex, 'We expected the "lineIndex" property of the second defective node to be 11, instead it was '.$warning['node']->lineIndex);
self::assertEquals('LAST-MODIFIED:', $warning['node']->lineString, 'We expected the "lineString" property of the second defective node to be "LAST-MODIFIED:", instead it was '.$warning['node']->lineString);
break;
}
JohnRDOrazio marked this conversation as resolved.
Show resolved Hide resolved
}
}

public function assertValidate($ics, $options, $expectedLevel, ?string $expectedMessage = null): void
{
$vcal = VObject\Reader::read($ics);
Expand Down