Container   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 172
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 28
c 0
b 0
f 0
lcom 1
cbo 1
dl 0
loc 172
rs 10

15 Methods

Rating   Name   Duplication   Size   Complexity  
contains() 0 1 ?
A checkMember() 0 8 2
A __construct() 0 10 4
A map() 0 10 2
A isEmpty() 0 4 2
A isClosed() 0 4 1
A setClosed() 0 4 1
A count() 0 4 1
A offsetExists() 0 4 1
A offsetGet() 0 4 1
A offsetSet() 0 14 6
A append() 0 8 2
A offsetUnset() 0 4 1
A getIterator() 0 4 1
A jsonLDSerialize() 0 11 3
1
<?php declare(strict_types = 1);
2
3
namespace JSKOS;
4
5
use InvalidArgumentException;
6
7
/**
8
 * Common base class of JSKOS Listing, Set, and LanguageMap.
9
 */
10
abstract class Container extends PrettyJsonSerializable implements \Countable, \ArrayAccess, \IteratorAggregate
11
{
12
    protected $members = [];
13
    protected $closed  = true;
14
15
    /**
16
     * Check whether value can be added as member.
17
     *
18
     * @throws InvalidArgumentException if value is no JSKOS Resource
19
     */
20
    protected static function checkMember($value)
21
    {
22
        if ($value instanceof Resource) {
23
            return $value;
24
        } else {
25
            throw new InvalidArgumentException(get_called_class() . ' may only contain JSKOS Resources');
26
        }
27
    }
28
29
    /**
30
     * Check whether an equal member alredy exists in this Container.
31
     */
32
    abstract public function contains($member): bool;
33
34
    /**
35
     * Create a new container, possibly from an array.
36
     */
37
    public function __construct(array $members = [])
38
    {
39
        foreach ($members as $m) {
40
            if (is_null($m)) {
41
                $this->setClosed(false);
42
            } elseif (!$this->contains($m)) {
43
                $this->members[] = static::checkMember($m);
44
            }
45
        }
46
    }
47
48
    /**
49
     * Apply a function to each member of this container.
50
     * @param $callback callable
51
     */
52
    public function map(callable $callback): array
53
    {
54
        $result = [];
55
56
        foreach ($this->members as $member) {
57
            $result[] = $callback($member);
58
        }
59
60
        return $result;
61
    }
62
63
    /**
64
     * Return whether this container is empty (no members and closed).
65
     */
66
    public function isEmpty(): bool
67
    {
68
        return $this->closed && !count($this->members);
69
    }
70
71
    /**
72
     * Return whether this container is closed.
73
     */
74
    public function isClosed(): bool
75
    {
76
        return $this->closed;
77
    }
78
79
    /**
80
     * Set whether this container is closed (no unknown members) or not.
81
     * @param Boolean $closed
82
     */
83
    public function setClosed(bool $closed = true)
84
    {
85
        $this->closed = $closed;
86
    }
87
88
    # implements Countable
89
90
    /**
91
     * Return the number of known values in this container (closed or not).
92
     */
93
    public function count(): int
94
    {
95
        return count($this->members);
96
    }
97
98
    # implements ArrayAccess:
99
100
    /**
101
     * Return whether an object exists at the given offset.
102
     * @param mixed $offset
103
     */
104
    public function offsetExists($offset)
105
    {
106
        return isset($this->members[$offset]);
107
    }
108
109
    /**
110
     * Return an object at the given offset.
111
     * @param mixed $offset
112
     */
113
    public function offsetGet($offset)
114
    {
115
        return $this->members[$offset];
116
    }
117
118
    /**
119
     * Set an object at the given offset.
120
     * @param mixed $offset
121
     * @param mixed $object
122
     */
123
    public function offsetSet($offset, $object)
124
    {
125
        if (is_int($offset) && $offset >= 0 && $offset < $this->count()) {
126
            $member = static::checkMember($object);
127
            # TODO: merge if duplicated
128
            if (!$this->contains($member)) {
129
                $this->members[$offset] = $member;
130
            }
131
        } elseif (is_null($object)) {
132
            $this->closed = false;
133
        } else {
134
            $this->append($object);
135
        }
136
    }
137
138
    /**
139
     * Append an object at the end.
140
     */
141
    public function append($object)
142
    {
143
        $member = static::checkMember($object);
144
        # TODO: merge if duplicated
145
        if (!$this->contains($member)) {
146
            $this->members[] = $member;
147
        }
148
    }
149
150
    /**
151
     * @throws \BadMethodCallException
152
     */
153
    public function offsetUnset($key)
154
    {
155
        throw new \BadMethodCallException(__METHOD__ . ' is not supported');
156
    }
157
158
    # implements IteratorAggregate:
159
160
    /**
161
     * Return an iterator to iterate all members of the set.
162
     */
163
    public function getIterator()
164
    {
165
        return new \ArrayIterator($this->members);
166
    }
167
168
    # extends PrettyJsonSerializable:
169
170
    public function jsonLDSerialize(string $context = self::DEFAULT_CONTEXT, bool $types = null)
171
    {
172
        $set = array_map(function ($m) use ($types) {
173
            return is_object($m) ? $m->jsonLDSerialize('', $types) : $m;
174
        }, $this->members);
175
176
        if (!$this->closed) {
177
            $set[] = null;
178
        }
179
        return $set;
180
    }
181
}
182