Completed
Push — renovate/pin-dependencies ( cad925...7b5606 )
by
unknown
39:51 queued 29:52
created

ChangelogEntry::getPrologue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
2
/**
3
 * Class representing a changelog entry.
4
 *
5
 * @package automattic/jetpack-changelogger
6
 */
7
8
// phpcs:disable WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
9
10
namespace Automattic\Jetpack\Changelog;
11
12
use DateTime;
13
use InvalidArgumentException;
14
use JsonSerializable;
15
16
/**
17
 * Class representing a changelog entry.
18
 */
19
class ChangelogEntry implements JsonSerializable {
20
21
	/**
22
	 * Entry version.
23
	 *
24
	 * @var string
25
	 */
26
	protected $version;
27
28
	/**
29
	 * Entry link.
30
	 *
31
	 * @var string|null
32
	 */
33
	protected $link = null;
34
35
	/**
36
	 * Entry timestamp.
37
	 *
38
	 * @var DateTime
39
	 */
40
	protected $timestamp;
41
42
	/**
43
	 * Content before the changes themselves.
44
	 *
45
	 * @var string
46
	 */
47
	protected $prologue = '';
48
49
	/**
50
	 * Content after the changes themselves.
51
	 *
52
	 * @var string
53
	 */
54
	protected $epilogue = '';
55
56
	/**
57
	 * Changes.
58
	 *
59
	 * @var ChangeEntry[]
60
	 */
61
	protected $changes = array();
62
63
	/**
64
	 * Constructor.
65
	 *
66
	 * @param string $version Version for the new entry.
67
	 * @param array  $data Data for other entry fields. Keys correspond to the setters, e.g. key 'link' calls `setLink()`.
68
	 * @throws InvalidArgumentException If an argument is invalid.
69
	 */
70 View Code Duplication
	public function __construct( $version, array $data = array() ) {
71
		$data = array( 'version' => $version ) + $data + array( 'timestamp' => 'now' );
72
		foreach ( $data as $k => $v ) {
73
			$func = array( $this, 'set' . ucfirst( $k ) );
74
			if ( is_callable( $func ) ) {
75
				$func( $v );
76
			} else {
77
				throw new InvalidArgumentException( __METHOD__ . ": Unrecognized data item \"$k\"." );
78
			}
79
		}
80
	}
81
82
	/**
83
	 * Get the version.
84
	 *
85
	 * @return string
86
	 */
87
	public function getVersion() {
88
		return $this->version;
89
	}
90
91
	/**
92
	 * Set the version.
93
	 *
94
	 * @param string $version Version to set.
95
	 * @returns $this
96
	 * @throws InvalidArgumentException If an argument is invalid.
97
	 */
98
	public function setVersion( $version ) {
99
		$version = (string) $version;
100
		if ( '' === $version ) {
101
			throw new InvalidArgumentException( __METHOD__ . ': Version may not be empty' );
102
		}
103
		$this->version = (string) $version;
104
		return $this;
105
	}
106
107
	/**
108
	 * Get the link.
109
	 *
110
	 * @return string|null
111
	 */
112
	public function getLink() {
113
		return $this->link;
114
	}
115
116
	/**
117
	 * Set the link.
118
	 *
119
	 * @param string|null $link Link to set.
120
	 * @returns $this
121
	 * @throws InvalidArgumentException If an argument is invalid.
122
	 */
123
	public function setLink( $link ) {
124
		if ( '' === $link ) {
125
			$link = null;
126
		} elseif ( null !== $link ) {
127
			$link = filter_var( $link, FILTER_VALIDATE_URL );
128
			if ( ! is_string( $link ) ) {
129
				throw new InvalidArgumentException( __METHOD__ . ': Invalid URL' );
130
			}
131
		}
132
		$this->link = $link;
133
		return $this;
134
	}
135
136
	/**
137
	 * Get the timestamp.
138
	 *
139
	 * @return DateTime
140
	 */
141
	public function getTimestamp() {
142
		return $this->timestamp;
143
	}
144
145
	/**
146
	 * Set the timestamp.
147
	 *
148
	 * @param DateTime|string $timestamp Timestamp to set.
149
	 * @returns $this
150
	 * @throws InvalidArgumentException If an argument is invalid.
151
	 */
152 View Code Duplication
	public function setTimestamp( $timestamp ) {
153
		if ( ! $timestamp instanceof DateTime ) {
154
			try {
155
				$timestamp = new DateTime( $timestamp );
156
			} catch ( \Exception $ex ) {
157
				throw new InvalidArgumentException( __METHOD__ . ': Invalid timestamp', 0, $ex );
158
			}
159
		}
160
		$this->timestamp = $timestamp;
161
		return $this;
162
	}
163
164
	/**
165
	 * Get the prologue content.
166
	 *
167
	 * @return string
168
	 */
169
	public function getPrologue() {
170
		return $this->prologue;
171
	}
172
173
	/**
174
	 * Set the prologue content.
175
	 *
176
	 * @param string $prologue Prologue content to set.
177
	 * @return $this
178
	 */
179
	public function setPrologue( $prologue ) {
180
		$this->prologue = (string) $prologue;
181
		return $this;
182
	}
183
184
	/**
185
	 * Get the epilogue content.
186
	 *
187
	 * @return string
188
	 */
189
	public function getEpilogue() {
190
		return $this->epilogue;
191
	}
192
193
	/**
194
	 * Set the epilogue content.
195
	 *
196
	 * @param string $epilogue Epilogue content to set.
197
	 * @return $this
198
	 */
199
	public function setEpilogue( $epilogue ) {
200
		$this->epilogue = (string) $epilogue;
201
		return $this;
202
	}
203
204
	/**
205
	 * Get the list of changes.
206
	 *
207
	 * @return ChangeEntry[]
208
	 */
209
	public function getChanges() {
210
		return $this->changes;
211
	}
212
213
	/**
214
	 * Set the list of changes.
215
	 *
216
	 * This replaces all existing changes. The caller is responsible
217
	 * for making sure the changes are sorted properly.
218
	 *
219
	 * @param ChangeEntry[] $changes Changes.
220
	 * @return $this
221
	 * @throws InvalidArgumentException If an argument is invalid.
222
	 */
223 View Code Duplication
	public function setChanges( array $changes ) {
224
		foreach ( $changes as $i => $change ) {
225
			if ( ! $change instanceof ChangeEntry ) {
226
				$what = is_object( $change ) ? get_class( $change ) : gettype( $change );
227
				throw new InvalidArgumentException( __METHOD__ . ": Expected a ChangeEntry, got $what at index $i" );
228
			}
229
		}
230
		$this->changes = array_values( $changes );
231
		return $this;
232
	}
233
234
	/**
235
	 * Add a new change.
236
	 *
237
	 * The new change is inserted before the first existing change where
238
	 * `ChangeEntry::compare()` says the existing change should come after.
239
	 *
240
	 * @param ChangeEntry $change New change.
241
	 * @param array       $compareconfig Comparison config, see `ChangeEntry::compare()`.
242
	 * @return $this
243
	 */
244
	public function insertChange( ChangeEntry $change, $compareconfig = array() ) {
245
		foreach ( $this->changes as $i => $e ) {
246
			if ( ChangeEntry::compare( $change, $e, $compareconfig ) < 0 ) {
247
				array_splice( $this->changes, $i, 0, array( $change ) );
248
				return $this;
249
			}
250
		}
251
		$this->changes[] = $change;
252
		return $this;
253
	}
254
255
	/**
256
	 * Append a new change.
257
	 *
258
	 * @param ChangeEntry $change New change.
259
	 * @return $this
260
	 */
261
	public function appendChange( ChangeEntry $change ) {
262
		$this->changes[] = $change;
263
		return $this;
264
	}
265
266
	/**
267
	 * Get the changes grouped by subheading.
268
	 *
269
	 * @param string|null $subheading Subheading to retrieve.
270
	 * @return ChangeEntry[]|ChangeEntry[][] An array of changes with the
271
	 *   heading if `$subheading` was passed, or an array keyed by subheading of
272
	 *   arrays of changes if it was null.
273
	 */
274
	public function getChangesBySubheading( $subheading = null ) {
275
		$ret = array();
276
		foreach ( $this->changes as $entry ) {
277
			$ret[ $entry->getSubheading() ][] = $entry;
278
		}
279
280
		return null === $subheading
281
			? $ret
282
			: ( isset( $ret[ $subheading ] ) ? $ret[ $subheading ] : array() );
283
	}
284
285
	/**
286
	 * Return data for serializing to JSON.
287
	 *
288
	 * @return array
289
	 */
290
	public function jsonSerialize() {
291
		return array(
292
			'__class__' => static::class,
293
			'version'   => $this->version,
294
			'link'      => $this->link,
295
			'timestamp' => $this->timestamp->format( DateTime::ISO8601 ),
296
			'prologue'  => $this->prologue,
297
			'epilogue'  => $this->epilogue,
298
			'changes'   => $this->changes,
299
		);
300
	}
301
302
	/**
303
	 * Unserialize from JSON.
304
	 *
305
	 * @param array $data JSON data as returned by self::jsonSerialize().
306
	 * @return static
307
	 * @throws InvalidArgumentException If the data is invalid.
308
	 */
309
	public static function jsonUnserialize( $data ) {
310
		$data = (array) $data;
311
		if ( ! isset( $data['__class__'] ) || ! isset( $data['version'] ) ) {
312
			throw new InvalidArgumentException( 'Invalid data' );
313
		}
314
		$class   = $data['__class__'];
315
		$version = $data['version'];
316
		unset( $data['__class__'], $data['version'] );
317 View Code Duplication
		if ( ! class_exists( $class ) || ! is_a( $class, static::class, true ) ) {
318
			throw new InvalidArgumentException( "Cannot instantiate $class via " . static::class . '::' . __FUNCTION__ );
319
		}
320
		if ( isset( $data['changes'] ) ) {
321
			$data['changes'] = array_map( array( ChangeEntry::class, 'jsonUnserialize' ), $data['changes'] );
322
		}
323
		return new $class( $version, $data );
324
	}
325
326
}
327