| Current File : /home/jvzmxxx/wiki/extensions/Wikibase/lib/includes/Changes/EntityChangeFactory.php |
<?php
namespace Wikibase\Lib\Changes;
use MWException;
use Wikibase\DataModel\Entity\EntityDocument;
use Wikibase\DataModel\Entity\EntityId;
use Wikibase\DataModel\Services\Diff\EntityDiffer;
use Wikibase\DataModel\Statement\StatementList;
use Wikibase\DataModel\Statement\StatementListHolder;
use Wikibase\DataModel\Statement\StatementListProvider;
use Wikibase\DataModel\Term\AliasGroupList;
use Wikibase\DataModel\Term\FingerprintProvider;
use Wikibase\DataModel\Term\TermList;
use Wikibase\EntityChange;
/**
* Factory for EntityChange objects
*
* @since 0.5
*
* @license GPL-2.0+
* @author Daniel Kinzler
* @author Bene* < benestar.wikimedia@gmail.com >
*/
class EntityChangeFactory {
/**
* @var EntityDiffer
*/
private $entityDiffer;
/**
* @var string[] Maps entity type IDs to subclasses of EntityChange.
*/
private $changeClasses;
/**
* @param EntityDiffer $entityDiffer
* @param string[] $changeClasses Maps entity type IDs to subclasses of EntityChange.
* Entity types not mapped explicitly are assumed to use EntityChange itself.
*/
public function __construct(
EntityDiffer $entityDiffer,
array $changeClasses = array()
) {
$this->entityDiffer = $entityDiffer;
$this->changeClasses = $changeClasses;
}
/**
* @since 0.5
*
* @param string $action The action name
* @param EntityId $entityId
* @param array $fields additional fields to set
*
* @return EntityChange
*/
public function newForEntity( $action, EntityId $entityId, array $fields = array() ) {
$entityType = $entityId->getEntityType();
if ( isset( $this->changeClasses[ $entityType ] ) ) {
$class = $this->changeClasses[$entityType];
} else {
$class = EntityChange::class;
}
/** @var EntityChange $instance */
$instance = new $class( $fields );
if ( !$instance->hasField( 'object_id' ) ) {
$instance->setField( 'object_id', $entityId->getSerialization() );
}
if ( !$instance->hasField( 'info' ) ) {
$instance->setField( 'info', array() );
}
// Note: the change type determines how the client will
// instantiate and handle the change
$type = 'wikibase-' . $entityId->getEntityType() . '~' . $action;
$instance->setField( 'type', $type );
return $instance;
}
/**
* Constructs an EntityChange from the given old and new Entity.
*
* @since 0.5
*
* @param string $action The action name
* @param EntityDocument|null $oldEntity
* @param EntityDocument|null $newEntity
* @param array $fields additional fields to set
*
* @return EntityChange
* @throws MWException
*/
public function newFromUpdate(
$action,
EntityDocument $oldEntity = null,
EntityDocument $newEntity = null,
array $fields = array()
) {
if ( $oldEntity === null && $newEntity === null ) {
throw new MWException( 'Either $oldEntity or $newEntity must be given' );
}
$this->minimizeEntityForDiffing( $oldEntity );
$this->minimizeEntityForDiffing( $newEntity );
if ( $oldEntity === null ) {
$id = $newEntity->getId();
$diff = $this->entityDiffer->getConstructionDiff( $newEntity );
} elseif ( $newEntity === null ) {
$id = $oldEntity->getId();
$diff = $this->entityDiffer->getDestructionDiff( $oldEntity );
} elseif ( $oldEntity->getType() !== $newEntity->getType() ) {
throw new MWException( 'Entity type mismatch' );
} else {
$id = $newEntity->getId();
$diff = $this->entityDiffer->diffEntities( $oldEntity, $newEntity );
}
/** @var EntityChange $instance */
$instance = self::newForEntity( $action, $id, $fields );
$instance->setDiff( $diff );
return $instance;
}
/**
* Hack: Don't include statement, description and alias diffs, since those are unused and not
* helpful performance-wise to the dispatcher and change handling.
*
* @fixme Implement T113468 and remove this.
*
* @param EntityDocument $entity
*/
private function minimizeEntityForDiffing( EntityDocument $entity = null ) {
if ( $entity instanceof StatementListHolder ) {
$entity->setStatements( new StatementList() );
} elseif ( $entity instanceof StatementListProvider ) {
$statements = $entity->getStatements();
foreach ( $statements->toArray() as $statement ) {
$statements->removeStatementsWithGuid( $statement->getGuid() );
}
}
if ( $entity instanceof FingerprintProvider ) {
$fingerprint = $entity->getFingerprint();
$fingerprint->setDescriptions( new TermList() );
$fingerprint->setAliasGroups( new AliasGroupList() );
}
}
}