MediaWiki  master
RevisionSlots.php
Go to the documentation of this file.
1 <?php
23 namespace MediaWiki\Revision;
24 
25 use Content;
26 use LogicException;
27 use Wikimedia\Assert\Assert;
28 
42 
44  protected $slots;
45 
52  public function __construct( $slots ) {
53  Assert::parameterType( 'array|callable', $slots, '$slots' );
54 
55  if ( is_callable( $slots ) ) {
56  $this->slots = $slots;
57  } else {
58  $this->setSlotsInternal( $slots );
59  }
60  }
61 
65  private function setSlotsInternal( array $slots ) {
66  Assert::parameterElementType( SlotRecord::class, $slots, '$slots' );
67 
68  $this->slots = [];
69 
70  // re-key the slot array
71  foreach ( $slots as $slot ) {
72  $role = $slot->getRole();
73  $this->slots[$role] = $slot;
74  }
75  }
76 
82  public function __sleep() {
83  throw new LogicException( __CLASS__ . ' is not serializable.' );
84  }
85 
101  public function getContent( $role ) {
102  // Return a copy to be safe. Immutable content objects return $this from copy().
103  return $this->getSlot( $role )->getContent()->copy();
104  }
105 
116  public function getSlot( $role ) {
117  $slots = $this->getSlots();
118 
119  if ( isset( $slots[$role] ) ) {
120  return $slots[$role];
121  } else {
122  throw new RevisionAccessException( 'No such slot: ' . $role );
123  }
124  }
125 
133  public function hasSlot( $role ) {
134  $slots = $this->getSlots();
135 
136  return isset( $slots[$role] );
137  }
138 
145  public function getSlotRoles() {
146  $slots = $this->getSlots();
147  return array_keys( $slots );
148  }
149 
158  public function computeSize() {
159  return array_reduce( $this->getSlots(), function ( $accu, SlotRecord $slot ) {
160  return $accu + $slot->getSize();
161  }, 0 );
162  }
163 
173  public function getSlots() {
174  if ( is_callable( $this->slots ) ) {
175  $slots = call_user_func( $this->slots );
176 
177  Assert::postcondition(
178  is_array( $slots ),
179  'Slots info callback should return an array of objects'
180  );
181 
182  $this->setSlotsInternal( $slots );
183  }
184 
185  return $this->slots;
186  }
187 
200  public function computeSha1() {
201  $slots = $this->getSlots();
202  ksort( $slots );
203 
204  if ( empty( $slots ) ) {
205  return SlotRecord::base36Sha1( '' );
206  }
207 
208  return array_reduce( $slots, function ( $accu, SlotRecord $slot ) {
209  return $accu === null
210  ? $slot->getSha1()
211  : SlotRecord::base36Sha1( $accu . $slot->getSha1() );
212  }, null );
213  }
214 
223  public function getOriginalSlots() {
224  return array_filter(
225  $this->getSlots(),
226  function ( SlotRecord $slot ) {
227  return !$slot->isInherited();
228  }
229  );
230  }
231 
240  public function getInheritedSlots() {
241  return array_filter(
242  $this->getSlots(),
243  function ( SlotRecord $slot ) {
244  return $slot->isInherited();
245  }
246  );
247  }
248 
258  public function hasSameContent( RevisionSlots $other ) {
259  if ( $other === $this ) {
260  return true;
261  }
262 
263  $aSlots = $this->getSlots();
264  $bSlots = $other->getSlots();
265 
266  ksort( $aSlots );
267  ksort( $bSlots );
268 
269  if ( array_keys( $aSlots ) !== array_keys( $bSlots ) ) {
270  return false;
271  }
272 
273  foreach ( $aSlots as $role => $s ) {
274  $t = $bSlots[$role];
275 
276  if ( !$s->hasSameContent( $t ) ) {
277  return false;
278  }
279  }
280 
281  return true;
282  }
283 
293  public function getRolesWithDifferentContent( RevisionSlots $other ) {
294  if ( $other === $this ) {
295  return [];
296  }
297 
298  $aSlots = $this->getSlots();
299  $bSlots = $other->getSlots();
300 
301  ksort( $aSlots );
302  ksort( $bSlots );
303 
304  $different = array_keys( array_merge(
305  array_diff_key( $aSlots, $bSlots ),
306  array_diff_key( $bSlots, $aSlots )
307  ) );
308 
310  $common = array_intersect_key( $aSlots, $bSlots );
311 
312  foreach ( $common as $role => $s ) {
313  $t = $bSlots[$role];
314 
315  if ( !$s->hasSameContent( $t ) ) {
316  $different[] = $role;
317  }
318  }
319 
320  return $different;
321  }
322 
323 }
324 
329 class_alias( RevisionSlots::class, 'MediaWiki\Storage\RevisionSlots' );
Revision\RevisionSlots\$slots
SlotRecord[] callable $slots
Definition: RevisionSlots.php:44
Revision\RevisionAccessException
Exception representing a failure to look up a revision.
Definition: RevisionAccessException.php:34
Revision\RevisionSlots\__construct
__construct( $slots)
Stable for calling.
Definition: RevisionSlots.php:52
Revision\RevisionSlots\__sleep
__sleep()
Implemented to defy serialization.
Definition: RevisionSlots.php:82
Revision\RevisionSlots\getRolesWithDifferentContent
getRolesWithDifferentContent(RevisionSlots $other)
Find roles for which the $other RevisionSlots object has different content as this RevisionSlots obje...
Definition: RevisionSlots.php:293
Revision\RevisionSlots\computeSha1
computeSha1()
Computes the combined hash of the revisions's slots.
Definition: RevisionSlots.php:200
Revision\RevisionSlots\hasSlot
hasSlot( $role)
Returns whether the given slot is set.
Definition: RevisionSlots.php:133
Revision\SlotRecord\isInherited
isInherited()
Whether this slot was inherited from an older revision.
Definition: SlotRecord.php:420
$s
$s
Definition: mergeMessageFileList.php:185
Revision\RevisionSlots\setSlotsInternal
setSlotsInternal(array $slots)
Definition: RevisionSlots.php:65
Revision\RevisionSlots\hasSameContent
hasSameContent(RevisionSlots $other)
Checks whether the other RevisionSlots instance has the same content as this instance.
Definition: RevisionSlots.php:258
MediaWiki\Revision
Definition: ContributionsLookup.php:3
Revision\RevisionSlots\getOriginalSlots
getOriginalSlots()
Return all slots that belong to the revision they originate from (that is, they are not inherited fro...
Definition: RevisionSlots.php:223
Revision\SlotRecord\base36Sha1
static base36Sha1( $blob)
Get the base 36 SHA-1 value for a string of text.
Definition: SlotRecord.php:612
Revision\SlotRecord\getSha1
getSha1()
Returns the content size.
Definition: SlotRecord.php:538
Revision\SlotRecord\getSize
getSize()
Returns the content size.
Definition: SlotRecord.php:522
Revision\RevisionSlots\getContent
getContent( $role)
Returns the Content of the given slot.
Definition: RevisionSlots.php:101
Revision\RevisionSlots\getInheritedSlots
getInheritedSlots()
Return all slots that are not not originate in the revision they belong to (that is,...
Definition: RevisionSlots.php:240
Revision\RevisionSlots\getSlots
getSlots()
Returns an associative array that maps role names to SlotRecords.
Definition: RevisionSlots.php:173
Content
Base interface for content objects.
Definition: Content.php:35
Revision\RevisionSlots\getSlot
getSlot( $role)
Returns the SlotRecord of the given slot.
Definition: RevisionSlots.php:116
Revision\RevisionSlots\computeSize
computeSize()
Computes the total nominal size of the revision's slots, in bogo-bytes.
Definition: RevisionSlots.php:158
Revision\RevisionSlots\getSlotRoles
getSlotRoles()
Returns the slot names (roles) of all slots present in this revision.
Definition: RevisionSlots.php:145
Revision\RevisionSlots
Value object representing the set of slots belonging to a revision.
Definition: RevisionSlots.php:41
$t
$t
Definition: testCompression.php:74
Revision\SlotRecord
Value object representing a content slot associated with a page revision.
Definition: SlotRecord.php:39