26use InvalidArgumentException;
28use OutOfBoundsException;
29use Wikimedia\Assert\Assert;
81 $row = clone $slot->row;
84 foreach ( $overrides as $key => $value ) {
111 'slot_revision_id' =>
null,
130 Assert::parameterType(
'string', $role,
'$role' );
134 'slot_revision_id' =>
null,
135 'slot_origin' =>
null,
136 'content_size' =>
null,
137 'content_sha1' =>
null,
138 'slot_content_id' =>
null,
139 'content_address' =>
null,
140 'role_name' => $role,
170 Assert::parameterType(
'integer', $revisionId,
'$revisionId' );
172 Assert::parameterType(
'integer|null', $contentId,
'$contentId' );
173 Assert::parameterType(
'string', $contentAddress,
'$contentAddress' );
176 throw new LogicException(
177 "Mismatching revision ID $revisionId: "
178 .
"The slot already belongs to revision {$protoSlot->getRevision()}. "
179 .
"Use SlotRecord::newInherited() to re-use content between revisions."
184 throw new LogicException(
185 "Mismatching blob address $contentAddress: "
186 .
"The slot already has content at {$protoSlot->getAddress()}."
191 throw new LogicException(
192 "Mismatching content ID $contentId: "
193 .
"The slot already has content row {$protoSlot->getContentId()} associated."
199 throw new InvalidArgumentException(
200 "An inherited blob should have a content address!"
203 if ( !$protoSlot->
hasField(
'slot_origin' ) ) {
204 throw new InvalidArgumentException(
205 "A saved inherited slot should have an origin set!"
210 $origin = $revisionId;
214 'slot_revision_id' => $revisionId,
215 'slot_content_id' => $contentId,
216 'slot_origin' => $origin,
217 'content_address' => $contentAddress,
235 Assert::parameterType(
'object',
$row,
'$row' );
236 Assert::parameterType(
'Content|callable',
$content,
'$content' );
239 property_exists(
$row,
'slot_revision_id' ),
240 '$row->slot_revision_id',
244 property_exists(
$row,
'slot_content_id' ),
245 '$row->slot_content_id',
249 property_exists(
$row,
'content_address' ),
250 '$row->content_address',
254 property_exists(
$row,
'model_name' ),
259 property_exists(
$row,
'slot_origin' ),
264 !property_exists(
$row,
'slot_inherited' ),
265 '$row->slot_inherited',
269 !property_exists(
$row,
'slot_revision' ),
270 '$row->slot_revision',
284 throw new LogicException( __CLASS__ .
' is not serializable.' );
303 if ( $this->content instanceof
Content ) {
307 $obj = call_user_func( $this->content, $this );
309 Assert::postcondition(
311 'Slot content callback should return a Content object'
314 $this->content = $obj;
330 if ( !isset( $this->row->$name ) ) {
332 if ( property_exists( $this->row, $name ) ) {
335 throw new OutOfBoundsException(
'No such field: ' . $name );
339 $value = $this->row->$name;
342 if ( !is_string( $value ) && is_callable( $value ) ) {
343 $value = call_user_func( $value, $this );
360 return strval( $this->
getField( $name ) );
373 return intval( $this->
getField( $name ) );
381 if ( isset( $this->row->$name ) ) {
383 if ( !is_string( $this->row->$name ) && is_callable( $this->row->$name ) ) {
388 return isset( $this->row->$name );
436 return $this->
hasField(
'content_address' );
447 return $this->
hasField(
'slot_origin' );
470 return $this->
hasField(
'slot_content_id' );
481 return $this->
hasField(
'slot_revision_id' );
527 $this->
setField(
'content_size', $size );
546 if ( $sha1 ===
null || $sha1 ===
'' ) {
547 $format = $this->
hasField(
'format_name' )
551 $data = $this->
getContent()->serialize( $format );
553 $this->
setField(
'content_sha1', $sha1 );
571 $this->
setField(
'model_name', $model );
589 if ( $this->
hasField(
'format_name' ) ) {
601 $this->row->$name = $value;
613 return \Wikimedia\base_convert( sha1(
$blob ), 16, 36, 31 );
636 if ( $other === $this ) {
646 && $this->getAddress() == $other->
getAddress()
668class_alias( SlotRecord::class,
'MediaWiki\Storage\SlotRecord' );
Base interface for content objects.
getModel()
Returns the ID of the content model used by this Content object.