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 all 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);
self::assertInstanceOf(VObject\Property\ICalendar\DateTime::class, $warning['node']);
self::assertObjectHasProperty('lineIndex', $warning['node']);
self::assertObjectHasProperty('lineString', $warning['node']);
switch ($idx) {
case 0:
self::assertEquals('10', $warning['node']->lineIndex);
self::assertEquals('CREATED:', $warning['node']->lineString);
break;
case 1:
self::assertEquals('11', $warning['node']->lineIndex);
self::assertEquals('LAST-MODIFIED:', $warning['node']->lineString);
break;
}
}
}

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