MediaWiki REL1_34
RevisionSlots.php
Go to the documentation of this file.
1<?php
23namespace MediaWiki\Revision;
24
25use Content;
26use LogicException;
27use Wikimedia\Assert\Assert;
28
36
38 protected $slots;
39
44 public function __construct( $slots ) {
45 Assert::parameterType( 'array|callable', $slots, '$slots' );
46
47 if ( is_callable( $slots ) ) {
48 $this->slots = $slots;
49 } else {
50 $this->setSlotsInternal( $slots );
51 }
52 }
53
57 private function setSlotsInternal( array $slots ) {
58 Assert::parameterElementType( SlotRecord::class, $slots, '$slots' );
59
60 $this->slots = [];
61
62 // re-key the slot array
63 foreach ( $slots as $slot ) {
64 $role = $slot->getRole();
65 $this->slots[$role] = $slot;
66 }
67 }
68
74 public function __sleep() {
75 throw new LogicException( __CLASS__ . ' is not serializable.' );
76 }
77
91 public function getContent( $role ) {
92 // Return a copy to be safe. Immutable content objects return $this from copy().
93 return $this->getSlot( $role )->getContent()->copy();
94 }
95
106 public function getSlot( $role ) {
107 $slots = $this->getSlots();
108
109 if ( isset( $slots[$role] ) ) {
110 return $slots[$role];
111 } else {
112 throw new RevisionAccessException( 'No such slot: ' . $role );
113 }
114 }
115
123 public function hasSlot( $role ) {
124 $slots = $this->getSlots();
125
126 return isset( $slots[$role] );
127 }
128
135 public function getSlotRoles() {
136 $slots = $this->getSlots();
137 return array_keys( $slots );
138 }
139
148 public function computeSize() {
149 return array_reduce( $this->getSlots(), function ( $accu, SlotRecord $slot ) {
150 return $accu + $slot->getSize();
151 }, 0 );
152 }
153
163 public function getSlots() {
164 if ( is_callable( $this->slots ) ) {
165 $slots = call_user_func( $this->slots );
166
167 Assert::postcondition(
168 is_array( $slots ),
169 'Slots info callback should return an array of objects'
170 );
171
172 $this->setSlotsInternal( $slots );
173 }
174
175 return $this->slots;
176 }
177
190 public function computeSha1() {
191 $slots = $this->getSlots();
192 ksort( $slots );
193
194 if ( empty( $slots ) ) {
195 return SlotRecord::base36Sha1( '' );
196 }
197
198 return array_reduce( $slots, function ( $accu, SlotRecord $slot ) {
199 return $accu === null
200 ? $slot->getSha1()
201 : SlotRecord::base36Sha1( $accu . $slot->getSha1() );
202 }, null );
203 }
204
213 public function getOriginalSlots() {
214 return array_filter(
215 $this->getSlots(),
216 function ( SlotRecord $slot ) {
217 return !$slot->isInherited();
218 }
219 );
220 }
221
230 public function getInheritedSlots() {
231 return array_filter(
232 $this->getSlots(),
233 function ( SlotRecord $slot ) {
234 return $slot->isInherited();
235 }
236 );
237 }
238
248 public function hasSameContent( RevisionSlots $other ) {
249 if ( $other === $this ) {
250 return true;
251 }
252
253 $aSlots = $this->getSlots();
254 $bSlots = $other->getSlots();
255
256 ksort( $aSlots );
257 ksort( $bSlots );
258
259 if ( array_keys( $aSlots ) !== array_keys( $bSlots ) ) {
260 return false;
261 }
262
263 foreach ( $aSlots as $role => $s ) {
264 $t = $bSlots[$role];
265
266 if ( !$s->hasSameContent( $t ) ) {
267 return false;
268 }
269 }
270
271 return true;
272 }
273
283 public function getRolesWithDifferentContent( RevisionSlots $other ) {
284 if ( $other === $this ) {
285 return [];
286 }
287
288 $aSlots = $this->getSlots();
289 $bSlots = $other->getSlots();
290
291 ksort( $aSlots );
292 ksort( $bSlots );
293
294 $different = array_keys( array_merge(
295 array_diff_key( $aSlots, $bSlots ),
296 array_diff_key( $bSlots, $aSlots )
297 ) );
298
300 $common = array_intersect_key( $aSlots, $bSlots );
301
302 foreach ( $common as $role => $s ) {
303 $t = $bSlots[$role];
304
305 if ( !$s->hasSameContent( $t ) ) {
306 $different[] = $role;
307 }
308 }
309
310 return $different;
311 }
312
313}
314
319class_alias( RevisionSlots::class, 'MediaWiki\Storage\RevisionSlots' );
Exception representing a failure to look up a revision.
Value object representing the set of slots belonging to a revision.
getSlotRoles()
Returns the slot names (roles) of all slots present in this revision.
computeSha1()
Computes the combined hash of the revisions's slots.
getInheritedSlots()
Return all slots that are not not originate in the revision they belong to (that is,...
hasSameContent(RevisionSlots $other)
Checks whether the other RevisionSlots instance has the same content as this instance.
getOriginalSlots()
Return all slots that belong to the revision they originate from (that is, they are not inherited fro...
computeSize()
Computes the total nominal size of the revision's slots, in bogo-bytes.
getContent( $role)
Returns the Content of the given slot.
getRolesWithDifferentContent(RevisionSlots $other)
Find roles for which the $other RevisionSlots object has different content as this RevisionSlots obje...
hasSlot( $role)
Returns whether the given slot is set.
getSlot( $role)
Returns the SlotRecord of the given slot.
__sleep()
Implemented to defy serialization.
getSlots()
Returns an associative array that maps role names to SlotRecords.
Value object representing a content slot associated with a page revision.
getSha1()
Returns the content size.
getSize()
Returns the content size.
static base36Sha1( $blob)
Get the base 36 SHA-1 value for a string of text.
isInherited()
Whether this slot was inherited from an older revision.
Base interface for content objects.
Definition Content.php:34