Skip to content

Commit

Permalink
Add select database properties
Browse files Browse the repository at this point in the history
  • Loading branch information
mariosimao committed Oct 31, 2021
1 parent 86a8ab7 commit 83d3d5c
Show file tree
Hide file tree
Showing 7 changed files with 380 additions and 8 deletions.
2 changes: 2 additions & 0 deletions src/Databases/Properties/Factory.php
Expand Up @@ -17,6 +17,8 @@ public static function fromArray(array $array): PropertyInterface
Property::TYPE_TITLE => Title::fromArray($array),
Property::TYPE_RICH_TEXT => RichText::fromArray($array),
Property::TYPE_NUMBER => Number::fromArray($array),
Property::TYPE_SELECT => Select::fromArray($array),
Property::TYPE_MULTI_SELECT => MultiSelect::fromArray($array),
default => throw new Exception("Invalid property type: '{$type}'"),
};
}
Expand Down
85 changes: 85 additions & 0 deletions src/Databases/Properties/MultiSelect.php
@@ -0,0 +1,85 @@
<?php

namespace Notion\Databases\Properties;

/**
* @psalm-import-type SelectOptionJson from SelectOption
*
* @psalm-type MultiSelectJson = array{
* id: string,
* name: string,
* type: "multi_select",
* multi_select: array{ options: SelectOptionJson[] },
* }
*/
class MultiSelect implements PropertyInterface
{
private const TYPE = Property::TYPE_MULTI_SELECT;

private Property $property;
/** @var SelectOption[] */
private array $options;

/** @param SelectOption[] $options */
private function __construct(Property $property, array $options)
{
$this->property = $property;
$this->options = $options;
}

/** @param SelectOption[] $options */
public static function create(string $propertyName = "Multi Select", array $options = []): self
{
$property = Property::create("", $propertyName, self::TYPE);

return new self($property, $options);
}

public function property(): Property
{
return $this->property;
}

/** @return SelectOption[] */
public function options(): array
{
return $this->options;
}

public function withOptions(SelectOption ...$options): self
{
return new self($this->property, $options);
}

public function addOption(SelectOption $option): self
{
$options = $this->options;
$options[] = $option;

return new self($this->property, $options);
}

public static function fromArray(array $array): self
{
/** @psalm-var MultiSelectJson $array */
$property = Property::fromArray($array);
$options = array_map(
function (array $option): SelectOption {
return SelectOption::fromArray($option);
},
$array[self::TYPE]["options"],
);

return new self($property, $options);
}

public function toArray(): array
{
$array = $this->property->toArray();
$array[self::TYPE] = [
"options" => array_map(fn(SelectOption $o) => $o->toArray(), $this->options),
];

return $array;
}
}
16 changes: 8 additions & 8 deletions src/Databases/Properties/Property.php
Expand Up @@ -90,15 +90,15 @@ public function isNumber(): bool
return $this->type === self::TYPE_NUMBER;
}

// public function isSelect(): bool
// {
// return $this->type === self::TYPE_SELECT;
// }
public function isSelect(): bool
{
return $this->type === self::TYPE_SELECT;
}

// public function isMultiSelect(): bool
// {
// return $this->type === self::TYPE_MULTI_SELECT;
// }
public function isMultiSelect(): bool
{
return $this->type === self::TYPE_MULTI_SELECT;
}

// public function isDate(): bool
// {
Expand Down
85 changes: 85 additions & 0 deletions src/Databases/Properties/Select.php
@@ -0,0 +1,85 @@
<?php

namespace Notion\Databases\Properties;

/**
* @psalm-import-type SelectOptionJson from SelectOption
*
* @psalm-type SelectJson = array{
* id: string,
* name: string,
* type: "select",
* select: array{ options: SelectOptionJson[] },
* }
*/
class Select implements PropertyInterface
{
private const TYPE = Property::TYPE_SELECT;

private Property $property;
/** @var SelectOption[] */
private array $options;

/** @param SelectOption[] $options */
private function __construct(Property $property, array $options)
{
$this->property = $property;
$this->options = $options;
}

/** @param SelectOption[] $options */
public static function create(string $propertyName = "Select", array $options = []): self
{
$property = Property::create("", $propertyName, self::TYPE);

return new self($property, $options);
}

public function property(): Property
{
return $this->property;
}

/** @return SelectOption[] */
public function options(): array
{
return $this->options;
}

public function withOptions(SelectOption ...$options): self
{
return new self($this->property, $options);
}

public function addOption(SelectOption $option): self
{
$options = $this->options;
$options[] = $option;

return new self($this->property, $options);
}

public static function fromArray(array $array): self
{
/** @psalm-var SelectJson $array */
$property = Property::fromArray($array);
$options = array_map(
function (array $option): SelectOption {
return SelectOption::fromArray($option);
},
$array[self::TYPE]["options"],
);

return new self($property, $options);
}

public function toArray(): array
{
$array = $this->property->toArray();
$array[self::TYPE] = [
"options" => array_map(fn(SelectOption $o) => $o->toArray(), $this->options),
];

return $array;
}
}
84 changes: 84 additions & 0 deletions src/Databases/Properties/SelectOption.php
@@ -0,0 +1,84 @@
<?php

namespace Notion\Databases\Properties;

/**
* @psalm-type SelectOptionJson = array{
* id: string,
* name: string,
* color: string,
* }
*/
class SelectOption
{
public const COLOR_DEFAULT = "default";
public const COLOR_GRAY = "gray";
public const COLOR_BROWN = "brown";
public const COLOR_ORANGE = "orange";
public const COLOR_YELLOW = "yellow";
public const COLOR_GREEN = "green";
public const COLOR_BLUE = "blue";
public const COLOR_PURPLE = "purple";
public const COLOR_PINK = "pink";
public const COLOR_RED = "red";

private string $id;
private string $name;
private string $color;

private function __construct(string $id, string $name, string $color)
{
$this->id = $id;
$this->name = $name;
$this->color = $color;
}

public static function create(string $name, string $color = "default"): self
{
return new self("", $name, $color);
}

public function id(): string
{
return $this->id;
}

public function name(): string
{
return $this->name;
}

public function color(): string
{
return $this->color;
}

public function withName(string $newName): self
{
return new self($this->id, $newName, $this->color);
}

public function withColor(string $newColor): self
{
return new self($this->id, $this->name, $newColor);
}

public static function fromArray(array $array): self
{
/** @psalm-var SelectOptionJson $array */
return new self(
$array["id"],
$array["name"],
$array["color"],
);
}

public function toArray(): array
{
return [
"id" => $this->id,
"name" => $this->name,
"color" => $this->color,
];
}
}
58 changes: 58 additions & 0 deletions tests/Unit/Databases/Properties/MultiSelectTest.php
@@ -0,0 +1,58 @@
<?php

namespace Notion\Test\Unit\Databases\Properties;

use Notion\Databases\Properties\Factory;
use Notion\Databases\Properties\MultiSelect;
use Notion\Databases\Properties\SelectOption;
use PHPUnit\Framework\TestCase;

class MultiSelectTest extends TestCase
{
public function test_create(): void
{
$select = MultiSelect::create("Dummy prop name");

$this->assertEquals("Dummy prop name", $select->property()->name());
$this->assertTrue($select->property()->isMultiSelect());
$this->assertEmpty($select->options());
}

public function test_replace_options(): void
{
$select = MultiSelect::create()->withOptions(
SelectOption::create("Option A"),
SelectOption::create("Option B"),
);

$this->assertCount(2, $select->options());
}

public function test_add_option(): void
{
$option = SelectOption::create("Option A");
$select = MultiSelect::create()->addOption($option);

$this->assertEquals([ $option ], $select->options());
}

public function test_array_conversion(): void
{
$array = [
"id" => "abc",
"name" => "MultiSelect",
"type" => "multi_select",
"multi_select" => [
"options" => [
[ "id" => "aaa", "name" => "Option A", "color" => "default" ],
[ "id" => "bbb", "name" => "Option B", "color" => "default" ],
],
],
];
$select = MultiSelect::fromArray($array);
$fromFactory = Factory::fromArray($array);

$this->assertEquals($array, $select->toArray());
$this->assertEquals($array, $fromFactory->toArray());
}
}

0 comments on commit 83d3d5c

Please sign in to comment.