Thiemo Mättig (WMDE) has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/133523

Change subject: Attempt to clean-up and refactor ChangeOp and Validators code
......................................................................

Attempt to clean-up and refactor ChangeOp and Validators code

This is not really fixing a bug. The code works. But it's hard to
read and to maintain. Unfortunatelly the best I could do is to use
clone. I tried to avoid it. It gets a mess very fast (try to
reconstruct a Fingerprint object from an other Fingerprint object).
This just doesn't feel right. I think we really need to discuss this.

This is a direct follow up to some (but not all) of the comments in
Ibb6ee8439ba3ab0252403eb811aa48d1274d1d58.

Change-Id: I7434d5c40cd601976e72f104ce5699e59fef184e
---
M repo/includes/ChangeOp/ChangeOpAliases.php
M repo/includes/ChangeOp/ChangeOpDescription.php
M repo/includes/ChangeOp/ChangeOpLabel.php
M repo/includes/Validators/CompositeFingerprintValidator.php
M repo/includes/Validators/FingerprintValidator.php
M repo/includes/Validators/LabelDescriptionUniquenessValidator.php
M repo/includes/Validators/LabelUniquenessValidator.php
7 files changed, 118 insertions(+), 105 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase 
refs/changes/23/133523/1

diff --git a/repo/includes/ChangeOp/ChangeOpAliases.php 
b/repo/includes/ChangeOp/ChangeOpAliases.php
index 4d38a4a..e77afa1 100644
--- a/repo/includes/ChangeOp/ChangeOpAliases.php
+++ b/repo/includes/ChangeOp/ChangeOpAliases.php
@@ -25,86 +25,87 @@
         *
         * @var string
         */
-       protected $language;
+       private $languageCode;
 
        /**
         * @since 0.4
         *
         * @var string[]
         */
-       protected $aliases;
+       private $aliases;
 
        /**
         * @since 0.4
         *
         * @var array
         */
-       protected $action;
+       private $action;
 
        /**
         * @since 0.5
         *
         * @var TermValidatorFactory
         */
-       protected $termValidatorFactory;
+       private $termValidatorFactory;
 
        /**
         * @since 0.5
         *
-        * @param string $language
+        * @param string $languageCode
         * @param string[] $aliases
         * @param string $action should be set|add|remove
-        *
         * @param TermValidatorFactory $termValidatorFactory
         *
         * @throws InvalidArgumentException
         */
        public function __construct(
-               $language,
+               $languageCode,
                array $aliases,
                $action,
                TermValidatorFactory $termValidatorFactory
        ) {
-               if ( !is_string( $language ) ) {
-                       throw new InvalidArgumentException( '$language needs to 
be a string' );
+               if ( !is_string( $languageCode ) ) {
+                       throw new InvalidArgumentException( 'Language code 
needs to be a string.' );
                }
 
                if ( !is_string( $action ) ) {
-                       throw new InvalidArgumentException( '$action needs to 
be a string' );
+                       throw new InvalidArgumentException( 'Action needs to be 
a string.' );
                }
 
-               $this->language = $language;
+               $this->languageCode = $languageCode;
                $this->aliases = $aliases;
                $this->action = $action;
-
                $this->termValidatorFactory = $termValidatorFactory;
        }
 
        /**
-        * Applies the change to the fingerprint
-        *
         * @param Fingerprint $fingerprint
         *
         * @throws ChangeOpException
+        * @returns Fingerprint
         */
-       private function updateFingerprint( Fingerprint $fingerprint ) {
-               try {
-                       $current = $fingerprint->getAliasGroup( $this->language 
)->getAliases();
-               } catch ( \OutOfBoundsException $ex ) {
-                       $current = array();
+       private function getUpdatedFingerprint( Fingerprint $fingerprint ) {
+               if ( $fingerprint->getAliasGroups()->hasGroupForLanguage( 
$this->languageCode ) ) {
+                       $oldAliases = $fingerprint->getAliasGroup( 
$this->languageCode )->getAliases();
+               } else {
+                       $oldAliases = array();
                }
 
-               if ( $this->action === "remove" ) {
-                       $updated = array_diff( $current, $this->aliases );
-               } elseif ( $this->action === "add" ) {
-                       $updated = array_merge( $current, $this->aliases );
-               } elseif ( $this->action === "set" || $this->action === "" ) {
-                       $updated = $this->aliases;
+               $fingerprint = clone $fingerprint;
+
+               if ( $this->action === 'set' || $this->action === '' ) {
+                       $newAliases = $this->aliases;
+               } elseif ( $this->action === 'add' ) {
+                       $newAliases = array_merge( $oldAliases, $this->aliases 
);
+               } elseif ( $this->action === 'remove' ) {
+                       $newAliases = array_diff( $oldAliases, $this->aliases );
                } else {
                        throw new ChangeOpException( 'Bad action: ' . 
$this->action );
                }
 
-               $fingerprint->setAliasGroup( new AliasGroup( $this->language, 
$updated ) );
+               $fingerprint->setAliasGroup( new AliasGroup( 
$this->languageCode, $newAliases ) );
+
+               return $fingerprint;
        }
 
        /**
@@ -113,10 +114,11 @@
        public function apply( Entity $entity, Summary $summary = null ) {
                $fingerprint = $entity->getFingerprint();
 
-               $this->updateFingerprint( $fingerprint );
-               $this->updateSummary( $summary, $this->action, $this->language, 
$this->aliases );
+               $this->updateSummary( $summary, $this->action, 
$this->languageCode, $this->aliases );
 
+               $fingerprint = $this->getUpdatedFingerprint( $fingerprint );
                $entity->setFingerprint( $fingerprint );
+
                return true;
        }
 
@@ -129,7 +131,6 @@
         *
         * @param Entity $entity
         *
-        * @throws ChangeOpException
         * @return Result
         */
        public function validate( Entity $entity ) {
@@ -137,13 +138,14 @@
                $termValidator = 
$this->termValidatorFactory->getLabelValidator( $entity->getType() );
 
                // check that the language is valid
-               $result = $languageValidator->validate( $this->language );
+               $result = $languageValidator->validate( $this->languageCode );
 
                if ( !$result->isValid() ) {
                        return $result;
                }
 
-               if ( $this->action === 'set' || $this->action === '' || 
$this->action === 'add' ) {
+               // It should be possible to remove invalid aliases, but not to 
add/set new invalid ones
+               if ( $this->action !== 'remove' ) {
                        // Check that the new aliases are valid
                        foreach ( $this->aliases as $alias ) {
                                $result = $termValidator->validate( $alias );
@@ -152,11 +154,10 @@
                                        return $result;
                                }
                        }
-               } elseif ( $this->action !== 'remove' )  {
-                       throw new ChangeOpException( 'Bad action: ' . 
$this->action );
                }
 
                //XXX: Do we want to check the updated fingerprint, as we do 
for labels and descriptions?
-               return Result::newSuccess();
+               return $result;
        }
+
 }
diff --git a/repo/includes/ChangeOp/ChangeOpDescription.php 
b/repo/includes/ChangeOp/ChangeOpDescription.php
index e99d13d..1e5d57f 100644
--- a/repo/includes/ChangeOp/ChangeOpDescription.php
+++ b/repo/includes/ChangeOp/ChangeOpDescription.php
@@ -7,6 +7,7 @@
 use Wikibase\DataModel\Entity\Entity;
 use Wikibase\DataModel\Term\Fingerprint;
 use Wikibase\DataModel\Term\Term;
+use Wikibase\DataModel\Term\TermList;
 use Wikibase\Summary;
 use Wikibase\Validators\TermValidatorFactory;
 
@@ -25,58 +26,60 @@
         *
         * @var string
         */
-       protected $language;
+       private $languageCode;
 
        /**
         * @since 0.4
         *
         * @var string|null
         */
-       protected $description;
+       private $description;
 
        /**
         * @since 0.5
         *
         * @var TermValidatorFactory
         */
-       protected $termValidatorFactory;
+       private $termValidatorFactory;
 
        /**
         * @since 0.4
         *
-        * @param string $language
+        * @param string $languageCode
         * @param string|null $description
-        *
         * @param TermValidatorFactory $termValidatorFactory
         *
         * @throws InvalidArgumentException
         */
        public function __construct(
-               $language,
+               $languageCode,
                $description,
                TermValidatorFactory $termValidatorFactory
        ) {
-               if ( !is_string( $language ) ) {
-                       throw new InvalidArgumentException( '$language needs to 
be a string' );
+               if ( !is_string( $languageCode ) ) {
+                       throw new InvalidArgumentException( 'Language code 
needs to be a string.' );
                }
 
-               $this->language = $language;
+               $this->languageCode = $languageCode;
                $this->description = $description;
-
                $this->termValidatorFactory = $termValidatorFactory;
        }
 
        /**
-        * Applies the change to the fingerprint
-        *
         * @param Fingerprint $fingerprint
+        *
+        * @returns Fingerprint
         */
-       private function updateFingerprint( Fingerprint $fingerprint ) {
+       private function getUpdatedFingerprint( Fingerprint $fingerprint ) {
+               $fingerprint = clone $fingerprint;
+
                if ( $this->description === null ) {
-                       $fingerprint->removeDescription( $this->language );
+                       $fingerprint->removeDescription( $this->languageCode );
                } else {
-                       $fingerprint->setDescription( new Term( 
$this->language, $this->description ) );
+                       $fingerprint->setDescription( new Term( 
$this->languageCode, $this->description ) );
                }
+
+               return $fingerprint;
        }
 
        /**
@@ -84,23 +87,19 @@
         */
        public function apply( Entity $entity, Summary $summary = null ) {
                $fingerprint = $entity->getFingerprint();
-               $exists = $fingerprint->getDescriptions()->hasTermForLanguage( 
$this->language );
 
-               if ( $this->description === null ) {
-                       if ( $exists ) {
-                               $old = $fingerprint->getDescription( 
$this->language )->getText();
-                               $this->updateSummary( $summary, 'remove', 
$this->language, $old );
+               if ( $fingerprint->getDescriptions()->hasTermForLanguage( 
$this->languageCode ) ) {
+                       if ( $this->description === null ) {
+                               $removedDescription = 
$fingerprint->getDescription( $this->languageCode )->getText();
+                               $this->updateSummary( $summary, 'remove', 
$this->languageCode, $removedDescription );
+                       } else {
+                               $this->updateSummary( $summary, 'set', 
$this->languageCode, $this->description );
                        }
                } else {
-                       if ( $exists ) {
-                               $fingerprint->getDescription( $this->language );
-                               $this->updateSummary( $summary, 'set', 
$this->language, $this->description );
-                       } else {
-                               $this->updateSummary( $summary, 'add', 
$this->language, $this->description );
-                       }
+                       $this->updateSummary( $summary, 'add', 
$this->languageCode, $this->description );
                }
 
-               $this->updateFingerprint( $fingerprint );
+               $fingerprint = $this->getUpdatedFingerprint( $fingerprint );
                $entity->setFingerprint( $fingerprint );
 
                return true;
@@ -123,7 +122,7 @@
                $fingerprintValidator = 
$this->termValidatorFactory->getFingerprintValidator( $entity->getType() );
 
                // check that the language is valid
-               $result = $languageValidator->validate( $this->language );
+               $result = $languageValidator->validate( $this->languageCode );
 
                if ( $result->isValid() && $this->description !== null ) {
                        // Check that the new description is valid
@@ -137,12 +136,12 @@
                // Check if the new fingerprint of the entity is valid (e.g. if 
the combination
                // of label and description  is still unique)
                $fingerprint = $entity->getFingerprint();
-               $this->updateFingerprint( $fingerprint );
+               $fingerprint = $this->getUpdatedFingerprint( $fingerprint );
 
                $result = $fingerprintValidator->validateFingerprint(
                        $fingerprint,
                        $entity->getId(),
-                       array( $this->language )
+                       array( $this->languageCode )
                );
 
                return $result;
diff --git a/repo/includes/ChangeOp/ChangeOpLabel.php 
b/repo/includes/ChangeOp/ChangeOpLabel.php
index e3578cc..c2870cd 100644
--- a/repo/includes/ChangeOp/ChangeOpLabel.php
+++ b/repo/includes/ChangeOp/ChangeOpLabel.php
@@ -3,7 +3,6 @@
 namespace Wikibase\ChangeOp;
 
 use InvalidArgumentException;
-use OutOfBoundsException;
 use ValueValidators\Result;
 use Wikibase\DataModel\Entity\Entity;
 use Wikibase\DataModel\Term\Fingerprint;
@@ -26,58 +25,60 @@
         *
         * @var string
         */
-       protected $language;
+       private $languageCode;
 
        /**
         * @since 0.4
         *
         * @var string|null
         */
-       protected $label;
+       private $label;
 
        /**
         * @since 0.5
         *
         * @var TermValidatorFactory
         */
-       protected $termValidatorFactory;
+       private $termValidatorFactory;
 
        /**
         * @since 0.5
         *
-        * @param string $language
+        * @param string $languageCode
         * @param string|null $label
-        *
         * @param TermValidatorFactory $termValidatorFactory
         *
         * @throws InvalidArgumentException
         */
        public function __construct(
-               $language,
+               $languageCode,
                $label,
                TermValidatorFactory $termValidatorFactory
        ) {
-               if ( !is_string( $language ) ) {
-                       throw new InvalidArgumentException( '$language needs to 
be a string' );
+               if ( !is_string( $languageCode ) ) {
+                       throw new InvalidArgumentException( 'Language code 
needs to be a string.' );
                }
 
-               $this->language = $language;
+               $this->languageCode = $languageCode;
                $this->label = $label;
-
                $this->termValidatorFactory = $termValidatorFactory;
        }
 
        /**
-        * Applies the change to the fingerprint
-        *
         * @param Fingerprint $fingerprint
+        *
+        * @return Fingerprint
         */
-       private function updateFingerprint( Fingerprint $fingerprint ) {
+       private function getUpdatedFingerprint( Fingerprint $fingerprint ) {
+               $fingerprint = clone $fingerprint;
+
                if ( $this->label === null ) {
-                       $fingerprint->removeLabel( $this->language );
+                       $fingerprint->removeLabel( $this->languageCode );
                } else {
-                       $fingerprint->setLabel( new Term( $this->language, 
$this->label ) );
+                       $fingerprint->setLabel( new Term( $this->languageCode, 
$this->label ) );
                }
+
+               return $fingerprint;
        }
 
        /**
@@ -86,28 +87,23 @@
         * @param Entity $entity
         * @param Summary $summary
         *
-        * @throws ChangeOpException
         * @return bool
         */
        public function apply( Entity $entity, Summary $summary = null ) {
                $fingerprint = $entity->getFingerprint();
-               $exists = $fingerprint->getLabels()->hasTermForLanguage( 
$this->language );
 
-               if ( $this->label === null ) {
-                       if ( $exists ) {
-                               $old = $fingerprint->getLabel( $this->language 
)->getText();
-                               $this->updateSummary( $summary, 'remove', 
$this->language, $old );
+               if ( $fingerprint->getLabels()->hasTermForLanguage( 
$this->languageCode ) ) {
+                       if ( $this->label === null ) {
+                               $oldLabel = $fingerprint->getLabel( 
$this->languageCode )->getText();
+                               $this->updateSummary( $summary, 'remove', 
$this->languageCode, $oldLabel );
+                       } else {
+                               $this->updateSummary( $summary, 'set', 
$this->languageCode, $this->label );
                        }
                } else {
-                       if ( $exists ) {
-                               $fingerprint->getLabel( $this->language );
-                               $this->updateSummary( $summary, 'set', 
$this->language, $this->label );
-                       } else {
-                               $this->updateSummary( $summary, 'add', 
$this->language, $this->label );
-                       }
+                       $this->updateSummary( $summary, 'add', 
$this->languageCode, $this->label );
                }
 
-               $this->updateFingerprint( $fingerprint );
+               $fingerprint = $this->getUpdatedFingerprint( $fingerprint );
                $entity->setFingerprint( $fingerprint );
 
                return true;
@@ -130,7 +126,7 @@
                $fingerprintValidator = 
$this->termValidatorFactory->getFingerprintValidator( $entity->getType() );
 
                // check that the language is valid
-               $result = $languageValidator->validate( $this->language );
+               $result = $languageValidator->validate( $this->languageCode );
 
                if ( $result->isValid() && $this->label !== null ) {
                        // Check that the new label is valid
@@ -143,12 +139,12 @@
 
                // Check if the new fingerprint of the entity is valid (e.g. if 
the label is unique)
                $fingerprint = $entity->getFingerprint();
-               $this->updateFingerprint( $fingerprint );
+               $fingerprint = $this->getUpdatedFingerprint( $fingerprint );
 
                $result = $fingerprintValidator->validateFingerprint(
                        $fingerprint,
                        $entity->getId(),
-                       array( $this->language )
+                       array( $this->languageCode )
                );
 
                return $result;
diff --git a/repo/includes/Validators/CompositeFingerprintValidator.php 
b/repo/includes/Validators/CompositeFingerprintValidator.php
index 084051f..177dd1f 100644
--- a/repo/includes/Validators/CompositeFingerprintValidator.php
+++ b/repo/includes/Validators/CompositeFingerprintValidator.php
@@ -41,7 +41,11 @@
         *
         * @return Result
         */
-       public function validateFingerprint( Fingerprint $fingerprint, EntityId 
$entityId = null, $languageCodes = null ) {
+       public function validateFingerprint(
+               Fingerprint $fingerprint,
+               EntityId $entityId = null,
+               array $languageCodes = null
+       ) {
                foreach ( $this->validators as $validator ) {
                        $result = $validator->validateFingerprint( 
$fingerprint, $entityId, $languageCodes );
 
diff --git a/repo/includes/Validators/FingerprintValidator.php 
b/repo/includes/Validators/FingerprintValidator.php
index cad460d..fd499bb 100644
--- a/repo/includes/Validators/FingerprintValidator.php
+++ b/repo/includes/Validators/FingerprintValidator.php
@@ -26,11 +26,16 @@
         * @param Fingerprint $fingerprint
         * @param EntityId|null $entityId Context for uniqueness checks: 
conflicts with this entity
         *        are ignored.
-        * @param string[]|null $languageCodes If given, the validation may be 
limited to the given languages;
-        *        This is intended for optimization for the common case of only 
a single language changing.
+        * @param string[]|null $languageCodes If given, the validation may be 
limited to the given
+        *        languages. This is intended for optimization for the common 
case of only a single
+        *        language changing.
         *
         * @return Result
         */
-       public function validateFingerprint( Fingerprint $fingerprint, EntityId 
$entityId = null, $languageCodes = null );
+       public function validateFingerprint(
+               Fingerprint $fingerprint,
+               EntityId $entityId = null,
+               array $languageCodes = null
+       );
 
-}
\ No newline at end of file
+}
diff --git a/repo/includes/Validators/LabelDescriptionUniquenessValidator.php 
b/repo/includes/Validators/LabelDescriptionUniquenessValidator.php
index ec651e1..66531e4 100644
--- a/repo/includes/Validators/LabelDescriptionUniquenessValidator.php
+++ b/repo/includes/Validators/LabelDescriptionUniquenessValidator.php
@@ -51,11 +51,15 @@
         *
         * @param Fingerprint $fingerprint
         * @param EntityId|null $entityId
-        * @param array|null $languageCodes
+        * @param string[]|null $languageCodes
         *
         * @return Result
         */
-       public function validateFingerprint( Fingerprint $fingerprint, EntityId 
$entityId = null, $languageCodes = null ) {
+       public function validateFingerprint(
+               Fingerprint $fingerprint,
+               EntityId $entityId = null,
+               array $languageCodes = null
+       ) {
                $labels = array_map(
                        function( Term $term ) {
                                return $term->getText();
diff --git a/repo/includes/Validators/LabelUniquenessValidator.php 
b/repo/includes/Validators/LabelUniquenessValidator.php
index db6426a..dcb8b46 100644
--- a/repo/includes/Validators/LabelUniquenessValidator.php
+++ b/repo/includes/Validators/LabelUniquenessValidator.php
@@ -51,11 +51,15 @@
         *
         * @param Fingerprint $fingerprint
         * @param EntityId|null $entityId
-        * @param array|null $languageCodes
+        * @param string[]|null $languageCodes
         *
         * @return Result
         */
-       public function validateFingerprint( Fingerprint $fingerprint, EntityId 
$entityId = null, $languageCodes = null ) {
+       public function validateFingerprint(
+               Fingerprint $fingerprint,
+               EntityId $entityId = null,
+               array $languageCodes = null
+       ) {
                $labels = array_map(
                        function( Term $term ) {
                                return $term->getText();

-- 
To view, visit https://gerrit.wikimedia.org/r/133523
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I7434d5c40cd601976e72f104ce5699e59fef184e
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Thiemo Mättig (WMDE) <thiemo.maet...@wikimedia.de>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to