diff --git a/README.md b/README.md
index 62eddd6be..eed457288 100644
--- a/README.md
+++ b/README.md
@@ -58,6 +58,18 @@ $localBusiness->name('Spatie');
> *All types also accept arrays of the expected data type, for example `sameAs` accepts a string or an array of strings.*
+All types also implement the SPL's `ArrayAccess` for accessing the properties via array notation:
+
+```php
+$anotherLocalBusiness = new LocalBusiness();
+var_dump(isset($anotherLocalBusiness['name'])); // => false
+$anotherLocalBusiness['name'] = 'Spatie';
+var_dump(isset($anotherLocalBusiness['name'])); // => true
+var_dump($anotherLocalBusiness['name']); // => 'Spatie'
+unset($anotherLocalBusiness['name']);
+var_dump(isset($anotherLocalBusiness['name'])); // => false
+```
+
Types can be converted to an array or rendered to a script.
```php
@@ -68,6 +80,12 @@ $localBusiness->toScript();
echo $localBusiness; // Same output as `toScript()`
```
+Additionally, all types can be converted to a plain JSON string by just calling `json_encode()` with your object:
+
+```php
+echo json_encode($localBusiness);
+```
+
There's no full API documentation for types and properties. You can refer to [the source](https://github.com/spatie/schema-org/tree/master/src) or to [the schema.org website](http://schema.org).
If you don't want to break the chain of a large schema object, you can use the `if` method to conditionally modify the schema.
diff --git a/generator/templates/static/BaseType.php b/generator/templates/static/BaseType.php
index 1b6581dc1..720b6a580 100644
--- a/generator/templates/static/BaseType.php
+++ b/generator/templates/static/BaseType.php
@@ -7,7 +7,7 @@
use DateTimeInterface;
use Spatie\SchemaOrg\Exceptions\InvalidProperty;
-abstract class BaseType implements Type
+abstract class BaseType implements Type, \ArrayAccess, \JsonSerializable
{
/** @var array */
protected $properties = [];
@@ -57,6 +57,26 @@ public function getProperties(): array
return $this->properties;
}
+ public function offsetExists($offset)
+ {
+ return array_key_exists($offset, $this->properties);
+ }
+
+ public function offsetGet($offset)
+ {
+ return $this->getProperty($offset);
+ }
+
+ public function offsetSet($offset, $value)
+ {
+ $this->setProperty($offset, $value);
+ }
+
+ public function offsetUnset($offset)
+ {
+ unset($this->properties[$offset]);
+ }
+
public function toArray(): array
{
$properties = $this->serializeProperty($this->getProperties());
@@ -94,6 +114,11 @@ public function toScript(): string
return '';
}
+ public function jsonSerialize()
+ {
+ return $this->toArray();
+ }
+
public function __call(string $method, array $arguments)
{
return $this->setProperty($method, $arguments[0] ?? '');
diff --git a/src/BaseType.php b/src/BaseType.php
index 1b6581dc1..720b6a580 100644
--- a/src/BaseType.php
+++ b/src/BaseType.php
@@ -7,7 +7,7 @@
use DateTimeInterface;
use Spatie\SchemaOrg\Exceptions\InvalidProperty;
-abstract class BaseType implements Type
+abstract class BaseType implements Type, \ArrayAccess, \JsonSerializable
{
/** @var array */
protected $properties = [];
@@ -57,6 +57,26 @@ public function getProperties(): array
return $this->properties;
}
+ public function offsetExists($offset)
+ {
+ return array_key_exists($offset, $this->properties);
+ }
+
+ public function offsetGet($offset)
+ {
+ return $this->getProperty($offset);
+ }
+
+ public function offsetSet($offset, $value)
+ {
+ $this->setProperty($offset, $value);
+ }
+
+ public function offsetUnset($offset)
+ {
+ unset($this->properties[$offset]);
+ }
+
public function toArray(): array
{
$properties = $this->serializeProperty($this->getProperties());
@@ -94,6 +114,11 @@ public function toScript(): string
return '';
}
+ public function jsonSerialize()
+ {
+ return $this->toArray();
+ }
+
public function __call(string $method, array $arguments)
{
return $this->setProperty($method, $arguments[0] ?? '');
diff --git a/tests/BaseTypeTest.php b/tests/BaseTypeTest.php
index fb9e9abe8..5b238b088 100644
--- a/tests/BaseTypeTest.php
+++ b/tests/BaseTypeTest.php
@@ -186,6 +186,73 @@ public function it_can_set_a_property_via_a_magic_call_method()
$this->assertEquals(['foo' => 'bar'], $type->getProperties());
}
+
+ /** @test */
+ public function it_can_use_array_access_to_set_a_property()
+ {
+ $type = new DummyType();
+
+ $type['foo'] = 'bar';
+
+ $this->assertEquals(['foo' => 'bar'], $type->getProperties());
+ }
+
+ /** @test */
+ public function it_can_use_array_access_to_unset_a_property()
+ {
+ $type = new DummyType();
+
+ $type->setProperty('foo', 'bar');
+ $type->setProperty('bar', 'baz');
+ unset($type['foo']);
+
+ $this->assertEquals(['bar' => 'baz'], $type->getProperties());
+ }
+
+ /** @test */
+ public function it_can_use_array_access_to_determine_if_a_property_exists()
+ {
+ $type = new DummyType();
+
+ $type->setProperty('foo', 'bar');
+
+ $this->assertTrue(isset($type['foo']));
+ $this->assertFalse(isset($type['bar']));
+ }
+
+ /** @test */
+ public function it_can_use_array_access_to_get_a_property()
+ {
+ $type = new DummyType();
+
+ $type->setProperty('foo', 'bar');
+
+ $this->assertEquals('bar', $type['foo']);
+ }
+
+ /** @test */
+ public function it_can_be_json_serialized()
+ {
+ $type = new DummyType();
+ $child = new DummyType();
+ $child->setProperty('bar', 'baz');
+
+ $type->setProperty('foo', 'bar');
+ $type->setProperty('child', $child);
+
+ $expected = [
+ '@context' => 'http://schema.org',
+ '@type' => 'DummyType',
+ 'foo' => 'bar',
+ 'child' => [
+ '@type' => 'DummyType',
+ 'bar' => 'baz',
+ ],
+ ];
+
+ $this->assertEquals($expected, $type->jsonSerialize(), 'Return value of `jsonSerialize` is wrong');
+ $this->assertEquals(json_encode($expected), json_encode($type), 'JSON representation is wrong');
+ }
}
class DummyType extends BaseType