From bd1fb4a7f06aea92ea2e67ae5c30547461c912c3 Mon Sep 17 00:00:00 2001 From: vims Date: Mon, 10 Aug 2020 16:31:51 +0200 Subject: [PATCH 01/36] change PHP-Version to 7.2 because it's 2020 --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index b1d8732..c158501 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "babymarkt/deepl-php-lib", "type": "library", - "description": "DeepL API Client Library supporting PHP >= 5.3 && PHP < 8.0", + "description": "DeepL API Client Library supporting PHP >= 7.2 && PHP < 8.0", "keywords": [ "babymarkt", "deepl", @@ -19,10 +19,10 @@ } ], "require": { - "php": ">=5.3 <8.0" + "php": ">=7.2 <8.0" }, "require-dev": { - "php": ">=5.3 <8.0", + "php": ">=7.2 <8.0", "phpmd/phpmd": "2.4.*", "phpunit/phpunit": "^4.8", "squizlabs/php_codesniffer": "^2.9" From 4ca4f23809e0bb0f7251e7e10e3d8a6848011ba5 Mon Sep 17 00:00:00 2001 From: vims Date: Mon, 10 Aug 2020 16:34:06 +0200 Subject: [PATCH 02/36] - add host to constructor - add all 3 resources form DeepL api - refactor buildURL-function - add usage-fcuntion --- src/DeepL.php | 68 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index 634a46d..1759927 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -10,14 +10,24 @@ class DeepL { /** - * API v1 URL + * API BASE URL + */ + const API_URL_BASE = '%s://%s/v%s'; + + /** + * API URL: translate + */ + const API_URL_RESOURCE_TRANSLATE = 'translate'; + + /** + * API URL: usage */ - const API_URL_V1 = 'https://api.deepl.com/v1/translate'; + const API_URL_RESOURCE_USAGE = 'usage'; /** - * API v2 URL + * API URL: languages */ - const API_URL_V2 = 'https://api.deepl.com/v2/translate'; + const API_URL_RESOURCE_LANGUAGES = 'languages '; /** * API URL: Parameter auth_key @@ -132,10 +142,11 @@ class DeepL * @param string $authKey * @param integer $apiVersion */ - public function __construct($authKey, $apiVersion = 2) + public function __construct($authKey, $apiVersion = 2, $host = 'api.deepl.com') { $this->authKey = $authKey; $this->apiVersion = $apiVersion; + $this->host = $host; $this->curl = curl_init(); curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1); @@ -193,6 +204,16 @@ public function translate( return $translationsArray['translations']; } + public function usage() + { + $result = []; + $body = ''; + $url = $this->buildUrl(null, null, [], [], '', 'usage'); + $result = $this->request($url, $body); + + return $result; + } + /** * Check if the given languages are supported * @@ -232,31 +253,30 @@ protected function checkLanguages($sourceLanguage, $destinationLanguage) * @param array $tagHandling * @param array $ignoreTags * @param string $formality + * @param string $resource * * @return string */ protected function buildUrl( - $sourceLanguage, - $destinationLanguage, - array $tagHandling = array(), - array $ignoreTags = array(), - $formality = "default" - ) { - // select correct api url - switch ($this->apiVersion) { - case 1: - $url = DeepL::API_URL_V1; - break; - case 2: - $url = DeepL::API_URL_V2; - break; - default: - $url = DeepL::API_URL_V2; + $sourceLanguage = null, + $destinationLanguage = null, + $tagHandling = null, + $ignoreTags = null, + $formality="default", + $resource='translate' + ) + { + $url = sprintf(DeepL::API_URL_BASE, 'https', $this->host, $this->apiVersion); + $url .= sprintf('/%s', $resource); + $url .= '?' . sprintf(DeepL::API_URL_AUTH_KEY, $this->authKey); + + if (!empty($sourceLanguage)) { + $url .= '&'.sprintf(DeepL::API_URL_SOURCE_LANG, strtolower($sourceLanguage)); } - $url .= '?' . sprintf(DeepL::API_URL_AUTH_KEY, $this->authKey); - $url .= '&' . sprintf(DeepL::API_URL_SOURCE_LANG, strtolower($sourceLanguage)); - $url .= '&' . sprintf(DeepL::API_URL_DESTINATION_LANG, strtolower($destinationLanguage)); + if (!empty($destinationLanguage)) { + $url .= '&'.sprintf(DeepL::API_URL_DESTINATION_LANG, strtolower($destinationLanguage)); + } if (!empty($tagHandling)) { $url .= '&' . sprintf(DeepL::API_URL_TAG_HANDLING, implode(',', $tagHandling)); From a0ce41626cff0ce8fe75b25c2c6681ffa1eeb8b2 Mon Sep 17 00:00:00 2001 From: vims Date: Tue, 11 Aug 2020 15:04:57 +0200 Subject: [PATCH 03/36] - add languages-function - add Missiong DeepL-Parameters to buildUrl and translate functions - refactor code for PHP7+ - Adjust Tests --- src/DeepL.php | 230 ++++++++++++++++++++++++++++++-------------- tests/DeepLTest.php | 42 +++++--- 2 files changed, 184 insertions(+), 88 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index 1759927..9bd9d93 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -10,8 +10,8 @@ class DeepL { /** - * API BASE URL - */ + * API BASE URL + */ const API_URL_BASE = '%s://%s/v%s'; /** @@ -27,7 +27,7 @@ class DeepL /** * API URL: languages */ - const API_URL_RESOURCE_LANGUAGES = 'languages '; + const API_URL_RESOURCE_LANGUAGES = 'languages'; /** * API URL: Parameter auth_key @@ -64,25 +64,50 @@ class DeepL */ const API_URL_FORMALITY = 'formality=%s'; + /** + * API URL: Parameter split_sentences + */ + const API_URL_SPLIT_SENTENCES= 'split_sentences=%s'; + + /** + * API URL: Parameter preserve_formatting + */ + const API_URL_PRESERVER_FORMATING = 'preserve_formatting=%s'; + + /** + * API URL: Parameter non_splitting_tags + */ + const API_URL_NON_SPLITTING_TAGS= 'non_splitting_tags=%s'; + + /** + * API URL: Parameter outline_detection + */ + const API_URL_OUTLINE_DETECTION= 'outline_detection=%s'; + + /** + * API URL: Parameter splitting_tags + */ + const API_URL_SPLITTING_TAGS = 'splitting_tags=%s'; + /** * DeepL HTTP error codes * * @var array */ - protected $errorCodes = array( + protected $errorCodes = [ 400 => 'Wrong request, please check error message and your parameters.', 403 => 'Authorization failed. Please supply a valid auth_key parameter.', 413 => 'Request Entity Too Large. The request size exceeds the current limit.', 429 => 'Too many requests. Please wait and send your request once again.', - 456 => 'Quota exceeded. The character limit has been reached.' - ); + 456 => 'Quota exceeded. The character limit has been reached.', + ]; /** * Supported translation source languages * * @var array */ - protected $sourceLanguages = array( + protected $sourceLanguages = [ 'EN', 'DE', 'FR', @@ -93,15 +118,15 @@ class DeepL 'PL', 'RU', 'JA', - 'ZH' - ); + 'ZH', + ]; /** * Supported translation destination languages * * @var array */ - protected $destinationLanguages = array( + protected $destinationLanguages = [ 'EN', 'DE', 'FR', @@ -114,8 +139,8 @@ class DeepL 'PL', 'RU', 'JA', - 'ZH' - ); + 'ZH', + ]; /** * @var integer @@ -177,18 +202,31 @@ public function __destruct() * @throws DeepLException */ public function translate( - $text, - $sourceLanguage = 'de', - $destinationLanguage = 'en', - array $tagHandling = array(), - array $ignoreTags = array(), - $formality = "default" + string $text, + string $sourceLanguage = 'de', + string $destinationLanguage = 'en', + string $tagHandling = null, + array $ignoreTags = null, + string $formality = "default", + string $resource = 'translate', + string $splitSentences = null, + bool $preserveFormatting = null, + array $nonSplittingTags = null, + bool $outlineDetection = null, + array $splittingTags = null ) { // make sure we only accept supported languages $this->checkLanguages($sourceLanguage, $destinationLanguage); // build the DeepL API request url - $url = $this->buildUrl($sourceLanguage, $destinationLanguage, $tagHandling, $ignoreTags, $formality); + $url = $this->buildUrl( + $sourceLanguage, + $destinationLanguage, + $tagHandling, + $ignoreTags, + $formality, + self::API_URL_RESOURCE_TRANSLATE + ); $body = $this->buildBody($text); // request the DeepL API @@ -204,16 +242,6 @@ public function translate( return $translationsArray['translations']; } - public function usage() - { - $result = []; - $body = ''; - $url = $this->buildUrl(null, null, [], [], '', 'usage'); - $result = $this->request($url, $body); - - return $result; - } - /** * Check if the given languages are supported * @@ -224,11 +252,11 @@ public function usage() * * @throws DeepLException */ - protected function checkLanguages($sourceLanguage, $destinationLanguage) + protected function checkLanguages(string $sourceLanguage, string $destinationLanguage) { $sourceLanguage = strtoupper($sourceLanguage); - if (!in_array($sourceLanguage, $this->sourceLanguages)) { + if (false === in_array($sourceLanguage, $this->sourceLanguages)) { throw new DeepLException( sprintf('The language "%s" is not supported as source language.', $sourceLanguage) ); @@ -236,7 +264,7 @@ protected function checkLanguages($sourceLanguage, $destinationLanguage) $destinationLanguage = strtoupper($destinationLanguage); - if (!in_array($destinationLanguage, $this->destinationLanguages)) { + if (false === in_array($destinationLanguage, $this->destinationLanguages)) { throw new DeepLException( sprintf('The language "%s" is not supported as destination language.', $destinationLanguage) ); @@ -258,66 +286,63 @@ protected function checkLanguages($sourceLanguage, $destinationLanguage) * @return string */ protected function buildUrl( - $sourceLanguage = null, - $destinationLanguage = null, - $tagHandling = null, - $ignoreTags = null, - $formality="default", - $resource='translate' - ) - { - $url = sprintf(DeepL::API_URL_BASE, 'https', $this->host, $this->apiVersion); + string $sourceLanguage = null, + string $destinationLanguage = null, + string $tagHandling = null, + array $ignoreTags = null, + string $formality = 'default', + string $resource = 'translate', + string $splitSentences = null, + bool $preserveFormatting = null, + array $nonSplittingTags = null, + bool $outlineDetection = null, + array $splittingTags = null + ) { + $url = sprintf(self::API_URL_BASE, 'https', $this->host, $this->apiVersion); $url .= sprintf('/%s', $resource); - $url .= '?' . sprintf(DeepL::API_URL_AUTH_KEY, $this->authKey); + $url .= '?'.sprintf(self::API_URL_AUTH_KEY, $this->authKey); - if (!empty($sourceLanguage)) { - $url .= '&'.sprintf(DeepL::API_URL_SOURCE_LANG, strtolower($sourceLanguage)); + if (false === empty($sourceLanguage)) { + $url .= '&'.sprintf(self::API_URL_SOURCE_LANG, strtolower($sourceLanguage)); } - if (!empty($destinationLanguage)) { - $url .= '&'.sprintf(DeepL::API_URL_DESTINATION_LANG, strtolower($destinationLanguage)); + if (false === empty($destinationLanguage)) { + $url .= '&'.sprintf(self::API_URL_DESTINATION_LANG, strtolower($destinationLanguage)); } - if (!empty($tagHandling)) { - $url .= '&' . sprintf(DeepL::API_URL_TAG_HANDLING, implode(',', $tagHandling)); + if (false === empty($tagHandling)) { + $url .= '&'.sprintf(self::API_URL_TAG_HANDLING, $tagHandling); } - if (!empty($ignoreTags)) { - $url .= '&' . sprintf(DeepL::API_URL_IGNORE_TAGS, implode(',', $ignoreTags)); + if (false === empty($ignoreTags)) { + $url .= '&'.sprintf(self::API_URL_IGNORE_TAGS, implode(',', $ignoreTags)); } - if (!empty($formality)) { - $url .= '&' . sprintf(DeepL::API_URL_FORMALITY, $formality); + if (false === empty($formality)) { + $url .= '&'.sprintf(self::API_URL_FORMALITY, $formality); } - return $url; - } + if (false === empty($splitSentences)) { + $url .= '&'.sprintf(self::API_URL_SPLIT_SENTENCES, $splitSentences); + } - /** - * Build the body for the DeepL API request - * - * @param string|string[] $text - * - * @return string - */ - protected function buildBody($text) - { - $body = ''; - $first = true; + if (false === empty($preserveFormatting)) { + $url .= '&'.sprintf(self::API_URL_PRESERVER_FORMATING, $preserveFormatting); + } - if (!is_array($text)) { - $text = (array)$text; + if (false === empty($nonSplittingTags)) { + $url .= '&'.sprintf(self::API_URL_NON_SPLITTING_TAGS, implode(',', $nonSplittingTags)); } - foreach ($text as $textElement) { - $body .= ($first ? '' : '&') . sprintf(DeepL::API_URL_TEXT, rawurlencode($textElement)); + if (false === empty($outlineDetection)) { + $url .= '&'.sprintf(self::API_URL_OUTLINE_DETECTION, $outlineDetection); + } - if ($first) { - $first = false; - } + if (false === empty($splittingTags)) { + $url .= '&'.sprintf(self::API_URL_SPLITTING_TAGS, implode(',', $splittingTags)); } - return $body; + return $url; } /** @@ -331,9 +356,10 @@ protected function buildBody($text) */ protected function request($url, $body) { + curl_setopt($this->curl, CURLOPT_POST, true); curl_setopt($this->curl, CURLOPT_URL, $url); curl_setopt($this->curl, CURLOPT_POSTFIELDS, $body); - curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); + curl_setopt($this->curl, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']); $response = curl_exec($this->curl); @@ -355,4 +381,60 @@ protected function request($url, $body) return $translationsArray; } + + /** + * Build the body for the DeepL API request + * + * @param string|string[] $text + * + * @return string + */ + protected function buildBody($text) + { + $body = ''; + $first = true; + + if (!is_array($text)) { + $text = (array)$text; + } + + foreach ($text as $textElement) { + $body .= ($first ? '' : '&').sprintf(self::API_URL_TEXT, rawurlencode($textElement)); + + if ($first) { + $first = false; + } + } + + return $body; + } + + /** + * @return array + * @throws DeepLException + */ + public function usage() + { + $result = []; + $body = ''; + $url = $this->buildUrl(null, null, null, null, '', self::API_URL_RESOURCE_USAGE); + $result = $this->request($url, $body); + + return $result; + } + + + /** + * @return array + * @throws DeepLException + */ + public function languages() + { + $result = []; + $body = ''; + $url = $this->buildUrl(null, null, [], [], '', self::API_URL_RESOURCE_LANGUAGES); + $result = $this->request($url, $body); + + return $result; + } } diff --git a/tests/DeepLTest.php b/tests/DeepLTest.php index e4b4879..3e6d2ce 100644 --- a/tests/DeepLTest.php +++ b/tests/DeepLTest.php @@ -164,7 +164,7 @@ public function testBuildUrlWithTags() $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildUrl'); - $return = $buildUrl->invokeArgs($deepl, array('de', 'en', array('xml'), array('x'))); + $return = $buildUrl->invokeArgs($deepl, array('de', 'en', 'xml', array('x'))); $this->assertEquals($expectedString, $return); } @@ -188,7 +188,7 @@ public function testBuildUrlWithTagsV1() $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildUrl'); - $return = $buildUrl->invokeArgs($deepl, array('de', 'en', array('xml'), array('x'))); + $return = $buildUrl->invokeArgs($deepl, array('de', 'en', 'xml', array('x'))); $this->assertEquals($expectedString, $return); } @@ -257,20 +257,17 @@ public function testTranslateV1Success() * * TEST REQUIRES VALID DEEPL AUTH KEY!! */ - public function testTranslateWrongVersionSuccess() + public function testTranslateWrongVersion() { if (self::$authKey === false) { $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); } + $germanText = 'Hallo Welt'; + $deepl = new DeepL(self::$authKey, 3); - $deepl = new DeepL(self::$authKey, 3); - - $germanText = 'Hallo Welt'; - $expectedText = 'Hello World'; - - $translatedText = $deepl->translate($germanText); + $this->setExpectedException('\BabyMarkt\DeepL\DeepLException'); - $this->assertEquals($expectedText, $translatedText); + $deepl->translate($germanText); } /** @@ -293,7 +290,7 @@ public function testTranslateTagHandlingSuccess() $englishText, 'en', 'de', - array('xml') + 'xml' ); $this->assertEquals($expectedText, $translatedText); @@ -319,7 +316,7 @@ public function testTranslateIgnoreTagsSuccess() $englishText, 'en', 'de', - array('xml'), + 'xml', array('strong') ); @@ -333,11 +330,28 @@ public function testTranslateException() { $authKey = '123456'; $germanText = 'Hallo Welt'; - - $deepl = new DeepL($authKey); + $deepl = new DeepL($authKey); $this->setExpectedException('\BabyMarkt\DeepL\DeepLException'); $deepl->translate($germanText); } + + /** + * Test usage() has certain array-keys + * + * TEST REQUIRES VALID DEEPL AUTH KEY!! + */ + public function testUsage() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey); + $response = $deepl->usage(); + + $this->assertArrayHasKey('character_count', $response); + $this->assertArrayHasKey('character_limit', $response); + } } From 2296053871e7e85b7ada550400abed6ed9286cd4 Mon Sep 17 00:00:00 2001 From: vims Date: Tue, 11 Aug 2020 15:06:28 +0200 Subject: [PATCH 04/36] - fix typo --- src/DeepL.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index 9bd9d93..e6b311d 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -72,7 +72,7 @@ class DeepL /** * API URL: Parameter preserve_formatting */ - const API_URL_PRESERVER_FORMATING = 'preserve_formatting=%s'; + const API_URL_PRESERVE_FORMATTING = 'preserve_formatting=%s'; /** * API URL: Parameter non_splitting_tags @@ -327,7 +327,7 @@ protected function buildUrl( } if (false === empty($preserveFormatting)) { - $url .= '&'.sprintf(self::API_URL_PRESERVER_FORMATING, $preserveFormatting); + $url .= '&'.sprintf(self::API_URL_PRESERVE_FORMATTING, $preserveFormatting); } if (false === empty($nonSplittingTags)) { From 363bc293d2f0059009b22e171ee52aed6be6aff4 Mon Sep 17 00:00:00 2001 From: vims Date: Wed, 12 Aug 2020 10:16:56 +0200 Subject: [PATCH 05/36] composer.json: - revert to php 5.3 - Change Author - add ext curl und json to requirements - remove php-duplicate from require-dev DeepL.php - add API_URL_SCHEMA constant - rewrite base-url - remove API_URL_AUTH_KEY constant - fix some typos - fix codestyle - revert back to php 5.3 - add some comments - add missin parameters to buildUrl and translate functions --- composer.json | 11 +-- src/DeepL.php | 207 ++++++++++++++++++++++++++++++-------------------- 2 files changed, 132 insertions(+), 86 deletions(-) diff --git a/composer.json b/composer.json index c158501..9ff2b43 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "babymarkt/deepl-php-lib", "type": "library", - "description": "DeepL API Client Library supporting PHP >= 7.2 && PHP < 8.0", + "description": "DeepL API Client Library supporting PHP >= 5.3 && PHP < 8.0", "keywords": [ "babymarkt", "deepl", @@ -14,15 +14,16 @@ "license": "MIT", "authors": [ { - "name": "Arkadius Jonczek", - "email": "jonczek@babymarkt.de" + "name": "Entwicklungsteam babymarkt.de", + "email": "entwicklung@babymarkt.de" } ], "require": { - "php": ">=7.2 <8.0" + "php": ">=5.3 <8.0", + "ext-json": "*", + "ext-curl": "*" }, "require-dev": { - "php": ">=7.2 <8.0", "phpmd/phpmd": "2.4.*", "phpunit/phpunit": "^4.8", "squizlabs/php_codesniffer": "^2.9" diff --git a/src/DeepL.php b/src/DeepL.php index e6b311d..0165a67 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -9,10 +9,12 @@ */ class DeepL { + const API_URL_SCHEMA = 'https'; /** * API BASE URL + * https://api.deepl.com/v2/[resource]?auth_key=[yourAuthKey] */ - const API_URL_BASE = '%s://%s/v%s'; + const API_URL_BASE = '%s://%s/v%s/%s?auth_key=%s'; /** * API URL: translate @@ -29,10 +31,6 @@ class DeepL */ const API_URL_RESOURCE_LANGUAGES = 'languages'; - /** - * API URL: Parameter auth_key - */ - const API_URL_AUTH_KEY = 'auth_key=%s'; /** * API URL: Parameter text @@ -67,7 +65,7 @@ class DeepL /** * API URL: Parameter split_sentences */ - const API_URL_SPLIT_SENTENCES= 'split_sentences=%s'; + const API_URL_SPLIT_SENTENCES = 'split_sentences=%s'; /** * API URL: Parameter preserve_formatting @@ -77,12 +75,12 @@ class DeepL /** * API URL: Parameter non_splitting_tags */ - const API_URL_NON_SPLITTING_TAGS= 'non_splitting_tags=%s'; + const API_URL_NON_SPLITTING_TAGS = 'non_splitting_tags=%s'; /** * API URL: Parameter outline_detection */ - const API_URL_OUTLINE_DETECTION= 'outline_detection=%s'; + const API_URL_OUTLINE_DETECTION = 'outline_detection=%s'; /** * API URL: Parameter splitting_tags @@ -94,20 +92,20 @@ class DeepL * * @var array */ - protected $errorCodes = [ + protected $errorCodes = array( 400 => 'Wrong request, please check error message and your parameters.', 403 => 'Authorization failed. Please supply a valid auth_key parameter.', 413 => 'Request Entity Too Large. The request size exceeds the current limit.', 429 => 'Too many requests. Please wait and send your request once again.', 456 => 'Quota exceeded. The character limit has been reached.', - ]; + ); /** * Supported translation source languages * * @var array */ - protected $sourceLanguages = [ + protected $sourceLanguages = array( 'EN', 'DE', 'FR', @@ -119,14 +117,14 @@ class DeepL 'RU', 'JA', 'ZH', - ]; + ); /** * Supported translation destination languages * * @var array */ - protected $destinationLanguages = [ + protected $destinationLanguages = array( 'EN', 'DE', 'FR', @@ -140,9 +138,11 @@ class DeepL 'RU', 'JA', 'ZH', - ]; + ); /** + * DeepL API Version (v2 is default since 2018) + * * @var integer */ protected $apiVersion; @@ -161,11 +161,19 @@ class DeepL */ protected $curl; + /** + * Hostname of the API (in most cases api.deepl.com) + * + * @var string + */ + protected $host; + /** * DeepL constructor * * @param string $authKey * @param integer $apiVersion + * @param string $host */ public function __construct($authKey, $apiVersion = 2, $host = 'api.deepl.com') { @@ -193,49 +201,62 @@ public function __destruct() * @param string|string[] $text * @param string $sourceLanguage * @param string $destinationLanguage - * @param array $tagHandling - * @param array $ignoreTags + * @param string $tagHandling + * @param array|null $ignoreTags * @param string $formality + * @param string $resource + * @param null $splitSentences + * @param null $preserveFormatting + * @param array|null $nonSplittingTags + * @param null $outlineDetection + * @param array|null $splittingTags * - * @return string|string[] - * + * @return mixed * @throws DeepLException + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function translate( - string $text, - string $sourceLanguage = 'de', - string $destinationLanguage = 'en', - string $tagHandling = null, + $text, + $sourceLanguage = 'de', + $destinationLanguage = 'en', + $tagHandling = null, array $ignoreTags = null, - string $formality = "default", - string $resource = 'translate', - string $splitSentences = null, - bool $preserveFormatting = null, + $formality = "default", + $resource = self::API_URL_RESOURCE_TRANSLATE, + $splitSentences = null, + $preserveFormatting = null, array $nonSplittingTags = null, - bool $outlineDetection = null, + $outlineDetection = null, array $splittingTags = null ) { // make sure we only accept supported languages $this->checkLanguages($sourceLanguage, $destinationLanguage); // build the DeepL API request url - $url = $this->buildUrl( + $url = $this->buildUrl( $sourceLanguage, $destinationLanguage, $tagHandling, $ignoreTags, $formality, - self::API_URL_RESOURCE_TRANSLATE + $resource, + $splitSentences, + $preserveFormatting, + $nonSplittingTags, + $outlineDetection, + $splittingTags ); + $body = $this->buildBody($text); // request the DeepL API $translationsArray = $this->request($url, $body); $translationsCount = count($translationsArray['translations']); - if ($translationsCount == 0) { + if ($translationsCount === 0) { throw new DeepLException('No translations found.'); - } elseif ($translationsCount == 1) { + } elseif ($translationsCount === 1) { return $translationsArray['translations'][0]['text']; } @@ -252,7 +273,7 @@ public function translate( * * @throws DeepLException */ - protected function checkLanguages(string $sourceLanguage, string $destinationLanguage) + protected function checkLanguages($sourceLanguage, $destinationLanguage) { $sourceLanguage = strtoupper($sourceLanguage); @@ -284,23 +305,25 @@ protected function checkLanguages(string $sourceLanguage, string $destinationLan * @param string $resource * * @return string + * + * @SuppressWarnings(PHPMD.NPathComplexity) + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ protected function buildUrl( - string $sourceLanguage = null, - string $destinationLanguage = null, - string $tagHandling = null, + $sourceLanguage = null, + $destinationLanguage = null, + $tagHandling = null, array $ignoreTags = null, - string $formality = 'default', - string $resource = 'translate', - string $splitSentences = null, - bool $preserveFormatting = null, + $formality = 'default', + $resource = 'translate', + $splitSentences = null, + $preserveFormatting = null, array $nonSplittingTags = null, - bool $outlineDetection = null, + $outlineDetection = null, array $splittingTags = null ) { - $url = sprintf(self::API_URL_BASE, 'https', $this->host, $this->apiVersion); - $url .= sprintf('/%s', $resource); - $url .= '?'.sprintf(self::API_URL_AUTH_KEY, $this->authKey); + $url = $this->buildBaseUrl($resource); if (false === empty($sourceLanguage)) { $url .= '&'.sprintf(self::API_URL_SOURCE_LANG, strtolower($sourceLanguage)); @@ -345,6 +368,54 @@ protected function buildUrl( return $url; } + /** + * Creates the Base-Url which all of the 3 API-recourses have in common. + * + * @param string $resource + * + * @return string + */ + protected function buildBaseUrl($resource = 'translate') + { + $url = sprintf( + self::API_URL_BASE, + self::API_URL_SCHEMA, + $this->host, + $this->apiVersion, + $resource, + $this->authKey + ); + + return $url; + } + + /** + * Build the body for the DeepL API request + * + * @param string|string[] $text + * + * @return string + */ + protected function buildBody($text) + { + $body = ''; + $first = true; + + if (!is_array($text)) { + $text = (array)$text; + } + + foreach ($text as $textElement) { + $body .= ($first ? '' : '&').sprintf(self::API_URL_TEXT, rawurlencode($textElement)); + + if ($first) { + $first = false; + } + } + + return $body; + } + /** * Make a request to the given URL * @@ -359,7 +430,7 @@ protected function request($url, $body) curl_setopt($this->curl, CURLOPT_POST, true); curl_setopt($this->curl, CURLOPT_URL, $url); curl_setopt($this->curl, CURLOPT_POSTFIELDS, $body); - curl_setopt($this->curl, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']); + curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); $response = curl_exec($this->curl); @@ -383,58 +454,32 @@ protected function request($url, $body) } /** - * Build the body for the DeepL API request + * Calls the usage-Endpoint and return Json-response as an array * - * @param string|string[] $text - * - * @return string - */ - protected function buildBody($text) - { - $body = ''; - $first = true; - - if (!is_array($text)) { - $text = (array)$text; - } - - foreach ($text as $textElement) { - $body .= ($first ? '' : '&').sprintf(self::API_URL_TEXT, rawurlencode($textElement)); - - if ($first) { - $first = false; - } - } - - return $body; - } - - /** * @return array * @throws DeepLException */ public function usage() { - $result = []; - $body = ''; - $url = $this->buildUrl(null, null, null, null, '', self::API_URL_RESOURCE_USAGE); - $result = $this->request($url, $body); + $body = ''; + $url = $this->buildBaseUrl(self::API_URL_RESOURCE_USAGE); + $usage = $this->request($url, $body); - return $result; + return $usage; } - /** + * Call languages-Endpoint and return Json-response as an Array + * * @return array * @throws DeepLException */ public function languages() { - $result = []; - $body = ''; - $url = $this->buildUrl(null, null, [], [], '', self::API_URL_RESOURCE_LANGUAGES); - $result = $this->request($url, $body); + $body = ''; + $url = $this->buildBaseUrl(self::API_URL_RESOURCE_LANGUAGES); + $languages = $this->request($url, $body); - return $result; + return $languages; } } From 74948a904c294205c0b7879fb61ea6c6900e83d4 Mon Sep 17 00:00:00 2001 From: vims Date: Wed, 12 Aug 2020 10:47:55 +0200 Subject: [PATCH 06/36] - add Test for languages-function - add 2 Tests for buildBaseUrl --- tests/DeepLTest.php | 62 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/tests/DeepLTest.php b/tests/DeepLTest.php index 3e6d2ce..0f9608e 100644 --- a/tests/DeepLTest.php +++ b/tests/DeepLTest.php @@ -354,4 +354,66 @@ public function testUsage() $this->assertArrayHasKey('character_count', $response); $this->assertArrayHasKey('character_limit', $response); } + + /** + * Test languages() has certain array-keys + * + * TEST REQUIRES VALID DEEPL AUTH KEY!! + */ + public function testLanguages() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey); + $response = $deepl->languages(); + + foreach ($response as $language) { + $this->assertArrayHasKey('language', $language); + $this->assertArrayHasKey('name', $language); + } + + } + + /** + * Test buildBaseUrl() + */ + public function testbuildBaseUrl() + { + $authKey = '123456'; + + $expectedString = 'https://api.deepl.com/v2/translate?'. http_build_query(array( + 'auth_key' => $authKey + )); + + $deepl = new DeepL($authKey); + + $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildBaseUrl'); + + $return = $buildUrl->invokeArgs($deepl,array()); + + $this->assertEquals($expectedString, $return); + } + + /** + * Test buildBaseUrl() with own host + */ + public function testbuildBaseUrlHost() + { + $authKey = '123456'; + $host = 'myownhost.dev'; + + $expectedString = 'https://'.$host.'/v2/translate?'. http_build_query(array( + 'auth_key' => $authKey + )); + + $deepl = new DeepL($authKey, 2, $host); + + $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildBaseUrl'); + + $return = $buildUrl->invokeArgs($deepl,array()); + + $this->assertEquals($expectedString, $return); + } } From d68ee9da5f195674a6c246cb6e30355df0867672 Mon Sep 17 00:00:00 2001 From: vims Date: Wed, 12 Aug 2020 10:59:31 +0200 Subject: [PATCH 07/36] - fix Codestyle in Tests --- tests/DeepLTest.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/DeepLTest.php b/tests/DeepLTest.php index 0f9608e..1e488ab 100644 --- a/tests/DeepLTest.php +++ b/tests/DeepLTest.php @@ -373,7 +373,6 @@ public function testLanguages() $this->assertArrayHasKey('language', $language); $this->assertArrayHasKey('name', $language); } - } /** @@ -391,7 +390,7 @@ public function testbuildBaseUrl() $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildBaseUrl'); - $return = $buildUrl->invokeArgs($deepl,array()); + $return = $buildUrl->invokeArgs($deepl, array()); $this->assertEquals($expectedString, $return); } @@ -412,7 +411,7 @@ public function testbuildBaseUrlHost() $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildBaseUrl'); - $return = $buildUrl->invokeArgs($deepl,array()); + $return = $buildUrl->invokeArgs($deepl, array()); $this->assertEquals($expectedString, $return); } From 8f74d00ad3cc5136946afc470c97280b36637359 Mon Sep 17 00:00:00 2001 From: vims Date: Wed, 19 Aug 2020 09:23:32 +0200 Subject: [PATCH 08/36] - remove $errorCodes-Array and add Messages from DeepL-Response to DeepLException - fix conversion from array to url-param - change behaviour for $outlineDetection since DeepL-Api only needs it when it is disabled - fix some missing Doc-Blocks - Split Unit-(=local) and Integration(=api)-Tests - add some Testcases discovered while manual testing //I really want to refactor the Tests using Dataproviders! --- src/DeepL.php | 57 +++--- tests/integration/DeepLApiTest.php | 276 +++++++++++++++++++++++++++++ tests/{ => unit}/DeepLTest.php | 211 ++++------------------ 3 files changed, 334 insertions(+), 210 deletions(-) create mode 100644 tests/integration/DeepLApiTest.php rename tests/{ => unit}/DeepLTest.php (57%) diff --git a/src/DeepL.php b/src/DeepL.php index 0165a67..0f74664 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -31,7 +31,6 @@ class DeepL */ const API_URL_RESOURCE_LANGUAGES = 'languages'; - /** * API URL: Parameter text */ @@ -87,19 +86,6 @@ class DeepL */ const API_URL_SPLITTING_TAGS = 'splitting_tags=%s'; - /** - * DeepL HTTP error codes - * - * @var array - */ - protected $errorCodes = array( - 400 => 'Wrong request, please check error message and your parameters.', - 403 => 'Authorization failed. Please supply a valid auth_key parameter.', - 413 => 'Request Entity Too Large. The request size exceeds the current limit.', - 429 => 'Too many requests. Please wait and send your request once again.', - 456 => 'Quota exceeded. The character limit has been reached.', - ); - /** * Supported translation source languages * @@ -297,12 +283,17 @@ protected function checkLanguages($sourceLanguage, $destinationLanguage) /** * Build the URL for the DeepL API request * - * @param string $sourceLanguage - * @param string $destinationLanguage - * @param array $tagHandling - * @param array $ignoreTags - * @param string $formality - * @param string $resource + * @param string $sourceLanguage + * @param string $destinationLanguage + * @param string $tagHandling + * @param array|null $ignoreTags + * @param string $formality + * @param string $resource + * @param null $splitSentences + * @param null $preserveFormatting + * @param array|null $nonSplittingTags + * @param null $outlineDetection + * @param array|null $splittingTags * * @return string * @@ -316,11 +307,11 @@ protected function buildUrl( $tagHandling = null, array $ignoreTags = null, $formality = 'default', - $resource = 'translate', + $resource = self::API_URL_RESOURCE_TRANSLATE, $splitSentences = null, $preserveFormatting = null, array $nonSplittingTags = null, - $outlineDetection = null, + $outlineDetection = 1, array $splittingTags = null ) { $url = $this->buildBaseUrl($resource); @@ -338,7 +329,7 @@ protected function buildUrl( } if (false === empty($ignoreTags)) { - $url .= '&'.sprintf(self::API_URL_IGNORE_TAGS, implode(',', $ignoreTags)); + $url .= '&'.sprintf(self::API_URL_IGNORE_TAGS, urlencode(implode(',', $ignoreTags))); } if (false === empty($formality)) { @@ -354,15 +345,15 @@ protected function buildUrl( } if (false === empty($nonSplittingTags)) { - $url .= '&'.sprintf(self::API_URL_NON_SPLITTING_TAGS, implode(',', $nonSplittingTags)); + $url .= '&'.sprintf(self::API_URL_NON_SPLITTING_TAGS, urlencode(implode(',', $nonSplittingTags))); } - if (false === empty($outlineDetection)) { + if (0 === $outlineDetection) { $url .= '&'.sprintf(self::API_URL_OUTLINE_DETECTION, $outlineDetection); } if (false === empty($splittingTags)) { - $url .= '&'.sprintf(self::API_URL_SPLITTING_TAGS, implode(',', $splittingTags)); + $url .= '&'.sprintf(self::API_URL_SPLITTING_TAGS, urlencode(implode(',', $splittingTags))); } return $url; @@ -437,20 +428,18 @@ protected function request($url, $body) if (curl_errno($this->curl)) { throw new DeepLException('There was a cURL Request Error.'); } + $httpCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); + $responseArray = json_decode($response, true); - $httpCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); - - if ($httpCode != 200 && array_key_exists($httpCode, $this->errorCodes)) { - throw new DeepLException($this->errorCodes[$httpCode], $httpCode); + if ($httpCode != 200) { + throw new DeepLException($responseArray['message'], $httpCode); } - $translationsArray = json_decode($response, true); - - if (!$translationsArray) { + if (false === is_array($responseArray)) { throw new DeepLException('The Response seems to not be valid JSON.'); } - return $translationsArray; + return $responseArray; } /** diff --git a/tests/integration/DeepLApiTest.php b/tests/integration/DeepLApiTest.php new file mode 100644 index 0000000..f00593d --- /dev/null +++ b/tests/integration/DeepLApiTest.php @@ -0,0 +1,276 @@ +getMethod($methodName); + $method->setAccessible(true); + + return $method; + } + + /** + * Test translate() success with v2 API + */ + public function testTranslateSuccess() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey); + + $germanText = 'Hallo Welt'; + $expectedText = 'Hello World'; + + $translatedText = $deepl->translate($germanText); + + $this->assertEquals($expectedText, $translatedText); + } + + /** + * Test translate() success with v1 API + */ + public function testTranslateV1Success() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey, 1); + + $germanText = 'Hallo Welt'; + $expectedText = 'Hello World'; + + $translatedText = $deepl->translate($germanText); + + $this->assertEquals($expectedText, $translatedText); + } + + /** + * Test translate() success with default v2 API + */ + public function testTranslateWrongVersion() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + $germanText = 'Hallo Welt'; + $deepl = new DeepL(self::$authKey, 3); + + $this->setExpectedException('\BabyMarkt\DeepL\DeepLException'); + + $deepl->translate($germanText); + } + + /** + * Test translate() with tag handling success + */ + public function testTranslateTagHandlingSuccess() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey); + + $englishText = 'text to translate'; + $expectedText = 'zu übersetzender Text'; + + $translatedText = $deepl->translate( + $englishText, + 'en', + 'de', + 'xml' + ); + + $this->assertEquals($expectedText, $translatedText); + } + + /** + * Test translate() with tag ignored success + */ + public function testTranslateIgnoreTagsSuccess() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey); + + $englishText = 'text to do not translate

text to translate

'; + $expectedText = 'text to do not translate

zu übersetzender Text

'; + + $translatedText = $deepl->translate( + $englishText, + 'en', + 'de', + 'xml', + array('strong') + ); + + $this->assertEquals($expectedText, $translatedText); + } + + /** + * Test usage() has certain array-keys + */ + public function testUsage() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey); + $response = $deepl->usage(); + + $this->assertArrayHasKey('character_count', $response); + $this->assertArrayHasKey('character_limit', $response); + } + + /** + * Test languages() has certain array-keys + */ + public function testLanguages() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey); + $response = $deepl->languages(); + + foreach ($response as $language) { + $this->assertArrayHasKey('language', $language); + $this->assertArrayHasKey('name', $language); + } + } + + /** + * Test translate() with all Params + */ + public function testTranslateWithAllParams() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey); + + $englishText = 'text to do not translate

please translate this text

'; + $expectedText = 'text to do not translate

bitte übersetzen Sie diesen Text

'; + + $translatedText = $deepl->translate( + $englishText, + 'en', //$sourceLanguage + 'de', //$destinationLanguage + 'xml', //$tagHandling + array('html','html5','html6'), //$ignoreTags + 'more', //$formality + 'translate', //$resource + 'nonewlines', //$splitSentences + 1, //$preserveFormatting + array('href','href2'), //$nonSplittingTags + 0, //$outlineDetection + array('p','br') //$splittingTags + ); + + $this->assertEquals($expectedText, $translatedText); + } + + /** + * Test translate() $formality + */ + public function testTranslateFormality() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey); + + $englishText = 'text to do not translate

please translate this text

'; + $expectedText = 'nicht zu übersetzender Text

bitte diesen Text übersetzen

'; + $translatedText = $deepl->translate( + $englishText, + 'en', //$sourceLanguage + 'de', //$destinationLanguage + null, //$tagHandling + null, //$ignoreTags + 'less' //$formality + ); + + $this->assertEquals($expectedText, $translatedText); + } + + /** + * Test translate() $formality + */ + public function testTranslateFormalityFail() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey); + $englishText = 'text to do not translate

please translate this text

'; + + $this->setExpectedException('\BabyMarkt\DeepL\DeepLException'); + + $deepl->translate( + $englishText, + 'en', //$sourceLanguage + 'es', //$destinationLanguage + null, //$tagHandling + null, //$ignoreTags + 'more' //$formality + ); + } +} diff --git a/tests/DeepLTest.php b/tests/unit/DeepLTest.php similarity index 57% rename from tests/DeepLTest.php rename to tests/unit/DeepLTest.php index 1e488ab..cd1b9dc 100644 --- a/tests/DeepLTest.php +++ b/tests/unit/DeepLTest.php @@ -1,7 +1,9 @@ assertEquals($expectedString, $return); } - /** - * Test translate() success with v2 API - * - * TEST REQUIRES VALID DEEPL AUTH KEY!! - */ - public function testTranslateSuccess() - { - if (self::$authKey === false) { - $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); - } - - $deepl = new DeepL(self::$authKey); - - $germanText = 'Hallo Welt'; - $expectedText = 'Hello World'; - - $translatedText = $deepl->translate($germanText); - - $this->assertEquals($expectedText, $translatedText); - } - - /** - * Test translate() success with v1 API - * - * TEST REQUIRES VALID DEEPL AUTH KEY!! - */ - public function testTranslateV1Success() - { - if (self::$authKey === false) { - $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); - } - - $deepl = new DeepL(self::$authKey, 1); - - $germanText = 'Hallo Welt'; - $expectedText = 'Hello World'; - - $translatedText = $deepl->translate($germanText); - - $this->assertEquals($expectedText, $translatedText); - } - - /** - * Test translate() success with default v2 API - * - * TEST REQUIRES VALID DEEPL AUTH KEY!! - */ - public function testTranslateWrongVersion() - { - if (self::$authKey === false) { - $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); - } - $germanText = 'Hallo Welt'; - $deepl = new DeepL(self::$authKey, 3); - - $this->setExpectedException('\BabyMarkt\DeepL\DeepLException'); - - $deepl->translate($germanText); - } - - /** - * Test translate() with tag handling success - * - * TEST REQUIRES VALID DEEPL AUTH KEY!! - */ - public function testTranslateTagHandlingSuccess() - { - if (self::$authKey === false) { - $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); - } - - $deepl = new DeepL(self::$authKey); - - $englishText = 'text to translate'; - $expectedText = 'zu übersetzender Text'; - - $translatedText = $deepl->translate( - $englishText, - 'en', - 'de', - 'xml' - ); - - $this->assertEquals($expectedText, $translatedText); - } - - /** - * Test translate() with tag ignored success - * - * TEST REQUIRES VALID DEEPL AUTH KEY!! - */ - public function testTranslateIgnoreTagsSuccess() - { - if (self::$authKey === false) { - $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); - } - - $deepl = new DeepL(self::$authKey); - - $englishText = 'text to do not translate

text to translate

'; - $expectedText = 'text to do not translate

zu übersetzender Text

'; - - $translatedText = $deepl->translate( - $englishText, - 'en', - 'de', - 'xml', - array('strong') - ); - - $this->assertEquals($expectedText, $translatedText); - } - /** * Test translate() */ @@ -337,44 +203,6 @@ public function testTranslateException() $deepl->translate($germanText); } - /** - * Test usage() has certain array-keys - * - * TEST REQUIRES VALID DEEPL AUTH KEY!! - */ - public function testUsage() - { - if (self::$authKey === false) { - $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); - } - - $deepl = new DeepL(self::$authKey); - $response = $deepl->usage(); - - $this->assertArrayHasKey('character_count', $response); - $this->assertArrayHasKey('character_limit', $response); - } - - /** - * Test languages() has certain array-keys - * - * TEST REQUIRES VALID DEEPL AUTH KEY!! - */ - public function testLanguages() - { - if (self::$authKey === false) { - $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); - } - - $deepl = new DeepL(self::$authKey); - $response = $deepl->languages(); - - foreach ($response as $language) { - $this->assertArrayHasKey('language', $language); - $this->assertArrayHasKey('name', $language); - } - } - /** * Test buildBaseUrl() */ @@ -415,4 +243,35 @@ public function testbuildBaseUrlHost() $this->assertEquals($expectedString, $return); } + + + public function testBuildUrlWithAllParams() + { + $authKey = '123456'; + // created with DeepL Simulator: https://www.deepl.com/docs-api/simulator/ + $expectedString = 'https://api.deepl.com/v2/translate?auth_key='.$authKey; + $expectedString .= '&source_lang=en&target_lang=de&tag_handling=xml&ignore_tags=html%2Chtml5%2Chtml6'; + $expectedString .= '&formality=more&split_sentences=nonewlines&preserve_formatting=1'; + $expectedString .= '&non_splitting_tags=href%2Chref2&outline_detection=0&splitting_tags=p%2Cbr'; + + $deepl = new DeepL($authKey); + $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildUrl'); + $args = array( + 'en', //$sourceLanguage + 'de', //$destinationLanguage + 'xml', //$tagHandling + array('html','html5','html6'), //$ignoreTags + 'more', //$formality + 'translate', //$resource + 'nonewlines', //$splitSentences + 1, //$preserveFormatting + array('href','href2'), //$nonSplittingTags + 0, //$outlineDetection + array('p','br') //$splittingTags + ); + + $return = $buildUrl->invokeArgs($deepl, $args); + + $this->assertEquals($expectedString, $return); + } } From 7190c9569dcf5e2e35b6dab713444e11d6318ec3 Mon Sep 17 00:00:00 2001 From: vims Date: Wed, 19 Aug 2020 10:01:11 +0200 Subject: [PATCH 09/36] - check for array and key --- src/DeepL.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index 0f74664..16bc252 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -431,12 +431,12 @@ protected function request($url, $body) $httpCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); $responseArray = json_decode($response, true); - if ($httpCode != 200) { + if ($httpCode != 200 && is_array($responseArray) && array_key_exists('message', $responseArray)) { throw new DeepLException($responseArray['message'], $httpCode); } if (false === is_array($responseArray)) { - throw new DeepLException('The Response seems to not be valid JSON.'); + throw new DeepLException('The Response seems to not be valid JSON.', $httpCode); } return $responseArray; From 70729a57b7e7359312f886ff73ecef9f029874f6 Mon Sep 17 00:00:00 2001 From: vims Date: Mon, 24 Aug 2020 16:08:07 +0200 Subject: [PATCH 10/36] - remove buildUrl - remove buildBody - write params to post-body with http_build_query instead - remove Tests --- src/DeepL.php | 138 +++++-------------------------------- tests/unit/DeepLTest.php | 142 --------------------------------------- 2 files changed, 18 insertions(+), 262 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index 16bc252..c8b7555 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -219,22 +219,25 @@ public function translate( // make sure we only accept supported languages $this->checkLanguages($sourceLanguage, $destinationLanguage); - // build the DeepL API request url - $url = $this->buildUrl( - $sourceLanguage, - $destinationLanguage, - $tagHandling, - $ignoreTags, - $formality, - $resource, - $splitSentences, - $preserveFormatting, - $nonSplittingTags, - $outlineDetection, - $splittingTags + $url = $this->buildBaseUrl($resource); + $splittingTags = (true === is_array($splittingTags)) ? implode(',', $splittingTags) : null; + $nonSplittingTags = (true === is_array($nonSplittingTags)) ? implode(',', $nonSplittingTags) : null; + $ignoreTags = (true === is_array($ignoreTags)) ? implode(',', $ignoreTags) : null; + $paramsArray = array( + 'text' => $text, + 'source_lang' => $sourceLanguage, + 'target_lang' => $destinationLanguage, + 'ignore_tags' => $ignoreTags, + 'tag_handling' => $tagHandling, + 'formality' => $formality, + 'split_sentences' => $splitSentences, + 'preserve_formatting' => $preserveFormatting, + 'non_splitting_tags' => $nonSplittingTags, + 'outline_detection' => $outlineDetection, + 'splitting_tags' => $splittingTags ); - $body = $this->buildBody($text); + $body = http_build_query($paramsArray, null, '&', PHP_QUERY_RFC3986); // request the DeepL API $translationsArray = $this->request($url, $body); @@ -280,86 +283,7 @@ protected function checkLanguages($sourceLanguage, $destinationLanguage) return true; } - /** - * Build the URL for the DeepL API request - * - * @param string $sourceLanguage - * @param string $destinationLanguage - * @param string $tagHandling - * @param array|null $ignoreTags - * @param string $formality - * @param string $resource - * @param null $splitSentences - * @param null $preserveFormatting - * @param array|null $nonSplittingTags - * @param null $outlineDetection - * @param array|null $splittingTags - * - * @return string - * - * @SuppressWarnings(PHPMD.NPathComplexity) - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.ExcessiveParameterList) - */ - protected function buildUrl( - $sourceLanguage = null, - $destinationLanguage = null, - $tagHandling = null, - array $ignoreTags = null, - $formality = 'default', - $resource = self::API_URL_RESOURCE_TRANSLATE, - $splitSentences = null, - $preserveFormatting = null, - array $nonSplittingTags = null, - $outlineDetection = 1, - array $splittingTags = null - ) { - $url = $this->buildBaseUrl($resource); - - if (false === empty($sourceLanguage)) { - $url .= '&'.sprintf(self::API_URL_SOURCE_LANG, strtolower($sourceLanguage)); - } - - if (false === empty($destinationLanguage)) { - $url .= '&'.sprintf(self::API_URL_DESTINATION_LANG, strtolower($destinationLanguage)); - } - - if (false === empty($tagHandling)) { - $url .= '&'.sprintf(self::API_URL_TAG_HANDLING, $tagHandling); - } - - if (false === empty($ignoreTags)) { - $url .= '&'.sprintf(self::API_URL_IGNORE_TAGS, urlencode(implode(',', $ignoreTags))); - } - - if (false === empty($formality)) { - $url .= '&'.sprintf(self::API_URL_FORMALITY, $formality); - } - - if (false === empty($splitSentences)) { - $url .= '&'.sprintf(self::API_URL_SPLIT_SENTENCES, $splitSentences); - } - - if (false === empty($preserveFormatting)) { - $url .= '&'.sprintf(self::API_URL_PRESERVE_FORMATTING, $preserveFormatting); - } - - if (false === empty($nonSplittingTags)) { - $url .= '&'.sprintf(self::API_URL_NON_SPLITTING_TAGS, urlencode(implode(',', $nonSplittingTags))); - } - - if (0 === $outlineDetection) { - $url .= '&'.sprintf(self::API_URL_OUTLINE_DETECTION, $outlineDetection); - } - - if (false === empty($splittingTags)) { - $url .= '&'.sprintf(self::API_URL_SPLITTING_TAGS, urlencode(implode(',', $splittingTags))); - } - - return $url; - } - - /** + /** * Creates the Base-Url which all of the 3 API-recourses have in common. * * @param string $resource @@ -380,32 +304,6 @@ protected function buildBaseUrl($resource = 'translate') return $url; } - /** - * Build the body for the DeepL API request - * - * @param string|string[] $text - * - * @return string - */ - protected function buildBody($text) - { - $body = ''; - $first = true; - - if (!is_array($text)) { - $text = (array)$text; - } - - foreach ($text as $textElement) { - $body .= ($first ? '' : '&').sprintf(self::API_URL_TEXT, rawurlencode($textElement)); - - if ($first) { - $first = false; - } - } - - return $body; - } /** * Make a request to the given URL diff --git a/tests/unit/DeepLTest.php b/tests/unit/DeepLTest.php index cd1b9dc..58d425b 100644 --- a/tests/unit/DeepLTest.php +++ b/tests/unit/DeepLTest.php @@ -78,117 +78,6 @@ public function testCheckLanguagesDestinationLanguageException() $checkLanguages->invokeArgs($deepl, array('de', 'fo')); } - /** - * Test buildUrl() - */ - public function testBuildUrl() - { - $authKey = '123456'; - - $expectedString = 'https://api.deepl.com/v2/translate?' . http_build_query(array( - 'auth_key' => $authKey, - 'source_lang' => 'de', - 'target_lang' => 'en', - 'formality' => 'default' - )); - - $deepl = new DeepL($authKey); - - $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildUrl'); - - $return = $buildUrl->invokeArgs($deepl, array('de', 'en')); - - $this->assertEquals($expectedString, $return); - } - - /** - * Test buildUrl() - */ - public function testBuildUrlV1() - { - $authKey = '123456'; - - $expectedString = 'https://api.deepl.com/v1/translate?' . http_build_query(array( - 'auth_key' => $authKey, - 'source_lang' => 'de', - 'target_lang' => 'en', - 'formality' => 'default' - )); - - $deepl = new DeepL($authKey, 1); - - $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildUrl'); - - $return = $buildUrl->invokeArgs($deepl, array('de', 'en')); - - $this->assertEquals($expectedString, $return); - } - - /** - * Test buildUrl() - */ - public function testBuildUrlWithTags() - { - $authKey = '123456'; - $expectedString = 'https://api.deepl.com/v2/translate?' . http_build_query(array( - 'auth_key' => $authKey, - 'source_lang' => 'de', - 'target_lang' => 'en', - 'tag_handling' => 'xml', - 'ignore_tags' => 'x', - 'formality' => 'default' - )); - - $deepl = new DeepL($authKey); - - $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildUrl'); - - $return = $buildUrl->invokeArgs($deepl, array('de', 'en', 'xml', array('x'))); - - $this->assertEquals($expectedString, $return); - } - - /** - * Test buildUrl() - */ - public function testBuildUrlWithTagsV1() - { - $authKey = '123456'; - $expectedString = 'https://api.deepl.com/v1/translate?' . http_build_query(array( - 'auth_key' => $authKey, - 'source_lang' => 'de', - 'target_lang' => 'en', - 'tag_handling' => 'xml', - 'ignore_tags' => 'x', - 'formality' => 'default' - )); - - $deepl = new DeepL($authKey, 1); - - $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildUrl'); - - $return = $buildUrl->invokeArgs($deepl, array('de', 'en', 'xml', array('x'))); - - $this->assertEquals($expectedString, $return); - } - - /** - * Test buildBody() - */ - public function testBuildBody() - { - $expectedString = 'text=Hallo%20Welt'; - - $authKey = '123456'; - $deepl = new DeepL($authKey); - - $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildBody'); - - $return = $buildUrl->invokeArgs($deepl, array('Hallo Welt')); - - $this->assertEquals($expectedString, $return); - } - /** * Test translate() */ @@ -243,35 +132,4 @@ public function testbuildBaseUrlHost() $this->assertEquals($expectedString, $return); } - - - public function testBuildUrlWithAllParams() - { - $authKey = '123456'; - // created with DeepL Simulator: https://www.deepl.com/docs-api/simulator/ - $expectedString = 'https://api.deepl.com/v2/translate?auth_key='.$authKey; - $expectedString .= '&source_lang=en&target_lang=de&tag_handling=xml&ignore_tags=html%2Chtml5%2Chtml6'; - $expectedString .= '&formality=more&split_sentences=nonewlines&preserve_formatting=1'; - $expectedString .= '&non_splitting_tags=href%2Chref2&outline_detection=0&splitting_tags=p%2Cbr'; - - $deepl = new DeepL($authKey); - $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildUrl'); - $args = array( - 'en', //$sourceLanguage - 'de', //$destinationLanguage - 'xml', //$tagHandling - array('html','html5','html6'), //$ignoreTags - 'more', //$formality - 'translate', //$resource - 'nonewlines', //$splitSentences - 1, //$preserveFormatting - array('href','href2'), //$nonSplittingTags - 0, //$outlineDetection - array('p','br') //$splittingTags - ); - - $return = $buildUrl->invokeArgs($deepl, $args); - - $this->assertEquals($expectedString, $return); - } } From f6db89c7027865811ceed3abfbc13664a933f1d9 Mon Sep 17 00:00:00 2001 From: vims Date: Mon, 24 Aug 2020 16:10:55 +0200 Subject: [PATCH 11/36] - remove unnecessary constants --- src/DeepL.php | 55 --------------------------------------------------- 1 file changed, 55 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index c8b7555..a1dde3f 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -31,61 +31,6 @@ class DeepL */ const API_URL_RESOURCE_LANGUAGES = 'languages'; - /** - * API URL: Parameter text - */ - const API_URL_TEXT = 'text=%s'; - - /** - * API URL: Parameter source_lang - */ - const API_URL_SOURCE_LANG = 'source_lang=%s'; - - /** - * API URL: Parameter target_lang - */ - const API_URL_DESTINATION_LANG = 'target_lang=%s'; - - /** - * API URL: Parameter tag_handling - */ - const API_URL_TAG_HANDLING = 'tag_handling=%s'; - - /** - * API URL: Parameter ignore_tags - */ - const API_URL_IGNORE_TAGS = 'ignore_tags=%s'; - - /** - * API URL: Parameter formality - */ - const API_URL_FORMALITY = 'formality=%s'; - - /** - * API URL: Parameter split_sentences - */ - const API_URL_SPLIT_SENTENCES = 'split_sentences=%s'; - - /** - * API URL: Parameter preserve_formatting - */ - const API_URL_PRESERVE_FORMATTING = 'preserve_formatting=%s'; - - /** - * API URL: Parameter non_splitting_tags - */ - const API_URL_NON_SPLITTING_TAGS = 'non_splitting_tags=%s'; - - /** - * API URL: Parameter outline_detection - */ - const API_URL_OUTLINE_DETECTION = 'outline_detection=%s'; - - /** - * API URL: Parameter splitting_tags - */ - const API_URL_SPLITTING_TAGS = 'splitting_tags=%s'; - /** * Supported translation source languages * From b20b126f829458bd772567cd2d6ec49409781ef0 Mon Sep 17 00:00:00 2001 From: vims Date: Tue, 25 Aug 2020 10:20:30 +0200 Subject: [PATCH 12/36] - extract buildQuery from translate --- src/DeepL.php | 84 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 19 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index a1dde3f..667b4b2 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -153,7 +153,7 @@ public function translate( $destinationLanguage = 'en', $tagHandling = null, array $ignoreTags = null, - $formality = "default", + $formality = 'default', $resource = self::API_URL_RESOURCE_TRANSLATE, $splitSentences = null, $preserveFormatting = null, @@ -165,25 +165,20 @@ public function translate( $this->checkLanguages($sourceLanguage, $destinationLanguage); $url = $this->buildBaseUrl($resource); - $splittingTags = (true === is_array($splittingTags)) ? implode(',', $splittingTags) : null; - $nonSplittingTags = (true === is_array($nonSplittingTags)) ? implode(',', $nonSplittingTags) : null; - $ignoreTags = (true === is_array($ignoreTags)) ? implode(',', $ignoreTags) : null; - $paramsArray = array( - 'text' => $text, - 'source_lang' => $sourceLanguage, - 'target_lang' => $destinationLanguage, - 'ignore_tags' => $ignoreTags, - 'tag_handling' => $tagHandling, - 'formality' => $formality, - 'split_sentences' => $splitSentences, - 'preserve_formatting' => $preserveFormatting, - 'non_splitting_tags' => $nonSplittingTags, - 'outline_detection' => $outlineDetection, - 'splitting_tags' => $splittingTags + $body = $this->buildQuery( + $splittingTags, + $nonSplittingTags, + $ignoreTags, + $text, + $sourceLanguage, + $destinationLanguage, + $tagHandling, + $formality, + $splitSentences, + $preserveFormatting, + $outlineDetection ); - $body = http_build_query($paramsArray, null, '&', PHP_QUERY_RFC3986); - // request the DeepL API $translationsArray = $this->request($url, $body); $translationsCount = count($translationsArray['translations']); @@ -229,7 +224,7 @@ protected function checkLanguages($sourceLanguage, $destinationLanguage) } /** - * Creates the Base-Url which all of the 3 API-recourses have in common. + * Creates the Base-Url which all of the 3 API-resources have in common. * * @param string $resource * @@ -314,4 +309,55 @@ public function languages() return $languages; } + + /** + * @param $splittingTags + * @param $nonSplittingTags + * @param $ignoreTags + * @param $text + * @param $sourceLanguage + * @param $destinationLanguage + * @param $tagHandling + * @param $formality + * @param $splitSentences + * @param $preserveFormatting + * @param $outlineDetection + * + * @return string + * @SuppressWarnings(PHPMD.ExcessiveParameterList) + */ + protected function buildQuery( + $splittingTags, + $nonSplittingTags, + $ignoreTags, + $text, + $sourceLanguage, + $destinationLanguage, + $tagHandling, + $formality, + $splitSentences, + $preserveFormatting, + $outlineDetection + ) { + $splittingTags = (true === is_array($splittingTags)) ? implode(',', $splittingTags) : null; + $nonSplittingTags = (true === is_array($nonSplittingTags)) ? implode(',', $nonSplittingTags) : null; + $ignoreTags = (true === is_array($ignoreTags)) ? implode(',', $ignoreTags) : null; + $paramsArray = array( + 'text' => $text, + 'source_lang' => $sourceLanguage, + 'target_lang' => $destinationLanguage, + 'ignore_tags' => $ignoreTags, + 'tag_handling' => $tagHandling, + 'formality' => $formality, + 'split_sentences' => $splitSentences, + 'preserve_formatting' => $preserveFormatting, + 'non_splitting_tags' => $nonSplittingTags, + 'outline_detection' => $outlineDetection, + 'splitting_tags' => $splittingTags + ); + + $body = http_build_query($paramsArray, null, '&', PHP_QUERY_RFC3986); + + return $body; + } } From 301922bcd30d8f54581258ef4734eb86e5112109 Mon Sep 17 00:00:00 2001 From: vims Date: Tue, 25 Aug 2020 14:07:49 +0200 Subject: [PATCH 13/36] - code cleanup - fix Bugs discovered while writing Tests - add Testcases for testBuildQuery --- src/DeepL.php | 41 +++++++++------- tests/unit/DeepLTest.php | 103 +++++++++++++++++++++++++++++++-------- 2 files changed, 106 insertions(+), 38 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index 667b4b2..3153217 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -161,17 +161,21 @@ public function translate( $outlineDetection = null, array $splittingTags = null ) { + if (false === isset($text)) { + throw new DeepLException('Text is a required Argument'); + } + // make sure we only accept supported languages $this->checkLanguages($sourceLanguage, $destinationLanguage); - $url = $this->buildBaseUrl($resource); - $body = $this->buildQuery( + $url = $this->buildBaseUrl($resource); + $body = $this->buildQuery( + $text, + $destinationLanguage, + $sourceLanguage, $splittingTags, $nonSplittingTags, $ignoreTags, - $text, - $sourceLanguage, - $destinationLanguage, $tagHandling, $formality, $splitSentences, @@ -311,12 +315,12 @@ public function languages() } /** + * @param $text + * @param $destinationLanguage + * @param $sourceLanguage * @param $splittingTags * @param $nonSplittingTags * @param $ignoreTags - * @param $text - * @param $sourceLanguage - * @param $destinationLanguage * @param $tagHandling * @param $formality * @param $splitSentences @@ -327,12 +331,12 @@ public function languages() * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ protected function buildQuery( + $text, + $destinationLanguage, + $sourceLanguage, $splittingTags, $nonSplittingTags, $ignoreTags, - $text, - $sourceLanguage, - $destinationLanguage, $tagHandling, $formality, $splitSentences, @@ -342,18 +346,19 @@ protected function buildQuery( $splittingTags = (true === is_array($splittingTags)) ? implode(',', $splittingTags) : null; $nonSplittingTags = (true === is_array($nonSplittingTags)) ? implode(',', $nonSplittingTags) : null; $ignoreTags = (true === is_array($ignoreTags)) ? implode(',', $ignoreTags) : null; + $outlineDetection = ('0' != $outlineDetection) ? null : '0'; $paramsArray = array( 'text' => $text, 'source_lang' => $sourceLanguage, 'target_lang' => $destinationLanguage, - 'ignore_tags' => $ignoreTags, - 'tag_handling' => $tagHandling, - 'formality' => $formality, - 'split_sentences' => $splitSentences, - 'preserve_formatting' => $preserveFormatting, - 'non_splitting_tags' => $nonSplittingTags, + 'splitting_tags' => $splittingTags ?: null, + 'non_splitting_tags' => $nonSplittingTags ?: null, + 'ignore_tags' => $ignoreTags ?: null, + 'tag_handling' => $tagHandling ?: null, + 'formality' => $formality ?: null, + 'split_sentences' => $splitSentences ?: null, + 'preserve_formatting' => $preserveFormatting ?: null, 'outline_detection' => $outlineDetection, - 'splitting_tags' => $splittingTags ); $body = http_build_query($paramsArray, null, '&', PHP_QUERY_RFC3986); diff --git a/tests/unit/DeepLTest.php b/tests/unit/DeepLTest.php index 58d425b..ea38921 100644 --- a/tests/unit/DeepLTest.php +++ b/tests/unit/DeepLTest.php @@ -95,40 +95,103 @@ public function testTranslateException() /** * Test buildBaseUrl() */ - public function testbuildBaseUrl() + public function testBuildBaseUrl() { - $authKey = '123456'; - - $expectedString = 'https://api.deepl.com/v2/translate?'. http_build_query(array( - 'auth_key' => $authKey - )); + $authKey = '123456'; + $expectedUrl = 'https://api.deepl.com/v2/translate?auth_key='.$authKey; + $deepl = new DeepL($authKey); + $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildBaseUrl'); + $return = $buildUrl->invokeArgs($deepl, array()); - $deepl = new DeepL($authKey); - - $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildBaseUrl'); + $this->assertEquals($expectedUrl, $return); + } - $return = $buildUrl->invokeArgs($deepl, array()); + /** + * Test buildBaseUrl() with own host + */ + public function testBuildBaseUrlHost() + { + $authKey = '123456'; + $host = 'myownhost.dev'; + $expectedString = 'https://'.$host.'/v2/translate?auth_key='.$authKey; + $deepl = new DeepL($authKey, 2, $host); + $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildBaseUrl'); + $return = $buildUrl->invokeArgs($deepl, array()); $this->assertEquals($expectedString, $return); } /** - * Test buildBaseUrl() with own host + * Test buildQuery with empty Arguemtns */ - public function testbuildBaseUrlHost() + public function testBuildQueryWithNulledArguments() { - $authKey = '123456'; - $host = 'myownhost.dev'; + $authKey = '123456'; + $args = array(null,null,null,null,null,null,null,null,null,null,null); + $expectedString = ''; + $deepl = new DeepL($authKey); + $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); + $return = $buildQuery->invokeArgs($deepl, $args); - $expectedString = 'https://'.$host.'/v2/translate?'. http_build_query(array( - 'auth_key' => $authKey - )); + $this->assertEquals($expectedString, $return); + } - $deepl = new DeepL($authKey, 2, $host); + public function testBuildQueryWithMinimalArguments() + { + $authKey = '123456'; + $args = array('text','en','de',null,null,null,null,null,null,null,null); + $expectedString = 'text=text&source_lang=de&target_lang=en'; + $deepl = new DeepL($authKey); + $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); + $return = $buildQuery->invokeArgs($deepl, $args); - $buildUrl = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildBaseUrl'); + $this->assertEquals($expectedString, $return); + } - $return = $buildUrl->invokeArgs($deepl, array()); + public function testBuildQueryWithEmptyArguments() + { + $authKey = '123456'; + $args = array('text','en','de',array(),array(),array(),'','','','',''); + $expectedString = 'text=text&source_lang=de&target_lang=en'; + $deepl = new DeepL($authKey); + $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); + $return = $buildQuery->invokeArgs($deepl, $args); + + $this->assertEquals($expectedString, $return); + } + + public function testBuildQueryWithAllArguments() + { + $authKey = '123456'; + $args = array('text','en','de',array('p','h1'),array('br','strong'),array('href','i'),'xml','default','nonewlines',1,0); + $expectedString = 'text=text&source_lang=de&target_lang=en&splitting_tags=p%2Ch1&non_splitting_tags=br%2Cstrong&ignore_tags=href%2Ci&tag_handling=xml&formality=default&split_sentences=nonewlines&preserve_formatting=1&outline_detection=0'; + $deepl = new DeepL($authKey); + $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); + $return = $buildQuery->invokeArgs($deepl, $args); + + $this->assertEquals($expectedString, $return); + } + + public function testBuildQueryWithAllArgumentsAndPreserveFormattingZero() + { + $authKey = '123456'; + $args = array('text','en','de',array('p','h1'),array('br','strong'),array('href','i'),'xml','default','nonewlines',0,0); + $expectedString = 'text=text&source_lang=de&target_lang=en&splitting_tags=p%2Ch1&non_splitting_tags=br%2Cstrong&ignore_tags=href%2Ci&tag_handling=xml&formality=default&split_sentences=nonewlines&outline_detection=0'; + $deepl = new DeepL($authKey); + $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); + $return = $buildQuery->invokeArgs($deepl, $args); + + $this->assertEquals($expectedString, $return); + } + + public function testBuildQueryWithAllArgumentsAndOutlineDetectionOne() + { + $authKey = '123456'; + $args = array('text','en','de',array('p','h1'),array('br','strong'),array('href','i'),'xml','default','nonewlines',0,1); + $expectedString = 'text=text&source_lang=de&target_lang=en&splitting_tags=p%2Ch1&non_splitting_tags=br%2Cstrong&ignore_tags=href%2Ci&tag_handling=xml&formality=default&split_sentences=nonewlines'; + $deepl = new DeepL($authKey); + $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); + $return = $buildQuery->invokeArgs($deepl, $args); $this->assertEquals($expectedString, $return); } From 62bcdf4ee0be007fe9ae64db2d60ce9b4ec493e4 Mon Sep 17 00:00:00 2001 From: vims Date: Tue, 25 Aug 2020 15:37:24 +0200 Subject: [PATCH 14/36] - add Testcase for multiple Texts as Array - code cleanup - readd functionality for text as array - try to reduce CyclomaticComplexity and NPathComplexity --- src/DeepL.php | 178 +++++++++++++++++++++------------------ tests/unit/DeepLTest.php | 128 ++++++++++++++++++++++++++-- 2 files changed, 215 insertions(+), 91 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index 3153217..c4b81bc 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -126,6 +126,36 @@ public function __destruct() } } + /** + * Calls the usage-Endpoint and return Json-response as an array + * + * @return array + * @throws DeepLException + */ + public function usage() + { + $body = ''; + $url = $this->buildBaseUrl(self::API_URL_RESOURCE_USAGE); + $usage = $this->request($url, $body); + + return $usage; + } + + /** + * Call languages-Endpoint and return Json-response as an Array + * + * @return array + * @throws DeepLException + */ + public function languages() + { + $body = ''; + $url = $this->buildBaseUrl(self::API_URL_RESOURCE_LANGUAGES); + $languages = $this->request($url, $body); + + return $languages; + } + /** * Translate the text string or array from source to destination language * @@ -161,10 +191,6 @@ public function translate( $outlineDetection = null, array $splittingTags = null ) { - if (false === isset($text)) { - throw new DeepLException('Text is a required Argument'); - } - // make sure we only accept supported languages $this->checkLanguages($sourceLanguage, $destinationLanguage); @@ -248,72 +274,6 @@ protected function buildBaseUrl($resource = 'translate') return $url; } - - /** - * Make a request to the given URL - * - * @param string $url - * - * @return array - * - * @throws DeepLException - */ - protected function request($url, $body) - { - curl_setopt($this->curl, CURLOPT_POST, true); - curl_setopt($this->curl, CURLOPT_URL, $url); - curl_setopt($this->curl, CURLOPT_POSTFIELDS, $body); - curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); - - $response = curl_exec($this->curl); - - if (curl_errno($this->curl)) { - throw new DeepLException('There was a cURL Request Error.'); - } - $httpCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); - $responseArray = json_decode($response, true); - - if ($httpCode != 200 && is_array($responseArray) && array_key_exists('message', $responseArray)) { - throw new DeepLException($responseArray['message'], $httpCode); - } - - if (false === is_array($responseArray)) { - throw new DeepLException('The Response seems to not be valid JSON.', $httpCode); - } - - return $responseArray; - } - - /** - * Calls the usage-Endpoint and return Json-response as an array - * - * @return array - * @throws DeepLException - */ - public function usage() - { - $body = ''; - $url = $this->buildBaseUrl(self::API_URL_RESOURCE_USAGE); - $usage = $this->request($url, $body); - - return $usage; - } - - /** - * Call languages-Endpoint and return Json-response as an Array - * - * @return array - * @throws DeepLException - */ - public function languages() - { - $body = ''; - $url = $this->buildBaseUrl(self::API_URL_RESOURCE_LANGUAGES); - $languages = $this->request($url, $body); - - return $languages; - } - /** * @param $text * @param $destinationLanguage @@ -329,6 +289,7 @@ public function languages() * * @return string * @SuppressWarnings(PHPMD.ExcessiveParameterList) + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function buildQuery( $text, @@ -343,26 +304,79 @@ protected function buildQuery( $preserveFormatting, $outlineDetection ) { - $splittingTags = (true === is_array($splittingTags)) ? implode(',', $splittingTags) : null; - $nonSplittingTags = (true === is_array($nonSplittingTags)) ? implode(',', $nonSplittingTags) : null; - $ignoreTags = (true === is_array($ignoreTags)) ? implode(',', $ignoreTags) : null; - $outlineDetection = ('0' != $outlineDetection) ? null : '0'; $paramsArray = array( 'text' => $text, 'source_lang' => $sourceLanguage, 'target_lang' => $destinationLanguage, - 'splitting_tags' => $splittingTags ?: null, - 'non_splitting_tags' => $nonSplittingTags ?: null, - 'ignore_tags' => $ignoreTags ?: null, - 'tag_handling' => $tagHandling ?: null, - 'formality' => $formality ?: null, - 'split_sentences' => $splitSentences ?: null, - 'preserve_formatting' => $preserveFormatting ?: null, - 'outline_detection' => $outlineDetection, + 'splitting_tags' => $splittingTags, + 'non_splitting_tags' => $nonSplittingTags, + 'ignore_tags' => $ignoreTags, + 'tag_handling' => $tagHandling, + 'formality' => $formality, + 'split_sentences' => $splitSentences, + 'preserve_formatting' => $preserveFormatting, + 'outline_detection' => $outlineDetection ); + foreach ($paramsArray as $key => $value) { + if (true === is_array($value) && array() != $value) { + $paramsArray[$key] = implode(',', $value); + } + + if (true === empty($value) || ('text' === $key && true === is_array($value))) { + unset($paramsArray[$key]); + } + + if ('outline_detection' === $key) { + $paramsArray[$key] = ('0' != $value) ? null : '0'; + } + } + $body = http_build_query($paramsArray, null, '&', PHP_QUERY_RFC3986); + if (true === is_array($text)) { + $textString =''; + foreach ($text as $textElement) { + $textString .= '&text='.rawurlencode($textElement); + } + $body = $textString.'&'.$body; + } + return $body; } + + /** + * Make a request to the given URL + * + * @param string $url + * + * @return array + * + * @throws DeepLException + */ + protected function request($url, $body) + { + curl_setopt($this->curl, CURLOPT_POST, true); + curl_setopt($this->curl, CURLOPT_URL, $url); + curl_setopt($this->curl, CURLOPT_POSTFIELDS, $body); + curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); + + $response = curl_exec($this->curl); + + if (curl_errno($this->curl)) { + throw new DeepLException('There was a cURL Request Error.'); + } + $httpCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); + $responseArray = json_decode($response, true); + + if ($httpCode != 200 && is_array($responseArray) && array_key_exists('message', $responseArray)) { + throw new DeepLException($responseArray['message'], $httpCode); + } + + if (false === is_array($responseArray)) { + throw new DeepLException('The Response seems to not be valid JSON.', $httpCode); + } + + return $responseArray; + } } diff --git a/tests/unit/DeepLTest.php b/tests/unit/DeepLTest.php index ea38921..c80fde3 100644 --- a/tests/unit/DeepLTest.php +++ b/tests/unit/DeepLTest.php @@ -163,36 +163,146 @@ public function testBuildQueryWithEmptyArguments() public function testBuildQueryWithAllArguments() { $authKey = '123456'; - $args = array('text','en','de',array('p','h1'),array('br','strong'),array('href','i'),'xml','default','nonewlines',1,0); - $expectedString = 'text=text&source_lang=de&target_lang=en&splitting_tags=p%2Ch1&non_splitting_tags=br%2Cstrong&ignore_tags=href%2Ci&tag_handling=xml&formality=default&split_sentences=nonewlines&preserve_formatting=1&outline_detection=0'; + $args = array( + 'text', + 'en', + 'de', + array('p','h1'), + array('br','strong'), + array('href','i'), + 'xml', + 'default', + 'nonewlines', + 1, + 0 + ); + + $expectation = http_build_query(array( + 'text' => 'text', + 'source_lang' => 'de', + 'target_lang' => 'en', + 'splitting_tags' => 'p,h1', + 'non_splitting_tags' => 'br,strong', + 'ignore_tags' => 'href,i', + 'tag_handling' => 'xml', + 'formality' => 'default', + 'split_sentences' => 'nonewlines', + 'preserve_formatting' => 1, + 'outline_detection' => 0 + )); + $deepl = new DeepL($authKey); $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); $return = $buildQuery->invokeArgs($deepl, $args); - $this->assertEquals($expectedString, $return); + $this->assertEquals($expectation, $return); } public function testBuildQueryWithAllArgumentsAndPreserveFormattingZero() { $authKey = '123456'; - $args = array('text','en','de',array('p','h1'),array('br','strong'),array('href','i'),'xml','default','nonewlines',0,0); - $expectedString = 'text=text&source_lang=de&target_lang=en&splitting_tags=p%2Ch1&non_splitting_tags=br%2Cstrong&ignore_tags=href%2Ci&tag_handling=xml&formality=default&split_sentences=nonewlines&outline_detection=0'; + $args = array( + 'text', + 'en', + 'de', + array('p', 'h1'), + array('br', 'strong'), + array('href', 'i'), + 'xml', + 'default', + 'nonewlines', + 0, + 0, + ); + + $expectation = http_build_query(array( + 'text' => 'text', + 'source_lang' => 'de', + 'target_lang' => 'en', + 'splitting_tags' => 'p,h1', + 'non_splitting_tags' => 'br,strong', + 'ignore_tags' => 'href,i', + 'tag_handling' => 'xml', + 'formality' => 'default', + 'split_sentences' => 'nonewlines', + 'outline_detection' => 0 + )); $deepl = new DeepL($authKey); $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); $return = $buildQuery->invokeArgs($deepl, $args); - $this->assertEquals($expectedString, $return); + $this->assertEquals($expectation, $return); } public function testBuildQueryWithAllArgumentsAndOutlineDetectionOne() { $authKey = '123456'; - $args = array('text','en','de',array('p','h1'),array('br','strong'),array('href','i'),'xml','default','nonewlines',0,1); - $expectedString = 'text=text&source_lang=de&target_lang=en&splitting_tags=p%2Ch1&non_splitting_tags=br%2Cstrong&ignore_tags=href%2Ci&tag_handling=xml&formality=default&split_sentences=nonewlines'; + $args = array( + 'text', + 'en', + 'de', + array('p', 'h1'), + array('br', 'strong'), + array('href', 'i'), + 'xml', + 'default', + 'nonewlines', + 0, + 1, + ); + + $expectation = http_build_query(array( + 'text' => 'text', + 'source_lang' => 'de', + 'target_lang' => 'en', + 'splitting_tags' => 'p,h1', + 'non_splitting_tags' => 'br,strong', + 'ignore_tags' => 'href,i', + 'tag_handling' => 'xml', + 'formality' => 'default', + 'split_sentences' => 'nonewlines', + )); $deepl = new DeepL($authKey); $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); $return = $buildQuery->invokeArgs($deepl, $args); - $this->assertEquals($expectedString, $return); + $this->assertEquals($expectation, $return); + } + + public function testBuildQueryWithAllArgumentsAndMultipleTexts() + { + $authKey = '123456'; + $args = array( + array('text','more text','even more text'), + 'en', + 'de', + array('p','h1'), + array('br','strong'), + array('href','i'), + 'xml', + 'default', + 'nonewlines', + 1, + 0 + ); + $expectation = '&text=text&text=more%20text&text=even%20more%20text&'; + $expectation .= http_build_query(array( + 'source_lang' => 'de', + 'target_lang' => 'en', + 'splitting_tags' => 'p,h1', + 'non_splitting_tags' => 'br,strong', + 'ignore_tags' => 'href,i', + 'tag_handling' => 'xml', + 'formality' => 'default', + 'split_sentences' => 'nonewlines', + 'preserve_formatting' => 1, + 'outline_detection' => 0 + )); + + $deepl = new DeepL($authKey); + $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); + $return = $buildQuery->invokeArgs($deepl, $args); + + $this->assertEquals($expectation, $return); } } From dd69d89e882e0428285575efd26468261e6e5233 Mon Sep 17 00:00:00 2001 From: vims Date: Tue, 25 Aug 2020 18:11:20 +0200 Subject: [PATCH 15/36] - further cleanup - removeEmptyParams to reduce complexity of buildQuery - add Testcases for removeEmptyParams --- src/DeepL.php | 230 +++++++++++----------- tests/unit/DeepLTest.php | 404 ++++++++++++++++++++++++++++----------- 2 files changed, 400 insertions(+), 234 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index c4b81bc..3aa70a8 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -141,6 +141,62 @@ public function usage() return $usage; } + /** + * Creates the Base-Url which all of the 3 API-resources have in common. + * + * @param string $resource + * + * @return string + */ + protected function buildBaseUrl($resource = 'translate') + { + $url = sprintf( + self::API_URL_BASE, + self::API_URL_SCHEMA, + $this->host, + $this->apiVersion, + $resource, + $this->authKey + ); + + return $url; + } + + /** + * Make a request to the given URL + * + * @param string $url + * + * @return array + * + * @throws DeepLException + */ + protected function request($url, $body) + { + curl_setopt($this->curl, CURLOPT_POST, true); + curl_setopt($this->curl, CURLOPT_URL, $url); + curl_setopt($this->curl, CURLOPT_POSTFIELDS, $body); + curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); + + $response = curl_exec($this->curl); + + if (curl_errno($this->curl)) { + throw new DeepLException('There was a cURL Request Error.'); + } + $httpCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); + $responseArray = json_decode($response, true); + + if ($httpCode != 200 && is_array($responseArray) && array_key_exists('message', $responseArray)) { + throw new DeepLException($responseArray['message'], $httpCode); + } + + if (false === is_array($responseArray)) { + throw new DeepLException('The Response seems to not be valid JSON.', $httpCode); + } + + return $responseArray; + } + /** * Call languages-Endpoint and return Json-response as an Array * @@ -191,23 +247,26 @@ public function translate( $outlineDetection = null, array $splittingTags = null ) { + $paramsArray = array( + 'text' => $text, + 'source_lang' => $sourceLanguage, + 'target_lang' => $destinationLanguage, + 'splitting_tags' => $splittingTags, + 'non_splitting_tags' => $nonSplittingTags, + 'ignore_tags' => $ignoreTags, + 'tag_handling' => $tagHandling, + 'formality' => $formality, + 'split_sentences' => $splitSentences, + 'preserve_formatting' => $preserveFormatting, + 'outline_detection' => $outlineDetection, + ); + $paramsArray = $this->removeEmptyParams($paramsArray); + // make sure we only accept supported languages $this->checkLanguages($sourceLanguage, $destinationLanguage); $url = $this->buildBaseUrl($resource); - $body = $this->buildQuery( - $text, - $destinationLanguage, - $sourceLanguage, - $splittingTags, - $nonSplittingTags, - $ignoreTags, - $tagHandling, - $formality, - $splitSentences, - $preserveFormatting, - $outlineDetection - ); + $body = $this->buildQuery($paramsArray); // request the DeepL API $translationsArray = $this->request($url, $body); @@ -222,6 +281,32 @@ public function translate( return $translationsArray['translations']; } + /** + * @param array $paramsArray + * + * @return array + */ + private function removeEmptyParams($paramsArray) + { + + foreach ($paramsArray as $key => $value) { + if (true === empty($value)) { + unset($paramsArray[$key]); + } + if ('outline_detection' === $key) { + if (1 === $value) { + unset($paramsArray[$key]); + } + + if (0 === $value) { + $paramsArray[$key] = 0; + } + } + } + + return $paramsArray; + } + /** * Check if the given languages are supported * @@ -253,130 +338,35 @@ protected function checkLanguages($sourceLanguage, $destinationLanguage) return true; } - /** - * Creates the Base-Url which all of the 3 API-resources have in common. - * - * @param string $resource - * - * @return string - */ - protected function buildBaseUrl($resource = 'translate') - { - $url = sprintf( - self::API_URL_BASE, - self::API_URL_SCHEMA, - $this->host, - $this->apiVersion, - $resource, - $this->authKey - ); - - return $url; - } - /** - * @param $text - * @param $destinationLanguage - * @param $sourceLanguage - * @param $splittingTags - * @param $nonSplittingTags - * @param $ignoreTags - * @param $tagHandling - * @param $formality - * @param $splitSentences - * @param $preserveFormatting - * @param $outlineDetection + * @param array $paramsArray * * @return string - * @SuppressWarnings(PHPMD.ExcessiveParameterList) - * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function buildQuery( - $text, - $destinationLanguage, - $sourceLanguage, - $splittingTags, - $nonSplittingTags, - $ignoreTags, - $tagHandling, - $formality, - $splitSentences, - $preserveFormatting, - $outlineDetection + $paramsArray ) { - $paramsArray = array( - 'text' => $text, - 'source_lang' => $sourceLanguage, - 'target_lang' => $destinationLanguage, - 'splitting_tags' => $splittingTags, - 'non_splitting_tags' => $nonSplittingTags, - 'ignore_tags' => $ignoreTags, - 'tag_handling' => $tagHandling, - 'formality' => $formality, - 'split_sentences' => $splitSentences, - 'preserve_formatting' => $preserveFormatting, - 'outline_detection' => $outlineDetection - ); + if (true === is_array($paramsArray['text'])) { + $text = $paramsArray['text']; + unset($paramsArray['text']); + $textString = ''; + foreach ($text as $textElement) { + $textString .= '&text='.rawurlencode($textElement); + } + } foreach ($paramsArray as $key => $value) { - if (true === is_array($value) && array() != $value) { + if (true === is_array($value)) { $paramsArray[$key] = implode(',', $value); } - - if (true === empty($value) || ('text' === $key && true === is_array($value))) { - unset($paramsArray[$key]); - } - - if ('outline_detection' === $key) { - $paramsArray[$key] = ('0' != $value) ? null : '0'; - } } $body = http_build_query($paramsArray, null, '&', PHP_QUERY_RFC3986); - if (true === is_array($text)) { - $textString =''; - foreach ($text as $textElement) { - $textString .= '&text='.rawurlencode($textElement); - } + if (isset($textString)) { $body = $textString.'&'.$body; } return $body; } - - /** - * Make a request to the given URL - * - * @param string $url - * - * @return array - * - * @throws DeepLException - */ - protected function request($url, $body) - { - curl_setopt($this->curl, CURLOPT_POST, true); - curl_setopt($this->curl, CURLOPT_URL, $url); - curl_setopt($this->curl, CURLOPT_POSTFIELDS, $body); - curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); - - $response = curl_exec($this->curl); - - if (curl_errno($this->curl)) { - throw new DeepLException('There was a cURL Request Error.'); - } - $httpCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); - $responseArray = json_decode($response, true); - - if ($httpCode != 200 && is_array($responseArray) && array_key_exists('message', $responseArray)) { - throw new DeepLException($responseArray['message'], $httpCode); - } - - if (false === is_array($responseArray)) { - throw new DeepLException('The Response seems to not be valid JSON.', $httpCode); - } - - return $responseArray; - } } diff --git a/tests/unit/DeepLTest.php b/tests/unit/DeepLTest.php index c80fde3..5e4c99a 100644 --- a/tests/unit/DeepLTest.php +++ b/tests/unit/DeepLTest.php @@ -14,40 +14,40 @@ */ class DeepLTest extends PHPUnit_Framework_TestCase { + /** + * Test checkLanguages() + */ + public function testCheckLanguages() + { + $authKey = '123456'; + $deepl = new DeepL($authKey); + + $checkLanguages = self::getMethod('\BabyMarkt\DeepL\DeepL', 'checkLanguages'); + + $return = $checkLanguages->invokeArgs($deepl, array('de', 'en')); + + $this->assertTrue($return); + } + /** * Get protected method * * @param $className * @param $methodName * + * @return \ReflectionMethod * @throws \ReflectionException * - * @return \ReflectionMethod */ protected static function getMethod($className, $methodName) { - $class = new ReflectionClass($className); + $class = new ReflectionClass($className); $method = $class->getMethod($methodName); $method->setAccessible(true); return $method; } - /** - * Test checkLanguages() - */ - public function testCheckLanguages() - { - $authKey = '123456'; - $deepl = new DeepL($authKey); - - $checkLanguages = self::getMethod('\BabyMarkt\DeepL\DeepL', 'checkLanguages'); - - $return = $checkLanguages->invokeArgs($deepl, array('de', 'en')); - - $this->assertTrue($return); - } - /** * Test checkLanguages() with exception for source language */ @@ -121,13 +121,28 @@ public function testBuildBaseUrlHost() $this->assertEquals($expectedString, $return); } + /** * Test buildQuery with empty Arguemtns */ public function testBuildQueryWithNulledArguments() { $authKey = '123456'; - $args = array(null,null,null,null,null,null,null,null,null,null,null); + $args = array( + array( + 'text' => null, + 'source_lang' => null, + 'target_lang' => null, + 'splitting_tags' => null, + 'non_splitting_tags' => null, + 'ignore_tags' => null, + 'tag_handling' => null, + 'formality' => null, + 'split_sentences' => null, + 'preserve_formatting' => null, + 'outline_detection' => null, + ), + ); $expectedString = ''; $deepl = new DeepL($authKey); $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); @@ -139,7 +154,13 @@ public function testBuildQueryWithNulledArguments() public function testBuildQueryWithMinimalArguments() { $authKey = '123456'; - $args = array('text','en','de',null,null,null,null,null,null,null,null); + $args = array( + array( + 'text' => 'text', + 'source_lang' => 'de', + 'target_lang' => 'en', + ), + ); $expectedString = 'text=text&source_lang=de&target_lang=en'; $deepl = new DeepL($authKey); $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); @@ -151,8 +172,22 @@ public function testBuildQueryWithMinimalArguments() public function testBuildQueryWithEmptyArguments() { $authKey = '123456'; - $args = array('text','en','de',array(),array(),array(),'','','','',''); - $expectedString = 'text=text&source_lang=de&target_lang=en'; + $args = array( + array( + 'text' => 'text', + 'source_lang' => 'en', + 'target_lang' => 'de', + 'splitting_tags' => array(), + 'non_splitting_tags' => array(), + 'ignore_tags' => array(), + 'tag_handling' => null, + 'formality' => null, + 'split_sentences' => null, + 'preserve_formatting' => null, + 'outline_detection' => null, + ), + ); + $expectedString = 'text=text&source_lang=en&target_lang=de&splitting_tags=&non_splitting_tags=&ignore_tags='; $deepl = new DeepL($authKey); $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); $return = $buildQuery->invokeArgs($deepl, $args); @@ -162,145 +197,286 @@ public function testBuildQueryWithEmptyArguments() public function testBuildQueryWithAllArguments() { - $authKey = '123456'; - $args = array( - 'text', - 'en', - 'de', - array('p','h1'), - array('br','strong'), - array('href','i'), - 'xml', - 'default', - 'nonewlines', - 1, - 0 + $authKey = '123456'; + $args = array( + array( + 'text' => 'text', + 'source_lang' => 'de', + 'target_lang' => 'en', + 'splitting_tags' => array('p', 'h1'), + 'non_splitting_tags' => array('br', 'strong'), + 'ignore_tags' => array('href', 'i'), + 'tag_handling' => 'xml', + 'formality' => 'default', + 'split_sentences' => 'nonewlines', + 'preserve_formatting' => 1, + 'outline_detection' => 0, + ), ); - $expectation = http_build_query(array( - 'text' => 'text', - 'source_lang' => 'de', - 'target_lang' => 'en', - 'splitting_tags' => 'p,h1', - 'non_splitting_tags' => 'br,strong', - 'ignore_tags' => 'href,i', - 'tag_handling' => 'xml', - 'formality' => 'default', - 'split_sentences' => 'nonewlines', - 'preserve_formatting' => 1, - 'outline_detection' => 0 - )); + $expectation = http_build_query( + array( + 'text' => 'text', + 'source_lang' => 'de', + 'target_lang' => 'en', + 'splitting_tags' => 'p,h1', + 'non_splitting_tags' => 'br,strong', + 'ignore_tags' => 'href,i', + 'tag_handling' => 'xml', + 'formality' => 'default', + 'split_sentences' => 'nonewlines', + 'preserve_formatting' => 1, + 'outline_detection' => 0, + ) + ); - $deepl = new DeepL($authKey); - $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); - $return = $buildQuery->invokeArgs($deepl, $args); + $deepl = new DeepL($authKey); + $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); + $return = $buildQuery->invokeArgs($deepl, $args); $this->assertEquals($expectation, $return); } public function testBuildQueryWithAllArgumentsAndPreserveFormattingZero() + { + $authKey = '123456'; + $args = array( + array( + 'text' => 'text', + 'source_lang' => 'de', + 'target_lang' => 'en', + 'splitting_tags' => array('p', 'h1'), + 'non_splitting_tags' => array('br', 'strong'), + 'ignore_tags' => array('href', 'i'), + 'tag_handling' => 'xml', + 'formality' => 'default', + 'split_sentences' => 'nonewlines', + 'outline_detection' => 0, + ), + ); + + $expectation = http_build_query( + array( + 'text' => 'text', + 'source_lang' => 'de', + 'target_lang' => 'en', + 'splitting_tags' => 'p,h1', + 'non_splitting_tags' => 'br,strong', + 'ignore_tags' => 'href,i', + 'tag_handling' => 'xml', + 'formality' => 'default', + 'split_sentences' => 'nonewlines', + 'outline_detection' => 0, + ) + ); + $deepl = new DeepL($authKey); + $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); + $return = $buildQuery->invokeArgs($deepl, $args); + + $this->assertEquals($expectation, $return); + } + + public function testBuildQueryWithAllArgumentsAndMultipleTexts() + { + $authKey = '123456'; + $args = array( + array( + 'text' => array('text', 'more text', 'even more text'), + 'source_lang' => 'de', + 'target_lang' => 'en', + 'splitting_tags' => array('p', 'h1'), + 'non_splitting_tags' => array('br', 'strong'), + 'ignore_tags' => array('href', 'i'), + 'tag_handling' => 'xml', + 'formality' => 'default', + 'split_sentences' => 'nonewlines', + 'preserve_formatting' => 1, + 'outline_detection' => 0, + ), + ); + $expectation = '&text=text&text=more%20text&text=even%20more%20text&'; + $expectation .= http_build_query( + array( + 'source_lang' => 'de', + 'target_lang' => 'en', + 'splitting_tags' => 'p,h1', + 'non_splitting_tags' => 'br,strong', + 'ignore_tags' => 'href,i', + 'tag_handling' => 'xml', + 'formality' => 'default', + 'split_sentences' => 'nonewlines', + 'preserve_formatting' => 1, + 'outline_detection' => 0, + ) + ); + + $deepl = new DeepL($authKey); + $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); + $return = $buildQuery->invokeArgs($deepl, $args); + + $this->assertEquals($expectation, $return); + } + + public function testRemoveEmptyParamsWithMinimalArguments() { $authKey = '123456'; - $args = array( - 'text', - 'en', - 'de', - array('p', 'h1'), - array('br', 'strong'), - array('href', 'i'), - 'xml', - 'default', - 'nonewlines', - 0, - 0, + $args = array(array( + 'text' => 'text', + 'source_lang' => 'de', + 'target_lang' => 'en', + 'splitting_tags' => null, + 'non_splitting_tags' => null, + 'ignore_tags' => null, + 'tag_handling' => null, + 'formality' => null, + 'split_sentences' => null, + 'preserve_formatting' => null, + 'outline_detection' => null + )); + $expectedString = array( + 'text' => 'text', + 'source_lang' => 'de', + 'target_lang' => 'en' + ); + $deepl = new DeepL($authKey); + $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'removeEmptyParams'); + $return = $buildQuery->invokeArgs($deepl, $args); + + $this->assertEquals($expectedString, $return); + } + + public function testRemoveEmptyParamsWithEmptyArguments() + { + $authKey = '123456'; + $args = array(array( + 'text' => 'text', + 'source_lang' => 'de', + 'target_lang' => 'en', + 'splitting_tags' => array(), + 'non_splitting_tags' => array(), + 'ignore_tags' => array(), + 'tag_handling' => null, + 'formality' => null, + 'split_sentences' => null, + 'preserve_formatting' => null, + 'outline_detection' => null + )); + $expectedString = array( + 'text' => 'text', + 'source_lang' => 'de', + 'target_lang' => 'en' ); + $deepl = new DeepL($authKey); + $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'removeEmptyParams'); + $return = $buildQuery->invokeArgs($deepl, $args); + + $this->assertEquals($expectedString, $return); + } - $expectation = http_build_query(array( + public function testRemoveEmptyParamsAllArgumentsAndPreserveFormattingZero() + { + $authKey = '123456'; + $args = array(array( + 'text' => 'text', + 'source_lang' => 'de', + 'target_lang' => 'en', + 'splitting_tags' => array('p','h1'), + 'non_splitting_tags' => array('br','strong'), + 'ignore_tags' => array('href','i'), + 'tag_handling' => 'xml', + 'formality' => 'default', + 'split_sentences' => 'nonewlines', + 'preserve_formatting' => 0, + 'outline_detection' => 0 + )); + + $expectation = array( 'text' => 'text', 'source_lang' => 'de', 'target_lang' => 'en', - 'splitting_tags' => 'p,h1', - 'non_splitting_tags' => 'br,strong', - 'ignore_tags' => 'href,i', + 'splitting_tags' => array('p','h1'), + 'non_splitting_tags' => array('br','strong'), + 'ignore_tags' => array('href','i'), 'tag_handling' => 'xml', 'formality' => 'default', 'split_sentences' => 'nonewlines', 'outline_detection' => 0 - )); + ); $deepl = new DeepL($authKey); - $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); + $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'removeEmptyParams'); $return = $buildQuery->invokeArgs($deepl, $args); - $this->assertEquals($expectation, $return); + $this->assertSame($expectation, $return); } - public function testBuildQueryWithAllArgumentsAndOutlineDetectionOne() + public function testRemoveEmptyParamsWithAllArguments() { $authKey = '123456'; - $args = array( - 'text', - 'en', - 'de', - array('p', 'h1'), - array('br', 'strong'), - array('href', 'i'), - 'xml', - 'default', - 'nonewlines', - 0, - 1, - ); + $args = array(array( + 'text' => 'text', + 'source_lang' => 'de', + 'target_lang' => 'en', + 'splitting_tags' => array('p','h1'), + 'non_splitting_tags' => array('br','strong'), + 'ignore_tags' => array('href','i'), + 'tag_handling' => 'xml', + 'formality' => 'default', + 'split_sentences' => 'nonewlines', + 'preserve_formatting' => 1, + 'outline_detection' => 0 + )); - $expectation = http_build_query(array( + $expectation = array( 'text' => 'text', 'source_lang' => 'de', 'target_lang' => 'en', - 'splitting_tags' => 'p,h1', - 'non_splitting_tags' => 'br,strong', - 'ignore_tags' => 'href,i', + 'splitting_tags' => array('p','h1'), + 'non_splitting_tags' => array('br','strong'), + 'ignore_tags' => array('href','i'), 'tag_handling' => 'xml', 'formality' => 'default', 'split_sentences' => 'nonewlines', - )); + 'preserve_formatting' => 1, + 'outline_detection' => 0 + ); + $deepl = new DeepL($authKey); - $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); + $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'removeEmptyParams'); $return = $buildQuery->invokeArgs($deepl, $args); $this->assertEquals($expectation, $return); } - public function testBuildQueryWithAllArgumentsAndMultipleTexts() + public function testRemoveEmptyParamsAllArgumentsAndOutlineDetectionOne() { $authKey = '123456'; - $args = array( - array('text','more text','even more text'), - 'en', - 'de', - array('p','h1'), - array('br','strong'), - array('href','i'), - 'xml', - 'default', - 'nonewlines', - 1, - 0 - ); - $expectation = '&text=text&text=more%20text&text=even%20more%20text&'; - $expectation .= http_build_query(array( + $args = array(array( + 'text' => 'text', + 'source_lang' => 'de', + 'target_lang' => 'en', + 'splitting_tags' => array('p','h1'), + 'non_splitting_tags' => array('br','strong'), + 'ignore_tags' => array('href','i'), + 'tag_handling' => 'xml', + 'formality' => 'default', + 'split_sentences' => 'nonewlines', + 'preserve_formatting' => 0, + 'outline_detection' => 1 + )); + + $expectation = array( + 'text' => 'text', 'source_lang' => 'de', 'target_lang' => 'en', - 'splitting_tags' => 'p,h1', - 'non_splitting_tags' => 'br,strong', - 'ignore_tags' => 'href,i', + 'splitting_tags' => array('p','h1'), + 'non_splitting_tags' => array('br','strong'), + 'ignore_tags' => array('href','i'), 'tag_handling' => 'xml', 'formality' => 'default', - 'split_sentences' => 'nonewlines', - 'preserve_formatting' => 1, - 'outline_detection' => 0 - )); - + 'split_sentences' => 'nonewlines' + ); $deepl = new DeepL($authKey); - $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'buildQuery'); + $buildQuery = self::getMethod('\BabyMarkt\DeepL\DeepL', 'removeEmptyParams'); $return = $buildQuery->invokeArgs($deepl, $args); $this->assertEquals($expectation, $return); From ea63485d17fe8ba7ec1380c5eff00b0fad5d6dcb Mon Sep 17 00:00:00 2001 From: vims Date: Tue, 25 Aug 2020 18:20:02 +0200 Subject: [PATCH 16/36] - remove PHP_QUERY_RFC3986 from due to PHP 5.3 --- src/DeepL.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DeepL.php b/src/DeepL.php index 3aa70a8..d6ca270 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -361,7 +361,7 @@ protected function buildQuery( } } - $body = http_build_query($paramsArray, null, '&', PHP_QUERY_RFC3986); + $body = http_build_query($paramsArray, null, '&'); if (isset($textString)) { $body = $textString.'&'.$body; From 33133b1d205d72591a8138720dd46279ddd9e261 Mon Sep 17 00:00:00 2001 From: vims Date: Wed, 26 Aug 2020 16:06:34 +0200 Subject: [PATCH 17/36] - add a little documentation for a special Case --- src/DeepL.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/DeepL.php b/src/DeepL.php index d6ca270..f046aa3 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -293,6 +293,9 @@ private function removeEmptyParams($paramsArray) if (true === empty($value)) { unset($paramsArray[$key]); } + // Special Workaround for outline_detection which will be unset above + // DeepL assumes outline_detection=1 if it is not send + // in order to deactivate it, we need to send outline_detection=0 to the api if ('outline_detection' === $key) { if (1 === $value) { unset($paramsArray[$key]); From 66b901326049fdc71a06b2cbb0b23bcd38b9d771 Mon Sep 17 00:00:00 2001 From: vims Date: Wed, 26 Aug 2020 17:28:46 +0200 Subject: [PATCH 18/36] - fix Docblock and Codestyle --- src/DeepL.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index f046aa3..8217df8 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -166,6 +166,7 @@ protected function buildBaseUrl($resource = 'translate') * Make a request to the given URL * * @param string $url + * @param string $body * * @return array * @@ -346,9 +347,8 @@ protected function checkLanguages($sourceLanguage, $destinationLanguage) * * @return string */ - protected function buildQuery( - $paramsArray - ) { + protected function buildQuery($paramsArray) + { if (true === is_array($paramsArray['text'])) { $text = $paramsArray['text']; unset($paramsArray['text']); From 013cf80001f739d76bdb0e206eb2b7f82c2d30a1 Mon Sep 17 00:00:00 2001 From: vims Date: Thu, 27 Aug 2020 14:20:48 +0200 Subject: [PATCH 19/36] - add Testcase for Handling of html5-Tags --- tests/integration/DeepLApiTest.php | 46 ++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/tests/integration/DeepLApiTest.php b/tests/integration/DeepLApiTest.php index f00593d..d16b927 100644 --- a/tests/integration/DeepLApiTest.php +++ b/tests/integration/DeepLApiTest.php @@ -273,4 +273,50 @@ public function testTranslateFormalityFail() 'more' //$formality ); } + + + /** + * Test to Test the Tag-Handling. + */ + public function testTranslateWithHTML() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey); + $textToTranslate = array( + 'Hello WorldThis should stay the same', + 'Another Text
new line

this is a paragraph

' + ); + + $expectedArray = array( + array( + 'detected_source_language' => "EN", + 'text' => "Hallo WeltThis should stay the same", + ), + array( + 'detected_source_language' => "EN", + 'text' => "Ein weiterer Text neue Zeile

dies ist ein Absatz

", + ), + + ); + + $translatedText = $deepl->translate( + $textToTranslate, + 'en', //$sourceLanguage + 'de', //$destinationLanguage + 'xml', //$tagHandling + array('strong'), //$ignoreTags + 'less', //$formality + 'translate', + 1, + 0, + array('br'), + 1, + array('p') + ); + + $this->assertEquals($expectedArray, $translatedText); + } } From 9182dc8a0c42f1b9ee71336f680ce4e300007cff Mon Sep 17 00:00:00 2001 From: vims Date: Fri, 28 Aug 2020 08:36:33 +0200 Subject: [PATCH 20/36] - fix commemt for Test --- tests/integration/DeepLApiTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/DeepLApiTest.php b/tests/integration/DeepLApiTest.php index d16b927..8332070 100644 --- a/tests/integration/DeepLApiTest.php +++ b/tests/integration/DeepLApiTest.php @@ -95,7 +95,7 @@ public function testTranslateV1Success() } /** - * Test translate() success with default v2 API + * Test translate() with unknown API-Version */ public function testTranslateWrongVersion() { From 93757944b80f695a014c8ad7c30ac1f4134420e3 Mon Sep 17 00:00:00 2001 From: vims Date: Fri, 28 Aug 2020 08:38:06 +0200 Subject: [PATCH 21/36] - remove unessesarry $resource-parameter from translate-function --- src/DeepL.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index 8217df8..492ace8 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -222,7 +222,6 @@ public function languages() * @param string $tagHandling * @param array|null $ignoreTags * @param string $formality - * @param string $resource * @param null $splitSentences * @param null $preserveFormatting * @param array|null $nonSplittingTags @@ -241,7 +240,6 @@ public function translate( $tagHandling = null, array $ignoreTags = null, $formality = 'default', - $resource = self::API_URL_RESOURCE_TRANSLATE, $splitSentences = null, $preserveFormatting = null, array $nonSplittingTags = null, @@ -266,7 +264,7 @@ public function translate( // make sure we only accept supported languages $this->checkLanguages($sourceLanguage, $destinationLanguage); - $url = $this->buildBaseUrl($resource); + $url = $this->buildBaseUrl(); $body = $this->buildQuery($paramsArray); // request the DeepL API From 16eb956566cf3348967ea6b7a38e0acf1516227b Mon Sep 17 00:00:00 2001 From: vims Date: Fri, 28 Aug 2020 08:42:26 +0200 Subject: [PATCH 22/36] - fix Tests for translate() --- tests/integration/DeepLApiTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/integration/DeepLApiTest.php b/tests/integration/DeepLApiTest.php index 8332070..b8fa33e 100644 --- a/tests/integration/DeepLApiTest.php +++ b/tests/integration/DeepLApiTest.php @@ -214,7 +214,6 @@ public function testTranslateWithAllParams() 'xml', //$tagHandling array('html','html5','html6'), //$ignoreTags 'more', //$formality - 'translate', //$resource 'nonewlines', //$splitSentences 1, //$preserveFormatting array('href','href2'), //$nonSplittingTags @@ -309,7 +308,6 @@ public function testTranslateWithHTML() 'xml', //$tagHandling array('strong'), //$ignoreTags 'less', //$formality - 'translate', 1, 0, array('br'), From 42fa07159b0c7dca2147bacf5c50796ed6cd7a4a Mon Sep 17 00:00:00 2001 From: vims Date: Fri, 28 Aug 2020 11:39:44 +0200 Subject: [PATCH 23/36] Breaking-Changes: - Remove string-return of translate() - Add Exception when $tagHandling is send as array instead of String - Adjust and Add Testcases --- src/DeepL.php | 13 +++++-------- tests/integration/DeepLApiTest.php | 12 ++++++------ tests/unit/DeepLTest.php | 16 +++++++++++++++- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index 492ace8..e0056a2 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -228,7 +228,7 @@ public function languages() * @param null $outlineDetection * @param array|null $splittingTags * - * @return mixed + * @return array * @throws DeepLException * * @SuppressWarnings(PHPMD.ExcessiveParameterList) @@ -246,6 +246,10 @@ public function translate( $outlineDetection = null, array $splittingTags = null ) { + if (is_array($tagHandling)) { + throw new \InvalidArgumentException('$tagHandling must be of type String in V2 of DeepLLibrary'); + } + $paramsArray = array( 'text' => $text, 'source_lang' => $sourceLanguage, @@ -269,13 +273,6 @@ public function translate( // request the DeepL API $translationsArray = $this->request($url, $body); - $translationsCount = count($translationsArray['translations']); - - if ($translationsCount === 0) { - throw new DeepLException('No translations found.'); - } elseif ($translationsCount === 1) { - return $translationsArray['translations'][0]['text']; - } return $translationsArray['translations']; } diff --git a/tests/integration/DeepLApiTest.php b/tests/integration/DeepLApiTest.php index b8fa33e..2e3737d 100644 --- a/tests/integration/DeepLApiTest.php +++ b/tests/integration/DeepLApiTest.php @@ -72,7 +72,7 @@ public function testTranslateSuccess() $translatedText = $deepl->translate($germanText); - $this->assertEquals($expectedText, $translatedText); + $this->assertEquals($expectedText, $translatedText[0]['text']); } /** @@ -91,7 +91,7 @@ public function testTranslateV1Success() $translatedText = $deepl->translate($germanText); - $this->assertEquals($expectedText, $translatedText); + $this->assertEquals($expectedText, $translatedText[0]['text']); } /** @@ -131,7 +131,7 @@ public function testTranslateTagHandlingSuccess() 'xml' ); - $this->assertEquals($expectedText, $translatedText); + $this->assertEquals($expectedText, $translatedText[0]['text']); } /** @@ -156,7 +156,7 @@ public function testTranslateIgnoreTagsSuccess() array('strong') ); - $this->assertEquals($expectedText, $translatedText); + $this->assertEquals($expectedText, $translatedText[0]['text']); } /** @@ -221,7 +221,7 @@ public function testTranslateWithAllParams() array('p','br') //$splittingTags ); - $this->assertEquals($expectedText, $translatedText); + $this->assertEquals($expectedText, $translatedText[0]['text']); } /** @@ -246,7 +246,7 @@ public function testTranslateFormality() 'less' //$formality ); - $this->assertEquals($expectedText, $translatedText); + $this->assertEquals($expectedText, $translatedText[0]['text']); } /** diff --git a/tests/unit/DeepLTest.php b/tests/unit/DeepLTest.php index 5e4c99a..9c127e9 100644 --- a/tests/unit/DeepLTest.php +++ b/tests/unit/DeepLTest.php @@ -123,7 +123,7 @@ public function testBuildBaseUrlHost() /** - * Test buildQuery with empty Arguemtns + * Test buildQuery with empty Arguments */ public function testBuildQueryWithNulledArguments() { @@ -481,4 +481,18 @@ public function testRemoveEmptyParamsAllArgumentsAndOutlineDetectionOne() $this->assertEquals($expectation, $return); } + + /** + * Test behaviour of translate() when tagHandling is an array + */ + public function testTranslateExceptionTagHandling() + { + $authKey = '123456'; + $germanText = 'Hallo Welt'; + $deepl = new DeepL($authKey); + + $this->setExpectedException('InvalidArgumentException'); + + $deepl->translate($germanText, 'de', 'en', array('xml')); + } } From c22f16b0ae1c2a9da7ffacfbeb10dd0a19729e6f Mon Sep 17 00:00:00 2001 From: vims Date: Fri, 28 Aug 2020 11:48:25 +0200 Subject: [PATCH 24/36] - remove checkLanguages with Tests --- src/DeepL.php | 74 ---------------------------------------- tests/unit/DeepLTest.php | 45 ------------------------ 2 files changed, 119 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index e0056a2..db2bab8 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -31,46 +31,6 @@ class DeepL */ const API_URL_RESOURCE_LANGUAGES = 'languages'; - /** - * Supported translation source languages - * - * @var array - */ - protected $sourceLanguages = array( - 'EN', - 'DE', - 'FR', - 'ES', - 'PT', - 'IT', - 'NL', - 'PL', - 'RU', - 'JA', - 'ZH', - ); - - /** - * Supported translation destination languages - * - * @var array - */ - protected $destinationLanguages = array( - 'EN', - 'DE', - 'FR', - 'ES', - 'PT', - 'PT-PT', - 'PT-BR', - 'IT', - 'NL', - 'PL', - 'RU', - 'JA', - 'ZH', - ); - /** * DeepL API Version (v2 is default since 2018) * @@ -265,9 +225,6 @@ public function translate( ); $paramsArray = $this->removeEmptyParams($paramsArray); - // make sure we only accept supported languages - $this->checkLanguages($sourceLanguage, $destinationLanguage); - $url = $this->buildBaseUrl(); $body = $this->buildQuery($paramsArray); @@ -306,37 +263,6 @@ private function removeEmptyParams($paramsArray) return $paramsArray; } - /** - * Check if the given languages are supported - * - * @param string $sourceLanguage - * @param string $destinationLanguage - * - * @return boolean - * - * @throws DeepLException - */ - protected function checkLanguages($sourceLanguage, $destinationLanguage) - { - $sourceLanguage = strtoupper($sourceLanguage); - - if (false === in_array($sourceLanguage, $this->sourceLanguages)) { - throw new DeepLException( - sprintf('The language "%s" is not supported as source language.', $sourceLanguage) - ); - } - - $destinationLanguage = strtoupper($destinationLanguage); - - if (false === in_array($destinationLanguage, $this->destinationLanguages)) { - throw new DeepLException( - sprintf('The language "%s" is not supported as destination language.', $destinationLanguage) - ); - } - - return true; - } - /** * @param array $paramsArray * diff --git a/tests/unit/DeepLTest.php b/tests/unit/DeepLTest.php index 9c127e9..45971ba 100644 --- a/tests/unit/DeepLTest.php +++ b/tests/unit/DeepLTest.php @@ -14,21 +14,6 @@ */ class DeepLTest extends PHPUnit_Framework_TestCase { - /** - * Test checkLanguages() - */ - public function testCheckLanguages() - { - $authKey = '123456'; - $deepl = new DeepL($authKey); - - $checkLanguages = self::getMethod('\BabyMarkt\DeepL\DeepL', 'checkLanguages'); - - $return = $checkLanguages->invokeArgs($deepl, array('de', 'en')); - - $this->assertTrue($return); - } - /** * Get protected method * @@ -48,36 +33,6 @@ protected static function getMethod($className, $methodName) return $method; } - /** - * Test checkLanguages() with exception for source language - */ - public function testCheckLanguagesSourceLanguageException() - { - $authKey = '123456'; - $deepl = new DeepL($authKey); - - $checkLanguages = self::getMethod('\BabyMarkt\DeepL\DeepL', 'checkLanguages'); - - $this->setExpectedException('\BabyMarkt\DeepL\DeepLException'); - - $checkLanguages->invokeArgs($deepl, array('fo', 'en')); - } - - /** - * Test checkLanguages() with exception for destination language - */ - public function testCheckLanguagesDestinationLanguageException() - { - $authKey = '123456'; - $deepl = new DeepL($authKey); - - $checkLanguages = self::getMethod('\BabyMarkt\DeepL\DeepL', 'checkLanguages'); - - $this->setExpectedException('\BabyMarkt\DeepL\DeepLException'); - - $checkLanguages->invokeArgs($deepl, array('de', 'fo')); - } - /** * Test translate() */ From 049b850ee94a48e6a9b4ad7b66c7b3b1e503b497 Mon Sep 17 00:00:00 2001 From: vims Date: Fri, 28 Aug 2020 12:02:31 +0200 Subject: [PATCH 25/36] - add Testcase for unsupported Languages --- tests/integration/DeepLApiTest.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/integration/DeepLApiTest.php b/tests/integration/DeepLApiTest.php index 2e3737d..d90e559 100644 --- a/tests/integration/DeepLApiTest.php +++ b/tests/integration/DeepLApiTest.php @@ -317,4 +317,34 @@ public function testTranslateWithHTML() $this->assertEquals($expectedArray, $translatedText); } + + /** + * Test translate() with unsupported sourceLanguage + */ + public function testTranslateWithNotSupportedSourceLanguage() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey); + + $this->setExpectedException('\BabyMarkt\DeepL\DeepLException'); + $deepl->translate('some txt', 'dk', 'de'); + } + + /** + * Test translate() with unsupported sourceLanguage + */ + public function testTranslateWithNotSupportedDestinationLanguage() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey); + + $this->setExpectedException('\BabyMarkt\DeepL\DeepLException'); + $deepl->translate('some txt', 'en', 'dk'); + } } From 3e3ba234cb1dbad1948cc105349719c0011a2b3d Mon Sep 17 00:00:00 2001 From: vims Date: Fri, 28 Aug 2020 14:09:20 +0200 Subject: [PATCH 26/36] - use ReflectionMethod insted of array --- src/DeepL.php | 67 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index db2bab8..965c4ad 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -2,6 +2,8 @@ namespace BabyMarkt\DeepL; +use ReflectionMethod; + /** * DeepL API client library * @@ -16,11 +18,6 @@ class DeepL */ const API_URL_BASE = '%s://%s/v%s/%s?auth_key=%s'; - /** - * API URL: translate - */ - const API_URL_RESOURCE_TRANSLATE = 'translate'; - /** * API URL: usage */ @@ -177,8 +174,8 @@ public function languages() * Translate the text string or array from source to destination language * * @param string|string[] $text - * @param string $sourceLanguage - * @param string $destinationLanguage + * @param string $sourceLang + * @param string $targetLang * @param string $tagHandling * @param array|null $ignoreTags * @param string $formality @@ -191,12 +188,12 @@ public function languages() * @return array * @throws DeepLException * - * @SuppressWarnings(PHPMD.ExcessiveParameterList) + * @SuppressWarnings(PHPMD.UnusedParameters) */ public function translate( $text, - $sourceLanguage = 'de', - $destinationLanguage = 'en', + $sourceLang = 'de', + $targetLang = 'en', $tagHandling = null, array $ignoreTags = null, $formality = 'default', @@ -209,24 +206,17 @@ public function translate( if (is_array($tagHandling)) { throw new \InvalidArgumentException('$tagHandling must be of type String in V2 of DeepLLibrary'); } + $paramsArray = array(); + $reflection = new ReflectionMethod('Babymarkt\DeepL\DeepL', 'translate'); - $paramsArray = array( - 'text' => $text, - 'source_lang' => $sourceLanguage, - 'target_lang' => $destinationLanguage, - 'splitting_tags' => $splittingTags, - 'non_splitting_tags' => $nonSplittingTags, - 'ignore_tags' => $ignoreTags, - 'tag_handling' => $tagHandling, - 'formality' => $formality, - 'split_sentences' => $splitSentences, - 'preserve_formatting' => $preserveFormatting, - 'outline_detection' => $outlineDetection, - ); + foreach ($reflection->getParameters() as $param) { + $paramName = $param->name; + $paraKey = $this->camelToSnake($paramName); + $paramsArray[$paraKey] = $$paramName; + } $paramsArray = $this->removeEmptyParams($paramsArray); - - $url = $this->buildBaseUrl(); - $body = $this->buildQuery($paramsArray); + $url = $this->buildBaseUrl(); + $body = $this->buildQuery($paramsArray); // request the DeepL API $translationsArray = $this->request($url, $body); @@ -293,4 +283,29 @@ protected function buildQuery($paramsArray) return $body; } + + + /** + * @param string $subject + * + * @return string + */ + private function camelToSnake($subject) + { + if (preg_match('/[A-Z]/', $subject) === 0) { + return $subject; + } + $pattern = '/([a-z])([A-Z])/'; + $snakeString = strtolower( + preg_replace_callback( + $pattern, + function ($match) { + return $match[1]."_".strtolower($match[2]); + }, + $subject + ) + ); + + return $snakeString; + } } From fbc7997af5d2b4e63c2c1dacddb304a3a6411323 Mon Sep 17 00:00:00 2001 From: vims Date: Fri, 28 Aug 2020 14:20:46 +0200 Subject: [PATCH 27/36] - revert from ReflectionMethod to Array, because MessDetection did not like it. --- src/DeepL.php | 47 ++++++++++++++--------------------------------- 1 file changed, 14 insertions(+), 33 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index 965c4ad..cafa4c2 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -188,7 +188,7 @@ public function languages() * @return array * @throws DeepLException * - * @SuppressWarnings(PHPMD.UnusedParameters) + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function translate( $text, @@ -206,14 +206,20 @@ public function translate( if (is_array($tagHandling)) { throw new \InvalidArgumentException('$tagHandling must be of type String in V2 of DeepLLibrary'); } - $paramsArray = array(); - $reflection = new ReflectionMethod('Babymarkt\DeepL\DeepL', 'translate'); + $paramsArray = array( + 'text' => $text, + 'source_lang' => $sourceLang, + 'target_lang' => $targetLang, + 'splitting_tags' => $splittingTags, + 'non_splitting_tags' => $nonSplittingTags, + 'ignore_tags' => $ignoreTags, + 'tag_handling' => $tagHandling, + 'formality' => $formality, + 'split_sentences' => $splitSentences, + 'preserve_formatting' => $preserveFormatting, + 'outline_detection' => $outlineDetection, + ); - foreach ($reflection->getParameters() as $param) { - $paramName = $param->name; - $paraKey = $this->camelToSnake($paramName); - $paramsArray[$paraKey] = $$paramName; - } $paramsArray = $this->removeEmptyParams($paramsArray); $url = $this->buildBaseUrl(); $body = $this->buildQuery($paramsArray); @@ -283,29 +289,4 @@ protected function buildQuery($paramsArray) return $body; } - - - /** - * @param string $subject - * - * @return string - */ - private function camelToSnake($subject) - { - if (preg_match('/[A-Z]/', $subject) === 0) { - return $subject; - } - $pattern = '/([a-z])([A-Z])/'; - $snakeString = strtolower( - preg_replace_callback( - $pattern, - function ($match) { - return $match[1]."_".strtolower($match[2]); - }, - $subject - ) - ); - - return $snakeString; - } } From e488af1be6bd93b2e195be024f26952fdbef8c33 Mon Sep 17 00:00:00 2001 From: vims Date: Fri, 28 Aug 2020 14:22:10 +0200 Subject: [PATCH 28/36] - remove unused Class --- src/DeepL.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index cafa4c2..d2b36d8 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -2,8 +2,6 @@ namespace BabyMarkt\DeepL; -use ReflectionMethod; - /** * DeepL API client library * From c760b1d52b563b3e2ebf97ae89cd0677c2e11a71 Mon Sep 17 00:00:00 2001 From: Sebastian V <273156+VimS@users.noreply.github.com> Date: Tue, 1 Sep 2020 10:28:48 +0200 Subject: [PATCH 29/36] Update tests/integration/DeepLApiTest.php Co-authored-by: Dennis Exner <59438491+dexner@users.noreply.github.com> --- tests/integration/DeepLApiTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/DeepLApiTest.php b/tests/integration/DeepLApiTest.php index d90e559..26baa73 100644 --- a/tests/integration/DeepLApiTest.php +++ b/tests/integration/DeepLApiTest.php @@ -334,7 +334,7 @@ public function testTranslateWithNotSupportedSourceLanguage() } /** - * Test translate() with unsupported sourceLanguage + * Test translate() with unsupported targetLanguage */ public function testTranslateWithNotSupportedDestinationLanguage() { From 840d8287fe1bbe62680d028805117ae7d2fae60c Mon Sep 17 00:00:00 2001 From: vims Date: Thu, 3 Sep 2020 09:04:49 +0200 Subject: [PATCH 30/36] some minor improvements: - sort class properties by type and alphabetically - change parametes of request-Function to get rid of unnecessary variable initialization --- src/DeepL.php | 187 +++++++++++++++++++++++++------------------------- 1 file changed, 94 insertions(+), 93 deletions(-) diff --git a/src/DeepL.php b/src/DeepL.php index d2b36d8..01b5f02 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -89,85 +89,12 @@ public function __destruct() */ public function usage() { - $body = ''; $url = $this->buildBaseUrl(self::API_URL_RESOURCE_USAGE); - $usage = $this->request($url, $body); + $usage = $this->request($url); return $usage; } - /** - * Creates the Base-Url which all of the 3 API-resources have in common. - * - * @param string $resource - * - * @return string - */ - protected function buildBaseUrl($resource = 'translate') - { - $url = sprintf( - self::API_URL_BASE, - self::API_URL_SCHEMA, - $this->host, - $this->apiVersion, - $resource, - $this->authKey - ); - - return $url; - } - - /** - * Make a request to the given URL - * - * @param string $url - * @param string $body - * - * @return array - * - * @throws DeepLException - */ - protected function request($url, $body) - { - curl_setopt($this->curl, CURLOPT_POST, true); - curl_setopt($this->curl, CURLOPT_URL, $url); - curl_setopt($this->curl, CURLOPT_POSTFIELDS, $body); - curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); - - $response = curl_exec($this->curl); - - if (curl_errno($this->curl)) { - throw new DeepLException('There was a cURL Request Error.'); - } - $httpCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); - $responseArray = json_decode($response, true); - - if ($httpCode != 200 && is_array($responseArray) && array_key_exists('message', $responseArray)) { - throw new DeepLException($responseArray['message'], $httpCode); - } - - if (false === is_array($responseArray)) { - throw new DeepLException('The Response seems to not be valid JSON.', $httpCode); - } - - return $responseArray; - } - - /** - * Call languages-Endpoint and return Json-response as an Array - * - * @return array - * @throws DeepLException - */ - public function languages() - { - $body = ''; - $url = $this->buildBaseUrl(self::API_URL_RESOURCE_LANGUAGES); - $languages = $this->request($url, $body); - - return $languages; - } - /** * Translate the text string or array from source to destination language * @@ -229,32 +156,38 @@ public function translate( } /** - * @param array $paramsArray + * Call languages-Endpoint and return Json-response as an Array * * @return array + * @throws DeepLException */ - private function removeEmptyParams($paramsArray) + public function languages() { + $url = $this->buildBaseUrl(self::API_URL_RESOURCE_LANGUAGES); + $languages = $this->request($url); - foreach ($paramsArray as $key => $value) { - if (true === empty($value)) { - unset($paramsArray[$key]); - } - // Special Workaround for outline_detection which will be unset above - // DeepL assumes outline_detection=1 if it is not send - // in order to deactivate it, we need to send outline_detection=0 to the api - if ('outline_detection' === $key) { - if (1 === $value) { - unset($paramsArray[$key]); - } + return $languages; + } - if (0 === $value) { - $paramsArray[$key] = 0; - } - } - } + /** + * Creates the Base-Url which all of the 3 API-resources have in common. + * + * @param string $resource + * + * @return string + */ + protected function buildBaseUrl($resource = 'translate') + { + $url = sprintf( + self::API_URL_BASE, + self::API_URL_SCHEMA, + $this->host, + $this->apiVersion, + $resource, + $this->authKey + ); - return $paramsArray; + return $url; } /** @@ -287,4 +220,72 @@ protected function buildQuery($paramsArray) return $body; } + + + + + /** + * Make a request to the given URL + * + * @param string $url + * @param string $body + * + * @return array + * + * @throws DeepLException + */ + protected function request($url, $body = '') + { + curl_setopt($this->curl, CURLOPT_POST, true); + curl_setopt($this->curl, CURLOPT_URL, $url); + curl_setopt($this->curl, CURLOPT_POSTFIELDS, $body); + curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); + + $response = curl_exec($this->curl); + + if (curl_errno($this->curl)) { + throw new DeepLException('There was a cURL Request Error.'); + } + $httpCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); + $responseArray = json_decode($response, true); + + if ($httpCode != 200 && is_array($responseArray) && array_key_exists('message', $responseArray)) { + throw new DeepLException($responseArray['message'], $httpCode); + } + + if (false === is_array($responseArray)) { + throw new DeepLException('The Response seems to not be valid JSON.', $httpCode); + } + + return $responseArray; + } + + /** + * @param array $paramsArray + * + * @return array + */ + private function removeEmptyParams($paramsArray) + { + + foreach ($paramsArray as $key => $value) { + if (true === empty($value)) { + unset($paramsArray[$key]); + } + // Special Workaround for outline_detection which will be unset above + // DeepL assumes outline_detection=1 if it is not send + // in order to deactivate it, we need to send outline_detection=0 to the api + if ('outline_detection' === $key) { + if (1 === $value) { + unset($paramsArray[$key]); + } + + if (0 === $value) { + $paramsArray[$key] = 0; + } + } + } + + return $paramsArray; + } } From 3c75c72b822affc337525f1a8891c615e2e8d7b4 Mon Sep 17 00:00:00 2001 From: vims Date: Fri, 4 Sep 2020 09:41:18 +0200 Subject: [PATCH 31/36] - Update README.md - add source & target option to languages-function - add Testscases --- README.md | 36 ++++++++++++--------- src/DeepL.php | 26 ++++++++------- tests/integration/DeepLApiTest.php | 52 ++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index ccff431..299239c 100644 --- a/README.md +++ b/README.md @@ -51,20 +51,26 @@ foreach ($translations as $translation) { } ``` ### Supported languages -* `de` - German -* `en` - English -* `fr` - French -* `it` - Italian -* `ja` - Japanese -* `es` - Spanish -* `nl` - Dutch -* `pl` - Polish -* `pt` - Portuguese -* `pt-pt` - Portuguese variant -* `pt-br` - Portuguese variant -* `ru` - Russian -* `zh` - Chinese +In Version 2 we removed the internal List of supported Languages. +Instead, you can now get an array with the supported Languages directly form DeepL: +```php +$languagesArray = $deepl->languages(); + +foreach ($languagesArray as $language) { + echo $language['name']; + echo $language['language']; +} +``` + +### Monitoring usage +You can now check ow much you translate, as well as the limits set. +```php +$usageArray = $deepl->usage(); + +echo 'You have used '.$usageArray['character_count'].' of '.$usageArray['character_limit'].' in in the current billing period.'; + +``` ## Testing Run PHP_CodeSniffer Tests: @@ -93,7 +99,7 @@ composer test:all ## Credits -- [Arkadius Jonczek][link-author] +- [babymarkt.de GmbH][link-author] - [All Contributors][link-contributors] ## License @@ -112,5 +118,5 @@ The MIT License (MIT). Please see [License File](LICENSE.md) for more informatio [link-scrutinizer]: https://scrutinizer-ci.com/g/Baby-Markt/deepl-php-lib/code-structure [link-code-quality]: https://scrutinizer-ci.com/g/Baby-Markt/deepl-php-lib [link-downloads]: https://packagist.org/packages/babymarkt/deepl-php-lib -[link-author]: https://github.com/arkadiusjonczek +[link-author]: https://github.com/Baby-Markt [link-contributors]: ../../contributors diff --git a/src/DeepL.php b/src/DeepL.php index 01b5f02..d123f9a 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -82,17 +82,20 @@ public function __destruct() } /** - * Calls the usage-Endpoint and return Json-response as an array + * Call languages-Endpoint and return Json-response as an Array + * + * @param string $type * * @return array * @throws DeepLException */ - public function usage() + public function languages($type = null) { - $url = $this->buildBaseUrl(self::API_URL_RESOURCE_USAGE); - $usage = $this->request($url); + $url = $this->buildBaseUrl(self::API_URL_RESOURCE_LANGUAGES); + $body = $this->buildQuery(array('type' => $type)); + $languages = $this->request($url, $body); - return $usage; + return $languages; } /** @@ -156,19 +159,20 @@ public function translate( } /** - * Call languages-Endpoint and return Json-response as an Array + * Calls the usage-Endpoint and return Json-response as an array * * @return array * @throws DeepLException */ - public function languages() + public function usage() { - $url = $this->buildBaseUrl(self::API_URL_RESOURCE_LANGUAGES); - $languages = $this->request($url); + $url = $this->buildBaseUrl(self::API_URL_RESOURCE_USAGE); + $usage = $this->request($url); - return $languages; + return $usage; } + /** * Creates the Base-Url which all of the 3 API-resources have in common. * @@ -197,7 +201,7 @@ protected function buildBaseUrl($resource = 'translate') */ protected function buildQuery($paramsArray) { - if (true === is_array($paramsArray['text'])) { + if (isset($paramsArray['text']) && true === is_array($paramsArray['text'])) { $text = $paramsArray['text']; unset($paramsArray['text']); $textString = ''; diff --git a/tests/integration/DeepLApiTest.php b/tests/integration/DeepLApiTest.php index 26baa73..b9e7919 100644 --- a/tests/integration/DeepLApiTest.php +++ b/tests/integration/DeepLApiTest.php @@ -193,6 +193,58 @@ public function testLanguages() } } + /** + * Test languages() can return the source-languages + */ + public function testLanguagesSource() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey); + $response = $deepl->languages('source'); + + foreach ($response as $language) { + $this->assertArrayHasKey('language', $language); + $this->assertArrayHasKey('name', $language); + } + } + + /** + * Test languages() can return the targe-languages + */ + public function testLanguagesTarget() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey); + $response = $deepl->languages('target'); + + foreach ($response as $language) { + $this->assertArrayHasKey('language', $language); + $this->assertArrayHasKey('name', $language); + } + } + + /** + * Test languages() will fail with wrong Parameter + */ + public function testLanguagesFail() + { + if (self::$authKey === false) { + $this->markTestSkipped('DeepL Auth Key (DEEPL_AUTH_KEY) is not configured.'); + } + + $deepl = new DeepL(self::$authKey); + + $this->setExpectedException('\BabyMarkt\DeepL\DeepLException'); + + $deepl->languages('fail'); + } + /** * Test translate() with all Params */ From ad43f45b02097c900704607b77ff739f55177bb4 Mon Sep 17 00:00:00 2001 From: vims Date: Fri, 4 Sep 2020 11:22:24 +0200 Subject: [PATCH 32/36] - Updated README.md --- README.md | 46 ++++++++++++++++++++++++++++++++++++++++------ src/DeepL.php | 1 + 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 299239c..a262a32 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ Simple PHP Library for DeepL API. You can translate one or multiple text strings 🇬🇧🇩🇪🇫🇷🇪🇸🇵🇹🇮🇹🇷🇺🇯🇵🇨🇳🇵🇱🇳🇱🇸🇪🇩🇰🇫🇮🇬🇷🇨🇿🇷🇴🇭🇺🇸🇰🇧🇬🇸🇮🇱🇹🇱🇻🇪🇪🇲🇹 +[Official DeepL API][link-deepl] + ## Install Use composer if you want to use this library in your project. @@ -28,11 +30,12 @@ $authKey = ''; $deepl = new DeepL($authKey); ``` +### Translate Translate one Text: ```php $translatedText = $deepl->translate('Hallo Welt', 'de', 'en'); -echo $translatedText; +echo $translatedText[0]['text'].PHP_EOL; ``` Translate multiple Texts: @@ -47,9 +50,24 @@ $text = array( $translations = $deepl->translate($text, 'de', 'en'); foreach ($translations as $translation) { - echo $translation['text']; + echo $translation['text'].PHP_EOL; } ``` + +| param | Description | +|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| $text | Text to be translated. Only UTF8-encoded plain text is supported. The parameter may be specified as an Array and translations are returned in the same order as they are requested. Each of the parameter values may contain multiple sentences. Up to 50 texts can be sent for translation in one request. | +| $sourceLang | Language of the text to be translated.
default: de | +| $targetLang | The language into which the text should be translated.
default: en | +| $tagHandling | Sets which kind of tags should be handled. Options currently available: "xml" | +| $ignoreTags | Array of XML tags that indicate text not to be translated.
default: null | +| $formality | Sets whether the translated text should lean towards formal or informal language. This feature currently works for all target languages except "EN" (English), "EN-GB" (British English), "EN-US" (American English), "ES" (Spanish), "JA" (Japanese) and "ZH" (Chinese).

Possible options are:
"default" (default)
"more" - for a more formal language
"less" - for a more informal language | +| $splitSentences | Array of XML tags which always cause splits
default: null | +| $preserveFormatting | Sets whether the translation engine should respect the original formatting, even if it would usually correct some aspects. Possible values are:
"0" (default)
"1"
The formatting aspects affected by this setting include:
Punctuation at the beginning and end of the sentence
Upper/lower case at the beginning of the sentence | +| $nonSplittingTags | Comma-separated list of XML tags which never split sentences.
default: null | +| $outlineDetection | See: https://www.deepl.com/docs-api/handling-xml/outline-detection/
default: 1 | +| $splittingTags | Array of XML tags which always cause splits.
default: null | + ### Supported languages In Version 2 we removed the internal List of supported Languages. Instead, you can now get an array with the supported Languages directly form DeepL: @@ -58,17 +76,32 @@ Instead, you can now get an array with the supported Languages directly form Dee $languagesArray = $deepl->languages(); foreach ($languagesArray as $language) { - echo $language['name']; - echo $language['language']; + echo 'Name: '.$language['name'].' Api-Shorthand: '.$language['language'].PHP_EOL; } ``` +You can check for the supported Source-Languages: +```php +$sourceLanguagesArray = $deepl->languages('source'); +foreach ($sourceLanguagesArray as $srouceLanguage) { + echo 'Name: '.$srouceLanguage['name'].' Api-shorthand: '.$srouceLanguage['language'].PHP_EOL; +} +``` + +Check for the supported Target-Languages: +```php +$targetLanguagesArray = $deepl->languages('target'); + +foreach ($targetLanguagesArray as $targetLanguage) { + echo 'Name: '.$targetLanguage['name'].' Api-Shorthand: '.$targetLanguage['language'].PHP_EOL; +} +``` ### Monitoring usage -You can now check ow much you translate, as well as the limits set. +You can now check ow much you translate, as well as the limit: ```php $usageArray = $deepl->usage(); -echo 'You have used '.$usageArray['character_count'].' of '.$usageArray['character_limit'].' in in the current billing period.'; +echo 'You have used '.$usageArray['character_count'].' of '.$usageArray['character_limit'].' in the current billing period.'.PHP_EOL; ``` ## Testing @@ -120,3 +153,4 @@ The MIT License (MIT). Please see [License File](LICENSE.md) for more informatio [link-downloads]: https://packagist.org/packages/babymarkt/deepl-php-lib [link-author]: https://github.com/Baby-Markt [link-contributors]: ../../contributors +[link-deepl]: https://www.deepl.com/docs-api/introduction/ diff --git a/src/DeepL.php b/src/DeepL.php index d123f9a..2588d1a 100644 --- a/src/DeepL.php +++ b/src/DeepL.php @@ -100,6 +100,7 @@ public function languages($type = null) /** * Translate the text string or array from source to destination language + * For detailed info on Parameters see README.md * * @param string|string[] $text * @param string $sourceLang From b1a286124a48bb308dd58deddc64e61572b20fb8 Mon Sep 17 00:00:00 2001 From: vims Date: Fri, 4 Sep 2020 11:27:34 +0200 Subject: [PATCH 33/36] - Updated README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a262a32..ffdb9c5 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ foreach ($translations as $translation) { | param | Description | |---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| $text | Text to be translated. Only UTF8-encoded plain text is supported. The parameter may be specified as an Array and translations are returned in the same order as they are requested. Each of the parameter values may contain multiple sentences. Up to 50 texts can be sent for translation in one request. | +| $text | Text to be translated. Only UTF8-encoded plain text is supported. The parameter may be specified as an Array and translations are returned in the same order as they are requested. Each of the array values may contain multiple sentences. Up to 50 texts can be sent for translation in one request. | | $sourceLang | Language of the text to be translated.
default: de | | $targetLang | The language into which the text should be translated.
default: en | | $tagHandling | Sets which kind of tags should be handled. Options currently available: "xml" | From f0796f4c07455936df85f62df49ad94a78896ca6 Mon Sep 17 00:00:00 2001 From: vims Date: Fri, 4 Sep 2020 13:31:25 +0200 Subject: [PATCH 34/36] - Updated README.md: User Flags of countries which are actually supported by DeepL --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ffdb9c5..f82cafc 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Simple PHP Library for DeepL API. You can translate one or multiple text strings (up to 50) per request. -🇬🇧🇩🇪🇫🇷🇪🇸🇵🇹🇮🇹🇷🇺🇯🇵🇨🇳🇵🇱🇳🇱🇸🇪🇩🇰🇫🇮🇬🇷🇨🇿🇷🇴🇭🇺🇸🇰🇧🇬🇸🇮🇱🇹🇱🇻🇪🇪🇲🇹 +🇩🇪🇬🇧🇺🇸🇪🇸🇲🇽🇫🇷🇮🇹🇯🇵🇳🇱🇵🇱🇵🇹🇧🇷🇷🇺🇨🇳 [Official DeepL API][link-deepl] From 192b2c606c716aaf2fb2257a4d6325d4a815898c Mon Sep 17 00:00:00 2001 From: vims Date: Fri, 4 Sep 2020 13:32:14 +0200 Subject: [PATCH 35/36] - add Changelog.md: tried my best to add Changes done in previous Versions --- CHANGELOG.md | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..5bc4a73 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,146 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [2.0.0] - 2020-09-?? +####Major overhaul of the Library with some Breaking changes. Please read before updating! +### Added +- Ability to change the API-Host +- Support for the full Range of Request Parameters offered by DeepL +- Ability to check Languages supported by DeepL-Api (source and target) +- Ability to monitor API usage +### Changed +- **Breaking Change!** tagHandling-Parameter for translate-function was changed from array to string. +- **Breaking Change!** translate now always returns an array, because in our internal usages we found, that we always converted the string to an array anyway. +- Errocodes & Messages come now directly from DeepL +- all Requests are now send as POST as it is recommended by DeepL +- all Parameters except the API-key are send in the Requestbody +- Tests are now split into Unit- and Intergration-Tests (which need an API-Key to run) +### Removed +- internal Error-codes +- internal storage of source- and target-languages + +## [1.1.0] - 2020-08-07 +### Changed +- use API v2 as default [@arkadiusjonczek](https://github.com/arkadiusjonczek) + +## [1.0.11] - 2020-06-23 +### Added +- Add supported languages to Readme [@bestog](https://github.com/bestog) +- Add Japanese and Chinese to supported languages [@bestog](https://github.com/bestog) +- add formality parameter [@tomschwiha](https://github.com/tomschwiha) +- Added possible Portuguese variants [@interferenc](https://github.com/interferenc) +### Changed +- Update README.md (added Flaggs) [@arkadiusjonczek](https://github.com/arkadiusjonczek) +- Add portuguese varieties in README [@Sasti](https://github.com/Sasti) + +## [1.0.10] - 2020-02-26 +### Added +- create clover.xml in travis and push to scrutinizer +### Changed +- update scrutinizer config +- change keyword in composer.json + +all by [@arkadiusjonczek](https://github.com/arkadiusjonczek) + +## [1.0.9] - 2020-02-03 +### Added +- add phpcs to project and integrate it into travis-ci configuration +### Changed +- update composer description +- fix scrutinizer ci url +- disable xdebug in composer for travis-ci +- update testing sequence + +all by [@arkadiusjonczek](https://github.com/arkadiusjonczek) + +## [1.0.8] - 2019-11-28 +### Changed +- update tests for travis deepl api testing +- fix testTranslateIgnoreTagsSuccess +- update php version + +all by [@arkadiusjonczek](https://github.com/arkadiusjonczek) + + +## [1.0.7] - 2019-11-25 +### Added +- packagist status to README.md file [@arkadiusjonczek](https://github.com/arkadiusjonczek) +### Changed +- Fix ignore tags [@tomschwiha](https://github.com/tomschwiha) +- Update README.md [@tomschwiha](https://github.com/tomschwiha) + + +## [1.0.6] - 2019-09-05 +### Added +- add php 5.5 to travis ci test [@arkadiusjonczek](https://github.com/arkadiusjonczek) +### Changed +- Fix wrong error message [@shamimmoeen](https://github.com/shamimmoeen) +- set dist precise for php 5.4 and php 5.5 in travis configuration [@arkadiusjonczek](https://github.com/arkadiusjonczek) + + +## [1.0.5] - 2019-02-20 +### Added +- deepl v2 api support and [@arkadiusjonczek](https://github.com/arkadiusjonczek) +### Changed +- fix some little errors [@arkadiusjonczek](https://github.com/arkadiusjonczek) + + +## [1.0.4] - 2019-02-14 +### Added +- Add PT and RU to supported languages [@floranpagliai](https://github.com/floranpagliai) +### Changed +- replace travis build php nightly build with php 7.3 [@arkadiusjonczek](https://github.com/arkadiusjonczek) +### Removed + +## [1.0.3] - 2018-19-23 +### Added +- Add tag_handling optional param [@floranpagliai](https://github.com/floranpagliai) +- Add tagHandling test [@floranpagliai](https://github.com/floranpagliai) +- Add ignore_tag optional param [@floranpagliai](https://github.com/floranpagliai) +- Add test for ignore tags [@floranpagliai](https://github.com/floranpagliai) +- Add var typing on setIgnoreTags method [@floranpagliai](https://github.com/floranpagliai) +### Changed +- Fixed array syntax [@floranpagliai](https://github.com/floranpagliai) +- Fixed array syntax [@floranpagliai](https://github.com/floranpagliai) +- Fixed buildUrl test [@floranpagliai](https://github.com/floranpagliai) + + +## [1.0.2] - 2018-06-04 +### Changed +- send text as POST body to solve 414 uri too long error [@arkadiusjonczek](https://github.com/arkadiusjonczek) + +## [1.0.1] - 2018-06-12 +### Changed +- fix travis-ci build status image [@arkadiusjonczek](https://github.com/arkadiusjonczek) +- update translate method return [@arkadiusjonczek](https://github.com/arkadiusjonczek) +- update readme [@arkadiusjonczek](https://github.com/arkadiusjonczek) + + +## [1.0.0] - 2018-06-12 +Initial public Release [@arkadiusjonczek](https://github.com/arkadiusjonczek) + + + + +[Unreleased]: https://github.com/Baby-Markt/deepl-php-lib/compare/master...head +[2.0.0]: https://github.com/Baby-Markt/deepl-php-lib/releases/tag/2.0.0 +[1.1.0]: https://github.com/Baby-Markt/deepl-php-lib/releases/tag/v1.1.0 +[1.0.11]: https://github.com/Baby-Markt/deepl-php-lib/releases/tag/v1.0.11 +[1.0.10]: https://github.com/Baby-Markt/deepl-php-lib/releases/tag/v1.0.10 +[1.0.9]: https://github.com/Baby-Markt/deepl-php-lib/releases/tag/v1.0.9 +[1.0.8]: https://github.com/Baby-Markt/deepl-php-lib/releases/tag/v1.0.8 +[1.0.7]: https://github.com/Baby-Markt/deepl-php-lib/releases/tag/v1.0.7 +[1.0.6]: https://github.com/Baby-Markt/deepl-php-lib/releases/tag/v1.0.6 +[1.0.5]: https://github.com/Baby-Markt/deepl-php-lib/releases/tag/v1.0.5 +[1.0.4]: https://github.com/Baby-Markt/deepl-php-lib/releases/tag/v1.0.4 +[1.0.3]: https://github.com/Baby-Markt/deepl-php-lib/releases/tag/v1.0.3 +[1.0.2]: https://github.com/Baby-Markt/deepl-php-lib/releases/tag/v1.0.2 +[1.0.1]: https://github.com/Baby-Markt/deepl-php-lib/releases/tag/v1.0.1 +[1.0.0]: https://github.com/Baby-Markt/deepl-php-lib/releases/tag/v1.0.0 + +What is a changelog? From 169f0f535974616b57a5358db49165398194b1ba Mon Sep 17 00:00:00 2001 From: vims Date: Fri, 4 Sep 2020 13:35:03 +0200 Subject: [PATCH 36/36] - add link to CHANGELOG.md in README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f82cafc..8eea123 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ Simple PHP Library for DeepL API. You can translate one or multiple text strings [Official DeepL API][link-deepl] +[CHANGELOG](CHANGELOG.md) + ## Install Use composer if you want to use this library in your project.