Skip to content

Commit

Permalink
Ability to access an objects group
Browse files Browse the repository at this point in the history
  • Loading branch information
Riley19280 committed Jan 16, 2024
1 parent a27292d commit 1fd72b5
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 6 deletions.
13 changes: 13 additions & 0 deletions src/Exceptions/InvalidDataException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace MiroClipboard\Exceptions;

use Throwable;

class InvalidDataException extends MiroDataException
{
public function __construct(int $code = 0, ?Throwable $previous = null)
{
parent::__construct('Unable to parse miro clipboard data', $code, $previous);
}
}
7 changes: 7 additions & 0 deletions src/Exceptions/MiroDataException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace MiroClipboard\Exceptions;

class MiroDataException extends \Exception
{
}
2 changes: 1 addition & 1 deletion src/Exceptions/ParserNotResolvedException.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use Throwable;

class ParserNotResolvedException extends \Exception
class ParserNotResolvedException extends MiroDataException
{
public function __construct(string $parserType, int $code = 0, ?Throwable $previous = null)
{
Expand Down
4 changes: 4 additions & 0 deletions src/MiroParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use MiroClipboard\Parsers\LineParser;
use MiroClipboard\Parsers\MiroParserInterface;
use MiroClipboard\Parsers\ShapeParser;
use MiroClipboard\Utility\HasGroup;

use function MiroClipboard\MiroUtility\decodeMiroDataString;

Expand Down Expand Up @@ -40,6 +41,9 @@ public static function parse(string|array $data): MiroClipboardData
if (method_exists($object, 'resolveClipboardDataReferences')) {
$object->resolveClipboardDataReferences($newClipboardData);
}
if (in_array(HasGroup::class, class_uses($object))) {
$object->resolveGroupClipboardDataReferences($newClipboardData);
}
}

return $newClipboardData;
Expand Down
17 changes: 17 additions & 0 deletions src/Objects/MiroGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use MiroClipboard\Enums\ObjectType;
use MiroClipboard\MiroClipboardData;
use MiroClipboard\Utility\HasGroup;
use MiroClipboard\Utility\Makeable;

class MiroGroup extends MiroObject
Expand Down Expand Up @@ -33,6 +34,10 @@ public function __construct()
public function add(int|MiroObject $object): static
{
if ($object instanceof MiroObject) {
if (in_array(HasGroup::class, class_uses($object))) {
$object->setGroup($this);

Check failure on line 38 in src/Objects/MiroGroup.php

View workflow job for this annotation

GitHub Actions / phpstan

Call to an undefined method MiroClipboard\Objects\MiroObject::setGroup().
}

$this->objects[] = $object;
$this->ids[] = $object->id;
} else {
Expand All @@ -50,6 +55,18 @@ public function getObjects(): array
return $this->objects;
}

public function findObject(int|MiroObject $object): false|MiroObject
{
$searchId = is_int($object) ? $object : $object->getId();
foreach ($this->objects as $existing) {
if ($existing->getId() === $searchId) {
return $existing;
}
}

return false;
}

/**
* @param MiroClipboardData $clipboardData
*
Expand Down
2 changes: 2 additions & 0 deletions src/Objects/MiroLine.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
use MiroClipboard\MiroClipboardData;
use MiroClipboard\MiroWidget;
use MiroClipboard\Styles\MiroLineStyle;
use MiroClipboard\Utility\HasGroup;
use MiroClipboard\Utility\SetPropertiesFromArray;

class MiroLine extends MiroWidget
{
use HasGroup;
use SetPropertiesFromArray;

private MiroLineStyle $lineStyle;
Expand Down
2 changes: 2 additions & 0 deletions src/Objects/MiroShape.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
use MiroClipboard\Enums\WidgetType;
use MiroClipboard\MiroWidget;
use MiroClipboard\Styles\MiroShapeStyle;
use MiroClipboard\Utility\HasGroup;
use MiroClipboard\Utility\SetPropertiesFromArray;

class MiroShape extends MiroWidget
{
use HasGroup;
use SetPropertiesFromArray;

private MiroShapeStyle $shapeStyle;
Expand Down
46 changes: 46 additions & 0 deletions src/Utility/HasGroup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace MiroClipboard\Utility;

use MiroClipboard\MiroClipboardData;
use MiroClipboard\Objects\MiroGroup;

trait HasGroup
{
protected ?MiroGroup $group = null;

public function group(): ?MiroGroup
{
return $this->group;
}

/**
* @internal
*/
public function setGroup(MiroGroup $group): static
{
$this->group = $group;

return $this;
}

/**
* @param MiroClipboardData $clipboardData
*
* @return void
*
* @internal
*/
public function resolveGroupClipboardDataReferences(MiroClipboardData $clipboardData): void
{
foreach ($clipboardData->getObjects() as $object) {
if ($object instanceof MiroGroup) {
if (in_array($this->getId(), $found = $object->toArray()['items'])) {
if (in_array(HasGroup::class, class_uses(static::class))) {
$this->group = $object;
}
}
}
}
}
}
7 changes: 6 additions & 1 deletion src/Utility/MiroUtility.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace MiroClipboard\MiroUtility;

use MiroClipboard\Exceptions\InvalidDataException;

use function MiroClipboard\Utility\stringToByteArray;

function encodeMiroData(array $data, int $encodingOffset = 59): string
Expand All @@ -21,9 +23,12 @@ function encodeMiroData(array $data, int $encodingOffset = 59): string

function decodeMiroDataString(string $text, int $encodingOffset = 59): array
{
$isHtml = preg_match('/(?:^.*?\(miro-data-v[0-9]+\))(.*?)(?:\(\/miro-data-v[0-9]+\).*?$)/', $text, $matches);
$isHtml = preg_match('/(?:^.*?\(miro-data-v[0-9]+\))(.*?)(?:\(\/miro-data-v[0-9]+\).*?$)/m', $text, $matches);

if ($isHtml) {
$text = $matches[1];
} else {
throw new InvalidDataException();
}

$text = base64_decode($text);
Expand Down
2 changes: 2 additions & 0 deletions src/Utility/SetPropertiesFromArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ enum_exists($enumName = $propType->getName()) &&
) {
/** @phpstan-ignore-next-line */
$this->$key = $enumName::from($val);
} elseif ($propType->allowsNull() && empty($val)) {
$this->$key = null;
} else {
$this->$key = $val;
}
Expand Down
31 changes: 27 additions & 4 deletions tests/Unit/MiroGroupTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,35 @@
test('create group from array', function() {
$clipboardData = MiroClipboardData::make()
->addGroup([
MiroWidget::make()->shape()->text('hello')->position(100, 100),
MiroWidget::make()->shape()->text('world')->position(200, 200),
$shape1 = MiroWidget::make()->shape()->text('hello')->position(100, 100),
$shape2 = MiroWidget::make()->shape()->text('world')->position(200, 200),
]);

expect($clipboardData->getObjects())->toHaveCount(3);

expect($shape1->group())->toEqual($clipboardData->getObjects()[2]);
expect($shape2->group())->toEqual($clipboardData->getObjects()[2]);
});

test('create group from object', function() {
$group = MiroGroup::make()
->add(MiroWidget::make()->shape()->text('test1')->position(100, 100))
->add(MiroWidget::make()->shape()->text('test2')->position(200, 200));
->add($shape1 = MiroWidget::make()->shape()->text('test1')->position(100, 100))
->add($shape2 = MiroWidget::make()->shape()->text('test2')->position(200, 200));

$clipboardData = MiroClipboardData::make()->addObject($group);

expect($clipboardData->getObjects())->toHaveCount(3);
expect(array_map(fn($x) => get_class($x), $clipboardData->getObjects()))->toBe([MiroShape::class, MiroShape::class, MiroGroup::class]);

expect($shape1->group())->toEqual($group);
expect($shape2->group())->toEqual($group);
});

test('can get group of object', function() {
$group = MiroGroup::make()
->add($shape = MiroWidget::make()->shape()->text('test1')->position(100, 100));

expect($shape->group())->toEqual($group);
});

test('group to array', function() {
Expand All @@ -34,3 +47,13 @@

expect($group->toArray()['items'])->toBe([123, 456, 987]);
});

test('find object in group', function() {
$group = MiroGroup::make();

expect($group->findObject(123))->toBeFalse();

$group->add(MiroWidget::make()->id(123)->shape()->text('test1')->position(100, 100));

expect($group->findObject(123))->toBeInstanceOf(MiroShape::class);
});
30 changes: 30 additions & 0 deletions tests/Unit/ParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use MiroClipboard\Parsers\ShapeParser;
use MiroClipboard\Styles\MiroLineStyle;
use MiroClipboard\Styles\MiroShapeStyle;
use MiroClipboard\Utility\SetPropertiesFromArray;

test('parse string', function() {
$shape = MiroWidget::make()->shape()->position(1.1, 1.1);
Expand Down Expand Up @@ -142,6 +143,19 @@
expect(invade($parsedData->getObjects()[2])->objects)->toHaveCount(2);
});

test('parsed objects part of a group have a group reference', function() {
$clipboardData = MiroClipboardData::make()
->addGroup(MiroGroup::make()
->add(MiroWidget::make()->shape()->text('hello')->position(100, 100))
);

$parsedData = MiroClipboardData::parse($clipboardData->toHTML());

expect($shape = $parsedData->getObjects()[0])->toBeInstanceOf(MiroShape::class);

expect($shape->group())->toEqual($parsedData->getObjects()[1]);
});

test('line object to and from objects are set', function() {
$clipboardData = MiroClipboardData::make()
->addObject(MiroLine::make()->id(1)
Expand All @@ -159,3 +173,19 @@
expect(invade($line)->fromObject)->toBeInstanceOf(MiroShape::class);
expect(invade($line)->toObject)->toBeInstanceOf(MiroShape::class);
});

test('throws with invalid data', function() {
MiroParser::parse('test');
})->throws(\MiroClipboard\Exceptions\InvalidDataException::class);

test('parsing empty string into nullable field', function() {
$instance = new class()
{
public ?string $field;
use SetPropertiesFromArray;
};

$instance->setPropertiesFromArray(['field' => '']);

expect($instance->field)->toBeNull();
});

0 comments on commit 1fd72b5

Please sign in to comment.