Completed
Push — master ( 988510...51ff77 )
by Joni
02:47
created

RDN::allOf()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 7
cts 7
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 1
crap 1
1
<?php
2
3
namespace X501\ASN1;
4
5
use ASN1\Type\Constructed\Set;
6
use ASN1\Type\UnspecifiedType;
7
use X501\ASN1\AttributeValue\AttributeValue;
8
9
10
/**
11
 * Implements <i>RelativeDistinguishedName</i> ASN.1 type.
12
 *
13
 * @link
14
 *       https://www.itu.int/ITU-T/formal-language/itu-t/x/x501/2012/InformationFramework.html#InformationFramework.RelativeDistinguishedName
15
 */
16
class RDN implements \Countable, \IteratorAggregate
17
{
18
	/**
19
	 * Attributes.
20
	 *
21
	 * @var AttributeTypeAndValue[] $_attribs
22
	 */
23
	protected $_attribs;
24
	
25
	/**
26
	 * Constructor
27
	 *
28
	 * @param AttributeTypeAndValue ...$attribs One or more attributes
29
	 */
30 40
	public function __construct(AttributeTypeAndValue ...$attribs) {
31 40
		if (!count($attribs)) {
32 1
			throw new \UnexpectedValueException(
33 1
				"RDN must have at least one AttributeTypeAndValue.");
34
		}
35 39
		$this->_attribs = $attribs;
36 39
	}
37
	
38
	/**
39
	 * Convenience method to initialize RDN from AttributeValue objects.
40
	 *
41
	 * @param AttributeValue ...$values One or more attributes
42
	 * @return self
43
	 */
44 1
	public static function fromAttributeValues(AttributeValue ...$values) {
45 1
		$attribs = array_map(
46
			function (AttributeValue $value) {
47 1
				return new AttributeTypeAndValue(
48 1
					new AttributeType($value->oid()), $value);
49 1
			}, $values);
50 1
		return new self(...$attribs);
51
	}
52
	
53
	/**
54
	 * Initialize from ASN.1.
55
	 *
56
	 * @param Set $set
57
	 * @return self
58
	 */
59 4
	public static function fromASN1(Set $set) {
60 4
		$attribs = array_map(
61
			function (UnspecifiedType $el) {
62 4
				return AttributeTypeAndValue::fromASN1($el->asSequence());
63 4
			}, $set->elements());
64 4
		return new self(...$attribs);
65
	}
66
	
67
	/**
68
	 * Generate ASN.1 structure.
69
	 *
70
	 * @return Set
71
	 */
72 4
	public function toASN1() {
73 4
		$elements = array_map(
74
			function (AttributeTypeAndValue $tv) {
75 4
				return $tv->toASN1();
76 4
			}, $this->_attribs);
77 4
		$set = new Set(...$elements);
78 4
		return $set->sortedSetOf();
79
	}
80
	
81
	/**
82
	 * Get name-component string conforming to RFC 2253.
83
	 *
84
	 * @link https://tools.ietf.org/html/rfc2253#section-2.2
85
	 * @return string
86
	 */
87 15
	public function toString() {
88 15
		$parts = array_map(
89
			function (AttributeTypeAndValue $tv) {
90 15
				return $tv->toString();
91 15
			}, $this->_attribs);
92 15
		return implode("+", $parts);
93
	}
94
	
95
	/**
96
	 * Check whether RDN is semantically equal to other.
97
	 *
98
	 * @param RDN $other Object to compare to
99
	 * @return bool
100
	 */
101 22
	public function equals(RDN $other) {
102
		// if attribute count doesn't match
103 22
		if (count($this) != count($other)) {
104 1
			return false;
105
		}
106 21
		$attribs1 = $this->_attribs;
107 21
		$attribs2 = $other->_attribs;
108
		// if there's multiple attributes, sort using SET OF rules
109 21
		if (count($attribs1) > 1) {
110 2
			$attribs1 = self::fromASN1($this->toASN1())->_attribs;
111 2
			$attribs2 = self::fromASN1($other->toASN1())->_attribs;
112 2
		}
113 21
		for ($i = count($attribs1) - 1; $i >= 0; --$i) {
114 21
			$tv1 = $attribs1[$i];
115 21
			$tv2 = $attribs2[$i];
116 21
			if (!$tv1->equals($tv2)) {
117 8
				return false;
118
			}
119 16
		}
120 16
		return true;
121
	}
122
	
123
	/**
124
	 * Get all AttributeTypeAndValue objects.
125
	 *
126
	 * @return AttributeTypeAndValue[]
127
	 */
128 1
	public function all() {
129 1
		return $this->_attribs;
130
	}
131
	
132
	/**
133
	 * Get all AttributeTypeAndValue objects of the given attribute type.
134
	 *
135
	 * @param string $name Attribute OID or name
136
	 * @return AttributeTypeAndValue[]
137
	 */
138 8
	public function allOf($name) {
139 8
		$oid = AttributeType::attrNameToOID($name);
140 8
		$attribs = array_filter($this->_attribs, 
141 8
			function (AttributeTypeAndValue $tv) use ($oid) {
142 8
				return $tv->oid() == $oid;
143 8
			});
144 8
		return array_values($attribs);
145
	}
146
	
147
	/**
148
	 *
149
	 * @see Countable::count()
150
	 * @return int
151
	 */
152 23
	public function count() {
153 23
		return count($this->_attribs);
154
	}
155
	
156
	/**
157
	 *
158
	 * @see IteratorAggregate::getIterator()
159
	 * @return \ArrayIterator
160
	 */
161 1
	public function getIterator() {
162 1
		return new \ArrayIterator($this->_attribs);
163
	}
164
	
165
	/**
166
	 *
167
	 * @return string
168
	 */
169 1
	public function __toString() {
170 1
		return $this->toString();
171
	}
172
}
173