Anja Jentzsch has submitted this change and it was merged. Change subject: (bug 44095) enhanced claim diff visualizaion including refs ......................................................................
(bug 44095) enhanced claim diff visualizaion including refs - still todo: qualifiers, ranks. squashed: (bug 44095) visualize claim differences This commit is a follow up to 5fc812442e19d55a7d1c2072ba8a839ce7d1f067. It tackles some design issues and adds tests, while removing the preliminary visualization code, which needs to be re-added. Change-Id: I7f8645df860b1860b4016003f52e7959af685a25 --- M lib/WikibaseLib.hooks.php M lib/WikibaseLib.i18n.php M lib/WikibaseLib.php M lib/includes/DiffView.php A lib/includes/claim/ClaimDiffer.php A lib/includes/claim/ClaimDifference.php A lib/includes/claim/ClaimDifferenceVisualizer.php D lib/includes/entity/EntityDiffView.php A lib/includes/entity/EntityDiffVisualizer.php A lib/tests/phpunit/claim/ClaimDifferTest.php A lib/tests/phpunit/claim/ClaimDifferenceTest.php A lib/tests/phpunit/claim/ClaimDifferenceVisualizerTest.php M repo/includes/EntityContentDiffView.php M repo/includes/actions/EditEntityAction.php 14 files changed, 768 insertions(+), 197 deletions(-) Approvals: Anja Jentzsch: Verified; Looks good to me, approved diff --git a/lib/WikibaseLib.hooks.php b/lib/WikibaseLib.hooks.php index 7487c4d..b1c6cfd 100644 --- a/lib/WikibaseLib.hooks.php +++ b/lib/WikibaseLib.hooks.php @@ -33,6 +33,9 @@ 'changes/EntityChange', 'claim/ClaimAggregate', + 'claim/ClaimDifference', + 'claim/ClaimDifferenceVisualizer', + 'claim/ClaimDiffer', 'claim/ClaimListAccess', 'claim/Claims', 'claim/Claim', diff --git a/lib/WikibaseLib.i18n.php b/lib/WikibaseLib.i18n.php index d85f151..39fdd75 100644 --- a/lib/WikibaseLib.i18n.php +++ b/lib/WikibaseLib.i18n.php @@ -21,6 +21,9 @@ 'wikibase-entity-item' => 'item', 'wikibase-entity-property' => 'property', 'wikibase-entity-query' => 'query', + 'wikibase-diffview-reference' => 'reference', + 'wikibase-diffview-rank' => 'rank', + 'wikibase-diffview-qualifier' => 'qualifier', 'wikibase-error-unexpected' => 'An unexpected error occurred.', 'wikibase-error-save-generic' => 'An error occurred while trying to perform save and because of this, your changes could not be completed.', 'wikibase-error-remove-generic' => 'An error occurred while trying to perform remove and because of this, your changes could not be completed.', @@ -63,6 +66,9 @@ {{Identical|Property}}', 'wikibase-entity-query' => 'How we refer to entities of type query. See also Wikidatas glossary on [[m:Wikidata/Glossary#entity|entity]]. {{Identical|Query}}', + 'wikibase-diffview-reference' => 'Label within the header of a diff-operation on the entity diff view to describe that the diff-operation affects a reference. Will be shown as e.g. "claim / property q1 / referenece".', + 'wikibase-diffview-rank' => 'Label within the header of a diff-operation on the entity diff view to describe that the diff-operation affects the rank of the statement. Will be shown as e.g. "claim / property q1 / rank".', + 'wikibase-diffview-qualifier' => 'Label within the header of a diff-operation on the entity diff view to describe that the diff-operation affects a qualifier. Will be shown as e.g. "claim / property q1 / qualifier".', 'wikibase-error-unexpected' => 'Error message that is used as a fallback message if no other message can be assigned to the error that occurred. This error message being displayed should never happen. However, there may be "unexpected" errors not covered by the implemented error handling.', 'wikibase-error-save-generic' => 'Generic error message for an error happening during a save operation.', 'wikibase-error-remove-generic' => 'Generic error message for an error happening during a remove operation', diff --git a/lib/WikibaseLib.php b/lib/WikibaseLib.php index 0a9987f..f0e5545 100644 --- a/lib/WikibaseLib.php +++ b/lib/WikibaseLib.php @@ -129,6 +129,9 @@ // includes/claims $wgAutoloadClasses['Wikibase\Claim'] = $dir . 'includes/claim/Claim.php'; $wgAutoloadClasses['Wikibase\ClaimAggregate'] = $dir . 'includes/claim/ClaimAggregate.php'; +$wgAutoloadClasses['Wikibase\ClaimDiffer'] = $dir . 'includes/claim/ClaimDiffer.php'; +$wgAutoloadClasses['Wikibase\ClaimDifference'] = $dir . 'includes/claim/ClaimDifference.php'; +$wgAutoloadClasses['Wikibase\ClaimDifferenceVisualizer'] = $dir . 'includes/claim/ClaimDifferenceVisualizer.php'; $wgAutoloadClasses['Wikibase\ClaimListAccess'] = $dir . 'includes/claim/ClaimListAccess.php'; $wgAutoloadClasses['Wikibase\Claims'] = $dir . 'includes/claim/Claims.php'; $wgAutoloadClasses['Wikibase\Claim'] = $dir . 'includes/claim/Claim.php'; @@ -136,7 +139,7 @@ // includes/entity $wgAutoloadClasses['Wikibase\Entity'] = $dir . 'includes/entity/Entity.php'; $wgAutoloadClasses['Wikibase\EntityDiff'] = $dir . 'includes/entity/EntityDiff.php'; -$wgAutoloadClasses['Wikibase\EntityDiffView'] = $dir . 'includes/entity/EntityDiffView.php'; +$wgAutoloadClasses['Wikibase\EntityDiffVisualizer'] = $dir . 'includes/entity/EntityDiffVisualizer.php'; $wgAutoloadClasses['Wikibase\EntityFactory'] = $dir . 'includes/entity/EntityFactory.php'; $wgAutoloadClasses['Wikibase\EntityId'] = $dir . 'includes/entity/EntityId.php'; $wgAutoloadClasses['Wikibase\Entity'] = $dir . 'includes/entity/Entity.php'; diff --git a/lib/includes/DiffView.php b/lib/includes/DiffView.php index bab18fc..b7b241b 100644 --- a/lib/includes/DiffView.php +++ b/lib/includes/DiffView.php @@ -2,7 +2,7 @@ namespace Wikibase; use Html; -use Diff\IDiff; +use Diff\Diff; use Diff\DiffOp; /** @@ -45,7 +45,7 @@ /** * @since 0.1 * - * @var IDiff + * @var Diff */ protected $diff; @@ -55,10 +55,10 @@ * @since 0.1 * * @param array $path - * @param IDiff $diff + * @param Diff $diff * @param \IContextSource|null $contextSource */ - public function __construct( array $path, IDiff $diff, \IContextSource $contextSource = null ) { + public function __construct( array $path, Diff $diff, \IContextSource $contextSource = null ) { $this->path = $path; $this->diff = $diff; @@ -133,7 +133,7 @@ $html .= Html::rawElement( 'td', array( 'class' => 'diff-marker' ), '+' ); $html .= Html::rawElement( 'td', array( 'class' => 'diff-addedline' ), Html::rawElement( 'div', array(), - Html::element( 'ins', array( 'class' => 'diffchange diffchange-inline' ), + Html::rawElement( 'ins', array( 'class' => 'diffchange diffchange-inline' ), $value ) ) ); $html .= Html::closeElement( 'tr' ); @@ -154,7 +154,7 @@ $html .= Html::rawElement( 'td', array( 'class' => 'diff-marker' ), '-' ); $html .= Html::rawElement( 'td', array( 'class' => 'diff-deletedline' ), Html::rawElement( 'div', array(), - Html::element( 'del', array( 'class' => 'diffchange diffchange-inline' ), + Html::rawElement( 'del', array( 'class' => 'diffchange diffchange-inline' ), $value ) ) ); $html .= Html::rawElement( 'td', array( 'colspan'=>'2' ), ' ' ); $html .= Html::closeElement( 'tr' ); @@ -178,12 +178,12 @@ $html .= Html::rawElement( 'td', array( 'class' => 'diff-marker' ), '-' ); $html .= Html::rawElement( 'td', array( 'class' => 'diff-deletedline' ), Html::rawElement( 'div', array(), - Html::element( 'del', array( 'class' => 'diffchange diffchange-inline' ), + Html::rawElement( 'del', array( 'class' => 'diffchange diffchange-inline' ), $oldValue ) ) ); $html .= Html::rawElement( 'td', array( 'class' => 'diff-marker' ), '+' ); $html .= Html::rawElement( 'td', array( 'class' => 'diff-addedline' ), Html::rawElement( 'div', array(), - Html::element( 'ins', array( 'class' => 'diffchange diffchange-inline' ), + Html::rawElement( 'ins', array( 'class' => 'diffchange diffchange-inline' ), $newValue ) ) ); $html .= Html::closeElement( 'tr' ); $html .= Html::closeElement( 'tr' ); @@ -202,8 +202,8 @@ */ protected function generateDiffHeaderHtml( $name ) { $html = Html::openElement( 'tr' ); - $html .= Html::element( 'td', array( 'colspan'=>'2', 'class' => 'diff-lineno' ), $name ); - $html .= Html::element( 'td', array( 'colspan'=>'2', 'class' => 'diff-lineno' ), $name ); + $html .= Html::rawElement( 'td', array( 'colspan'=>'2', 'class' => 'diff-lineno' ), $name ); + $html .= Html::rawElement( 'td', array( 'colspan'=>'2', 'class' => 'diff-lineno' ), $name ); $html .= Html::closeElement( 'tr' ); return $html; diff --git a/lib/includes/claim/ClaimDiffer.php b/lib/includes/claim/ClaimDiffer.php new file mode 100644 index 0000000..4aad00f --- /dev/null +++ b/lib/includes/claim/ClaimDiffer.php @@ -0,0 +1,98 @@ +<?php + +namespace Wikibase; + +use Diff\Diff; +use Diff\ListDiffer; +use Diff\DiffOpChange; + +/** + * Class for generating a ClaimDifference given two claims. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @since 0.4 + * + * @file + * @ingroup WikibaseLib + * + * @licence GNU GPL v2+ + * @author Tobias Gritschacher < tobias.gritschac...@wikimedia.de > + */ +class ClaimDiffer { + + /** + * @since 0.4 + * + * @var ListDiffer + */ + private $listDiffer; + + /** + * Constructor. + * + * @since 0.4 + * + * @param ListDiffer $listDiffer + */ + public function __construct( ListDiffer $listDiffer ) { + $this->listDiffer = $listDiffer; + } + + /** + * Calculates diff of two Claims and stores the difference in a ClaimDifference + * + * @since 0.4 + * + * @param Claim $oldClaim + * @param Claim $newClaim + * + * @return ClaimDifference + */ + public function diffClaims( Claim $oldClaim, Claim $newClaim ) { + $mainSnakChange = null; + $rankChange = null; + $referenceChanges = null; + + if ( !$oldClaim->getMainSnak()->equals( $newClaim->getMainSnak() ) ) { + $mainSnakChange = new DiffOpChange( $oldClaim->getMainSnak(), $newClaim->getMainSnak() ); + } + + $this->listDiffer->setComparisonCallback( function( \Comparable $old, \Comparable $new ) { + return $old->equals( $new ); + } ); + + $qualifierChanges = new Diff( $this->listDiffer->doDiff( + iterator_to_array( $oldClaim->getQualifiers() ), + iterator_to_array( $newClaim->getQualifiers() ) + ), false ); + + if ( $oldClaim instanceof Statement && $newClaim instanceof Statement ) { + + if ( $oldClaim->getRank() !== $newClaim->getRank() ) { + $rankChange = new DiffOpChange( $oldClaim->getRank(), $newClaim->getRank() ); + } + + $referenceChanges = new Diff( $this->listDiffer->doDiff( + iterator_to_array( $oldClaim->getReferences() ), + iterator_to_array( $newClaim->getReferences() ) + ), false ); + } + + return new ClaimDifference( $mainSnakChange, $qualifierChanges, $referenceChanges, $rankChange ); + } + +} diff --git a/lib/includes/claim/ClaimDifference.php b/lib/includes/claim/ClaimDifference.php new file mode 100644 index 0000000..e0fb757 --- /dev/null +++ b/lib/includes/claim/ClaimDifference.php @@ -0,0 +1,146 @@ +<?php + +namespace Wikibase; + +use Diff\DiffOpChange; +use Diff\Diff; +use Comparable; + +/** + * Represents the difference between two Claim objects. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @since 0.4 + * + * @file + * @ingroup WikibaseLib + * + * @licence GNU GPL v2+ + * @author Tobias Gritschacher < tobias.gritschac...@wikimedia.de > + */ +class ClaimDifference implements Comparable { + + /** + * @since 0.4 + * + * @var Diff|null + */ + private $referenceChanges; + + /** + * @since 0.4 + * + * @var DiffOpChange|null + */ + private $mainSnakChange; + + /** + * @since 0.4 + * + * @var DiffOpChange|null + */ + private $rankChange; + + /** + * @since 0.4 + * + * @var Diff|null + */ + private $qualifierChanges; + + /** + * @since 0.4 + * + * @param DiffOpChange|null $mainSnakChange + * @param Diff|null $qualifierChanges + * @param Diff|null $referenceChanges + * @param DiffOpChange|null $rankChange + */ + public function __construct( DiffOpChange $mainSnakChange = null, Diff $qualifierChanges = null, + Diff $referenceChanges = null, DiffOpChange $rankChange = null ) { + + $this->referenceChanges = $referenceChanges; + $this->mainSnakChange = $mainSnakChange; + $this->rankChange = $rankChange; + $this->qualifierChanges = $qualifierChanges; + } + + /** + * Returns the reference change. + * + * @since 0.4 + * + * @return Diff + */ + public function getReferenceChanges() { + return $this->referenceChanges === null ? new Diff( array(), false ) : $this->referenceChanges; + } + + /** + * Returns the mainsnak change. + * + * @since 0.4 + * + * @return DiffOpChange|null + */ + public function getMainSnakChange() { + return $this->mainSnakChange; + } + + /** + * Returns the rank change. + * + * @since 0.4 + * + * @return DiffOpChange|null + */ + public function getRankChange() { + return $this->rankChange; + } + + /** + * Returns the qualifier change. + * + * @since 0.4 + * + * @return Diff + */ + public function getQualifierChanges() { + return $this->qualifierChanges === null ? new Diff( array(), false ) : $this->qualifierChanges; + } + + /** + * @see Comparable::equals + * + * @since 0.1 + * + * @param mixed $target + * + * @return boolean + */ + public function equals( $target ) { + if ( !( $target instanceof ClaimDifference ) ) { + return false; + } + + return $this->getMainSnakChange() == $target->getMainSnakChange() + && $this->getRankChange() == $target->getRankChange() + && $this->getQualifierChanges() == $target->getQualifierChanges() + && $this->getReferenceChanges() == $target->getReferenceChanges(); + } + +} diff --git a/lib/includes/claim/ClaimDifferenceVisualizer.php b/lib/includes/claim/ClaimDifferenceVisualizer.php new file mode 100644 index 0000000..22a841d --- /dev/null +++ b/lib/includes/claim/ClaimDifferenceVisualizer.php @@ -0,0 +1,65 @@ +<?php + +namespace Wikibase; + +use Html; +use Diff; + +/** + * Class for generating HTML for Claim Diffs. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @since 0.4 + * + * @file + * @ingroup WikibaseLib + * + * @licence GNU GPL v2+ + * @author Tobias Gritschacher < tobias.gritschac...@wikimedia.de > + */ +class ClaimDifferenceVisualizer { + + /** + * @since 0.4 + * + * @var EntityLookup + */ + private $entityLookup; + + /** + * Constructor. + * + * @since 0.4 + * + * @param EntityLookup $entityLookup + */ + public function __construct( $entityLookup ) { + $this->entityLookup = $entityLookup; + } + + /** + * @since 0.4 + * + * @param ClaimDifference $claimDifference + * + * @return string + */ + public function visualizeDiff( ClaimDifference $claimDifference ) { + return 'TODO'; // TODO + } + +} diff --git a/lib/includes/entity/EntityDiffView.php b/lib/includes/entity/EntityDiffView.php deleted file mode 100644 index f98e770..0000000 --- a/lib/includes/entity/EntityDiffView.php +++ /dev/null @@ -1,179 +0,0 @@ -<?php - -namespace Wikibase; -use IContextSource; -use Html; -use Diff\IDiff; -use Diff\DiffOp; - -/** - * Class for generating views of EntityDiff objects. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @since 0.1 - * - * @file - * @ingroup WikibaseLib - * - * @licence GNU GPL v2+ - * @author Jeroen De Dauw < jeroended...@gmail.com > - * @author Tobias Gritschacher < tobias.gritschac...@wikimedia.de > - */ - -class EntityDiffView extends DiffView { - - /** - * @since 0.4 - * - * @var EntityLookup|null - */ - private static $entityLookup; - - /** - * Returns a new EntityDiffView for the provided EntityDiff. - * - * @since 0.4 - * - * @param EntityDiff $diff - * @param IContextSource $contextSource - * @param EntityLookup|null $entityLookup - * - * @return EntityDiffView - */ - public static function newForDiff( EntityDiff $diff, IContextSource $contextSource = null, $entityLookup = null ) { - self::$entityLookup = $entityLookup; - return new static( array(), $diff, $contextSource, $entityLookup ); - // TODO: grep for new EntityDiffView and rep by this - } - - /** - * Does the actual work. - * - * @since 0.4 - * - * @param array $path - * @param DiffOp $op - * - * @return string - * @throws \MWException - */ - protected function generateOpHtml( array $path, DiffOp $op ) { - if ( $op->isAtomic() ) { - if ( $path[0] === 'claim' ) { - if ( $op->getType() === 'change' || $op->getType() === 'remove' ) { - $propertyId = $op->getOldValue()->getPropertyId(); - } elseif ( $op->getType() === 'add' ) { - $propertyId = $op->getNewValue()->getPropertyId(); - } - $name = $path[0] . ' / ' . $this->getEntityLabel( $propertyId ); - } else { - $name = implode( ' / ', $path ); // TODO: l10n - } - - $html = $this->generateDiffHeaderHtml( $name ); - - if ( $op->getType() === 'add' ) { - $newValue = $op->getNewValue(); - if ( !is_string( $newValue ) && $path[0] === 'claim' ) { - $newValue = $this->getClaimHtml( $newValue ); - } - $html .= $this->generateAddOpHtml( $newValue ); - } elseif ( $op->getType() === 'remove' ) { - $oldValue = $op->getOldValue(); - if ( !is_string( $oldValue ) && $path[0] === 'claim' ) { - $oldValue = $this->getClaimHtml( $oldValue ); - } - $html .= $this->generateRemoveOpHtml( $oldValue ); - } elseif ( $op->getType() === 'change' ) { - $newValue = $op->getNewValue(); - if ( !is_string( $newValue ) && $path[0] === 'claim' ) { - $newValue = $this->getClaimHtml( $newValue ); - } - - $oldValue = $op->getOldValue(); - if ( !is_string( $oldValue ) && $path[0] === 'claim' ) { - $oldValue = $this->getClaimHtml( $oldValue ); - } - - $html .= $this->generateChangeOpHtml( $oldValue, $newValue ); - } - else { - throw new \MWException( 'Invalid diffOp type' ); - } - } else { - $html = ''; - foreach ( $op as $key => $subOp ) { - $html .= $this->generateOpHtml( - array_merge( $path, array( $key ) ), - $subOp - ); - } - } - - return $html; - } - - /** - * Get HTML for a changed snak - * - * @since 0.4 - * - * @param Claim $claim - * - * @return string - */ - protected function getClaimHtml( Claim $claim ) { - $snakType = $claim->getMainSnak()->getType(); - $diffValueString = $snakType; - - if ( $snakType === 'value' ) { - $dataValue = $claim->getMainSnak()->getDataValue(); - - //FIXME: This will break for types other than EntityId or StringValue - //we do not have a generic way to get string representations of the values yet - if ( $dataValue instanceof EntityId ) { - $diffValueString = $this->getEntityLabel( $dataValue ); - } else { - $diffValueString = $dataValue->getValue(); - } - } - - return $diffValueString; - } - - /** - * Get the label of an entity represented by its EntityId - * - * @since 0.4 - * - * @param EntityId $id - * - * @return string - */ - protected function getEntityLabel( EntityId $id ) { - $label = $id->getPrefixedId(); - - $lookedUpLabel = self::$entityLookup->getEntity( $id )->getLabel( - $this->getContext()->getLanguage()->getCode() - ); - if ( $lookedUpLabel !== false ) { - $label = $lookedUpLabel; - } - - return $label; - } -} \ No newline at end of file diff --git a/lib/includes/entity/EntityDiffVisualizer.php b/lib/includes/entity/EntityDiffVisualizer.php new file mode 100644 index 0000000..e29ebe0 --- /dev/null +++ b/lib/includes/entity/EntityDiffVisualizer.php @@ -0,0 +1,160 @@ +<?php + +namespace Wikibase; + +use IContextSource; +use Html; +use MWException; +use Diff\Diff; +use Diff\DiffOp; +use Diff\DiffOpChange; +use Diff\DiffOpAdd; +use Diff\DiffOpRemove; + +/** + * Class for generating views of EntityDiff objects. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @since 0.4 + * + * @file + * @ingroup WikibaseLib + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroended...@gmail.com > + * @author Tobias Gritschacher < tobias.gritschac...@wikimedia.de > + */ +class EntityDiffVisualizer { + + /** + * @since 0.4 + * + * @var IContextSource + */ + private $context; + + /** + * @since 0.4 + * + * @var ClaimDiffer|null + */ + private $claimDiffer; + + /** + * @since 0.4 + * + * @var ClaimDifferenceVisualizer|null + */ + private $claimDiffVisualizer; + + /** + * Constructor. + * + * @since 0.4 + * + * @param IContextSource $contextSource + * @param ClaimDiffer $claimDiffer + * @param ClaimDifferenceVisualizer $claimDiffView + */ + public function __construct( IContextSource $contextSource, ClaimDiffer $claimDiffer, ClaimDifferenceVisualizer $claimDiffView ) { + $this->context = $contextSource; + $this->claimDiffer = $claimDiffer; + $this->claimDiffVisualizer = $claimDiffView; + } + + /** + * Generates and returns an HTML visualization of the provided EntityDiff. + * + * @since 0.4 + * + * @param EntityDiff $diff + * + * @return string + */ + public function visualizeDiff( EntityDiff $diff ) { + $html = ''; + + $termDiffVisualizer = new DiffView( + array(), + new Diff( array( + 'label' => $diff->getLabelsDiff(), + 'aliases' => $diff->getAliasesDiff(), + 'description' => $diff->getDescriptionsDiff(), + ), true ), + $this->context + ); + + $html .= $termDiffVisualizer->getHtml(); + + foreach ( $diff->getClaimsDiff() as $claimDiffOp ) { + $html .= $this->getClaimDiffHtml( $claimDiffOp ); + } + + // FIXME: this does not belong here as it is specific to items + if ( $diff instanceof ItemDiff ) { + $termDiffVisualizer = new DiffView( + array(), + new Diff( array( + 'links' => $diff->getSiteLinkDiff(), + ), true ), + $this->context + ); + + $html .= $termDiffVisualizer->getHtml(); + } + + return $html; + } + + /** + * Returns the HTML for a single claim DiffOp. + * + * @since 0.4 + * + * @param DiffOp $claimDiffOp + * + * @return string + * @throws MWException + */ + protected function getClaimDiffHtml( DiffOp $claimDiffOp ) { + if ( $claimDiffOp instanceof DiffOpChange ) { + $claimDifference = $this->claimDiffer->diffClaims( $claimDiffOp->getOldValue(), $claimDiffOp->getNewValue() ); + return $this->claimDiffVisualizer->visualizeDiff( $claimDifference ); + } + + if ( $claimDiffOp instanceof DiffOpAdd || $claimDiffOp instanceof DiffOpRemove ) { + $claim = $claimDiffOp instanceof DiffOpAdd ? $claimDiffOp->getNewValue() : $claimDiffOp->getOldValue(); + return $this->getClaimHtml( $claim ); + } + + throw new MWException( 'Encountered an unexpected diff operation type for a claim' ); + } + + /** + * Returns the HTML for a single Claim. + * + * @since 0.4 + * + * @param Claim $claim + * + * @return string + */ + protected function getClaimHtml( Claim $claim ) { + return 'TODO'; // TODO + } + +} diff --git a/lib/tests/phpunit/claim/ClaimDifferTest.php b/lib/tests/phpunit/claim/ClaimDifferTest.php new file mode 100644 index 0000000..7c3739d --- /dev/null +++ b/lib/tests/phpunit/claim/ClaimDifferTest.php @@ -0,0 +1,69 @@ +<?php + +namespace Wikibase\Test; + +use Wikibase\ClaimDiffer; +use Wikibase\ClaimDifference; +use Wikibase\Claim; + +/** + * Tests for the Wikibase\ClaimDiffer class. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @since 0.4 + * + * @ingroup WikibaseLib + * @ingroup Test + * + * @group Wikibase + * @group WikibaseLib + * @group WikibaseClaim + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroended...@gmail.com > + */ +class ClaimDifferTest extends \MediaWikiTestCase { + + public function diffClaimsProvider() { + $argLists = array(); + + $simpleClaim = new Claim( new \Wikibase\PropertyNoValueSnak( 42 ) ); + + $argLists[] = array( $simpleClaim, $simpleClaim, new ClaimDifference() ); + + // TODO: more tests + + return $argLists; + } + + /** + * @dataProvider diffClaimsProvider + * + * @param Claim $oldClaim + * @param Claim $newClaim + * @param ClaimDifference $expected + */ + public function testDiffClaims( Claim $oldClaim, Claim $newClaim, ClaimDifference $expected ) { + $differ = new ClaimDiffer( new \Diff\ListDiffer() ); + $actual = $differ->diffClaims( $oldClaim, $newClaim ); + + $this->assertInstanceOf( 'Wikibase\ClaimDifference', $actual ); + $this->assertTrue( $expected->equals( $actual ), 'Expected equals actual' ); + } + +} diff --git a/lib/tests/phpunit/claim/ClaimDifferenceTest.php b/lib/tests/phpunit/claim/ClaimDifferenceTest.php new file mode 100644 index 0000000..7acbe16 --- /dev/null +++ b/lib/tests/phpunit/claim/ClaimDifferenceTest.php @@ -0,0 +1,94 @@ +<?php + +namespace Wikibase\Test; + +use Wikibase\ClaimDifference; + +/** + * Tests for the Wikibase\ClaimDifference class. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @since 0.4 + * + * @ingroup WikibaseLib + * @ingroup Test + * + * @group Wikibase + * @group WikibaseLib + * @group WikibaseClaim + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroended...@gmail.com > + */ +class ClaimDifferenceTest extends \MediaWikiTestCase { + + public function testGetReferenceChanges() { + $expected = new \Diff\Diff( array( + new \Diff\DiffOpAdd( new \Wikibase\Reference() ) + ), false ); + + $difference = new ClaimDifference( null, null, $expected ); + + $actual = $difference->getReferenceChanges(); + + $this->assertInstanceOf( 'Diff\Diff', $actual ); + $this->assertEquals( $expected, $actual ); + } + + public function testGetQualifierChanges() { + $expected = new \Diff\Diff( array( + new \Diff\DiffOpAdd( new \Wikibase\PropertyNoValueSnak( 42 ) ) + ), false ); + + $difference = new ClaimDifference( null, $expected ); + + $actual = $difference->getQualifierChanges(); + + $this->assertInstanceOf( 'Diff\Diff', $actual ); + $this->assertEquals( $expected, $actual ); + } + + public function testGetMainSnakChange() { + $expected = new \Diff\DiffOpChange( + new \Wikibase\PropertyNoValueSnak( 42 ), + new \Wikibase\PropertyNoValueSnak( 43 ) + ); + + $difference = new ClaimDifference( $expected ); + + $actual = $difference->getMainSnakChange(); + + $this->assertInstanceOf( 'Diff\DiffOpChange', $actual ); + $this->assertEquals( $expected, $actual ); + } + + public function testGetRankChange() { + $expected = new \Diff\DiffOpChange( + \Wikibase\Statement::RANK_PREFERRED, + \Wikibase\Statement::RANK_DEPRECATED + ); + + $difference = new ClaimDifference( null, null, null, $expected ); + + $actual = $difference->getRankChange(); + + $this->assertInstanceOf( 'Diff\DiffOpChange', $actual ); + $this->assertEquals( $expected, $actual ); + } + +} diff --git a/lib/tests/phpunit/claim/ClaimDifferenceVisualizerTest.php b/lib/tests/phpunit/claim/ClaimDifferenceVisualizerTest.php new file mode 100644 index 0000000..6509eaf --- /dev/null +++ b/lib/tests/phpunit/claim/ClaimDifferenceVisualizerTest.php @@ -0,0 +1,93 @@ +<?php + +namespace Wikibase\Test; + +use Wikibase\ClaimDifferenceVisualizer; +use Wikibase\ClaimDifference; + +/** + * Tests for the Wikibase\ClaimDifferenceVisualizer class. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @since 0.4 + * + * @ingroup WikibaseLib + * @ingroup Test + * + * @group Wikibase + * @group WikibaseLib + * @group WikibaseClaim + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroended...@gmail.com > + */ +class ClaimDifferenceVisualizerTest extends \MediaWikiTestCase { + + public function visualizeDiffProvider() { + $differences = array(); + + $differences[] = new ClaimDifference(); + + $differences[] = new ClaimDifference( + new \Diff\DiffOpChange( + new \Wikibase\PropertyNoValueSnak( 42 ), + new \Wikibase\PropertyNoValueSnak( 43 ) + ), + new \Diff\Diff( array( + new \Diff\DiffOpAdd( new \Wikibase\PropertySomeValueSnak( 44 ) ), + new \Diff\DiffOpRemove( new \Wikibase\PropertyValueSnak( 45, new \DataValues\StringValue( 'foo' ) ) ), + new \Diff\DiffOpChange( new \Wikibase\PropertySomeValueSnak( 46 ), new \Wikibase\PropertySomeValueSnak( 47 ) ), + ) ) + ); + + $differences[] = new ClaimDifference( + new \Diff\DiffOpChange( + new \Wikibase\PropertyNoValueSnak( 42 ), + new \Wikibase\PropertyNoValueSnak( 43 ) + ), + null, + new \Diff\Diff( array( + new \Diff\DiffOpAdd( new \Wikibase\Reference() ), + new \Diff\DiffOpRemove( new \Wikibase\Reference( new \Wikibase\SnakList( array( new \Wikibase\PropertyNoValueSnak( 50 ) ) ) ) ), + ) ) + ); + + $differences[] = new ClaimDifference( + null, + null, + null, + new \Diff\DiffOpChange( \Wikibase\Statement::RANK_DEPRECATED, \Wikibase\Statement::RANK_PREFERRED ) + ); + + return $this->arrayWrap( $differences ); + } + + /** + * @dataProvider visualizeDiffProvider + * + * @param ClaimDifference $claimDifference + */ + public function testVisualizeDiff( ClaimDifference $claimDifference ) { + $differenceVisualizer = new ClaimDifferenceVisualizer( new \Wikibase\CachingEntityLoader() ); + + $visualization = $differenceVisualizer->visualizeDiff( $claimDifference ); + + $this->assertInternalType( 'string', $visualization ); + } + +} diff --git a/repo/includes/EntityContentDiffView.php b/repo/includes/EntityContentDiffView.php index 23bcca5..13d8430 100644 --- a/repo/includes/EntityContentDiffView.php +++ b/repo/includes/EntityContentDiffView.php @@ -1,6 +1,8 @@ <?php namespace Wikibase; +use Diff\ListDiffer; + use Content, Html; /** @@ -123,19 +125,25 @@ return $header; } + // FIXME: can haz visibility? function generateContentDiffBody( Content $old, Content $new ) { /** * @var EntityContent $old * @var EntityContent $new */ - $diff = $old->getEntity()->getDiff( $new->getEntity() ); - $diffView = EntityDiffView::newForDiff( $diff, $this->getContext(), new WikiPageEntityLookup() ); - return $diffView->getHtml(); + // TODO: derp inject the EntityDiffVisualizer + $diffVisualizer = new EntityDiffVisualizer( + $this->getContext(), + new ClaimDiffer( new ListDiffer() ), + new ClaimDifferenceVisualizer( new WikiPageEntityLookup() ) + ); + + return $diffVisualizer->visualizeDiff( $diff ); } - protected function getParserOutput( \WikiPage $page, \Revision $rev ) { //NOTE: needs a core change to work + protected function getParserOutput( \WikiPage $page, \Revision $rev ) { $parserOptions = \ParserOptions::newFromContext( $this->getContext() ); $parserOptions->enableLimitReport(); $parserOptions->setTidy( true ); diff --git a/repo/includes/actions/EditEntityAction.php b/repo/includes/actions/EditEntityAction.php index b1c01ec..d6a9ac4 100644 --- a/repo/includes/actions/EditEntityAction.php +++ b/repo/includes/actions/EditEntityAction.php @@ -397,8 +397,6 @@ * @param EntityDiff $diff */ protected function displayUndoDiff( EntityDiff $diff ) { - $diffView = EntityDiffView::newForDiff( $diff, $this->getContext() ); - $tableClass = 'diff diff-contentalign-' . htmlspecialchars( $this->getTitle()->getPageLanguage()->alignStart() ); $this->getOutput()->addHTML( Html::openElement( 'table', array( 'class' => $tableClass ) ) ); @@ -414,7 +412,14 @@ $this->getOutput()->addHTML( Html::rawElement( 'td', array( 'colspan' => '2' ), Html::rawElement( 'div', array( 'id' => 'mw-diff-ntitle1' ), $new ) ) ); $this->getOutput()->addHTML( Html::closeElement( 'tr' ) ); - $this->getOutput()->addHTML( $diffView->getHtml() ); + // TODO: derp inject the EntityDiffVisualizer + $diffVisualizer = new EntityDiffVisualizer( + $this->getContext(), + new ClaimDiffer( new \Diff\ListDiffer() ), + new ClaimDifferenceVisualizer( new WikiPageEntityLookup() ) + ); + + $this->getOutput()->addHTML( $diffVisualizer->visualizeDiff( $diff ) ); $this->getOutput()->addHTML( Html::closeElement( 'tbody' ) ); $this->getOutput()->addHTML( Html::closeElement( 'table' ) ); -- To view, visit https://gerrit.wikimedia.org/r/51652 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7f8645df860b1860b4016003f52e7959af685a25 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Wikibase Gerrit-Branch: mw1.21-wmf11 Gerrit-Owner: Anja Jentzsch <anja.jentz...@wikimedia.de> Gerrit-Reviewer: Anja Jentzsch <anja.jentz...@wikimedia.de> Gerrit-Reviewer: Siebrand <siebr...@wikimedia.org> Gerrit-Reviewer: Tobias Gritschacher <tobias.gritschac...@wikimedia.de> Gerrit-Reviewer: jenkins-bot _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits