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 
40 
42  protected $slots;
43 
48  public function __construct( $slots ) {
49  Assert::parameterType( 'array|callable', $slots, '$slots' );
50 
51  if ( is_callable( $slots ) ) {
52  $this->slots = $slots;
53  } else {
54  $this->setSlotsInternal( $slots );
55  }
56  }
57 
61  private function setSlotsInternal( array $slots ) {
62  Assert::parameterElementType( SlotRecord::class, $slots, '$slots' );
63 
64  $this->slots = [];
65 
66  // re-key the slot array
67  foreach ( $slots as $slot ) {
68  $role = $slot->getRole();
69  $this->slots[$role] = $slot;
70  }
71  }
72 
78  public function __sleep() {
79  throw new LogicException( __CLASS__ . ' is not serializable.' );
80  }
81 
97  public function getContent( $role ) {
98  // Return a copy to be safe. Immutable content objects return $this from copy().
99  return $this->getSlot( $role )->getContent()->copy();
100  }
101 
112  public function getSlot( $role ) {
113  $slots = $this->getSlots();
114 
115  if ( isset( $slots[$role] ) ) {
116  return $slots[$role];
117  } else {
118  throw new RevisionAccessException( 'No such slot: ' . $role );
119  }
120  }
121 
129  public function hasSlot( $role ) {
130  $slots = $this->getSlots();
131 
132  return isset( $slots[$role] );
133  }
134 
141  public function getSlotRoles() {
142  $slots = $this->getSlots();
143  return array_keys( $slots );
144  }
145 
154  public function computeSize() {
155  return array_reduce( $this->getSlots(), function ( $accu, SlotRecord $slot ) {
156  return $accu + $slot->getSize();
157  }, 0 );
158  }
159 
169  public function getSlots() {
170  if ( is_callable( $this->slots ) ) {
171  $slots = call_user_func( $this->slots );
172 
173  Assert::postcondition(
174  is_array( $slots ),
175  'Slots info callback should return an array of objects'
176  );
177 
178  $this->setSlotsInternal( $slots );
179  }
180 
181  return $this->slots;
182  }
183 
196  public function computeSha1() {
197  $slots = $this->getSlots();
198  ksort( $slots );
199 
200  if ( empty( $slots ) ) {
201  return SlotRecord::base36Sha1( '' );
202  }
203 
204  return array_reduce( $slots, function ( $accu, SlotRecord $slot ) {
205  return $accu === null
206  ? $slot->getSha1()
207  : SlotRecord::base36Sha1( $accu . $slot->getSha1() );
208  }, null );
209  }
210 
219  public function getOriginalSlots() {
220  return array_filter(
221  $this->getSlots(),
222  function ( SlotRecord $slot ) {
223  return !$slot->isInherited();
224  }
225  );
226  }
227 
236  public function getInheritedSlots() {
237  return array_filter(
238  $this->getSlots(),
239  function ( SlotRecord $slot ) {
240  return $slot->isInherited();
241  }
242  );
243  }
244 
254  public function hasSameContent( RevisionSlots $other ) {
255  if ( $other === $this ) {
256  return true;
257  }
258 
259  $aSlots = $this->getSlots();
260  $bSlots = $other->getSlots();
261 
262  ksort( $aSlots );
263  ksort( $bSlots );
264 
265  if ( array_keys( $aSlots ) !== array_keys( $bSlots ) ) {
266  return false;
267  }
268 
269  foreach ( $aSlots as $role => $s ) {
270  $t = $bSlots[$role];
271 
272  if ( !$s->hasSameContent( $t ) ) {
273  return false;
274  }
275  }
276 
277  return true;
278  }
279 
289  public function getRolesWithDifferentContent( RevisionSlots $other ) {
290  if ( $other === $this ) {
291  return [];
292  }
293 
294  $aSlots = $this->getSlots();
295  $bSlots = $other->getSlots();
296 
297  ksort( $aSlots );
298  ksort( $bSlots );
299 
300  $different = array_keys( array_merge(
301  array_diff_key( $aSlots, $bSlots ),
302  array_diff_key( $bSlots, $aSlots )
303  ) );
304 
306  $common = array_intersect_key( $aSlots, $bSlots );
307 
308  foreach ( $common as $role => $s ) {
309  $t = $bSlots[$role];
310 
311  if ( !$s->hasSameContent( $t ) ) {
312  $different[] = $role;
313  }
314  }
315 
316  return $different;
317  }
318 
319 }
320 
325 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)