Giter Site home page Giter Site logo

deeplcom / deepl-php Goto Github PK

View Code? Open in Web Editor NEW
180.0 12.0 23.0 173 KB

Official PHP library for the DeepL language translation API.

License: MIT License

PHP 99.59% Dockerfile 0.17% Shell 0.24%
api deepl language php translation translator official i18n

deepl-php's Introduction

deepl-php

Latest Stable Version Minimum PHP version License: MIT

Official PHP client library for the DeepL API.

The DeepL API is a language translation API that allows other computer programs to send texts and documents to DeepL's servers and receive high-quality translations. This opens a whole universe of opportunities for developers: any translation product you can imagine can now be built on top of DeepL's best-in-class translation technology.

The DeepL PHP library offers a convenient way for applications written for PHP to interact with the DeepL API. We intend to support all API functions with the library, though support for new features may be added to the library after they’re added to the API.

Getting an authentication key

To use deepl-php, you'll need an API authentication key. To get a key, please create an account here. With a DeepL API Free account you can translate up to 500,000 characters/month for free.

Installation

To use this library in your project, install it using Composer:

composer require deeplcom/deepl-php

Requirements

The library officially supports PHP 7.3 and later.

Starting in 2024, we will drop support for older PHP versions that have reached official end-of-life. You can find the PHP versions and support timelines here. To continue using this library, you should update to PHP 8.1+.

Usage

Construct a Translator object. The first argument is a string containing your API authentication key as found in your DeepL Pro Account.

Be careful not to expose your key, for example when sharing source code.

$authKey = "f63c02c5-f056-..."; // Replace with your key
$translator = new \DeepL\Translator($authKey);

$result = $translator->translateText('Hello, world!', null, 'fr');
echo $result->text; // Bonjour, le monde!

Translator accepts options as the second argument, see Configuration for more information.

Translating text

To translate text, call translateText(). The first argument is a string containing the text you want to translate, or an array of strings if you want to translate multiple texts.

The second and third arguments are the source and target language codes. Language codes are case-insensitive strings according to ISO 639-1, for example 'de', 'fr', 'ja''. Some target languages also include the regional variant according to ISO 3166-1, for example 'en-US', or 'pt-BR'. The source language also accepts null, to enable auto-detection of the source language.

The last argument to translateText() is optional, and specifies extra translation options, see Text translation options below.

translateText() returns a TextResult, or an array of TextResults corresponding to your input text(s). TextResult has two properties: text is the translated text, and detectedSourceLang is the detected source language code.

// Translate text into a target language, in this case, French:
$translationResult = $translator->translateText('Hello, world!', 'en', 'fr');
echo $translationResult->text; // 'Bonjour, le monde !'

// Translate multiple texts into British English:
$translations = $translator->translateText(
    ['お元気ですか?', '¿Cómo estás?'],
    null,
    'en-GB',
);
echo $translations[0]->text; // 'How are you?'
echo $translations[0]->detectedSourceLang; // 'ja'
echo $translations[1]->text; // 'How are you?'
echo $translations[1]->detectedSourceLang; // 'es'

// Translate into German with less and more Formality:
echo $translator->translateText('How are you?', null, 'de', ['formality' => 'less']); // 'Wie geht es dir?'
echo $translator->translateText('How are you?', null, 'de', ['formality' => 'more']); // 'Wie geht es Ihnen?'

Text translation options

Provide options to the translateText function as an associative array, using the following keys:

  • split_sentences: specify how input text should be split into sentences, default: 'on'.
    • 'on': input text will be split into sentences using both newlines and punctuation.
    • 'off': input text will not be split into sentences. Use this for applications where each input text contains only one sentence.
    • 'nonewlines': input text will be split into sentences using punctuation but not newlines.
  • preserve_formatting: controls automatic-formatting-correction. Set to true to prevent automatic-correction of formatting, default: false.
  • formality: controls whether translations should lean toward informal or formal language. This option is only available for some target languages, see Listing available languages. Use the prefer_* options to apply formality if it is available for the target language, or otherwise fallback to the default.
    • 'less': use informal language.
    • 'more': use formal, more polite language.
    • 'default': use default formality.
    • 'prefer_less': use informal language if available, otherwise default.
    • 'prefer_more': use formal, more polite language if available, otherwise default.
  • tag_handling: type of tags to parse before translation, options are 'html' and 'xml'.
  • context: specifies additional context to influence translations, that is not translated itself. Note this is an alpha feature: it may be deprecated at any time, or incur charges if it becomes generally available. See the API documentation for more information and example usage.
  • glossary: glossary ID of glossary to use for translation.

The following options are only used if tag_handling is 'xml':

  • outline_detection: specify false to disable automatic tag detection, default is true.
  • splitting_tags: list of XML tags that should be used to split text into sentences. Tags may be specified as an array of strings (['tag1', 'tag2']), or a comma-separated list of strings ('tag1,tag2'). The default is an empty list.
  • non_splitting_tags: list of XML tags that should not be used to split text into sentences. Format and default are the same as for splitting_tags.
  • ignore_tags: list of XML tags that containing content that should not be translated. Format and default are the same as for splitting_tags.

The TranslateTextOptions class defines constants for the options above, for example TranslateTextOptions::FORMALITY is defined as 'formality'.

Translating documents

To translate documents, call translateDocument(). The first and second arguments are the input and output file paths.

The third and fourth arguments are the source and target language codes, and they work exactly the same as when translating text with translateText().

The last argument to translateDocument() is optional, and specifies extra translation options, see Document translation options below.

// Translate a formal document from English to German:
try {
    $translator->translateDocument(
        'Instruction Manual.docx',
        'Bedienungsanleitung.docx',
        'en',
        'de',
        ['formality' => 'more'],
    );
} catch (\DeepL\DocumentTranslationException $error) {
    // If the error occurs after the document was already uploaded,
    // documentHandle will contain the document ID and key
    echo 'Error occurred while translating document: ' . ($error->getMessage() ?? 'unknown error');
    if ($error->documentHandle) {
        $handle = $error->documentHandle;
        echo "Document ID: {$handle->documentId}, document key: {$handle->documentKey}";
    } else {
        echo 'Unknown document handle';
    }
}

translateDocument() wraps multiple API calls: uploading, polling status until the translation is complete, and downloading. If your application needs to execute these steps individually, you can instead use the following functions directly:

  • uploadDocument(),
  • getDocumentStatus() (or waitUntilDocumentTranslationComplete()), and
  • downloadDocument()

Document translation options

Provide options to the translateDocument function as an associative array, using the following keys:

The uploadDocument function also supports these options.

The TranslateDocumentOptions class defines constants for the options above, for example TranslateDocumentOptions::FORMALITY is defined as 'formality'.

Glossaries

Glossaries allow you to customize your translations using user-defined terms. Multiple glossaries can be stored with your account, each with a user-specified name and a uniquely-assigned ID.

Creating a glossary

You can create a glossary with your desired terms and name using createGlossary(). Each glossary applies to a single source-target language pair. Note: Glossaries are only supported for some language pairs, see Listing available glossary languages for more information. The entries should be specified as a GlossaryEntries object; you can create one using GlossaryEntries::fromEntries using an associative array with the source terms as keys and the target terms as values.

Then use createGlossary() with the glossary name, source and target language codes and the GlossaryEntries. If successful, the glossary is created and stored with your DeepL account, and a GlossaryInfo object is returned including the ID, name, languages and entry count.

// Create an English to German glossary with two terms:
$entries = GlossaryEntries::fromEntries(['artist' => 'Maler', 'prize' => 'Gewinn']);
$myGlossary = $translator->createGlossary('My glossary', 'en', 'de', $entries);
echo "Created '$myGlossary->name' ($myGlossary->glossaryId) " .
    "$myGlossary->sourceLang to $myGlossary->targetLang " .
    "containing $myGlossary->entryCount entries";
// Example: Created 'My glossary' (559192ed-8e23-...) en to de containing 2 entries

You can also upload a glossary downloaded from the DeepL website using createGlossaryFromCsv(). Similar to createGlossary, specify the glossary name, and source and target language codes, but instead of specifying the terms as an associative array, specify the CSV data as a string:

// Read CSV data from a file, for example: "artist,Maler,en,de\nprize,Gewinn,en,de"
$csvData = file_get_contents('/path/to/glossary_file.csv');
$myCsvGlossary = $translator->createGlossaryFromCsv(
    'CSV glossary',
    'en',
    'de',
    $csvData,
)

The API documentation explains the expected CSV format in detail.

Getting, listing and deleting stored glossaries

Functions to get, list, and delete stored glossaries are also provided:

  • getGlossary() takes a glossary ID and returns a GlossaryInfo object for a stored glossary, or raises an exception if no such glossary is found.
  • listGlossaries() returns a list of GlossaryInfo objects corresponding to all of your stored glossaries.
  • deleteGlossary() takes a glossary ID or GlossaryInfo object and deletes the stored glossary from the server, or raises an exception if no such glossary is found.
// Retrieve a stored glossary using the ID
$glossaryId = '559192ed-8e23-...';
$myGlossary = $translator->getGlossary($glossaryId);

// Find and delete glossaries named 'Old glossary'
$glossaries = $translator->listGlossaries();
foreach ($glossaries as $glossary) {
    if ($glossary->name === 'Old glossary') {
        $translator->deleteGlossary($glossary);
    }
}

Listing entries in a stored glossary

The GlossaryInfo object does not contain the glossary entries, but instead only the number of entries in the entryCount property.

To list the entries contained within a stored glossary, use getGlossaryEntries() providing either the GlossaryInfo object or glossary ID. A GlossaryEntries object is returned; you can access the entries as an associative array using getEntries():

$entries = $translator->getGlossaryEntries($myGlossary);
print_r($entries->getEntries()); // Array ( [artist] => Maler, [prize] => Gewinn)

Using a stored glossary

You can use a stored glossary for text translation by setting the glossary option to either the glossary ID or GlossaryInfo object. You must also specify the sourceLang argument (it is required when using a glossary):

$text = 'The artist was awarded a prize.';
$withGlossary = $translator->translateText($text, 'en', 'de', ['glossary' => $myGlossary]);
echo $withGlossary->text; // "Der Maler wurde mit einem Gewinn ausgezeichnet."

// For comparison, the result without a glossary:
$withGlossary = $translator->translateText($text, null, 'de');
echo $withoutGlossary->text; // "Der Künstler wurde mit einem Preis ausgezeichnet."

Using a stored glossary for document translation is the same: set the glossary option. The sourceLang argument must also be specified:

$translator->translateDocument(
    $inFile, $outFile, 'en', 'de', ['glossary' => $myGlossary]
)

The translateDocument() and translateDocumentUpload() functions both support the glossary argument.

Checking account usage

To check account usage, use the getUsage() function.

The returned Usage object contains up to three usage subtypes, depending on your account type: character, document and teamDocument. For API accounts character will be set, the others null.

Each usage subtypes (if set) have count and limit properties giving the amount used and maximum amount respectively, and the limitReached() function that checks if the usage has reached the limit. The top level Usage object has the anyLimitReached() function to check all usage subtypes.

$usage = $translator->getUsage();
if ($usage->anyLimitReached()) {
    echo 'Translation limit exceeded.';
}
if ($usage->character) {
    echo 'Characters: ' . $usage->character->count . ' of ' . $usage->character->limit;
}
if ($usage->document) {
    echo 'Documents: ' . $usage->document->count . ' of ' . $usage->document->limit;
}

Listing available languages

You can request the list of languages supported by DeepL Translator for text and documents using the getSourceLanguages() and getTargetLanguages() functions. They both return an array of Language objects.

The name property gives the name of the language in English, and the code property gives the language code. The supportsFormality property only appears for target languages, and is a bool indicating whether the target language supports the optional formality parameter.

$sourceLanguages = $translator->getSourceLanguages();
foreach ($sourceLanguages as $sourceLanguage) {
    echo $sourceLanguage->name . ' (' . $sourceLanguage->code . ')'; // Example: 'English (en)'
}

$targetLanguages = $translator->getTargetLanguages();
foreach ($targetLanguages as $targetLanguage) {
    if ($targetLanguage->supportsFormality) {
        echo $targetLanguage->name . ' (' . $targetLanguage->code . ') supports formality';
        // Example: 'German (de) supports formality'
    }
}

Listing available glossary languages

Glossaries are supported for a subset of language pairs. To retrieve those languages use the getGlossaryLanguages() function, which returns an array of GlossaryLanguagePair objects. Each has sourceLang and targetLang properties indicating that that pair of language codes is supported.

$glossaryLanguages = $translator->getGlossaryLanguages();
foreach ($glossaryLanguages as $glossaryLanguage) {
    echo "$glossaryLanguage->sourceLang to $glossaryLanguage->targetLang";
    // Example: "en to de", "de to en", etc.
}

You can also find the list of supported glossary language pairs in the API documentation.

Note that glossaries work for all target regional-variants: a glossary for the target language English ('en') supports translations to both American English ('en-US') and British English ('en-GB').

Writing a Plugin

If you use this library in an application, please identify the application with the app_info TranslatorOption, which needs the name and version of the app:

$options = ['app_info' => new \DeepL\AppInfo('my-custom-php-chat-client', '1.2.3')];
$translator = new \DeepL\Translator('YOUR_AUTH_KEY', $options);

This information is passed along when the library makes calls to the DeepL API. Both name and version are required. Please note that setting the User-Agent header via the headers TranslatorOption will override this setting, if you need to use this, please manually identify your Application in the User-Agent header.

Configuration

The Translator constructor accepts configuration options as a second argument, for example:

$options = [ 'max_retries' => 5, 'timeout' => 10.0 ];
$translator = new \DeepL\Translator('YOUR_AUTH_KEY', $options);

Provide the options as an associative array with the following keys:

  • max_retries: the maximum number of failed HTTP requests to retry, per function call. By default, 5 retries are made. See Request retries.
  • timeout: the number of seconds used as connection timeout for each HTTP request retry. The default value is 10.0 (10 seconds).
  • server_url: string containing the URL of the DeepL API, can be overridden for example for testing purposes. By default, the URL is selected based on the user account type (free or paid).
  • headers: extra HTTP headers attached to every HTTP request. By default, no extra headers are used. Note that Authorization and User-Agent headers are added automatically but may be overridden by this option.
  • proxy: specify a proxy server URL.
  • logger: specify a PSR-3 compatible logger that the library should log messages to.

The TranslatorOptions class defines constants for the options above.

Proxy configuration

You can configure a proxy using the proxy option when constructing a Translator:

$proxy = 'http://user:[email protected]:3128';
$translator = new \DeepL\Translator('YOUR_AUTH_KEY', ['proxy' => $proxy]);

The proxy option is used for the CURLOPT_PROXY option when preparing the cURL request, see the documentation for cURL.

Logging

To enable logging, specify a PSR-3 compatible logger as the 'logger' option in the Translator configuration options.

Anonymous platform information

By default, we send some basic information about the platform the client library is running on with each request, see here for an explanation. This data is completely anonymous and only used to improve our product, not track any individual users. If you do not wish to send this data, you can opt-out when creating your Translator object by setting the send_platform_option flag in the options like so:

$translator = new \DeepL\Translator('YOUR_AUTH_KEY', ['send_platform_info' => false]);

You can also customize the User-Agent header completely by setting its value explicitly in the options via the headers field (this overrides the send_platform_option option). For example::

$headers = [
    'Authorization' => "DeepL-Auth-Key YOUR_AUTH_KEY",
    'User-Agent' => 'my-custom-php-client',
];
$translator = new \DeepL\Translator('YOUR_AUTH_KEY', ['headers' => $headers]);

Custom HTTP client

If you want to set specific HTTP options that we don't expose (or otherwise want more control over the API calls by the library), you can configure the library to use a PSR-18 compliant HTTP client of your choosing. For example, in order to use a connect timeout of 5.2 seconds and read timeout of 7.4 seconds while using a proxy with Guzzle:

$client = new \GuzzleHttp\Client([
    'connect_timeout' => 5.2,
    'read_timeout' => 7.4,
    'proxy' => 'http://localhost:8125'
]);
$translator = new \DeepL\Translator('YOUR_AUTH_KEY', [TranslatorOptions::HTTP_CLIENT => $client]);
$translator->getUsage(); // Or a translate call, etc

Request retries

Requests to the DeepL API that fail due to transient conditions (for example, network timeouts or high server-load) will be retried. The maximum number of retries can be configured when constructing the Translator object using the max_retries option. The timeout for each request attempt may be controlled using the timeout option. An exponential-backoff strategy is used, so requests that fail multiple times will incur delays.

Issues

If you experience problems using the library, or would like to request a new feature, please open an issue.

Development

We welcome Pull Requests, please read the contributing guidelines.

Tests

Execute the tests using phpunit. The tests communicate with the DeepL API using the auth key defined by the DEEPL_AUTH_KEY environment variable.

Be aware that the tests make DeepL API requests that contribute toward your API usage.

The test suite may instead be configured to communicate with the mock-server provided by deepl-mock. Although most test cases work for either, some test cases work only with the DeepL API or the mock-server and will be otherwise skipped. The test cases that require the mock-server trigger server errors and test the client error-handling. To execute the tests using deepl-mock, run it in another terminal while executing the tests. Execute the tests using phpunit with the DEEPL_MOCK_SERVER_PORT and DEEPL_SERVER_URL environment variables defined referring to the mock-server.

deepl-php's People

Contributors

daniel-jones-dev avatar janebbing avatar martkcz avatar vincentlanglet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

deepl-php's Issues

413 Request Entity Too Large

I am trying to translate 1009 lines of text (312 KiB) in a single POST request via a WordPress plugin I created and can't due to a generic internal server error (HTTP 500). After inspecting the logs, I found this client error:

PHP Fatal error:  Uncaught DeepL\DeepLException: Unexpected status code: 413 , <html>
<head><title>413 Request Entity Too Large</title></head>
<body>
<center><h1>413 Request Entity Too Large</h1></center>
<hr><center>nginx</center>
</body>
</html>
, content: <html>
<head><title>413 Request Entity Too Large</title></head>
<body>
<center><h1>413 Request Entity Too Large</h1></center>
<hr><center>nginx</center>
</body>
</html>

I've done some brief research, to find that the maximum possible size of a POST request is limited by the server, as well as the client by doing something like: min(serverMaxSize, clientMaxSize). Since it's a HTTP 4xx error, I presume the fault lies within the library/client here?

Here are some of my server settings (php.ini), which look fine to me:

Key Value Description
max_input_vars 1000 PHP max input variables
max_execution_time 30 PHP time limit
memory_limit 512M PHP memory limit
max_input_time 60 Max input time
upload_max_filesize 50M Upload max filesize
post_max_size 50M PHP post max size

Any ideas are greatly appreciated! Thanks for making this open source!

Autoloading not working

Hello,

I'm guessing this is not directly related to this library but I am experiencing some very strange behaviour and was hoping you could still help me.

I am working on a WordPress plugin with the following code:

<?php
/**
 * [...]
 */

namespace My\Namespace;

define( 'PLUGIN_FILEPATH', __FILE__ );
define( 'DEEPL_API_HOST', 'api-free.deepl.com' );
define( 'DEEPL_API_KEY', '[...]' );

require_once __DIR__ . '/vendor/autoload.php'; // composer's autoloader
require_once __DIR__ . '/src/autoload.php'; // my own autoloader for the plugin

$plugin = new Plugin( PLUGIN_FILEPATH );
$plugin->run();

require_once '/vendor/deeplcom/deepl-php/src/Translator.php'; // Required to avoid error
$translator      = new \Deepl\Translator(DEEPL_API_KEY);
$sourceLanguages = $translator->getSourceLanguages();

Without manually requiring the DeepL class I get the following error:

PHP Fatal error:  Uncaught Error: Class "Deepl\Translator" not found in /path/to/my/plugin/my-plugin.php:36
Stack trace:
#0 /path/to/wordpress/wp-settings.php(453): include_once()
#1 /path/to/wordpress/wp-config.php(96): require_once('C:\\laragon\\www\\...')
#2 /path/to/wordpress/wp-load.php(50): require_once('C:\\laragon\\www\\...')
#3 /path/to/wordpress/wp-admin\admin.php(34): require_once('C:\\laragon\\www\\...')
#4 {main}
  thrown in /path/to/my/plugin/my-plugin.php on line 36

Composer commands I have run in an attempt to fix this:

  • composer require deeplcom/deepl-php
  • composer install
  • composer dump-autoload

My composer.json:

{
    "require": {
        "deeplcom/deepl-php": "^1.4"
    }
}

I'm probably making an obvious mistake but can't see what. Please help!

Thanks in advance!

Word not found

Hi, as far as I know, when a word is not found, DeepL will try to guess or just return the same entry.
Is it possible to know when that happens? or to have the option to avoid it altogether? sometimes it's better to get a 'not found' message/error than a wild guess due to a misspelling.
Thank you for this, by the way, it's very useful!
Andres

Progress bar for DeepL PHP API

Hello,

I've implemented a progress bar for uploading and translating documents using the DeepL PHP API.
I use Javascript Fetch(), $translator->uploadDocument() and $translator->waitUntilDocumentTranslationComplete($document_handle)

The current documentation isn't very detailed, so I'd like to send you a pull-request,
which would add an examples directory and the example usage file with progress bar.

I thought it might help other users; if you're interested, please let me know.

Adding curl-options

Hi,
is there a way to add curl-options when instantiating the Translator?
I need to include verify_peer: false and verify_host: false, otherwise I'll get a "SSL certificate error: unable to get local issuer certificate"-exception.

I have tried
$translator = new \DeepL\Translator('KEY', ['headers' => ['verify_peer' => false, 'verify_host' => false]]);
but that doesn't work (same with "0" instead of "false" for both options).
I see the options getting added to $curlOptions in HttpClient (line 182), but they don't seem to do anything.

Thanks

Error while instaling: Your requirements could not be resolved to an installable set of packages.

Hi, I received that error while installing:

miguel@miguel-IdeaPad-3-15ITL6:/var/www/html/vmo$ composer require deeplcom/deepl-php
Warning from https://repo.packagist.org: Support for Composer 1 is deprecated and some packages will not be available. You should upgrade to Composer 2. See https://blog.packagist.com/deprecating-composer-1-support/
Info from https://repo.packagist.org: #StandWithUkraine
Using version ^0.4.0 for deeplcom/deepl-php
./composer.json has been updated
Loading composer repositories with package information
Warning from https://repo.packagist.org: Support for Composer 1 is deprecated and some packages will not be available. You should upgrade to Composer 2. See https://blog.packagist.com/deprecating-composer-1-support/
Info from https://repo.packagist.org: #StandWithUkraine
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - The requested package vendor/package could not be found in any version, there may be a typo in the package name.
  Problem 2
    - The requested package vendor/package2 could not be found in any version, there may be a typo in the package name.
  Problem 3
    - The requested package vendor/package3 could not be found in any version, there may be a typo in the package name.
  Problem 4
    - pelago/emogrifier v2.2.0 requires php ^5.5.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 -> your PHP version (7.4.3) does not satisfy that requirement.
    - pelago/emogrifier v2.2.0 requires php ^5.5.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 -> your PHP version (7.4.3) does not satisfy that requirement.
    - Installation request for pelago/emogrifier (installed at v2.2.0) -> satisfiable by pelago/emogrifier[v2.2.0].

Potential causes:
 - A typo in the package name
 - The package is not available in a stable-enough version according to your minimum-stability setting
   see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.
 - It's a private package and you forgot to add a custom repository to find it

Read <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.

Installation failed, reverting ./composer.json to its original content.
miguel@miguel-IdeaPad-3-15ITL6:/var/www/html/vmo$

Any solution please?

Thank you,
Miguel

BUG: Class Http\Discovery\Psr17FactoryDiscovery not found error

After updating the package deeplcom/deepl-php to the latest version [1.5.0 according to VERSION] by running composer update today (27.06.2023) and having to add the pugin php-http/discovery to my allow-plugins list, I receive the following error message:

[27-Jun-2023 10:03:06 Europe/Zurich] PHP Fatal error:  Uncaught Error: Class "Http\Discovery\Psr17FactoryDiscovery" not found in /photos/holiday/vendor/deeplcom/deepl-php/src/HttpClientWrapper.php:66
Stack trace:
#0 /photos/holiday/vendor/deeplcom/deepl-php/src/Translator.php(75): DeepL\HttpClientWrapper->__construct()
#1 /photos/holiday/lib3/class.Translate.php(26): DeepL\Translator->__construct()
#2 /photos/holiday/web3/holiday.php(47): Translate->__construct()
#3 {main}
  thrown in /photos/holiday/vendor/deeplcom/deepl-php/src/HttpClientWrapper.php on line 66

Cannot create account / API key

Hi, the following appears on your site when you sign up -- only after providing a credit card...

image

I actually tried again with a new account and got the same thing. Doesn't seem to be a way to generate API keys right now. I did contact support, but have not heard anything.

Getting "syntax error, unexpected ')' in src/Translator.php" when constructing Translator

Docker php:7.4-fpm

I get a syntax error when calling:

$translator = new \DeepL\Translator($authKey);

and if you look into the file deepl-php/src/Translator.php at Line 552 and Line 559 shown as below:

// Line 552, validateAndAppendTexts()
throw new DeepLException(
    'texts parameter must be a non-empty string or array of non-empty strings',
);

// Same as above, Line 559, validateAndAppendTexts()
throw new DeepLException(
    'texts parameter must be a non-empty string or array of non-empty strings',
);

Remove the comma right after the message will fix it :

throw new DeepLException(
    'texts parameter must be a non-empty string or array of non-empty strings'
);

Just in case anyone has the same issue, so I posted it here :)

Problems with POST request with getUsage (400 status code - bad request)

I had some problems using this client library. Specifically, the Translator::getUsage() call worked on a development system, but not on other machine (with the same software package). Everything else worked very reliably.

The problem that occurs is that the getUsage request returns 400 HTTP status code (bad request).

I can reproduce this consistently, I even created a small test script with (basically) the same code.

After some tests I could narrow it down:

All systems use

  • deeplcom/deepl v1.3.0
  • PHP 7.4 or 8.1

Always worked:

  • Translator::listGlossaries()
  • Translator::getGlossaryEntries()
  • Translator::createGlossary()

Problems on some machines:

  • Translator::getUsage()

The problems occured on:

  • RHEL systems with PHP 8 and PHP 7 (curl 7.29.0)

Ok:

  • Ubuntu with PHP 8 (curl 7.81.0)

Suspected problem

  • some differences between systems in cURL library / PHP settings (the configuration and usage of deeplcom/deepl was identical)
  • getUsage is the only call that uses POST request, not GET
  • with POST, the Content-Type header is not set and also CURLOPT_POSTFIELDS is not set. I assume that my different cURL libs handle that differently.

Resproduce

It is a little difficult to reproduce because the problem does not manifest itself on all systems and I am not sure what is the relevant setting.

Possible solution

Ideally, figure out exact reason why server sends 404. However, this also seems to fix the problem:

  1. Either use GET with getUsage. I am not sure why POST is used, the API docs use GET: https://www.deepl.com/docs-api/general/get-usage/
  2. or

in HttpClient::sendRequest

$headers['Content-Type'] = 'application/json';
$payload = json_encode( [] );
$curlOptions[\CURLOPT_POSTFIELDS] = $payload;

Additional information

I activated logging and also have a test script which reproduces the problem on the affected machines and outputs some more information. I can upload the logs if requested.

The test script is here: https://github.com/sypets/sypets_test_deepl_usage_standalone

Encode/decode the results for italian and other languages?

Hi there!

I see when i try to translate the result is wrong some times.

I wonder if there is some encode/decode integrated function to prevent those texts with special caracteres?

Ej: áéú etc?

Or shold i just use usual php functions?

Thank you!

Version 1.5.0 should be considered a breaking change?

Per, issue #27 DeepL PHP library now requires devs to add

require __DIR__ . '/../vendor/autoload.php';

prior to instantiating the translator.

In my composer.json, I had my constraints set to allow upgrades to non-breaking versions. However, because of this additional step, the DeepL library triggered fatal errors after a running composer install on a deployment.

However when v1.4.0 is installed and running composer outdated, it denotes v 1.5.0 only contains bug fixes. I disagree considering it will likely break the apps of people coming from v.1.5.0.

Anyhow thought I'd give you a heads up in case this was an oversight.

Also, the fix in the issue above should be mentioned in the docs, right?

FEATURE REQUEST: Add support for changing httpClient

Currently you are using a static internal http client based on curl. It would be good if there would be an option to set an alternative http client (e.g. guzzlephp, php streams or any psr18 compatible client).

This would be usefull e.g. when you can`t use curl, or when you are using any framework with its own httpclient.

I would suggest to add a new option to the options array e.g.

  $translator = new \DeepL\Translator($authKey);
  $translator->translateText($text, $source, $target, [
      'httpClient' => new Psr18Client()
  ]);

The option httpClient should accept any client matching to an from predefined defined "HttpClientInterface" and you change your code to only use HttpClientInterface to be compatible with all comming implementations on this interface.

Benefit would be, you only need to implement the basic logic of passing new clients based on this interface, createing different clients could be done by the community.

examples how this could be done can be found in other projects using changeable http clients like here

EDIT:
This feature would automatically resolve #14 because you could ad or change an alternative curl client with custom config.

targetLang="en" is deprecated, please use "en-GB" or "en-US" instead

Execute scheduled task: Autotranslation Fetch (filter_autotranslate\task\autotranslate_task)
... started 22:06:02. Current memory use 29.1 MB.
Debugging increased temporarily due to faildelay of 60
Executing autotranslation fetch jobs...
200 jobs found...
fetching en translation for d41d8cd98f00b204e9800998ecf8427e key...
... used 4 dbqueries
... used 0.015782117843628 seconds
Scheduled task failed: Autotranslation Fetch (filter_autotranslate\task\autotranslate_task),targetLang="en" is deprecated, please use "en-GB" or "en-US" instead.
Backtrace:
* line 156 of /filter/autotranslate/vendor/deeplcom/deepl-php/src/Translator.php: call to DeepL\Translator->buildBodyParams()
* line 108 of /filter/autotranslate/classes/task/autotranslate_task.php: call to DeepL\Translator->translateText()
* line 405 of /lib/classes/cron.php: call to filter_autotranslate\task\autotranslate_task->execute()
* line 208 of /lib/classes/cron.php: call to core\cron::run_inner_scheduled_task()
* line 125 of /lib/classes/cron.php: call to core\cron::run_scheduled_tasks()
* line 186 of /admin/cli/cron.php: call to core\cron::run_main_process()

This isn't technically a bug but it broke our entire app. The Readme might need updated to notify users of this. We have a custom plugin on Moodle that's based entirely on 2 letter locale codes and I haven't gotten into the internals yet to see if it will give us the en-US format. There might be other software out there that suffers from the same problem.

Feature request: Make it possible to retrieve billing period for usage

This probably requires an API change as well.

I would like to know to what time frame the "usage" applies to. I have count used and a limit (for characters, document and team documents). I assume it applies to current billing period, which is in our case monthly but the start of the time interval may vary (for example in our case it is February 26, 2023 - March 25, 2023). So you cannot assume the month starts with day 1, e.g. February 1.

For example this is the output I would like to display:

characters:
20% used (February 26, 2023 - March 25, 2023)

I can use the timeframe as fixed string in my case, but if people want to supply further PHP packages based on this API for public use, it would be helpful to be able to read this from the API.

My wish would be to extend the Usage information fetched from the DeepL API and Usage class in deepl-php.

https://www.deepl.com/docs-api/general/get-usage/

Use glossary for target language en-GB

QUEST:
With which parameters do I have to create a glossary for DE->EN so that I can use it for translation?


When creating a glossary, the target language is changed from "en-GB" to "en".
Translator.php::331
This means that it is only possible to create a glossary for e.g. "de"->"en".


When using Translator::translateText for the target language "en"
you get an error message:
Fatal error: Uncaught DeepL\DeepLException: targetLang="en" is deprecated, please use "en-GB".

Therefore, you must use Translator::translateText with "en-GB".
This will give results when using WITHOUT glossary.

When using the previously created glossary with target language "en"
the library sends these post parameters to the API:
target_lang=en-GB&source_lang=en&formality=prefer_more&glossary_id=500ebda5-50b5-4e6b-ae0e-b8d64bcf57b3&text=Example+Sentence&tag_handling=html
you get the error message:
{"message": "Language pair of the glossary doesn't match the language pair of the request"}

Problems with "final class Translator in phpunit integration Tests

Hey,
at the moment I try to replace https://github.com/Baby-Markt/deepl-php-lib with your Library.
Everything went relatively smooth but I ran into an Issues when it comes to user the Library in integration Tests.
Since I am not able to start an API-Mock-Server during our Tests, I want to Mock your Translator class and to manipulate the return value of for example the translateText-Method. At the moment this is not possible because the Translator-Class is final and phpunit uses Class-Extension to create Mockclasses.
I tried Mockery but since we use type hinting this fails too.

Is it possible for you to Change the definition or do you have an other suggestion for this Problem?

Question about keys in translated arrays

Why does the translation function not retain the key, when translating an array of text?

$to_translate = array('a' => 'Text A', 'b' => 'Text B');
$translations = $translator->translateText($to_translate, 'en-US', 'de');

The result is return as an array indexed 0, 1 rather than indexed using 'a', 'b'. Is there a reason for this behavior?

[Security] Actions due to/Information around CVE-2023-38545

The cURL project recently announced a high-severity security flaw affecting cURL and libcurl, with patches coming out on Oct 11th. DeepL takes security extremely seriously and is taking the appropriate internal measures to ensure the flaw is fixed in our systems ASAP. This issue serves to inform the users of our client libraries how this flaw affects the client libraries.

Affected libraries
We reviewed our dependencies and found no link to cURL in any library except this PHP one. This library uses the PHP cURL extension ext-curl, and does not itself include libcurl or similar. Hence, it is the user's responsibility to update the library on the system the client library is running on.

How can I check if I am affected?
Run this command in your console with the php binary that is also used for the client library. php -r "phpinfo(INFO_MODULES);" | grep cURL

If the cURL Information line shows a version below 8.4.0, you are affected and should update your system's cURL version.

How can I update?

This will depend on your operating system/how you installed cURL. You can find some general pointers for all major operating systems here.

When passing in WP $content variable, translate_text emits a type errror

I am working on adding DeepL API to my organization's Wordpress site.

Right now, I have a hook that gets the content of blogs, pages and posts that has already been converted to HTML and translates it using the DeepL PHP library. It works great most of the time. However, whenever the post content includes content from a secondary query that retrieves featured posts, I get the following error:

 Uncaught Exception: texts parameter must be a non-empty string or array of non-empty strings 

However, when I check the type of the content variable and its length, it is confirmed to be a string. I checked the function in Translator.php to see what it's checking for and it's simply checking to see if the text argument is indeed a string AND is not empty.

Here's my code:

add_filter('the_content', function($content){
        if(in_the_loop()){
            $deepl_api_key = $_SERVER['DEEPL_API_KEY'];
            $translator = new \DeepL\Translator($deepl_api_key);
            $content_translated = $translator->translateText($content, 'EN', 'ES', ['tag_handling' => 'html'] );
            return $content_translated;
        }
        return $content;
  }, 99);

Here's the full error being emitted

Fatal error: Uncaught Exception: texts parameter must be a non-empty string or array of non-empty strings (View: /srv/www/site.com/current/web/app/themes/theme/resources/views/blocks/featured-posts.blade.php) (View: /srv/www/site.com/current/web/app/themes/theme/resources/views/blocks/featured-posts.blade.php)
in /srv/www/site.com/current/vendor/deeplcom/deepl-php/src/Translator.php on line 558


I am somewhat grasping at straws for what is causing this issue and am aware this could be an issue with WP Core or our custom theme. However, I figured I might as well place the issue here in case it is a DeepL PHP library issue. 

QUESTION: Question/Issue regarding translation speed for Tweet-sized sentences

I am currently benchmarking DeepL against Google Translate for translating photo captions the size of a Tweet with a rather standardized sentence structure from English to German and French. 80% of the translated caption phrases are identical and in the last 20%, DeepL chooses a more appropriate vocabulary, e.g.

ORIGINAL: Belinda Bencic of Switzerland plays the ball during her third round match against Donna Vekic of Croatia on day two of the 2019 French Open at the Roland Garros stadium in Paris, France on May 31, 2019 (Photo by Claude Diderich / freshfocus)
DEEPL TRANSLATION:  PARIS, FRANKREICH - 31. MAI: Belinda Bencic aus der Schweiz spielt den Ball während ihres Drittrundenmatches gegen Donna Vekic aus Kroatien am zweiten Tag der French Open 2019 im Roland-Garros-Stadion in Paris, Frankreich am 31. Mai 2019 (Foto: Claude Diderich / freshfocus)
GOOGLE TRANSLATION: PARIS, FRANKREICH - 31. MAI: Belinda Bencic aus der Schweiz spielt den Ball während ihres Spiels in der dritten Runde gegen Donna Vekic aus Kroatien am zweiten Tag der French Open 2019 im Roland Garros-Stadion in Paris, Frankreich, am 31. Mai 2019 (Foto von Claude Diderich / freshfocus)

But I noticed that on the speed/latency side, Google is 2x to 3x faster (0.15s vs 0.31s, 0.13s vs 0.39s, 0.2s vs 0.52s, etc.). I was wondering if that is due to

  1. the fact that I am currently using the free version from DeepL, i.e., the paid version would be much faster, or
  2. the translation at deepl.com taking more time than Google does, due to the complexity of the translation algorithm used, i.e., it's coming from the software side, or
  3. deepl.com having less sophisticated hardware resources in place, i.e., it's coming from the hardware side, or
  4. me being located in Switzerland and my network connection to translate.google.com is faster than to deepl.com?

instaling libreries without composer

Hi. I have problem with composer and deepl libraries.

It is posible to install without composer ?

Where are the files and a simple example in php for translate deepl using a frre api

best regards

ErrorMessage -> too many errors

When I translate a document pdf with a table using the glossary, I have this error message.

I would like to know what´s the error or how to fix it, could you help me?

image

Usage API may not return limit

Currently, the API is only returning the character_count and not the character_limit:

11:31:06 INFO      [app] DeepL API response POST https://api.deepl.com/v2/usage 200
11:31:06 DEBUG     [app] Response details: {"character_count":151629018}

In my use case, we only need to have the character_count, but the implementation discards the response if both are not present:

 private function buildUsageDetail(string $prefix, array $json): ?UsageDetail
    {
        $count = "{$prefix}_count";
        $limit = "{$prefix}_limit";
        if (array_key_exists($count, $json) && array_key_exists($limit, $json)) {
            return new UsageDetail($json[$count], $json[$limit]);
        }
        return null;
    }

Call to undefined function DeepL\curl_version() in deeplcom\deepl-php\src\Translator.php:738

I tried to change the http-client like shown in the README section - Custom HTTP client.

What results in Error:

 Call to undefined function DeepL\curl_version() in deeplcom\deepl-php\src\Translator.php:738

Here is my code to find this error:

$client = new \GuzzleHttp\Client([
    'handler' => new \GuzzleHttp\Handler\StreamHandler()
]);

$translator = new \DeepL\Translator($authKey);
$translator->translateText($text, $source, $target, [
    TranslatorOptions::HTTP_CLIENT => $client
]);

So it seems that even when you chance the HttpClient, the Translator Class still tries to use method/functions related to Curl HttpClient for building the user-agend string.

Suggestion to fix:

  1. check which Guzzle handler is used
  2. Only is a handler is used, that extends CurlHandler, set $libraryInfoStr to " curl/$curlVer"
  3. for other Handler, either don`t add this info, or find a way to get similar infos from the other Handler classes

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.