Skip to content
This repository was archived by the owner on Jun 26, 2025. It is now read-only.

Commit d306905

Browse files
committed
Abstract implementation of the CollectionInterface.
1 parent 1ad8a97 commit d306905

File tree

1 file changed

+173
-0
lines changed

1 file changed

+173
-0
lines changed

src/AbstractCollection.php

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
<?php
2+
3+
namespace TwoDotsTwice\Collection;
4+
5+
use TwoDotsTwice\Collection\Exception\CollectionItemNotFoundException;
6+
use TwoDotsTwice\Collection\Exception\CollectionKeyNotFoundException;
7+
8+
abstract class AbstractCollection implements CollectionInterface
9+
{
10+
/**
11+
* @var array
12+
*/
13+
protected $items;
14+
15+
public function __construct()
16+
{
17+
$this->items = array();
18+
}
19+
20+
/**
21+
* @inheritdoc
22+
*/
23+
public function with($item, $key = null)
24+
{
25+
$this->guardObjectType($item);
26+
27+
$copy = clone $this;
28+
29+
if (is_null($key)) {
30+
$copy->items[] = $item;
31+
} else {
32+
$copy->items[$key] = $item;
33+
}
34+
35+
return $copy;
36+
}
37+
38+
/**
39+
* @inheritdoc
40+
*/
41+
public function without($item)
42+
{
43+
$key = $this->getKeyFor($item);
44+
45+
$copy = clone $this;
46+
unset($copy->items[$key]);
47+
return $copy;
48+
}
49+
50+
/**
51+
* @inheritdoc
52+
*/
53+
public function withoutKey($key)
54+
{
55+
if (!isset($this->items[$key])) {
56+
throw new CollectionKeyNotFoundException($key);
57+
}
58+
59+
$copy = clone $this;
60+
unset($copy->items[$key]);
61+
return $copy;
62+
}
63+
64+
/**
65+
* @inheritdoc
66+
*/
67+
public function getByKey($key)
68+
{
69+
if (!isset($this->items[$key])) {
70+
throw new CollectionKeyNotFoundException($key);
71+
}
72+
73+
return $this->items[$key];
74+
}
75+
76+
/**
77+
* @inheritdoc
78+
*/
79+
public function getKeyFor($item)
80+
{
81+
$this->guardObjectType($item);
82+
83+
$key = array_search($item, $this->items);
84+
85+
if ($key === false) {
86+
throw new CollectionItemNotFoundException();
87+
}
88+
89+
return $key;
90+
}
91+
92+
/**
93+
* @inheritdoc
94+
*/
95+
public function getKeys()
96+
{
97+
return array_keys($this->items);
98+
}
99+
100+
/**
101+
* @inheritdoc
102+
*/
103+
public function length()
104+
{
105+
return count($this->items);
106+
}
107+
108+
/**
109+
* @inheritdoc
110+
*/
111+
public function toArray()
112+
{
113+
return $this->items;
114+
}
115+
116+
/**
117+
* @inheritdoc
118+
*/
119+
public static function fromArray(array $items)
120+
{
121+
$collection = new static();
122+
foreach ($items as $item) {
123+
$collection = $collection->with($item);
124+
}
125+
return $collection;
126+
}
127+
128+
/**
129+
* @inheritdoc
130+
*/
131+
public function getIterator()
132+
{
133+
return new \ArrayIterator($this->items);
134+
}
135+
136+
/**
137+
* @return string
138+
*/
139+
abstract protected function getValidObjectType();
140+
141+
/**
142+
* @param mixed $object
143+
* Object of which the type should be validated.
144+
*
145+
* @return bool
146+
* TRUE if the object is of a valid type, FALSE otherwise.
147+
*/
148+
protected function isValidObjectType($object)
149+
{
150+
$type = (string) $this->getValidObjectType();
151+
return ($object instanceof $type);
152+
}
153+
154+
/**
155+
* @param mixed $object
156+
* Object of which the type should be guarded.
157+
*
158+
* @throws \InvalidArgumentException
159+
* When the provided object is not of the specified type.
160+
*/
161+
protected function guardObjectType($object)
162+
{
163+
if (!$this->isValidObjectType($object)) {
164+
throw new \InvalidArgumentException(
165+
sprintf(
166+
'Expected instance of %s, found %s instead.',
167+
$this->getValidObjectType(),
168+
get_class($object)
169+
)
170+
);
171+
}
172+
}
173+
}

0 commit comments

Comments
 (0)