Use SharpAPI for Translating E-Commerce Product Info
Tags: laravel, ai, php, ecommerce
Published: 2024-05-28 06:38:30

In [Auctibles](https://auctibles.com), we use [SharpAPI](https://sharpapi.com) to translate product info. 

Auctibles is built with the Laravel PHP framework.

## The Service

We defined a service that will translate a text into a given language.

The service provides a `translate` function that translates the `text` parameter into the required language:

	<?php
	namespace App\Services;
	
	use GuzzleHttp\Exception\ClientException;
	
	class SharpAPI
	{
		private $service;
	
		public function __construct()
		{
		}
		
		public function translate(string $text, string $to_language)
		{		
			
			try {
				
				$statusUrl = \SharpApiService::translate($text, $to_language);
				
			} catch(ClientException $e) {
			
				$rsp = $e->getResponse();
				return ['flag' => null];
				
			}
		
			$result = \SharpApiService::fetchResults($statusUrl);
			$res = json_decode($result->getResultJson());
		
			return ['flag' => true, 'content' => $res->content];
		}
	
	}

The function returns an associative array, with:

* `bool flag` - signifying success or failure
* `content` - translated content

## The Job

Because calling SharpAPI takes time, we do this asynchronously in a job, once the user saves the product information. 

The job takes an `$obj` parameter, which is the product, and an array of `$fields` to be translated. The job iterates over the fields and sends each one to the service for translation.

The object comes from an Eloquent model using [Laravel-Translatable](https://spatie.be/docs/laravel-translatable/v6/introduction). So each field is a JSON array, mapping languages to the value for that language.

	<?php
	
	namespace App\Jobs\AI;
	
	use Illuminate\Bus\Queueable;
	use Illuminate\Contracts\Queue\ShouldBeEncrypted;
	use Illuminate\Contracts\Queue\ShouldQueue;
	use Illuminate\Foundation\Bus\Dispatchable;
	use Illuminate\Queue\InteractsWithQueue;
	use Illuminate\Queue\SerializesModels;
	
	use SharpAPI\SharpApiService\Enums\SharpApiLanguages;
	
	use App\Services\SharpAPI;
	
	class SharpAPITranslator implements ShouldQueue, ShouldBeEncrypted
	{
	    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
	
	    /**
	     * Create a new job instance.
	     */
	    public function __construct(private string $from_language, private $obj, private $fields)
	    {
	        
	    }
	
	    /**
	     * Execute the job.
	     */
	    public function handle(): void
	    {
			    // instantiate the service
	        $sharp_api = new SharpAPI();
	
	        foreach($this->fields as $field) 
	        {
							foreach(array_keys(config('app.content_languages')) as $to_language)
	            {
	                if ($to_language != $this->from_language) {
											
											// get the content for the from_language
	                    $text = $obj->getTranslation($field, $fromlang, true)
	                    
	                                      
	                    $result = $sharp_api->translate(
	                        $text, 
	                        $this->sharp_api_language($to_language)
	                    );
	                    
	
	                    if ($result['flag']) {
			                    // store the content for to_language
	                        $this->obj->setTranslation(
	                            $field, 
	                            $to_language,
	                            $result['content']
	                        );
	                    }
	
	
	                }
	            }
	
	            $this->obj->save();
	            
	        }
	
	    }
	
	    private function sharp_api_language(string $locale): string
	    {
	        switch($locale)
	        {
	            case 'en':
	                return SharpApiLanguages::ENGLISH;
	
	            case 'pl':
	                return SharpApiLanguages::POLISH;
	
	        }
	    }
	}