26use InvalidArgumentException;
28use OutOfBoundsException;
29use Wikimedia\Assert\Assert;
76 $row = clone $slot->row;
79 foreach ( $overrides as $key =>
$value ) {
106 'slot_revision_id' =>
null,
125 Assert::parameterType(
'string', $role,
'$role' );
129 'slot_revision_id' =>
null,
130 'slot_origin' =>
null,
131 'content_size' =>
null,
132 'content_sha1' =>
null,
133 'slot_content_id' =>
null,
134 'content_address' =>
null,
135 'role_name' => $role,
165 Assert::parameterType(
'integer', $revisionId,
'$revisionId' );
166 Assert::parameterType(
'integer', $contentId,
'$contentId' );
167 Assert::parameterType(
'string', $contentAddress,
'$contentAddress' );
169 if ( $protoSlot->hasRevision() && $protoSlot->getRevision() !== $revisionId ) {
170 throw new LogicException(
171 "Mismatching revision ID $revisionId: "
172 .
"The slot already belongs to revision {$protoSlot->getRevision()}. "
173 .
"Use SlotRecord::newInherited() to re-use content between revisions."
177 if ( $protoSlot->hasAddress() && $protoSlot->getAddress() !== $contentAddress ) {
178 throw new LogicException(
179 "Mismatching blob address $contentAddress: "
180 .
"The slot already has content at {$protoSlot->getAddress()}."
184 if ( $protoSlot->hasAddress() && $protoSlot->getContentId() !== $contentId ) {
185 throw new LogicException(
186 "Mismatching content ID $contentId: "
187 .
"The slot already has content row {$protoSlot->getContentId()} associated."
191 if ( $protoSlot->isInherited() ) {
192 if ( !$protoSlot->hasAddress() ) {
193 throw new InvalidArgumentException(
194 "An inherited blob should have a content address!"
197 if ( !$protoSlot->hasField(
'slot_origin' ) ) {
198 throw new InvalidArgumentException(
199 "A saved inherited slot should have an origin set!"
202 $origin = $protoSlot->getOrigin();
204 $origin = $revisionId;
208 'slot_revision_id' => $revisionId,
209 'slot_content_id' => $contentId,
210 'slot_origin' => $origin,
211 'content_address' => $contentAddress,
231 Assert::parameterType(
'object',
$row,
'$row' );
232 Assert::parameterType(
'Content|callable',
$content,
'$content' );
235 property_exists(
$row,
'slot_id' ),
240 property_exists(
$row,
'slot_revision_id' ),
241 '$row->slot_revision_id',
245 property_exists(
$row,
'slot_content_id' ),
246 '$row->slot_content_id',
250 property_exists(
$row,
'content_address' ),
251 '$row->content_address',
255 property_exists(
$row,
'model_name' ),
260 property_exists(
$row,
'slot_origin' ),
265 !property_exists(
$row,
'slot_inherited' ),
266 '$row->slot_inherited',
270 !property_exists(
$row,
'slot_revision' ),
271 '$row->slot_revision',
285 throw new LogicException( __CLASS__ .
' is not serializable.' );
304 if ( $this->content instanceof
Content ) {
308 $obj = call_user_func( $this->content, $this );
310 Assert::postcondition(
312 'Slot content callback should return a Content object'
315 $this->content = $obj;
331 if ( !isset( $this->row->$name ) ) {
333 if ( property_exists( $this->row, $name ) ) {
336 throw new OutOfBoundsException(
'No such field: ' . $name );
340 $value = $this->row->$name;
361 return strval( $this->
getField( $name ) );
374 return intval( $this->
getField( $name ) );
382 return isset( $this->row->$name );
430 return $this->
hasField(
'content_address' );
441 return $this->
hasField(
'slot_revision_id' );
484 $this->
setField(
'content_size', $size );
499 $format = $this->
hasField(
'format_name' )
503 $data = $this->
getContent()->serialize( $format );
505 $this->
setField(
'content_sha1', $sha1 );
523 $this->
setField(
'model_name', $model );
541 if ( $this->
hasField(
'format_name' ) ) {
553 $this->row->$name =
$value;
565 return \Wikimedia\base_convert( sha1(
$blob ), 16, 36, 31 );
Base interface for content objects.
getModel()
Returns the ID of the content model used by this Content object.