Completed
Push — add/changelog-tooling ( fa9ac3...7f5585 )
by
unknown
517:08 queued 507:24
created

Changelog::jsonUnserialize()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 22

Duplication

Lines 3
Ratio 13.64 %

Importance

Changes 0
Metric Value
cc 7
nc 10
nop 1
dl 3
loc 22
rs 8.6346
c 0
b 0
f 0
1
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
2
/**
3
 * Class representing a changelog.
4
 *
5
 * @package automattic/jetpack-changelogger
6
 */
7
8
// phpcs:disable WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
9
10
namespace Automattic\Jetpack\Changelog;
11
12
use InvalidArgumentException;
13
use JsonSerializable;
14
15
/**
16
 * Class representing a changelog.
17
 */
18
class Changelog implements JsonSerializable {
19
20
	/**
21
	 * Content before the changelog itself.
22
	 *
23
	 * @var string
24
	 */
25
	protected $prologue = '';
26
27
	/**
28
	 * Content after the changelog itself.
29
	 *
30
	 * @var string
31
	 */
32
	protected $epilogue = '';
33
34
	/**
35
	 * Changelog entries, one per version.
36
	 *
37
	 * @var ChangelogEntry[]
38
	 */
39
	protected $entries = array();
40
41
	/**
42
	 * Get the prologue content.
43
	 *
44
	 * @return string
45
	 */
46
	public function getPrologue() {
47
		return $this->prologue;
48
	}
49
50
	/**
51
	 * Set the prologue content.
52
	 *
53
	 * @param string $prologue Prologue content to set.
54
	 * @return $this
55
	 */
56
	public function setPrologue( $prologue ) {
57
		$this->prologue = (string) $prologue;
58
		return $this;
59
	}
60
61
	/**
62
	 * Get the epilogue content.
63
	 *
64
	 * @return string
65
	 */
66
	public function getEpilogue() {
67
		return $this->epilogue;
68
	}
69
70
	/**
71
	 * Set the epilogue content.
72
	 *
73
	 * @param string $epilogue Epilogue content to set.
74
	 * @return $this
75
	 */
76
	public function setEpilogue( $epilogue ) {
77
		$this->epilogue = (string) $epilogue;
78
		return $this;
79
	}
80
81
	/**
82
	 * Get the list of changelog entries.
83
	 *
84
	 * @return ChangelogEntry[]
85
	 */
86
	public function getEntries() {
87
		return $this->entries;
88
	}
89
90
	/**
91
	 * Set the list of changelog entries.
92
	 *
93
	 * This replaces all existing entries.
94
	 *
95
	 * @param ChangelogEntry[] $entries Changelog entries.
96
	 * @return $this
97
	 * @throws InvalidArgumentException If an argument is invalid.
98
	 */
99 View Code Duplication
	public function setEntries( array $entries ) {
100
		foreach ( $entries as $i => $entry ) {
101
			if ( ! $entry instanceof ChangelogEntry ) {
102
				$what = is_object( $entry ) ? get_class( $entry ) : gettype( $entry );
103
				throw new InvalidArgumentException( __METHOD__ . ": Expected a ChangelogEntry, got $what at index $i" );
104
			}
105
		}
106
		$this->entries = array_values( $entries );
107
		return $this;
108
	}
109
110
	/**
111
	 * Get the latest changelog entry.
112
	 *
113
	 * @return ChangelogEntry|null
114
	 */
115
	public function getLatestEntry() {
116
		return isset( $this->entries[0] ) ? $this->entries[0] : null;
117
	}
118
119
	/**
120
	 * Add a new entry as the latest.
121
	 *
122
	 * @param ChangelogEntry $entry New entry.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $entry not be null|ChangelogEntry?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
123
	 * @return $this
124
	 */
125
	public function addEntry( ChangelogEntry $entry = null ) {
126
		array_unshift( $this->entries, $entry );
127
		return $this;
128
	}
129
130
	/**
131
	 * Get the list of versions in the changelog.
132
	 *
133
	 * @return string[]
134
	 */
135
	public function getVersions() {
136
		$ret = array();
137
		foreach ( $this->entries as $entry ) {
138
			$ret[] = $entry->getVersion();
139
		}
140
		return $ret;
141
	}
142
143
	/**
144
	 * Find an entry by version.
145
	 *
146
	 * @param string $version Version to search for.
147
	 * @param string $operator Operator as for `version_compare()`. Note the
148
	 *   passed `$version` is passed to `version_compare()` as the second
149
	 *   argument, and the first entry matching is returned.
150
	 * @return ChangelogEntry|null
151
	 */
152
	public function findEntryByVersion( $version, $operator = '==' ) {
153
		foreach ( $this->entries as $entry ) {
154
			if ( version_compare( $entry->getVersion(), $version, $operator ) ) {
155
				return $entry;
156
			}
157
		}
158
		return null;
159
	}
160
161
	/**
162
	 * Fetch all entries by a version check.
163
	 *
164
	 * @param array $constraints Version constraints. Keys are operations
165
	 *   recognized by `version_compare()`, values are the version to compare
166
	 *   with as the second argument.
167
	 * @return ChangelogEntry[]
168
	 */
169
	public function findEntriesByVersions( $constraints ) {
170
		$ret = array();
171
		foreach ( $this->entries as $entry ) {
172
			foreach ( $constraints as $op => $version ) {
173
				if ( ! version_compare( $entry->getVersion(), $version, $op ) ) {
174
					continue 2;
175
				}
176
			}
177
			$ret[] = $entry;
178
		}
179
		return $ret;
180
	}
181
182
	/**
183
	 * Return data for serializing to JSON.
184
	 *
185
	 * @return array
186
	 */
187
	public function jsonSerialize() {
188
		return array(
189
			'__class__' => static::class,
190
			'prologue'  => $this->prologue,
191
			'epilogue'  => $this->epilogue,
192
			'entries'   => $this->entries,
193
		);
194
	}
195
196
	/**
197
	 * Unserialize from JSON.
198
	 *
199
	 * @param array $data JSON data as returned by self::jsonSerialize().
200
	 * @return static
201
	 * @throws InvalidArgumentException If the data is invalid.
202
	 */
203
	public static function jsonUnserialize( $data ) {
204
		$data = (array) $data;
205
		if ( ! isset( $data['__class__'] ) ) {
206
			throw new InvalidArgumentException( 'Invalid data' );
207
		}
208
		$class = $data['__class__'];
209
		unset( $data['__class__'] );
210 View Code Duplication
		if ( ! class_exists( $class ) || ! is_a( $class, static::class, true ) ) {
211
			throw new InvalidArgumentException( "Cannot instantiate $class via " . static::class . '::' . __FUNCTION__ );
212
		}
213
		$ret = new $class();
214
		if ( isset( $data['prologue'] ) ) {
215
			$ret->setPrologue( $data['prologue'] );
216
		}
217
		if ( isset( $data['epilogue'] ) ) {
218
			$ret->setEpilogue( $data['epilogue'] );
219
		}
220
		if ( isset( $data['entries'] ) ) {
221
			$ret->setEntries( array_map( array( ChangelogEntry::class, 'jsonUnserialize' ), $data['entries'] ) );
222
		}
223
		return $ret;
224
	}
225
226
}
227