Skip to content

Commit 028b282

Browse files
committed
Implement new AttributeBag plus AttributeAware interfaces
1 parent 79bc948 commit 028b282

8 files changed

Lines changed: 372 additions & 0 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace Fhaculty\Graph\Attribute;
4+
5+
/**
6+
* Implemented by any entity that is aware of additional attributes
7+
*
8+
* Each attribute consists of a name (string) and an arbitrary value.
9+
*/
10+
interface AttributeAware
11+
{
12+
/**
13+
* get a single attribute with the given $name
14+
*
15+
* @param string $name
16+
* @return mixed|null
17+
*/
18+
public function getAttribute($name);
19+
20+
/**
21+
* set a single attribute with the given $name to given $value
22+
*
23+
* @param string $name
24+
* @param mixed $value
25+
*/
26+
public function setAttribute($name, $value);
27+
28+
/**
29+
* get a container for all attributes
30+
*
31+
* @return AttributeBag
32+
*/
33+
public function getAttributeBag();
34+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace Fhaculty\Graph\Attribute;
4+
5+
/**
6+
* Interface to container that represents multiple attributes
7+
*/
8+
interface AttributeBag extends AttributeAware
9+
{
10+
// public function getAttribute($name);
11+
// public function setAttribute($name, $value);
12+
// public function getAttributeBag();
13+
14+
/**
15+
* set an array of additional attributes
16+
*
17+
* @param array $attributes
18+
*/
19+
public function setAttributes(array $attributes);
20+
21+
/**
22+
* get an array of all attributes
23+
*
24+
* @return array
25+
*/
26+
public function getAttributes();
27+
28+
/**
29+
* get an array of the names of all existing attributes
30+
*
31+
* @return string[]
32+
*/
33+
public function getNames();
34+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Fhaculty\Graph\Attribute;
4+
5+
class AttributeBagContainer implements AttributeBag
6+
{
7+
private $attributes = array();
8+
9+
public function getAttribute($name)
10+
{
11+
return isset($this->attributes[$name]) ? $this->attributes[$name] : null;
12+
}
13+
14+
public function setAttribute($name, $value)
15+
{
16+
$this->attributes[$name] = $value;
17+
18+
return $this;
19+
}
20+
21+
public function getAttributes()
22+
{
23+
return $this->attributes;
24+
}
25+
26+
public function setAttributes(array $attributes)
27+
{
28+
$this->attributes = $attributes + $this->attributes;
29+
30+
return $this;
31+
}
32+
33+
public function getNames()
34+
{
35+
return array_keys($this->attributes);
36+
}
37+
38+
public function getAttributeBag()
39+
{
40+
return $this;
41+
}
42+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
namespace Fhaculty\Graph\Attribute;
4+
5+
/**
6+
* An attribute bag that automatically prefixes a given namespace
7+
*/
8+
class AttributeBagNamespaced implements AttributeBag
9+
{
10+
private $bag;
11+
private $prefix;
12+
13+
public function __construct(AttributeAware $bag, $prefix)
14+
{
15+
if (!($bag instanceof AttributeBag)) {
16+
$bag = $bag->getAttributeBag();
17+
}
18+
$this->bag = $bag;
19+
$this->prefix = $prefix;
20+
}
21+
22+
public function getAttribute($name)
23+
{
24+
return $this->bag->getAttribute($this->prefix . $name);
25+
}
26+
27+
public function setAttribute($name, $value)
28+
{
29+
$this->bag->setAttribute($this->prefix . $name, $value);
30+
}
31+
32+
public function getAttributes()
33+
{
34+
$attributes = array();
35+
$len = strlen($this->prefix);
36+
37+
foreach ($this->bag->getAttributes() as $name => $value) {
38+
if (strpos($name, $this->prefix) === 0) {
39+
$attributes[substr($name, $len)] = $value;
40+
}
41+
}
42+
43+
return $attributes;
44+
}
45+
46+
public function setAttributes(array $attributes)
47+
{
48+
foreach ($attributes as $name => $value) {
49+
$this->bag->setAttribute($this->prefix . $name, $value);
50+
}
51+
}
52+
53+
public function getNames()
54+
{
55+
$names = array();
56+
$len = strlen($this->prefix);
57+
58+
foreach ($this->bag->getAttributes() as $name => $value) {
59+
if (strpos($name, $this->prefix) === 0) {
60+
$names []= substr($name, $len);
61+
}
62+
}
63+
64+
return $names;
65+
}
66+
67+
public function getAttributeBag()
68+
{
69+
return $this;
70+
}
71+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace Fhaculty\Graph\Attribute;
4+
5+
class AttributeBagReference implements AttributeBag
6+
{
7+
private $attributes;
8+
9+
public function __construct(array &$attributes)
10+
{
11+
$this->attributes =& $attributes;
12+
}
13+
14+
public function getAttribute($name)
15+
{
16+
return isset($this->attributes[$name]) ? $this->attributes[$name] : null;
17+
}
18+
19+
public function setAttribute($name, $value)
20+
{
21+
$this->attributes[$name] = $value;
22+
23+
return $this;
24+
}
25+
26+
public function getAttributes()
27+
{
28+
return $this->attributes;
29+
}
30+
31+
public function setAttributes(array $attributes)
32+
{
33+
$this->attributes = $attributes + $this->attributes;
34+
35+
return $this;
36+
}
37+
38+
public function getNames()
39+
{
40+
return array_keys($this->attributes);
41+
}
42+
43+
public function getAttributeBag()
44+
{
45+
return $this;
46+
}
47+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
use Fhaculty\Graph\Attribute\AttributeBagContainer;
4+
5+
class AttributeBagContainerTest extends TestCase
6+
{
7+
public function testEmpty()
8+
{
9+
$bag = new AttributeBagContainer();
10+
11+
$this->assertNull($bag->getAttribute('unknown'));
12+
$this->assertEquals(array(), $bag->getAttributes());
13+
$this->assertEquals(array(), $bag->getNames());
14+
15+
$this->assertSame($bag, $bag->getAttributeBag());
16+
}
17+
18+
public function testSome()
19+
{
20+
$bag = new AttributeBagContainer();
21+
22+
$bag->setAttribute('true', true);
23+
$bag->setAttribute('two', 2);
24+
25+
$this->assertSame(true, $bag->getAttribute('true'));
26+
$this->assertSame(2, $bag->getAttribute('two'));
27+
$this->assertEquals(array('true', 'two'), $bag->getNames());
28+
29+
$bag->setAttribute('float', '1.2');
30+
$bag->setAttributes(array('two' => 'two', 'three' => 3));
31+
32+
$expected = array('true' => true, 'two' => 'two', 'float' => 1.2, 'three' => 3);
33+
$this->assertEquals($expected, $bag->getAttributes());
34+
}
35+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
use Fhaculty\Graph\Graph;
4+
use Fhaculty\Graph\Attribute\AttributeBagNamespaced;
5+
use Fhaculty\Graph\Attribute\AttributeAware;
6+
use Fhaculty\Graph\Attribute\AttributeBagContainer;
7+
8+
class AtributeBagNamespacedTest extends TestCase
9+
{
10+
public function testBagContainer()
11+
{
12+
$container = new AttributeBagContainer();
13+
$bag = new AttributeBagNamespaced($container, 'test.');
14+
$this->assertSame($bag, $bag->getAttributeBag());
15+
16+
$container->setAttribute('a.b', 'c');
17+
$container->setAttribute('test.d', 'e');
18+
19+
$this->assertEquals('e', $bag->getAttribute('d'));
20+
21+
$bag->setAttribute('d', 'test');
22+
23+
$this->assertEquals('test', $bag->getAttribute('d'));
24+
$this->assertEquals('test', $container->getAttribute('test.d'));
25+
26+
$bag->setAttributes(array('d' => 'd', 'e' => 'e'));
27+
28+
$this->assertEquals(array('d', 'e'), $bag->getNames());
29+
$this->assertEquals(array('a.b', 'test.d', 'test.e'), $container->getNames());
30+
}
31+
32+
/**
33+
*
34+
* @param AttributeAware $entity
35+
* @dataProvider provideNamespacable
36+
*/
37+
public function testReadableEntities(AttributeAware $entity)
38+
{
39+
$bag = new AttributeBagNamespaced($entity, 'test.');
40+
$this->assertSame($bag, $bag->getAttributeBag());
41+
42+
$entity->setAttribute('a.b', 'c');
43+
$entity->setAttribute('test.d', 'e');
44+
45+
$this->assertEquals('e', $bag->getAttribute('d'));
46+
47+
$this->assertNull($bag->getAttribute('a.b'));
48+
$this->assertNull($bag->getAttribute('test.d'));
49+
50+
$this->assertEquals(array('d' => 'e'), $bag->getAttributes());
51+
$this->assertEquals(array('d'), $bag->getNames());
52+
}
53+
54+
public function provideNamespacable()
55+
{
56+
$graph = new Graph();
57+
$vertex = $graph->createVertex();
58+
$bag = $vertex->getAttributeBag();
59+
$subNamespace = new AttributeBagNamespaced($bag, 'prefix');
60+
61+
return array(
62+
array($graph),
63+
array($vertex),
64+
array($bag),
65+
array($subNamespace),
66+
);
67+
}
68+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
use Fhaculty\Graph\Attribute\AttributeBagReference;
4+
5+
class AttributeBagReferenceTest extends TestCase
6+
{
7+
public function testEmpty()
8+
{
9+
$attributes = array();
10+
11+
$bag = new AttributeBagReference($attributes);
12+
13+
$this->assertNull($bag->getAttribute('unknown'));
14+
$this->assertEquals(array(), $bag->getAttributes());
15+
$this->assertEquals(array(), $bag->getNames());
16+
17+
$this->assertSame($bag, $bag->getAttributeBag());
18+
}
19+
20+
public function testSome()
21+
{
22+
$attributes = array(
23+
'true' => true,
24+
'two' => 2,
25+
);
26+
27+
$bag = new AttributeBagReference($attributes);
28+
29+
$this->assertSame(true, $bag->getAttribute('true'));
30+
$this->assertSame(2, $bag->getAttribute('two'));
31+
$this->assertEquals(array('true', 'two'), $bag->getNames());
32+
33+
$bag->setAttribute('float', '1.2');
34+
$bag->setAttributes(array('two' => 'two', 'three' => 3));
35+
36+
$expected = array('true' => true, 'two' => 'two', 'float' => 1.2, 'three' => 3);
37+
$this->assertEquals($expected, $bag->getAttributes());
38+
39+
$this->assertEquals($expected, $attributes);
40+
}
41+
}

0 commit comments

Comments
 (0)