jenkins-bot has submitted this change and it was merged.

Change subject: Follow up on compatibility breaks in Wikibase.
......................................................................


Follow up on compatibility breaks in Wikibase.

Change-Id: Ia3b0b6f4e4d3c03d849632325758caf07f076a64
---
M api/RunCrossCheck.php
M composer.json
M includes/CrossCheck/CrossCheckInteractor.php
M includes/CrossCheck/CrossChecker.php
M specials/SpecialCrossCheck.php
M specials/SpecialExternalDbs.php
M tests/phpunit/Api/RunCrossCheckTest.php
M tests/phpunit/CrossCheck/CrossCheckInteractorTest.php
M tests/phpunit/DumpMetaInformation/SqlDumpMetaInformationRepoTest.php
M tests/phpunit/EvaluateCrossCheckJobServiceTest.php
M tests/phpunit/Specials/SpecialCrossCheckTest.php
11 files changed, 64 insertions(+), 63 deletions(-)

Approvals:
  Tamslo: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/api/RunCrossCheck.php b/api/RunCrossCheck.php
index 31d94f0..b92eb63 100755
--- a/api/RunCrossCheck.php
+++ b/api/RunCrossCheck.php
@@ -4,14 +4,14 @@
 
 use ApiBase;
 use ApiMain;
-use DataValues\Serializers;
 use RequestContext;
+use DataValues\Serializers;
+use Wikibase\DataModel\Entity\EntityId;
+use Wikibase\DataModel\Services\EntityId\EntityIdParser;
+use Wikibase\DataModel\Services\Statement\StatementGuidValidator;
 use Wikibase\Repo\Api\ApiErrorReporter;
 use Wikibase\Repo\Api\ApiHelperFactory;
 use Wikibase\Repo\Api\ResultBuilder;
-use Wikibase\DataModel\Entity\EntityId;
-use Wikibase\DataModel\Entity\EntityIdParser;
-use Wikibase\Lib\ClaimGuidValidator;
 use Wikibase\Repo\WikibaseRepo;
 use WikibaseQuality\ExternalValidation\CrossCheck\CrossCheckInteractor;
 use WikibaseQuality\ExternalValidation\ExternalValidationServices;
@@ -30,9 +30,14 @@
 class RunCrossCheck extends ApiBase {
 
        /**
-        * @var ClaimGuidValidator
+        * @var EntityIdParser
         */
-       private $claimGuidValidator;
+       private $entityIdParser;
+
+       /**
+        * @var StatementGuidValidator
+        */
+       private $statementGuidValidator;
 
        /**
         * @var CrossCheckInteractor
@@ -55,11 +60,6 @@
        private $resultBuilder;
 
        /**
-        * @var EntityIdParser
-        */
-       private $idParser;
-
-       /**
         * Creates new instance from global state.
         *
         * @param ApiMain $main
@@ -75,11 +75,11 @@
                        $main,
                        $name,
                        $prefix,
-                       $repo->getClaimGuidValidator(),
+                       $repo->getEntityIdParser(),
+                       $repo->getStatementGuidValidator(),
                        $externalValidationServices->getCrossCheckInteractor(),
                        $externalValidationServices->getSerializerFactory(),
-                       $repo->getApiHelperFactory( RequestContext::getMain() ),
-                       $repo->getEntityIdParser()
+                       $repo->getApiHelperFactory( RequestContext::getMain() )
                );
        }
 
@@ -87,18 +87,23 @@
         * @param ApiMain $main
         * @param string $name
         * @param string $prefix
+        * @param EntityIdParser $entityIdParser
+        * @param StatementGuidValidator $statementGuidValidator
+        * @param CrossCheckInteractor $crossCheckInteractor
+        * @param SerializerFactory $serializerFactory
+        * @param ApiHelperFactory $apiHelperFactory
         */
-       public function __construct( ApiMain $main, $name, $prefix = '', 
ClaimGuidValidator $claimGuidValidator,
-                                                                
CrossCheckInteractor $crossCheckInteractor, SerializerFactory 
$serializerFactory,
-                                                                
ApiHelperFactory $apiHelperFactory, EntityIdParser $idParser ) {
+       public function __construct( ApiMain $main, $name, $prefix = '', 
EntityIdParser $entityIdParser,
+                                                                
StatementGuidValidator $statementGuidValidator, CrossCheckInteractor 
$crossCheckInteractor,
+                                                                
SerializerFactory $serializerFactory, ApiHelperFactory $apiHelperFactory ) {
                parent::__construct( $main, $name, $prefix );
 
-               $this->claimGuidValidator = $claimGuidValidator;
+               $this->entityIdParser = $entityIdParser;
+               $this->statementGuidValidator = $statementGuidValidator;
                $this->crossCheckInteractor = $crossCheckInteractor;
                $this->serializerFactory = $serializerFactory;
-               $this->errorReporter = $apiHelperFactory->getErrorReporter( 
$this );
                $this->resultBuilder = $apiHelperFactory->getResultBuilder( 
$this );
-               $this->idParser = $idParser;
+               $this->errorReporter = $apiHelperFactory->getErrorReporter( 
$this );
        }
 
        /**
@@ -142,7 +147,7 @@
         */
        private function parseEntityIds( array $entityIds ) {
                return array_map(
-                       array( $this->idParser, 'parse' ),
+                       array( $this->entityIdParser, 'parse' ),
                        $entityIds
                );
        }
@@ -152,7 +157,7 @@
         */
        private function assertAreValidClaimGuids( array $claimGuids ) {
                foreach ( $claimGuids as $claimGuid ) {
-                       if ( $this->claimGuidValidator->validateFormat( 
$claimGuid ) === false ) {
+                       if ( $this->statementGuidValidator->validateFormat( 
$claimGuid ) === false ) {
                                $this->errorReporter->dieError( 'Invalid claim 
guid.', 'invalid-guid' );
                        }
                }
diff --git a/composer.json b/composer.json
index e047d0c..8d0c315 100755
--- a/composer.json
+++ b/composer.json
@@ -15,7 +15,8 @@
        },
        "require": {
                "php": ">=5.3.0",
-               "wikibase/data-model": "~3.0",
+               "wikibase/data-model": "~4.0",
+               "wikibase/data-model-services": "~1.1",
                "serialization/serialization": "3.*,>=3.2.1",
                "wikibase/data-model-serialization": "~1.3",
                "wikimedia/assert": "~0.2.2"
diff --git a/includes/CrossCheck/CrossCheckInteractor.php 
b/includes/CrossCheck/CrossCheckInteractor.php
index 73fdee2..cac7472 100755
--- a/includes/CrossCheck/CrossCheckInteractor.php
+++ b/includes/CrossCheck/CrossCheckInteractor.php
@@ -3,13 +3,13 @@
 namespace WikibaseQuality\ExternalValidation\CrossCheck;
 
 use InvalidArgumentException;
-use Wikibase\DataModel\Statement\StatementGuidParser;
+use Wikibase\DataModel\Services\Lookup\EntityLookup;
+use Wikibase\DataModel\Services\Statement\StatementGuidParser;
 use Wikimedia\Assert\Assert;
 use Wikibase\DataModel\Entity\Entity;
 use Wikibase\DataModel\Entity\EntityId;
 use Wikibase\DataModel\Entity\PropertyId;
 use Wikibase\DataModel\Statement\StatementList;
-use Wikibase\Lib\Store\EntityLookup;
 use WikibaseQuality\ExternalValidation\CrossCheck\Result\CrossCheckResultList;
 
 
diff --git a/includes/CrossCheck/CrossChecker.php 
b/includes/CrossCheck/CrossChecker.php
index 38f0ebd..f7827f3 100755
--- a/includes/CrossCheck/CrossChecker.php
+++ b/includes/CrossCheck/CrossChecker.php
@@ -9,10 +9,10 @@
 use Wikibase\DataModel\Entity\Entity;
 use Wikibase\DataModel\Entity\EntityIdValue;
 use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Services\Lookup\EntityLookup;
 use Wikibase\DataModel\Snak\PropertyValueSnak;
 use Wikibase\DataModel\Statement\Statement;
 use Wikibase\DataModel\Statement\StatementList;
-use Wikibase\Lib\Store\EntityLookup;
 use 
WikibaseQuality\ExternalValidation\CrossCheck\ValueParser\ComparativeValueParser;
 use 
WikibaseQuality\ExternalValidation\CrossCheck\ValueParser\ComparativeValueParserFactory;
 use WikibaseQuality\ExternalValidation\CrossCheck\Comparer\DataValueComparer;
diff --git a/specials/SpecialCrossCheck.php b/specials/SpecialCrossCheck.php
index 4557f15..2c92910 100755
--- a/specials/SpecialCrossCheck.php
+++ b/specials/SpecialCrossCheck.php
@@ -14,19 +14,16 @@
 use ValueFormatters\FormatterOptions;
 use ValueFormatters\ValueFormatter;
 use Wikibase\DataModel\Entity\EntityId;
-use Wikibase\DataModel\Entity\EntityIdParser;
-use Wikibase\DataModel\Entity\EntityIdParsingException;
 use Wikibase\DataModel\Entity\EntityIdValue;
-use Wikibase\Lib\EntityIdFormatter;
-use Wikibase\Lib\EntityIdHtmlLinkFormatter;
-use Wikibase\Lib\EntityIdLabelFormatter;
-use Wikibase\Lib\LanguageNameLookup;
+use Wikibase\DataModel\Services\EntityId\EntityIdFormatter;
+use Wikibase\DataModel\Services\EntityId\EntityIdParser;
+use Wikibase\DataModel\Services\EntityId\EntityIdParsingException;
+use Wikibase\DataModel\Services\Lookup\EntityLookup;
+use Wikibase\DataModel\Services\Lookup\LanguageLabelDescriptionLookup;
+use Wikibase\DataModel\Services\Lookup\TermLookup;
 use Wikibase\Lib\OutputFormatValueFormatterFactory;
 use Wikibase\Lib\SnakFormatter;
-use Wikibase\Lib\Store\EntityLookup;
 use Wikibase\Lib\Store\EntityTitleLookup;
-use Wikibase\Lib\Store\LanguageLabelDescriptionLookup;
-use Wikibase\Lib\Store\TermLookup;
 use Wikibase\Repo\EntityIdHtmlLinkFormatterFactory;
 use Wikibase\Repo\EntityIdLabelFormatterFactory;
 use Wikibase\Repo\WikibaseRepo;
diff --git a/specials/SpecialExternalDbs.php b/specials/SpecialExternalDbs.php
index 03754a4..f549c8d 100755
--- a/specials/SpecialExternalDbs.php
+++ b/specials/SpecialExternalDbs.php
@@ -3,19 +3,13 @@
 namespace WikibaseQuality\ExternalValidation\Specials;
 
 
-use DateInterval;
-use DateTime;
-use DateTimeZone;
 use Html;
 use Language;
 use Linker;
 use SpecialPage;
-use Wikibase\Lib\EntityIdFormatter;
-use Wikibase\Lib\EntityIdHtmlLinkFormatter;
-use Wikibase\Lib\LanguageNameLookup;
+use Wikibase\DataModel\Services\Lookup\LanguageLabelDescriptionLookup;
+use Wikibase\DataModel\Services\Lookup\TermLookup;
 use Wikibase\Lib\Store\EntityTitleLookup;
-use Wikibase\Lib\Store\LanguageLabelDescriptionLookup;
-use Wikibase\Lib\Store\TermLookup;
 use Wikibase\Repo\EntityIdHtmlLinkFormatterFactory;
 use Wikibase\Repo\WikibaseRepo;
 use WikibaseQuality\ExternalValidation\DumpMetaInformation\DumpMetaInformation;
@@ -29,7 +23,7 @@
 class SpecialExternalDbs extends SpecialPage {
 
        /**
-        * @var EntityIdFormatter
+        * @var EntityIdHtmlLinkFormatterFactory
         */
        private $entityIdLinkFormatter;
 
diff --git a/tests/phpunit/Api/RunCrossCheckTest.php 
b/tests/phpunit/Api/RunCrossCheckTest.php
index 4911c10..f4fbe1d 100755
--- a/tests/phpunit/Api/RunCrossCheckTest.php
+++ b/tests/phpunit/Api/RunCrossCheckTest.php
@@ -9,8 +9,9 @@
 use Wikibase\DataModel\Entity\ItemId;
 use Wikibase\DataModel\Entity\Property;
 use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Services\Statement\V4GuidGenerator;
 use Wikibase\DataModel\Snak\PropertyValueSnak;
-use Wikibase\Lib\ClaimGuidGenerator;
+use Wikibase\DataModel\Statement\StatementGuid;
 use Wikibase\Repo\WikibaseRepo;
 use Wikibase\Test\Repo\Api\WikibaseApiTestCase;
 use 
WikibaseQuality\ExternalValidation\DumpMetaInformation\SqlDumpMetaInformationRepo;
@@ -44,7 +45,7 @@
  * @author BP2014N1
  * @license GNU GPL v2+
  */
-class RunCrossCheckTest extends WikibaseApiTestcase {
+class RunCrossCheckTest extends WikibaseApiTestCase {
 
        /**
         * Id of a item that (hopefully) does not exist.
@@ -90,29 +91,29 @@
                        $store->saveEntity( $itemQ1, 'TestEntityQ1', 
$GLOBALS['wgUser'], EDIT_NEW );
                        self::$idMap['Q1'] = $itemQ1->getId();
 
-                       $claimGuidGenerator = new ClaimGuidGenerator();
+                       $guidGenerator = new V4GuidGenerator();
 
                        $dataValue = new EntityIdValue( new ItemId( 
IDENTIFIER_PROPERTY_QID ) );
                        $snak = new PropertyValueSnak( new PropertyId( 
INSTANCE_OF_PID ), $dataValue );
-                       $claimGuid = $claimGuidGenerator->newGuid( 
self::$idMap['P3'] );
+                       $claimGuid = self::$idMap['P3']->getSerialization() . 
StatementGuid::SEPARATOR . $guidGenerator->newGuid();
                        $propertyP3->getStatements()->addNewStatement( $snak, 
null, null, $claimGuid );
                        $store->saveEntity( $propertyP3, 'TestEntityP3',  
$GLOBALS['wgUser'], EDIT_UPDATE );
 
                        $dataValue = new StringValue( 'foo' );
                        $snak = new PropertyValueSnak( self::$idMap['P1'], 
$dataValue );
-                       $claimGuid = $claimGuidGenerator->newGuid( 
self::$idMap['Q1'] );
+                       $claimGuid = self::$idMap['Q1']->getSerialization() . 
StatementGuid::SEPARATOR . $guidGenerator->newGuid();
                        self::$claimGuids['P1'] = $claimGuid;
                        $itemQ1->getStatements()->addNewStatement( $snak, null, 
null, $claimGuid );
 
                        $dataValue = new StringValue( 'baz' );
                        $snak = new PropertyValueSnak( self::$idMap['P2'], 
$dataValue );
-                       $claimGuid = $claimGuidGenerator->newGuid( 
self::$idMap['Q1'] );
+                       $claimGuid = self::$idMap['Q1']->getSerialization() . 
StatementGuid::SEPARATOR . $guidGenerator->newGuid();
                        self::$claimGuids['P2'] = $claimGuid;
                        $itemQ1->getStatements()->addNewStatement( $snak, null, 
null, $claimGuid );
 
                        $dataValue = new StringValue( '1234' );
                        $snak = new PropertyValueSnak( self::$idMap['P3'], 
$dataValue );
-                       $claimGuid = $claimGuidGenerator->newGuid( 
self::$idMap['Q1'] );
+                       $claimGuid = self::$idMap['Q1']->getSerialization() . 
StatementGuid::SEPARATOR . $guidGenerator->newGuid();
                        self::$claimGuids['P3'] = $claimGuid;
                        $itemQ1->getStatements()->addNewStatement( $snak, null, 
null, $claimGuid );
 
diff --git a/tests/phpunit/CrossCheck/CrossCheckInteractorTest.php 
b/tests/phpunit/CrossCheck/CrossCheckInteractorTest.php
index db00ed5..44a6076 100755
--- a/tests/phpunit/CrossCheck/CrossCheckInteractorTest.php
+++ b/tests/phpunit/CrossCheck/CrossCheckInteractorTest.php
@@ -2,12 +2,12 @@
 
 namespace WikibaseQuality\ExternalValidation\Tests\CrossCheck;
 
-use Wikibase\DataModel\Statement\StatementGuidParser;
-use Wikibase\DataModel\Entity\BasicEntityIdParser;
 use Wikibase\DataModel\Entity\Entity;
 use Wikibase\DataModel\Entity\Item;
 use Wikibase\DataModel\Entity\ItemId;
 use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Services\EntityId\BasicEntityIdParser;
+use Wikibase\DataModel\Services\Statement\StatementGuidParser;
 use Wikibase\DataModel\Statement\Statement;
 use Wikibase\DataModel\Statement\StatementList;
 use WikibaseQuality\ExternalValidation\CrossCheck\CrossCheckInteractor;
diff --git 
a/tests/phpunit/DumpMetaInformation/SqlDumpMetaInformationRepoTest.php 
b/tests/phpunit/DumpMetaInformation/SqlDumpMetaInformationRepoTest.php
index 472bc27..741da5c 100755
--- a/tests/phpunit/DumpMetaInformation/SqlDumpMetaInformationRepoTest.php
+++ b/tests/phpunit/DumpMetaInformation/SqlDumpMetaInformationRepoTest.php
@@ -2,10 +2,9 @@
 
 namespace WikibaseQuality\ExternalValidation\Tests\DumpMetaInformation;
 
-use DateTime;
-use Wikibase\DataModel\Entity\BasicEntityIdParser;
 use Wikibase\DataModel\Entity\ItemId;
 use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Services\EntityId\BasicEntityIdParser;
 use WikibaseQuality\ExternalValidation\DumpMetaInformation\DumpMetaInformation;
 use 
WikibaseQuality\ExternalValidation\DumpMetaInformation\SqlDumpMetaInformationRepo;
 
diff --git a/tests/phpunit/EvaluateCrossCheckJobServiceTest.php 
b/tests/phpunit/EvaluateCrossCheckJobServiceTest.php
index ca30046..5986314 100755
--- a/tests/phpunit/EvaluateCrossCheckJobServiceTest.php
+++ b/tests/phpunit/EvaluateCrossCheckJobServiceTest.php
@@ -6,6 +6,8 @@
 use Wikibase\DataModel\Entity\Item;
 use Wikibase\DataModel\Entity\ItemId;
 use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Services\Statement\V4GuidGenerator;
+use Wikibase\DataModel\Statement\StatementGuid;
 use WikibaseQuality\ExternalValidation\EvaluateCrossCheckJobService;
 use WikibaseQuality\ExternalValidation\DumpMetaInformation\DumpMetaInformation;
 use WikibaseQuality\ExternalValidation\CrossCheck\Result\ComparisonResult;
@@ -42,9 +44,9 @@
                $propertyId = new PropertyId( 'P188' );
                $identifierPropertyIds = array( new PropertyId( 'P42' ) );
 
-               $guidGenerator = new ClaimGuidGenerator();
+               $guidGenerator = new V4GuidGenerator();
                $itemId = new ItemId( 'Q42' );
-               $claimGuid = $guidGenerator->newGuid( $itemId );
+               $claimGuid = $itemId->getSerialization() . 
StatementGuid::SEPARATOR . $guidGenerator->newGuid();
 
                $externalId = 'foobar';
 
diff --git a/tests/phpunit/Specials/SpecialCrossCheckTest.php 
b/tests/phpunit/Specials/SpecialCrossCheckTest.php
index 5878bdd..7f5e672 100755
--- a/tests/phpunit/Specials/SpecialCrossCheckTest.php
+++ b/tests/phpunit/Specials/SpecialCrossCheckTest.php
@@ -5,6 +5,8 @@
 use Wikibase\DataModel\Entity\EntityIdValue;
 use Wikibase\DataModel\Entity\ItemId;
 use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Services\Statement\V4GuidGenerator;
+use Wikibase\DataModel\Statement\StatementGuid;
 use Wikibase\Repo\EntityIdLabelFormatterFactory;
 use Wikibase\Test\SpecialPageTestBase;
 use 
WikibaseQuality\ExternalValidation\DumpMetaInformation\SqlDumpMetaInformationRepo;
@@ -121,17 +123,17 @@
                        $store->saveEntity($itemQ1, 'TestEntityQ1', 
$GLOBALS['wgUser'], EDIT_NEW);
                        self::$idMap['Q1'] = $itemQ1->getId();
 
-                       $statementGuidGenerator = new ClaimGuidGenerator();
+                       $guidGenerator = new V4GuidGenerator();
 
                        $dataValue = new EntityIdValue(new 
ItemId(IDENTIFIER_PROPERTY_QID));
                        $snak = new PropertyValueSnak(new 
PropertyId(INSTANCE_OF_PID), $dataValue);
-                       $claimGuid = 
$statementGuidGenerator->newGuid(self::$idMap['P3']);
+                       $claimGuid = self::$idMap['P3']->getSerialization() . 
StatementGuid::SEPARATOR . $guidGenerator->newGuid();
                        $propertyP3->getStatements()->addNewStatement($snak, 
null, null, $claimGuid);
                        $store->saveEntity($propertyP3, 'TestEntityP3', 
$GLOBALS['wgUser'], EDIT_UPDATE);
 
                        $dataValue = new StringValue('foo');
                        $snak = new PropertyValueSnak(self::$idMap['P1'], 
$dataValue);
-                       $statementGuid = 
$statementGuidGenerator->newGuid(self::$idMap['Q1']);
+                       $statementGuid = self::$idMap['Q1']->getSerialization() 
. StatementGuid::SEPARATOR . $guidGenerator->newGuid();
                        $statement = new Statement($snak);
                        self::$statementGuids['P1'] = $statementGuid;
                        $statement->setGuid($statementGuid);
@@ -139,7 +141,7 @@
 
                        $dataValue = new StringValue('baz');
                        $snak = new PropertyValueSnak(self::$idMap['P2'], 
$dataValue);
-                       $statementGuid = 
$statementGuidGenerator->newGuid(self::$idMap['Q1']);
+                       $statementGuid = self::$idMap['Q1']->getSerialization() 
. StatementGuid::SEPARATOR . $guidGenerator->newGuid();
                        $statement = new Statement($snak);
                        self::$statementGuids['P2'] = $statementGuid;
                        $statement->setGuid($statementGuid);
@@ -148,7 +150,7 @@
                        $dataValue = new StringValue('1234');
                        $snak = new PropertyValueSnak(self::$idMap['P3'], 
$dataValue);
                        $statement = new Statement($snak);
-                       $statementGuid = 
$statementGuidGenerator->newGuid(self::$idMap['Q1']);
+                       $statementGuid = self::$idMap['Q1']->getSerialization() 
. StatementGuid::SEPARATOR . $guidGenerator->newGuid();
                        self::$statementGuids['P3'] = $statementGuid;
                        $statement->setGuid($statementGuid);
                        $itemQ1->getStatements()->addStatement($statement);
@@ -156,7 +158,7 @@
                        $dataValue = new StringValue('partiall');
                        $snak = new PropertyValueSnak(self::$idMap['P4'], 
$dataValue);
                        $statement = new Statement($snak);
-                       $statementGuid = 
$statementGuidGenerator->newGuid(self::$idMap['Q1']);
+                       $statementGuid = self::$idMap['Q1']->getSerialization() 
. StatementGuid::SEPARATOR . $guidGenerator->newGuid();
                        self::$statementGuids['P4'] = $statementGuid;
                        $statement->setGuid($statementGuid);
                        $itemQ1->getStatements()->addStatement($statement);

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ia3b0b6f4e4d3c03d849632325758caf07f076a64
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/extensions/WikibaseQualityExternalValidation
Gerrit-Branch: v1
Gerrit-Owner: Soeren.oldag <[email protected]>
Gerrit-Reviewer: Tamslo <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to