MediaWiki  master
RevisionSlots.php
Go to the documentation of this file.
1 <?php
23 namespace MediaWiki\Revision;
24 
25 use Content;
26 use LogicException;
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 
319 class_alias( RevisionSlots::class, 'MediaWiki\Storage\RevisionSlots' );
getOriginalSlots()
Return all slots that belong to the revision they originate from (that is, they are not inherited fro...
__sleep()
Implemented to defy serialization.
computeSha1()
Computes the combined hash of the revisions&#39;s slots.
getSlotRoles()
Returns the slot names (roles) of all slots present in this revision.
getContent( $role)
Returns the Content of the given slot.
Value object representing a content slot associated with a page revision.
Definition: SlotRecord.php:39
hasSameContent(RevisionSlots $other)
Checks whether the other RevisionSlots instance has the same content as this instance.
getSlot( $role)
Returns the SlotRecord of the given slot.
SlotRecord [] callable $slots
isInherited()
Whether this slot was inherited from an older revision.
Definition: SlotRecord.php:420
getInheritedSlots()
Return all slots that are not not originate in the revision they belong to (that is, they are inherited from some other revision).
Created by PhpStorm.
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.
static base36Sha1( $blob)
Get the base 36 SHA-1 value for a string of text.
Definition: SlotRecord.php:612
getSha1()
Returns the content size.
Definition: SlotRecord.php:538
getSize()
Returns the content size.
Definition: SlotRecord.php:522
Exception representing a failure to look up a revision.
getSlots()
Returns an associative array that maps role names to SlotRecords.
Value object representing the set of slots belonging to a revision.
computeSize()
Computes the total nominal size of the revision&#39;s slots, in bogo-bytes.
setSlotsInternal(array $slots)