Completed
Push — master ( ca1b11...988510 )
by Joni
03:19
created

RDN::firstOf()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 6
cts 6
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 1
crap 2
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 
17
	\Countable, \IteratorAggregate
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces before interface name; 1 found
Loading history...
Coding Style introduced by
Only one interface may be specified per line in a multi-line implements declaration
Loading history...
18
{
19
	/**
20
	 * Attributes.
21
	 *
22
	 * @var AttributeTypeAndValue[] $_attribs
23
	 */
24
	protected $_attribs;
25
	
26
	/**
27
	 * Constructor
28
	 *
29
	 * @param AttributeTypeAndValue ...$attribs One or more attributes
30
	 */
31 39
	public function __construct(AttributeTypeAndValue ...$attribs) {
32 39
		if (!count($attribs)) {
33 1
			throw new \UnexpectedValueException(
34 1
				"RDN must have at least one AttributeTypeAndValue.");
35
		}
36 38
		$this->_attribs = $attribs;
37 38
	}
38
	
39
	/**
40
	 * Convenience method to initialize RDN from AttributeValue objects.
41
	 *
42
	 * @param AttributeValue ...$values One or more attributes
43
	 * @return self
44
	 */
45 4
	public static function fromAttributeValues(AttributeValue ...$values) {
46 1
		$attribs = array_map(
47
			function (AttributeValue $value) {
48 1
				return new AttributeTypeAndValue(
49 1
					new AttributeType($value->oid()), $value);
50 1
			}, $values);
51 1
		return new self(...$attribs);
52 4
	}
53
	
54
	/**
55
	 * Initialize from ASN.1.
56
	 *
57
	 * @param Set $set
58
	 * @return self
59
	 */
60 4
	public static function fromASN1(Set $set) {
61 4
		$attribs = array_map(
62
			function (UnspecifiedType $el) {
63 4
				return AttributeTypeAndValue::fromASN1($el->asSequence());
64 4
			}, $set->elements());
65 4
		return new self(...$attribs);
66
	}
67
	
68
	/**
69
	 * Generate ASN.1 structure.
70
	 *
71
	 * @return Set
72
	 */
73 4
	public function toASN1() {
74 4
		$elements = array_map(
75
			function (AttributeTypeAndValue $tv) {
76 4
				return $tv->toASN1();
77 4
			}, $this->_attribs);
78 4
		$set = new Set(...$elements);
79 4
		return $set->sortedSetOf();
80
	}
81
	
82
	/**
83
	 * Get name-component string conforming to RFC 2253.
84
	 *
85
	 * @link https://tools.ietf.org/html/rfc2253#section-2.2
86
	 * @return string
87
	 */
88 15
	public function toString() {
89 15
		$parts = array_map(
90 15
			function (AttributeTypeAndValue $tv) {
91 15
				return $tv->toString();
92 15
			}, $this->_attribs);
93 15
		return implode("+", $parts);
94
	}
95
	
96
	/**
97
	 * Check whether RDN is semantically equal to other.
98
	 *
99
	 * @param RDN $other Object to compare to
100
	 * @return bool
101
	 */
102 22
	public function equals(RDN $other) {
103
		// if attribute count doesn't match
104 22
		if (count($this) != count($other)) {
105 1
			return false;
106
		}
107 21
		$attribs1 = $this->_attribs;
108 21
		$attribs2 = $other->_attribs;
109
		// if there's multiple attributes, sort using SET OF rules
110 21
		if (count($attribs1) > 1) {
111 2
			$attribs1 = self::fromASN1($this->toASN1())->_attribs;
112 2
			$attribs2 = self::fromASN1($other->toASN1())->_attribs;
113 2
		}
114 21
		for ($i = count($attribs1) - 1; $i >= 0; --$i) {
115 21
			$tv1 = $attribs1[$i];
116 21
			$tv2 = $attribs2[$i];
117 21
			if (!$tv1->equals($tv2)) {
118 8
				return false;
119
			}
120 16
		}
121 16
		return true;
122
	}
123
	
124
	/**
125
	 * Get all AttributeTypeAndValue objects.
126
	 *
127
	 * @return AttributeTypeAndValue[]
128
	 */
129 1
	public function all() {
130 1
		return $this->_attribs;
131
	}
132
	
133
	/**
134
	 *
135
	 * @see Countable::count()
136
	 * @return int
137
	 */
138 23
	public function count() {
139 23
		return count($this->_attribs);
140
	}
141
	
142
	/**
143
	 *
144
	 * @see IteratorAggregate::getIterator()
145
	 * @return \ArrayIterator
146
	 */
147 1
	public function getIterator() {
148 1
		return new \ArrayIterator($this->_attribs);
149
	}
150
	
151
	/**
152
	 *
153
	 * @return string
154
	 */
155 1
	public function __toString() {
156 1
		return $this->toString();
157
	}
158
}
159